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