Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

bpf_filter.c File Reference

#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>
#include <net/bpf.h>
#include <stdlib.h>
#include <netinet/in.h>

Include dependency graph for bpf/net/bpf_filter.c:

Include dependency graph

Go to the source code of this file.

Defines

#define SOLARIS   (defined(sun) && (defined(__SVR4) || defined(__svr4__)))
#define MLEN(m)   ((m)->m_len)
#define int32   bpf_int32
#define u_int32   bpf_u_int32
#define EXTRACT_SHORT(p)   ((u_short)ntohs(*(u_short *)p))
#define EXTRACT_LONG(p)   (ntohl(*(u_int32 *)p))

Functions

u_int bpf_filter (struct bpf_insn *pc, u_char *p, u_int wirelen, u_int buflen)
int bpf_validate (struct bpf_insn *f, int len)

Variables

const char rcsid []


Define Documentation

#define EXTRACT_LONG p   )     (ntohl(*(u_int32 *)p))
 

Definition at line 82 of file bpf/net/bpf_filter.c.

Referenced by bpf_filter().

#define EXTRACT_SHORT p   )     ((u_short)ntohs(*(u_short *)p))
 

Definition at line 81 of file bpf/net/bpf_filter.c.

Referenced by bpf_filter().

#define int32   bpf_int32
 

Definition at line 68 of file bpf/net/bpf_filter.c.

Referenced by bpf_filter().

#define MLEN  )     ((m)->m_len)
 

Definition at line 59 of file bpf/net/bpf_filter.c.

Referenced by bpf_filter().

#define SOLARIS   (defined(sun) && (defined(__SVR4) || defined(__svr4__)))
 

Definition at line 50 of file bpf/net/bpf_filter.c.

#define u_int32   bpf_u_int32
 

Definition at line 69 of file bpf/net/bpf_filter.c.

Referenced by bpf_filter().


Function Documentation

u_int bpf_filter struct bpf_insn pc,
u_char *  p,
u_int  wirelen,
u_int  buflen
 

Definition at line 181 of file bpf/net/bpf_filter.c.

