diff -Naur libpcap-1.3.0/bpf/net/bpf_filter.c libpcap-1.3.0-with-modulus/bpf/net/bpf_filter.c --- libpcap-1.3.0/bpf/net/bpf_filter.c 2012-03-29 12:57:32.000000000 +0000 +++ libpcap-1.3.0-with-modulus/bpf/net/bpf_filter.c 2012-08-31 01:36:53.206825554 +0000 @@ -469,6 +469,12 @@ A /= X; continue; + case BPF_ALU|BPF_MOD|BPF_X: + if (X == 0) + return 0; + A %= X; + continue; + case BPF_ALU|BPF_AND|BPF_X: A &= X; continue; @@ -501,6 +507,10 @@ A /= pc->k; continue; + case BPF_ALU|BPF_MOD|BPF_K: + A %= pc->k; + continue; + case BPF_ALU|BPF_AND|BPF_K: A &= pc->k; continue; @@ -621,6 +631,13 @@ */ if (BPF_SRC(p->code) == BPF_K && p->k == 0) return 0; + break; + case BPF_MOD: + /* + * Check for illegal modulus 0. + */ + if (BPF_SRC(p->code) == BPF_K && p->k == 0) + return 0; break; default: return 0; diff -Naur libpcap-1.3.0/bpf_image.c libpcap-1.3.0-with-modulus/bpf_image.c --- libpcap-1.3.0/bpf_image.c 2012-03-29 12:57:32.000000000 +0000 +++ libpcap-1.3.0-with-modulus/bpf_image.c 2012-08-31 01:36:53.225825770 +0000 @@ -216,6 +216,11 @@ fmt = "x"; break; + case BPF_ALU|BPF_MOD|BPF_X: + op = "mod"; + fmt = "x"; + break; + case BPF_ALU|BPF_AND|BPF_X: op = "and"; fmt = "x"; @@ -256,6 +261,11 @@ fmt = "#%d"; break; + case BPF_ALU|BPF_MOD|BPF_K: + op = "mod"; + fmt = "#%d"; + break; + case BPF_ALU|BPF_AND|BPF_K: op = "and"; fmt = "#0x%x"; diff -Naur libpcap-1.3.0/grammar.y libpcap-1.3.0-with-modulus/grammar.y --- libpcap-1.3.0/grammar.y 2012-03-29 12:57:32.000000000 +0000 +++ libpcap-1.3.0-with-modulus/grammar.y 2012-08-31 01:36:53.196825439 +0000 @@ -617,6 +617,7 @@ | arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); } | arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); } | arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); } + | arth '%' arth { $$ = gen_arth(BPF_MOD, $1, $3); } | arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); } | arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); } | arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); } diff -Naur libpcap-1.3.0/optimize.c libpcap-1.3.0-with-modulus/optimize.c --- libpcap-1.3.0/optimize.c 2012-03-29 12:57:32.000000000 +0000 +++ libpcap-1.3.0-with-modulus/optimize.c 2012-08-31 01:36:53.188825347 +0000 @@ -666,6 +666,12 @@ a /= b; break; + case BPF_MOD: + if (b == 0) + bpf_error("illegal modulus 0"); + a %= b; + break; + case BPF_AND: a &= b; break; @@ -1044,6 +1050,7 @@ case BPF_ALU|BPF_SUB|BPF_K: case BPF_ALU|BPF_MUL|BPF_K: case BPF_ALU|BPF_DIV|BPF_K: + case BPF_ALU|BPF_MOD|BPF_K: case BPF_ALU|BPF_AND|BPF_K: case BPF_ALU|BPF_OR|BPF_K: case BPF_ALU|BPF_LSH|BPF_K: @@ -1079,6 +1086,7 @@ case BPF_ALU|BPF_SUB|BPF_X: case BPF_ALU|BPF_MUL|BPF_X: case BPF_ALU|BPF_DIV|BPF_X: + case BPF_ALU|BPF_MOD|BPF_X: case BPF_ALU|BPF_AND|BPF_X: case BPF_ALU|BPF_OR|BPF_X: case BPF_ALU|BPF_LSH|BPF_X: @@ -1112,7 +1120,7 @@ vstore(s, &val[A_ATOM], val[X_ATOM], alter); break; } - else if (op == BPF_MUL || op == BPF_DIV || + else if (op == BPF_MUL || op == BPF_DIV || op == BPF_MOD || op == BPF_AND || op == BPF_LSH || op == BPF_RSH) { s->code = BPF_LD|BPF_IMM; s->k = 0; diff -Naur libpcap-1.3.0/pcap/bpf.h libpcap-1.3.0-with-modulus/pcap/bpf.h --- libpcap-1.3.0/pcap/bpf.h 2012-06-12 16:55:36.000000000 +0000 +++ libpcap-1.3.0-with-modulus/pcap/bpf.h 2012-08-31 01:36:53.199825471 +0000 @@ -1235,6 +1235,7 @@ #define BPF_LSH 0x60 #define BPF_RSH 0x70 #define BPF_NEG 0x80 +#define BPF_MOD 0x90 #define BPF_JA 0x00 #define BPF_JEQ 0x10 #define BPF_JGT 0x20 diff -Naur libpcap-1.3.0/scanner.l libpcap-1.3.0-with-modulus/scanner.l --- libpcap-1.3.0/scanner.l 2012-03-29 12:57:32.000000000 +0000 +++ libpcap-1.3.0-with-modulus/scanner.l 2012-08-31 01:36:53.225825770 +0000 @@ -329,7 +329,7 @@ sls return SLS; [ \r\n\t] ; -[+\-*/:\[\]!<>()&|=] return yytext[0]; +[+\-*/:\[\]!<>()&|=%] return yytext[0]; ">=" return GEQ; "<=" return LEQ; "!=" return NEQ; @@ -387,7 +387,7 @@ [A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? { yylval.s = sdup((char *)yytext); return ID; } "\\"[^ !()\n\t]+ { yylval.s = sdup((char *)yytext + 1); return ID; } -[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+ { +[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=%]+ { bpf_error("illegal token: %s", yytext); } . { bpf_error("illegal char '%c'", *yytext); } %%