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/netatalk/ddp_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) 2004-2005 Robert N. M. Watson
    3  * 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  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * Copyright (c) 1990, 1994 Regents of The University of Michigan.
   27  * All Rights Reserved.
   28  *
   29  * Permission to use, copy, modify, and distribute this software and
   30  * its documentation for any purpose and without fee is hereby granted,
   31  * provided that the above copyright notice appears in all copies and
   32  * that both that copyright notice and this permission notice appear
   33  * in supporting documentation, and that the name of The University
   34  * of Michigan not be used in advertising or publicity pertaining to
   35  * distribution of the software without specific, written prior
   36  * permission. This software is supplied as is without expressed or
   37  * implied warranties of any kind.
   38  *
   39  * This product includes software developed by the University of
   40  * California, Berkeley and its contributors.
   41  *
   42  *      Research Systems Unix Group
   43  *      The University of Michigan
   44  *      c/o Wesley Craig
   45  *      535 W. William Street
   46  *      Ann Arbor, Michigan
   47  *      +1-313-764-2278
   48  *      netatalk@umich.edu
   49  *
   50  * $FreeBSD$
   51  */
   52 
   53 #include <sys/param.h>
   54 #include <sys/systm.h>
   55 #include <sys/malloc.h>
   56 #include <sys/mbuf.h>
   57 #include <sys/socket.h>
   58 #include <sys/socketvar.h>
   59 #include <sys/protosw.h>
   60 #include <net/if.h>
   61 #include <net/route.h>
   62 #include <net/netisr.h>
   63 
   64 #include <netatalk/at.h>
   65 #include <netatalk/at_var.h>
   66 #include <netatalk/ddp_var.h>
   67 #include <netatalk/ddp_pcb.h>
   68 #include <netatalk/at_extern.h>
   69 
   70 static u_long   ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */
   71 static u_long   ddp_recvspace = 10 * (587 + sizeof(struct sockaddr_at));
   72 
   73 static struct ifqueue atintrq1, atintrq2, aarpintrq;
   74 
   75 static int
   76 ddp_attach(struct socket *so, int proto, struct thread *td)
   77 {
   78         int error = 0;
   79         
   80         KASSERT(sotoddpcb(so) == NULL, ("ddp_attach: ddp != NULL"));
   81 
   82         /*
   83          * Allocate socket buffer space first so that it's present
   84          * before first use.
   85          */
   86         error = soreserve(so, ddp_sendspace, ddp_recvspace);
   87         if (error)
   88                 return (error);
   89 
   90         DDP_LIST_XLOCK();
   91         error = at_pcballoc(so);
   92         DDP_LIST_XUNLOCK();
   93         return (error);
   94 }
   95 
   96 static void
   97 ddp_detach(struct socket *so)
   98 {
   99         struct ddpcb *ddp;
  100         
  101         ddp = sotoddpcb(so);
  102         KASSERT(ddp != NULL, ("ddp_detach: ddp == NULL"));
  103 
  104         DDP_LIST_XLOCK();
  105         DDP_LOCK(ddp);
  106         at_pcbdetach(so, ddp);
  107         DDP_LIST_XUNLOCK();
  108 }
  109 
  110 static int      
  111 ddp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
  112 {
  113         struct ddpcb *ddp;
  114         int error = 0;
  115         
  116         ddp = sotoddpcb(so);
  117         KASSERT(ddp != NULL, ("ddp_bind: ddp == NULL"));
  118 
  119         DDP_LIST_XLOCK();
  120         DDP_LOCK(ddp);
  121         error = at_pcbsetaddr(ddp, nam, td);
  122         DDP_UNLOCK(ddp);
  123         DDP_LIST_XUNLOCK();
  124         return (error);
  125 }
  126     
  127 static int
  128 ddp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
  129 {
  130         struct ddpcb *ddp;
  131         int error = 0;
  132         
  133         ddp = sotoddpcb(so);
  134         KASSERT(ddp != NULL, ("ddp_connect: ddp == NULL"));
  135 
  136         DDP_LIST_XLOCK();
  137         DDP_LOCK(ddp);
  138         if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) {
  139                 DDP_UNLOCK(ddp);
  140                 DDP_LIST_XUNLOCK();
  141                 return (EISCONN);
  142         }
  143 
  144         error = at_pcbconnect( ddp, nam, td );
  145         DDP_UNLOCK(ddp);
  146         DDP_LIST_XUNLOCK();
  147         if (error == 0)
  148                 soisconnected(so);
  149         return (error);
  150 }
  151 
  152 static int
  153 ddp_disconnect(struct socket *so)
  154 {
  155         struct ddpcb *ddp;
  156         
  157         ddp = sotoddpcb(so);
  158         KASSERT(ddp != NULL, ("ddp_disconnect: ddp == NULL"));
  159 
  160         DDP_LOCK(ddp);
  161         if (ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE) {
  162                 DDP_UNLOCK(ddp);
  163                 return (ENOTCONN);
  164         }
  165 
  166         at_pcbdisconnect(ddp);
  167         ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE;
  168         DDP_UNLOCK(ddp);
  169         soisdisconnected(so);
  170         return (0);
  171 }
  172 
  173 static int
  174 ddp_shutdown(struct socket *so)
  175 {
  176 
  177         KASSERT(sotoddpcb(so) != NULL, ("ddp_shutdown: ddp == NULL"));
  178 
  179         socantsendmore(so);
  180         return (0);
  181 }
  182 
  183 static int
  184 ddp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  185     struct mbuf *control, struct thread *td)
  186 {
  187         struct ddpcb *ddp;
  188         int error = 0;
  189         
  190         ddp = sotoddpcb(so);
  191         KASSERT(ddp != NULL, ("ddp_send: ddp == NULL"));
  192 
  193         if (control && control->m_len)
  194                 return (EINVAL);
  195 
  196         if (addr != NULL) {
  197                 DDP_LIST_XLOCK();
  198                 DDP_LOCK(ddp);
  199                 if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) {
  200                         error = EISCONN;
  201                         goto out;
  202                 }
  203 
  204                 error = at_pcbconnect(ddp, addr, td);
  205                 if (error == 0) {
  206                         error = ddp_output(m, so);
  207                         at_pcbdisconnect(ddp);
  208                 }
  209 out:
  210                 DDP_UNLOCK(ddp);
  211                 DDP_LIST_XUNLOCK();
  212         } else {
  213                 DDP_LOCK(ddp);
  214                 if (ddp->ddp_fsat.sat_port == ATADDR_ANYPORT)
  215                         error = ENOTCONN;
  216                 else
  217                         error = ddp_output(m, so);
  218                 DDP_UNLOCK(ddp);
  219         }
  220         return (error);
  221 }
  222 
  223 /*
  224  * XXXRW: This is never called because we only invoke abort on stream
  225  * protocols.
  226  */
  227 static void
  228 ddp_abort(struct socket *so)
  229 {
  230         struct ddpcb    *ddp;
  231         
  232         ddp = sotoddpcb(so);
  233         KASSERT(ddp != NULL, ("ddp_abort: ddp == NULL"));
  234 
  235         DDP_LOCK(ddp);
  236         at_pcbdisconnect(ddp);
  237         DDP_UNLOCK(ddp);
  238         soisdisconnected(so);
  239 }
  240 
  241 static void
  242 ddp_close(struct socket *so)
  243 {
  244         struct ddpcb    *ddp;
  245         
  246         ddp = sotoddpcb(so);
  247         KASSERT(ddp != NULL, ("ddp_close: ddp == NULL"));
  248 
  249         DDP_LOCK(ddp);
  250         at_pcbdisconnect(ddp);
  251         DDP_UNLOCK(ddp);
  252         soisdisconnected(so);
  253 }
  254 
  255 void 
  256 ddp_init(void)
  257 {
  258 
  259         atintrq1.ifq_maxlen = IFQ_MAXLEN;
  260         atintrq2.ifq_maxlen = IFQ_MAXLEN;
  261         aarpintrq.ifq_maxlen = IFQ_MAXLEN;
  262         mtx_init(&atintrq1.ifq_mtx, "at1_inq", NULL, MTX_DEF);
  263         mtx_init(&atintrq2.ifq_mtx, "at2_inq", NULL, MTX_DEF);
  264         mtx_init(&aarpintrq.ifq_mtx, "aarp_inq", NULL, MTX_DEF);
  265         DDP_LIST_LOCK_INIT();
  266         netisr_register(NETISR_ATALK1, at1intr, &atintrq1, NETISR_MPSAFE);
  267         netisr_register(NETISR_ATALK2, at2intr, &atintrq2, NETISR_MPSAFE);
  268         netisr_register(NETISR_AARP, aarpintr, &aarpintrq, NETISR_MPSAFE);
  269 }
  270 
  271 #if 0
  272 static void 
  273 ddp_clean(void)
  274 {
  275         struct ddpcp    *ddp;
  276 
  277         for (ddp = ddpcb_list; ddp != NULL; ddp = ddp->ddp_next)
  278                 at_pcbdetach(ddp->ddp_socket, ddp);
  279         DDP_LIST_LOCK_DESTROY();
  280 }
  281 #endif
  282 
  283 static int
  284 at_getpeeraddr(struct socket *so, struct sockaddr **nam)
  285 {
  286 
  287         return (EOPNOTSUPP);
  288 }
  289 
  290 static int
  291 at_getsockaddr(struct socket *so, struct sockaddr **nam)
  292 {
  293         struct ddpcb    *ddp;
  294 
  295         ddp = sotoddpcb(so);
  296         KASSERT(ddp != NULL, ("at_getsockaddr: ddp == NULL"));
  297 
  298         DDP_LOCK(ddp);
  299         at_sockaddr(ddp, nam);
  300         DDP_UNLOCK(ddp);
  301         return (0);
  302 }
  303 
  304 struct pr_usrreqs ddp_usrreqs = {
  305         .pru_abort =            ddp_abort,
  306         .pru_attach =           ddp_attach,
  307         .pru_bind =             ddp_bind,
  308         .pru_connect =          ddp_connect,
  309         .pru_control =          at_control,
  310         .pru_detach =           ddp_detach,
  311         .pru_disconnect =       ddp_disconnect,
  312         .pru_peeraddr =         at_getpeeraddr,
  313         .pru_send =             ddp_send,
  314         .pru_shutdown =         ddp_shutdown,
  315         .pru_sockaddr =         at_getsockaddr,
  316         .pru_close =            ddp_close,
  317 };

Cache object: 0423e344f1d2ec5ce5963247aa9bddcc


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