The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netatm/atm_socket.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 250c66d460125a4e842683c7b28d4fb6


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