X-Git-Url: https://git.tcpdump.org/libpcap/blobdiff_plain/bcbef226ca11662342b5e267e7f12066bcfd60d0..71abe040fa49dfcb8ba3e08e5f21896b0c7cc6e8:/gencode.c diff --git a/gencode.c b/gencode.c index 7aa96387..09f72d43 100644 --- a/gencode.c +++ b/gencode.c @@ -433,6 +433,25 @@ bpf_parser_error(compiler_state_t *cstate, const char *msg) /* NOTREACHED */ } +/* + * For use by the optimizer, which needs to do its *own* cleanup before + * delivering a longjmp-based exception. + */ +void +bpf_vset_error(compiler_state_t *cstate, const char *fmt, va_list ap) +{ + if (cstate->bpf_pcap != NULL) + (void)pcap_vsnprintf(pcap_geterr(cstate->bpf_pcap), + PCAP_ERRBUF_SIZE, fmt, ap); +} + +void PCAP_NORETURN +bpf_abort_compilation(compiler_state_t *cstate) +{ + longjmp(cstate->top_ctx, 1); + /* NOTREACHED */ +} + /* VARARGS */ void PCAP_NORETURN bpf_error(compiler_state_t *cstate, const char *fmt, ...) @@ -440,11 +459,9 @@ bpf_error(compiler_state_t *cstate, const char *fmt, ...) va_list ap; va_start(ap, fmt); - if (cstate->bpf_pcap != NULL) - (void)pcap_vsnprintf(pcap_geterr(cstate->bpf_pcap), - PCAP_ERRBUF_SIZE, fmt, ap); + bpf_vset_error(cstate, fmt, ap); va_end(ap); - longjmp(cstate->top_ctx, 1); + bpf_abort_compilation(cstate); /* NOTREACHED */ } @@ -4701,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(); @@ -4797,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); @@ -4947,88 +4988,109 @@ gen_host6(compiler_state_t *cstate, struct in6_addr *addr, bpf_error(cstate, "'arp' modifier applied to ip6 %s", typestr); case Q_SCTP: - bpf_error(cstate, "'sctp' modifier applied to %s", typestr); + bpf_error(cstate, "'sctp' modifier applied to ip6 %s", typestr); case Q_TCP: - bpf_error(cstate, "'tcp' modifier applied to %s", typestr); + bpf_error(cstate, "'tcp' modifier applied to ip6 %s", typestr); case Q_UDP: - bpf_error(cstate, "'udp' modifier applied to %s", typestr); + bpf_error(cstate, "'udp' modifier applied to ip6 %s", typestr); case Q_ICMP: - bpf_error(cstate, "'icmp' modifier applied to %s", typestr); + bpf_error(cstate, "'icmp' modifier applied to ip6 %s", typestr); case Q_IGMP: - bpf_error(cstate, "'igmp' modifier applied to %s", typestr); + bpf_error(cstate, "'igmp' modifier applied to ip6 %s", typestr); case Q_IGRP: - bpf_error(cstate, "'igrp' modifier applied to %s", typestr); - - case Q_PIM: - bpf_error(cstate, "'pim' modifier applied to %s", typestr); - - case Q_VRRP: - bpf_error(cstate, "'vrrp' modifier applied to %s", typestr); - - case Q_CARP: - bpf_error(cstate, "'carp' modifier applied to %s", typestr); + bpf_error(cstate, "'igrp' modifier applied to ip6 %s", typestr); case Q_ATALK: - bpf_error(cstate, "AppleTalk modifier applied to %s", typestr); - - case Q_AARP: - bpf_error(cstate, "AARP host filtering not implemented"); + bpf_error(cstate, "AppleTalk modifier applied to ip6 %s", typestr); case Q_DECNET: bpf_error(cstate, "'decnet' modifier applied to ip6 %s", typestr); - case Q_SCA: - bpf_error(cstate, "SCA host filtering not implemented"); - case Q_LAT: - bpf_error(cstate, "LAT host filtering not implemented"); + bpf_error(cstate, "'lat' modifier applied to ip6 %s", typestr); - case Q_MOPDL: - bpf_error(cstate, "MOPDL host filtering not implemented"); + case Q_SCA: + bpf_error(cstate, "'sca' modifier applied to ip6 %s", typestr); case Q_MOPRC: - bpf_error(cstate, "MOPRC host filtering not implemented"); + bpf_error(cstate, "'moprc' modifier applied to ip6 %s", typestr); + + case Q_MOPDL: + bpf_error(cstate, "'mopdl' modifier applied to ip6 %s", typestr); case Q_IPV6: return gen_hostop6(cstate, addr, mask, dir, ETHERTYPE_IPV6, 8, 24); case Q_ICMPV6: - bpf_error(cstate, "'icmp6' modifier applied to %s", typestr); + bpf_error(cstate, "'icmp6' modifier applied to ip6 %s", typestr); case Q_AH: - bpf_error(cstate, "'ah' modifier applied to %s", typestr); + bpf_error(cstate, "'ah' modifier applied to ip6 %s", typestr); case Q_ESP: - bpf_error(cstate, "'esp' modifier applied to %s", typestr); + bpf_error(cstate, "'esp' modifier applied to ip6 %s", typestr); + + case Q_PIM: + bpf_error(cstate, "'pim' modifier applied to ip6 %s", typestr); + + case Q_VRRP: + bpf_error(cstate, "'vrrp' modifier applied to ip6 %s", typestr); + + case Q_AARP: + bpf_error(cstate, "'aarp' modifier applied to ip6 %s", typestr); case Q_ISO: - bpf_error(cstate, "ISO host filtering not implemented"); + bpf_error(cstate, "'iso' modifier applied to ip6 %s", typestr); case Q_ESIS: - bpf_error(cstate, "'esis' modifier applied to %s", typestr); + bpf_error(cstate, "'esis' modifier applied to ip6 %s", typestr); case Q_ISIS: - bpf_error(cstate, "'isis' modifier applied to %s", typestr); + bpf_error(cstate, "'isis' modifier applied to ip6 %s", typestr); case Q_CLNP: - bpf_error(cstate, "'clnp' modifier applied to %s", typestr); + bpf_error(cstate, "'clnp' modifier applied to ip6 %s", typestr); case Q_STP: - bpf_error(cstate, "'stp' modifier applied to %s", typestr); + bpf_error(cstate, "'stp' modifier applied to ip6 %s", typestr); case Q_IPX: - bpf_error(cstate, "IPX host filtering not implemented"); + bpf_error(cstate, "'ipx' modifier applied to ip6 %s", typestr); case Q_NETBEUI: - bpf_error(cstate, "'netbeui' modifier applied to %s", typestr); + bpf_error(cstate, "'netbeui' modifier applied to ip6 %s", typestr); + + case Q_ISIS_L1: + bpf_error(cstate, "'l1' modifier applied to ip6 %s", typestr); + + case Q_ISIS_L2: + bpf_error(cstate, "'l2' modifier applied to ip6 %s", typestr); + + case Q_ISIS_IIH: + bpf_error(cstate, "'iih' modifier applied to ip6 %s", typestr); + + case Q_ISIS_SNP: + bpf_error(cstate, "'snp' modifier applied to ip6 %s", typestr); + + case Q_ISIS_CSNP: + bpf_error(cstate, "'csnp' modifier applied to ip6 %s", typestr); + + case Q_ISIS_PSNP: + bpf_error(cstate, "'psnp' modifier applied to ip6 %s", typestr); + + case Q_ISIS_LSP: + bpf_error(cstate, "'lsp' modifier applied to ip6 %s", typestr); case Q_RADIO: - bpf_error(cstate, "'radio' modifier applied to %s", typestr); + bpf_error(cstate, "'radio' modifier applied to ip6 %s", typestr); + + case Q_CARP: + bpf_error(cstate, "'carp' modifier applied to ip6 %s", typestr); default: abort(); @@ -7393,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) @@ -7400,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); @@ -8500,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; @@ -8538,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 */