Commit | Line | Data |
---|---|---|
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 | */ | |
28 | raw_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 | ||
36 | COUNT(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); |
78 | bad2: | |
79 | sbrelease(&so->so_snd); | |
80 | bad: | |
81 | (void) m_free(m); | |
82 | return (ENOBUFS); | |
83 | } | |
84 | ||
85 | /* | |
86 | * Detach the raw connection block and discard | |
87 | * socket resources. | |
88 | */ | |
89 | raw_detach(rp) | |
90 | register struct rawcb *rp; | |
91 | { | |
92 | struct socket *so = rp->rcb_socket; | |
93 | ||
94 | COUNT(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 | */ | |
104 | raw_disconnect(rp) | |
105 | struct rawcb *rp; | |
106 | { | |
107 | COUNT(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 | */ | |
117 | raw_connaddr(rp, addr) | |
118 | struct rawcb *rp; | |
119 | struct sockaddr *addr; | |
120 | { | |
121 | COUNT(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 | } |