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  * Copyright (c) 1980, 1986, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 4. Neither the name of the University nor the names of its contributors
   14  *    may be used to endorse or promote products derived from this software
   15  *    without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  *      @(#)raw_usrreq.c        8.1 (Berkeley) 6/10/93
   30  * $FreeBSD: src/sys/net/raw_usrreq.c,v 1.34.2.2 2005/01/31 23:26:23 imp Exp $
   31  */
   32 
   33 #include <sys/param.h>
   34 #include <sys/kernel.h>
   35 #include <sys/lock.h>
   36 #include <sys/malloc.h>
   37 #include <sys/mbuf.h>
   38 #include <sys/mutex.h>
   39 #include <sys/protosw.h>
   40 #include <sys/signalvar.h>
   41 #include <sys/socket.h>
   42 #include <sys/socketvar.h>
   43 #include <sys/sx.h>
   44 #include <sys/systm.h>
   45 
   46 #include <net/raw_cb.h>
   47 
   48 MTX_SYSINIT(rawcb_mtx, &rawcb_mtx, "rawcb", MTX_DEF);
   49 
   50 /*
   51  * Initialize raw connection block q.
   52  */
   53 void
   54 raw_init()
   55 {
   56 
   57         LIST_INIT(&rawcb_list);
   58 }
   59 
   60 
   61 /*
   62  * Raw protocol input routine.  Find the socket
   63  * associated with the packet(s) and move them over.  If
   64  * nothing exists for this packet, drop it.
   65  */
   66 /*
   67  * Raw protocol interface.
   68  */
   69 void
   70 raw_input(m0, proto, src, dst)
   71         struct mbuf *m0;
   72         register struct sockproto *proto;
   73         struct sockaddr *src, *dst;
   74 {
   75         register struct rawcb *rp;
   76         register struct mbuf *m = m0;
   77         struct socket *last;
   78 
   79         last = 0;
   80         mtx_lock(&rawcb_mtx);
   81         LIST_FOREACH(rp, &rawcb_list, list) {
   82                 if (rp->rcb_proto.sp_family != proto->sp_family)
   83                         continue;
   84                 if (rp->rcb_proto.sp_protocol  &&
   85                     rp->rcb_proto.sp_protocol != proto->sp_protocol)
   86                         continue;
   87                 /*
   88                  * We assume the lower level routines have
   89                  * placed the address in a canonical format
   90                  * suitable for a structure comparison.
   91                  *
   92                  * Note that if the lengths are not the same
   93                  * the comparison will fail at the first byte.
   94                  */
   95 #define equal(a1, a2) \
   96   (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
   97                 if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
   98                         continue;
   99                 if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
  100                         continue;
  101                 if (last) {
  102                         struct mbuf *n;
  103                         n = m_copy(m, 0, (int)M_COPYALL);
  104                         if (n) {
  105                                 if (sbappendaddr(&last->so_rcv, src,
  106                                     n, (struct mbuf *)0) == 0)
  107                                         /* should notify about lost packet */
  108                                         m_freem(n);
  109                                 else {
  110                                         sorwakeup(last);
  111                                 }
  112                         }
  113                 }
  114                 last = rp->rcb_socket;
  115         }
  116         if (last) {
  117                 if (sbappendaddr(&last->so_rcv, src,
  118                     m, (struct mbuf *)0) == 0)
  119                         m_freem(m);
  120                 else {
  121                         sorwakeup(last);
  122                 }
  123         } else
  124                 m_freem(m);
  125         mtx_unlock(&rawcb_mtx);
  126 }
  127 
  128 /*ARGSUSED*/
  129 void
  130 raw_ctlinput(cmd, arg, dummy)
  131         int cmd;
  132         struct sockaddr *arg;
  133         void *dummy;
  134 {
  135 
  136         if (cmd < 0 || cmd >= PRC_NCMDS)
  137                 return;
  138         /* INCOMPLETE */
  139 }
  140 
  141 static int
  142 raw_uabort(struct socket *so)
  143 {
  144         struct rawcb *rp = sotorawcb(so);
  145 
  146         if (rp == 0)
  147                 return EINVAL;
  148         raw_disconnect(rp);
  149         soisdisconnected(so);
  150         ACCEPT_LOCK();
  151         SOCK_LOCK(so);
  152         sotryfree(so);
  153         return 0;
  154 }
  155 
  156 /* pru_accept is EOPNOTSUPP */
  157 
  158 static int
  159 raw_uattach(struct socket *so, int proto, struct thread *td)
  160 {
  161         struct rawcb *rp = sotorawcb(so);
  162         int error;
  163 
  164         if (rp == 0)
  165                 return EINVAL;
  166         if (td && (error = suser(td)) != 0)
  167                 return error;
  168         return raw_attach(so, proto);
  169 }
  170 
  171 static int
  172 raw_ubind(struct socket *so, struct sockaddr *nam, struct thread *td)
  173 {
  174         return EINVAL;
  175 }
  176 
  177 static int
  178 raw_uconnect(struct socket *so, struct sockaddr *nam, struct thread *td)
  179 {
  180         return EINVAL;
  181 }
  182 
  183 /* pru_connect2 is EOPNOTSUPP */
  184 /* pru_control is EOPNOTSUPP */
  185 
  186 static int
  187 raw_udetach(struct socket *so)
  188 {
  189         struct rawcb *rp = sotorawcb(so);
  190 
  191         if (rp == 0)
  192                 return EINVAL;
  193 
  194         raw_detach(rp);
  195         return 0;
  196 }
  197 
  198 static int
  199 raw_udisconnect(struct socket *so)
  200 {
  201         struct rawcb *rp = sotorawcb(so);
  202 
  203         if (rp == 0)
  204                 return EINVAL;
  205         if (rp->rcb_faddr == 0) {
  206                 return ENOTCONN;
  207         }
  208         raw_disconnect(rp);
  209         soisdisconnected(so);
  210         return 0;
  211 }
  212 
  213 /* pru_listen is EOPNOTSUPP */
  214 
  215 static int
  216 raw_upeeraddr(struct socket *so, struct sockaddr **nam)
  217 {
  218         struct rawcb *rp = sotorawcb(so);
  219 
  220         if (rp == 0)
  221                 return EINVAL;
  222         if (rp->rcb_faddr == 0) {
  223                 return ENOTCONN;
  224         }
  225         *nam = sodupsockaddr(rp->rcb_faddr, M_WAITOK);
  226         return 0;
  227 }
  228 
  229 /* pru_rcvd is EOPNOTSUPP */
  230 /* pru_rcvoob is EOPNOTSUPP */
  231 
  232 static int
  233 raw_usend(struct socket *so, int flags, struct mbuf *m,
  234           struct sockaddr *nam, struct mbuf *control, struct thread *td)
  235 {
  236         int error;
  237         struct rawcb *rp = sotorawcb(so);
  238 
  239         if (rp == 0) {
  240                 error = EINVAL;
  241                 goto release;
  242         }
  243 
  244         if (flags & PRUS_OOB) {
  245                 error = EOPNOTSUPP;
  246                 goto release;
  247         }
  248 
  249         if (control && control->m_len) {
  250                 error = EOPNOTSUPP;
  251                 goto release;
  252         }
  253         if (nam) {
  254                 if (rp->rcb_faddr) {
  255                         error = EISCONN;
  256                         goto release;
  257                 }
  258                 rp->rcb_faddr = nam;
  259         } else if (rp->rcb_faddr == 0) {
  260                 error = ENOTCONN;
  261                 goto release;
  262         }
  263         error = (*so->so_proto->pr_output)(m, so);
  264         m = NULL;
  265         if (nam)
  266                 rp->rcb_faddr = 0;
  267 release:
  268         if (m != NULL)
  269                 m_freem(m);
  270         return (error);
  271 }
  272 
  273 /* pru_sense is null */
  274 
  275 static int
  276 raw_ushutdown(struct socket *so)
  277 {
  278         struct rawcb *rp = sotorawcb(so);
  279 
  280         if (rp == 0)
  281                 return EINVAL;
  282         socantsendmore(so);
  283         return 0;
  284 }
  285 
  286 static int
  287 raw_usockaddr(struct socket *so, struct sockaddr **nam)
  288 {
  289         struct rawcb *rp = sotorawcb(so);
  290 
  291         if (rp == 0)
  292                 return EINVAL;
  293         if (rp->rcb_laddr == 0)
  294                 return EINVAL;
  295         *nam = sodupsockaddr(rp->rcb_laddr, M_WAITOK);
  296         return 0;
  297 }
  298 
  299 struct pr_usrreqs raw_usrreqs = {
  300         raw_uabort, pru_accept_notsupp, raw_uattach, raw_ubind, raw_uconnect,
  301         pru_connect2_notsupp, pru_control_notsupp, raw_udetach, 
  302         raw_udisconnect, pru_listen_notsupp, raw_upeeraddr, pru_rcvd_notsupp,
  303         pru_rcvoob_notsupp, raw_usend, pru_sense_null, raw_ushutdown,
  304         raw_usockaddr, sosend, soreceive, sopoll, pru_sosetlabel_null
  305 };

Cache object: 9c29c955ebd787892cebdb62e6d06711


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