xref: /original-bsd/sys/net/raw_cb.c (revision f0fd5f8a)
1 /*	raw_cb.c	4.15	82/12/14	*/
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 "../vax/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, MT_PCB);
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 	m_freem(dtom(rp));
65 }
66 
67 /*
68  * Disconnect and possibly release resources.
69  */
70 raw_disconnect(rp)
71 	struct rawcb *rp;
72 {
73 
74 	rp->rcb_flags &= ~RAW_FADDR;
75 	if (rp->rcb_socket->so_state & SS_NOFDREF)
76 		raw_detach(rp);
77 }
78 
79 raw_bind(so, nam)
80 	register struct socket *so;
81 	struct mbuf *nam;
82 {
83 	struct sockaddr *addr = mtod(nam, struct sockaddr *);
84 	register struct rawcb *rp;
85 
86 	if (ifnet == 0)
87 		return (EADDRNOTAVAIL);
88 {
89 #include "../h/domain.h"
90 #include "../netinet/in.h"
91 #include "../netinet/in_systm.h"
92 /* BEGIN DUBIOUS */
93 	/*
94 	 * Should we verify address not already in use?
95 	 * Some say yes, others no.
96 	 */
97 	switch (addr->sa_family) {
98 
99 	case AF_IMPLINK:
100 	case AF_INET:
101 		if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
102 		    if_ifwithaddr(addr) == 0)
103 			return (EADDRNOTAVAIL);
104 		break;
105 
106 #ifdef PUP
107 	/*
108 	 * Curious, we convert PUP address format to internet
109 	 * to allow us to verify we're asking for an Ethernet
110 	 * interface.  This is wrong, but things are heavily
111 	 * oriented towards the internet addressing scheme, and
112 	 * converting internet to PUP would be very expensive.
113 	 */
114 	case AF_PUP: {
115 #include "../netpup/pup.h"
116 		struct sockaddr_pup *spup = (struct sockaddr_pup *)addr;
117 		struct sockaddr_in inpup;
118 
119 		bzero((caddr_t)&inpup, (unsigned)sizeof(inpup));
120 		inpup.sin_family = AF_INET;
121 		inpup.sin_addr.s_net = spup->sp_net;
122 		inpup.sin_addr.s_impno = spup->sp_host;
123 		if (inpup.sin_addr.s_addr &&
124 		    if_ifwithaddr((struct sockaddr *)&inpup) == 0)
125 			return (EADDRNOTAVAIL);
126 		break;
127 	}
128 #endif
129 
130 	default:
131 		return (EAFNOSUPPORT);
132 	}
133 }
134 /* END DUBIOUS */
135 	rp = sotorawcb(so);
136 	bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr));
137 	rp->rcb_flags |= RAW_LADDR;
138 	return (0);
139 }
140 
141 /*
142  * Associate a peer's address with a
143  * raw connection block.
144  */
145 raw_connaddr(rp, nam)
146 	struct rawcb *rp;
147 	struct mbuf *nam;
148 {
149 	struct sockaddr *addr = mtod(nam, struct sockaddr *);
150 
151 	bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr));
152 	rp->rcb_flags |= RAW_FADDR;
153 }
154