]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net/raw_usrreq.c
sysctl(9): Fix a few mandoc related issues
[FreeBSD/FreeBSD.git] / sys / net / raw_usrreq.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1980, 1986, 1993
5  *      The Regents of the University of California.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *      @(#)raw_usrreq.c        8.1 (Berkeley) 6/10/93
33  * $FreeBSD$
34  */
35
36 #include <sys/param.h>
37 #include <sys/kernel.h>
38 #include <sys/lock.h>
39 #include <sys/malloc.h>
40 #include <sys/mbuf.h>
41 #include <sys/mutex.h>
42 #include <sys/priv.h>
43 #include <sys/protosw.h>
44 #include <sys/signalvar.h>
45 #include <sys/socket.h>
46 #include <sys/socketvar.h>
47 #include <sys/sx.h>
48 #include <sys/systm.h>
49
50 #include <net/if.h>
51 #include <net/vnet.h>
52 #include <net/raw_cb.h>
53
54 MTX_SYSINIT(rawcb_mtx, &rawcb_mtx, "rawcb", MTX_DEF);
55
56 /*
57  * Initialize raw connection block q.
58  */
59 void
60 raw_init(void)
61 {
62
63         LIST_INIT(&V_rawcb_list);
64 }
65
66 /*
67  * Raw protocol input routine.  Find the socket associated with the packet(s)
68  * and move them over.  If nothing exists for this packet, drop it.
69  */
70 /*
71  * Raw protocol interface.
72  */
73 void
74 raw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src)
75 {
76
77         return (raw_input_ext(m0, proto, src, NULL));
78 }
79
80 void
81 raw_input_ext(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src,
82     raw_input_cb_fn cb)
83 {
84         struct rawcb *rp;
85         struct mbuf *m = m0;
86         struct socket *last;
87
88         last = NULL;
89         mtx_lock(&rawcb_mtx);
90         LIST_FOREACH(rp, &V_rawcb_list, list) {
91                 if (rp->rcb_proto.sp_family != proto->sp_family)
92                         continue;
93                 if (rp->rcb_proto.sp_protocol  &&
94                     rp->rcb_proto.sp_protocol != proto->sp_protocol)
95                         continue;
96                 if (cb != NULL && (*cb)(m, proto, src, rp) != 0)
97                         continue;
98                 if (last) {
99                         struct mbuf *n;
100                         n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
101                         if (n) {
102                                 if (sbappendaddr(&last->so_rcv, src,
103                                     n, (struct mbuf *)0) == 0)
104                                         /* should notify about lost packet */
105                                         m_freem(n);
106                                 else
107                                         sorwakeup(last);
108                         }
109                 }
110                 last = rp->rcb_socket;
111         }
112         if (last) {
113                 if (sbappendaddr(&last->so_rcv, src,
114                     m, (struct mbuf *)0) == 0)
115                         m_freem(m);
116                 else
117                         sorwakeup(last);
118         } else
119                 m_freem(m);
120         mtx_unlock(&rawcb_mtx);
121 }
122
123 /*ARGSUSED*/
124 void
125 raw_ctlinput(int cmd, struct sockaddr *arg, void *dummy)
126 {
127
128         if (cmd < 0 || cmd >= PRC_NCMDS)
129                 return;
130         /* INCOMPLETE */
131 }
132
133 static void
134 raw_uabort(struct socket *so)
135 {
136
137         KASSERT(sotorawcb(so) != NULL, ("raw_uabort: rp == NULL"));
138
139         soisdisconnected(so);
140 }
141
142 static void
143 raw_uclose(struct socket *so)
144 {
145
146         KASSERT(sotorawcb(so) != NULL, ("raw_uabort: rp == NULL"));
147
148         soisdisconnected(so);
149 }
150
151 /* pru_accept is EOPNOTSUPP */
152
153 static int
154 raw_uattach(struct socket *so, int proto, struct thread *td)
155 {
156         int error;
157
158         /*
159          * Implementors of raw sockets will already have allocated the PCB,
160          * so it must be non-NULL here.
161          */
162         KASSERT(sotorawcb(so) != NULL, ("raw_uattach: so_pcb == NULL"));
163
164         if (td != NULL) {
165                 error = priv_check(td, PRIV_NET_RAW);
166                 if (error)
167                         return (error);
168         }
169         return (raw_attach(so, proto));
170 }
171
172 static int
173 raw_ubind(struct socket *so, struct sockaddr *nam, struct thread *td)
174 {
175
176         return (EINVAL);
177 }
178
179 static int
180 raw_uconnect(struct socket *so, struct sockaddr *nam, struct thread *td)
181 {
182
183         return (EINVAL);
184 }
185
186 /* pru_connect2 is EOPNOTSUPP */
187 /* pru_control is EOPNOTSUPP */
188
189 static void
190 raw_udetach(struct socket *so)
191 {
192         struct rawcb *rp = sotorawcb(so);
193
194         KASSERT(rp != NULL, ("raw_udetach: rp == NULL"));
195
196         raw_detach(rp);
197 }
198
199 static int
200 raw_udisconnect(struct socket *so)
201 {
202
203         KASSERT(sotorawcb(so) != NULL, ("raw_udisconnect: rp == NULL"));
204
205         return (ENOTCONN);
206 }
207
208 /* pru_listen is EOPNOTSUPP */
209
210 static int
211 raw_upeeraddr(struct socket *so, struct sockaddr **nam)
212 {
213
214         KASSERT(sotorawcb(so) != NULL, ("raw_upeeraddr: rp == NULL"));
215
216         return (ENOTCONN);
217 }
218
219 /* pru_rcvd is EOPNOTSUPP */
220 /* pru_rcvoob is EOPNOTSUPP */
221
222 static int
223 raw_usend(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
224     struct mbuf *control, struct thread *td)
225 {
226
227         KASSERT(sotorawcb(so) != NULL, ("raw_usend: rp == NULL"));
228
229         if ((flags & PRUS_OOB) || (control && control->m_len)) {
230                 if (m != NULL)
231                         m_freem(m);
232                 if (control != NULL)
233                         m_freem(control);
234                 return (EOPNOTSUPP);
235         }
236
237         /*
238          * For historical (bad?) reasons, we effectively ignore the address
239          * argument to sendto(2).  Perhaps we should return an error instead?
240          */
241         return ((*so->so_proto->pr_output)(m, so));
242 }
243
244 /* pru_sense is null */
245
246 static int
247 raw_ushutdown(struct socket *so)
248 {
249
250         KASSERT(sotorawcb(so) != NULL, ("raw_ushutdown: rp == NULL"));
251
252         socantsendmore(so);
253         return (0);
254 }
255
256 static int
257 raw_usockaddr(struct socket *so, struct sockaddr **nam)
258 {
259
260         KASSERT(sotorawcb(so) != NULL, ("raw_usockaddr: rp == NULL"));
261
262         return (EINVAL);
263 }
264
265 struct pr_usrreqs raw_usrreqs = {
266         .pru_abort =            raw_uabort,
267         .pru_attach =           raw_uattach,
268         .pru_bind =             raw_ubind,
269         .pru_connect =          raw_uconnect,
270         .pru_detach =           raw_udetach, 
271         .pru_disconnect =       raw_udisconnect,
272         .pru_peeraddr =         raw_upeeraddr,
273         .pru_send =             raw_usend,
274         .pru_shutdown =         raw_ushutdown,
275         .pru_sockaddr =         raw_usockaddr,
276         .pru_close =            raw_uclose,
277 };