xref: /csrg-svn/sys/net/raw_cb.c (revision 5635)
1*5635Sroot /*	raw_cb.c	4.1	82/02/01	*/
2*5635Sroot 
3*5635Sroot #include "../h/param.h"
4*5635Sroot #include "../h/systm.h"
5*5635Sroot #include "../h/mbuf.h"
6*5635Sroot #include "../h/socket.h"
7*5635Sroot #include "../h/socketvar.h"
8*5635Sroot #include "../h/mtpr.h"
9*5635Sroot #include "../net/in.h"
10*5635Sroot #include "../net/in_systm.h"
11*5635Sroot #include "../net/if.h"
12*5635Sroot #include "../net/raw_cb.h"
13*5635Sroot #include "/usr/include/errno.h"
14*5635Sroot 
15*5635Sroot /*
16*5635Sroot  * Routines to manage the raw protocol control blocks.
17*5635Sroot  *
18*5635Sroot  * TODO:
19*5635Sroot  *	hash lookups by protocol family/protocol + address family
20*5635Sroot  *	take care of unique address problems per AF
21*5635Sroot  */
22*5635Sroot 
23*5635Sroot /*
24*5635Sroot  * Allocate a control block and a nominal amount
25*5635Sroot  * of buffer space for the socket.
26*5635Sroot  */
27*5635Sroot raw_attach(so, addr)
28*5635Sroot 	register struct socket *so;
29*5635Sroot 	struct sockaddr *addr;
30*5635Sroot {
31*5635Sroot 	struct mbuf *m;
32*5635Sroot 	register struct rawcb *rp;
33*5635Sroot 	struct ifnet *ifp = ifnet;
34*5635Sroot 
35*5635Sroot COUNT(RAW_ATTACH);
36*5635Sroot 	if (so->so_options & SO_DEBUG)
37*5635Sroot 		printf("raw_attach: addr=%d\n", addr->sa_family);
38*5635Sroot 	/*
39*5635Sroot 	 * Should we verify address not already in use?
40*5635Sroot 	 * Some say yes, others no.
41*5635Sroot 	 */
42*5635Sroot 	if (addr) switch (addr->sa_family) {
43*5635Sroot 
44*5635Sroot 	case AF_INET: {
45*5635Sroot 		register struct sockaddr_in *sin = (struct sockaddr_in *)addr;
46*5635Sroot 
47*5635Sroot 		if (ifnet && sin->sin_addr.s_addr == 0)
48*5635Sroot 			sin->sin_addr = ifnet->if_addr;
49*5635Sroot 		ifp = if_ifwithaddr(sin->sin_addr);
50*5635Sroot 		break;
51*5635Sroot 		}
52*5635Sroot 
53*5635Sroot 	default:
54*5635Sroot 		return (EAFNOSUPPORT);
55*5635Sroot 	}
56*5635Sroot 	if (ifp == 0)
57*5635Sroot 		return (EADDRNOTAVAIL);
58*5635Sroot 	m = m_getclr(M_DONTWAIT);
59*5635Sroot 	if (m == 0)
60*5635Sroot 		return (ENOBUFS);
61*5635Sroot 	if (sbreserve(&so->so_snd, RAWSNDQ) == 0)
62*5635Sroot 		goto bad;
63*5635Sroot 	if (sbreserve(&so->so_rcv, RAWRCVQ) == 0)
64*5635Sroot 		goto bad2;
65*5635Sroot 	rp = mtod(m, struct rawcb *);
66*5635Sroot 	rp->rcb_socket = so;
67*5635Sroot 	insque(rp, &rawcb);
68*5635Sroot 	so->so_pcb = (caddr_t)rp;
69*5635Sroot 	rp->rcb_pcb = 0;
70*5635Sroot 
71*5635Sroot 	if (addr)
72*5635Sroot 		bcopy(addr, &so->so_addr, sizeof(*addr));
73*5635Sroot 	return (0);
74*5635Sroot bad2:
75*5635Sroot 	sbrelease(&so->so_snd);
76*5635Sroot bad:
77*5635Sroot 	(void) m_free(m);
78*5635Sroot 	return (ENOBUFS);
79*5635Sroot }
80*5635Sroot 
81*5635Sroot /*
82*5635Sroot  * Detach the raw connection block and discard
83*5635Sroot  * socket resources.
84*5635Sroot  */
85*5635Sroot raw_detach(rp)
86*5635Sroot 	register struct rawcb *rp;
87*5635Sroot {
88*5635Sroot 	struct socket *so = rp->rcb_socket;
89*5635Sroot 
90*5635Sroot COUNT(RAW_DETACH);
91*5635Sroot 	if (rp->rcb_socket->so_options & SO_DEBUG)
92*5635Sroot 		printf("raw_detach: rp=%X\n", rp);
93*5635Sroot 	so->so_pcb = 0;
94*5635Sroot 	sofree(so);
95*5635Sroot 	remque(rp);
96*5635Sroot 	(void) m_freem(dtom(rp));
97*5635Sroot }
98*5635Sroot 
99*5635Sroot /*
100*5635Sroot  * Disconnect and possibly release resources.
101*5635Sroot  */
102*5635Sroot raw_disconnect(rp)
103*5635Sroot 	struct rawcb *rp;
104*5635Sroot {
105*5635Sroot COUNT(RAW_DISCONNECT);
106*5635Sroot 	if (rp->rcb_socket->so_options & SO_DEBUG)
107*5635Sroot 		printf("raw_disconnect: rp=%X\n", rp);
108*5635Sroot 	rp->rcb_flags &= ~RAW_ADDR;
109*5635Sroot 	if (rp->rcb_socket->so_state & SS_USERGONE)
110*5635Sroot 		raw_detach(rp);
111*5635Sroot }
112*5635Sroot 
113*5635Sroot /*
114*5635Sroot  * Associate a peer's address with a
115*5635Sroot  * raw connection block.
116*5635Sroot  */
117*5635Sroot raw_connaddr(rp, addr)
118*5635Sroot 	struct rawcb *rp;
119*5635Sroot 	struct sockaddr *addr;
120*5635Sroot {
121*5635Sroot COUNT(RAW_CONNADDR);
122*5635Sroot 	if (rp->rcb_socket->so_options & SO_DEBUG);
123*5635Sroot 		printf("raw_connaddr: rp=%x, addr=<%x,%x>\n",
124*5635Sroot 		 rp, addr->sa_family, ((struct sockaddr_in *)addr)->sin_addr);
125*5635Sroot 	bcopy(addr, &rp->rcb_addr, sizeof(struct sockaddr));
126*5635Sroot 	rp->rcb_flags |= RAW_ADDR;
127*5635Sroot }
128