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/netiso/clnp_options.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 /*      $NetBSD: clnp_options.c,v 1.14 2004/04/19 05:16:45 matt Exp $   */
    2 
    3 /*-
    4  * Copyright (c) 1991, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the University nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  *      @(#)clnp_options.c      8.1 (Berkeley) 6/10/93
   32  */
   33 
   34 /***********************************************************
   35                 Copyright IBM Corporation 1987
   36 
   37                       All Rights Reserved
   38 
   39 Permission to use, copy, modify, and distribute this software and its
   40 documentation for any purpose and without fee is hereby granted,
   41 provided that the above copyright notice appear in all copies and that
   42 both that copyright notice and this permission notice appear in
   43 supporting documentation, and that the name of IBM not be
   44 used in advertising or publicity pertaining to distribution of the
   45 software without specific, written prior permission.
   46 
   47 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
   48 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
   49 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
   50 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   51 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
   52 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
   53 SOFTWARE.
   54 
   55 ******************************************************************/
   56 
   57 /*
   58  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
   59  */
   60 
   61 #include <sys/cdefs.h>
   62 __KERNEL_RCSID(0, "$NetBSD: clnp_options.c,v 1.14 2004/04/19 05:16:45 matt Exp $");
   63 
   64 #include "opt_iso.h"
   65 #ifdef ISO
   66 
   67 #include <sys/param.h>
   68 #include <sys/mbuf.h>
   69 #include <sys/domain.h>
   70 #include <sys/protosw.h>
   71 #include <sys/socket.h>
   72 #include <sys/socketvar.h>
   73 #include <sys/errno.h>
   74 #include <sys/systm.h>
   75 
   76 #include <net/if.h>
   77 #include <net/route.h>
   78 
   79 #include <netiso/iso.h>
   80 #include <netiso/clnp.h>
   81 #include <netiso/clnp_stat.h>
   82 #include <netiso/argo_debug.h>
   83 
   84 /*
   85  * FUNCTION:            clnp_update_srcrt
   86  *
   87  * PURPOSE:             Process src rt option accompanying a clnp datagram.
   88  *                      - bump src route ptr if src routing and
   89  *                      we appear current in src route list.
   90  *
   91  * RETURNS:             none
   92  *
   93  * SIDE EFFECTS:
   94  *
   95  * NOTES:               If source routing has been terminated, do nothing.
   96  */
   97 void
   98 clnp_update_srcrt(
   99         struct mbuf *options,           /* ptr to options mbuf */
  100         struct clnp_optidx *oidx)       /* ptr to option index */
  101 {
  102         u_char          len;    /* length of current address */
  103         struct iso_addr isoa;   /* copy current address into here */
  104 
  105         if (CLNPSRCRT_TERM(oidx, options)) {
  106 #ifdef ARGO_DEBUG
  107                 if (argo_debug[D_OPTIONS]) {
  108                         printf("clnp_update_srcrt: src rt terminated\n");
  109                 }
  110 #endif
  111                 return;
  112         }
  113         len = CLNPSRCRT_CLEN(oidx, options);
  114         bcopy(CLNPSRCRT_CADDR(oidx, options), (caddr_t) & isoa, len);
  115         isoa.isoa_len = len;
  116 
  117 #ifdef ARGO_DEBUG
  118         if (argo_debug[D_OPTIONS]) {
  119                 printf("clnp_update_srcrt: current src rt: %s\n",
  120                     clnp_iso_addrp(&isoa));
  121         }
  122 #endif
  123 
  124         if (clnp_ours(&isoa)) {
  125 #ifdef ARGO_DEBUG
  126                 if (argo_debug[D_OPTIONS]) {
  127                         printf("clnp_update_srcrt: updating src rt\n");
  128                 }
  129 #endif
  130 
  131                 /* update pointer to next src route */
  132                 len++;          /* count length byte too! */
  133                 CLNPSRCRT_OFF(oidx, options) += len;
  134         }
  135 }
  136 
  137 /*
  138  * FUNCTION:            clnp_dooptions
  139  *
  140  * PURPOSE:             Process options accompanying a clnp datagram.
  141  *                      Processing includes
  142  *                      - log our address if recording route
  143  *
  144  * RETURNS:                     none
  145  *
  146  * SIDE EFFECTS:
  147  *
  148  * NOTES:
  149  */
  150 void
  151 clnp_dooptions(
  152         struct mbuf *options,           /* ptr to options mbuf */
  153         struct clnp_optidx *oidx,       /* ptr to option index */
  154         struct ifnet *ifp,              /* ptr to interface pkt is leaving on */
  155         struct iso_addr *isoa)          /* ptr to our address for this ifp */
  156 {
  157         /*
  158          *      If record route is specified, move all
  159          *      existing records over, and insert the address of
  160          *      interface passed
  161          */
  162         if (oidx->cni_recrtp) {
  163                 char           *opt;    /* ptr to beginning of recrt option */
  164                 u_char          off;    /* offset from opt of first free byte */
  165                 char           *rec_start;      /* beginning of new rt
  166                                                  * recorded */
  167 
  168                 opt = CLNP_OFFTOOPT(options, oidx->cni_recrtp);
  169                 off = *(opt + 1);
  170                 rec_start = opt + off - 1;
  171 
  172 #ifdef ARGO_DEBUG
  173                 if (argo_debug[D_OPTIONS]) {
  174                         printf("clnp_dooptions: record route: option %p for %d bytes\n",
  175                             opt, oidx->cni_recrt_len);
  176                         printf("\tfree slot offset x%x\n", off);
  177                         printf("clnp_dooptions: recording %s\n", clnp_iso_addrp(isoa));
  178                         printf("clnp_dooptions: option dump:\n");
  179                         dump_buf(opt, oidx->cni_recrt_len);
  180                 }
  181 #endif
  182 
  183                 /* proceed only if recording has not been terminated */
  184                 if (off != 0xff) {
  185                         int             new_addrlen = isoa->isoa_len + 1;
  186                         /*
  187                          * if there is insufficient room to store the next
  188                          * address, then terminate recording. Plus 1 on
  189                          * isoa_len is for the length byte itself
  190                          */
  191                         if (oidx->cni_recrt_len - (off - 1) < new_addrlen) {
  192                                 *(opt + 1) = 0xff;      /* terminate recording */
  193                         } else {
  194 #ifdef ARGO_DEBUG
  195                                 if (argo_debug[D_OPTIONS]) {
  196                                         printf("clnp_dooptions: new addr at %p for %d\n",
  197                                                rec_start, new_addrlen);
  198                                 }
  199 #endif
  200 
  201                                 bcopy((caddr_t) isoa, rec_start, new_addrlen);
  202 
  203                                 /* update offset field */
  204                                 *(opt + 1) += new_addrlen;
  205 
  206 #ifdef ARGO_DEBUG
  207                                 if (argo_debug[D_OPTIONS]) {
  208                                         printf("clnp_dooptions: new option dump:\n");
  209                                         dump_buf(opt, oidx->cni_recrt_len);
  210                                 }
  211 #endif
  212                         }
  213                 }
  214         }
  215 }
  216 
  217 /*
  218  * FUNCTION:            clnp_set_opts
  219  *
  220  * PURPOSE:             Check the data mbuf passed for option sanity. If it is
  221  *                      ok, then set the options ptr to address the data mbuf.
  222  *                      If an options mbuf exists, free it. This implies that
  223  *                      any old options will be lost. If data is NULL, simply
  224  *                      free any old options.
  225  *
  226  * RETURNS:             unix error code
  227  *
  228  * SIDE EFFECTS:
  229  *
  230  * NOTES:
  231  */
  232 int
  233 clnp_set_opts(
  234         struct mbuf **options,  /* target for option information */
  235         struct mbuf **data)     /* source of option information */
  236 {
  237         int             error = 0;      /* error return value */
  238         struct clnp_optidx dummy;       /* dummy index - not used */
  239 
  240         /*
  241          *      remove any existing options
  242          */
  243         if (*options != NULL) {
  244                 m_freem(*options);
  245                 *options = NULL;
  246         }
  247         if (*data != NULL) {
  248                 /*
  249                  *      Insure that the options are reasonable.
  250                  *
  251                  *      Also, we do not support security, priority,
  252                  *      nor do we allow one to send an ER option
  253                  *
  254                  *      The QOS parameter is checked for the DECBIT.
  255                  */
  256                 if ((clnp_opt_sanity(*data, mtod(*data, caddr_t), (*data)->m_len,
  257                                      &dummy) != 0) ||
  258                     (dummy.cni_securep) ||
  259                     (dummy.cni_priorp) ||
  260                     (dummy.cni_er_reason != ER_INVALREAS)) {
  261                         error = EINVAL;
  262                 } else {
  263                         *options = *data;
  264                         *data = NULL;   /* so caller won't free mbuf @ *data */
  265                 }
  266         }
  267         return error;
  268 }
  269 
  270 /*
  271  * FUNCTION:            clnp_opt_sanity
  272  *
  273  * PURPOSE:             Check the options (beginning at opts for len bytes) for
  274  *                      sanity. In addition, fill in the option index structure
  275  *                      in with information about each option discovered.
  276  *
  277  * RETURNS:             success (options check out) - 0
  278  *                      failure - an ER pdu error code describing failure
  279  *
  280  * SIDE EFFECTS:
  281  *
  282  * NOTES:               Each pointer field of the option index is filled in with
  283  *                      the offset from the beginning of the mbuf data, not the
  284  *                      actual address.
  285  */
  286 int
  287 clnp_opt_sanity(
  288         struct mbuf    *m,      /* mbuf options reside in */
  289         caddr_t         opts,   /* ptr to buffer containing options */
  290         int             len,    /* length of buffer */
  291         struct clnp_optidx *oidx)       /* RETURN: filled in with option idx
  292                                          * info */
  293 {
  294         u_char          opcode = 0;     /* code of particular option */
  295         u_char          oplen;  /* length of a particular option */
  296         caddr_t         opts_end;       /* ptr to end of options */
  297         u_char          pad = 0, secure = 0, srcrt = 0, recrt = 0,
  298                         qos = 0, prior = 0;
  299         /* flags for catching duplicate options */
  300 
  301 #ifdef ARGO_DEBUG
  302         if (argo_debug[D_OPTIONS]) {
  303                 printf("clnp_opt_sanity: checking %d bytes of data:\n", len);
  304                 dump_buf(opts, len);
  305         }
  306 #endif
  307 
  308         /* clear option index field if passed */
  309         bzero((caddr_t) oidx, sizeof(struct clnp_optidx));
  310 
  311         /*
  312          *      We need to indicate whether the ER option is present. This is done
  313          *      by overloading the er_reason field to also indicate presence of
  314          *      the option along with the option value. I would like ER_INVALREAS
  315          *      to have value 0, but alas, 0 is a valid er reason...
  316          */
  317         oidx->cni_er_reason = ER_INVALREAS;
  318 
  319         opts_end = opts + len;
  320         while (opts < opts_end) {
  321                 /* must have at least 2 bytes per option (opcode and len) */
  322                 if (opts + 2 > opts_end)
  323                         return (GEN_INCOMPLETE);
  324 
  325                 opcode = *opts++;
  326                 oplen = *opts++;
  327 #ifdef ARGO_DEBUG
  328                 if (argo_debug[D_OPTIONS]) {
  329                         printf("clnp_opt_sanity: opcode is %x and oplen %d\n",
  330                             opcode, oplen);
  331                         printf("clnp_opt_sanity: clnpoval_SRCRT is %x\n", CLNPOVAL_SRCRT);
  332 
  333                         switch (opcode) {
  334                         case CLNPOVAL_PAD:
  335                                 printf("CLNPOVAL_PAD\n");
  336                                 break;
  337                         case CLNPOVAL_SECURE:
  338                                 printf("CLNPOVAL_SECURE\n");
  339                                 break;
  340                         case CLNPOVAL_SRCRT:
  341                                 printf("CLNPOVAL_SRCRT\n");
  342                                 break;
  343                         case CLNPOVAL_RECRT:
  344                                 printf("CLNPOVAL_RECRT\n");
  345                                 break;
  346                         case CLNPOVAL_QOS:
  347                                 printf("CLNPOVAL_QOS\n");
  348                                 break;
  349                         case CLNPOVAL_PRIOR:
  350                                 printf("CLNPOVAL_PRIOR\n");
  351                                 break;
  352                         case CLNPOVAL_ERREAS:
  353                                 printf("CLNPOVAL_ERREAS\n");
  354                                 break;
  355                         default:
  356                                 printf("UNKNOWN option %x\n", opcode);
  357                                 break;
  358                         }
  359                 }
  360 #endif
  361 
  362                 /* don't allow crazy length values */
  363                 if (opts + oplen > opts_end)
  364                         return (GEN_INCOMPLETE);
  365 
  366                 switch (opcode) {
  367                 case CLNPOVAL_PAD:
  368                         /*
  369                          *      Padding: increment pointer by length of padding
  370                          */
  371                         if (pad++)      /* duplicate ? */
  372                                 return (GEN_DUPOPT);
  373                         opts += oplen;
  374                         break;
  375 
  376                 case CLNPOVAL_SECURE:{
  377                                 u_char          format = *opts;
  378 
  379                                 if (secure++)   /* duplicate ? */
  380                                         return (GEN_DUPOPT);
  381                                 /*
  382                                  *      Security: high 2 bits of first octet indicate format
  383                                  *      (00 in high bits is reserved).
  384                                  *      Remaining bits must be 0. Remaining octets indicate
  385                                  *      actual security
  386                                  */
  387                                 if (((format & 0x3f) > 0) ||    /* low 6 bits set ? */
  388                                     ((format & 0xc0) == 0))     /* high 2 bits zero ? */
  389                                         return (GEN_HDRSYNTAX);
  390 
  391                                 oidx->cni_securep = CLNP_OPTTOOFF(m, opts);
  392                                 oidx->cni_secure_len = oplen;
  393                                 opts += oplen;
  394                         } break;
  395 
  396                 case CLNPOVAL_SRCRT:{
  397                                 u_char          type, offset;   /* type of rt, offset of
  398                                                                  * start */
  399                                 caddr_t         route_end;      /* address of end of
  400                                                                  * route option */
  401 
  402 #ifdef ARGO_DEBUG
  403                                 if (argo_debug[D_OPTIONS]) {
  404                                         printf("clnp_opt_sanity: SRC RT\n");
  405                                 }
  406 #endif
  407 
  408                                 if (srcrt++)    /* duplicate ? */
  409                                         return (GEN_DUPOPT);
  410                                 /*
  411                                  * source route: There must be 2 bytes
  412                                  * following the length field: type and
  413                                  * offset. The type must be either partial
  414                                  * route or complete route. The offset field
  415                                  * must be within the option. A single
  416                                  * exception is made, however. The offset may
  417                                  * be 1 greater than the length. This case
  418                                  * occurs when the last source route record
  419                                  * is consumed. In this case, we ignore the
  420                                  * source route option. RAH? You should be
  421                                  * able to set offset to 'ff' like in record
  422                                  * route! Following this is a series of
  423                                  * address fields. Each address field is
  424                                  * composed of a (length, address) pair.
  425                                  * Insure that the offset and each address
  426                                  * length is reasonable
  427                                  */
  428                                 route_end = opts + oplen;
  429 
  430                                 if (opts + 2 > route_end)
  431                                         return (SRCRT_SYNTAX);
  432 
  433                                 type = *opts;
  434                                 offset = *(opts + 1);
  435 
  436 
  437                                 /* type must be partial or complete */
  438                                 if (!((type == CLNPOVAL_PARTRT) || (type == CLNPOVAL_COMPRT)))
  439                                         return (SRCRT_SYNTAX);
  440 
  441                                 oidx->cni_srcrt_s = CLNP_OPTTOOFF(m, opts);
  442                                 oidx->cni_srcrt_len = oplen;
  443 
  444                                 opts += offset - 1;     /* set opts to first
  445                                                          * addr in rt */
  446 
  447                                 /*
  448                                  * Offset must be reasonable: less than end
  449                                  * of options, or equal to end of options
  450                                  */
  451                                 if (opts >= route_end) {
  452                                         if (opts == route_end) {
  453 #ifdef ARGO_DEBUG
  454                                                 if (argo_debug[D_OPTIONS]) {
  455                                                         printf("clnp_opt_sanity: end of src route info\n");
  456                                                 }
  457 #endif
  458                                                 break;
  459                                         } else
  460                                                 return (SRCRT_SYNTAX);
  461                                 }
  462                                 while (opts < route_end) {
  463                                         u_char          addrlen = *opts++;
  464                                         if (opts + addrlen > route_end)
  465                                                 return (SRCRT_SYNTAX);
  466                                         opts += addrlen;
  467                                 }
  468                         } break;
  469                 case CLNPOVAL_RECRT:{
  470                                 u_char          type, offset;   /* type of rt, offset of
  471                                                                  * start */
  472                                 caddr_t         record_end;     /* address of end of
  473                                                                  * record option */
  474 
  475                                 if (recrt++)    /* duplicate ? */
  476                                         return (GEN_DUPOPT);
  477                                 /*
  478                                  *      record route: after the length field, expect a
  479                                  *      type and offset. Type must be partial or complete.
  480                                  *      Offset indicates where to start recording. Insure it
  481                                  *      is within the option. All ones for offset means
  482                                  *      recording is terminated.
  483                                  */
  484                                 record_end = opts + oplen;
  485 
  486                                 oidx->cni_recrtp = CLNP_OPTTOOFF(m, opts);
  487                                 oidx->cni_recrt_len = oplen;
  488 
  489                                 if (opts + 2 > record_end)
  490                                         return (GEN_INCOMPLETE);
  491 
  492                                 type = *opts;
  493                                 offset = *(opts + 1);
  494 
  495                                 /* type must be partial or complete */
  496                                 if (!((type == CLNPOVAL_PARTRT) || (type == CLNPOVAL_COMPRT)))
  497                                         return (GEN_HDRSYNTAX);
  498 
  499                                 /* offset must be reasonable */
  500                                 if ((offset < 0xff) && (opts + offset > record_end))
  501                                         return (GEN_HDRSYNTAX);
  502                                 opts += oplen;
  503                         } break;
  504                 case CLNPOVAL_QOS:{
  505                                 u_char          format = *opts;
  506 
  507                                 if (qos++)      /* duplicate ? */
  508                                         return (GEN_DUPOPT);
  509                                 /*
  510                                  *      qos: high 2 bits of first octet indicate format
  511                                  *      (00 in high bits is reserved).
  512                                  *      Remaining bits must be 0 (unless format indicates
  513                                  *      globally unique qos, in which case remaining bits indicate
  514                                  *      qos (except bit 6 which is reserved)).  Otherwise,
  515                                  *      remaining octets indicate actual qos.
  516                                  */
  517                                 if (((format & 0xc0) == 0) ||   /* high 2 bits zero ? */
  518                                     (((format & 0xc0) != CLNPOVAL_GLOBAL) &&
  519                                      ((format & 0x3f) > 0)))    /* not global,low bits
  520                                                                  * used ? */
  521                                         return (GEN_HDRSYNTAX);
  522 
  523                                 oidx->cni_qos_formatp = CLNP_OPTTOOFF(m, opts);
  524                                 oidx->cni_qos_len = oplen;
  525 
  526                                 opts += oplen;
  527                         } break;
  528 
  529                 case CLNPOVAL_PRIOR:{
  530                                 if (prior++)    /* duplicate ? */
  531                                         return (GEN_DUPOPT);
  532                                 /*
  533                                  *      priority: value must be one byte long
  534                                  */
  535                                 if (oplen != 1)
  536                                         return (GEN_HDRSYNTAX);
  537 
  538                                 oidx->cni_priorp = CLNP_OPTTOOFF(m, opts);
  539 
  540                                 opts += oplen;
  541                         } break;
  542 
  543                 case CLNPOVAL_ERREAS:{
  544                                 /*
  545                                  *      er reason: value must be two bytes long
  546                                  */
  547                                 if (oplen != 2)
  548                                         return (GEN_HDRSYNTAX);
  549 
  550                                 oidx->cni_er_reason = *opts;
  551 
  552                                 opts += oplen;
  553                         } break;
  554 
  555                 default:{
  556 #ifdef ARGO_DEBUG
  557                                 if (argo_debug[D_OPTIONS]) {
  558                                         printf("clnp_opt_sanity: UNKNOWN OPTION 0x%x\n", opcode);
  559                                 }
  560 #endif
  561                                 return (DISC_UNSUPPOPT);
  562                         }
  563                 }
  564         }
  565 #ifdef ARGO_DEBUG
  566         if (argo_debug[D_OPTIONS]) {
  567                 printf("clnp_opt_sanity: return(0)\n");
  568         }
  569 #endif
  570         return (0);
  571 }
  572 #endif /* ISO */

Cache object: 4a434d8dcd30364633b225bd6de1f37d


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