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