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

Cache object: aa32fc40e371f878d99bdb9f43f14c04


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