MCLALLOC must be called at splimp
[unix-history] / usr / src / sys / net / raw_cb.c
CommitLineData
cb1c44c2 1/*
1810611d 2 * Copyright (c) 1980, 1986 Regents of the University of California.
cb1c44c2
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
ffcd9f47 6 * @(#)raw_cb.c 7.2 (Berkeley) %G%
cb1c44c2 7 */
785d93ac 8
20666ad3
JB
9#include "param.h"
10#include "systm.h"
11#include "mbuf.h"
12#include "socket.h"
13#include "socketvar.h"
829f867e
MK
14#include "domain.h"
15#include "protosw.h"
20666ad3 16#include "errno.h"
f4d55810 17
20666ad3
JB
18#include "if.h"
19#include "route.h"
20#include "raw_cb.h"
9e9695c7 21#include "../netinet/in.h"
f4d55810
SL
22
23#include "../vax/mtpr.h"
785d93ac
BJ
24
25/*
26 * Routines to manage the raw protocol control blocks.
27 *
28 * TODO:
29 * hash lookups by protocol family/protocol + address family
ee787340 30 * take care of unique address problems per AF?
1e25d807 31 * redo address binding to allow wildcards
785d93ac
BJ
32 */
33
34/*
35 * Allocate a control block and a nominal amount
36 * of buffer space for the socket.
37 */
829f867e 38raw_attach(so, proto)
785d93ac 39 register struct socket *so;
829f867e 40 int proto;
785d93ac
BJ
41{
42 struct mbuf *m;
43 register struct rawcb *rp;
785d93ac 44
cce93e4b 45 m = m_getclr(M_DONTWAIT, MT_PCB);
785d93ac
BJ
46 if (m == 0)
47 return (ENOBUFS);
48 if (sbreserve(&so->so_snd, RAWSNDQ) == 0)
49 goto bad;
50 if (sbreserve(&so->so_rcv, RAWRCVQ) == 0)
51 goto bad2;
52 rp = mtod(m, struct rawcb *);
53 rp->rcb_socket = so;
785d93ac
BJ
54 so->so_pcb = (caddr_t)rp;
55 rp->rcb_pcb = 0;
829f867e
MK
56 rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
57 rp->rcb_proto.sp_protocol = proto;
58 insque(rp, &rawcb);
785d93ac
BJ
59 return (0);
60bad2:
61 sbrelease(&so->so_snd);
62bad:
63 (void) m_free(m);
64 return (ENOBUFS);
65}
66
67/*
68 * Detach the raw connection block and discard
69 * socket resources.
70 */
71raw_detach(rp)
72 register struct rawcb *rp;
73{
74 struct socket *so = rp->rcb_socket;
75
10c543d7
MK
76 if (rp->rcb_route.ro_rt)
77 rtfree(rp->rcb_route.ro_rt);
785d93ac
BJ
78 so->so_pcb = 0;
79 sofree(so);
80 remque(rp);
82acad77 81 if (rp->rcb_options)
ffcd9f47 82 m_freem(rp->rcb_options);
4053be18 83 m_freem(dtom(rp));
785d93ac
BJ
84}
85
86/*
87 * Disconnect and possibly release resources.
88 */
89raw_disconnect(rp)
90 struct rawcb *rp;
91{
4053be18 92
126472ab 93 rp->rcb_flags &= ~RAW_FADDR;
f832270b 94 if (rp->rcb_socket->so_state & SS_NOFDREF)
785d93ac
BJ
95 raw_detach(rp);
96}
97
14fa60f2
BJ
98raw_bind(so, nam)
99 register struct socket *so;
100 struct mbuf *nam;
101{
102 struct sockaddr *addr = mtod(nam, struct sockaddr *);
14fa60f2
BJ
103 register struct rawcb *rp;
104
105 if (ifnet == 0)
106 return (EADDRNOTAVAIL);
14fa60f2
BJ
107/* BEGIN DUBIOUS */
108 /*
109 * Should we verify address not already in use?
110 * Some say yes, others no.
111 */
112 switch (addr->sa_family) {
113
799358ac 114#ifdef INET
14fa60f2 115 case AF_IMPLINK:
9e9695c7 116 case AF_INET: {
14fa60f2 117 if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
cba69651 118 ifa_ifwithaddr(addr) == 0)
14fa60f2
BJ
119 return (EADDRNOTAVAIL);
120 break;
9e9695c7
SL
121 }
122#endif
14fa60f2 123
14fa60f2
BJ
124 default:
125 return (EAFNOSUPPORT);
126 }
14fa60f2 127/* END DUBIOUS */
af0b24db 128 rp = sotorawcb(so);
14fa60f2
BJ
129 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr));
130 rp->rcb_flags |= RAW_LADDR;
131 return (0);
132}
133
785d93ac
BJ
134/*
135 * Associate a peer's address with a
136 * raw connection block.
137 */
14fa60f2 138raw_connaddr(rp, nam)
785d93ac 139 struct rawcb *rp;
14fa60f2 140 struct mbuf *nam;
785d93ac 141{
14fa60f2
BJ
142 struct sockaddr *addr = mtod(nam, struct sockaddr *);
143
126472ab
SL
144 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr));
145 rp->rcb_flags |= RAW_FADDR;
785d93ac 146}