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_usrreq.c

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

    1 /*
    2  *
    3  * ===================================
    4  * HARP  |  Host ATM Research Platform
    5  * ===================================
    6  *
    7  *
    8  * This Host ATM Research Platform ("HARP") file (the "Software") is
    9  * made available by Network Computing Services, Inc. ("NetworkCS")
   10  * "AS IS".  NetworkCS does not provide maintenance, improvements or
   11  * support of any kind.
   12  *
   13  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
   14  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
   15  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
   16  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
   17  * In no event shall NetworkCS be responsible for any damages, including
   18  * but not limited to consequential damages, arising from or relating to
   19  * any use of the Software or related support.
   20  *
   21  * Copyright 1994-1998 Network Computing Services, Inc.
   22  *
   23  * Copies of this Software may be made, however, the above copyright
   24  * notice must be reproduced on all copies.
   25  *
   26  *      @(#) $FreeBSD: releng/5.1/sys/netatm/atm_usrreq.c 108172 2002-12-22 05:35:03Z hsu $
   27  *
   28  */
   29 
   30 /*
   31  * Core ATM Services
   32  * -----------------
   33  *
   34  * ATM DGRAM socket protocol processing
   35  *
   36  */
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/sockio.h>
   41 #include <sys/protosw.h>
   42 #include <sys/socket.h>
   43 #include <net/if.h>
   44 #include <netatm/port.h>
   45 #include <netatm/queue.h>
   46 #include <netatm/atm.h>
   47 #include <netatm/atm_sys.h>
   48 #include <netatm/atm_sap.h>
   49 #include <netatm/atm_cm.h>
   50 #include <netatm/atm_if.h>
   51 #include <netatm/atm_ioctl.h>
   52 #include <netatm/atm_sigmgr.h>
   53 #include <netatm/atm_stack.h>
   54 #include <netatm/atm_pcb.h>
   55 #include <netatm/atm_var.h>
   56 
   57 #ifndef lint
   58 __RCSID("@(#) $FreeBSD: releng/5.1/sys/netatm/atm_usrreq.c 108172 2002-12-22 05:35:03Z hsu $");
   59 #endif
   60 
   61 
   62 /*
   63  * Local functions
   64  */
   65 static int      atm_dgram_attach(struct socket *, int, struct thread *);
   66 static int      atm_dgram_control(struct socket *, u_long, caddr_t, 
   67                         struct ifnet *, struct thread *);
   68 static int      atm_dgram_info(caddr_t);
   69 
   70 
   71 /*
   72  * New-style socket request routines
   73  */
   74 struct pr_usrreqs       atm_dgram_usrreqs = {
   75         atm_proto_notsupp1,             /* pru_abort */
   76         pru_accept_notsupp,             /* pru_accept */
   77         atm_dgram_attach,               /* pru_attach */
   78         atm_proto_notsupp2,             /* pru_bind */
   79         pru_connect_notsupp,            /* pru_connect */
   80         pru_connect2_notsupp,           /* pru_connect2 */
   81         atm_dgram_control,              /* pru_control */
   82         atm_proto_notsupp1,             /* pru_detach */
   83         atm_proto_notsupp1,             /* pru_disconnect */
   84         pru_listen_notsupp,             /* pru_listen */
   85         atm_proto_notsupp3,             /* pru_peeraddr */
   86         pru_rcvd_notsupp,               /* pru_rcvd */
   87         pru_rcvoob_notsupp,             /* pru_rcvoob */
   88         atm_proto_notsupp4,             /* pru_send */
   89         pru_sense_null,                 /* pru_sense */
   90         atm_proto_notsupp1,             /* pru_shutdown */
   91         atm_proto_notsupp3,             /* pru_sockaddr */
   92 };
   93 
   94 
   95 /*
   96  * Handy common code macros
   97  */
   98 #ifdef DIAGNOSTIC
   99 #define ATM_INTRO()                                             \
  100         int             s, err = 0;                             \
  101         s = splnet();                                           \
  102         /*                                                      \
  103          * Stack queue should have been drained                 \
  104          */                                                     \
  105         if (atm_stackq_head != NULL)                            \
  106                 panic("atm_usrreq: stack queue not empty");     \
  107         ;
  108 #else
  109 #define ATM_INTRO()                                             \
  110         int             s, err = 0;                             \
  111         s = splnet();                                           \
  112         ;
  113 #endif
  114 
  115 #define ATM_OUTRO()                                             \
  116         /*                                                      \
  117          * Drain any deferred calls                             \
  118          */                                                     \
  119         STACK_DRAIN();                                          \
  120         (void) splx(s);                                         \
  121         return (err);                                           \
  122         ;
  123 
  124 #define ATM_RETERR(errno) {                                     \
  125         err = errno;                                            \
  126         goto out;                                               \
  127 }
  128 
  129 
  130 /*
  131  * Attach protocol to socket
  132  *
  133  * Arguments:
  134  *      so      pointer to socket
  135  *      proto   protocol identifier
  136  *      p       pointer to process
  137  *
  138  * Returns:
  139  *      0       request processed
  140  *      errno   error processing request - reason indicated
  141  *
  142  */
  143 static int
  144 atm_dgram_attach(so, proto, td)
  145         struct socket   *so;
  146         int             proto;
  147         struct thread   *td;
  148 {
  149         ATM_INTRO();
  150 
  151         /*
  152          * Nothing to do here for ioctl()-only sockets
  153          */
  154         ATM_OUTRO();
  155 }
  156 
  157 
  158 /*
  159  * Process ioctl system calls
  160  *
  161  * Arguments:
  162  *      so      pointer to socket
  163  *      cmd     ioctl code
  164  *      data    pointer to code specific parameter data area
  165  *      ifp     pointer to ifnet structure if it's an interface ioctl
  166  *      p       pointer to process
  167  *
  168  * Returns:
  169  *      0       request processed
  170  *      errno   error processing request - reason indicated
  171  *
  172  */
  173 static int
  174 atm_dgram_control(so, cmd, data, ifp, td)
  175         struct socket   *so;
  176         u_long          cmd;
  177         caddr_t         data;
  178         struct ifnet    *ifp;
  179         struct thread   *td;
  180 {
  181         ATM_INTRO();
  182 
  183         /*
  184          * First, figure out which ioctl we're dealing with and
  185          * then process it based on the sub-op code
  186          */
  187         switch (cmd) {
  188 
  189         case AIOCCFG: {
  190                 struct atmcfgreq        *acp = (struct atmcfgreq *)data;
  191                 struct atm_pif          *pip;
  192 
  193                 if (td && (suser(td) != 0))
  194                         ATM_RETERR(EPERM);
  195 
  196                 switch (acp->acr_opcode) {
  197 
  198                 case AIOCS_CFG_ATT:
  199                         /*
  200                          * Attach signalling manager
  201                          */
  202                         if ((pip = atm_pifname(acp->acr_att_intf)) == NULL)
  203                                 ATM_RETERR(ENXIO);
  204                         err = atm_sigmgr_attach(pip, acp->acr_att_proto);
  205                         break;
  206 
  207                 case AIOCS_CFG_DET:
  208                         /*
  209                          * Detach signalling manager
  210                          */
  211                         if ((pip = atm_pifname(acp->acr_det_intf)) == NULL)
  212                                 ATM_RETERR(ENXIO);
  213                         err = atm_sigmgr_detach(pip);
  214                         break;
  215 
  216                 default:
  217                         err = EOPNOTSUPP;
  218                 }
  219                 break;
  220         }
  221 
  222         case AIOCADD: {
  223                 struct atmaddreq        *aap = (struct atmaddreq *)data;
  224                 Atm_endpoint            *epp;
  225 
  226                 if (td && (suser(td) != 0))
  227                         ATM_RETERR(EPERM);
  228 
  229                 switch (aap->aar_opcode) {
  230 
  231                 case AIOCS_ADD_PVC:
  232                         /*
  233                          * Add a PVC definition
  234                          */
  235 
  236                         /*
  237                          * Locate requested endpoint service
  238                          */
  239                         epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL : 
  240                                         atm_endpoints[aap->aar_pvc_sap];
  241                         if (epp == NULL)
  242                                 ATM_RETERR(ENOPROTOOPT);
  243 
  244                         /*
  245                          * Let endpoint service handle it from here
  246                          */
  247                         err = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
  248                         break;
  249 
  250                 case AIOCS_ADD_ARP:
  251                         /*
  252                          * Add an ARP mapping
  253                          */
  254                         epp = atm_endpoints[ENDPT_IP];
  255                         if (epp == NULL)
  256                                 ATM_RETERR(ENOPROTOOPT);
  257 
  258                         /*
  259                          * Let IP/ATM endpoint handle this
  260                          */
  261                         err = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
  262                         break;
  263 
  264                 default:
  265                         err = EOPNOTSUPP;
  266                 }
  267                 break;
  268         }
  269 
  270         case AIOCDEL: {
  271                 struct atmdelreq        *adp = (struct atmdelreq *)data;
  272                 struct atm_pif          *pip;
  273                 struct sigmgr           *smp;
  274                 Atm_endpoint            *epp;
  275 
  276                 if (td && (suser(td) != 0))
  277                         ATM_RETERR(EPERM);
  278 
  279                 switch (adp->adr_opcode) {
  280 
  281                 case AIOCS_DEL_PVC:
  282                 case AIOCS_DEL_SVC:
  283                         /*
  284                          * Delete a PVC or SVC
  285                          */
  286 
  287                         /*
  288                          * Locate appropriate sigmgr
  289                          */
  290                         if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL)
  291                                 ATM_RETERR(ENXIO);
  292                         if ((smp = pip->pif_sigmgr) == NULL)
  293                                 ATM_RETERR(ENOENT);
  294 
  295                         /*
  296                          * Let sigmgr handle it from here
  297                          */
  298                         err = (*smp->sm_ioctl)(adp->adr_opcode, data, 
  299                                         (caddr_t)pip->pif_siginst);
  300                         break;
  301 
  302                 case AIOCS_DEL_ARP:
  303                         /*
  304                          * Delete an ARP mapping
  305                          */
  306                         epp = atm_endpoints[ENDPT_IP];
  307                         if (epp == NULL)
  308                                 ATM_RETERR(ENOPROTOOPT);
  309 
  310                         /*
  311                          * Let IP/ATM endpoint handle this
  312                          */
  313                         err = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
  314                         break;
  315 
  316                 default:
  317                         err = EOPNOTSUPP;
  318                 }
  319                 break;
  320         }
  321 
  322         case AIOCSET: {
  323                 struct atmsetreq        *asp = (struct atmsetreq *)data;
  324                 struct atm_pif          *pip;
  325                 struct atm_nif          *nip;
  326                 struct sigmgr           *smp;
  327                 struct ifnet            *ifp2;
  328 
  329                 if (td && (suser(td) != 0))
  330                         ATM_RETERR(EPERM);
  331 
  332                 switch (asp->asr_opcode) {
  333 
  334                 case AIOCS_SET_ASV:
  335                         /*
  336                          * Set an ARP server address
  337                          */
  338 
  339                         /*
  340                          * Locate appropriate sigmgr
  341                          */
  342                         if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL)
  343                                 ATM_RETERR(ENXIO);
  344                         pip = nip->nif_pif;
  345                         if ((smp = pip->pif_sigmgr) == NULL)
  346                                 ATM_RETERR(ENOENT);
  347 
  348                         /*
  349                          * Let sigmgr handle it from here
  350                          */
  351                         err = (*smp->sm_ioctl)(AIOCS_SET_ASV, data, 
  352                                         (caddr_t)nip);
  353                         break;
  354 
  355                 case AIOCS_SET_MAC:
  356                         /*
  357                          * Set physical interface MAC/ESI address
  358                          */
  359 
  360                         /*
  361                          * Locate physical interface
  362                          */
  363                         if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL)
  364                                 ATM_RETERR(ENXIO);
  365 
  366                         /*
  367                          * Interface must be detached
  368                          */
  369                         if (pip->pif_sigmgr != NULL)
  370                                 ATM_RETERR(EADDRINUSE);
  371 
  372                         /*
  373                          * Just plunk the address into the pif
  374                          */
  375                         bcopy((caddr_t)&asp->asr_mac_addr,
  376                                 (caddr_t)&pip->pif_macaddr,
  377                                 sizeof(struct mac_addr));
  378                         break;
  379 
  380                 case AIOCS_SET_NIF:
  381                         /*
  382                          * Define network interfaces
  383                          */
  384                         if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL)
  385                                 ATM_RETERR(ENXIO);
  386 
  387                         /*
  388                          * Validate interface count - logical interfaces
  389                          * are differentiated by the atm address selector.
  390                          */
  391                         if ((asp->asr_nif_cnt <= 0) || (asp->asr_nif_cnt > 256))
  392                                 ATM_RETERR(EINVAL);
  393 
  394                         /*
  395                          * Make sure prefix name is unique
  396                          */
  397                         IFNET_RLOCK();
  398                         TAILQ_FOREACH(ifp2, &ifnet, if_link) {
  399                                 if (!strcmp(ifp2->if_name, asp->asr_nif_pref)) {
  400                                         /*
  401                                          * If this is for the interface we're
  402                                          * (re-)defining, let it through
  403                                          */
  404                                         for (nip = pip->pif_nif; nip;
  405                                                         nip = nip->nif_pnext) {
  406                                                 if (&nip->nif_if == ifp2)
  407                                                         break;
  408                                         }
  409                                         if (nip)
  410                                                 continue;
  411                                         IFNET_RUNLOCK();
  412                                         ATM_RETERR(EEXIST);
  413                                 }
  414                         }
  415                         IFNET_RUNLOCK();
  416 
  417                         /*
  418                          * Let interface handle it from here
  419                          */
  420                         err = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
  421                                         (caddr_t)pip);
  422                         break;
  423 
  424                 case AIOCS_SET_PRF:
  425                         /*
  426                          * Set interface NSAP Prefix 
  427                          */
  428 
  429                         /*
  430                          * Locate appropriate sigmgr
  431                          */
  432                         if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL)
  433                                 ATM_RETERR(ENXIO);
  434                         if ((smp = pip->pif_sigmgr) == NULL)
  435                                 ATM_RETERR(ENOENT);
  436 
  437                         /*
  438                          * Let sigmgr handle it from here
  439                          */
  440                         err = (*smp->sm_ioctl)(AIOCS_SET_PRF, data, 
  441                                         (caddr_t)pip->pif_siginst);
  442                         break;
  443 
  444                 default:
  445                         err = EOPNOTSUPP;
  446                 }
  447                 break;
  448         }
  449 
  450         case AIOCINFO:
  451                 err = atm_dgram_info(data);
  452                 break;
  453 
  454         default:
  455                 err = EOPNOTSUPP;
  456         }
  457 
  458 out:
  459         ATM_OUTRO();
  460 }
  461 
  462 
  463 /*
  464  * Process AIOCINFO ioctl system calls
  465  *
  466  * Called at splnet.
  467  *
  468  * Arguments:
  469  *      data    pointer to AIOCINFO parameter structure
  470  *
  471  * Returns:
  472  *      0       request processed
  473  *      errno   error processing request - reason indicated
  474  *
  475  */
  476 static int
  477 atm_dgram_info(data)
  478         caddr_t                 data;
  479 {
  480         struct atminfreq        *aip = (struct atminfreq *)data;
  481         struct atm_pif          *pip;
  482         struct atm_nif          *nip;
  483         struct sigmgr           *smp;
  484         Atm_endpoint            *epp;
  485         int             len = aip->air_buf_len;
  486         int             err = 0;
  487 
  488         switch (aip->air_opcode) {
  489 
  490         case AIOCS_INF_VST:
  491         case AIOCS_INF_CFG:
  492                 /*
  493                  * Get vendor interface information
  494                  */
  495                 if (aip->air_vinfo_intf[0] != '\0') {
  496                         /*
  497                          * Interface specified
  498                          */
  499                         if ((pip = atm_pifname(aip->air_vinfo_intf))) {
  500                                 err = (*pip->pif_ioctl)(aip->air_opcode, data,
  501                                                 (caddr_t)pip);
  502                         } else {
  503                                 err = ENXIO;
  504                         }
  505                 } else {
  506                         /*
  507                          * Want info for every interface
  508                          */
  509                         for (pip = atm_interface_head; pip; 
  510                                         pip = pip->pif_next) {
  511                                 err = (*pip->pif_ioctl)(aip->air_opcode, data,
  512                                                 (caddr_t)pip);
  513                                 if (err)
  514                                         break;
  515                         }
  516                 }
  517                 break;
  518 
  519         case AIOCS_INF_IPM:
  520                 /*
  521                  * Get IP Map information
  522                  */
  523                 epp = atm_endpoints[ENDPT_IP];
  524                 if (epp) {
  525                         err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
  526                 } else {
  527                         err = ENOPROTOOPT;
  528                 }
  529                 break;
  530 
  531         case AIOCS_INF_ARP:
  532                 /*
  533                  * Get ARP table information
  534                  */
  535                 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
  536                         if ((smp = pip->pif_sigmgr) != NULL) {
  537                                 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
  538                                         data, (caddr_t)pip->pif_siginst);
  539                         }
  540                         if (err)
  541                                 break;
  542                 }
  543                 break;
  544 
  545         case AIOCS_INF_ASV:
  546                 /*
  547                  * Get ARP server information
  548                  */
  549                 if (aip->air_asrv_intf[0] != '\0') {
  550                         /*
  551                          * Interface specified
  552                          */
  553                         if ((nip = atm_nifname(aip->air_asrv_intf))) {
  554                                 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
  555                                         err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
  556                                                 data, (caddr_t)nip);
  557                                 }
  558                         } else {
  559                                 err = ENXIO;
  560                         }
  561                 } else {
  562                         /*
  563                          * Want info for all arp servers
  564                          */
  565                         for (pip = atm_interface_head; pip;
  566                                         pip = pip->pif_next) {
  567                                 if ((smp = pip->pif_sigmgr) != NULL) {
  568                                         for (nip = pip->pif_nif; nip; 
  569                                                         nip = nip->nif_pnext) {
  570                                                 err = (*smp->sm_ioctl)
  571                                                         (AIOCS_INF_ASV, data,
  572                                                         (caddr_t)nip);
  573                                                 if (err)
  574                                                         break;
  575                                         }
  576                                         if (err)
  577                                                 break;
  578                                 }
  579                         }
  580                 }
  581                 break;
  582 
  583         case AIOCS_INF_INT:
  584                 /*
  585                  * Get physical interface info
  586                  */
  587                 if (aip->air_int_intf[0] != '\0') {
  588                         /*
  589                          * Interface specified
  590                          */
  591                         if ((pip = atm_pifname(aip->air_int_intf))) {
  592                                 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
  593                                         data, (caddr_t)pip);
  594                         } else {
  595                                 err = ENXIO;
  596                         }
  597                 } else {
  598                         /*
  599                          * Want info for every physical interface
  600                          */
  601                         for (pip = atm_interface_head; pip; 
  602                                         pip = pip->pif_next) {
  603                                 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
  604                                                 data, (caddr_t)pip);
  605                                 if (err)
  606                                         break;
  607                         }
  608                 }
  609                 break;
  610 
  611         case AIOCS_INF_VCC:
  612                 /*
  613                  * Get VCC information
  614                  */
  615                 if (aip->air_vcc_intf[0] != '\0') {
  616                         /*
  617                          * Interface specified
  618                          */
  619                         if ((pip = atm_pifname(aip->air_vcc_intf))) {
  620                                 if ((smp = pip->pif_sigmgr) != NULL) {
  621                                         err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
  622                                                 data,
  623                                                 (caddr_t)pip->pif_siginst);
  624                                 } 
  625                         } else {
  626                                 err = ENXIO;
  627                         }
  628                 } else {
  629                         /*
  630                          * Want info for every interface
  631                          */
  632                         for (pip = atm_interface_head; pip; 
  633                                         pip = pip->pif_next) {
  634                                 if ((smp = pip->pif_sigmgr) != NULL) {
  635                                         err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
  636                                                 data,
  637                                                 (caddr_t)pip->pif_siginst);
  638                                 }
  639                                 if (err)
  640                                         break;
  641                         }
  642                 }
  643                 break;
  644 
  645         case AIOCS_INF_NIF:
  646                 /*
  647                  * Get network interface info
  648                  */
  649                 if (aip->air_int_intf[0] != '\0') {
  650                         /*
  651                          * Interface specified
  652                          */
  653                         if ((nip = atm_nifname(aip->air_int_intf))) {
  654                                 pip = nip->nif_pif;
  655                                 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
  656                                         data, (caddr_t)nip);
  657                         } else {
  658                                 err = ENXIO;
  659                         }
  660                 } else {
  661                         /*
  662                          * Want info for every network interface
  663                          */
  664                         for (pip = atm_interface_head; pip; 
  665                                         pip = pip->pif_next) {
  666                                 for (nip = pip->pif_nif; nip; 
  667                                                 nip = nip->nif_pnext) {
  668                                         err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
  669                                                         data, (caddr_t)nip);
  670                                         if (err)
  671                                                 break;
  672                                 }
  673                                 if (err)
  674                                         break;
  675                         }
  676                 }
  677                 break;
  678 
  679         case AIOCS_INF_PIS:
  680                 /*
  681                  * Get physical interface statistics
  682                  */
  683                 if (aip->air_physt_intf[0] != '\0') {
  684                         /*
  685                          * Interface specified
  686                          */
  687                         if ((pip = atm_pifname(aip->air_physt_intf))) {
  688                                 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
  689                                         data, (caddr_t)pip);
  690                         } else {
  691                                 err = ENXIO;
  692                         }
  693                 } else {
  694                         /*
  695                          * Want statistics for every physical interface
  696                          */
  697                         for (pip = atm_interface_head; pip; 
  698                                         pip = pip->pif_next) {
  699                                 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
  700                                                 data, (caddr_t)pip);
  701                                 if (err)
  702                                         break;
  703                         }
  704                 }
  705                 break;
  706 
  707         case AIOCS_INF_VER:
  708                 /*
  709                  * Get ATM software version
  710                  */
  711                 if (len < sizeof(atm_version)) {
  712                         err = ENOSPC;
  713                         break;
  714                 }
  715                 if ((err = copyout((caddr_t)&atm_version,
  716                                 aip->air_buf_addr,
  717                                 sizeof(atm_version))) != 0) {
  718                         break;
  719                 }
  720                 aip->air_buf_addr += sizeof(atm_version);
  721                 aip->air_buf_len -= sizeof(atm_version);
  722                 break;
  723 
  724         default:
  725                 err = EOPNOTSUPP;
  726         }
  727 
  728         /*
  729          * Calculate returned buffer length
  730          */
  731         aip->air_buf_len = len - aip->air_buf_len;
  732 
  733         return (err);
  734 }
  735 

Cache object: adf2a0a8a8b6a71d24544a53f9a70d5a


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