]> The Tcpdump Group git mirrors - libpcap/blobdiff - optimize.c
If parser debugging is enabled, ensure pcap_debug is exported.
[libpcap] / optimize.c
index 8a5210860486594e819178e00d5a9b46a386cef3..0a136b7a031a0ab5239beeb4e6d7e7aaadd7f847 100644 (file)
  *
  *  Optimization module for tcpdump intermediate representation.
  */
-#ifndef lint
-static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.91 2008-01-02 04:16:46 guy Exp $ (LBL)";
-#endif
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#ifdef WIN32
+#ifdef _WIN32
 #include <pcap-stdinc.h>
-#else /* WIN32 */
+#else /* _WIN32 */
 #if HAVE_INTTYPES_H
 #include <inttypes.h>
 #elif HAVE_STDINT_H
@@ -41,7 +37,7 @@ static const char rcsid[] _U_ =
 #include <sys/bitypes.h>
 #endif
 #include <sys/types.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -67,8 +63,26 @@ extern int _w32_ffs (int mask);
 #define ffs _w32_ffs
 #endif
 
-#if defined(WIN32) && defined (_MSC_VER)
-int ffs(int mask);
+/*
+ * So is the check for _MSC_VER done because MinGW has this?
+ */
+#if defined(_WIN32) && defined (_MSC_VER)
+/*
+ * ffs -- vax ffs instruction
+ *
+ * XXX - with versions of VS that have it, use _BitScanForward()?
+ */
+static int
+ffs(int mask)
+{
+       int bit;
+
+       if (mask == 0)
+               return(0);
+       for (bit = 1; !(mask & 1); bit++)
+               mask >>= 1;
+       return(bit);
+}
 #endif
 
 /*
@@ -610,6 +624,12 @@ fold_op(struct stmt *s, int v0, int v1)
                a /= b;
                break;
 
+       case BPF_MOD:
+               if (b == 0)
+                       bpf_error("modulus by zero");
+               a %= b;
+               break;
+
        case BPF_AND:
                a &= b;
                break;
@@ -618,6 +638,10 @@ fold_op(struct stmt *s, int v0, int v1)
                a |= b;
                break;
 
+       case BPF_XOR:
+               a ^= b;
+               break;
+
        case BPF_LSH:
                a <<= b;
                break;
@@ -978,8 +1002,10 @@ opt_stmt(struct stmt *s, int val[], int alter)
        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_XOR|BPF_K:
        case BPF_ALU|BPF_LSH|BPF_K:
        case BPF_ALU|BPF_RSH|BPF_K:
                op = BPF_OP(s->code);
@@ -990,7 +1016,7 @@ opt_stmt(struct stmt *s, int val[], int alter)
                                 * fixup the generated math code */
                                if (op == BPF_ADD ||
                                    op == BPF_LSH || op == BPF_RSH ||
-                                   op == BPF_OR) {
+                                   op == BPF_OR || op == BPF_XOR) {
                                        s->code = NOP;
                                        break;
                                }
@@ -1013,8 +1039,10 @@ opt_stmt(struct stmt *s, int val[], int alter)
        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_XOR|BPF_X:
        case BPF_ALU|BPF_LSH|BPF_X:
        case BPF_ALU|BPF_RSH|BPF_X:
                op = BPF_OP(s->code);
@@ -1041,12 +1069,12 @@ opt_stmt(struct stmt *s, int val[], int alter)
                 */
                if (alter && vmap[val[A_ATOM]].is_const
                    && vmap[val[A_ATOM]].const_val == 0) {
-                       if (op == BPF_ADD || op == BPF_OR) {
+                       if (op == BPF_ADD || op == BPF_OR || op == BPF_XOR) {
                                s->code = BPF_MISC|BPF_TXA;
                                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;
@@ -2210,7 +2238,7 @@ install_bpf_program(pcap_t *p, struct bpf_program *fp)
         * Validate the program.
         */
        if (!bpf_validate(fp->bf_insns, fp->bf_len)) {
-               snprintf(p->errbuf, sizeof(p->errbuf),
+               pcap_snprintf(p->errbuf, sizeof(p->errbuf),
                        "BPF program is not valid");
                return (-1);
        }
@@ -2224,7 +2252,7 @@ install_bpf_program(pcap_t *p, struct bpf_program *fp)
        p->fcode.bf_len = fp->bf_len;
        p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size);
        if (p->fcode.bf_insns == NULL) {
-               snprintf(p->errbuf, sizeof(p->errbuf),
+               pcap_snprintf(p->errbuf, sizeof(p->errbuf),
                         "malloc: %s", pcap_strerror(errno));
                return (-1);
        }