xref: /csrg-svn/sys/net/raw_cb.c (revision 10890)
1 /*	raw_cb.c	4.16	83/02/10	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/mbuf.h"
6 #include "../h/socket.h"
7 #include "../h/socketvar.h"
8 #include "../h/errno.h"
9 
10 #include "../net/if.h"
11 #include "../net/raw_cb.h"
12 
13 #include "../vax/mtpr.h"
14 
15 /*
16  * Routines to manage the raw protocol control blocks.
17  *
18  * TODO:
19  *	hash lookups by protocol family/protocol + address family
20  *	take care of unique address problems per AF?
21  *	redo address binding to allow wildcards
22  */
23 
24 /*
25  * Allocate a control block and a nominal amount
26  * of buffer space for the socket.
27  */
28 raw_attach(so)
29 	register struct socket *so;
30 {
31 	struct mbuf *m;
32 	register struct rawcb *rp;
33 
34 	m = m_getclr(M_DONTWAIT, MT_PCB);
35 	if (m == 0)
36 		return (ENOBUFS);
37 	if (sbreserve(&so->so_snd, RAWSNDQ) == 0)
38 		goto bad;
39 	if (sbreserve(&so->so_rcv, RAWRCVQ) == 0)
40 		goto bad2;
41 	rp = mtod(m, struct rawcb *);
42 	rp->rcb_socket = so;
43 	insque(rp, &rawcb);
44 	so->so_pcb = (caddr_t)rp;
45 	rp->rcb_pcb = 0;
46 	return (0);
47 bad2:
48 	sbrelease(&so->so_snd);
49 bad:
50 	(void) m_free(m);
51 	return (ENOBUFS);
52 }
53 
54 /*
55  * Detach the raw connection block and discard
56  * socket resources.
57  */
58 raw_detach(rp)
59 	register struct rawcb *rp;
60 {
61 	struct socket *so = rp->rcb_socket;
62 
63 	so->so_pcb = 0;
64 	sofree(so);
65 	remque(rp);
66 	m_freem(dtom(rp));
67 }
68 
69 /*
70  * Disconnect and possibly release resources.
71  */
72 raw_disconnect(rp)
73 	struct rawcb *rp;
74 {
75 
76 	rp->rcb_flags &= ~RAW_FADDR;
77 	if (rp->rcb_socket->so_state & SS_NOFDREF)
78 		raw_detach(rp);
79 }
80 
81 raw_bind(so, nam)
82 	register struct socket *so;
83 	struct mbuf *nam;
84 {
85 	struct sockaddr *addr = mtod(nam, struct sockaddr *);
86 	register struct rawcb *rp;
87 
88 	if (ifnet == 0)
89 		return (EADDRNOTAVAIL);
90 {
91 #include "../h/domain.h"
92 #include "../netinet/in.h"
93 #include "../netinet/in_systm.h"
94 /* BEGIN DUBIOUS */
95 	/*
96 	 * Should we verify address not already in use?
97 	 * Some say yes, others no.
98 	 */
99 	switch (addr->sa_family) {
100 
101 	case AF_IMPLINK:
102 	case AF_INET:
103 		if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
104 		    if_ifwithaddr(addr) == 0)
105 			return (EADDRNOTAVAIL);
106 		break;
107 
108 #ifdef PUP
109 	/*
110 	 * Curious, we convert PUP address format to internet
111 	 * to allow us to verify we're asking for an Ethernet
112 	 * interface.  This is wrong, but things are heavily
113 	 * oriented towards the internet addressing scheme, and
114 	 * converting internet to PUP would be very expensive.
115 	 */
116 	case AF_PUP: {
117 #include "../netpup/pup.h"
118 		struct sockaddr_pup *spup = (struct sockaddr_pup *)addr;
119 		struct sockaddr_in inpup;
120 
121 		bzero((caddr_t)&inpup, (unsigned)sizeof(inpup));
122 		inpup.sin_family = AF_INET;
123 		inpup.sin_addr.s_net = spup->sp_net;
124 		inpup.sin_addr.s_impno = spup->sp_host;
125 		if (inpup.sin_addr.s_addr &&
126 		    if_ifwithaddr((struct sockaddr *)&inpup) == 0)
127 			return (EADDRNOTAVAIL);
128 		break;
129 	}
130 #endif
131 
132 	default:
133 		return (EAFNOSUPPORT);
134 	}
135 }
136 /* END DUBIOUS */
137 	rp = sotorawcb(so);
138 	bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr));
139 	rp->rcb_flags |= RAW_LADDR;
140 	return (0);
141 }
142 
143 /*
144  * Associate a peer's address with a
145  * raw connection block.
146  */
147 raw_connaddr(rp, nam)
148 	struct rawcb *rp;
149 	struct mbuf *nam;
150 {
151 	struct sockaddr *addr = mtod(nam, struct sockaddr *);
152 
153 	bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr));
154 	rp->rcb_flags |= RAW_FADDR;
155 }
156