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

Cache object: eda2cd6012885389b061b9c8c1dd6d45


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