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

Cache object: 25e8ac7eadfea71cb5adea0ce2fac417


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