00186 {
00187         register u_int32 A, X;
00188         register int k;
00189         int32 mem[BPF_MEMWORDS];
00190 #if defined(KERNEL) || defined(_KERNEL)
00191         struct mbuf *m, *n;
00192         int merr, len;
00193 
00194         if (buflen == 0) {
00195                 m = (struct mbuf *)p;
00196                 p = mtod(m, u_char *);
00197                 buflen = MLEN(m);
00198         } else
00199                 m = NULL;
00200 #endif
00201 
00202         if (pc == 0)
00203                 /*
00204                  * No filter means accept all.
00205                  */
00206                 return (u_int)-1;
00207         A = 0;
00208         X = 0;
00209         --pc;
00210         while (1) {
00211                 ++pc;
00212                 switch (pc->code) {
00213 
00214                 default:
00215 #if defined(KERNEL) || defined(_KERNEL)
00216                         return 0;
00217 #else
00218                         abort();
00219 #endif                  
00220                 case BPF_RET|BPF_K:
00221                         return (u_int)pc->k;
00222 
00223                 case BPF_RET|BPF_A:
00224                         return (u_int)A;
00225 
00226                 case BPF_LD|BPF_W|BPF_ABS:
00227                         k = pc->k;
00228                         if (k + sizeof(int32) > buflen) {
00229 #if defined(KERNEL) || defined(_KERNEL)
00230                                 if (m == NULL)
00231                                         return 0;
00232                                 A = m_xword(m, k, &merr);
00233                                 if (merr != 0)
00234                                         return 0;
00235                                 continue;
00236 #else
00237                                 return 0;
00238 #endif
00239                         }
00240                         A = EXTRACT_LONG(&p[k]);
00241                         continue;
00242 
00243                 case BPF_LD|BPF_H|BPF_ABS:
00244                         k = pc->k;
00245                         if (k + sizeof(short) > buflen) {
00246 #if defined(KERNEL) || defined(_KERNEL)
00247                                 if (m == NULL)
00248                                         return 0;
00249                                 A = m_xhalf(m, k, &merr);
00250                                 if (merr != 0)
00251                                         return 0;
00252                                 continue;
00253 #else
00254                                 return 0;
00255 #endif
00256                         }
00257                         A = EXTRACT_SHORT(&p[k]);
00258                         continue;
00259 
00260                 case BPF_LD|BPF_B|BPF_ABS:
00261                         k = pc->k;
00262                         if (k >= buflen) {
00263 #if defined(KERNEL) || defined(_KERNEL)
00264                                 if (m == NULL)
00265                                         return 0;
00266                                 n = m;
00267                                 MINDEX(len, n, k);
00268                                 A = mtod(n, u_char *)[k];
00269                                 continue;
00270 #else
00271                                 return 0;
00272 #endif
00273                         }
00274                         A = p[k];
00275                         continue;
00276 
00277                 case BPF_LD|BPF_W|BPF_LEN:
00278                         A = wirelen;
00279                         continue;
00280 
00281                 case BPF_LDX|BPF_W|BPF_LEN:
00282                         X = wirelen;
00283                         continue;
00284 
00285                 case BPF_LD|BPF_W|BPF_IND:
00286                         k = X + pc->k;
00287                         if (k + sizeof(int32) > buflen) {
00288 #if defined(KERNEL) || defined(_KERNEL)
00289                                 if (m == NULL)
00290                                         return 0;
00291                                 A = m_xword(m, k, &merr);
00292                                 if (merr != 0)
00293                                         return 0;
00294                                 continue;
00295 #else
00296                                 return 0;
00297 #endif
00298                         }
00299                         A = EXTRACT_LONG(&p[k]);
00300                         continue;
00301 
00302                 case BPF_LD|BPF_H|BPF_IND:
00303                         k = X + pc->k;
00304                         if (k + sizeof(short) > buflen) {
00305 #if defined(KERNEL) || defined(_KERNEL)
00306                                 if (m == NULL)
00307                                         return 0;
00308                                 A = m_xhalf(m, k, &merr);
00309                                 if (merr != 0)
00310                                         return 0;
00311                                 continue;
00312 #else
00313                                 return 0;
00314 #endif
00315                         }
00316                         A = EXTRACT_SHORT(&p[k]);
00317                         continue;
00318 
00319                 case BPF_LD|BPF_B|BPF_IND:
00320                         k = X + pc->k;
00321                         if (k >= buflen) {
00322 #if defined(KERNEL) || defined(_KERNEL)
00323                                 if (m == NULL)
00324                                         return 0;
00325                                 n = m;
00326                                 MINDEX(len, n, k);
00327                                 A = mtod(n, u_char *)[k];
00328                                 continue;
00329 #else
00330                                 return 0;
00331 #endif
00332                         }
00333                         A = p[k];
00334                         continue;
00335 
00336                 case BPF_LDX|BPF_MSH|BPF_B:
00337                         k = pc->k;
00338                         if (k >= buflen) {
00339 #if defined(KERNEL) || defined(_KERNEL)
00340                                 if (m == NULL)
00341                                         return 0;
00342                                 n = m;
00343                                 MINDEX(len, n, k);
00344                                 X = (mtod(n, char *)[k] & 0xf) << 2;
00345                                 continue;
00346 #else
00347                                 return 0;
00348 #endif
00349                         }
00350                         X = (p[pc->k] & 0xf) << 2;
00351                         continue;
00352 
00353                 case BPF_LD|BPF_IMM:
00354                         A = pc->k;
00355                         continue;
00356 
00357                 case BPF_LDX|BPF_IMM:
00358                         X = pc->k;
00359                         continue;
00360 
00361                 case BPF_LD|BPF_MEM:
00362                         A = mem[pc->k];
00363                         continue;
00364                         
00365                 case BPF_LDX|BPF_MEM:
00366                         X = mem[pc->k];
00367                         continue;
00368 
00369                 case BPF_ST:
00370                         mem[pc->k] = A;
00371                         continue;
00372 
00373                 case BPF_STX:
00374                         mem[pc->k] = X;
00375                         continue;
00376 
00377                 case BPF_JMP|BPF_JA:
00378                         pc += pc->k;
00379                         continue;
00380 
00381                 case BPF_JMP|BPF_JGT|BPF_K:
00382                         pc += (A > pc->k) ? pc->jt : pc->jf;
00383                         continue;
00384 
00385                 case BPF_JMP|BPF_JGE|BPF_K:
00386                         pc += (A >= pc->k) ? pc->jt : pc->jf;
00387                         continue;
00388 
00389                 case BPF_JMP|BPF_JEQ|BPF_K:
00390                         pc += (A == pc->k) ? pc->jt : pc->jf;
00391                         continue;
00392 
00393                 case BPF_JMP|BPF_JSET|BPF_K:
00394                         pc += (A & pc->k) ? pc->jt : pc->jf;
00395                         continue;
00396 
00397                 case BPF_JMP|BPF_JGT|BPF_X:
00398                         pc += (A > X) ? pc->jt : pc->jf;
00399                         continue;
00400 
00401                 case BPF_JMP|BPF_JGE|BPF_X:
00402                         pc += (A >= X) ? pc->jt : pc->jf;
00403                         continue;
00404 
00405                 case BPF_JMP|BPF_JEQ|BPF_X:
00406                         pc += (A == X) ? pc->jt : pc->jf;
00407                         continue;
00408 
00409                 case BPF_JMP|BPF_JSET|BPF_X:
00410                         pc += (A & X) ? pc->jt : pc->jf;
00411                         continue;
00412 
00413                 case BPF_ALU|BPF_ADD|BPF_X:
00414                         A += X;
00415                         continue;
00416                         
00417                 case BPF_ALU|BPF_SUB|BPF_X:
00418                         A -= X;
00419                         continue;
00420                         
00421                 case BPF_ALU|BPF_MUL|BPF_X:
00422                         A *= X;
00423                         continue;
00424                         
00425                 case BPF_ALU|BPF_DIV|BPF_X:
00426                         if (X == 0)
00427                                 return 0;
00428                         A /= X;
00429                         continue;
00430                         
00431                 case BPF_ALU|BPF_AND|BPF_X:
00432                         A &= X;
00433                         continue;
00434                         
00435                 case BPF_ALU|BPF_OR|BPF_X:
00436                         A |= X;
00437                         continue;
00438 
00439                 case BPF_ALU|BPF_LSH|BPF_X:
00440                         A <<= X;
00441                         continue;
00442 
00443                 case BPF_ALU|BPF_RSH|BPF_X:
00444                         A >>= X;
00445                         continue;
00446 
00447                 case BPF_ALU|BPF_ADD|BPF_K:
00448                         A += pc->k;
00449                         continue;
00450                         
00451                 case BPF_ALU|BPF_SUB|BPF_K:
00452                         A -= pc->k;
00453                         continue;
00454                         
00455                 case BPF_ALU|BPF_MUL|BPF_K:
00456                         A *= pc->k;
00457                         continue;
00458                         
00459                 case BPF_ALU|BPF_DIV|BPF_K:
00460                         A /= pc->k;
00461                         continue;
00462                         
00463                 case BPF_ALU|BPF_AND|BPF_K:
00464                         A &= pc->k;
00465                         continue;
00466                         
00467                 case BPF_ALU|BPF_OR|BPF_K:
00468                         A |= pc->k;
00469                         continue;
00470 
00471                 case BPF_ALU|BPF_LSH|BPF_K:
00472                         A <<= pc->k;
00473                         continue;
00474 
00475                 case BPF_ALU|BPF_RSH|BPF_K:
00476                         A >>= pc->k;
00477                         continue;
00478 
00479                 case BPF_ALU|BPF_NEG:
00480                         A = -A;
00481                         continue;
00482 
00483                 case BPF_MISC|BPF_TAX:
00484                         X = A;
00485                         continue;
00486 
00487                 case BPF_MISC|BPF_TXA:
00488                         A = X;
00489                         continue;
00490                 }
00491         }
00492 }

