add IFF_LOCAL
[unix-history] / usr / src / sys / net / raw_cb.c
CommitLineData
b11be056 1/* raw_cb.c 6.1 83/07/29 */
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 10#include "../net/if.h"
71fb71a3 11#include "../net/route.h"
785d93ac 12#include "../net/raw_cb.h"
9e9695c7
SL
13#include "../netinet/in.h"
14#include "../netpup/pup.h"
f4d55810
SL
15
16#include "../vax/mtpr.h"
785d93ac
BJ
17
18/*
19 * Routines to manage the raw protocol control blocks.
20 *
21 * TODO:
22 * hash lookups by protocol family/protocol + address family
ee787340 23 * take care of unique address problems per AF?
1e25d807 24 * redo address binding to allow wildcards
785d93ac
BJ
25 */
26
27/*
28 * Allocate a control block and a nominal amount
29 * of buffer space for the socket.
30 */
14fa60f2 31raw_attach(so)
785d93ac 32 register struct socket *so;
785d93ac
BJ
33{
34 struct mbuf *m;
35 register struct rawcb *rp;
785d93ac 36
cce93e4b 37 m = m_getclr(M_DONTWAIT, MT_PCB);
785d93ac
BJ
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;
785d93ac
BJ
49 return (0);
50bad2:
51 sbrelease(&so->so_snd);
52bad:
53 (void) m_free(m);
54 return (ENOBUFS);
55}
56
57/*
58 * Detach the raw connection block and discard
59 * socket resources.
60 */
61raw_detach(rp)
62 register struct rawcb *rp;
63{
64 struct socket *so = rp->rcb_socket;
65
785d93ac
BJ
66 so->so_pcb = 0;
67 sofree(so);
68 remque(rp);
4053be18 69 m_freem(dtom(rp));
785d93ac
BJ
70}
71
72/*
73 * Disconnect and possibly release resources.
74 */
75raw_disconnect(rp)
76 struct rawcb *rp;
77{
4053be18 78
126472ab 79 rp->rcb_flags &= ~RAW_FADDR;
f832270b 80 if (rp->rcb_socket->so_state & SS_NOFDREF)
785d93ac
BJ
81 raw_detach(rp);
82}
83
14fa60f2
BJ
84raw_bind(so, nam)
85 register struct socket *so;
86 struct mbuf *nam;
87{
88 struct sockaddr *addr = mtod(nam, struct sockaddr *);
14fa60f2
BJ
89 register struct rawcb *rp;
90
91 if (ifnet == 0)
92 return (EADDRNOTAVAIL);
14fa60f2
BJ
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
9e9695c7 100#ifdef INET
14fa60f2 101 case AF_IMPLINK:
9e9695c7 102 case AF_INET: {
14fa60f2
BJ
103 if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
104 if_ifwithaddr(addr) == 0)
105 return (EADDRNOTAVAIL);
106 break;
9e9695c7
SL
107 }
108#endif
14fa60f2
BJ
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: {
14fa60f2
BJ
119 struct sockaddr_pup *spup = (struct sockaddr_pup *)addr;
120 struct sockaddr_in inpup;
121
af0b24db 122 bzero((caddr_t)&inpup, (unsigned)sizeof(inpup));
14fa60f2 123 inpup.sin_family = AF_INET;
a6787e03 124 inpup.sin_addr = if_makeaddr(spup->spup_net, spup->spup_host);
14fa60f2
BJ
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}