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  -  FREEBSD10  -  FREEBSD9  -  FREEBSD92  -  FREEBSD91  -  FREEBSD90  -  FREEBSD8  -  FREEBSD82  -  FREEBSD81  -  FREEBSD80  -  FREEBSD7  -  FREEBSD74  -  FREEBSD73  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  cheribsd  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1  -  FREEBSD-LIBC  -  FREEBSD8-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
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.24 2005/06/10 16:49:20 brooks 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         .pru_abort =            atm_proto_notsupp1,
   70         .pru_attach =           atm_dgram_attach,
   71         .pru_bind =             atm_proto_notsupp2,
   72         .pru_control =          atm_dgram_control,
   73         .pru_detach =           atm_proto_notsupp1,
   74         .pru_disconnect =       atm_proto_notsupp1,
   75         .pru_peeraddr =         atm_proto_notsupp3,
   76         .pru_send =             atm_proto_notsupp4,
   77         .pru_shutdown =         atm_proto_notsupp1,
   78         .pru_sockaddr =         atm_proto_notsupp3,
   79         .pru_sosend =           NULL,
   80         .pru_soreceive =        NULL,
   81         .pru_sopoll =           NULL,
   82 };
   83 
   84 
   85 /*
   86  * Handy common code macros
   87  */
   88 #ifdef DIAGNOSTIC
   89 #define ATM_INTRO()                                             \
   90         int             s, err = 0;                             \
   91         s = splnet();                                           \
   92         /*                                                      \
   93          * Stack queue should have been drained                 \
   94          */                                                     \
   95         if (atm_stackq_head != NULL)                            \
   96                 panic("atm_usrreq: stack queue not empty");     \
   97         ;
   98 #else
   99 #define ATM_INTRO()                                             \
  100         int             s, err = 0;                             \
  101         s = splnet();                                           \
  102         ;
  103 #endif
  104 
  105 #define ATM_OUTRO()                                             \
  106         /*                                                      \
  107          * Drain any deferred calls                             \
  108          */                                                     \
  109         STACK_DRAIN();                                          \
  110         (void) splx(s);                                         \
  111         return (err);                                           \
  112         ;
  113 
  114 #define ATM_RETERR(errno) {                                     \
  115         err = errno;                                            \
  116         goto out;                                               \
  117 }
  118 
  119 
  120 /*
  121  * Attach protocol to socket
  122  *
  123  * Arguments:
  124  *      so      pointer to socket
  125  *      proto   protocol identifier
  126  *      p       pointer to process
  127  *
  128  * Returns:
  129  *      0       request processed
  130  *      errno   error processing request - reason indicated
  131  *
  132  */
  133 static int
  134 atm_dgram_attach(so, proto, td)
  135         struct socket   *so;
  136         int             proto;
  137         struct thread   *td;
  138 {
  139         ATM_INTRO();
  140 
  141         /*
  142          * Nothing to do here for ioctl()-only sockets
  143          */
  144         ATM_OUTRO();
  145 }
  146 
  147 
  148 /*
  149  * Process ioctl system calls
  150  *
  151  * Arguments:
  152  *      so      pointer to socket
  153  *      cmd     ioctl code
  154  *      data    pointer to code specific parameter data area
  155  *      ifp     pointer to ifnet structure if it's an interface ioctl
  156  *      p       pointer to process
  157  *
  158  * Returns:
  159  *      0       request processed
  160  *      errno   error processing request - reason indicated
  161  *
  162  */
  163 static int
  164 atm_dgram_control(so, cmd, data, ifp, td)
  165         struct socket   *so;
  166         u_long          cmd;
  167         caddr_t         data;
  168         struct ifnet    *ifp;
  169         struct thread   *td;
  170 {
  171         ATM_INTRO();
  172 
  173         /*
  174          * First, figure out which ioctl we're dealing with and
  175          * then process it based on the sub-op code
  176          */
  177         switch (cmd) {
  178 
  179         case AIOCCFG: {
  180                 struct atmcfgreq        *acp = (struct atmcfgreq *)data;
  181                 struct atm_pif          *pip;
  182 
  183                 if (td && (suser(td) != 0))
  184                         ATM_RETERR(EPERM);
  185 
  186                 switch (acp->acr_opcode) {
  187 
  188                 case AIOCS_CFG_ATT:
  189                         /*
  190                          * Attach signalling manager
  191                          */
  192                         if ((pip = atm_pifname(acp->acr_att_intf)) == NULL)
  193                                 ATM_RETERR(ENXIO);
  194                         err = atm_sigmgr_attach(pip, acp->acr_att_proto);
  195                         break;
  196 
  197                 case AIOCS_CFG_DET:
  198                         /*
  199                          * Detach signalling manager
  200                          */
  201                         if ((pip = atm_pifname(acp->acr_det_intf)) == NULL)
  202                                 ATM_RETERR(ENXIO);
  203                         err = atm_sigmgr_detach(pip);
  204                         break;
  205 
  206                 default:
  207                         err = EOPNOTSUPP;
  208                 }
  209                 break;
  210         }
  211 
  212         case AIOCADD: {
  213                 struct atmaddreq        *aap = (struct atmaddreq *)data;
  214                 Atm_endpoint            *epp;
  215 
  216                 if (td && (suser(td) != 0))
  217                         ATM_RETERR(EPERM);
  218 
  219                 switch (aap->aar_opcode) {
  220 
  221                 case AIOCS_ADD_PVC:
  222                         /*
  223                          * Add a PVC definition
  224                          */
  225 
  226                         /*
  227                          * Locate requested endpoint service
  228                          */
  229                         epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL : 
  230                                         atm_endpoints[aap->aar_pvc_sap];
  231                         if (epp == NULL)
  232                                 ATM_RETERR(ENOPROTOOPT);
  233 
  234                         /*
  235                          * Let endpoint service handle it from here
  236                          */
  237                         err = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
  238                         break;
  239 
  240                 case AIOCS_ADD_ARP:
  241                         /*
  242                          * Add an ARP mapping
  243                          */
  244                         epp = atm_endpoints[ENDPT_IP];
  245                         if (epp == NULL)
  246                                 ATM_RETERR(ENOPROTOOPT);
  247 
  248                         /*
  249                          * Let IP/ATM endpoint handle this
  250                          */
  251                         err = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
  252                         break;
  253 
  254                 default:
  255                         err = EOPNOTSUPP;
  256                 }
  257                 break;
  258         }
  259 
  260         case AIOCDEL: {
  261                 struct atmdelreq        *adp = (struct atmdelreq *)data;
  262                 struct atm_pif          *pip;
  263                 struct sigmgr           *smp;
  264                 Atm_endpoint            *epp;
  265 
  266                 if (td && (suser(td) != 0))
  267                         ATM_RETERR(EPERM);
  268 
  269                 switch (adp->adr_opcode) {
  270 
  271                 case AIOCS_DEL_PVC:
  272                 case AIOCS_DEL_SVC:
  273                         /*
  274                          * Delete a PVC or SVC
  275                          */
  276 
  277                         /*
  278                          * Locate appropriate sigmgr
  279                          */
  280                         if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL)
  281                                 ATM_RETERR(ENXIO);
  282                         if ((smp = pip->pif_sigmgr) == NULL)
  283                                 ATM_RETERR(ENOENT);
  284 
  285                         /*
  286                          * Let sigmgr handle it from here
  287                          */
  288                         err = (*smp->sm_ioctl)(adp->adr_opcode, data, 
  289                                         (caddr_t)pip->pif_siginst);
  290                         break;
  291 
  292                 case AIOCS_DEL_ARP:
  293                         /*
  294                          * Delete an ARP mapping
  295                          */
  296                         epp = atm_endpoints[ENDPT_IP];
  297                         if (epp == NULL)
  298                                 ATM_RETERR(ENOPROTOOPT);
  299 
  300                         /*
  301                          * Let IP/ATM endpoint handle this
  302                          */
  303                         err = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
  304                         break;
  305 
  306                 default:
  307                         err = EOPNOTSUPP;
  308                 }
  309                 break;
  310         }
  311 
  312         case AIOCSET: {
  313                 struct atmsetreq        *asp = (struct atmsetreq *)data;
  314                 struct atm_pif          *pip;
  315                 struct atm_nif          *nip;
  316                 struct sigmgr           *smp;
  317                 struct ifnet            *ifp2;
  318 
  319                 if (td && (suser(td) != 0))
  320                         ATM_RETERR(EPERM);
  321 
  322                 switch (asp->asr_opcode) {
  323 
  324                 case AIOCS_SET_ASV:
  325                         /*
  326                          * Set an ARP server address
  327                          */
  328 
  329                         /*
  330                          * Locate appropriate sigmgr
  331                          */
  332                         if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL)
  333                                 ATM_RETERR(ENXIO);
  334                         pip = nip->nif_pif;
  335                         if ((smp = pip->pif_sigmgr) == NULL)
  336                                 ATM_RETERR(ENOENT);
  337 
  338                         /*
  339                          * Let sigmgr handle it from here
  340                          */
  341                         err = (*smp->sm_ioctl)(AIOCS_SET_ASV, data, 
  342                                         (caddr_t)nip);
  343                         break;
  344 
  345                 case AIOCS_SET_MAC:
  346                         /*
  347                          * Set physical interface MAC/ESI address
  348                          */
  349 
  350                         /*
  351                          * Locate physical interface
  352                          */
  353                         if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL)
  354                                 ATM_RETERR(ENXIO);
  355 
  356                         /*
  357                          * Interface must be detached
  358                          */
  359                         if (pip->pif_sigmgr != NULL)
  360                                 ATM_RETERR(EADDRINUSE);
  361 
  362                         /*
  363                          * Just plunk the address into the pif
  364                          */
  365                         bcopy((caddr_t)&asp->asr_mac_addr,
  366                                 (caddr_t)&pip->pif_macaddr,
  367                                 sizeof(struct mac_addr));
  368                         break;
  369 
  370                 case AIOCS_SET_NIF:
  371                         /*
  372                          * Define network interfaces
  373                          */
  374                         if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL)
  375                                 ATM_RETERR(ENXIO);
  376 
  377                         /*
  378                          * Validate interface count - logical interfaces
  379                          * are differentiated by the atm address selector.
  380                          */
  381                         if (asp->asr_nif_cnt == 0 || asp->asr_nif_cnt > 256)
  382                                 ATM_RETERR(EINVAL);
  383 
  384                         /*
  385                          * Make sure prefix name is unique
  386                          */
  387                         IFNET_RLOCK();
  388                         TAILQ_FOREACH(ifp2, &ifnet, if_link) {
  389                                 if (!strcmp(ifp2->if_dname, asp->asr_nif_pref)) {
  390                                         /*
  391                                          * If this is for the interface we're
  392                                          * (re-)defining, let it through
  393                                          */
  394                                         for (nip = pip->pif_nif; nip;
  395                                                         nip = nip->nif_pnext) {
  396                                                 if (ANIF2IFP(nip) == ifp2)
  397                                                         break;
  398                                         }
  399                                         if (nip)
  400                                                 continue;
  401                                         IFNET_RUNLOCK();
  402                                         ATM_RETERR(EEXIST);
  403                                 }
  404                         }
  405                         IFNET_RUNLOCK();
  406 
  407                         /*
  408                          * Let interface handle it from here
  409                          */
  410                         err = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
  411                                         (caddr_t)pip);
  412                         break;
  413 
  414                 case AIOCS_SET_PRF:
  415                         /*
  416                          * Set interface NSAP Prefix 
  417                          */
  418 
  419                         /*
  420                          * Locate appropriate sigmgr
  421                          */
  422                         if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL)
  423                                 ATM_RETERR(ENXIO);
  424                         if ((smp = pip->pif_sigmgr) == NULL)
  425                                 ATM_RETERR(ENOENT);
  426 
  427                         /*
  428                          * Let sigmgr handle it from here
  429                          */
  430                         err = (*smp->sm_ioctl)(AIOCS_SET_PRF, data, 
  431                                         (caddr_t)pip->pif_siginst);
  432                         break;
  433 
  434                 default:
  435                         err = EOPNOTSUPP;
  436                 }
  437                 break;
  438         }
  439 
  440         case AIOCINFO:
  441                 err = atm_dgram_info(data);
  442                 break;
  443 
  444         default:
  445                 err = EOPNOTSUPP;
  446         }
  447 
  448 out:
  449         ATM_OUTRO();
  450 }
  451 
  452 
  453 /*
  454  * Process AIOCINFO ioctl system calls
  455  *
  456  * Called at splnet.
  457  *
  458  * Arguments:
  459  *      data    pointer to AIOCINFO parameter structure
  460  *
  461  * Returns:
  462  *      0       request processed
  463  *      errno   error processing request - reason indicated
  464  *
  465  */
  466 static int
  467 atm_dgram_info(data)
  468         caddr_t                 data;
  469 {
  470         struct atminfreq        *aip = (struct atminfreq *)data;
  471         struct atm_pif          *pip;
  472         struct atm_nif          *nip;
  473         struct sigmgr           *smp;
  474         Atm_endpoint            *epp;
  475         int             len = aip->air_buf_len;
  476         int             err = 0;
  477 
  478         switch (aip->air_opcode) {
  479 
  480         case AIOCS_INF_VST:
  481         case AIOCS_INF_CFG:
  482                 /*
  483                  * Get vendor interface information
  484                  */
  485                 if (aip->air_vinfo_intf[0] != '\0') {
  486                         /*
  487                          * Interface specified
  488                          */
  489                         if ((pip = atm_pifname(aip->air_vinfo_intf))) {
  490                                 err = (*pip->pif_ioctl)(aip->air_opcode, data,
  491                                                 (caddr_t)pip);
  492                         } else {
  493                                 err = ENXIO;
  494                         }
  495                 } else {
  496                         /*
  497                          * Want info for every interface
  498                          */
  499                         for (pip = atm_interface_head; pip; 
  500                                         pip = pip->pif_next) {
  501                                 err = (*pip->pif_ioctl)(aip->air_opcode, data,
  502                                                 (caddr_t)pip);
  503                                 if (err)
  504                                         break;
  505                         }
  506                 }
  507                 break;
  508 
  509         case AIOCS_INF_IPM:
  510                 /*
  511                  * Get IP Map information
  512                  */
  513                 epp = atm_endpoints[ENDPT_IP];
  514                 if (epp) {
  515                         err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
  516                 } else {
  517                         err = ENOPROTOOPT;
  518                 }
  519                 break;
  520 
  521         case AIOCS_INF_ARP:
  522                 /*
  523                  * Get ARP table information
  524                  */
  525                 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
  526                         if ((smp = pip->pif_sigmgr) != NULL) {
  527                                 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
  528                                         data, (caddr_t)pip->pif_siginst);
  529                         }
  530                         if (err)
  531                                 break;
  532                 }
  533                 break;
  534 
  535         case AIOCS_INF_ASV:
  536                 /*
  537                  * Get ARP server information
  538                  */
  539                 if (aip->air_asrv_intf[0] != '\0') {
  540                         /*
  541                          * Interface specified
  542                          */
  543                         if ((nip = atm_nifname(aip->air_asrv_intf))) {
  544                                 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
  545                                         err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
  546                                                 data, (caddr_t)nip);
  547                                 }
  548                         } else {
  549                                 err = ENXIO;
  550                         }
  551                 } else {
  552                         /*
  553                          * Want info for all arp servers
  554                          */
  555                         for (pip = atm_interface_head; pip;
  556                                         pip = pip->pif_next) {
  557                                 if ((smp = pip->pif_sigmgr) != NULL) {
  558                                         for (nip = pip->pif_nif; nip; 
  559                                                         nip = nip->nif_pnext) {
  560                                                 err = (*smp->sm_ioctl)
  561                                                         (AIOCS_INF_ASV, data,
  562                                                         (caddr_t)nip);
  563                                                 if (err)
  564                                                         break;
  565                                         }
  566                                         if (err)
  567                                                 break;
  568                                 }
  569                         }
  570                 }
  571                 break;
  572 
  573         case AIOCS_INF_INT:
  574                 /*
  575                  * Get physical interface info
  576                  */
  577                 if (aip->air_int_intf[0] != '\0') {
  578                         /*
  579                          * Interface specified
  580                          */
  581                         if ((pip = atm_pifname(aip->air_int_intf))) {
  582                                 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
  583                                         data, (caddr_t)pip);
  584                         } else {
  585                                 err = ENXIO;
  586                         }
  587                 } else {
  588                         /*
  589                          * Want info for every physical interface
  590                          */
  591                         for (pip = atm_interface_head; pip; 
  592                                         pip = pip->pif_next) {
  593                                 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
  594                                                 data, (caddr_t)pip);
  595                                 if (err)
  596                                         break;
  597                         }
  598                 }
  599                 break;
  600 
  601         case AIOCS_INF_VCC:
  602                 /*
  603                  * Get VCC information
  604                  */
  605                 if (aip->air_vcc_intf[0] != '\0') {
  606                         /*
  607                          * Interface specified
  608                          */
  609                         if ((pip = atm_pifname(aip->air_vcc_intf))) {
  610                                 if ((smp = pip->pif_sigmgr) != NULL) {
  611                                         err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
  612                                                 data,
  613                                                 (caddr_t)pip->pif_siginst);
  614                                 } 
  615                         } else {
  616                                 err = ENXIO;
  617                         }
  618                 } else {
  619                         /*
  620                          * Want info for every interface
  621                          */
  622                         for (pip = atm_interface_head; pip; 
  623                                         pip = pip->pif_next) {
  624                                 if ((smp = pip->pif_sigmgr) != NULL) {
  625                                         err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
  626                                                 data,
  627                                                 (caddr_t)pip->pif_siginst);
  628                                 }
  629                                 if (err)
  630                                         break;
  631                         }
  632                 }
  633                 break;
  634 
  635         case AIOCS_INF_NIF:
  636                 /*
  637                  * Get network interface info
  638                  */
  639                 if (aip->air_int_intf[0] != '\0') {
  640                         /*
  641                          * Interface specified
  642                          */
  643                         if ((nip = atm_nifname(aip->air_int_intf))) {
  644                                 pip = nip->nif_pif;
  645                                 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
  646                                         data, (caddr_t)nip);
  647                         } else {
  648                                 err = ENXIO;
  649                         }
  650                 } else {
  651                         /*
  652                          * Want info for every network interface
  653                          */
  654                         for (pip = atm_interface_head; pip; 
  655                                         pip = pip->pif_next) {
  656                                 for (nip = pip->pif_nif; nip; 
  657                                                 nip = nip->nif_pnext) {
  658                                         err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
  659                                                         data, (caddr_t)nip);
  660                                         if (err)
  661                                                 break;
  662                                 }
  663                                 if (err)
  664                                         break;
  665                         }
  666                 }
  667                 break;
  668 
  669         case AIOCS_INF_PIS:
  670                 /*
  671                  * Get physical interface statistics
  672                  */
  673                 if (aip->air_physt_intf[0] != '\0') {
  674                         /*
  675                          * Interface specified
  676                          */
  677                         if ((pip = atm_pifname(aip->air_physt_intf))) {
  678                                 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
  679                                         data, (caddr_t)pip);
  680                         } else {
  681                                 err = ENXIO;
  682                         }
  683                 } else {
  684                         /*
  685                          * Want statistics for every physical interface
  686                          */
  687                         for (pip = atm_interface_head; pip; 
  688                                         pip = pip->pif_next) {
  689                                 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
  690                                                 data, (caddr_t)pip);
  691                                 if (err)
  692                                         break;
  693                         }
  694                 }
  695                 break;
  696 
  697         case AIOCS_INF_VER:
  698                 /*
  699                  * Get ATM software version
  700                  */
  701                 if (len < sizeof(atm_version)) {
  702                         err = ENOSPC;
  703                         break;
  704                 }
  705                 if ((err = copyout((caddr_t)&atm_version,
  706                                 aip->air_buf_addr,
  707                                 sizeof(atm_version))) != 0) {
  708                         break;
  709                 }
  710                 aip->air_buf_addr += sizeof(atm_version);
  711                 aip->air_buf_len -= sizeof(atm_version);
  712                 break;
  713 
  714         default:
  715                 err = EOPNOTSUPP;
  716         }
  717 
  718         /*
  719          * Calculate returned buffer length
  720          */
  721         aip->air_buf_len = len - aip->air_buf_len;
  722 
  723         return (err);
  724 }
  725 

Cache object: 081523a7b64500e338d18bdf7a730b99


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