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

Cache object: fd09afc39638610e6abc52c274fb3942


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