"Fossies" - the Fresh Open Source Software Archive

Member "daq-2.0.7/sfbpf/sf_bpf_filter.c" (8 Apr 2020, 19900 Bytes) of package /linux/misc/daq-2.0.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sf_bpf_filter.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.0.6_vs_2.0.7.

    1 /*-
    2  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
    3  *  The Regents of the University of California.  All rights reserved.
    4  *
    5  * Some Portions Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
    6  * Some portions Copyright (C) 2010-2013 Sourcefire, Inc.
    7  *
    8  * This code is derived from the Stanford/CMU enet packet filter,
    9  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
   10  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
   11  * Berkeley Laboratory.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. All advertising materials mentioning features or use of this software
   22  *    must display the following acknowledgement:
   23  *  This product includes software developed by the University of
   24  *  California, Berkeley and its contributors.
   25  * 4. Neither the name of the University nor the names of its contributors
   26  *    may be used to endorse or promote products derived from this software
   27  *    without specific prior written permission.
   28  *
   29  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   39  * SUCH DAMAGE.
   40  *
   41  *  @(#)bpf.c   7.5 (Berkeley) 7/15/91
   42  */
   43 
   44 #if !(defined(lint) || defined(KERNEL) || defined(_KERNEL))
   45 static const char rcsid[] =
   46     "@(#) $Header: //depot/firepower/daq-opensource/DAQ_2_0_7/sfbpf/sf_bpf_filter.c#1 $ (LBL)";
   47 #endif
   48 
   49 #ifdef HAVE_CONFIG_H
   50 #include "config.h"
   51 #endif
   52 
   53 #ifdef WIN32
   54 
   55 #include "win32-stdinc.h"
   56 
   57 #else /* WIN32 */
   58 
   59 #if HAVE_INTTYPES_H
   60 #include <inttypes.h>
   61 #elif HAVE_STDINT_H
   62 #include <stdint.h>
   63 #endif
   64 #ifdef HAVE_SYS_BITYPES_H
   65 #include <sys/bitypes.h>
   66 #endif
   67 
   68 #include <sys/param.h>
   69 #include <sys/types.h>
   70 #include <sys/time.h>
   71 
   72 #define SOLARIS (defined(sun) && (defined(__SVR4) || defined(__svr4__)))
   73 #if defined(__hpux) || SOLARIS
   74 # include <sys/sysmacros.h>
   75 # include <sys/stream.h>
   76 # define    mbuf    msgb
   77 # define    m_next  b_cont
   78 # define    MLEN(m) ((m)->b_wptr - (m)->b_rptr)
   79 # define    mtod(m,t)   ((t)(m)->b_rptr)
   80 #else /* defined(__hpux) || SOLARIS */
   81 # define    MLEN(m) ((m)->m_len)
   82 #endif /* defined(__hpux) || SOLARIS */
   83 
   84 #endif /* WIN32 */
   85 
   86 #include "sfbpf-int.h"
   87 
   88 #if !defined(KERNEL) && !defined(_KERNEL)
   89 #include <stdlib.h>
   90 #endif
   91 
   92 #define int32 bpf_int32
   93 #define u_int32 bpf_u_int32
   94 
   95 #ifndef LBL_ALIGN
   96 /*
   97  * XXX - IA-64?  If not, this probably won't work on Win64 IA-64
   98  * systems, unless LBL_ALIGN is defined elsewhere for them.
   99  * XXX - SuperH?  If not, this probably won't work on WinCE SuperH
  100  * systems, unless LBL_ALIGN is defined elsewhere for them.
  101  */
  102 #if defined(sparc) || defined(__sparc__) || defined(mips) || \
  103     defined(ibm032) || defined(__alpha) || defined(__hpux) || \
  104     defined(__arm__)
  105 #define LBL_ALIGN
  106 #endif
  107 #endif
  108 
  109 #ifndef LBL_ALIGN
  110 #ifndef WIN32
  111 #include <netinet/in.h>
  112 #endif
  113 
  114 #define EXTRACT_SHORT(p)    ((u_short)ntohs(*(u_short *)p))
  115 #define EXTRACT_LONG(p)     (ntohl(*(u_int32 *)p))
  116 #else
  117 #define EXTRACT_SHORT(p)\
  118     ((u_short)\
  119         ((u_short)*((u_char *)p+0)<<8|\
  120          (u_short)*((u_char *)p+1)<<0))
  121 #define EXTRACT_LONG(p)\
  122         ((u_int32)*((u_char *)p+0)<<24|\
  123          (u_int32)*((u_char *)p+1)<<16|\
  124          (u_int32)*((u_char *)p+2)<<8|\
  125          (u_int32)*((u_char *)p+3)<<0)
  126 #endif
  127 
  128 #if defined(KERNEL) || defined(_KERNEL)
  129 # if !defined(__hpux) && !SOLARIS
  130 #include <sys/mbuf.h>
  131 # endif
  132 #define MINDEX(len, _m, _k) \
  133 { \
  134     len = MLEN(m); \
  135     while ((_k) >= len) { \
  136         (_k) -= len; \
  137         (_m) = (_m)->m_next; \
  138         if ((_m) == 0) \
  139             return 0; \
  140         len = MLEN(m); \
  141     } \
  142 }
  143 
  144 static int m_xword(m, k, err)
  145      register struct mbuf *m;
  146      register int k, *err;
  147 {
  148     register int len;
  149     register u_char *cp, *np;
  150     register struct mbuf *m0;
  151 
  152     MINDEX(len, m, k);
  153     cp = mtod(m, u_char *) + k;
  154     if (len - k >= 4)
  155     {
  156         *err = 0;
  157         return EXTRACT_LONG(cp);
  158     }
  159     m0 = m->m_next;
  160     if (m0 == 0 || MLEN(m0) + len - k < 4)
  161         goto bad;
  162     *err = 0;
  163     np = mtod(m0, u_char *);
  164     switch (len - k)
  165     {
  166 
  167         case 1:
  168             return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2];
  169 
  170         case 2:
  171             return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1];
  172 
  173         default:
  174             return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0];
  175     }
  176   bad:
  177     *err = 1;
  178     return 0;
  179 }
  180 
  181 static int m_xhalf(m, k, err)
  182      register struct mbuf *m;
  183      register int k, *err;
  184 {
  185     register int len;
  186     register u_char *cp;
  187     register struct mbuf *m0;
  188 
  189     MINDEX(len, m, k);
  190     cp = mtod(m, u_char *) + k;
  191     if (len - k >= 2)
  192     {
  193         *err = 0;
  194         return EXTRACT_SHORT(cp);
  195     }
  196     m0 = m->m_next;
  197     if (m0 == 0)
  198         goto bad;
  199     *err = 0;
  200     return (cp[0] << 8) | mtod(m0, u_char *)[0];
  201   bad:
  202     *err = 1;
  203     return 0;
  204 }
  205 #endif
  206 
  207 /*
  208  * Execute the filter program starting at pc on the packet p
  209  * wirelen is the length of the original packet
  210  * buflen is the amount of data present
  211  * For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0,
  212  * in all other cases, p is a pointer to a buffer and buflen is its size.
  213  */
  214 DAQ_SO_PUBLIC u_int bpf_filter(pc, p, wirelen, buflen)
  215      register const struct bpf_insn *pc;
  216      register const u_char *p;
  217      u_int wirelen;
  218      register u_int buflen;
  219 {
  220     register u_int32 A, X;
  221     register int k;
  222     int32 mem[BPF_MEMWORDS];
  223 #if defined(KERNEL) || defined(_KERNEL)
  224     struct mbuf *m, *n;
  225     int merr, len;
  226 
  227     if (buflen == 0)
  228     {
  229         m = (struct mbuf *) p;
  230         p = mtod(m, u_char *);
  231         buflen = MLEN(m);
  232     }
  233     else
  234         m = NULL;
  235 #endif
  236 
  237     if (pc == 0)
  238         /*
  239          * No filter means accept all.
  240          */
  241         return (u_int) - 1;
  242     A = 0;
  243     X = 0;
  244     --pc;
  245     while (1)
  246     {
  247         ++pc;
  248         switch (pc->code)
  249         {
  250 
  251             default:
  252 #if defined(KERNEL) || defined(_KERNEL)
  253                 return 0;
  254 #else
  255                 abort();
  256 #endif
  257             case BPF_RET | BPF_K:
  258                 return (u_int) pc->k;
  259 
  260             case BPF_RET | BPF_A:
  261                 return (u_int) A;
  262 
  263             case BPF_LD | BPF_W | BPF_ABS:
  264                 k = pc->k;
  265                 if (k + sizeof(int32) > buflen)
  266                 {
  267 #if defined(KERNEL) || defined(_KERNEL)
  268                     if (m == NULL)
  269                         return 0;
  270                     A = m_xword(m, k, &merr);
  271                     if (merr != 0)
  272                         return 0;
  273                     continue;
  274 #else
  275                     return 0;
  276 #endif
  277                 }
  278                 A = EXTRACT_LONG(&p[k]);
  279                 continue;
  280 
  281             case BPF_LD | BPF_H | BPF_ABS:
  282                 k = pc->k;
  283                 if (k + sizeof(short) > buflen)
  284                 {
  285 #if defined(KERNEL) || defined(_KERNEL)
  286                     if (m == NULL)
  287                         return 0;
  288                     A = m_xhalf(m, k, &merr);
  289                     if (merr != 0)
  290                         return 0;
  291                     continue;
  292 #else
  293                     return 0;
  294 #endif
  295                 }
  296                 A = EXTRACT_SHORT(&p[k]);
  297                 continue;
  298 
  299             case BPF_LD | BPF_B | BPF_ABS:
  300                 k = pc->k;
  301                 if (k >= buflen)
  302                 {
  303 #if defined(KERNEL) || defined(_KERNEL)
  304                     if (m == NULL)
  305                         return 0;
  306                     n = m;
  307                     MINDEX(len, n, k);
  308                     A = mtod(n, u_char *)[k];
  309                     continue;
  310 #else
  311                     return 0;
  312 #endif
  313                 }
  314                 A = p[k];
  315                 continue;
  316 
  317             case BPF_LD | BPF_W | BPF_LEN:
  318                 A = wirelen;
  319                 continue;
  320 
  321             case BPF_LDX | BPF_W | BPF_LEN:
  322                 X = wirelen;
  323                 continue;
  324 
  325             case BPF_LD | BPF_W | BPF_IND:
  326                 k = X + pc->k;
  327                 if (k + sizeof(int32) > buflen)
  328                 {
  329 #if defined(KERNEL) || defined(_KERNEL)
  330                     if (m == NULL)
  331                         return 0;
  332                     A = m_xword(m, k, &merr);
  333                     if (merr != 0)
  334                         return 0;
  335                     continue;
  336 #else
  337                     return 0;
  338 #endif
  339                 }
  340                 A = EXTRACT_LONG(&p[k]);
  341                 continue;
  342 
  343             case BPF_LD | BPF_H | BPF_IND:
  344                 k = X + pc->k;
  345                 if (k + sizeof(short) > buflen)
  346                 {
  347 #if defined(KERNEL) || defined(_KERNEL)
  348                     if (m == NULL)
  349                         return 0;
  350                     A = m_xhalf(m, k, &merr);
  351                     if (merr != 0)
  352                         return 0;
  353                     continue;
  354 #else
  355                     return 0;
  356 #endif
  357                 }
  358                 A = EXTRACT_SHORT(&p[k]);
  359                 continue;
  360 
  361             case BPF_LD | BPF_B | BPF_IND:
  362                 k = X + pc->k;
  363                 if (k >= buflen)
  364                 {
  365 #if defined(KERNEL) || defined(_KERNEL)
  366                     if (m == NULL)
  367                         return 0;
  368                     n = m;
  369                     MINDEX(len, n, k);
  370                     A = mtod(n, u_char *)[k];
  371                     continue;
  372 #else
  373                     return 0;
  374 #endif
  375                 }
  376                 A = p[k];
  377                 continue;
  378 
  379             case BPF_LDX | BPF_MSH | BPF_B:
  380                 k = pc->k;
  381                 if (k >= buflen)
  382                 {
  383 #if defined(KERNEL) || defined(_KERNEL)
  384                     if (m == NULL)
  385                         return 0;
  386                     n = m;
  387                     MINDEX(len, n, k);
  388                     X = (mtod(n, char *)[k] & 0xf) << 2;
  389                     continue;
  390 #else
  391                     return 0;
  392 #endif
  393                 }
  394                 X = (p[pc->k] & 0xf) << 2;
  395                 continue;
  396 
  397             case BPF_LD | BPF_IMM:
  398                 A = pc->k;
  399                 continue;
  400 
  401             case BPF_LDX | BPF_IMM:
  402                 X = pc->k;
  403                 continue;
  404 
  405             case BPF_LD | BPF_MEM:
  406                 A = mem[pc->k];
  407                 continue;
  408 
  409             case BPF_LDX | BPF_MEM:
  410                 X = mem[pc->k];
  411                 continue;
  412 
  413             case BPF_ST:
  414                 mem[pc->k] = A;
  415                 continue;
  416 
  417             case BPF_STX:
  418                 mem[pc->k] = X;
  419                 continue;
  420 
  421             case BPF_JMP | BPF_JA:
  422                 pc += pc->k;
  423                 continue;
  424 
  425             case BPF_JMP | BPF_JGT | BPF_K:
  426                 pc += (A > pc->k) ? pc->jt : pc->jf;
  427                 continue;
  428 
  429             case BPF_JMP | BPF_JGE | BPF_K:
  430                 pc += (A >= pc->k) ? pc->jt : pc->jf;
  431                 continue;
  432 
  433             case BPF_JMP | BPF_JEQ | BPF_K:
  434                 pc += (A == pc->k) ? pc->jt : pc->jf;
  435                 continue;
  436 
  437             case BPF_JMP | BPF_JSET | BPF_K:
  438                 pc += (A & pc->k) ? pc->jt : pc->jf;
  439                 continue;
  440 
  441             case BPF_JMP | BPF_JGT | BPF_X:
  442                 pc += (A > X) ? pc->jt : pc->jf;
  443                 continue;
  444 
  445             case BPF_JMP | BPF_JGE | BPF_X:
  446                 pc += (A >= X) ? pc->jt : pc->jf;
  447                 continue;
  448 
  449             case BPF_JMP | BPF_JEQ | BPF_X:
  450                 pc += (A == X) ? pc->jt : pc->jf;
  451                 continue;
  452 
  453             case BPF_JMP | BPF_JSET | BPF_X:
  454                 pc += (A & X) ? pc->jt : pc->jf;
  455                 continue;
  456 
  457             case BPF_ALU | BPF_ADD | BPF_X:
  458                 A += X;
  459                 continue;
  460 
  461             case BPF_ALU | BPF_SUB | BPF_X:
  462                 A -= X;
  463                 continue;
  464 
  465             case BPF_ALU | BPF_MUL | BPF_X:
  466                 A *= X;
  467                 continue;
  468 
  469             case BPF_ALU | BPF_DIV | BPF_X:
  470                 if (X == 0)
  471                     return 0;
  472                 A /= X;
  473                 continue;
  474 
  475             case BPF_ALU | BPF_AND | BPF_X:
  476                 A &= X;
  477                 continue;
  478 
  479             case BPF_ALU | BPF_OR | BPF_X:
  480                 A |= X;
  481                 continue;
  482 
  483             case BPF_ALU | BPF_LSH | BPF_X:
  484                 A <<= X;
  485                 continue;
  486 
  487             case BPF_ALU | BPF_RSH | BPF_X:
  488                 A >>= X;
  489                 continue;
  490 
  491             case BPF_ALU | BPF_ADD | BPF_K:
  492                 A += pc->k;
  493                 continue;
  494 
  495             case BPF_ALU | BPF_SUB | BPF_K:
  496                 A -= pc->k;
  497                 continue;
  498 
  499             case BPF_ALU | BPF_MUL | BPF_K:
  500                 A *= pc->k;
  501                 continue;
  502 
  503             case BPF_ALU | BPF_DIV | BPF_K:
  504                 A /= pc->k;
  505                 continue;
  506 
  507             case BPF_ALU | BPF_AND | BPF_K:
  508                 A &= pc->k;
  509                 continue;
  510 
  511             case BPF_ALU | BPF_OR | BPF_K:
  512                 A |= pc->k;
  513                 continue;
  514 
  515             case BPF_ALU | BPF_LSH | BPF_K:
  516                 A <<= pc->k;
  517                 continue;
  518 
  519             case BPF_ALU | BPF_RSH | BPF_K:
  520                 A >>= pc->k;
  521                 continue;
  522 
  523             case BPF_ALU | BPF_NEG:
  524                 A = -A;
  525                 continue;
  526 
  527             case BPF_MISC | BPF_TAX:
  528                 X = A;
  529                 continue;
  530 
  531             case BPF_MISC | BPF_TXA:
  532                 A = X;
  533                 continue;
  534         }
  535     }
  536 }
  537 
  538 /*
  539  * Return true if the 'fcode' is a valid filter program.
  540  * The constraints are that each jump be forward and to a valid
  541  * code, that memory accesses are within valid ranges (to the
  542  * extent that this can be checked statically; loads of packet
  543  * data have to be, and are, also checked at run time), and that
  544  * the code terminates with either an accept or reject.
  545  *
  546  * The kernel needs to be able to verify an application's filter code.
  547  * Otherwise, a bogus program could easily crash the system.
  548  */
  549 DAQ_SO_PUBLIC int bpf_validate(f, len)
  550      const struct bpf_insn *f;
  551      int len;
  552 {
  553     u_int i, from;
  554     const struct bpf_insn *p;
  555 
  556     if (len < 1)
  557         return 0;
  558     /*
  559      * There's no maximum program length in userland.
  560      */
  561 #if defined(KERNEL) || defined(_KERNEL)
  562     if (len > BPF_MAXINSNS)
  563         return 0;
  564 #endif
  565 
  566     for (i = 0; i < len; ++i)
  567     {
  568         p = &f[i];
  569         switch (BPF_CLASS(p->code))
  570         {
  571                 /*
  572                  * Check that memory operations use valid addresses.
  573                  */
  574             case BPF_LD:
  575             case BPF_LDX:
  576                 switch (BPF_MODE(p->code))
  577                 {
  578                     case BPF_IMM:
  579                         break;
  580                     case BPF_ABS:
  581                     case BPF_IND:
  582                     case BPF_MSH:
  583                         /*
  584                          * There's no maximum packet data size
  585                          * in userland.  The runtime packet length
  586                          * check suffices.
  587                          */
  588 #if defined(KERNEL) || defined(_KERNEL)
  589                         /*
  590                          * More strict check with actual packet length
  591                          * is done runtime.
  592                          */
  593                         if (p->k >= bpf_maxbufsize)
  594                             return 0;
  595 #endif
  596                         break;
  597                     case BPF_MEM:
  598                         if (p->k >= BPF_MEMWORDS)
  599                             return 0;
  600                         break;
  601                     case BPF_LEN:
  602                         break;
  603                     default:
  604                         return 0;
  605                 }
  606                 break;
  607             case BPF_ST:
  608             case BPF_STX:
  609                 if (p->k >= BPF_MEMWORDS)
  610                     return 0;
  611                 break;
  612             case BPF_ALU:
  613                 switch (BPF_OP(p->code))
  614                 {
  615                     case BPF_ADD:
  616                     case BPF_SUB:
  617                     case BPF_MUL:
  618                     case BPF_OR:
  619                     case BPF_AND:
  620                     case BPF_LSH:
  621                     case BPF_RSH:
  622                     case BPF_NEG:
  623                         break;
  624                     case BPF_DIV:
  625                         /*
  626                          * Check for constant division by 0.
  627                          */
  628                         if (BPF_RVAL(p->code) == BPF_K && p->k == 0)
  629                             return 0;
  630                         break;
  631                     default:
  632                         return 0;
  633                 }
  634                 break;
  635             case BPF_JMP:
  636                 /*
  637                  * Check that jumps are within the code block,
  638                  * and that unconditional branches don't go
  639                  * backwards as a result of an overflow.
  640                  * Unconditional branches have a 32-bit offset,
  641                  * so they could overflow; we check to make
  642                  * sure they don't.  Conditional branches have
  643                  * an 8-bit offset, and the from address is <=
  644                  * BPF_MAXINSNS, and we assume that BPF_MAXINSNS
  645                  * is sufficiently small that adding 255 to it
  646                  * won't overflow.
  647                  *
  648                  * We know that len is <= BPF_MAXINSNS, and we
  649                  * assume that BPF_MAXINSNS is < the maximum size
  650                  * of a u_int, so that i + 1 doesn't overflow.
  651                  *
  652                  * For userland, we don't know that the from
  653                  * or len are <= BPF_MAXINSNS, but we know that
  654                  * from <= len, and, except on a 64-bit system,
  655                  * it's unlikely that len, if it truly reflects
  656                  * the size of the program we've been handed,
  657                  * will be anywhere near the maximum size of
  658                  * a u_int.  We also don't check for backward
  659                  * branches, as we currently support them in
  660                  * userland for the protochain operation.
  661                  */
  662                 from = i + 1;
  663                 switch (BPF_OP(p->code))
  664                 {
  665                     case BPF_JA:
  666 #if defined(KERNEL) || defined(_KERNEL)
  667                         if (from + p->k < from || from + p->k >= len)
  668 #else
  669                         if (from + p->k >= len)
  670 #endif
  671                             return 0;
  672                         break;
  673                     case BPF_JEQ:
  674                     case BPF_JGT:
  675                     case BPF_JGE:
  676                     case BPF_JSET:
  677                         if (from + p->jt >= len || from + p->jf >= len)
  678                             return 0;
  679                         break;
  680                     default:
  681                         return 0;
  682                 }
  683                 break;
  684             case BPF_RET:
  685                 break;
  686             case BPF_MISC:
  687                 break;
  688             default:
  689                 return 0;
  690         }
  691     }
  692     return BPF_CLASS(f[len - 1].code) == BPF_RET;
  693 }