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