]> 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 15cb93473deb568d15f0aad75bbf10d2d6e9b7dd..09f72d437cb17b9aaa85d8b61f3a0474c57d9009 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -7466,7 +7466,13 @@ gen_arth(compiler_state_t *cstate, int code, struct arth *a0,
                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) {
-               if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k > 31)
+               /*
+                * 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);
@@ -8568,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;
 
@@ -8606,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 */