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                     (p.brr.traffic_type != T_ATM_ABR) &&
  816                     (p.brr.traffic_type != T_ATM_UBR))
  817                         return (EINVAL);
  818                 if ((p.brr.timing_requirements != T_ATM_NULL) &&
  819                     (p.brr.timing_requirements != T_ATM_END_TO_END) &&
  820                     (p.brr.timing_requirements != T_ATM_NO_END_TO_END))
  821                         return (EINVAL);
  822                 if ((p.brr.clipping_susceptibility != T_NO) &&
  823                     (p.brr.clipping_susceptibility != T_YES))
  824                         return (EINVAL);
  825                 if ((p.brr.connection_configuration != T_ATM_1_TO_1) &&
  826                     (p.brr.connection_configuration != T_ATM_1_TO_MANY))
  827                         return (EINVAL);
  828 
  829                 atp->atp_attr.bearer.tag = T_ATM_PRESENT;
  830                 atp->atp_attr.bearer.v = p.brr;
  831                 break;
  832 
  833         case T_ATM_BHLI:
  834                 err = sooptcopyin(sopt, &p.bhl, sizeof p.bhl, sizeof p.bhl);
  835                 if (err)
  836                         break;
  837                 if ((p.bhl.ID_type != T_ATM_ABSENT) &&
  838                     (p.bhl.ID_type != T_ATM_ISO_APP_ID) &&
  839                     (p.bhl.ID_type != T_ATM_USER_APP_ID) &&
  840                     (p.bhl.ID_type != T_ATM_VENDOR_APP_ID))
  841                         return (EINVAL);
  842 
  843                 if (p.bhl.ID_type == T_ATM_ABSENT)
  844                         atp->atp_attr.bhli.tag = T_ATM_ABSENT;
  845                 else {
  846                         atp->atp_attr.bhli.tag = T_ATM_PRESENT;
  847                         atp->atp_attr.bhli.v = p.bhl;
  848                 }
  849                 break;
  850 
  851         case T_ATM_BLLI:
  852                 err = sooptcopyin(sopt, &p.bll, sizeof p.bll, sizeof p.bll);
  853                 if (err)
  854                         break;
  855                 if ((p.bll.layer_2_protocol.ID_type != T_ATM_ABSENT) &&
  856                     (p.bll.layer_2_protocol.ID_type != T_ATM_SIMPLE_ID) &&
  857                     (p.bll.layer_2_protocol.ID_type != T_ATM_USER_ID))
  858                         return (EINVAL);
  859                 if ((p.bll.layer_2_protocol.mode != T_ATM_ABSENT) &&
  860                     (p.bll.layer_2_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
  861                     (p.bll.layer_2_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
  862                         return (EINVAL);
  863                 if ((p.bll.layer_2_protocol.window_size != T_ATM_ABSENT) &&
  864                     (p.bll.layer_2_protocol.window_size < 1))
  865                         return (EINVAL);
  866 
  867                 if ((p.bll.layer_3_protocol.ID_type != T_ATM_ABSENT) &&
  868                     (p.bll.layer_3_protocol.ID_type != T_ATM_SIMPLE_ID) &&
  869                     (p.bll.layer_3_protocol.ID_type != T_ATM_IPI_ID) &&
  870                     (p.bll.layer_3_protocol.ID_type != T_ATM_SNAP_ID) &&
  871                     (p.bll.layer_3_protocol.ID_type != T_ATM_USER_ID))
  872                         return (EINVAL);
  873                 if ((p.bll.layer_3_protocol.mode != T_ATM_ABSENT) &&
  874                     (p.bll.layer_3_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
  875                     (p.bll.layer_3_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
  876                         return (EINVAL);
  877                 if ((p.bll.layer_3_protocol.packet_size != T_ATM_ABSENT) &&
  878                     (p.bll.layer_3_protocol.packet_size & MAXMASK(4)))
  879                         return (EINVAL);
  880                 if ((p.bll.layer_3_protocol.window_size != T_ATM_ABSENT) &&
  881                     (p.bll.layer_3_protocol.window_size < 1))
  882                         return (EINVAL);
  883 
  884                 if (p.bll.layer_2_protocol.ID_type == T_ATM_ABSENT) 
  885                         atp->atp_attr.blli.tag_l2 = T_ATM_ABSENT;
  886                 else
  887                         atp->atp_attr.blli.tag_l2 = T_ATM_PRESENT;
  888 
  889                 if (p.bll.layer_3_protocol.ID_type == T_ATM_ABSENT) 
  890                         atp->atp_attr.blli.tag_l3 = T_ATM_ABSENT;
  891                 else
  892                         atp->atp_attr.blli.tag_l3 = T_ATM_PRESENT;
  893 
  894                 if ((atp->atp_attr.blli.tag_l2 == T_ATM_PRESENT) ||
  895                     (atp->atp_attr.blli.tag_l3 == T_ATM_PRESENT))
  896                         atp->atp_attr.blli.v = p.bll;
  897                 break;
  898 
  899         case T_ATM_DEST_ADDR:
  900                 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
  901                 if (err)
  902                         break;
  903                 if ((p.addr.address_format != T_ATM_ENDSYS_ADDR) &&
  904                     (p.addr.address_format != T_ATM_E164_ADDR))
  905                         return (EINVAL);
  906                 if (p.addr.address_length > ATM_ADDR_LEN)
  907                         return (EINVAL);
  908 
  909                 atp->atp_attr.called.tag = T_ATM_PRESENT;
  910                 atp->atp_attr.called.addr = p.addr;
  911                 break;
  912 
  913         case T_ATM_DEST_SUB:
  914                 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
  915                 if (err)
  916                         break;
  917                 if ((p.addr.address_format != T_ATM_ABSENT) &&
  918                     (p.addr.address_format != T_ATM_NSAP_ADDR))
  919                         return (EINVAL);
  920                 if (p.addr.address_length > ATM_ADDR_LEN)
  921                         return (EINVAL);
  922 
  923                 /* T_ATM_DEST_ADDR controls tag */
  924                 atp->atp_attr.called.subaddr = p.addr;
  925                 break;
  926 
  927         case T_ATM_ORIG_ADDR:
  928                 return (EACCES);
  929 
  930         case T_ATM_ORIG_SUB:
  931                 return (EACCES);
  932 
  933         case T_ATM_CALLER_ID:
  934                 return (EACCES);
  935 
  936         case T_ATM_CAUSE:
  937                 err = sooptcopyin(sopt, &p.cau, sizeof p.cau, sizeof p.cau);
  938                 if (err)
  939                         break;
  940                 if ((p.cau.coding_standard != T_ATM_ABSENT) &&
  941                     (p.cau.coding_standard != T_ATM_ITU_CODING) &&
  942                     (p.cau.coding_standard != T_ATM_NETWORK_CODING))
  943                         return (EINVAL);
  944                 if ((p.cau.location != T_ATM_LOC_USER) &&
  945                     (p.cau.location != T_ATM_LOC_LOCAL_PRIVATE_NET) &&
  946                     (p.cau.location != T_ATM_LOC_LOCAL_PUBLIC_NET) &&
  947                     (p.cau.location != T_ATM_LOC_TRANSIT_NET) &&
  948                     (p.cau.location != T_ATM_LOC_REMOTE_PUBLIC_NET) &&
  949                     (p.cau.location != T_ATM_LOC_REMOTE_PRIVATE_NET) &&
  950                     (p.cau.location != T_ATM_LOC_INTERNATIONAL_NET) &&
  951                     (p.cau.location != T_ATM_LOC_BEYOND_INTERWORKING))
  952                         return (EINVAL);
  953 
  954                 if (p.cau.coding_standard == T_ATM_ABSENT)
  955                         atp->atp_attr.cause.tag = T_ATM_ABSENT;
  956                 else {
  957                         atp->atp_attr.cause.tag = T_ATM_PRESENT;
  958                         atp->atp_attr.cause.v = p.cau;
  959                 }
  960                 break;
  961 
  962         case T_ATM_QOS:
  963                 err = sooptcopyin(sopt, &p.qos, sizeof p.qos, sizeof p.qos);
  964                 if (err)
  965                         break;
  966                 if ((p.qos.coding_standard != T_ATM_ABSENT) &&
  967                     (p.qos.coding_standard != T_ATM_ITU_CODING) &&
  968                     (p.qos.coding_standard != T_ATM_NETWORK_CODING))
  969                         return (EINVAL);
  970                 if ((p.qos.forward.qos_class != T_ATM_QOS_CLASS_0) &&
  971                     (p.qos.forward.qos_class != T_ATM_QOS_CLASS_1) &&
  972                     (p.qos.forward.qos_class != T_ATM_QOS_CLASS_2) &&
  973                     (p.qos.forward.qos_class != T_ATM_QOS_CLASS_3) &&
  974                     (p.qos.forward.qos_class != T_ATM_QOS_CLASS_4))
  975                         return (EINVAL);
  976                 if ((p.qos.backward.qos_class != T_ATM_QOS_CLASS_0) &&
  977                     (p.qos.backward.qos_class != T_ATM_QOS_CLASS_1) &&
  978                     (p.qos.backward.qos_class != T_ATM_QOS_CLASS_2) &&
  979                     (p.qos.backward.qos_class != T_ATM_QOS_CLASS_3) &&
  980                     (p.qos.backward.qos_class != T_ATM_QOS_CLASS_4))
  981                         return (EINVAL);
  982 
  983                 if (p.qos.coding_standard == T_ATM_ABSENT)
  984                         atp->atp_attr.qos.tag = T_ATM_ABSENT;
  985                 else {
  986                         atp->atp_attr.qos.tag = T_ATM_PRESENT;
  987                         atp->atp_attr.qos.v = p.qos;
  988                 }
  989                 break;
  990 
  991         case T_ATM_TRANSIT:
  992                 err = sooptcopyin(sopt, &p.trn, sizeof p.trn, sizeof p.trn);
  993                 if (err)
  994                         break;
  995                 if (p.trn.length > T_ATM_MAX_NET_ID)
  996                         return (EINVAL);
  997 
  998                 if (p.trn.length == 0)
  999                         atp->atp_attr.transit.tag = T_ATM_ABSENT;
 1000                 else {
 1001                         atp->atp_attr.transit.tag = T_ATM_PRESENT;
 1002                         atp->atp_attr.transit.v = p.trn;
 1003                 }
 1004                 break;
 1005 
 1006         case T_ATM_ADD_LEAF:
 1007                 return (EPROTONOSUPPORT);       /* XXX */
 1008 
 1009         case T_ATM_DROP_LEAF:
 1010                 return (EPROTONOSUPPORT);       /* XXX */
 1011 
 1012         case T_ATM_NET_INTF:
 1013                 err = sooptcopyin(sopt, &p.nif, sizeof p.nif, sizeof p.nif);
 1014                 if (err)
 1015                         break;
 1016 
 1017                 atp->atp_attr.nif = atm_nifname(p.nif.net_intf);
 1018                 if (atp->atp_attr.nif == NULL)
 1019                         return (ENXIO);
 1020                 break;
 1021 
 1022         case T_ATM_LLC:
 1023                 err = sooptcopyin(sopt, &p.llc, sizeof p.llc, sizeof p.llc);
 1024                 if (err)
 1025                         break;
 1026                 if ((p.llc.llc_len < T_ATM_LLC_MIN_LEN) ||
 1027                     (p.llc.llc_len > T_ATM_LLC_MAX_LEN))
 1028                         return (EINVAL);
 1029 
 1030                 atp->atp_attr.llc.tag = T_ATM_PRESENT;
 1031                 atp->atp_attr.llc.v = p.llc;
 1032                 break;
 1033 
 1034         case T_ATM_APP_NAME:
 1035                 err = sooptcopyin(sopt, &p.appn, sizeof p.appn, sizeof p.appn);
 1036                 if (err)
 1037                         break;
 1038 
 1039                 strncpy(atp->atp_name, p.appn.app_name, T_ATM_APP_NAME_LEN);
 1040                 break;
 1041 
 1042         default:
 1043                 return (ENOPROTOOPT);
 1044         }
 1045 
 1046         return (err);
 1047 }
 1048 
 1049 
 1050 /*
 1051  * Common getsockopt processing
 1052  *
 1053  * Called at splnet.
 1054  *
 1055  * Arguments:
 1056  *      so      pointer to socket
 1057  *      sopt    pointer to socket option info
 1058  *      atp     pointer to ATM PCB
 1059  *
 1060  * Returns:
 1061  *      0       request processed
 1062  *      errno   error processing request - reason indicated
 1063  *
 1064  */
 1065 int
 1066 atm_sock_getopt(so, sopt, atp)
 1067         struct socket   *so;
 1068         struct sockopt  *sopt;
 1069         Atm_pcb         *atp;
 1070 {
 1071         Atm_attributes  *ap;
 1072 
 1073         /*
 1074          * If socket is connected, return attributes for the VCC in use,
 1075          * otherwise just return what the user has setup so far.
 1076          */
 1077         if (so->so_state & SS_ISCONNECTED)
 1078                 ap = &atp->atp_conn->co_connvc->cvc_attr;
 1079         else
 1080                 ap = &atp->atp_attr;
 1081 
 1082         switch (sopt->sopt_name) {
 1083 
 1084         case T_ATM_AAL5:
 1085                 if ((ap->aal.tag == T_ATM_PRESENT) &&
 1086                     (ap->aal.type == ATM_AAL5)) {
 1087                         return (sooptcopyout(sopt, &ap->aal.v.aal5,
 1088                                         sizeof ap->aal.v.aal5));
 1089                 } else {
 1090                         return (ENOENT);
 1091                 }
 1092                 break;
 1093 
 1094         case T_ATM_TRAFFIC:
 1095                 if (ap->traffic.tag == T_ATM_PRESENT) {
 1096                         return (sooptcopyout(sopt, &ap->traffic.v,
 1097                                         sizeof ap->traffic.v));
 1098                 } else {
 1099                         return (ENOENT);
 1100                 }
 1101                 break;
 1102 
 1103         case T_ATM_BEARER_CAP:
 1104                 if (ap->bearer.tag == T_ATM_PRESENT) {
 1105                         return (sooptcopyout(sopt, &ap->bearer.v,
 1106                                         sizeof ap->bearer.v));
 1107                 } else {
 1108                         return (ENOENT);
 1109                 }
 1110                 break;
 1111 
 1112         case T_ATM_BHLI:
 1113                 if (ap->bhli.tag == T_ATM_PRESENT) {
 1114                         return (sooptcopyout(sopt, &ap->bhli.v,
 1115                                         sizeof ap->bhli.v));
 1116                 } else {
 1117                         return (ENOENT);
 1118                 }
 1119                 break;
 1120 
 1121         case T_ATM_BLLI:
 1122                 if ((ap->blli.tag_l2 == T_ATM_PRESENT) ||
 1123                     (ap->blli.tag_l3 == T_ATM_PRESENT)) {
 1124                         return (sooptcopyout(sopt, &ap->blli.v,
 1125                                         sizeof ap->blli.v));
 1126                 } else {
 1127                         return (ENOENT);
 1128                 }
 1129                 break;
 1130 
 1131         case T_ATM_DEST_ADDR:
 1132                 if (ap->called.tag == T_ATM_PRESENT) {
 1133                         return (sooptcopyout(sopt, &ap->called.addr,
 1134                                         sizeof ap->called.addr));
 1135                 } else {
 1136                         return (ENOENT);
 1137                 }
 1138                 break;
 1139 
 1140         case T_ATM_DEST_SUB:
 1141                 if (ap->called.tag == T_ATM_PRESENT) {
 1142                         return (sooptcopyout(sopt, &ap->called.subaddr,
 1143                                         sizeof ap->called.subaddr));
 1144                 } else {
 1145                         return (ENOENT);
 1146                 }
 1147                 break;
 1148 
 1149         case T_ATM_ORIG_ADDR:
 1150                 if (ap->calling.tag == T_ATM_PRESENT) {
 1151                         return (sooptcopyout(sopt, &ap->calling.addr,
 1152                                         sizeof ap->calling.addr));
 1153                 } else {
 1154                         return (ENOENT);
 1155                 }
 1156                 break;
 1157 
 1158         case T_ATM_ORIG_SUB:
 1159                 if (ap->calling.tag == T_ATM_PRESENT) {
 1160                         return (sooptcopyout(sopt, &ap->calling.subaddr,
 1161                                         sizeof ap->calling.subaddr));
 1162                 } else {
 1163                         return (ENOENT);
 1164                 }
 1165                 break;
 1166 
 1167         case T_ATM_CALLER_ID:
 1168                 if (ap->calling.tag == T_ATM_PRESENT) {
 1169                         return (sooptcopyout(sopt, &ap->calling.cid,
 1170                                         sizeof ap->calling.cid));
 1171                 } else {
 1172                         return (ENOENT);
 1173                 }
 1174                 break;
 1175 
 1176         case T_ATM_CAUSE:
 1177                 if (ap->cause.tag == T_ATM_PRESENT) {
 1178                         return (sooptcopyout(sopt, &ap->cause.v,
 1179                                         sizeof ap->cause.v));
 1180                 } else {
 1181                         return (ENOENT);
 1182                 }
 1183                 break;
 1184 
 1185         case T_ATM_QOS:
 1186                 if (ap->qos.tag == T_ATM_PRESENT) {
 1187                         return (sooptcopyout(sopt, &ap->qos.v,
 1188                                         sizeof ap->qos.v));
 1189                 } else {
 1190                         return (ENOENT);
 1191                 }
 1192                 break;
 1193 
 1194         case T_ATM_TRANSIT:
 1195                 if (ap->transit.tag == T_ATM_PRESENT) {
 1196                         return (sooptcopyout(sopt, &ap->transit.v,
 1197                                         sizeof ap->transit.v));
 1198                 } else {
 1199                         return (ENOENT);
 1200                 }
 1201                 break;
 1202 
 1203         case T_ATM_LEAF_IND:
 1204                 return (EPROTONOSUPPORT);       /* XXX */
 1205 
 1206         case T_ATM_NET_INTF:
 1207                 if (ap->nif) {
 1208                         struct t_atm_net_intf   netif;
 1209                         struct ifnet            *ifp;
 1210 
 1211                         ifp = &ap->nif->nif_if;
 1212                         (void) snprintf(netif.net_intf, sizeof(netif.net_intf),
 1213                             "%s%d", ifp->if_name, ifp->if_unit);
 1214                         return (sooptcopyout(sopt, &netif,
 1215                                         sizeof netif));
 1216                 } else {
 1217                         return (ENOENT);
 1218                 }
 1219                 break;
 1220 
 1221         case T_ATM_LLC:
 1222                 if (ap->llc.tag == T_ATM_PRESENT) {
 1223                         return (sooptcopyout(sopt, &ap->llc.v,
 1224                                         sizeof ap->llc.v));
 1225                 } else {
 1226                         return (ENOENT);
 1227                 }
 1228                 break;
 1229 
 1230         default:
 1231                 return (ENOPROTOOPT);
 1232         }
 1233 
 1234         return (0);
 1235 }
 1236 
 1237 
 1238 /*
 1239  * Process Socket VCC Connected Notification
 1240  *
 1241  * Arguments:
 1242  *      toku    owner's connection token (atm_pcb protocol block)
 1243  *
 1244  * Returns:
 1245  *      none
 1246  *
 1247  */
 1248 void
 1249 atm_sock_connected(toku)
 1250         void            *toku;
 1251 {
 1252         Atm_pcb         *atp = (Atm_pcb *)toku;
 1253 
 1254         /*
 1255          * Connection is setup
 1256          */
 1257         atm_sock_stat.as_conncomp[atp->atp_type]++;
 1258         soisconnected(atp->atp_socket);
 1259 }
 1260 
 1261 
 1262 /*
 1263  * Process Socket VCC Cleared Notification
 1264  *
 1265  * Arguments:
 1266  *      toku    owner's connection token (atm_pcb protocol block)
 1267  *      cause   pointer to cause code
 1268  *
 1269  * Returns:
 1270  *      none
 1271  *
 1272  */
 1273 void
 1274 atm_sock_cleared(toku, cause)
 1275         void            *toku;
 1276         struct t_atm_cause      *cause;
 1277 {
 1278         Atm_pcb         *atp = (Atm_pcb *)toku;
 1279         struct socket   *so;
 1280 
 1281         so = atp->atp_socket;
 1282 
 1283         /*
 1284          * Save call clearing cause
 1285          */
 1286         atp->atp_attr.cause.tag = T_ATM_PRESENT;
 1287         atp->atp_attr.cause.v = *cause;
 1288 
 1289         /*
 1290          * Set user error code
 1291          */
 1292         if (so->so_state & SS_ISCONNECTED) {
 1293                 so->so_error = ECONNRESET;
 1294                 atm_sock_stat.as_connclr[atp->atp_type]++;
 1295         } else {
 1296                 so->so_error = ECONNREFUSED;
 1297                 atm_sock_stat.as_connfail[atp->atp_type]++;
 1298         }
 1299 
 1300         /*
 1301          * Connection is gone
 1302          */
 1303         atp->atp_conn = NULL;
 1304         soisdisconnected(so);
 1305 
 1306         /*
 1307          * Cleanup failed incoming connection setup
 1308          */
 1309         if (so->so_state & SS_NOFDREF) {
 1310                 (void) atm_sock_detach(so);
 1311         }
 1312 }
 1313 

Cache object: 51e87cef587e24db06d0c19260de2024


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