merge 4.1b and 4.1c
[unix-history] / usr / src / sys / net / raw_cb.c
CommitLineData
af0b24db 1/* raw_cb.c 4.14 82/11/13 */
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"
4053be18 8#include "../vax/mtpr.h"
785d93ac
BJ
9#include "../net/if.h"
10#include "../net/raw_cb.h"
c47a5909 11#include <errno.h>
785d93ac
BJ
12
13/*
14 * Routines to manage the raw protocol control blocks.
15 *
16 * TODO:
17 * hash lookups by protocol family/protocol + address family
ee787340 18 * take care of unique address problems per AF?
1e25d807 19 * redo address binding to allow wildcards
785d93ac
BJ
20 */
21
22/*
23 * Allocate a control block and a nominal amount
24 * of buffer space for the socket.
25 */
14fa60f2 26raw_attach(so)
785d93ac 27 register struct socket *so;
785d93ac
BJ
28{
29 struct mbuf *m;
30 register struct rawcb *rp;
785d93ac 31
785d93ac
BJ
32 m = m_getclr(M_DONTWAIT);
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;
785d93ac
BJ
44 return (0);
45bad2:
46 sbrelease(&so->so_snd);
47bad:
48 (void) m_free(m);
49 return (ENOBUFS);
50}
51
52/*
53 * Detach the raw connection block and discard
54 * socket resources.
55 */
56raw_detach(rp)
57 register struct rawcb *rp;
58{
59 struct socket *so = rp->rcb_socket;
60
785d93ac
BJ
61 so->so_pcb = 0;
62 sofree(so);
63 remque(rp);
4053be18 64 m_freem(dtom(rp));
785d93ac
BJ
65}
66
67/*
68 * Disconnect and possibly release resources.
69 */
70raw_disconnect(rp)
71 struct rawcb *rp;
72{
4053be18 73
126472ab 74 rp->rcb_flags &= ~RAW_FADDR;
f832270b 75 if (rp->rcb_socket->so_state & SS_NOFDREF)
785d93ac
BJ
76 raw_detach(rp);
77}
78
14fa60f2
BJ
79raw_bind(so, nam)
80 register struct socket *so;
81 struct mbuf *nam;
82{
83 struct sockaddr *addr = mtod(nam, struct sockaddr *);
14fa60f2
BJ
84 register struct rawcb *rp;
85
86 if (ifnet == 0)
87 return (EADDRNOTAVAIL);
88{
af0b24db 89#include "../h/domain.h"
14fa60f2
BJ
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
af0b24db 119 bzero((caddr_t)&inpup, (unsigned)sizeof(inpup));
14fa60f2
BJ
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 */
af0b24db 135 rp = sotorawcb(so);
14fa60f2
BJ
136 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr));
137 rp->rcb_flags |= RAW_LADDR;
138 return (0);
139}
140
785d93ac
BJ
141/*
142 * Associate a peer's address with a
143 * raw connection block.
144 */
14fa60f2 145raw_connaddr(rp, nam)
785d93ac 146 struct rawcb *rp;
14fa60f2 147 struct mbuf *nam;
785d93ac 148{
14fa60f2
BJ
149 struct sockaddr *addr = mtod(nam, struct sockaddr *);
150
126472ab
SL
151 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr));
152 rp->rcb_flags |= RAW_FADDR;
785d93ac 153}