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

Cache object: b8f748a028a41df2c34c5bc6f4cead4b


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