Commit | Line | Data |
---|---|---|
cb1c44c2 | 1 | /* |
1810611d | 2 | * Copyright (c) 1980, 1986 Regents of the University of California. |
5b519e94 | 3 | * All rights reserved. |
cb1c44c2 | 4 | * |
5b519e94 | 5 | * Redistribution and use in source and binary forms are permitted |
50c7758a KB |
6 | * provided that the above copyright notice and this paragraph are |
7 | * duplicated in all such forms and that any documentation, | |
8 | * advertising materials, and other materials related to such | |
9 | * distribution and use acknowledge that the software was developed | |
10 | * by the University of California, Berkeley. The name of the | |
11 | * University may not be used to endorse or promote products derived | |
12 | * from this software without specific prior written permission. | |
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
15 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
5b519e94 | 16 | * |
50c7758a | 17 | * @(#)raw_cb.c 7.6 (Berkeley) %G% |
cb1c44c2 | 18 | */ |
785d93ac | 19 | |
20666ad3 JB |
20 | #include "param.h" |
21 | #include "systm.h" | |
22 | #include "mbuf.h" | |
23 | #include "socket.h" | |
24 | #include "socketvar.h" | |
829f867e MK |
25 | #include "domain.h" |
26 | #include "protosw.h" | |
20666ad3 | 27 | #include "errno.h" |
f4d55810 | 28 | |
20666ad3 JB |
29 | #include "if.h" |
30 | #include "route.h" | |
31 | #include "raw_cb.h" | |
9e9695c7 | 32 | #include "../netinet/in.h" |
f4d55810 | 33 | |
2e62d00d | 34 | #include "../machine/mtpr.h" |
785d93ac BJ |
35 | |
36 | /* | |
37 | * Routines to manage the raw protocol control blocks. | |
38 | * | |
39 | * TODO: | |
40 | * hash lookups by protocol family/protocol + address family | |
ee787340 | 41 | * take care of unique address problems per AF? |
1e25d807 | 42 | * redo address binding to allow wildcards |
785d93ac BJ |
43 | */ |
44 | ||
45 | /* | |
46 | * Allocate a control block and a nominal amount | |
47 | * of buffer space for the socket. | |
48 | */ | |
829f867e | 49 | raw_attach(so, proto) |
785d93ac | 50 | register struct socket *so; |
829f867e | 51 | int proto; |
785d93ac BJ |
52 | { |
53 | struct mbuf *m; | |
54 | register struct rawcb *rp; | |
785d93ac | 55 | |
cce93e4b | 56 | m = m_getclr(M_DONTWAIT, MT_PCB); |
785d93ac BJ |
57 | if (m == 0) |
58 | return (ENOBUFS); | |
4c645d38 | 59 | if (sbreserve(&so->so_snd, (u_long) RAWSNDQ) == 0) |
785d93ac | 60 | goto bad; |
4c645d38 | 61 | if (sbreserve(&so->so_rcv, (u_long) RAWRCVQ) == 0) |
785d93ac BJ |
62 | goto bad2; |
63 | rp = mtod(m, struct rawcb *); | |
64 | rp->rcb_socket = so; | |
785d93ac BJ |
65 | so->so_pcb = (caddr_t)rp; |
66 | rp->rcb_pcb = 0; | |
829f867e MK |
67 | rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family; |
68 | rp->rcb_proto.sp_protocol = proto; | |
69 | insque(rp, &rawcb); | |
785d93ac BJ |
70 | return (0); |
71 | bad2: | |
72 | sbrelease(&so->so_snd); | |
73 | bad: | |
74 | (void) m_free(m); | |
75 | return (ENOBUFS); | |
76 | } | |
77 | ||
78 | /* | |
79 | * Detach the raw connection block and discard | |
80 | * socket resources. | |
81 | */ | |
82 | raw_detach(rp) | |
83 | register struct rawcb *rp; | |
84 | { | |
85 | struct socket *so = rp->rcb_socket; | |
86 | ||
10c543d7 MK |
87 | if (rp->rcb_route.ro_rt) |
88 | rtfree(rp->rcb_route.ro_rt); | |
785d93ac BJ |
89 | so->so_pcb = 0; |
90 | sofree(so); | |
91 | remque(rp); | |
82acad77 | 92 | if (rp->rcb_options) |
ffcd9f47 | 93 | m_freem(rp->rcb_options); |
4053be18 | 94 | m_freem(dtom(rp)); |
785d93ac BJ |
95 | } |
96 | ||
97 | /* | |
98 | * Disconnect and possibly release resources. | |
99 | */ | |
100 | raw_disconnect(rp) | |
101 | struct rawcb *rp; | |
102 | { | |
4053be18 | 103 | |
126472ab | 104 | rp->rcb_flags &= ~RAW_FADDR; |
f832270b | 105 | if (rp->rcb_socket->so_state & SS_NOFDREF) |
785d93ac BJ |
106 | raw_detach(rp); |
107 | } | |
108 | ||
14fa60f2 BJ |
109 | raw_bind(so, nam) |
110 | register struct socket *so; | |
111 | struct mbuf *nam; | |
112 | { | |
113 | struct sockaddr *addr = mtod(nam, struct sockaddr *); | |
14fa60f2 BJ |
114 | register struct rawcb *rp; |
115 | ||
116 | if (ifnet == 0) | |
117 | return (EADDRNOTAVAIL); | |
14fa60f2 BJ |
118 | /* BEGIN DUBIOUS */ |
119 | /* | |
120 | * Should we verify address not already in use? | |
121 | * Some say yes, others no. | |
122 | */ | |
123 | switch (addr->sa_family) { | |
124 | ||
799358ac | 125 | #ifdef INET |
14fa60f2 | 126 | case AF_IMPLINK: |
9e9695c7 | 127 | case AF_INET: { |
14fa60f2 | 128 | if (((struct sockaddr_in *)addr)->sin_addr.s_addr && |
cba69651 | 129 | ifa_ifwithaddr(addr) == 0) |
14fa60f2 BJ |
130 | return (EADDRNOTAVAIL); |
131 | break; | |
9e9695c7 SL |
132 | } |
133 | #endif | |
14fa60f2 | 134 | |
14fa60f2 BJ |
135 | default: |
136 | return (EAFNOSUPPORT); | |
137 | } | |
14fa60f2 | 138 | /* END DUBIOUS */ |
af0b24db | 139 | rp = sotorawcb(so); |
14fa60f2 BJ |
140 | bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr)); |
141 | rp->rcb_flags |= RAW_LADDR; | |
142 | return (0); | |
143 | } | |
144 | ||
785d93ac BJ |
145 | /* |
146 | * Associate a peer's address with a | |
147 | * raw connection block. | |
148 | */ | |
14fa60f2 | 149 | raw_connaddr(rp, nam) |
785d93ac | 150 | struct rawcb *rp; |
14fa60f2 | 151 | struct mbuf *nam; |
785d93ac | 152 | { |
14fa60f2 BJ |
153 | struct sockaddr *addr = mtod(nam, struct sockaddr *); |
154 | ||
126472ab SL |
155 | bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr)); |
156 | rp->rcb_flags |= RAW_FADDR; | |
785d93ac | 157 | } |