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 Robert N. M. Watson
    3  * Copyright (c) 1990,1994 Regents of The University of Michigan.
    4  * All Rights Reserved.  See COPYRIGHT.
    5  *
    6  * $FreeBSD: releng/5.3/sys/netatalk/ddp_usrreq.c 136588 2004-10-16 08:43:07Z cvs2svn $
    7  */
    8 
    9 #include <sys/param.h>
   10 #include <sys/systm.h>
   11 #include <sys/malloc.h>
   12 #include <sys/mbuf.h>
   13 #include <sys/socket.h>
   14 #include <sys/socketvar.h>
   15 #include <sys/protosw.h>
   16 #include <net/if.h>
   17 #include <net/route.h>
   18 #include <net/netisr.h>
   19 
   20 #include <netatalk/at.h>
   21 #include <netatalk/at_var.h>
   22 #include <netatalk/ddp_var.h>
   23 #include <netatalk/ddp_pcb.h>
   24 #include <netatalk/at_extern.h>
   25 
   26 static u_long   ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */
   27 static u_long   ddp_recvspace = 10 * (587 + sizeof(struct sockaddr_at));
   28 
   29 static struct ifqueue atintrq1, atintrq2, aarpintrq;
   30 
   31 static int
   32 ddp_attach(struct socket *so, int proto, struct thread *td)
   33 {
   34         struct ddpcb    *ddp;
   35         int             error = 0;
   36         
   37         ddp = sotoddpcb(so);
   38         if (ddp != NULL)
   39                 return (EINVAL);
   40 
   41         /*
   42          * Allocate socket buffer space first so that it's present
   43          * before first use.
   44          */
   45         error = soreserve(so, ddp_sendspace, ddp_recvspace);
   46         if (error)
   47                 return (error);
   48 
   49         DDP_LIST_XLOCK();
   50         error = at_pcballoc(so);
   51         DDP_LIST_XUNLOCK();
   52         return (error);
   53 }
   54 
   55 static int
   56 ddp_detach(struct socket *so)
   57 {
   58         struct ddpcb    *ddp;
   59         
   60         ddp = sotoddpcb(so);
   61         if (ddp == NULL)
   62             return (EINVAL);
   63 
   64         DDP_LIST_XLOCK();
   65         DDP_LOCK(ddp);
   66         at_pcbdetach(so, ddp);
   67         DDP_LIST_XUNLOCK();
   68         return (0);
   69 }
   70 
   71 static int      
   72 ddp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
   73 {
   74         struct ddpcb    *ddp;
   75         int             error = 0;
   76         
   77         ddp = sotoddpcb(so);
   78         if (ddp == NULL) {
   79             return (EINVAL);
   80         }
   81         DDP_LIST_XLOCK();
   82         DDP_LOCK(ddp);
   83         error = at_pcbsetaddr(ddp, nam, td);
   84         DDP_UNLOCK(ddp);
   85         DDP_LIST_XUNLOCK();
   86         return (error);
   87 }
   88     
   89 static int
   90 ddp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
   91 {
   92         struct ddpcb    *ddp;
   93         int             error = 0;
   94         
   95         ddp = sotoddpcb(so);
   96         if (ddp == NULL) {
   97             return (EINVAL);
   98         }
   99 
  100         DDP_LIST_XLOCK();
  101         DDP_LOCK(ddp);
  102         if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) {
  103             DDP_UNLOCK(ddp);
  104             DDP_LIST_XUNLOCK();
  105             return (EISCONN);
  106         }
  107 
  108         error = at_pcbconnect( ddp, nam, td );
  109         DDP_UNLOCK(ddp);
  110         DDP_LIST_XUNLOCK();
  111         if (error == 0)
  112             soisconnected(so);
  113         return (error);
  114 }
  115 
  116 static int
  117 ddp_disconnect(struct socket *so)
  118 {
  119 
  120         struct ddpcb    *ddp;
  121         
  122         ddp = sotoddpcb(so);
  123         if (ddp == NULL) {
  124             return (EINVAL);
  125         }
  126         DDP_LOCK(ddp);
  127         if (ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE) {
  128             DDP_UNLOCK(ddp);
  129             return (ENOTCONN);
  130         }
  131 
  132         at_pcbdisconnect(ddp);
  133         ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE;
  134         DDP_UNLOCK(ddp);
  135         soisdisconnected(so);
  136         return (0);
  137 }
  138 
  139 static int
  140 ddp_shutdown(struct socket *so)
  141 {
  142         struct ddpcb    *ddp;
  143 
  144         ddp = sotoddpcb(so);
  145         if (ddp == NULL) {
  146                 return (EINVAL);
  147         }
  148         socantsendmore(so);
  149         return (0);
  150 }
  151 
  152 static int
  153 ddp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  154             struct mbuf *control, struct thread *td)
  155 {
  156         struct ddpcb    *ddp;
  157         int             error = 0;
  158         
  159         ddp = sotoddpcb(so);
  160         if (ddp == NULL) {
  161                 return (EINVAL);
  162         }
  163 
  164         if (control && control->m_len) {
  165                 return (EINVAL);
  166         }
  167 
  168         if (addr != NULL) {
  169                 DDP_LIST_XLOCK();
  170                 DDP_LOCK(ddp);
  171                 if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) {
  172                         error = EISCONN;
  173                         goto out;
  174                 }
  175 
  176                 error = at_pcbconnect(ddp, addr, td);
  177                 if (error == 0) {
  178                         error = ddp_output(m, so);
  179                         at_pcbdisconnect(ddp);
  180                 }
  181 out:
  182                 DDP_UNLOCK(ddp);
  183                 DDP_LIST_XUNLOCK();
  184         } else {
  185                 DDP_LOCK(ddp);
  186                 if (ddp->ddp_fsat.sat_port == ATADDR_ANYPORT)
  187                         error = ENOTCONN;
  188                 else
  189                         error = ddp_output(m, so);
  190                 DDP_UNLOCK(ddp);
  191         }
  192         return (error);
  193 }
  194 
  195 static int
  196 ddp_abort(struct socket *so)
  197 {
  198         struct ddpcb    *ddp;
  199         
  200         ddp = sotoddpcb(so);
  201         if (ddp == NULL) {
  202                 return (EINVAL);
  203         }
  204         DDP_LIST_XLOCK();
  205         DDP_LOCK(ddp);
  206         at_pcbdetach(so, ddp);
  207         DDP_LIST_XUNLOCK();
  208         return (0);
  209 }
  210 
  211 void 
  212 ddp_init(void)
  213 {
  214         atintrq1.ifq_maxlen = IFQ_MAXLEN;
  215         atintrq2.ifq_maxlen = IFQ_MAXLEN;
  216         aarpintrq.ifq_maxlen = IFQ_MAXLEN;
  217         mtx_init(&atintrq1.ifq_mtx, "at1_inq", NULL, MTX_DEF);
  218         mtx_init(&atintrq2.ifq_mtx, "at2_inq", NULL, MTX_DEF);
  219         mtx_init(&aarpintrq.ifq_mtx, "aarp_inq", NULL, MTX_DEF);
  220         DDP_LIST_LOCK_INIT();
  221         netisr_register(NETISR_ATALK1, at1intr, &atintrq1, 0);
  222         netisr_register(NETISR_ATALK2, at2intr, &atintrq2, 0);
  223         netisr_register(NETISR_AARP, aarpintr, &aarpintrq, 0);
  224 }
  225 
  226 #if 0
  227 static void 
  228 ddp_clean(void)
  229 {
  230     struct ddpcb        *ddp;
  231 
  232     for (ddp = ddpcb_list; ddp != NULL; ddp = ddp->ddp_next) {
  233         at_pcbdetach(ddp->ddp_socket, ddp);
  234     }
  235     DDP_LIST_LOCK_DESTROY();
  236 }
  237 #endif
  238 
  239 static int
  240 at_setpeeraddr(struct socket *so, struct sockaddr **nam)
  241 {
  242         return (EOPNOTSUPP);
  243 }
  244 
  245 static int
  246 at_setsockaddr(struct socket *so, struct sockaddr **nam)
  247 {
  248         struct ddpcb    *ddp;
  249 
  250         ddp = sotoddpcb(so);
  251         if (ddp == NULL) {
  252             return (EINVAL);
  253         }
  254         DDP_LOCK(ddp);
  255         at_sockaddr(ddp, nam);
  256         DDP_UNLOCK(ddp);
  257         return (0);
  258 }
  259 
  260 struct pr_usrreqs ddp_usrreqs = {
  261         ddp_abort,
  262         pru_accept_notsupp,
  263         ddp_attach,
  264         ddp_bind,
  265         ddp_connect,
  266         pru_connect2_notsupp,
  267         at_control,
  268         ddp_detach,
  269         ddp_disconnect,
  270         pru_listen_notsupp,
  271         at_setpeeraddr,
  272         pru_rcvd_notsupp,
  273         pru_rcvoob_notsupp,
  274         ddp_send,
  275         pru_sense_null,
  276         ddp_shutdown,
  277         at_setsockaddr,
  278         sosend,
  279         soreceive,
  280         sopoll,
  281         pru_sosetlabel_null
  282 };

Cache object: 2759e9317e9a89d15976a9268c84e863


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