]> The Tcpdump Group git mirrors - libpcap/blobdiff - gencode.c
Report an error for MPLS labels that don't fit in 20 bits.
[libpcap] / gencode.c
index 5387978863c550980bad4ab2e9e4a6b694dcdca8..09f72d437cb17b9aaa85d8b61f3a0474c57d9009 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -4718,8 +4718,29 @@ gen_dnhostop(compiler_state_t *cstate, bpf_u_int32 addr, int dir)
                gen_or(b0, b1);
                return b1;
 
-       case Q_ISO:
-               bpf_error(cstate, "ISO host filtering not implemented");
+       case Q_ADDR1:
+               bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_ADDR2:
+               bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_ADDR3:
+               bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_ADDR4:
+               bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_RA:
+               bpf_error(cstate, "'ra' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+               break;
+
+       case Q_TA:
+               bpf_error(cstate, "'ta' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+               break;
 
        default:
                abort();
@@ -4814,6 +4835,9 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
                }
                return b0;
 
+       case Q_LINK:
+               bpf_error(cstate, "link-layer modifier applied to %s", typestr);
+
        case Q_IP:
                return gen_hostop(cstate, addr, mask, dir, ETHERTYPE_IP, 12, 16);
 
@@ -7431,6 +7455,9 @@ gen_arth(compiler_state_t *cstate, int code, struct arth *a0,
        /*
         * Disallow division by, or modulus by, zero; we do this here
         * so that it gets done even if the optimizer is disabled.
+        *
+        * Also disallow shifts by a value greater than 31; we do this
+        * here, for the same reason.
         */
        if (code == BPF_DIV) {
                if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k == 0)
@@ -7438,6 +7465,15 @@ gen_arth(compiler_state_t *cstate, int code, struct arth *a0,
        } else if (code == BPF_MOD) {
                if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k == 0)
                        bpf_error(cstate, "modulus by zero");
+       } else if (code == BPF_LSH || code == BPF_RSH) {
+               /*
+                * XXX - we need to make up our minds as to what integers
+                * are signed and what integers are unsigned in BPF programs
+                * and in our IR.
+                */
+               if (a1->s->s.code == (BPF_LD|BPF_IMM) &&
+                   (a1->s->s.k < 0 || a1->s->s.k > 31))
+                       bpf_error(cstate, "shift by more than 31 bits");
        }
        s0 = xfer_to_x(cstate, a1);
        s1 = xfer_to_a(cstate, a0);
@@ -8538,7 +8574,7 @@ gen_vlan(compiler_state_t *cstate, int vlan_num)
  * support for MPLS
  */
 struct block *
-gen_mpls(compiler_state_t *cstate, int label_num)
+gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num, int has_label_num)
 {
        struct  block   *b0, *b1;
 
@@ -8576,7 +8612,11 @@ gen_mpls(compiler_state_t *cstate, int label_num)
         }
 
        /* If a specific MPLS label is requested, check it */
-       if (label_num >= 0) {
+       if (has_label_num) {
+               if (label_num > 0xFFFFF) {
+                       bpf_error(cstate, "MPLS label %u greater than maximum %u",
+                           label_num, 0xFFFFF);
+               }
                label_num = label_num << 12; /* label is shifted 12 bits on the wire */
                b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W, (bpf_int32)label_num,
                    0xfffff000); /* only compare the first 20 bits */