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$
   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                                         soroverflow(last);
  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                         soroverflow(last);
  116                         m_freem(m);
  117                 } else
  118                         sorwakeup(last);
  119         } else
  120                 m_freem(m);
  121         mtx_unlock(&rawcb_mtx);
  122 }
  123 
  124 /*ARGSUSED*/
  125 void
  126 raw_ctlinput(int cmd, struct sockaddr *arg, void *dummy)
  127 {
  128 
  129         if (cmd < 0 || cmd >= PRC_NCMDS)
  130                 return;
  131         /* INCOMPLETE */
  132 }
  133 
  134 static void
  135 raw_uabort(struct socket *so)
  136 {
  137 
  138         KASSERT(sotorawcb(so) != NULL, ("raw_uabort: rp == NULL"));
  139 
  140         soisdisconnected(so);
  141 }
  142 
  143 static void
  144 raw_uclose(struct socket *so)
  145 {
  146 
  147         KASSERT(sotorawcb(so) != NULL, ("raw_uabort: rp == NULL"));
  148 
  149         soisdisconnected(so);
  150 }
  151 
  152 /* pru_accept is EOPNOTSUPP */
  153 
  154 static int
  155 raw_uattach(struct socket *so, int proto, struct thread *td)
  156 {
  157         int error;
  158 
  159         /*
  160          * Implementors of raw sockets will already have allocated the PCB,
  161          * so it must be non-NULL here.
  162          */
  163         KASSERT(sotorawcb(so) != NULL, ("raw_uattach: so_pcb == NULL"));
  164 
  165         if (td != NULL) {
  166                 error = priv_check(td, PRIV_NET_RAW);
  167                 if (error)
  168                         return (error);
  169         }
  170         return (raw_attach(so, proto));
  171 }
  172 
  173 static int
  174 raw_ubind(struct socket *so, struct sockaddr *nam, struct thread *td)
  175 {
  176 
  177         return (EINVAL);
  178 }
  179 
  180 static int
  181 raw_uconnect(struct socket *so, struct sockaddr *nam, struct thread *td)
  182 {
  183 
  184         return (EINVAL);
  185 }
  186 
  187 /* pru_connect2 is EOPNOTSUPP */
  188 /* pru_control is EOPNOTSUPP */
  189 
  190 static void
  191 raw_udetach(struct socket *so)
  192 {
  193         struct rawcb *rp = sotorawcb(so);
  194 
  195         KASSERT(rp != NULL, ("raw_udetach: rp == NULL"));
  196 
  197         raw_detach(rp);
  198 }
  199 
  200 static int
  201 raw_udisconnect(struct socket *so)
  202 {
  203 
  204         KASSERT(sotorawcb(so) != NULL, ("raw_udisconnect: rp == NULL"));
  205 
  206         return (ENOTCONN);
  207 }
  208 
  209 /* pru_listen is EOPNOTSUPP */
  210 
  211 static int
  212 raw_upeeraddr(struct socket *so, struct sockaddr **nam)
  213 {
  214 
  215         KASSERT(sotorawcb(so) != NULL, ("raw_upeeraddr: rp == NULL"));
  216 
  217         return (ENOTCONN);
  218 }
  219 
  220 /* pru_rcvd is EOPNOTSUPP */
  221 /* pru_rcvoob is EOPNOTSUPP */
  222 
  223 static int
  224 raw_usend(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
  225     struct mbuf *control, struct thread *td)
  226 {
  227 
  228         KASSERT(sotorawcb(so) != NULL, ("raw_usend: rp == NULL"));
  229 
  230         if ((flags & PRUS_OOB) || (control && control->m_len)) {
  231                 if (m != NULL)
  232                         m_freem(m);
  233                 if (control != NULL)
  234                         m_freem(control);
  235                 return (EOPNOTSUPP);
  236         }
  237 
  238         /*
  239          * For historical (bad?) reasons, we effectively ignore the address
  240          * argument to sendto(2).  Perhaps we should return an error instead?
  241          */
  242         return ((*so->so_proto->pr_output)(m, so));
  243 }
  244 
  245 /* pru_sense is null */
  246 
  247 static int
  248 raw_ushutdown(struct socket *so)
  249 {
  250 
  251         KASSERT(sotorawcb(so) != NULL, ("raw_ushutdown: rp == NULL"));
  252 
  253         socantsendmore(so);
  254         return (0);
  255 }
  256 
  257 static int
  258 raw_usockaddr(struct socket *so, struct sockaddr **nam)
  259 {
  260 
  261         KASSERT(sotorawcb(so) != NULL, ("raw_usockaddr: rp == NULL"));
  262 
  263         return (EINVAL);
  264 }
  265 
  266 struct pr_usrreqs raw_usrreqs = {
  267         .pru_abort =            raw_uabort,
  268         .pru_attach =           raw_uattach,
  269         .pru_bind =             raw_ubind,
  270         .pru_connect =          raw_uconnect,
  271         .pru_detach =           raw_udetach, 
  272         .pru_disconnect =       raw_udisconnect,
  273         .pru_peeraddr =         raw_upeeraddr,
  274         .pru_send =             raw_usend,
  275         .pru_shutdown =         raw_ushutdown,
  276         .pru_sockaddr =         raw_usockaddr,
  277         .pru_close =            raw_uclose,
  278 };

Cache object: 74f491912474db842a2ab7e72895d82a


[ 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.