int bpf_validate struct bpf_insn f,
int  len
 

Definition at line 506 of file bpf/net/bpf_filter.c.

00509 {
00510         register int i;
00511         register struct bpf_insn *p;
00512 
00513         for (i = 0; i < len; ++i) {
00514                 /*
00515                  * Check that that jumps are forward, and within 
00516                  * the code block.
00517                  */
00518                 p = &f[i];
00519                 if (BPF_CLASS(p->code) == BPF_JMP) {
00520                         register int from = i + 1;
00521 
00522                         if (BPF_OP(p->code) == BPF_JA) {
00523                                 if (from + p->k >= (unsigned)len)
00524                                         return 0;
00525                         }
00526                         else if (from + p->jt >= len || from + p->jf >= len)
00527                                 return 0;
00528                 }
00529                 /*
00530                  * Check that memory operations use valid addresses.
00531                  */
00532                 if ((BPF_CLASS(p->code) == BPF_ST ||
00533                      (BPF_CLASS(p->code) == BPF_LD && 
00534                       (p->code & 0xe0) == BPF_MEM)) &&
00535                     (p->k >= BPF_MEMWORDS || p->k < 0))
00536                         return 0;
00537                 /*
00538                  * Check for constant division by 0.
00539                  */
00540                 if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
00541                         return 0;
00542         }
00543         return BPF_CLASS(f[len - 1].code) == BPF_RET;
00544 }


Variable Documentation

const char rcsid[] [static]
 

Initial value:

    "@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.35 2000/10/23 19:32:21 fenner Exp $ (LBL)"

Definition at line 42 of file bpf/net/bpf_filter.c.


Generated on Wed Sep 14 02:57:18 2005 for bro_docs by doxygen 1.3.5