Add copyright
[unix-history] / usr / src / sys / net / raw_cb.c
CommitLineData
cb1c44c2
KM
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
6 * @(#)raw_cb.c 6.6 (Berkeley) %G%
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"
b1b3e868 22#ifdef PUP
9e9695c7 23#include "../netpup/pup.h"
b1b3e868 24#endif
f4d55810
SL
25
26#include "../vax/mtpr.h"
785d93ac
BJ
27
28/*
29 * Routines to manage the raw protocol control blocks.
30 *
31 * TODO:
32 * hash lookups by protocol family/protocol + address family
ee787340 33 * take care of unique address problems per AF?
1e25d807 34 * redo address binding to allow wildcards
785d93ac
BJ
35 */
36
37/*
38 * Allocate a control block and a nominal amount
39 * of buffer space for the socket.
40 */
829f867e 41raw_attach(so, proto)
785d93ac 42 register struct socket *so;
829f867e 43 int proto;
785d93ac
BJ
44{
45 struct mbuf *m;
46 register struct rawcb *rp;
785d93ac 47
cce93e4b 48 m = m_getclr(M_DONTWAIT, MT_PCB);
785d93ac
BJ
49 if (m == 0)
50 return (ENOBUFS);
51 if (sbreserve(&so->so_snd, RAWSNDQ) == 0)
52 goto bad;
53 if (sbreserve(&so->so_rcv, RAWRCVQ) == 0)
54 goto bad2;
55 rp = mtod(m, struct rawcb *);
56 rp->rcb_socket = so;
785d93ac
BJ
57 so->so_pcb = (caddr_t)rp;
58 rp->rcb_pcb = 0;
829f867e
MK
59 rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
60 rp->rcb_proto.sp_protocol = proto;
61 insque(rp, &rawcb);
785d93ac
BJ
62 return (0);
63bad2:
64 sbrelease(&so->so_snd);
65bad:
66 (void) m_free(m);
67 return (ENOBUFS);
68}
69
70/*
71 * Detach the raw connection block and discard
72 * socket resources.
73 */
74raw_detach(rp)
75 register struct rawcb *rp;
76{
77 struct socket *so = rp->rcb_socket;
78
785d93ac
BJ
79 so->so_pcb = 0;
80 sofree(so);
81 remque(rp);
4053be18 82 m_freem(dtom(rp));
785d93ac
BJ
83}
84
85/*
86 * Disconnect and possibly release resources.
87 */
88raw_disconnect(rp)
89 struct rawcb *rp;
90{
4053be18 91
126472ab 92 rp->rcb_flags &= ~RAW_FADDR;
f832270b 93 if (rp->rcb_socket->so_state & SS_NOFDREF)
785d93ac
BJ
94 raw_detach(rp);
95}
96
14fa60f2
BJ
97raw_bind(so, nam)
98 register struct socket *so;
99 struct mbuf *nam;
100{
101 struct sockaddr *addr = mtod(nam, struct sockaddr *);
14fa60f2
BJ
102 register struct rawcb *rp;
103
104 if (ifnet == 0)
105 return (EADDRNOTAVAIL);
14fa60f2
BJ
106/* BEGIN DUBIOUS */
107 /*
108 * Should we verify address not already in use?
109 * Some say yes, others no.
110 */
111 switch (addr->sa_family) {
112
9e9695c7 113#ifdef INET
14fa60f2 114 case AF_IMPLINK:
9e9695c7 115 case AF_INET: {
14fa60f2 116 if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
cba69651 117 ifa_ifwithaddr(addr) == 0)
14fa60f2
BJ
118 return (EADDRNOTAVAIL);
119 break;
9e9695c7
SL
120 }
121#endif
14fa60f2
BJ
122
123#ifdef PUP
124 /*
125 * Curious, we convert PUP address format to internet
126 * to allow us to verify we're asking for an Ethernet
127 * interface. This is wrong, but things are heavily
128 * oriented towards the internet addressing scheme, and
129 * converting internet to PUP would be very expensive.
130 */
131 case AF_PUP: {
14fa60f2
BJ
132 struct sockaddr_pup *spup = (struct sockaddr_pup *)addr;
133 struct sockaddr_in inpup;
134
af0b24db 135 bzero((caddr_t)&inpup, (unsigned)sizeof(inpup));
14fa60f2 136 inpup.sin_family = AF_INET;
cba69651 137 inpup.sin_addr = in_makeaddr(spup->spup_net, spup->spup_host);
14fa60f2 138 if (inpup.sin_addr.s_addr &&
cba69651 139 ifa_ifwithaddr((struct sockaddr *)&inpup) == 0)
14fa60f2
BJ
140 return (EADDRNOTAVAIL);
141 break;
142 }
143#endif
144
145 default:
146 return (EAFNOSUPPORT);
147 }
14fa60f2 148/* END DUBIOUS */
af0b24db 149 rp = sotorawcb(so);
14fa60f2
BJ
150 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr));
151 rp->rcb_flags |= RAW_LADDR;
152 return (0);
153}
154
785d93ac
BJ
155/*
156 * Associate a peer's address with a
157 * raw connection block.
158 */
14fa60f2 159raw_connaddr(rp, nam)
785d93ac 160 struct rawcb *rp;
14fa60f2 161 struct mbuf *nam;
785d93ac 162{
14fa60f2
BJ
163 struct sockaddr *addr = mtod(nam, struct sockaddr *);
164
126472ab
SL
165 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr));
166 rp->rcb_flags |= RAW_FADDR;
785d93ac 167}