The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net/raw_usrreq.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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: releng/12.0/sys/net/raw_usrreq.c 326023 2017-11-20 19:43:44Z pfg $
   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 };

Cache object: 89d00b8c9ef8f735801783c925cb4468


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.