lint
[unix-history] / usr / src / sys / net / raw_cb.c
CommitLineData
668cc26d 1/* raw_cb.c 4.5 82/03/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"
8#include "../h/mtpr.h"
9#include "../net/in.h"
10#include "../net/in_systm.h"
11#include "../net/if.h"
12#include "../net/raw_cb.h"
1e25d807 13#include "../errno.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
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 */
28raw_attach(so, addr)
29 register struct socket *so;
30 struct sockaddr *addr;
31{
32 struct mbuf *m;
33 register struct rawcb *rp;
34 struct ifnet *ifp = ifnet;
35
36COUNT(RAW_ATTACH);
785d93ac
BJ
37 /*
38 * Should we verify address not already in use?
39 * Some say yes, others no.
40 */
41 if (addr) switch (addr->sa_family) {
42
a2cd4df7 43 case AF_IMPLINK:
785d93ac
BJ
44 case AF_INET: {
45 register struct sockaddr_in *sin = (struct sockaddr_in *)addr;
46
47 if (ifnet && sin->sin_addr.s_addr == 0)
48 sin->sin_addr = ifnet->if_addr;
49 ifp = if_ifwithaddr(sin->sin_addr);
50 break;
51 }
52
1e25d807
BJ
53 case AF_PUP:
54 ifp = ifnet;
55 break;
56
785d93ac
BJ
57 default:
58 return (EAFNOSUPPORT);
59 }
60 if (ifp == 0)
61 return (EADDRNOTAVAIL);
62 m = m_getclr(M_DONTWAIT);
63 if (m == 0)
64 return (ENOBUFS);
65 if (sbreserve(&so->so_snd, RAWSNDQ) == 0)
66 goto bad;
67 if (sbreserve(&so->so_rcv, RAWRCVQ) == 0)
68 goto bad2;
69 rp = mtod(m, struct rawcb *);
70 rp->rcb_socket = so;
71 insque(rp, &rawcb);
72 so->so_pcb = (caddr_t)rp;
73 rp->rcb_pcb = 0;
74
75 if (addr)
668cc26d 76 bcopy((caddr_t)addr, (caddr_t)&so->so_addr, sizeof(*addr));
785d93ac
BJ
77 return (0);
78bad2:
79 sbrelease(&so->so_snd);
80bad:
81 (void) m_free(m);
82 return (ENOBUFS);
83}
84
85/*
86 * Detach the raw connection block and discard
87 * socket resources.
88 */
89raw_detach(rp)
90 register struct rawcb *rp;
91{
92 struct socket *so = rp->rcb_socket;
93
94COUNT(RAW_DETACH);
785d93ac
BJ
95 so->so_pcb = 0;
96 sofree(so);
97 remque(rp);
668cc26d 98 m_freem(dtom(rp));
785d93ac
BJ
99}
100
101/*
102 * Disconnect and possibly release resources.
103 */
104raw_disconnect(rp)
105 struct rawcb *rp;
106{
107COUNT(RAW_DISCONNECT);
785d93ac
BJ
108 rp->rcb_flags &= ~RAW_ADDR;
109 if (rp->rcb_socket->so_state & SS_USERGONE)
110 raw_detach(rp);
111}
112
113/*
114 * Associate a peer's address with a
115 * raw connection block.
116 */
117raw_connaddr(rp, addr)
118 struct rawcb *rp;
119 struct sockaddr *addr;
120{
121COUNT(RAW_CONNADDR);
668cc26d 122 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_addr, sizeof(struct sockaddr));
785d93ac
BJ
123 rp->rcb_flags |= RAW_ADDR;
124}