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/netatm/atm_socket.c

Version: -  FREEBSD  -  FREEBSD10  -  FREEBSD9  -  FREEBSD92  -  FREEBSD91  -  FREEBSD90  -  FREEBSD8  -  FREEBSD82  -  FREEBSD81  -  FREEBSD80  -  FREEBSD7  -  FREEBSD74  -  FREEBSD73  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * ===================================
    3  * HARP  |  Host ATM Research Platform
    4  * ===================================
    5  *
    6  *
    7  * This Host ATM Research Platform ("HARP") file (the "Software") is
    8  * made available by Network Computing Services, Inc. ("NetworkCS")
    9  * "AS IS".  NetworkCS does not provide maintenance, improvements or
   10  * support of any kind.
   11  *
   12  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
   13  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
   14  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
   15  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
   16  * In no event shall NetworkCS be responsible for any damages, including
   17  * but not limited to consequential damages, arising from or relating to
   18  * any use of the Software or related support.
   19  *
   20  * Copyright 1994-1998 Network Computing Services, Inc.
   21  *
   22  * Copies of this Software may be made, however, the above copyright
   23  * notice must be reproduced on all copies.
   24  */
   25 
   26 /*
   27  * Core ATM Services
   28  * -----------------
   29  *
   30  * ATM common socket protocol processing
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD: src/sys/netatm/atm_socket.c,v 1.20.2.3 2005/03/07 13:08:04 rwatson Exp $");
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/malloc.h>
   39 #include <sys/socket.h>
   40 #include <sys/socketvar.h>
   41 #include <sys/syslog.h>
   42 #include <net/if.h>
   43 #include <netatm/port.h>
   44 #include <netatm/queue.h>
   45 #include <netatm/atm.h>
   46 #include <netatm/atm_sys.h>
   47 #include <netatm/atm_sap.h>
   48 #include <netatm/atm_cm.h>
   49 #include <netatm/atm_if.h>
   50 #include <netatm/atm_sigmgr.h>
   51 #include <netatm/atm_stack.h>
   52 #include <netatm/atm_pcb.h>
   53 #include <netatm/atm_var.h>
   54 
   55 
   56 /*
   57  * Local functions
   58  */
   59 
   60 
   61 /*
   62  * Local variables
   63  */
   64 static uma_zone_t atm_pcb_zone;
   65 
   66 static struct t_atm_cause       atm_sock_cause = {
   67         T_ATM_ITU_CODING,
   68         T_ATM_LOC_USER,
   69         T_ATM_CAUSE_UNSPECIFIED_NORMAL,
   70         {0, 0, 0, 0}
   71 };
   72 
   73 void
   74 atm_sock_init(void)
   75 {
   76 
   77         atm_pcb_zone = uma_zcreate("atm pcb", sizeof(Atm_pcb), NULL, NULL,
   78             NULL, NULL, UMA_ALIGN_PTR, 0);
   79         if (atm_pcb_zone == NULL)
   80                 panic("atm_sock_init: unable to initialize atm_pcb_zone");
   81 }
   82 
   83 /*
   84  * Allocate resources for a new ATM socket
   85  *
   86  * Called at splnet.
   87  *
   88  * Arguments:
   89  *      so      pointer to socket
   90  *      send    socket send buffer maximum
   91  *      recv    socket receive buffer maximum
   92  *
   93  * Returns:
   94  *      0       attach successful
   95  *      errno   attach failed - reason indicated
   96  *
   97  */
   98 int
   99 atm_sock_attach(so, send, recv)
  100         struct socket   *so;
  101         u_long          send;
  102         u_long          recv;
  103 {
  104         Atm_pcb         *atp = sotoatmpcb(so);
  105         int             err;
  106 
  107         /*
  108          * Make sure initialization has happened
  109          */
  110         if (!atm_init)
  111                 atm_initialize();
  112 
  113         /*
  114          * Make sure we're not already attached
  115          */
  116         if (atp)
  117                 return (EISCONN);
  118 
  119         /*
  120          * Reserve socket buffer space, if not already done
  121          */
  122         if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) {
  123                 err = soreserve(so, send, recv);
  124                 if (err)
  125                         return (err);
  126         }
  127 
  128         /*
  129          * Allocate and initialize our control block
  130          */
  131         atp = uma_zalloc(atm_pcb_zone, M_ZERO | M_NOWAIT);
  132         if (atp == NULL)
  133                 return (ENOMEM);
  134 
  135         atp->atp_socket = so;
  136         so->so_pcb = (caddr_t)atp;
  137         return (0);
  138 }
  139 
  140 
  141 /*
  142  * Detach from socket and free resources
  143  *
  144  * Called at splnet.
  145  *
  146  * Arguments:
  147  *      so      pointer to socket
  148  *
  149  * Returns:
  150  *      0       detach successful
  151  *      errno   detach failed - reason indicated
  152  *
  153  */
  154 int
  155 atm_sock_detach(so)
  156         struct socket   *so;
  157 {
  158         Atm_pcb         *atp = sotoatmpcb(so);
  159 
  160         /*
  161          * Make sure we're still attached
  162          */
  163         if (atp == NULL)
  164                 return (ENOTCONN);
  165 
  166         /*
  167          * Terminate any (possibly pending) connection
  168          */
  169         if (atp->atp_conn) {
  170                 (void) atm_sock_disconnect(so);
  171         }
  172 
  173         /*
  174          * Break links and free control blocks
  175          */
  176         ACCEPT_LOCK();
  177         SOCK_LOCK(so);
  178         so->so_pcb = NULL;
  179         sotryfree(so);
  180 
  181         uma_zfree(atm_pcb_zone, atp);
  182 
  183         return (0);
  184 }
  185 
  186 
  187 /*
  188  * Bind local address to socket
  189  *
  190  * Called at splnet.
  191  *
  192  * Arguments:
  193  *      so      pointer to socket
  194  *      addr    pointer to protocol address
  195  *
  196  * Returns:
  197  *      0       request processed
  198  *      errno   error processing request - reason indicated
  199  *
  200  */
  201 int
  202 atm_sock_bind(so, addr)
  203         struct socket   *so;
  204         struct sockaddr *addr;
  205 {
  206         Atm_pcb                 *atp = sotoatmpcb(so);
  207         Atm_attributes          attr;
  208         struct sockaddr_atm     *satm;
  209         struct t_atm_sap_addr   *sapadr;
  210         struct t_atm_sap_layer2 *sapl2;
  211         struct t_atm_sap_layer3 *sapl3;
  212         struct t_atm_sap_appl   *sapapl;
  213 
  214         /*
  215          * Make sure we're still attached
  216          */
  217         if (atp == NULL)
  218                 return (ENOTCONN);
  219 
  220         /*
  221          * Can't change local address once we've started connection process
  222          */
  223         if (atp->atp_conn != NULL)
  224                 return (EADDRNOTAVAIL);
  225 
  226         /*
  227          * Validate requested local address
  228          */
  229         satm = (struct sockaddr_atm *)addr;
  230         if (satm->satm_family != AF_ATM)
  231                 return (EAFNOSUPPORT);
  232 
  233         sapadr = &satm->satm_addr.t_atm_sap_addr;
  234         if (sapadr->SVE_tag_addr == T_ATM_PRESENT) {
  235                 if (sapadr->address_format == T_ATM_ENDSYS_ADDR) {
  236                         if (sapadr->SVE_tag_selector != T_ATM_PRESENT)
  237                                 return (EINVAL);
  238                 } else if (sapadr->address_format == T_ATM_E164_ADDR) {
  239                         if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
  240                                 return (EINVAL);
  241                 } else
  242                         return (EINVAL);
  243         } else if ((sapadr->SVE_tag_addr != T_ATM_ABSENT) &&
  244                    (sapadr->SVE_tag_addr != T_ATM_ANY))
  245                 return (EINVAL);
  246         if (sapadr->address_length > ATM_ADDR_LEN)
  247                 return (EINVAL);
  248 
  249         sapl2 = &satm->satm_addr.t_atm_sap_layer2;
  250         if (sapl2->SVE_tag == T_ATM_PRESENT) {
  251                 if ((sapl2->ID_type != T_ATM_SIMPLE_ID) &&
  252                     (sapl2->ID_type != T_ATM_USER_ID))
  253                         return (EINVAL);
  254         } else if ((sapl2->SVE_tag != T_ATM_ABSENT) &&
  255                    (sapl2->SVE_tag != T_ATM_ANY))
  256                 return (EINVAL);
  257 
  258         sapl3 = &satm->satm_addr.t_atm_sap_layer3;
  259         if (sapl3->SVE_tag == T_ATM_PRESENT) {
  260                 if ((sapl3->ID_type != T_ATM_SIMPLE_ID) &&
  261                     (sapl3->ID_type != T_ATM_IPI_ID) &&
  262                     (sapl3->ID_type != T_ATM_SNAP_ID) &&
  263                     (sapl3->ID_type != T_ATM_USER_ID))
  264                         return (EINVAL);
  265         } else if ((sapl3->SVE_tag != T_ATM_ABSENT) &&
  266                    (sapl3->SVE_tag != T_ATM_ANY))
  267                 return (EINVAL);
  268 
  269         sapapl = &satm->satm_addr.t_atm_sap_appl;
  270         if (sapapl->SVE_tag == T_ATM_PRESENT) {
  271                 if ((sapapl->ID_type != T_ATM_ISO_APP_ID) &&
  272                     (sapapl->ID_type != T_ATM_USER_APP_ID) &&
  273                     (sapapl->ID_type != T_ATM_VENDOR_APP_ID))
  274                         return (EINVAL);
  275         } else if ((sapapl->SVE_tag != T_ATM_ABSENT) &&
  276                    (sapapl->SVE_tag != T_ATM_ANY))
  277                 return (EINVAL);
  278 
  279         /*
  280          * Create temporary attributes list so that we can check out the
  281          * new bind parameters before we modify the socket's values;
  282          */
  283         attr = atp->atp_attr;
  284         attr.called.tag = sapadr->SVE_tag_addr;
  285         bcopy(&sapadr->address_format, &attr.called.addr, sizeof(Atm_addr));
  286 
  287         attr.blli.tag_l2 = sapl2->SVE_tag;
  288         if (sapl2->SVE_tag == T_ATM_PRESENT) {
  289                 attr.blli.v.layer_2_protocol.ID_type = sapl2->ID_type;
  290                 bcopy(&sapl2->ID, &attr.blli.v.layer_2_protocol.ID,
  291                         sizeof(attr.blli.v.layer_2_protocol.ID));
  292         }
  293 
  294         attr.blli.tag_l3 = sapl3->SVE_tag;
  295         if (sapl3->SVE_tag == T_ATM_PRESENT) {
  296                 attr.blli.v.layer_3_protocol.ID_type = sapl3->ID_type;
  297                 bcopy(&sapl3->ID, &attr.blli.v.layer_3_protocol.ID,
  298                         sizeof(attr.blli.v.layer_3_protocol.ID));
  299         }
  300 
  301         attr.bhli.tag = sapapl->SVE_tag;
  302         if (sapapl->SVE_tag == T_ATM_PRESENT) {
  303                 attr.bhli.v.ID_type = sapapl->ID_type;
  304                 bcopy(&sapapl->ID, &attr.bhli.v.ID,
  305                         sizeof(attr.bhli.v.ID));
  306         }
  307 
  308         /*
  309          * Make sure we have unique listening attributes
  310          */
  311         if (atm_cm_match(&attr, NULL) != NULL)
  312                 return (EADDRINUSE);
  313 
  314         /*
  315          * Looks good, save new attributes
  316          */
  317         atp->atp_attr = attr;
  318 
  319         return (0);
  320 }
  321 
  322 
  323 /*
  324  * Listen for incoming connections
  325  *
  326  * Called at splnet.
  327  *
  328  * Arguments:
  329  *      so      pointer to socket
  330  *      epp     pointer to endpoint definition structure
  331  *
  332  * Returns:
  333  *      0       request processed
  334  *      errno   error processing request - reason indicated
  335  *
  336  */
  337 int
  338 atm_sock_listen(so, epp)
  339         struct socket   *so;
  340         Atm_endpoint    *epp;
  341 {
  342         Atm_pcb         *atp = sotoatmpcb(so);
  343 
  344         /*
  345          * Make sure we're still attached
  346          */
  347         if (atp == NULL)
  348                 return (ENOTCONN);
  349 
  350         /*
  351          * Start listening for incoming calls
  352          */
  353         return (atm_cm_listen(so, epp, atp, &atp->atp_attr, &atp->atp_conn));
  354 }
  355 
  356 
  357 /*
  358  * Connect socket to peer
  359  *
  360  * Called at splnet.
  361  *
  362  * Arguments:
  363  *      so      pointer to socket
  364  *      addr    pointer to protocol address
  365  *      epp     pointer to endpoint definition structure
  366  *
  367  * Returns:
  368  *      0       request processed
  369  *      errno   error processing request - reason indicated
  370  *
  371  */
  372 int
  373 atm_sock_connect(so, addr, epp)
  374         struct socket   *so;
  375         struct sockaddr *addr;
  376         Atm_endpoint    *epp;
  377 {
  378         Atm_pcb         *atp = sotoatmpcb(so);
  379         struct sockaddr_atm     *satm;
  380         struct t_atm_sap_addr   *sapadr;
  381         struct t_atm_sap_layer2 *sapl2;
  382         struct t_atm_sap_layer3 *sapl3;
  383         struct t_atm_sap_appl   *sapapl;
  384         int             err;
  385 
  386         /*
  387          * Make sure we're still attached
  388          */
  389         if (atp == NULL)
  390                 return (ENOTCONN);
  391 
  392         /*
  393          * Validate requested peer address
  394          */
  395         satm = (struct sockaddr_atm *)addr;
  396         if (satm->satm_family != AF_ATM)
  397                 return (EAFNOSUPPORT);
  398 
  399         sapadr = &satm->satm_addr.t_atm_sap_addr;
  400         if (sapadr->SVE_tag_addr != T_ATM_PRESENT)
  401                 return (EINVAL);
  402         if (sapadr->address_format == T_ATM_ENDSYS_ADDR) {
  403                 if (sapadr->SVE_tag_selector != T_ATM_PRESENT)
  404                         return (EINVAL);
  405         } else if (sapadr->address_format == T_ATM_E164_ADDR) {
  406                 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
  407                         return (EINVAL);
  408         } else if (sapadr->address_format == T_ATM_PVC_ADDR) {
  409                 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
  410                         return (EINVAL);
  411         } else
  412                 return (EINVAL);
  413         if (sapadr->address_length > ATM_ADDR_LEN)
  414                 return (EINVAL);
  415 
  416         sapl2 = &satm->satm_addr.t_atm_sap_layer2;
  417         if (sapl2->SVE_tag == T_ATM_PRESENT) {
  418                 if ((sapl2->ID_type != T_ATM_SIMPLE_ID) &&
  419                     (sapl2->ID_type != T_ATM_USER_ID))
  420                         return (EINVAL);
  421         } else if (sapl2->SVE_tag != T_ATM_ABSENT)
  422                 return (EINVAL);
  423 
  424         sapl3 = &satm->satm_addr.t_atm_sap_layer3;
  425         if (sapl3->SVE_tag == T_ATM_PRESENT) {
  426                 if ((sapl3->ID_type != T_ATM_SIMPLE_ID) &&
  427                     (sapl3->ID_type != T_ATM_IPI_ID) &&
  428                     (sapl3->ID_type != T_ATM_SNAP_ID) &&
  429                     (sapl3->ID_type != T_ATM_USER_ID))
  430                         return (EINVAL);
  431         } else if (sapl3->SVE_tag != T_ATM_ABSENT)
  432                 return (EINVAL);
  433 
  434         sapapl = &satm->satm_addr.t_atm_sap_appl;
  435         if (sapapl->SVE_tag == T_ATM_PRESENT) {
  436                 if ((sapapl->ID_type != T_ATM_ISO_APP_ID) &&
  437                     (sapapl->ID_type != T_ATM_USER_APP_ID) &&
  438                     (sapapl->ID_type != T_ATM_VENDOR_APP_ID))
  439                         return (EINVAL);
  440         } else if (sapapl->SVE_tag != T_ATM_ABSENT)
  441                 return (EINVAL);
  442 
  443         /*
  444          * Select an outgoing network interface
  445          */
  446         if (atp->atp_attr.nif == NULL) {
  447                 struct atm_pif  *pip;
  448 
  449                 for (pip = atm_interface_head; pip != NULL;
  450                                                 pip = pip->pif_next) {
  451                         if (pip->pif_nif != NULL) {
  452                                 atp->atp_attr.nif = pip->pif_nif;
  453                                 break;
  454                         }
  455                 }
  456                 if (atp->atp_attr.nif == NULL)
  457                         return (ENXIO);
  458         }
  459 
  460         /*
  461          * Set supplied connection attributes
  462          */
  463         atp->atp_attr.called.tag = T_ATM_PRESENT;
  464         bcopy(&sapadr->address_format, &atp->atp_attr.called.addr,
  465                         sizeof(Atm_addr));
  466 
  467         atp->atp_attr.blli.tag_l2 = sapl2->SVE_tag;
  468         if (sapl2->SVE_tag == T_ATM_PRESENT) {
  469                 atp->atp_attr.blli.v.layer_2_protocol.ID_type = sapl2->ID_type;
  470                 bcopy(&sapl2->ID, &atp->atp_attr.blli.v.layer_2_protocol.ID,
  471                         sizeof(atp->atp_attr.blli.v.layer_2_protocol.ID));
  472         }
  473 
  474         atp->atp_attr.blli.tag_l3 = sapl3->SVE_tag;
  475         if (sapl3->SVE_tag == T_ATM_PRESENT) {
  476                 atp->atp_attr.blli.v.layer_3_protocol.ID_type = sapl3->ID_type;
  477                 bcopy(&sapl3->ID, &atp->atp_attr.blli.v.layer_3_protocol.ID,
  478                         sizeof(atp->atp_attr.blli.v.layer_3_protocol.ID));
  479         }
  480 
  481         atp->atp_attr.bhli.tag = sapapl->SVE_tag;
  482         if (sapapl->SVE_tag == T_ATM_PRESENT) {
  483                 atp->atp_attr.bhli.v.ID_type = sapapl->ID_type;
  484                 bcopy(&sapapl->ID, &atp->atp_attr.bhli.v.ID,
  485                         sizeof(atp->atp_attr.bhli.v.ID));
  486         }
  487 
  488         /*
  489          * We're finally ready to initiate the ATM connection
  490          */
  491         soisconnecting(so);
  492         atm_sock_stat.as_connreq[atp->atp_type]++;
  493         err = atm_cm_connect(epp, atp, &atp->atp_attr, &atp->atp_conn);
  494         if (err == 0) {
  495                 /*
  496                  * Connection is setup
  497                  */
  498                 atm_sock_stat.as_conncomp[atp->atp_type]++;
  499                 soisconnected(so);
  500 
  501         } else if (err == EINPROGRESS) {
  502                 /*
  503                  * We've got to wait for a connected event
  504                  */
  505                 err = 0;
  506 
  507         } else {
  508                 /*
  509                  * Call failed...
  510                  */
  511                 atm_sock_stat.as_connfail[atp->atp_type]++;
  512                 soisdisconnected(so);
  513         }
  514 
  515         return (err);
  516 }
  517 
  518 
  519 /*
  520  * Disconnect connected socket
  521  *
  522  * Called at splnet.
  523  *
  524  * Arguments:
  525  *      so      pointer to socket
  526  *
  527  * Returns:
  528  *      0       request processed
  529  *      errno   error processing request - reason indicated
  530  *
  531  */
  532 int
  533 atm_sock_disconnect(so)
  534         struct socket   *so;
  535 {
  536         Atm_pcb         *atp = sotoatmpcb(so);
  537         struct t_atm_cause      *cause;
  538         int             err;
  539 
  540         /*
  541          * Make sure we're still attached
  542          */
  543         if (atp == NULL)
  544                 return (ENOTCONN);
  545 
  546         /*
  547          * Release the ATM connection
  548          */
  549         if (atp->atp_conn) {
  550                 if (atp->atp_attr.cause.tag == T_ATM_PRESENT)
  551                         cause = &atp->atp_attr.cause.v;
  552                 else
  553                         cause = &atm_sock_cause;
  554                 err = atm_cm_release(atp->atp_conn, cause);
  555                 if (err)
  556                         log(LOG_ERR, "atm_sock_disconnect: release fail (%d)\n",
  557                                 err);
  558                 atm_sock_stat.as_connrel[atp->atp_type]++;
  559                 atp->atp_conn = NULL;
  560         }
  561 
  562         soisdisconnected(so);
  563 
  564         return (0);
  565 }
  566 
  567 
  568 /*
  569  * Retrieve local socket address
  570  *
  571  * Called at splnet.
  572  *
  573  * Arguments:
  574  *      so      pointer to socket
  575  *      addr    pointer to pointer to contain protocol address
  576  *
  577  * Returns:
  578  *      0       request processed
  579  *      errno   error processing request - reason indicated
  580  *
  581  */
  582 int
  583 atm_sock_sockaddr(so, addr)
  584         struct socket   *so;
  585         struct sockaddr **addr;
  586 {
  587         struct sockaddr_atm     *satm;
  588         struct t_atm_sap_addr   *saddr;
  589         Atm_pcb         *atp = sotoatmpcb(so);
  590 
  591         /*
  592          * Return local interface address, if known
  593          */
  594         satm = malloc(sizeof(*satm), M_SONAME, M_WAITOK | M_ZERO);
  595         if (satm == NULL)
  596                 return (ENOMEM);
  597 
  598         satm->satm_family = AF_ATM;
  599         satm->satm_len = sizeof(*satm);
  600 
  601         saddr = &satm->satm_addr.t_atm_sap_addr;
  602         if (atp->atp_attr.nif && atp->atp_attr.nif->nif_pif->pif_siginst) {
  603                 saddr->SVE_tag_addr = T_ATM_PRESENT;
  604                 ATM_ADDR_SEL_COPY(
  605                         &atp->atp_attr.nif->nif_pif->pif_siginst->si_addr,
  606                         atp->atp_attr.nif->nif_sel, saddr);
  607                 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
  608                         saddr->SVE_tag_selector = T_ATM_PRESENT;
  609                 else
  610                         saddr->SVE_tag_selector = T_ATM_ABSENT;
  611         } else {
  612                 saddr->SVE_tag_addr = T_ATM_ABSENT;
  613                 saddr->SVE_tag_selector = T_ATM_ABSENT;
  614                 saddr->address_format = T_ATM_ABSENT;
  615         }
  616         satm->satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_ABSENT;
  617         satm->satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
  618         satm->satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
  619 
  620         *addr = (struct sockaddr *)satm;
  621         return (0);
  622 }
  623 
  624 
  625 /*
  626  * Retrieve peer socket address
  627  *
  628  * Called at splnet.
  629  *
  630  * Arguments:
  631  *      so      pointer to socket
  632  *      addr    pointer to pointer to contain protocol address
  633  *
  634  * Returns:
  635  *      0       request processed
  636  *      errno   error processing request - reason indicated
  637  *
  638  */
  639 int
  640 atm_sock_peeraddr(so, addr)
  641         struct socket   *so;
  642         struct sockaddr **addr;
  643 {
  644         struct sockaddr_atm     *satm;
  645         struct t_atm_sap_addr   *saddr;
  646         Atm_pcb         *atp = sotoatmpcb(so);
  647         Atm_connvc      *cvp;
  648 
  649         /*
  650          * Return remote address, if known
  651          */
  652         satm = malloc(sizeof(*satm), M_SONAME, M_WAITOK | M_ZERO);
  653         if (satm == NULL)
  654                 return (ENOMEM);
  655 
  656         satm->satm_family = AF_ATM;
  657         satm->satm_len = sizeof(*satm);
  658         saddr = &satm->satm_addr.t_atm_sap_addr;
  659         if (so->so_state & SS_ISCONNECTED) {
  660                 cvp = atp->atp_conn->co_connvc;
  661                 saddr->SVE_tag_addr = T_ATM_PRESENT;
  662                 if (cvp->cvc_flags & CVCF_CALLER) {
  663                         ATM_ADDR_COPY(&cvp->cvc_attr.called.addr, saddr);
  664                 } else {
  665                         if (cvp->cvc_attr.calling.tag == T_ATM_PRESENT) {
  666                                 ATM_ADDR_COPY(&cvp->cvc_attr.calling.addr,
  667                                                         saddr);
  668                         } else {
  669                                 saddr->SVE_tag_addr = T_ATM_ABSENT;
  670                                 saddr->address_format = T_ATM_ABSENT;
  671                         }
  672                 }
  673                 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
  674                         saddr->SVE_tag_selector = T_ATM_PRESENT;
  675                 else
  676                         saddr->SVE_tag_selector = T_ATM_ABSENT;
  677         } else {
  678                 saddr->SVE_tag_addr = T_ATM_ABSENT;
  679                 saddr->SVE_tag_selector = T_ATM_ABSENT;
  680                 saddr->address_format = T_ATM_ABSENT;
  681         }
  682         satm->satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_ABSENT;
  683         satm->satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
  684         satm->satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
  685 
  686         *addr = (struct sockaddr *)satm;
  687         return (0);
  688 }
  689 
  690 
  691 /*
  692  * Common setsockopt processing
  693  *
  694  * Called at splnet.
  695  *
  696  * Arguments:
  697  *      so      pointer to socket
  698  *      sopt    pointer to socket option info
  699  *      atp     pointer to ATM PCB
  700  *
  701  * Returns:
  702  *      0       request processed
  703  *      errno   error processing request - reason indicated
  704  *
  705  */
  706 int
  707 atm_sock_setopt(so, sopt, atp)
  708         struct socket   *so;
  709         struct sockopt  *sopt;
  710         Atm_pcb         *atp;
  711 {
  712         int     err = 0;
  713         union {
  714                 struct t_atm_aal5       aal5;
  715                 struct t_atm_traffic    trf;
  716                 struct t_atm_bearer     brr;
  717                 struct t_atm_bhli       bhl;
  718                 struct t_atm_blli       bll;
  719                 Atm_addr                addr;
  720                 struct t_atm_cause      cau;
  721                 struct t_atm_qos        qos;
  722                 struct t_atm_transit    trn;
  723                 struct t_atm_net_intf   nif;
  724                 struct t_atm_llc        llc;
  725                 struct t_atm_app_name   appn;
  726         } p;
  727 
  728 #define MAXVAL(bits)    ((1 << bits) - 1)
  729 #define MAXMASK(bits)   (~MAXVAL(bits))
  730 
  731         switch (sopt->sopt_name) {
  732 
  733         case T_ATM_AAL5:
  734                 err = sooptcopyin(sopt, &p.aal5, sizeof p.aal5, sizeof p.aal5);
  735                 if (err)
  736                         break;
  737                 if ((p.aal5.forward_max_SDU_size != T_ATM_ABSENT) &&
  738                     (p.aal5.forward_max_SDU_size & MAXMASK(16)))
  739                         return (EINVAL);
  740                 if ((p.aal5.backward_max_SDU_size != T_ATM_ABSENT) &&
  741                     (p.aal5.backward_max_SDU_size & MAXMASK(16)))
  742                         return (EINVAL);
  743                 if ((p.aal5.SSCS_type != T_ATM_ABSENT) &&
  744                     (p.aal5.SSCS_type != T_ATM_NULL) &&
  745                     (p.aal5.SSCS_type != T_ATM_SSCS_SSCOP_REL) &&
  746                     (p.aal5.SSCS_type != T_ATM_SSCS_SSCOP_UNREL) &&
  747                     (p.aal5.SSCS_type != T_ATM_SSCS_FR))
  748                         return (EINVAL);
  749 
  750                 if ((p.aal5.forward_max_SDU_size == T_ATM_ABSENT) &&
  751                     (p.aal5.backward_max_SDU_size == T_ATM_ABSENT) &&
  752                     (p.aal5.SSCS_type == T_ATM_ABSENT))
  753                         atp->atp_attr.aal.tag = T_ATM_ABSENT;
  754                 else {
  755                         atp->atp_attr.aal.tag = T_ATM_PRESENT;
  756                         atp->atp_attr.aal.type = ATM_AAL5;
  757                         atp->atp_attr.aal.v.aal5 = p.aal5;
  758                 }
  759                 break;
  760 
  761         case T_ATM_TRAFFIC:
  762                 err = sooptcopyin(sopt, &p.trf, sizeof p.trf, sizeof p.trf);
  763                 if (err)
  764                         break;
  765                 if ((p.trf.forward.PCR_high_priority != T_ATM_ABSENT) &&
  766                     (p.trf.forward.PCR_high_priority & MAXMASK(24)))
  767                         return (EINVAL);
  768                 if (p.trf.forward.PCR_all_traffic & MAXMASK(24))
  769                         return (EINVAL);
  770                 if ((p.trf.forward.SCR_high_priority != T_ATM_ABSENT) &&
  771                     (p.trf.forward.SCR_high_priority & MAXMASK(24)))
  772                         return (EINVAL);
  773                 if ((p.trf.forward.SCR_all_traffic != T_ATM_ABSENT) &&
  774                     (p.trf.forward.SCR_all_traffic & MAXMASK(24)))
  775                         return (EINVAL);
  776                 if ((p.trf.forward.MBS_high_priority != T_ATM_ABSENT) &&
  777                     (p.trf.forward.MBS_high_priority & MAXMASK(24)))
  778                         return (EINVAL);
  779                 if ((p.trf.forward.MBS_all_traffic != T_ATM_ABSENT) &&
  780                     (p.trf.forward.MBS_all_traffic & MAXMASK(24)))
  781                         return (EINVAL);
  782                 if ((p.trf.forward.tagging != T_YES) &&
  783                     (p.trf.forward.tagging != T_NO))
  784                         return (EINVAL);
  785 
  786                 if ((p.trf.backward.PCR_high_priority != T_ATM_ABSENT) &&
  787                     (p.trf.backward.PCR_high_priority & MAXMASK(24)))
  788                         return (EINVAL);
  789                 if (p.trf.backward.PCR_all_traffic & MAXMASK(24))
  790                         return (EINVAL);
  791                 if ((p.trf.backward.SCR_high_priority != T_ATM_ABSENT) &&
  792                     (p.trf.backward.SCR_high_priority & MAXMASK(24)))
  793                         return (EINVAL);
  794                 if ((p.trf.backward.SCR_all_traffic != T_ATM_ABSENT) &&
  795                     (p.trf.backward.SCR_all_traffic & MAXMASK(24)))
  796                         return (EINVAL);
  797                 if ((p.trf.backward.MBS_high_priority != T_ATM_ABSENT) &&
  798                     (p.trf.backward.MBS_high_priority & MAXMASK(24)))
  799                         return (EINVAL);
  800                 if ((p.trf.backward.MBS_all_traffic != T_ATM_ABSENT) &&
  801                     (p.trf.backward.MBS_all_traffic & MAXMASK(24)))
  802                         return (EINVAL);
  803                 if ((p.trf.backward.tagging != T_YES) &&
  804                     (p.trf.backward.tagging != T_NO))
  805                         return (EINVAL);
  806                 if ((p.trf.best_effort != T_YES) &&
  807                     (p.trf.best_effort != T_NO))
  808                         return (EINVAL);
  809 
  810                 atp->atp_attr.traffic.tag = T_ATM_PRESENT;
  811                 atp->atp_attr.traffic.v = p.trf;
  812                 break;
  813 
  814         case T_ATM_BEARER_CAP:
  815                 err = sooptcopyin(sopt, &p.brr, sizeof p.brr, sizeof p.brr);
  816                 if (err)
  817                         break;
  818                 if ((p.brr.bearer_class != T_ATM_CLASS_A) &&
  819                     (p.brr.bearer_class != T_ATM_CLASS_C) &&
  820                     (p.brr.bearer_class != T_ATM_CLASS_X))
  821                         return (EINVAL);
  822                 if ((p.brr.traffic_type != T_ATM_NULL) &&
  823                     (p.brr.traffic_type != T_ATM_CBR) &&
  824                     (p.brr.traffic_type != T_ATM_VBR) &&
  825                     (p.brr.traffic_type != T_ATM_ABR) &&
  826                     (p.brr.traffic_type != T_ATM_UBR))
  827                         return (EINVAL);
  828                 if ((p.brr.timing_requirements != T_ATM_NULL) &&
  829                     (p.brr.timing_requirements != T_ATM_END_TO_END) &&
  830                     (p.brr.timing_requirements != T_ATM_NO_END_TO_END))
  831                         return (EINVAL);
  832                 if ((p.brr.clipping_susceptibility != T_NO) &&
  833                     (p.brr.clipping_susceptibility != T_YES))
  834                         return (EINVAL);
  835                 if ((p.brr.connection_configuration != T_ATM_1_TO_1) &&
  836                     (p.brr.connection_configuration != T_ATM_1_TO_MANY))
  837                         return (EINVAL);
  838 
  839                 atp->atp_attr.bearer.tag = T_ATM_PRESENT;
  840                 atp->atp_attr.bearer.v = p.brr;
  841                 break;
  842 
  843         case T_ATM_BHLI:
  844                 err = sooptcopyin(sopt, &p.bhl, sizeof p.bhl, sizeof p.bhl);
  845                 if (err)
  846                         break;
  847                 if ((p.bhl.ID_type != T_ATM_ABSENT) &&
  848                     (p.bhl.ID_type != T_ATM_ISO_APP_ID) &&
  849                     (p.bhl.ID_type != T_ATM_USER_APP_ID) &&
  850                     (p.bhl.ID_type != T_ATM_VENDOR_APP_ID))
  851                         return (EINVAL);
  852 
  853                 if (p.bhl.ID_type == T_ATM_ABSENT)
  854                         atp->atp_attr.bhli.tag = T_ATM_ABSENT;
  855                 else {
  856                         atp->atp_attr.bhli.tag = T_ATM_PRESENT;
  857                         atp->atp_attr.bhli.v = p.bhl;
  858                 }
  859                 break;
  860 
  861         case T_ATM_BLLI:
  862                 err = sooptcopyin(sopt, &p.bll, sizeof p.bll, sizeof p.bll);
  863                 if (err)
  864                         break;
  865                 if ((p.bll.layer_2_protocol.ID_type != T_ATM_ABSENT) &&
  866                     (p.bll.layer_2_protocol.ID_type != T_ATM_SIMPLE_ID) &&
  867                     (p.bll.layer_2_protocol.ID_type != T_ATM_USER_ID))
  868                         return (EINVAL);
  869                 if ((p.bll.layer_2_protocol.mode != T_ATM_ABSENT) &&
  870                     (p.bll.layer_2_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
  871                     (p.bll.layer_2_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
  872                         return (EINVAL);
  873                 if ((p.bll.layer_2_protocol.window_size != T_ATM_ABSENT) &&
  874                     (p.bll.layer_2_protocol.window_size < 1))
  875                         return (EINVAL);
  876 
  877                 if ((p.bll.layer_3_protocol.ID_type != T_ATM_ABSENT) &&
  878                     (p.bll.layer_3_protocol.ID_type != T_ATM_SIMPLE_ID) &&
  879                     (p.bll.layer_3_protocol.ID_type != T_ATM_IPI_ID) &&
  880                     (p.bll.layer_3_protocol.ID_type != T_ATM_SNAP_ID) &&
  881                     (p.bll.layer_3_protocol.ID_type != T_ATM_USER_ID))
  882                         return (EINVAL);
  883                 if ((p.bll.layer_3_protocol.mode != T_ATM_ABSENT) &&
  884                     (p.bll.layer_3_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
  885                     (p.bll.layer_3_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
  886                         return (EINVAL);
  887                 if ((p.bll.layer_3_protocol.packet_size != T_ATM_ABSENT) &&
  888                     (p.bll.layer_3_protocol.packet_size & MAXMASK(4)))
  889                         return (EINVAL);
  890                 if ((p.bll.layer_3_protocol.window_size != T_ATM_ABSENT) &&
  891                     (p.bll.layer_3_protocol.window_size < 1))
  892                         return (EINVAL);
  893 
  894                 if (p.bll.layer_2_protocol.ID_type == T_ATM_ABSENT) 
  895                         atp->atp_attr.blli.tag_l2 = T_ATM_ABSENT;
  896                 else
  897                         atp->atp_attr.blli.tag_l2 = T_ATM_PRESENT;
  898 
  899                 if (p.bll.layer_3_protocol.ID_type == T_ATM_ABSENT) 
  900                         atp->atp_attr.blli.tag_l3 = T_ATM_ABSENT;
  901                 else
  902                         atp->atp_attr.blli.tag_l3 = T_ATM_PRESENT;
  903 
  904                 if ((atp->atp_attr.blli.tag_l2 == T_ATM_PRESENT) ||
  905                     (atp->atp_attr.blli.tag_l3 == T_ATM_PRESENT))
  906                         atp->atp_attr.blli.v = p.bll;
  907                 break;
  908 
  909         case T_ATM_DEST_ADDR:
  910                 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
  911                 if (err)
  912                         break;
  913                 if ((p.addr.address_format != T_ATM_ENDSYS_ADDR) &&
  914                     (p.addr.address_format != T_ATM_E164_ADDR))
  915                         return (EINVAL);
  916                 if (p.addr.address_length > ATM_ADDR_LEN)
  917                         return (EINVAL);
  918 
  919                 atp->atp_attr.called.tag = T_ATM_PRESENT;
  920                 atp->atp_attr.called.addr = p.addr;
  921                 break;
  922 
  923         case T_ATM_DEST_SUB:
  924                 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
  925                 if (err)
  926                         break;
  927                 if ((p.addr.address_format != T_ATM_ABSENT) &&
  928                     (p.addr.address_format != T_ATM_NSAP_ADDR))
  929                         return (EINVAL);
  930                 if (p.addr.address_length > ATM_ADDR_LEN)
  931                         return (EINVAL);
  932 
  933                 /* T_ATM_DEST_ADDR controls tag */
  934                 atp->atp_attr.called.subaddr = p.addr;
  935                 break;
  936 
  937         case T_ATM_ORIG_ADDR:
  938                 return (EACCES);
  939 
  940         case T_ATM_ORIG_SUB:
  941                 return (EACCES);
  942 
  943         case T_ATM_CALLER_ID:
  944                 return (EACCES);
  945 
  946         case T_ATM_CAUSE:
  947                 err = sooptcopyin(sopt, &p.cau, sizeof p.cau, sizeof p.cau);
  948                 if (err)
  949                         break;
  950                 if ((p.cau.coding_standard != T_ATM_ABSENT) &&
  951                     (p.cau.coding_standard != T_ATM_ITU_CODING) &&
  952                     (p.cau.coding_standard != T_ATM_NETWORK_CODING))
  953                         return (EINVAL);
  954                 if ((p.cau.location != T_ATM_LOC_USER) &&
  955                     (p.cau.location != T_ATM_LOC_LOCAL_PRIVATE_NET) &&
  956                     (p.cau.location != T_ATM_LOC_LOCAL_PUBLIC_NET) &&
  957                     (p.cau.location != T_ATM_LOC_TRANSIT_NET) &&
  958                     (p.cau.location != T_ATM_LOC_REMOTE_PUBLIC_NET) &&
  959                     (p.cau.location != T_ATM_LOC_REMOTE_PRIVATE_NET) &&
  960                     (p.cau.location != T_ATM_LOC_INTERNATIONAL_NET) &&
  961                     (p.cau.location != T_ATM_LOC_BEYOND_INTERWORKING))
  962                         return (EINVAL);
  963 
  964                 if (p.cau.coding_standard == T_ATM_ABSENT)
  965                         atp->atp_attr.cause.tag = T_ATM_ABSENT;
  966                 else {
  967                         atp->atp_attr.cause.tag = T_ATM_PRESENT;
  968                         atp->atp_attr.cause.v = p.cau;
  969                 }
  970                 break;
  971 
  972         case T_ATM_QOS:
  973                 err = sooptcopyin(sopt, &p.qos, sizeof p.qos, sizeof p.qos);
  974                 if (err)
  975                         break;
  976                 if ((p.qos.coding_standard != T_ATM_ABSENT) &&
  977                     (p.qos.coding_standard != T_ATM_ITU_CODING) &&
  978                     (p.qos.coding_standard != T_ATM_NETWORK_CODING))
  979                         return (EINVAL);
  980                 if ((p.qos.forward.qos_class != T_ATM_QOS_CLASS_0) &&
  981                     (p.qos.forward.qos_class != T_ATM_QOS_CLASS_1) &&
  982                     (p.qos.forward.qos_class != T_ATM_QOS_CLASS_2) &&
  983                     (p.qos.forward.qos_class != T_ATM_QOS_CLASS_3) &&
  984                     (p.qos.forward.qos_class != T_ATM_QOS_CLASS_4))
  985                         return (EINVAL);
  986                 if ((p.qos.backward.qos_class != T_ATM_QOS_CLASS_0) &&
  987                     (p.qos.backward.qos_class != T_ATM_QOS_CLASS_1) &&
  988                     (p.qos.backward.qos_class != T_ATM_QOS_CLASS_2) &&
  989                     (p.qos.backward.qos_class != T_ATM_QOS_CLASS_3) &&
  990                     (p.qos.backward.qos_class != T_ATM_QOS_CLASS_4))
  991                         return (EINVAL);
  992 
  993                 if (p.qos.coding_standard == T_ATM_ABSENT)
  994                         atp->atp_attr.qos.tag = T_ATM_ABSENT;
  995                 else {
  996                         atp->atp_attr.qos.tag = T_ATM_PRESENT;
  997                         atp->atp_attr.qos.v = p.qos;
  998                 }
  999                 break;
 1000 
 1001         case T_ATM_TRANSIT:
 1002                 err = sooptcopyin(sopt, &p.trn, sizeof p.trn, sizeof p.trn);
 1003                 if (err)
 1004                         break;
 1005                 if (p.trn.length > T_ATM_MAX_NET_ID)
 1006                         return (EINVAL);
 1007 
 1008                 if (p.trn.length == 0)
 1009                         atp->atp_attr.transit.tag = T_ATM_ABSENT;
 1010                 else {
 1011                         atp->atp_attr.transit.tag = T_ATM_PRESENT;
 1012                         atp->atp_attr.transit.v = p.trn;
 1013                 }
 1014                 break;
 1015 
 1016         case T_ATM_ADD_LEAF:
 1017                 return (EPROTONOSUPPORT);       /* XXX */
 1018 
 1019         case T_ATM_DROP_LEAF:
 1020                 return (EPROTONOSUPPORT);       /* XXX */
 1021 
 1022         case T_ATM_NET_INTF:
 1023                 err = sooptcopyin(sopt, &p.nif, sizeof p.nif, sizeof p.nif);
 1024                 if (err)
 1025                         break;
 1026 
 1027                 atp->atp_attr.nif = atm_nifname(p.nif.net_intf);
 1028                 if (atp->atp_attr.nif == NULL)
 1029                         return (ENXIO);
 1030                 break;
 1031 
 1032         case T_ATM_LLC:
 1033                 err = sooptcopyin(sopt, &p.llc, sizeof p.llc, sizeof p.llc);
 1034                 if (err)
 1035                         break;
 1036                 if ((p.llc.llc_len < T_ATM_LLC_MIN_LEN) ||
 1037                     (p.llc.llc_len > T_ATM_LLC_MAX_LEN))
 1038                         return (EINVAL);
 1039 
 1040                 atp->atp_attr.llc.tag = T_ATM_PRESENT;
 1041                 atp->atp_attr.llc.v = p.llc;
 1042                 break;
 1043 
 1044         case T_ATM_APP_NAME:
 1045                 err = sooptcopyin(sopt, &p.appn, sizeof p.appn, sizeof p.appn);
 1046                 if (err)
 1047                         break;
 1048 
 1049                 strncpy(atp->atp_name, p.appn.app_name, T_ATM_APP_NAME_LEN);
 1050                 break;
 1051 
 1052         default:
 1053                 return (ENOPROTOOPT);
 1054         }
 1055 
 1056         return (err);
 1057 }
 1058 
 1059 
 1060 /*
 1061  * Common getsockopt processing
 1062  *
 1063  * Called at splnet.
 1064  *
 1065  * Arguments:
 1066  *      so      pointer to socket
 1067  *      sopt    pointer to socket option info
 1068  *      atp     pointer to ATM PCB
 1069  *
 1070  * Returns:
 1071  *      0       request processed
 1072  *      errno   error processing request - reason indicated
 1073  *
 1074  */
 1075 int
 1076 atm_sock_getopt(so, sopt, atp)
 1077         struct socket   *so;
 1078         struct sockopt  *sopt;
 1079         Atm_pcb         *atp;
 1080 {
 1081         Atm_attributes  *ap;
 1082 
 1083         /*
 1084          * If socket is connected, return attributes for the VCC in use,
 1085          * otherwise just return what the user has setup so far.
 1086          */
 1087         if (so->so_state & SS_ISCONNECTED)
 1088                 ap = &atp->atp_conn->co_connvc->cvc_attr;
 1089         else
 1090                 ap = &atp->atp_attr;
 1091 
 1092         switch (sopt->sopt_name) {
 1093 
 1094         case T_ATM_AAL5:
 1095                 if ((ap->aal.tag == T_ATM_PRESENT) &&
 1096                     (ap->aal.type == ATM_AAL5)) {
 1097                         return (sooptcopyout(sopt, &ap->aal.v.aal5,
 1098                                         sizeof ap->aal.v.aal5));
 1099                 } else {
 1100                         return (ENOENT);
 1101                 }
 1102                 break;
 1103 
 1104         case T_ATM_TRAFFIC:
 1105                 if (ap->traffic.tag == T_ATM_PRESENT) {
 1106                         return (sooptcopyout(sopt, &ap->traffic.v,
 1107                                         sizeof ap->traffic.v));
 1108                 } else {
 1109                         return (ENOENT);
 1110                 }
 1111                 break;
 1112 
 1113         case T_ATM_BEARER_CAP:
 1114                 if (ap->bearer.tag == T_ATM_PRESENT) {
 1115                         return (sooptcopyout(sopt, &ap->bearer.v,
 1116                                         sizeof ap->bearer.v));
 1117                 } else {
 1118                         return (ENOENT);
 1119                 }
 1120                 break;
 1121 
 1122         case T_ATM_BHLI:
 1123                 if (ap->bhli.tag == T_ATM_PRESENT) {
 1124                         return (sooptcopyout(sopt, &ap->bhli.v,
 1125                                         sizeof ap->bhli.v));
 1126                 } else {
 1127                         return (ENOENT);
 1128                 }
 1129                 break;
 1130 
 1131         case T_ATM_BLLI:
 1132                 if ((ap->blli.tag_l2 == T_ATM_PRESENT) ||
 1133                     (ap->blli.tag_l3 == T_ATM_PRESENT)) {
 1134                         return (sooptcopyout(sopt, &ap->blli.v,
 1135                                         sizeof ap->blli.v));
 1136                 } else {
 1137                         return (ENOENT);
 1138                 }
 1139                 break;
 1140 
 1141         case T_ATM_DEST_ADDR:
 1142                 if (ap->called.tag == T_ATM_PRESENT) {
 1143                         return (sooptcopyout(sopt, &ap->called.addr,
 1144                                         sizeof ap->called.addr));
 1145                 } else {
 1146                         return (ENOENT);
 1147                 }
 1148                 break;
 1149 
 1150         case T_ATM_DEST_SUB:
 1151                 if (ap->called.tag == T_ATM_PRESENT) {
 1152                         return (sooptcopyout(sopt, &ap->called.subaddr,
 1153                                         sizeof ap->called.subaddr));
 1154                 } else {
 1155                         return (ENOENT);
 1156                 }
 1157                 break;
 1158 
 1159         case T_ATM_ORIG_ADDR:
 1160                 if (ap->calling.tag == T_ATM_PRESENT) {
 1161                         return (sooptcopyout(sopt, &ap->calling.addr,
 1162                                         sizeof ap->calling.addr));
 1163                 } else {
 1164                         return (ENOENT);
 1165                 }
 1166                 break;
 1167 
 1168         case T_ATM_ORIG_SUB:
 1169                 if (ap->calling.tag == T_ATM_PRESENT) {
 1170                         return (sooptcopyout(sopt, &ap->calling.subaddr,
 1171                                         sizeof ap->calling.subaddr));
 1172                 } else {
 1173                         return (ENOENT);
 1174                 }
 1175                 break;
 1176 
 1177         case T_ATM_CALLER_ID:
 1178                 if (ap->calling.tag == T_ATM_PRESENT) {
 1179                         return (sooptcopyout(sopt, &ap->calling.cid,
 1180                                         sizeof ap->calling.cid));
 1181                 } else {
 1182                         return (ENOENT);
 1183                 }
 1184                 break;
 1185 
 1186         case T_ATM_CAUSE:
 1187                 if (ap->cause.tag == T_ATM_PRESENT) {
 1188                         return (sooptcopyout(sopt, &ap->cause.v,
 1189                                         sizeof ap->cause.v));
 1190                 } else {
 1191                         return (ENOENT);
 1192                 }
 1193                 break;
 1194 
 1195         case T_ATM_QOS:
 1196                 if (ap->qos.tag == T_ATM_PRESENT) {
 1197                         return (sooptcopyout(sopt, &ap->qos.v,
 1198                                         sizeof ap->qos.v));
 1199                 } else {
 1200                         return (ENOENT);
 1201                 }
 1202                 break;
 1203 
 1204         case T_ATM_TRANSIT:
 1205                 if (ap->transit.tag == T_ATM_PRESENT) {
 1206                         return (sooptcopyout(sopt, &ap->transit.v,
 1207                                         sizeof ap->transit.v));
 1208                 } else {
 1209                         return (ENOENT);
 1210                 }
 1211                 break;
 1212 
 1213         case T_ATM_LEAF_IND:
 1214                 return (EPROTONOSUPPORT);       /* XXX */
 1215 
 1216         case T_ATM_NET_INTF:
 1217                 if (ap->nif) {
 1218                         struct t_atm_net_intf   netif;
 1219                         struct ifnet            *ifp;
 1220 
 1221                         ifp = &ap->nif->nif_if;
 1222                         (void) snprintf(netif.net_intf, sizeof(netif.net_intf),
 1223                             "%s", ifp->if_xname);
 1224                         return (sooptcopyout(sopt, &netif,
 1225                                         sizeof netif));
 1226                 } else {
 1227                         return (ENOENT);
 1228                 }
 1229                 break;
 1230 
 1231         case T_ATM_LLC:
 1232                 if (ap->llc.tag == T_ATM_PRESENT) {
 1233                         return (sooptcopyout(sopt, &ap->llc.v,
 1234                                         sizeof ap->llc.v));
 1235                 } else {
 1236                         return (ENOENT);
 1237                 }
 1238                 break;
 1239 
 1240         default:
 1241                 return (ENOPROTOOPT);
 1242         }
 1243 
 1244         return (0);
 1245 }
 1246 
 1247 
 1248 /*
 1249  * Process Socket VCC Connected Notification
 1250  *
 1251  * Arguments:
 1252  *      toku    owner's connection token (atm_pcb protocol block)
 1253  *
 1254  * Returns:
 1255  *      none
 1256  *
 1257  */
 1258 void
 1259 atm_sock_connected(toku)
 1260         void            *toku;
 1261 {
 1262         Atm_pcb         *atp = (Atm_pcb *)toku;
 1263 
 1264         /*
 1265          * Connection is setup
 1266          */
 1267         atm_sock_stat.as_conncomp[atp->atp_type]++;
 1268         soisconnected(atp->atp_socket);
 1269 }
 1270 
 1271 
 1272 /*
 1273  * Process Socket VCC Cleared Notification
 1274  *
 1275  * Arguments:
 1276  *      toku    owner's connection token (atm_pcb protocol block)
 1277  *      cause   pointer to cause code
 1278  *
 1279  * Returns:
 1280  *      none
 1281  *
 1282  */
 1283 void
 1284 atm_sock_cleared(toku, cause)
 1285         void            *toku;
 1286         struct t_atm_cause      *cause;
 1287 {
 1288         Atm_pcb         *atp = (Atm_pcb *)toku;
 1289         struct socket   *so;
 1290 
 1291         so = atp->atp_socket;
 1292 
 1293         /*
 1294          * Save call clearing cause
 1295          */
 1296         atp->atp_attr.cause.tag = T_ATM_PRESENT;
 1297         atp->atp_attr.cause.v = *cause;
 1298 
 1299         /*
 1300          * Set user error code
 1301          */
 1302         if (so->so_state & SS_ISCONNECTED) {
 1303                 so->so_error = ECONNRESET;
 1304                 atm_sock_stat.as_connclr[atp->atp_type]++;
 1305         } else {
 1306                 so->so_error = ECONNREFUSED;
 1307                 atm_sock_stat.as_connfail[atp->atp_type]++;
 1308         }
 1309 
 1310         /*
 1311          * Connection is gone
 1312          */
 1313         atp->atp_conn = NULL;
 1314         soisdisconnected(so);
 1315 
 1316         /*
 1317          * Cleanup failed incoming connection setup
 1318          */
 1319         if (so->so_state & SS_NOFDREF) {
 1320                 (void) atm_sock_detach(so);
 1321         }
 1322 }
 1323 

Cache object: b2c4ee3eca11e9e357d73010e4527a88


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