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

Cache object: b0437af96ab2c2fe1dc9d9e146afa649


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