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