virtual consoles
[unix-history] / usr / src / sys / net / raw_cb.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 1980, 1986 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 7.3 (Berkeley) %G%
7 */
8
9#include "param.h"
10#include "systm.h"
11#include "mbuf.h"
12#include "socket.h"
13#include "socketvar.h"
14#include "domain.h"
15#include "protosw.h"
16#include "errno.h"
17
18#include "if.h"
19#include "route.h"
20#include "raw_cb.h"
21#include "../netinet/in.h"
22
23#include "../machine/mtpr.h"
24
25/*
26 * Routines to manage the raw protocol control blocks.
27 *
28 * TODO:
29 * hash lookups by protocol family/protocol + address family
30 * take care of unique address problems per AF?
31 * redo address binding to allow wildcards
32 */
33
34/*
35 * Allocate a control block and a nominal amount
36 * of buffer space for the socket.
37 */
38raw_attach(so, proto)
39 register struct socket *so;
40 int proto;
41{
42 struct mbuf *m;
43 register struct rawcb *rp;
44
45 m = m_getclr(M_DONTWAIT, MT_PCB);
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;
54 so->so_pcb = (caddr_t)rp;
55 rp->rcb_pcb = 0;
56 rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
57 rp->rcb_proto.sp_protocol = proto;
58 insque(rp, &rawcb);
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
76 if (rp->rcb_route.ro_rt)
77 rtfree(rp->rcb_route.ro_rt);
78 so->so_pcb = 0;
79 sofree(so);
80 remque(rp);
81 if (rp->rcb_options)
82 m_freem(rp->rcb_options);
83 m_freem(dtom(rp));
84}
85
86/*
87 * Disconnect and possibly release resources.
88 */
89raw_disconnect(rp)
90 struct rawcb *rp;
91{
92
93 rp->rcb_flags &= ~RAW_FADDR;
94 if (rp->rcb_socket->so_state & SS_NOFDREF)
95 raw_detach(rp);
96}
97
98raw_bind(so, nam)
99 register struct socket *so;
100 struct mbuf *nam;
101{
102 struct sockaddr *addr = mtod(nam, struct sockaddr *);
103 register struct rawcb *rp;
104
105 if (ifnet == 0)
106 return (EADDRNOTAVAIL);
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
114#ifdef INET
115 case AF_IMPLINK:
116 case AF_INET: {
117 if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
118 ifa_ifwithaddr(addr) == 0)
119 return (EADDRNOTAVAIL);
120 break;
121 }
122#endif
123
124 default:
125 return (EAFNOSUPPORT);
126 }
127/* END DUBIOUS */
128 rp = sotorawcb(so);
129 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr));
130 rp->rcb_flags |= RAW_LADDR;
131 return (0);
132}
133
134/*
135 * Associate a peer's address with a
136 * raw connection block.
137 */
138raw_connaddr(rp, nam)
139 struct rawcb *rp;
140 struct mbuf *nam;
141{
142 struct sockaddr *addr = mtod(nam, struct sockaddr *);
143
144 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr));
145 rp->rcb_flags |= RAW_FADDR;
146}