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         struct ddpcb *ddp;
   79         int error = 0;
   80         
   81         ddp = sotoddpcb(so);
   82         KASSERT(ddp == NULL, ("ddp_attach: ddp != NULL"));
   83 
   84         /*
   85          * Allocate socket buffer space first so that it's present
   86          * before first use.
   87          */
   88         error = soreserve(so, ddp_sendspace, ddp_recvspace);
   89         if (error)
   90                 return (error);
   91 
   92         DDP_LIST_XLOCK();
   93         error = at_pcballoc(so);
   94         DDP_LIST_XUNLOCK();
   95         return (error);
   96 }
   97 
   98 static void
   99 ddp_detach(struct socket *so)
  100 {
  101         struct ddpcb *ddp;
  102         
  103         ddp = sotoddpcb(so);
  104         KASSERT(ddp != NULL, ("ddp_detach: ddp == NULL"));
  105 
  106         DDP_LIST_XLOCK();
  107         DDP_LOCK(ddp);
  108         at_pcbdetach(so, ddp);
  109         DDP_LIST_XUNLOCK();
  110 }
  111 
  112 static int      
  113 ddp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
  114 {
  115         struct ddpcb *ddp;
  116         int error = 0;
  117         
  118         ddp = sotoddpcb(so);
  119         KASSERT(ddp != NULL, ("ddp_bind: ddp == NULL"));
  120 
  121         DDP_LIST_XLOCK();
  122         DDP_LOCK(ddp);
  123         error = at_pcbsetaddr(ddp, nam, td);
  124         DDP_UNLOCK(ddp);
  125         DDP_LIST_XUNLOCK();
  126         return (error);
  127 }
  128     
  129 static int
  130 ddp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
  131 {
  132         struct ddpcb *ddp;
  133         int error = 0;
  134         
  135         ddp = sotoddpcb(so);
  136         KASSERT(ddp != NULL, ("ddp_connect: ddp == NULL"));
  137 
  138         DDP_LIST_XLOCK();
  139         DDP_LOCK(ddp);
  140         if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) {
  141                 DDP_UNLOCK(ddp);
  142                 DDP_LIST_XUNLOCK();
  143                 return (EISCONN);
  144         }
  145 
  146         error = at_pcbconnect( ddp, nam, td );
  147         DDP_UNLOCK(ddp);
  148         DDP_LIST_XUNLOCK();
  149         if (error == 0)
  150                 soisconnected(so);
  151         return (error);
  152 }
  153 
  154 static int
  155 ddp_disconnect(struct socket *so)
  156 {
  157         struct ddpcb *ddp;
  158         
  159         ddp = sotoddpcb(so);
  160         KASSERT(ddp != NULL, ("ddp_disconnect: ddp == NULL"));
  161 
  162         DDP_LOCK(ddp);
  163         if (ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE) {
  164                 DDP_UNLOCK(ddp);
  165                 return (ENOTCONN);
  166         }
  167 
  168         at_pcbdisconnect(ddp);
  169         ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE;
  170         DDP_UNLOCK(ddp);
  171         soisdisconnected(so);
  172         return (0);
  173 }
  174 
  175 static int
  176 ddp_shutdown(struct socket *so)
  177 {
  178         struct ddpcb    *ddp;
  179 
  180         ddp = sotoddpcb(so);
  181         KASSERT(ddp != NULL, ("ddp_shutdown: ddp == NULL"));
  182 
  183         socantsendmore(so);
  184         return (0);
  185 }
  186 
  187 static int
  188 ddp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  189     struct mbuf *control, struct thread *td)
  190 {
  191         struct ddpcb *ddp;
  192         int error = 0;
  193         
  194         ddp = sotoddpcb(so);
  195         KASSERT(ddp != NULL, ("ddp_send: ddp == NULL"));
  196 
  197         if (control && control->m_len)
  198                 return (EINVAL);
  199 
  200         if (addr != NULL) {
  201                 DDP_LIST_XLOCK();
  202                 DDP_LOCK(ddp);
  203                 if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) {
  204                         error = EISCONN;
  205                         goto out;
  206                 }
  207 
  208                 error = at_pcbconnect(ddp, addr, td);
  209                 if (error == 0) {
  210                         error = ddp_output(m, so);
  211                         at_pcbdisconnect(ddp);
  212                 }
  213 out:
  214                 DDP_UNLOCK(ddp);
  215                 DDP_LIST_XUNLOCK();
  216         } else {
  217                 DDP_LOCK(ddp);
  218                 if (ddp->ddp_fsat.sat_port == ATADDR_ANYPORT)
  219                         error = ENOTCONN;
  220                 else
  221                         error = ddp_output(m, so);
  222                 DDP_UNLOCK(ddp);
  223         }
  224         return (error);
  225 }
  226 
  227 /*
  228  * XXXRW: This is never called because we only invoke abort on stream
  229  * protocols.
  230  */
  231 static void
  232 ddp_abort(struct socket *so)
  233 {
  234         struct ddpcb    *ddp;
  235         
  236         ddp = sotoddpcb(so);
  237         KASSERT(ddp != NULL, ("ddp_abort: ddp == NULL"));
  238 
  239         DDP_LOCK(ddp);
  240         at_pcbdisconnect(ddp);
  241         DDP_UNLOCK(ddp);
  242         soisdisconnected(so);
  243 }
  244 
  245 static void
  246 ddp_close(struct socket *so)
  247 {
  248         struct ddpcb    *ddp;
  249         
  250         ddp = sotoddpcb(so);
  251         KASSERT(ddp != NULL, ("ddp_close: ddp == NULL"));
  252 
  253         DDP_LOCK(ddp);
  254         at_pcbdisconnect(ddp);
  255         DDP_UNLOCK(ddp);
  256         soisdisconnected(so);
  257 }
  258 
  259 void 
  260 ddp_init(void)
  261 {
  262 
  263         atintrq1.ifq_maxlen = IFQ_MAXLEN;
  264         atintrq2.ifq_maxlen = IFQ_MAXLEN;
  265         aarpintrq.ifq_maxlen = IFQ_MAXLEN;
  266         mtx_init(&atintrq1.ifq_mtx, "at1_inq", NULL, MTX_DEF);
  267         mtx_init(&atintrq2.ifq_mtx, "at2_inq", NULL, MTX_DEF);
  268         mtx_init(&aarpintrq.ifq_mtx, "aarp_inq", NULL, MTX_DEF);
  269         DDP_LIST_LOCK_INIT();
  270         netisr_register(NETISR_ATALK1, at1intr, &atintrq1, NETISR_MPSAFE);
  271         netisr_register(NETISR_ATALK2, at2intr, &atintrq2, NETISR_MPSAFE);
  272         netisr_register(NETISR_AARP, aarpintr, &aarpintrq, NETISR_MPSAFE);
  273 }
  274 
  275 #if 0
  276 static void 
  277 ddp_clean(void)
  278 {
  279         struct ddpcp    *ddp;
  280 
  281         for (ddp = ddpcb_list; ddp != NULL; ddp = ddp->ddp_next)
  282                 at_pcbdetach(ddp->ddp_socket, ddp);
  283         DDP_LIST_LOCK_DESTROY();
  284 }
  285 #endif
  286 
  287 static int
  288 at_getpeeraddr(struct socket *so, struct sockaddr **nam)
  289 {
  290 
  291         return (EOPNOTSUPP);
  292 }
  293 
  294 static int
  295 at_getsockaddr(struct socket *so, struct sockaddr **nam)
  296 {
  297         struct ddpcb    *ddp;
  298 
  299         ddp = sotoddpcb(so);
  300         KASSERT(ddp != NULL, ("at_getsockaddr: ddp == NULL"));
  301 
  302         DDP_LOCK(ddp);
  303         at_sockaddr(ddp, nam);
  304         DDP_UNLOCK(ddp);
  305         return (0);
  306 }
  307 
  308 struct pr_usrreqs ddp_usrreqs = {
  309         .pru_abort =            ddp_abort,
  310         .pru_attach =           ddp_attach,
  311         .pru_bind =             ddp_bind,
  312         .pru_connect =          ddp_connect,
  313         .pru_control =          at_control,
  314         .pru_detach =           ddp_detach,
  315         .pru_disconnect =       ddp_disconnect,
  316         .pru_peeraddr =         at_getpeeraddr,
  317         .pru_send =             ddp_send,
  318         .pru_shutdown =         ddp_shutdown,
  319         .pru_sockaddr =         at_getsockaddr,
  320         .pru_close =            ddp_close,
  321 };

Cache object: 88ba7cdd8475fc899db2736aaf4725d8


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