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