diff --git a/0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch b/0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch index 888bb9a..46cc956 100644 --- a/0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch +++ b/0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch @@ -25,3 +25,4 @@ index f5a7e0c..f220e68 100644 -- 1.8.3.1 + diff --git a/0002-pcap-config-mitigate-multilib-conflict.patch b/0002-pcap-config-mitigate-multilib-conflict.patch index 8b6b420..c57ccd4 100644 --- a/0002-pcap-config-mitigate-multilib-conflict.patch +++ b/0002-pcap-config-mitigate-multilib-conflict.patch @@ -86,3 +86,4 @@ index 206be3b..75f2c9f 100644 -- 1.8.3.1 + diff --git a/0003-pcap-linux-apparently-ctc-interfaces-on-s390-has-eth.patch b/0003-pcap-linux-apparently-ctc-interfaces-on-s390-has-eth.patch new file mode 100644 index 0000000..6d7532c --- /dev/null +++ b/0003-pcap-linux-apparently-ctc-interfaces-on-s390-has-eth.patch @@ -0,0 +1,29 @@ +From b9fa92532328daad84766753422e8a21fd474e6f Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 29 Sep 2014 08:37:25 +0200 +Subject: [PATCH 3/4] pcap-linux: apparently ctc interfaces on s390 has + ethernet DLT + +--- + pcap-linux.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/pcap-linux.c b/pcap-linux.c +index 900ebbc..58292c3 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -3197,6 +3197,10 @@ activate_new(pcap_t *handle) + handle->linktype = DLT_LINUX_SLL; + } + ++ /* Hack to make things work on s390 ctc interfaces */ ++ if (strncmp("ctc", device, 3) == 0) ++ handle->linktype = DLT_EN10MB; ++ + handlep->ifindex = iface_get_id(sock_fd, device, + handle->errbuf); + if (handlep->ifindex == -1) { +-- +1.8.3.1 + + diff --git a/0012-Plug-a-file-descriptor-leak.patch b/0012-Plug-a-file-descriptor-leak.patch deleted file mode 100644 index 878dc4c..0000000 --- a/0012-Plug-a-file-descriptor-leak.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 40fe5f21bae1847a92f18efdcc8ad061db8f6cce Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Thu, 7 Mar 2019 22:05:24 -0800 -Subject: [PATCH 12/83] Plug a file descriptor leak. - ---- - savefile.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/savefile.c b/savefile.c -index 01ee7d0..c6c0cb8 100644 ---- a/savefile.c -+++ b/savefile.c -@@ -317,6 +317,7 @@ pcap_t* pcap_hopen_offline_with_tstamp_precision(intptr_t osfd, u_int precision, - { - pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, - errno, "_fdopen"); -+ _close(fd); - return NULL; - } - --- -1.8.3.1 - diff --git a/0036-Use-the-snapshot-length-to-set-the-buffer-size-and-s.patch b/0036-Use-the-snapshot-length-to-set-the-buffer-size-and-s.patch deleted file mode 100644 index 7344551..0000000 --- a/0036-Use-the-snapshot-length-to-set-the-buffer-size-and-s.patch +++ /dev/null @@ -1,291 +0,0 @@ -From 4ccdc8a3cbf5195a7c089002136e53db541b36ba Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Tue, 19 Mar 2019 11:03:40 -0700 -Subject: [PATCH 36/83] Use the snapshot length to set the buffer size, and set - the len field properly. - -The USB buffer size limits the number of bytes worth of data that is -saved; set the buffer size based on the snapshot length. Limit the -buffer size values to the range of values the kernel supports, and -adjust the reported snapshot length if we can't set the buffer size -large enough for the requested snapshot length. - -When reading packets, for packets with URB data, set the len field based -on the urb_len field rather than the data_len field, so it reflects how -much data was transferred in the transaction rather than how much of -that data was actually provided by the USB monitor mechanism. - -Fix usb_read_linux_mmap() to use sizeof(pcap_usb_header_mmapped) rather -than sizeof(pcap_usb_header) everywhere, as pcap_usb_header_mmapped is -the structure being supplied as the metadata header. - -This should fix GitHub issue #808. ---- - pcap-usb-linux.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 178 insertions(+), 17 deletions(-) - -diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c -index 3e70a8d..f202cb6 100644 ---- a/pcap-usb-linux.c -+++ b/pcap-usb-linux.c -@@ -381,18 +381,102 @@ usb_findalldevs(pcap_if_list_t *devlistp, char *err_str) - } - } - -+/* -+ * Matches what's in mon_bin.c in the Linux kernel. -+ */ -+#define MIN_RING_SIZE (8*1024) -+#define MAX_RING_SIZE (1200*1024) -+ -+static int -+usb_set_ring_size(pcap_t* handle, size_t header_size) -+{ -+ /* -+ * A packet from binary usbmon has: -+ * -+ * 1) a fixed-length header, of size header_size; -+ * 2) descriptors, for isochronous transfers; -+ * 3) the payload. -+ * -+ * The kernel buffer has a size, defaulting to 300KB, with a -+ * minimum of 8KB and a maximum of 1200KB. The size is set with -+ * the MON_IOCT_RING_SIZE ioctl; the size passed in is rounded up -+ * to a page size. -+ * -+ * No more than {buffer size}/5 bytes worth of payload is saved. -+ * Therefore, if we subtract the fixed-length size from the -+ * snapshot length, we have the biggest payload we want (we -+ * don't worry about the descriptors - if we have descriptors, -+ * we'll just discard the last bit of the payload to get it -+ * to fit). We multiply that result by 5 and set the buffer -+ * size to that value. -+ */ -+ int ring_size; -+ -+ if ((size_t)handle->snapshot < header_size) -+ handle->snapshot = header_size; -+ /* The maximum snapshot size is small enough that this won't overflow */ -+ ring_size = (handle->snapshot - header_size) * 5; -+ -+ /* -+ * Will this get an error? -+ * (There's no wqy to query the minimum or maximum, so we just -+ * copy the value from the kernel source. We don't round it -+ * up to a multiple of the page size.) -+ */ -+ if (ring_size > MAX_RING_SIZE) { -+ /* -+ * Yes. Lower the ring size to the maximum, and set the -+ * snapshot length to the value that would give us a -+ * maximum-size ring. -+ */ -+ ring_size = MAX_RING_SIZE; -+ handle->snapshot = header_size + (MAX_RING_SIZE/5); -+ } else if (ring_size < MIN_RING_SIZE) { -+ /* -+ * Yes. Raise the ring size to the minimum, but leave -+ * the snapshot length unchanged, so we show the -+ * callback no more data than specified by the -+ * snapshot length. -+ */ -+ ring_size = MIN_RING_SIZE; -+ } -+ -+ if (ioctl(handle->fd, MON_IOCT_RING_SIZE, ring_size) == -1) { -+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, -+ errno, "Can't set ring size from fd %d", handle->fd); -+ return -1; -+ } -+ return ring_size; -+} -+ - static - int usb_mmap(pcap_t* handle) - { - struct pcap_usb_linux *handlep = handle->priv; -- int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE); -- if (len < 0) -+ int len; -+ -+ /* -+ * Attempt to set the ring size as appropriate for the snapshot -+ * length, reducing the snapshot length if that'd make the ring -+ * bigger than the kernel supports. -+ */ -+ len = usb_set_ring_size(handle, sizeof(pcap_usb_header_mmapped)); -+ if (len == -1) { -+ /* Failed. Fall back on non-memory-mapped access. */ - return 0; -+ } - - handlep->mmapbuflen = len; - handlep->mmapbuf = mmap(0, handlep->mmapbuflen, PROT_READ, - MAP_SHARED, handle->fd, 0); -- return handlep->mmapbuf != MAP_FAILED; -+ if (handlep->mmapbuf == MAP_FAILED) { -+ /* -+ * Failed. We don't treat that as a fatal error, we -+ * just try to fall back on non-memory-mapped access. -+ */ -+ return 0; -+ } -+ return 1; - } - - #ifdef HAVE_LINUX_USBDEVICE_FS_H -@@ -606,6 +690,7 @@ usb_activate(pcap_t* handle) - /* try to use fast mmap access */ - if (usb_mmap(handle)) - { -+ /* We succeeded. */ - handle->linktype = DLT_USB_LINUX_MMAPPED; - handle->stats_op = usb_stats_linux_bin; - handle->read_op = usb_read_linux_mmap; -@@ -622,7 +707,19 @@ usb_activate(pcap_t* handle) - return 0; - } - -- /* can't mmap, use plain binary interface access */ -+ /* -+ * We failed; try plain binary interface access. -+ * -+ * Attempt to set the ring size as appropriate for -+ * the snapshot length, reducing the snapshot length -+ * if that'd make the ring bigger than the kernel -+ * supports. -+ */ -+ if (usb_set_ring_size(handle, sizeof(pcap_usb_header)) == -1) { -+ /* Failed. */ -+ close(handle->fd); -+ return PCAP_ERROR; -+ } - handle->stats_op = usb_stats_linux_bin; - handle->read_op = usb_read_linux_bin; - #ifdef HAVE_LINUX_USBDEVICE_FS_H -@@ -1075,13 +1172,44 @@ usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u - return -1; - } - -- /* we can get less that than really captured from kernel, depending on -- * snaplen, so adjust header accordingly */ -+ /* -+ * info.hdr->data_len is the number of bytes of isochronous -+ * descriptors (if any) plus the number of bytes of data -+ * provided. There are no isochronous descriptors here, -+ * because we're using the old 48-byte header. -+ * -+ * If info.hdr->data_flag is non-zero, there's no URB data; -+ * info.hdr->urb_len is the size of the buffer into which -+ * data is to be placed; it does not represent the amount -+ * of data transferred. If info.hdr->data_flag is zero, -+ * there is URB data, and info.hdr->urb_len is the number -+ * of bytes transmitted or received; it doesn't include -+ * isochronous descriptors. -+ * -+ * The kernel may give us more data than the snaplen; if it did, -+ * reduce the data length so that the total number of bytes we -+ * tell our client we have is not greater than the snaplen. -+ */ - if (info.hdr->data_len < clen) - clen = info.hdr->data_len; - info.hdr->data_len = clen; -- pkth.caplen = clen + sizeof(pcap_usb_header); -- pkth.len = info.hdr->data_len + sizeof(pcap_usb_header); -+ pkth.caplen = sizeof(pcap_usb_header) + clen; -+ if (info.hdr->data_flag) { -+ /* -+ * No data; just base the on-the-wire length on -+ * info.hdr->data_len (so that it's >= the captured -+ * length). -+ */ -+ pkth.len = sizeof(pcap_usb_header) + info.hdr->data_len; -+ } else { -+ /* -+ * We got data; base the on-the-wire length on -+ * info.hdr->urb_len, so that it includes data -+ * discarded by the USB monitor device due to -+ * its buffer being too small. -+ */ -+ pkth.len = sizeof(pcap_usb_header) + info.hdr->urb_len; -+ } - pkth.ts.tv_sec = info.hdr->ts_sec; - pkth.ts.tv_usec = info.hdr->ts_usec; - -@@ -1108,12 +1236,12 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch - struct mon_bin_mfetch fetch; - int32_t vec[VEC_SIZE]; - struct pcap_pkthdr pkth; -- pcap_usb_header* hdr; -+ pcap_usb_header_mmapped* hdr; - int nflush = 0; - int packets = 0; - u_int clen, max_clen; - -- max_clen = handle->snapshot - sizeof(pcap_usb_header); -+ max_clen = handle->snapshot - sizeof(pcap_usb_header_mmapped); - - for (;;) { - int i, ret; -@@ -1151,19 +1279,52 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch - nflush = fetch.nfetch; - for (i=0; immapbuf[vec[i]]; -+ hdr = (pcap_usb_header_mmapped*) &handlep->mmapbuf[vec[i]]; - if (hdr->event_type == '@') - continue; - -- /* we can get less that than really captured from kernel, depending on -- * snaplen, so adjust header accordingly */ -+ /* -+ * hdr->data_len is the number of bytes of -+ * isochronous descriptors (if any) plus the -+ * number of bytes of data provided. -+ * -+ * If hdr->data_flag is non-zero, there's no -+ * URB data; hdr->urb_len is the size of the -+ * buffer into which data is to be placed; it does -+ * not represent the amount of data transferred. -+ * If hdr->data_flag is zero, there is URB data, -+ * and hdr->urb_len is the number of bytes -+ * transmitted or received; it doesn't include -+ * isochronous descriptors. -+ * -+ * The kernel may give us more data than the -+ * snaplen; if it did, reduce the data length -+ * so that the total number of bytes we -+ * tell our client we have is not greater than -+ * the snaplen. -+ */ - clen = max_clen; - if (hdr->data_len < clen) - clen = hdr->data_len; -- -- /* get packet info from header*/ -- pkth.caplen = clen + sizeof(pcap_usb_header_mmapped); -- pkth.len = hdr->data_len + sizeof(pcap_usb_header_mmapped); -+ pkth.caplen = sizeof(pcap_usb_header_mmapped) + clen; -+ if (hdr->data_flag) { -+ /* -+ * No data; just base the on-the-wire length -+ * on hdr->data_len (so that it's >= the -+ * captured length). -+ */ -+ pkth.len = sizeof(pcap_usb_header_mmapped) + -+ hdr->data_len; -+ } else { -+ /* -+ * We got data; base the on-the-wire length -+ * on hdr->urb_len, so that it includes -+ * data discarded by the USB monitor device -+ * due to its buffer being too small. -+ */ -+ pkth.len = sizeof(pcap_usb_header_mmapped) + -+ (hdr->ndesc * sizeof (usb_isodesc)) + hdr->urb_len; -+ } - pkth.ts.tv_sec = hdr->ts_sec; - pkth.ts.tv_usec = hdr->ts_usec; - --- -1.8.3.1 diff --git a/0066-Check-for-an-empty-description-by-checking-if-the-fi.patch b/0066-Check-for-an-empty-description-by-checking-if-the-fi.patch deleted file mode 100644 index 28e4a86..0000000 --- a/0066-Check-for-an-empty-description-by-checking-if-the-fi.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 593769c3637583653bafa924fe348115016618c3 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Fri, 31 May 2019 10:35:25 -0700 -Subject: [PATCH 66/83] Check for an empty description by checking if the first - character is NUL. - ---- - pcap.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/pcap.c b/pcap.c -index d9917a2..0d98519 100644 ---- a/pcap.c -+++ b/pcap.c -@@ -802,7 +802,7 @@ get_if_description(const char *name) - } - #endif /* __FreeBSD__ */ - close(s); -- if (description != NULL && strlen(description) == 0) { -+ if (description != NULL && description[0] == '\0') { - /* - * Description is empty, so discard it. - */ --- -1.8.3.1 - diff --git a/0068-Fixed-the-fread-call-in-the-savefile.c-file.patch b/0068-Fixed-the-fread-call-in-the-savefile.c-file.patch deleted file mode 100644 index 788f121..0000000 --- a/0068-Fixed-the-fread-call-in-the-savefile.c-file.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 9157a663d9e845e23697f598994f53f67cfef799 Mon Sep 17 00:00:00 2001 -From: Tymoteusz Blazejczyk -Date: Wed, 12 Jun 2019 10:30:32 +0200 -Subject: [PATCH 68/83] Fixed the fread call in the savefile.c file - -Currently it was an undefined behavior (UB). -It passes wrong parameters to the fread function call (1 byte, 4 elements). -It should be 4 bytes and 1 element because the `magic` variable is a single 32-bits integer (4 bytes). - -``` -bytes_read = fread(pointer, number_of_bytes, number_of_elements, file); -``` - -On some machines the `fread()` call returned 0 with no error from the `ferror()` call with -correct and valid PCAP files. - -Reference: https://en.cppreference.com/w/c/io/fread ---- - savefile.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/savefile.c b/savefile.c -index 152c917..e6404e7 100644 ---- a/savefile.c -+++ b/savefile.c -@@ -359,7 +359,7 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision, - * Windows Sniffer, and Microsoft Network Monitor) all have magic - * numbers that are unique in their first 4 bytes. - */ -- amt_read = fread((char *)&magic, 1, sizeof(magic), fp); -+ amt_read = fread(&magic, sizeof(magic), 1, fp); - if (amt_read != sizeof(magic)) { - if (ferror(fp)) { - pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, --- -1.8.3.1 - - diff --git a/0069-Fixed-number-of-elements-returned.patch b/0069-Fixed-number-of-elements-returned.patch deleted file mode 100644 index 4dc9f6f..0000000 --- a/0069-Fixed-number-of-elements-returned.patch +++ /dev/null @@ -1,25 +0,0 @@ -From b0e790519df4ec8204c843987fdfa4aa18e2a3cd Mon Sep 17 00:00:00 2001 -From: Tymoteusz Blazejczyk -Date: Wed, 12 Jun 2019 16:01:05 +0200 -Subject: [PATCH 69/83] Fixed number of elements returned - ---- - savefile.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/savefile.c b/savefile.c -index e6404e7..9e4724b 100644 ---- a/savefile.c -+++ b/savefile.c -@@ -360,7 +360,7 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision, - * numbers that are unique in their first 4 bytes. - */ - amt_read = fread(&magic, sizeof(magic), 1, fp); -- if (amt_read != sizeof(magic)) { -+ if (amt_read != 1) { - if (ferror(fp)) { - pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, - errno, "error reading dump file"); --- -1.8.3.1 - diff --git a/0070-Read-the-magic-number-into-a-byte-array.patch b/0070-Read-the-magic-number-into-a-byte-array.patch deleted file mode 100644 index 23917bf..0000000 --- a/0070-Read-the-magic-number-into-a-byte-array.patch +++ /dev/null @@ -1,212 +0,0 @@ -From 2e9d0ae34ece4d6f67f4d66a4c3628febf0b13dd Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Wed, 12 Jun 2019 11:32:21 -0700 -Subject: [PATCH 70/83] Read the magic number into a byte array. - -Apparently, in some C implementations, attempting to do an fread() into -a variable of a 32-bit unsigned integral type with a size of 1 and a -count of 4 returns 0 with an EOF indication; see GitHub pull request - -We can make the size be the size of the variable and the count be 1, but -that means that the count returned by an fread() terminated by an EOF -will be 0, not the number of bytes successfully read, so the "truncated -dump file" message will give an invalid count: - - tcpdump: truncated dump file; tried to read 4 file header bytes, - only got 0 - -If, instead, we read into an array of 4 bytes, with a size of 1 and a -count of 4, we'll get the right short count back. - -Pass the byte array to the file-type-specific "is this a file of this -type?" routines, so that if we add support for files where the magic -number isn't byte-order dependent (e.g., Microsoft Network Monitor), we -can handle them more cleanly (check for the standard magic number as a -4-byte array, rather than as its numerical value in both the host's byte -order and the byte-swapped byte order). ---- - savefile.c | 8 ++++---- - sf-pcap.c | 24 ++++++++++++++---------- - sf-pcap.h | 2 +- - sf-pcapng.c | 14 ++++++++------ - sf-pcapng.h | 2 +- - 5 files changed, 28 insertions(+), 22 deletions(-) - -diff --git a/savefile.c b/savefile.c -index 9e4724b..7adee42 100644 ---- a/savefile.c -+++ b/savefile.c -@@ -332,7 +332,7 @@ pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf) - } - #endif - --static pcap_t *(*check_headers[])(bpf_u_int32, FILE *, u_int, char *, int *) = { -+static pcap_t *(*check_headers[])(const uint8_t *, FILE *, u_int, char *, int *) = { - pcap_check_header, - pcap_ng_check_header - }; -@@ -347,7 +347,7 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision, - char *errbuf) - { - register pcap_t *p; -- bpf_u_int32 magic; -+ uint8_t magic[4]; - size_t amt_read; - u_int i; - int err; -@@ -359,8 +359,8 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision, - * Windows Sniffer, and Microsoft Network Monitor) all have magic - * numbers that are unique in their first 4 bytes. - */ -- amt_read = fread(&magic, sizeof(magic), 1, fp); -- if (amt_read != 1) { -+ amt_read = fread(&magic, 1, sizeof(magic), fp); -+ if (amt_read != sizeof(magic)) { - if (ferror(fp)) { - pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, - errno, "error reading dump file"); -diff --git a/sf-pcap.c b/sf-pcap.c -index 87fc5ce..f56fff7 100644 ---- a/sf-pcap.c -+++ b/sf-pcap.c -@@ -150,9 +150,10 @@ struct pcap_sf { - * relevant information from the header. - */ - pcap_t * --pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf, -+pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf, - int *err) - { -+ bpf_u_int32 magic_int; - struct pcap_file_header hdr; - size_t amt_read; - pcap_t *p; -@@ -169,11 +170,14 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf, - * number for a pcap savefile, or for a byte-swapped pcap - * savefile. - */ -- if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC && -- magic != NSEC_TCPDUMP_MAGIC) { -- magic = SWAPLONG(magic); -- if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC && -- magic != NSEC_TCPDUMP_MAGIC) -+ memcpy(&magic_int, magic, sizeof(magic_int)); -+ if (magic_int != TCPDUMP_MAGIC && -+ magic_int != KUZNETZOV_TCPDUMP_MAGIC && -+ magic_int != NSEC_TCPDUMP_MAGIC) { -+ magic_int = SWAPLONG(magic_int); -+ if (magic_int != TCPDUMP_MAGIC && -+ magic_int != KUZNETZOV_TCPDUMP_MAGIC && -+ magic_int != NSEC_TCPDUMP_MAGIC) - return (NULL); /* nope */ - swapped = 1; - } -@@ -182,7 +186,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf, - * They are. Put the magic number in the header, and read - * the rest of the header. - */ -- hdr.magic = magic; -+ hdr.magic = magic_int; - amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1, - sizeof(hdr) - sizeof(hdr.magic), fp); - if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) { -@@ -273,7 +277,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf, - switch (precision) { - - case PCAP_TSTAMP_PRECISION_MICRO: -- if (magic == NSEC_TCPDUMP_MAGIC) { -+ if (magic_int == NSEC_TCPDUMP_MAGIC) { - /* - * The file has nanoseconds, the user - * wants microseconds; scale the -@@ -290,7 +294,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf, - break; - - case PCAP_TSTAMP_PRECISION_NANO: -- if (magic == NSEC_TCPDUMP_MAGIC) { -+ if (magic_int == NSEC_TCPDUMP_MAGIC) { - /* - * The file has nanoseconds, the - * user wants nanoseconds; nothing to do. -@@ -344,7 +348,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf, - break; - } - -- if (magic == KUZNETZOV_TCPDUMP_MAGIC) { -+ if (magic_int == KUZNETZOV_TCPDUMP_MAGIC) { - /* - * XXX - the patch that's in some versions of libpcap - * changes the packet header but not the magic number, -diff --git a/sf-pcap.h b/sf-pcap.h -index e9c7eaf..bc7150f 100644 ---- a/sf-pcap.h -+++ b/sf-pcap.h -@@ -31,7 +31,7 @@ - #ifndef sf_pcap_h - #define sf_pcap_h - --extern pcap_t *pcap_check_header(bpf_u_int32 magic, FILE *fp, -+extern pcap_t *pcap_check_header(const uint8_t *magic, FILE *fp, - u_int precision, char *errbuf, int *err); - - #endif -diff --git a/sf-pcapng.c b/sf-pcapng.c -index 7394ce4..52f795f 100644 ---- a/sf-pcapng.c -+++ b/sf-pcapng.c -@@ -761,9 +761,10 @@ add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf) - * relevant information from the header. - */ - pcap_t * --pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf, -- int *err) -+pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, -+ char *errbuf, int *err) - { -+ bpf_u_int32 magic_int; - size_t amt_read; - bpf_u_int32 total_length; - bpf_u_int32 byte_order_magic; -@@ -785,7 +786,8 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf, - * Check whether the first 4 bytes of the file are the block - * type for a pcapng savefile. - */ -- if (magic != BT_SHB) { -+ memcpy(&magic_int, magic, sizeof(magic_int)); -+ if (magic_int != BT_SHB) { - /* - * XXX - check whether this looks like what the block - * type would be after being munged by mapping between -@@ -944,12 +946,12 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf, - */ - bhdrp = (struct block_header *)p->buffer; - shbp = (struct section_header_block *)((u_char *)p->buffer + sizeof(struct block_header)); -- bhdrp->block_type = magic; -+ bhdrp->block_type = magic_int; - bhdrp->total_length = total_length; - shbp->byte_order_magic = byte_order_magic; - if (read_bytes(fp, -- (u_char *)p->buffer + (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)), -- total_length - (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)), -+ (u_char *)p->buffer + (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)), -+ total_length - (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)), - 1, errbuf) == -1) - goto fail; - -diff --git a/sf-pcapng.h b/sf-pcapng.h -index d99b0d4..835082a 100644 ---- a/sf-pcapng.h -+++ b/sf-pcapng.h -@@ -26,7 +26,7 @@ - #ifndef sf_pcapng_h - #define sf_pcapng_h - --extern pcap_t *pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, -+extern pcap_t *pcap_ng_check_header(const uint8_t *magic, FILE *fp, - u_int precision, char *errbuf, int *err); - - #endif --- -1.8.3.1 - - diff --git a/0075-Use-ab-rather-than-rb-for-the-pcap_dump_open_append-.patch b/0075-Use-ab-rather-than-rb-for-the-pcap_dump_open_append-.patch deleted file mode 100644 index e96f969..0000000 --- a/0075-Use-ab-rather-than-rb-for-the-pcap_dump_open_append-.patch +++ /dev/null @@ -1,171 +0,0 @@ -From f542342e5e232c9ed522b99897cf7aedccc89fe8 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Tue, 25 Jun 2019 01:55:16 -0700 -Subject: [PATCH 75/83] Use "ab+" rather than "rb+" for the - pcap_dump_open_append() open mode. - -That way, the file will be created if it doesn't exist. - -Do a seek to the beginning of the file before checking whether it has a -file header; ISO C says it's implementation-defined whether an open in -append mode puts the file position indicator at the beginning or the end -of the file, and neither the Single UNIX Specification nor the Microsoft -documentation seemed to indicate which of those are the case. - -Consistently cast the result of fclose() on an open failure to void - -we've already gotten an error, so we don't care whether the close fails -as well. - -Clean up an error message slightly. - -See GitHub issue #247. ---- - sf-pcap.c | 51 +++++++++++++++++++++++++++++++++++++++------------ - 1 file changed, 39 insertions(+), 12 deletions(-) - -diff --git a/sf-pcap.c b/sf-pcap.c -index f56fff7..23057a0 100644 ---- a/sf-pcap.c -+++ b/sf-pcap.c -@@ -930,11 +930,19 @@ pcap_dump_open_append(pcap_t *p, const char *fname) - return (pcap_setup_dump(p, linktype, stdout, "standard output")); - - /* -+ * "a" will cause the file *not* to be truncated if it exists -+ * but will cause it to be created if it doesn't. It will -+ * also cause all writes to be done at the end of the file, -+ * but will allow reads to be done anywhere in the file. This -+ * is what we need, because we need to read from the beginning -+ * of the file to see if it already has a header and packets -+ * or if it doesn't. -+ * - * "b" is supported as of C90, so *all* UN*Xes should support it, - * even though it does nothing. It's required on Windows, as the - * file is a binary file and must be read in binary mode. - */ -- f = fopen(fname, "rb+"); -+ f = fopen(fname, "ab+"); - if (f == NULL) { - pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, - errno, "%s", fname); -@@ -943,18 +951,33 @@ pcap_dump_open_append(pcap_t *p, const char *fname) - - /* - * Try to read a pcap header. -+ * -+ * We do not assume that the file will be positioned at the -+ * beginning immediately after we've opened it - we seek to -+ * the beginning. ISO C says it's implementation-defined -+ * whether the file position indicator is at the beginning -+ * or the end of the file after an append-mode open, and -+ * it wasn't obvious from the Single UNIX Specification -+ * or the Microsoft documentation how that works on SUS- -+ * compliant systems or on Windows. - */ -+ if (fseek(f, 0, SEEK_SET) == -1) { -+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, -+ errno, "Can't seek to the beginning of %s", fname); -+ (void)fclose(f); -+ return (NULL); -+ } - amt_read = fread(&ph, 1, sizeof (ph), f); - if (amt_read != sizeof (ph)) { - if (ferror(f)) { - pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, - errno, "%s", fname); -- fclose(f); -+ (void)fclose(f); - return (NULL); - } else if (feof(f) && amt_read > 0) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "%s: truncated pcap file header", fname); -- fclose(f); -+ (void)fclose(f); - return (NULL); - } - } -@@ -990,7 +1013,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname) - if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "%s: different time stamp precision, cannot append to file", fname); -- fclose(f); -+ (void)fclose(f); - return (NULL); - } - break; -@@ -999,7 +1022,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname) - if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "%s: different time stamp precision, cannot append to file", fname); -- fclose(f); -+ (void)fclose(f); - return (NULL); - } - break; -@@ -1008,7 +1031,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname) - case SWAPLONG(NSEC_TCPDUMP_MAGIC): - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "%s: different byte order, cannot append to file", fname); -- fclose(f); -+ (void)fclose(f); - return (NULL); - - case KUZNETZOV_TCPDUMP_MAGIC: -@@ -1017,13 +1040,13 @@ pcap_dump_open_append(pcap_t *p, const char *fname) - case SWAPLONG(NAVTEL_TCPDUMP_MAGIC): - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "%s: not a pcap file to which we can append", fname); -- fclose(f); -+ (void)fclose(f); - return (NULL); - - default: - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "%s: not a pcap file", fname); -- fclose(f); -+ (void)fclose(f); - return (NULL); - } - -@@ -1035,19 +1058,19 @@ pcap_dump_open_append(pcap_t *p, const char *fname) - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "%s: version is %u.%u, cannot append to file", fname, - ph.version_major, ph.version_minor); -- fclose(f); -+ (void)fclose(f); - return (NULL); - } - if ((bpf_u_int32)linktype != ph.linktype) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "%s: different linktype, cannot append to file", fname); -- fclose(f); -+ (void)fclose(f); - return (NULL); - } - if ((bpf_u_int32)p->snapshot != ph.snaplen) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "%s: different snaplen, cannot append to file", fname); -- fclose(f); -+ (void)fclose(f); - return (NULL); - } - } else { -@@ -1064,10 +1087,14 @@ pcap_dump_open_append(pcap_t *p, const char *fname) - - /* - * Start writing at the end of the file. -+ * -+ * XXX - this shouldn't be necessary, given that we're opening -+ * the file in append mode, and ISO C specifies that all writes -+ * are done at the end of the file in that mode. - */ - if (fseek(f, 0, SEEK_END) == -1) { - pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, -- errno, "Can't seek to end of %s", fname); -+ errno, "Can't seek to the end of %s", fname); - (void)fclose(f); - return (NULL); - } --- -1.8.3.1 - diff --git a/0079-Treat-both-ENXIO-and-EIO-as-device-went-away.patch b/0079-Treat-both-ENXIO-and-EIO-as-device-went-away.patch deleted file mode 100644 index 58523f7..0000000 --- a/0079-Treat-both-ENXIO-and-EIO-as-device-went-away.patch +++ /dev/null @@ -1,29 +0,0 @@ -From f22bd1264917671c87bb98e9c66c5734676f3150 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Sun, 30 Jun 2019 15:42:53 -0700 -Subject: [PATCH 79/83] Treat both ENXIO and EIO as "device went away". - -ENXIO is used on FreeBSD, DragonFly BSD, and Darwin; EIO is used on -OpenBSD. ---- - pcap-bpf.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/pcap-bpf.c b/pcap-bpf.c -index 6fe2eaf..62e2ed0 100644 ---- a/pcap-bpf.c -+++ b/pcap-bpf.c -@@ -1020,7 +1020,8 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) - case EWOULDBLOCK: - return (0); - -- case ENXIO: -+ case ENXIO: /* FreeBSD, DragonFly BSD, and Darwin */ -+ case EIO: /* OpenBSD */ - /* - * The device on which we're capturing - * went away. --- -1.8.3.1 - - diff --git a/0080-Change-the-error-message-for-ENXIO-EIO-to-match-real.patch b/0080-Change-the-error-message-for-ENXIO-EIO-to-match-real.patch deleted file mode 100644 index 27da597..0000000 --- a/0080-Change-the-error-message-for-ENXIO-EIO-to-match-real.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 8072538381d3f8f80c6ec643ce52a8355ac5fa65 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Sun, 30 Jun 2019 19:18:58 -0700 -Subject: [PATCH 80/83] Change the error message for ENXIO/EIO to match - reality. - -If an interface is configured down on one of the *BSDs or a Darwin-based -OS, capturing on that interface on a BPF device doesn't get an error; -ENXIO/EIO means "the interface went away completely" (e.g., unplugging a -hot-pluggable interface, shutting down a dynamically-created PPP link, -etc.). ---- - pcap-bpf.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/pcap-bpf.c b/pcap-bpf.c -index 62e2ed0..3f9e9ad 100644 ---- a/pcap-bpf.c -+++ b/pcap-bpf.c -@@ -1022,17 +1022,19 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) - - case ENXIO: /* FreeBSD, DragonFly BSD, and Darwin */ - case EIO: /* OpenBSD */ -+ /* NetBSD appears not to return an error in this case */ - /* - * The device on which we're capturing - * went away. - * - * XXX - we should really return -- * PCAP_ERROR_IFACE_NOT_UP, but -- * pcap_dispatch() etc. aren't -- * defined to retur that. -+ * an appropriate error for that, -+ * but pcap_dispatch() etc. aren't -+ * documented as having error returns -+ * other than PCAP_ERROR or PCAP_ERROR_BREAK. - */ - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, -- "The interface went down"); -+ "The interface disappeared"); - return (PCAP_ERROR); - - #if defined(sun) && !defined(BSD) && !defined(__svr4__) && !defined(__SVR4) --- -1.8.3.1 - - diff --git a/0194-Plug-some-memory-leaks.patch b/0194-Plug-some-memory-leaks.patch deleted file mode 100644 index 05fa39c..0000000 --- a/0194-Plug-some-memory-leaks.patch +++ /dev/null @@ -1,234 +0,0 @@ -From bcbef226ca11662342b5e267e7f12066bcfd60d0 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Wed, 17 Oct 2018 00:59:40 -0700 -Subject: [PATCH 194/470] Plug some memory leaks. - -For ARCNET and MAC addresses, don't convert them to binary until we get -to gen_acode() and gen_ecode(); instead, just save the string in a buffe -that's allocated in a way that gets cleaned up when the parser finishes, -the same way we do for some other string tokens. Otherwise, if the -parser fails before we get to free it, it gets leaked; that was -happening. - -Save the generated binary address in the parser state until we're done -with it, so that, if a call that uses the parser state calls -bpf_error(), the generated binary address gets freed. - -Credit to OSS-Fuzz for finding this issue. ---- - gencode.c | 53 ++++++++++++++++++++++++++++++++++++++++++----------- - gencode.h | 4 ++-- - grammar.y | 25 +++---------------------- - scanner.l | 10 ++-------- - 4 files changed, 49 insertions(+), 43 deletions(-) - -diff --git a/gencode.c b/gencode.c -index 1b20124..7aa9638 100644 ---- a/gencode.c -+++ b/gencode.c -@@ -279,6 +279,13 @@ struct _compiler_state { - struct addrinfo *ai; - - /* -+ * Another thing that's allocated is the result of pcap_ether_aton(); -+ * it must be freed with free(). This variable points to any -+ * address that would need to be freed. -+ */ -+ u_char *e; -+ -+ /* - * Various code constructs need to know the layout of the packet. - * These values give the necessary offsets from the beginning - * of the packet data. -@@ -710,6 +717,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program, - #ifdef INET6 - cstate.ai = NULL; - #endif -+ cstate.e = NULL; - cstate.ic.root = NULL; - cstate.ic.cur_mark = 0; - cstate.bpf_pcap = p; -@@ -720,6 +728,8 @@ pcap_compile(pcap_t *p, struct bpf_program *program, - if (cstate.ai != NULL) - freeaddrinfo(cstate.ai); - #endif -+ if (cstate.e != NULL) -+ free(cstate.e); - rc = -1; - goto quit; - } -@@ -6916,36 +6926,49 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2, - #endif /*INET6*/ - - struct block * --gen_ecode(compiler_state_t *cstate, const u_char *eaddr, struct qual q) -+gen_ecode(compiler_state_t *cstate, const char *s, struct qual q) - { - struct block *b, *tmp; - - if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { -+ cstate->e = pcap_ether_aton(s); -+ if (cstate->e == NULL) -+ bpf_error(cstate, "malloc"); - switch (cstate->linktype) { - case DLT_EN10MB: - case DLT_NETANALYZER: - case DLT_NETANALYZER_TRANSPARENT: - tmp = gen_prevlinkhdr_check(cstate); -- b = gen_ehostop(cstate, eaddr, (int)q.dir); -+ b = gen_ehostop(cstate, cstate->e, (int)q.dir); - if (tmp != NULL) - gen_and(tmp, b); -- return b; -+ break; - case DLT_FDDI: -- return gen_fhostop(cstate, eaddr, (int)q.dir); -+ b = gen_fhostop(cstate, cstate->e, (int)q.dir); -+ break; - case DLT_IEEE802: -- return gen_thostop(cstate, eaddr, (int)q.dir); -+ b = gen_thostop(cstate, cstate->e, (int)q.dir); -+ break; - case DLT_IEEE802_11: - case DLT_PRISM_HEADER: - case DLT_IEEE802_11_RADIO_AVS: - case DLT_IEEE802_11_RADIO: - case DLT_PPI: -- return gen_wlanhostop(cstate, eaddr, (int)q.dir); -+ b = gen_wlanhostop(cstate, cstate->e, (int)q.dir); -+ break; - case DLT_IP_OVER_FC: -- return gen_ipfchostop(cstate, eaddr, (int)q.dir); -+ b = gen_ipfchostop(cstate, cstate->e, (int)q.dir); -+ break; - default: -+ free(cstate->e); -+ cstate->e = NULL; - bpf_error(cstate, "ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel"); -+ /* NOTREACHED */ - break; - } -+ free(cstate->e); -+ cstate->e = NULL; -+ return (b); - } - bpf_error(cstate, "ethernet address used in non-ether expression"); - /* NOTREACHED */ -@@ -8127,16 +8150,24 @@ gen_p80211_fcdir(compiler_state_t *cstate, int fcdir) - } - - struct block * --gen_acode(compiler_state_t *cstate, const u_char *eaddr, struct qual q) -+gen_acode(compiler_state_t *cstate, const char *s, struct qual q) - { -+ struct block *b; -+ - switch (cstate->linktype) { - - case DLT_ARCNET: - case DLT_ARCNET_LINUX: - if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && -- q.proto == Q_LINK) -- return (gen_ahostop(cstate, eaddr, (int)q.dir)); -- else { -+ q.proto == Q_LINK) { -+ cstate->e = pcap_ether_aton(s); -+ if (cstate->e == NULL) -+ bpf_error(cstate, "malloc"); -+ b = gen_ahostop(cstate, cstate->e, (int)q.dir); -+ free(cstate->e); -+ cstate->e = NULL; -+ return (b); -+ } else { - bpf_error(cstate, "ARCnet address used in non-arc expression"); - /* NOTREACHED */ - } -diff --git a/gencode.h b/gencode.h -index 6a6fda5..e97e90f 100644 ---- a/gencode.h -+++ b/gencode.h -@@ -297,8 +297,8 @@ void gen_or(struct block *, struct block *); - void gen_not(struct block *); - - struct block *gen_scode(compiler_state_t *, const char *, struct qual); --struct block *gen_ecode(compiler_state_t *, const u_char *, struct qual); --struct block *gen_acode(compiler_state_t *, const u_char *, struct qual); -+struct block *gen_ecode(compiler_state_t *, const char *, struct qual); -+struct block *gen_acode(compiler_state_t *, const char *, struct qual); - struct block *gen_mcode(compiler_state_t *, const char *, const char *, - unsigned int, struct qual); - #ifdef INET6 -diff --git a/grammar.y b/grammar.y -index 62f9b5f..e3883b5 100644 ---- a/grammar.y -+++ b/grammar.y -@@ -307,7 +307,6 @@ DIAG_OFF_BISON_BYACC - %union { - int i; - bpf_u_int32 h; -- u_char *e; - char *s; - struct stmt *stmt; - struct arth *a; -@@ -363,9 +362,7 @@ DIAG_OFF_BISON_BYACC - %token SIO OPC DPC SLS HSIO HOPC HDPC HSLS - - --%type ID --%type EID --%type AID -+%type ID EID AID - %type HID HID6 - %type NUM action reason type subtype type_subtype dir - -@@ -437,24 +434,8 @@ nid: ID { $$.b = gen_scode(cstate, $1, $$.q = $0.q); } - "in this configuration"); - #endif /*INET6*/ - } -- | EID { -- $$.b = gen_ecode(cstate, $1, $$.q = $0.q); -- /* -- * $1 was allocated by "pcap_ether_aton()", -- * so we must free it now that we're done -- * with it. -- */ -- free($1); -- } -- | AID { -- $$.b = gen_acode(cstate, $1, $$.q = $0.q); -- /* -- * $1 was allocated by "pcap_ether_aton()", -- * so we must free it now that we're done -- * with it. -- */ -- free($1); -- } -+ | EID { $$.b = gen_ecode(cstate, $1, $$.q = $0.q); } -+ | AID { $$.b = gen_acode(cstate, $1, $$.q = $0.q); } - | not id { gen_not($2.b); $$ = $2; } - ; - not: '!' { $$ = $0; } -diff --git a/scanner.l b/scanner.l -index e0890b4..e9565aa 100644 ---- a/scanner.l -+++ b/scanner.l -@@ -397,14 +397,8 @@ hsls return HSLS; - "==" return '='; - "<<" return LSH; - ">>" return RSH; --${B} { yylval->e = pcap_ether_aton(((char *)yytext)+1); -- if (yylval->e == NULL) -- bpf_error(yyextra, "malloc"); -- return AID; } --{MAC} { yylval->e = pcap_ether_aton((char *)yytext); -- if (yylval->e == NULL) -- bpf_error(yyextra, "malloc"); -- return EID; } -+${B} { yylval->s = sdup(yyextra, yytext); return AID; } -+{MAC} { yylval->s = sdup(yyextra, yytext); return EID; } - {N} { yylval->i = stoi((char *)yytext); return NUM; } - ({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) { - yylval->s = sdup(yyextra, (char *)yytext); return HID; } --- -1.8.3.1 - diff --git a/0195-Plug-some-memory-leaks.patch b/0195-Plug-some-memory-leaks.patch deleted file mode 100644 index 2db130a..0000000 --- a/0195-Plug-some-memory-leaks.patch +++ /dev/null @@ -1,319 +0,0 @@ -From 947f2be1e0345bbd6f66f6c945ad51eb7f074e8a Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Wed, 17 Oct 2018 13:29:19 -0700 -Subject: [PATCH 195/470] Plug some memory leaks. - -The optimizer and code emitter (icode_to_fcode()) allocate their own -memory that must be cleaned up if an error is thrown, so we can't use -bpf_error(), we need to add our own error routines for them. - -In some cases, just free up the memory before calling bpf_error(). - -Credit to OSS-Fuzz for finding this issue. ---- - gencode.c | 25 +++++++++++++--- - gencode.h | 5 +++- - optimize.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------- - 3 files changed, 108 insertions(+), 21 deletions(-) - -diff --git a/gencode.c b/gencode.c -index 7aa9638..2b18a32 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 */ - } - -diff --git a/gencode.h b/gencode.h -index e97e90f..a819900 100644 ---- a/gencode.h -+++ b/gencode.h -@@ -384,8 +384,11 @@ struct icode { - int cur_mark; - }; - --void bpf_optimize(compiler_state_t *, struct icode *ic); -+void bpf_optimize(compiler_state_t *, struct icode *); - void PCAP_NORETURN bpf_syntax_error(compiler_state_t *, const char *); -+void bpf_vset_error(compiler_state_t *, const char *, va_list) -+ PCAP_PRINTFLIKE(2, 0); -+void PCAP_NORETURN bpf_abort_compilation(compiler_state_t *); - void PCAP_NORETURN bpf_error(compiler_state_t *, const char *, ...) - PCAP_PRINTFLIKE(2, 3); - -diff --git a/optimize.c b/optimize.c -index 0d2fcca..2258a3c 100644 ---- a/optimize.c -+++ b/optimize.c -@@ -323,6 +323,8 @@ typedef struct { - - static void opt_init(compiler_state_t *, opt_state_t *, struct icode *); - static void opt_cleanup(opt_state_t *); -+static void PCAP_NORETURN opt_error(compiler_state_t *, opt_state_t *, const char *, ...) -+ PCAP_PRINTFLIKE(3, 4); - - static void intern_blocks(opt_state_t *, struct icode *); - -@@ -722,13 +724,13 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state, - - case BPF_DIV: - if (b == 0) -- bpf_error(cstate, "division by zero"); -+ opt_error(cstate, opt_state, "division by zero"); - a /= b; - break; - - case BPF_MOD: - if (b == 0) -- bpf_error(cstate, "modulus by zero"); -+ opt_error(cstate, opt_state, "modulus by zero"); - a %= b; - break; - -@@ -1972,6 +1974,22 @@ opt_cleanup(opt_state_t *opt_state) - } - - /* -+ * Like bpf_error(), but also cleans up the optimizer state. -+ */ -+static void PCAP_NORETURN -+opt_error(compiler_state_t *cstate, opt_state_t *opt_state, const char *fmt, ...) -+{ -+ va_list ap; -+ -+ opt_cleanup(opt_state); -+ va_start(ap, fmt); -+ bpf_vset_error(cstate, fmt, ap); -+ va_end(ap); -+ bpf_abort_compilation(cstate); -+ /* NOTREACHED */ -+} -+ -+/* - * Return the number of stmts in 's'. - */ - static u_int -@@ -2075,15 +2093,20 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic) - - opt_state->n_edges = 2 * opt_state->n_blocks; - opt_state->edges = (struct edge **)calloc(opt_state->n_edges, sizeof(*opt_state->edges)); -- if (opt_state->edges == NULL) -+ if (opt_state->edges == NULL) { -+ free(opt_state->blocks); - bpf_error(cstate, "malloc"); -+ } - - /* - * The number of levels is bounded by the number of nodes. - */ - opt_state->levels = (struct block **)calloc(opt_state->n_blocks, sizeof(*opt_state->levels)); -- if (opt_state->levels == NULL) -+ if (opt_state->levels == NULL) { -+ free(opt_state->edges); -+ free(opt_state->blocks); - bpf_error(cstate, "malloc"); -+ } - - opt_state->edgewords = opt_state->n_edges / (8 * sizeof(bpf_u_int32)) + 1; - opt_state->nodewords = opt_state->n_blocks / (8 * sizeof(bpf_u_int32)) + 1; -@@ -2091,8 +2114,12 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic) - /* XXX */ - opt_state->space = (bpf_u_int32 *)malloc(2 * opt_state->n_blocks * opt_state->nodewords * sizeof(*opt_state->space) - + opt_state->n_edges * opt_state->edgewords * sizeof(*opt_state->space)); -- if (opt_state->space == NULL) -+ if (opt_state->space == NULL) { -+ free(opt_state->levels); -+ free(opt_state->edges); -+ free(opt_state->blocks); - bpf_error(cstate, "malloc"); -+ } - p = opt_state->space; - opt_state->all_dom_sets = p; - for (i = 0; i < n; ++i) { -@@ -2129,9 +2156,22 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic) - */ - opt_state->maxval = 3 * max_stmts; - opt_state->vmap = (struct vmapinfo *)calloc(opt_state->maxval, sizeof(*opt_state->vmap)); -+ if (opt_state->vmap == NULL) { -+ free(opt_state->space); -+ free(opt_state->levels); -+ free(opt_state->edges); -+ free(opt_state->blocks); -+ bpf_error(cstate, "malloc"); -+ } - opt_state->vnode_base = (struct valnode *)calloc(opt_state->maxval, sizeof(*opt_state->vnode_base)); -- if (opt_state->vmap == NULL || opt_state->vnode_base == NULL) -+ if (opt_state->vnode_base == NULL) { -+ free(opt_state->vmap); -+ free(opt_state->space); -+ free(opt_state->levels); -+ free(opt_state->edges); -+ free(opt_state->blocks); - bpf_error(cstate, "malloc"); -+ } - } - - /* -@@ -2143,6 +2183,9 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic) - int bids[NBIDS]; - #endif - -+static void PCAP_NORETURN conv_error(compiler_state_t *, conv_state_t *, const char *, ...) -+ PCAP_PRINTFLIKE(3, 4); -+ - /* - * Returns true if successful. Returns false if a branch has - * an offset that is too large. If so, we have marked that -@@ -2179,7 +2222,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state, - if (slen) { - offset = (struct slist **)calloc(slen, sizeof(struct slist *)); - if (!offset) { -- bpf_error(cstate, "not enough core"); -+ conv_error(cstate, conv_state, "not enough core"); - /*NOTREACHED*/ - } - } -@@ -2203,7 +2246,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state, - if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) { - #if 0 - if (src->s.jt || src->s.jf) { -- bpf_error(cstate, "illegal jmp destination"); -+ free(offset); -+ conv_error(cstate, conv_state, "illegal jmp destination"); - /*NOTREACHED*/ - } - #endif -@@ -2223,7 +2267,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state, - #endif - - if (!src->s.jt || !src->s.jf) { -- bpf_error(cstate, ljerr, "no jmp destination", off); -+ free(offset); -+ conv_error(cstate, conv_state, ljerr, "no jmp destination", off); - /*NOTREACHED*/ - } - -@@ -2231,12 +2276,14 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state, - for (i = 0; i < slen; i++) { - if (offset[i] == src->s.jt) { - if (jt) { -- bpf_error(cstate, ljerr, "multiple matches", off); -+ free(offset); -+ conv_error(cstate, conv_state, ljerr, "multiple matches", off); - /*NOTREACHED*/ - } - - if (i - off - 1 >= 256) { -- bpf_error(cstate, ljerr, "out-of-range jump", off); -+ free(offset); -+ conv_error(cstate, conv_state, ljerr, "out-of-range jump", off); - /*NOTREACHED*/ - } - dst->jt = (u_char)(i - off - 1); -@@ -2244,11 +2291,13 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state, - } - if (offset[i] == src->s.jf) { - if (jf) { -- bpf_error(cstate, ljerr, "multiple matches", off); -+ free(offset); -+ conv_error(cstate, conv_state, ljerr, "multiple matches", off); - /*NOTREACHED*/ - } - if (i - off - 1 >= 256) { -- bpf_error(cstate, ljerr, "out-of-range jump", off); -+ free(offset); -+ conv_error(cstate, conv_state, ljerr, "out-of-range jump", off); - /*NOTREACHED*/ - } - dst->jf = (u_char)(i - off - 1); -@@ -2256,7 +2305,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state, - } - } - if (!jt || !jf) { -- bpf_error(cstate, ljerr, "no destination found", off); -+ free(offset); -+ conv_error(cstate, conv_state, ljerr, "no destination found", off); - /*NOTREACHED*/ - } - } -@@ -2285,7 +2335,7 @@ filled: - } - /* branch if T to following jump */ - if (extrajmps >= 256) { -- bpf_error(cstate, "too many extra jumps"); -+ conv_error(cstate, conv_state, "too many extra jumps"); - /*NOTREACHED*/ - } - dst->jt = (u_char)extrajmps; -@@ -2306,7 +2356,7 @@ filled: - /* branch if F to following jump */ - /* if two jumps are inserted, F goes to second one */ - if (extrajmps >= 256) { -- bpf_error(cstate, "too many extra jumps"); -+ conv_error(cstate, conv_state, "too many extra jumps"); - /*NOTREACHED*/ - } - dst->jf = (u_char)extrajmps; -@@ -2372,6 +2422,23 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic, - } - - /* -+ * Like bpf_error(), but also frees the array into which we're putting -+ * the generated BPF code. -+ */ -+static void PCAP_NORETURN -+conv_error(compiler_state_t *cstate, conv_state_t *conv_state, const char *fmt, ...) -+{ -+ va_list ap; -+ -+ free(conv_state->fstart); -+ va_start(ap, fmt); -+ bpf_vset_error(cstate, fmt, ap); -+ va_end(ap); -+ bpf_abort_compilation(cstate); -+ /* NOTREACHED */ -+} -+ -+/* - * Make a copy of a BPF program and put it in the "fcode" member of - * a "pcap_t". - * --- -1.8.3.1 - diff --git a/0470-Plug-memory-leak.patch b/0470-Plug-memory-leak.patch deleted file mode 100644 index e7a13ae..0000000 --- a/0470-Plug-memory-leak.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 05d67a9f95ca3ed2c2ffaf8bb8e157a8e6194dc0 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Thu, 14 Feb 2019 13:16:02 -0800 -Subject: [PATCH 470/470] Plug memory leak. - -If the URL had "file" as the scheme, *and* if we couldn't allocate -memory for the path, we'd leak the memory we allocated for the scheme. - -Should address Coverity CID 1442632 (although Coverity misdiagnosed the -underlying problem). ---- - pcap.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/pcap.c b/pcap.c -index c134cd6..7336260 100644 ---- a/pcap.c -+++ b/pcap.c -@@ -1663,13 +1663,14 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop, - * the pathname. - */ - if (pcap_strcasecmp(scheme, "file") == 0) { -- *schemep = scheme; - *pathp = strdup(colonp + 3); - if (*pathp == NULL) { - pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, - errno, "malloc"); -+ free(scheme); - return (-1); - } -+ *schemep = scheme; - return (0); - } - --- -1.8.3.1 - diff --git a/Catch-another-place-where-we-divide-by-or-take-a-mod.patch b/Catch-another-place-where-we-divide-by-or-take-a-mod.patch deleted file mode 100644 index b968a67..0000000 --- a/Catch-another-place-where-we-divide-by-or-take-a-mod.patch +++ /dev/null @@ -1,51 +0,0 @@ -From a463e82f5f0152c3c0d7cf1ebfa56d9b099f7fee Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Thu, 18 Oct 2018 12:04:06 -0700 -Subject: [PATCH 196/470] Catch another place where we divide by or take a - modulus by zero. - -Credit to OSS-Fuzz for finding this issue. ---- - optimize.c | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - -diff --git a/optimize.c b/optimize.c -index 2258a3c..4c2a84c 100644 ---- a/optimize.c -+++ b/optimize.c -@@ -1144,9 +1144,17 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state, - op = BPF_OP(s->code); - if (alter) { - if (s->k == 0) { -- /* don't optimize away "sub #0" -+ /* -+ * Optimize operations where the constant -+ * is zero. -+ * -+ * Don't optimize away "sub #0" - * as it may be needed later to -- * fixup the generated math code */ -+ * fixup the generated math code. -+ * -+ * Fail if we're dividing by zero or taking -+ * a modulus by zero. -+ */ - if (op == BPF_ADD || - op == BPF_LSH || op == BPF_RSH || - op == BPF_OR || op == BPF_XOR) { -@@ -1158,6 +1166,12 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state, - val[A_ATOM] = K(s->k); - break; - } -+ if (op == BPF_DIV) -+ opt_error(cstate, opt_state, -+ "division by zero"); -+ if (op == BPF_MOD) -+ opt_error(cstate, opt_state, -+ "modulus by zero"); - } - if (opt_state->vmap[val[A_ATOM]].is_const) { - fold_op(cstate, opt_state, s, val[A_ATOM], K(s->k)); --- -1.8.3.1 - diff --git a/Don-t-overflow-an-int.patch b/Don-t-overflow-an-int.patch deleted file mode 100644 index 88acd8e..0000000 --- a/Don-t-overflow-an-int.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 6060056e819a5b5b1a222499fe8e4060eaff1934 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Mon, 15 Oct 2018 13:27:37 -0700 -Subject: [PATCH 182/470] Don't overflow an int. - ---- - sf-pcap.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/sf-pcap.c b/sf-pcap.c -index b493f4a..44a43d0 100644 ---- a/sf-pcap.c -+++ b/sf-pcap.c -@@ -43,6 +43,7 @@ - #include - #include - #include -+#include /* for INT_MAX */ - - #include "pcap-int.h" - -@@ -369,8 +370,14 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf, - * length will be misleading if you use it to figure - * out why a capture doesn't have all the packet data, - * but there's not much we can do to avoid that. -+ * -+ * But don't grow the snapshot length past the -+ * maximum value of an int. - */ -- p->snapshot += 14; -+ if (p->snapshot <= INT_MAX - 14) -+ p->snapshot += 14; -+ else -+ p->snapshot = INT_MAX; - } - } else - ps->hdrsize = sizeof(struct pcap_sf_pkthdr); --- -1.8.3.1 - diff --git a/Fix-leak-in-rpcap.patch b/Fix-leak-in-rpcap.patch deleted file mode 100644 index fe7da43..0000000 --- a/Fix-leak-in-rpcap.patch +++ /dev/null @@ -1,25 +0,0 @@ -From b3cedb07ac72ac03e552be437149244be12363b7 Mon Sep 17 00:00:00 2001 -From: Kevin Boulain -Date: Tue, 16 Oct 2018 15:46:46 +0000 -Subject: [PATCH 188/470] Fix leak in rpcap - ---- - pcap-rpcap.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/pcap-rpcap.c b/pcap-rpcap.c -index a62296d..8e7e1ad 100644 ---- a/pcap-rpcap.c -+++ b/pcap-rpcap.c -@@ -763,6 +763,8 @@ static void pcap_cleanup_rpcap(pcap_t *fp) - pr->currentfilter = NULL; - } - -+ pcap_cleanup_live_common(fp); -+ - /* To avoid inconsistencies in the number of sock_init() */ - sock_cleanup(); - } --- -1.8.3.1 - diff --git a/Fix-the-semantics-of-BPF_LSH-and-BPF_RSH-for-shifts-.patch b/Fix-the-semantics-of-BPF_LSH-and-BPF_RSH-for-shifts-.patch deleted file mode 100644 index 155226c..0000000 --- a/Fix-the-semantics-of-BPF_LSH-and-BPF_RSH-for-shifts-.patch +++ /dev/null @@ -1,48 +0,0 @@ -From db833b997d9d825a4bb0e78804d85552b38a562a Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Tue, 16 Oct 2018 23:23:10 -0700 -Subject: [PATCH 193/470] Fix the semantics of BPF_LSH and BPF_RSH for shifts - >= 32 bits. - -Some processors treat shifts greater than the width of the shifted -operand as setting the destination to 0, some others treat it as a shift -modulo the width. - -C says it's undefined, and most if not all implementations make it work -the way the target processor works. - -We treat it as setting the destination to 0, regardless of how the -processor on which we're running works. - -Credit to OSS-Fuzz for finding this issue. ---- - bpf_filter.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/bpf_filter.c b/bpf_filter.c -index e5c286b..b19b25d 100644 ---- a/bpf_filter.c -+++ b/bpf_filter.c -@@ -302,11 +302,17 @@ pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, - continue; - - case BPF_ALU|BPF_LSH|BPF_X: -- A <<= X; -+ if (X < 32) -+ A <<= X; -+ else -+ A = 0; - continue; - - case BPF_ALU|BPF_RSH|BPF_X: -- A >>= X; -+ if (X < 32) -+ A >>= X; -+ else -+ A = 0; - continue; - - case BPF_ALU|BPF_ADD|BPF_K: --- -1.8.3.1 - diff --git a/Fix-using-uninitialised-file-descriptor.patch b/Fix-using-uninitialised-file-descriptor.patch deleted file mode 100644 index 27dc791..0000000 --- a/Fix-using-uninitialised-file-descriptor.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 2a46edf29049ccf3dcfb7a2f2a2cdb6943a3e142 Mon Sep 17 00:00:00 2001 -From: Cedric Cellier -Date: Fri, 25 May 2018 15:46:39 +0200 -Subject: [PATCH 001/470] Fix using uninitialised file descriptor - -Too quick copy-pasta. ---- - pcap-rpcap.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/pcap-rpcap.c b/pcap-rpcap.c -index 65e235f..f14a220 100644 ---- a/pcap-rpcap.c -+++ b/pcap-rpcap.c -@@ -2276,7 +2276,7 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim - goto error; - - /* Discard the rest of the message, if there is any. */ -- if (rpcap_discard(pr->rmt_sockctrl, plen, errbuf) == -1) -+ if (rpcap_discard(sockctrl, plen, errbuf) == -1) - goto error_nodiscard; - - /* Set proper fields into the pcap_t struct */ -@@ -2314,7 +2314,7 @@ error: - * We already reported an error; if this gets an error, just - * drive on. - */ -- (void)rpcap_discard(pr->rmt_sockctrl, plen, NULL); -+ (void)rpcap_discard(sockctrl, plen, NULL); - - error_nodiscard: - if (!active) --- -1.8.3.1 - diff --git a/Make-qerr-const.patch b/Make-qerr-const.patch deleted file mode 100644 index 19820de..0000000 --- a/Make-qerr-const.patch +++ /dev/null @@ -1,28 +0,0 @@ -From cd512217e570f796ef3e3a7ad67c66d78c83c2dc Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Fri, 26 Oct 2018 13:02:59 -0700 -Subject: [PATCH 214/470] Make qerr const. - -It's not something we're allowed to modify, as that could fail if two or -more threads are all running in pcap_compile(); declare it as const to -make sure we don't modify it. ---- - grammar.y | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grammar.y b/grammar.y -index e060cde..3eeb135 100644 ---- a/grammar.y -+++ b/grammar.y -@@ -237,7 +237,7 @@ str2tok(const char *str, const struct tok *toks) - return (-1); - } - --static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; -+static const struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; - - static PCAP_NORETURN_DEF void - yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg) --- -1.8.3.1 - diff --git a/clean-up-signed-vs-unsigned-do-more-error-checking-in-the-parser.patch b/clean-up-signed-vs-unsigned-do-more-error-checking-in-the-parser.patch new file mode 100644 index 0000000..1586e9a --- /dev/null +++ b/clean-up-signed-vs-unsigned-do-more-error-checking-in-the-parser.patch @@ -0,0 +1,2975 @@ +From 72902568e6df7d410b0a9f09133601cdcf65d6a3 Mon Sep 17 00:00:00 2001 +From: Guy Harris +Date: Tue, 17 Dec 2019 22:12:55 +0800 + +From:https://github.com/the-tcpdump-group/libpcap/commit/81d760fecaec22d89d8cdad54d605ec8f25be143#diff-021c0dd9e9ed7100b9e31d8d95c930f2L2379 +--- + gencode.c | 697 ++++++++++++++++++++++++++--------------------------- + gencode.h | 32 +-- + grammar.y | 139 ++++++----- + optimize.c | 92 ++++--- + scanner.l | 237 +++++++++++------- + 5 files changed, 652 insertions(+), 545 deletions(-) + +diff --git a/gencode.c b/gencode.c +index e3425cd..07bec50 100644 +--- a/gencode.c ++++ b/gencode.c +@@ -248,6 +248,7 @@ struct chunk { + struct _compiler_state { + jmp_buf top_ctx; + pcap_t *bpf_pcap; ++ int error_set; + + struct icode ic; + +@@ -435,10 +436,22 @@ bpf_set_error(compiler_state_t *cstate, const char *fmt, ...) + { + va_list ap; + +- va_start(ap, fmt); +- (void)pcap_vsnprintf(cstate->bpf_pcap->errbuf, PCAP_ERRBUF_SIZE, +- fmt, ap); +- va_end(ap); ++ /* ++ * If we've already set an error, don't override it. ++ * The lexical analyzer reports some errors by setting ++ * the error and then returning a LEX_ERROR token, which ++ * is not recognized by any grammar rule, and thus forces ++ * the parse to stop. We don't want the error reported ++ * by the lexical analyzer to be overwritten by the syntax ++ * error. ++ */ ++ if (!cstate->error_set) { ++ va_start(ap, fmt); ++ (void)pcap_vsnprintf(cstate->bpf_pcap->errbuf, PCAP_ERRBUF_SIZE, ++ fmt, ap); ++ va_end(ap); ++ cstate->error_set = 1; ++ } + } + + /* +@@ -479,21 +492,21 @@ static inline void syntax(compiler_state_t *cstate); + static void backpatch(struct block *, struct block *); + static void merge(struct block *, struct block *); + static struct block *gen_cmp(compiler_state_t *, enum e_offrel, u_int, +- u_int, bpf_int32); ++ u_int, bpf_u_int32); + static struct block *gen_cmp_gt(compiler_state_t *, enum e_offrel, u_int, +- u_int, bpf_int32); ++ u_int, bpf_u_int32); + static struct block *gen_cmp_ge(compiler_state_t *, enum e_offrel, u_int, +- u_int, bpf_int32); ++ u_int, bpf_u_int32); + static struct block *gen_cmp_lt(compiler_state_t *, enum e_offrel, u_int, +- u_int, bpf_int32); ++ u_int, bpf_u_int32); + static struct block *gen_cmp_le(compiler_state_t *, enum e_offrel, u_int, +- u_int, bpf_int32); ++ u_int, bpf_u_int32); + static struct block *gen_mcmp(compiler_state_t *, enum e_offrel, u_int, +- u_int, bpf_int32, bpf_u_int32); ++ u_int, bpf_u_int32, bpf_u_int32); + static struct block *gen_bcmp(compiler_state_t *, enum e_offrel, u_int, + u_int, const u_char *); +-static struct block *gen_ncmp(compiler_state_t *, enum e_offrel, bpf_u_int32, +- bpf_u_int32, bpf_u_int32, bpf_u_int32, int, bpf_int32); ++static struct block *gen_ncmp(compiler_state_t *, enum e_offrel, u_int, ++ u_int, bpf_u_int32, int, int, bpf_u_int32); + static struct slist *gen_load_absoffsetrel(compiler_state_t *, bpf_abs_offset *, + u_int, u_int); + static struct slist *gen_load_a(compiler_state_t *, enum e_offrel, u_int, +@@ -502,9 +515,9 @@ static struct slist *gen_loadx_iphdrlen(compiler_state_t *); + static struct block *gen_uncond(compiler_state_t *, int); + static inline struct block *gen_true(compiler_state_t *); + static inline struct block *gen_false(compiler_state_t *); +-static struct block *gen_ether_linktype(compiler_state_t *, int); +-static struct block *gen_ipnet_linktype(compiler_state_t *, int); +-static struct block *gen_linux_sll_linktype(compiler_state_t *, int); ++static struct block *gen_ether_linktype(compiler_state_t *, bpf_u_int32); ++static struct block *gen_ipnet_linktype(compiler_state_t *, bpf_u_int32); ++static struct block *gen_linux_sll_linktype(compiler_state_t *, bpf_u_int32); + static struct slist *gen_load_prism_llprefixlen(compiler_state_t *); + static struct slist *gen_load_avs_llprefixlen(compiler_state_t *); + static struct slist *gen_load_radiotap_llprefixlen(compiler_state_t *); +@@ -512,15 +525,15 @@ static struct slist *gen_load_ppi_llprefixlen(compiler_state_t *); + static void insert_compute_vloffsets(compiler_state_t *, struct block *); + static struct slist *gen_abs_offset_varpart(compiler_state_t *, + bpf_abs_offset *); +-static int ethertype_to_ppptype(int); +-static struct block *gen_linktype(compiler_state_t *, int); ++static bpf_u_int32 ethertype_to_ppptype(bpf_u_int32); ++static struct block *gen_linktype(compiler_state_t *, bpf_u_int32); + static struct block *gen_snap(compiler_state_t *, bpf_u_int32, bpf_u_int32); +-static struct block *gen_llc_linktype(compiler_state_t *, int); ++static struct block *gen_llc_linktype(compiler_state_t *, bpf_u_int32); + static struct block *gen_hostop(compiler_state_t *, bpf_u_int32, bpf_u_int32, +- int, int, u_int, u_int); ++ int, bpf_u_int32, u_int, u_int); + #ifdef INET6 + static struct block *gen_hostop6(compiler_state_t *, struct in6_addr *, +- struct in6_addr *, int, int, u_int, u_int); ++ struct in6_addr *, int, bpf_u_int32, u_int, u_int); + #endif + static struct block *gen_ahostop(compiler_state_t *, const u_char *, int); + static struct block *gen_ehostop(compiler_state_t *, const u_char *, int); +@@ -529,7 +542,7 @@ static struct block *gen_thostop(compiler_state_t *, const u_char *, int); + static struct block *gen_wlanhostop(compiler_state_t *, const u_char *, int); + static struct block *gen_ipfchostop(compiler_state_t *, const u_char *, int); + static struct block *gen_dnhostop(compiler_state_t *, bpf_u_int32, int); +-static struct block *gen_mpls_linktype(compiler_state_t *, int); ++static struct block *gen_mpls_linktype(compiler_state_t *, bpf_u_int32); + static struct block *gen_host(compiler_state_t *, bpf_u_int32, bpf_u_int32, + int, int, int); + #ifdef INET6 +@@ -541,23 +554,25 @@ static struct block *gen_gateway(compiler_state_t *, const u_char *, + struct addrinfo *, int, int); + #endif + static struct block *gen_ipfrag(compiler_state_t *); +-static struct block *gen_portatom(compiler_state_t *, int, bpf_int32); +-static struct block *gen_portrangeatom(compiler_state_t *, int, bpf_int32, +- bpf_int32); +-static struct block *gen_portatom6(compiler_state_t *, int, bpf_int32); +-static struct block *gen_portrangeatom6(compiler_state_t *, int, bpf_int32, +- bpf_int32); +-struct block *gen_portop(compiler_state_t *, int, int, int); +-static struct block *gen_port(compiler_state_t *, int, int, int); +-struct block *gen_portrangeop(compiler_state_t *, int, int, int, int); +-static struct block *gen_portrange(compiler_state_t *, int, int, int, int); +-struct block *gen_portop6(compiler_state_t *, int, int, int); +-static struct block *gen_port6(compiler_state_t *, int, int, int); +-struct block *gen_portrangeop6(compiler_state_t *, int, int, int, int); +-static struct block *gen_portrange6(compiler_state_t *, int, int, int, int); ++static struct block *gen_portatom(compiler_state_t *, int, bpf_u_int32); ++static struct block *gen_portrangeatom(compiler_state_t *, u_int, bpf_u_int32, ++ bpf_u_int32); ++static struct block *gen_portatom6(compiler_state_t *, int, bpf_u_int32); ++static struct block *gen_portrangeatom6(compiler_state_t *, u_int, bpf_u_int32, ++ bpf_u_int32); ++static struct block *gen_portop(compiler_state_t *, u_int, u_int, int); ++static struct block *gen_port(compiler_state_t *, u_int, int, int); ++static struct block *gen_portrangeop(compiler_state_t *, u_int, u_int, ++ bpf_u_int32, int); ++static struct block *gen_portrange(compiler_state_t *, u_int, u_int, int, int); ++struct block *gen_portop6(compiler_state_t *, u_int, u_int, int); ++static struct block *gen_port6(compiler_state_t *, u_int, int, int); ++static struct block *gen_portrangeop6(compiler_state_t *, u_int, u_int, ++ bpf_u_int32, int); ++static struct block *gen_portrange6(compiler_state_t *, u_int, u_int, int, int); + static int lookup_proto(compiler_state_t *, const char *, int); +-static struct block *gen_protochain(compiler_state_t *, int, int, int); +-static struct block *gen_proto(compiler_state_t *, int, int, int); ++static struct block *gen_protochain(compiler_state_t *, bpf_u_int32, int); ++static struct block *gen_proto(compiler_state_t *, bpf_u_int32, int, int); + static struct slist *xfer_to_x(compiler_state_t *, struct arth *); + static struct slist *xfer_to_a(compiler_state_t *, struct arth *); + static struct block *gen_mac_multicast(compiler_state_t *, int); +@@ -567,7 +582,7 @@ static struct block *gen_geneve_ll_check(compiler_state_t *cstate); + + static struct block *gen_ppi_dlt_check(compiler_state_t *); + static struct block *gen_atmfield_code_internal(compiler_state_t *, int, +- bpf_int32, bpf_u_int32, int); ++ bpf_u_int32, int, int); + static struct block *gen_atmtype_llc(compiler_state_t *); + static struct block *gen_msg_abbrev(compiler_state_t *, int type); + +@@ -762,6 +777,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program, + cstate.ic.root = NULL; + cstate.ic.cur_mark = 0; + cstate.bpf_pcap = p; ++ cstate.error_set = 0; + init_regs(&cstate); + + cstate.netmask = mask; +@@ -1013,42 +1029,42 @@ gen_not(struct block *b) + + static struct block * + gen_cmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, +- u_int size, bpf_int32 v) ++ u_int size, bpf_u_int32 v) + { + return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JEQ, 0, v); + } + + static struct block * + gen_cmp_gt(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, +- u_int size, bpf_int32 v) ++ u_int size, bpf_u_int32 v) + { + return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JGT, 0, v); + } + + static struct block * + gen_cmp_ge(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, +- u_int size, bpf_int32 v) ++ u_int size, bpf_u_int32 v) + { + return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JGE, 0, v); + } + + static struct block * + gen_cmp_lt(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, +- u_int size, bpf_int32 v) ++ u_int size, bpf_u_int32 v) + { + return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JGE, 1, v); + } + + static struct block * + gen_cmp_le(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, +- u_int size, bpf_int32 v) ++ u_int size, bpf_u_int32 v) + { + return gen_ncmp(cstate, offrel, offset, size, 0xffffffff, BPF_JGT, 1, v); + } + + static struct block * + gen_mcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, +- u_int size, bpf_int32 v, bpf_u_int32 mask) ++ u_int size, bpf_u_int32 v, bpf_u_int32 mask) + { + return gen_ncmp(cstate, offrel, offset, size, mask, BPF_JEQ, 0, v); + } +@@ -1059,16 +1075,6 @@ gen_bcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, + { + register struct block *b, *tmp; + +- /* +- * XXX - the actual *instructions* do unsigned comparisons on +- * most platforms, and the load instructions don't do sign +- * extension, so gen_cmp() should really take an unsigned +- * value argument. +- * +- * As the load instructons also don't do sign-extension, we +- * fetch the values from the byte array as unsigned. We don't +- * want to use the signed versions of the extract calls. +- */ + b = NULL; + while (size >= 4) { + register const u_char *p = &v[size - 4]; +@@ -1091,7 +1097,7 @@ gen_bcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, + size -= 2; + } + if (size > 0) { +- tmp = gen_cmp(cstate, offrel, offset, BPF_B, (bpf_int32)v[0]); ++ tmp = gen_cmp(cstate, offrel, offset, BPF_B, v[0]); + if (b != NULL) + gen_and(b, tmp); + b = tmp; +@@ -1106,9 +1112,9 @@ gen_bcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, + * should test the opposite of "jtype". + */ + static struct block * +-gen_ncmp(compiler_state_t *cstate, enum e_offrel offrel, bpf_u_int32 offset, +- bpf_u_int32 size, bpf_u_int32 mask, bpf_u_int32 jtype, int reverse, +- bpf_int32 v) ++gen_ncmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset, ++ u_int size, bpf_u_int32 mask, int jtype, int reverse, ++ bpf_u_int32 v) + { + struct slist *s, *s2; + struct block *b; +@@ -1956,11 +1962,11 @@ gen_false(compiler_state_t *cstate) + * the appropriate test. + */ + static struct block * +-gen_ether_linktype(compiler_state_t *cstate, int proto) ++gen_ether_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto) + { + struct block *b0, *b1; + +- switch (proto) { ++ switch (ll_proto) { + + case LLCSAP_ISONS: + case LLCSAP_IP: +@@ -1979,8 +1985,7 @@ gen_ether_linktype(compiler_state_t *cstate, int proto) + */ + b0 = gen_cmp_gt(cstate, OR_LINKTYPE, 0, BPF_H, ETHERMTU); + gen_not(b0); +- b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_int32) +- ((proto << 8) | proto)); ++ b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (ll_proto << 8) | ll_proto); + gen_and(b0, b1); + return b1; + +@@ -2017,8 +2022,8 @@ gen_ether_linktype(compiler_state_t *cstate, int proto) + * This generates code to check both for the + * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3. + */ +- b0 = gen_cmp(cstate, OR_LLC, 0, BPF_B, (bpf_int32)LLCSAP_IPX); +- b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_int32)0xFFFF); ++ b0 = gen_cmp(cstate, OR_LLC, 0, BPF_B, LLCSAP_IPX); ++ b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, 0xFFFF); + gen_or(b0, b1); + + /* +@@ -2048,7 +2053,7 @@ gen_ether_linktype(compiler_state_t *cstate, int proto) + * do that before checking for the other frame + * types. + */ +- b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)ETHERTYPE_IPX); ++ b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ETHERTYPE_IPX); + gen_or(b0, b1); + return b1; + +@@ -2078,9 +2083,9 @@ gen_ether_linktype(compiler_state_t *cstate, int proto) + * 0x000000 (encapsulated Ethernet) and a protocol + * type of ETHERTYPE_AARP (Appletalk ARP). + */ +- if (proto == ETHERTYPE_ATALK) ++ if (ll_proto == ETHERTYPE_ATALK) + b1 = gen_snap(cstate, 0x080007, ETHERTYPE_ATALK); +- else /* proto == ETHERTYPE_AARP */ ++ else /* ll_proto == ETHERTYPE_AARP */ + b1 = gen_snap(cstate, 0x000000, ETHERTYPE_AARP); + gen_and(b0, b1); + +@@ -2089,13 +2094,13 @@ gen_ether_linktype(compiler_state_t *cstate, int proto) + * phase 1?); we just check for the Ethernet + * protocol type. + */ +- b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); ++ b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ll_proto); + + gen_or(b0, b1); + return b1; + + default: +- if (proto <= ETHERMTU) { ++ if (ll_proto <= ETHERMTU) { + /* + * This is an LLC SAP value, so the frames + * that match would be 802.2 frames. +@@ -2106,7 +2111,7 @@ gen_ether_linktype(compiler_state_t *cstate, int proto) + */ + b0 = gen_cmp_gt(cstate, OR_LINKTYPE, 0, BPF_H, ETHERMTU); + gen_not(b0); +- b1 = gen_cmp(cstate, OR_LINKTYPE, 2, BPF_B, (bpf_int32)proto); ++ b1 = gen_cmp(cstate, OR_LINKTYPE, 2, BPF_B, ll_proto); + gen_and(b0, b1); + return b1; + } else { +@@ -2115,18 +2120,17 @@ gen_ether_linktype(compiler_state_t *cstate, int proto) + * the length/type field with it (if + * the frame is an 802.2 frame, the length + * field will be <= ETHERMTU, and, as +- * "proto" is > ETHERMTU, this test ++ * "ll_proto" is > ETHERMTU, this test + * will fail and the frame won't match, + * which is what we want). + */ +- return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, +- (bpf_int32)proto); ++ return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ll_proto); + } + } + } + + static struct block * +-gen_loopback_linktype(compiler_state_t *cstate, int proto) ++gen_loopback_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto) + { + /* + * For DLT_NULL, the link-layer header is a 32-bit word +@@ -2154,10 +2158,10 @@ gen_loopback_linktype(compiler_state_t *cstate, int proto) + * code to compare against the result. + */ + if (cstate->bpf_pcap->rfile != NULL && cstate->bpf_pcap->swapped) +- proto = SWAPLONG(proto); +- proto = htonl(proto); ++ ll_proto = SWAPLONG(ll_proto); ++ ll_proto = htonl(ll_proto); + } +- return (gen_cmp(cstate, OR_LINKHDR, 0, BPF_W, (bpf_int32)proto)); ++ return (gen_cmp(cstate, OR_LINKHDR, 0, BPF_W, ll_proto)); + } + + /* +@@ -2165,17 +2169,16 @@ gen_loopback_linktype(compiler_state_t *cstate, int proto) + * or IPv6 then we have an error. + */ + static struct block * +-gen_ipnet_linktype(compiler_state_t *cstate, int proto) ++gen_ipnet_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto) + { +- switch (proto) { ++ switch (ll_proto) { + + case ETHERTYPE_IP: +- return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, (bpf_int32)IPH_AF_INET); ++ return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, IPH_AF_INET); + /*NOTREACHED*/ + + case ETHERTYPE_IPV6: +- return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, +- (bpf_int32)IPH_AF_INET6); ++ return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, IPH_AF_INET6); + /*NOTREACHED*/ + + default: +@@ -2188,17 +2191,17 @@ gen_ipnet_linktype(compiler_state_t *cstate, int proto) + /* + * Generate code to match a particular packet type. + * +- * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP ++ * "ll_proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP + * value, if <= ETHERMTU. We use that to determine whether to + * match the type field or to check the type field for the special + * LINUX_SLL_P_802_2 value and then do the appropriate test. + */ + static struct block * +-gen_linux_sll_linktype(compiler_state_t *cstate, int proto) ++gen_linux_sll_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto) + { + struct block *b0, *b1; + +- switch (proto) { ++ switch (ll_proto) { + + case LLCSAP_ISONS: + case LLCSAP_IP: +@@ -2216,8 +2219,7 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto) + * (i.e., other SAP values)? + */ + b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2); +- b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_int32) +- ((proto << 8) | proto)); ++ b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (ll_proto << 8) | ll_proto); + gen_and(b0, b1); + return b1; + +@@ -2247,7 +2249,7 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto) + * then put a check for LINUX_SLL_P_802_2 frames + * before it. + */ +- b0 = gen_cmp(cstate, OR_LLC, 0, BPF_B, (bpf_int32)LLCSAP_IPX); ++ b0 = gen_cmp(cstate, OR_LLC, 0, BPF_B, LLCSAP_IPX); + b1 = gen_snap(cstate, 0x000000, ETHERTYPE_IPX); + gen_or(b0, b1); + b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2); +@@ -2265,7 +2267,7 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto) + * do that before checking for the other frame + * types. + */ +- b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)ETHERTYPE_IPX); ++ b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ETHERTYPE_IPX); + gen_or(b0, b1); + return b1; + +@@ -2294,9 +2296,9 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto) + * 0x000000 (encapsulated Ethernet) and a protocol + * type of ETHERTYPE_AARP (Appletalk ARP). + */ +- if (proto == ETHERTYPE_ATALK) ++ if (ll_proto == ETHERTYPE_ATALK) + b1 = gen_snap(cstate, 0x080007, ETHERTYPE_ATALK); +- else /* proto == ETHERTYPE_AARP */ ++ else /* ll_proto == ETHERTYPE_AARP */ + b1 = gen_snap(cstate, 0x000000, ETHERTYPE_AARP); + gen_and(b0, b1); + +@@ -2305,13 +2307,13 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto) + * phase 1?); we just check for the Ethernet + * protocol type. + */ +- b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); ++ b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ll_proto); + + gen_or(b0, b1); + return b1; + + default: +- if (proto <= ETHERMTU) { ++ if (ll_proto <= ETHERMTU) { + /* + * This is an LLC SAP value, so the frames + * that match would be 802.2 frames. +@@ -2321,7 +2323,7 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto) + */ + b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, LINUX_SLL_P_802_2); + b1 = gen_cmp(cstate, OR_LINKHDR, cstate->off_linkpl.constant_part, BPF_B, +- (bpf_int32)proto); ++ ll_proto); + gen_and(b0, b1); + return b1; + } else { +@@ -2330,11 +2332,11 @@ gen_linux_sll_linktype(compiler_state_t *cstate, int proto) + * the length/type field with it (if + * the frame is an 802.2 frame, the length + * field will be <= ETHERMTU, and, as +- * "proto" is > ETHERMTU, this test ++ * "ll_proto" is > ETHERMTU, this test + * will fail and the frame won't match, + * which is what we want). + */ +- return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); ++ return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ll_proto); + } + } + } +@@ -3035,33 +3037,33 @@ gen_abs_offset_varpart(compiler_state_t *cstate, bpf_abs_offset *off) + /* + * Map an Ethernet type to the equivalent PPP type. + */ +-static int +-ethertype_to_ppptype(int proto) ++static bpf_u_int32 ++ethertype_to_ppptype(bpf_u_int32 ll_proto) + { +- switch (proto) { ++ switch (ll_proto) { + + case ETHERTYPE_IP: +- proto = PPP_IP; ++ ll_proto = PPP_IP; + break; + + case ETHERTYPE_IPV6: +- proto = PPP_IPV6; ++ ll_proto = PPP_IPV6; + break; + + case ETHERTYPE_DN: +- proto = PPP_DECNET; ++ ll_proto = PPP_DECNET; + break; + + case ETHERTYPE_ATALK: +- proto = PPP_APPLE; ++ ll_proto = PPP_APPLE; + break; + + case ETHERTYPE_NS: +- proto = PPP_NS; ++ ll_proto = PPP_NS; + break; + + case LLCSAP_ISONS: +- proto = PPP_OSI; ++ ll_proto = PPP_OSI; + break; + + case LLCSAP_8021D: +@@ -3070,14 +3072,14 @@ ethertype_to_ppptype(int proto) + * over PPP are Spanning Tree Protocol + * Bridging PDUs. + */ +- proto = PPP_BRPDU; ++ ll_proto = PPP_BRPDU; + break; + + case LLCSAP_IPX: +- proto = PPP_IPX; ++ ll_proto = PPP_IPX; + break; + } +- return (proto); ++ return (ll_proto); + } + + /* +@@ -3133,29 +3135,14 @@ gen_prevlinkhdr_check(compiler_state_t *cstate) + * value, if <= ETHERMTU. + */ + static struct block * +-gen_linktype(compiler_state_t *cstate, int proto) ++gen_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto) + { + struct block *b0, *b1, *b2; + const char *description; + + /* are we checking MPLS-encapsulated packets? */ +- if (cstate->label_stack_depth > 0) { +- switch (proto) { +- case ETHERTYPE_IP: +- case PPP_IP: +- /* FIXME add other L3 proto IDs */ +- return gen_mpls_linktype(cstate, Q_IP); +- +- case ETHERTYPE_IPV6: +- case PPP_IPV6: +- /* FIXME add other L3 proto IDs */ +- return gen_mpls_linktype(cstate, Q_IPV6); +- +- default: +- bpf_error(cstate, "unsupported protocol over mpls"); +- /*NOTREACHED*/ +- } +- } ++ if (cstate->label_stack_depth > 0) ++ return gen_mpls_linktype(cstate, ll_proto); + + switch (cstate->linktype) { + +@@ -3169,21 +3156,21 @@ gen_linktype(compiler_state_t *cstate, int proto) + else + b0 = NULL; + +- b1 = gen_ether_linktype(cstate, proto); ++ b1 = gen_ether_linktype(cstate, ll_proto); + if (b0 != NULL) + gen_and(b0, b1); + return b1; + /*NOTREACHED*/ + + case DLT_C_HDLC: +- switch (proto) { ++ switch (ll_proto) { + + case LLCSAP_ISONS: +- proto = (proto << 8 | LLCSAP_ISONS); ++ ll_proto = (ll_proto << 8 | LLCSAP_ISONS); + /* fall through */ + + default: +- return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); ++ return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ll_proto); + /*NOTREACHED*/ + } + +@@ -3200,7 +3187,7 @@ gen_linktype(compiler_state_t *cstate, int proto) + /* + * Now check for the specified link-layer type. + */ +- b1 = gen_llc_linktype(cstate, proto); ++ b1 = gen_llc_linktype(cstate, ll_proto); + gen_and(b0, b1); + return b1; + /*NOTREACHED*/ +@@ -3209,20 +3196,20 @@ gen_linktype(compiler_state_t *cstate, int proto) + /* + * XXX - check for LLC frames. + */ +- return gen_llc_linktype(cstate, proto); ++ return gen_llc_linktype(cstate, ll_proto); + /*NOTREACHED*/ + + case DLT_IEEE802: + /* + * XXX - check for LLC PDUs, as per IEEE 802.5. + */ +- return gen_llc_linktype(cstate, proto); ++ return gen_llc_linktype(cstate, ll_proto); + /*NOTREACHED*/ + + case DLT_ATM_RFC1483: + case DLT_ATM_CLIP: + case DLT_IP_OVER_FC: +- return gen_llc_linktype(cstate, proto); ++ return gen_llc_linktype(cstate, ll_proto); + /*NOTREACHED*/ + + case DLT_SUNATM: +@@ -3234,13 +3221,13 @@ gen_linktype(compiler_state_t *cstate, int proto) + * Check for LLC encapsulation and then check the protocol. + */ + b0 = gen_atmfield_code_internal(cstate, A_PROTOTYPE, PT_LLC, BPF_JEQ, 0); +- b1 = gen_llc_linktype(cstate, proto); ++ b1 = gen_llc_linktype(cstate, ll_proto); + gen_and(b0, b1); + return b1; + /*NOTREACHED*/ + + case DLT_LINUX_SLL: +- return gen_linux_sll_linktype(cstate, proto); ++ return gen_linux_sll_linktype(cstate, ll_proto); + /*NOTREACHED*/ + + case DLT_SLIP: +@@ -3253,7 +3240,7 @@ gen_linktype(compiler_state_t *cstate, int proto) + * XXX - for IPv4, check for a version number of 4, and, + * for IPv6, check for a version number of 6? + */ +- switch (proto) { ++ switch (ll_proto) { + + case ETHERTYPE_IP: + /* Check for a version number of 4. */ +@@ -3272,7 +3259,7 @@ gen_linktype(compiler_state_t *cstate, int proto) + /* + * Raw IPv4, so no type field. + */ +- if (proto == ETHERTYPE_IP) ++ if (ll_proto == ETHERTYPE_IP) + return gen_true(cstate); /* always true */ + + /* Checking for something other than IPv4; always false */ +@@ -3283,7 +3270,7 @@ gen_linktype(compiler_state_t *cstate, int proto) + /* + * Raw IPv6, so no type field. + */ +- if (proto == ETHERTYPE_IPV6) ++ if (ll_proto == ETHERTYPE_IPV6) + return gen_true(cstate); /* always true */ + + /* Checking for something other than IPv6; always false */ +@@ -3298,8 +3285,8 @@ gen_linktype(compiler_state_t *cstate, int proto) + * We use Ethernet protocol types inside libpcap; + * map them to the corresponding PPP protocol types. + */ +- proto = ethertype_to_ppptype(proto); +- return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); ++ return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ++ ethertype_to_ppptype(ll_proto)); + /*NOTREACHED*/ + + case DLT_PPP_BSDOS: +@@ -3307,7 +3294,7 @@ gen_linktype(compiler_state_t *cstate, int proto) + * We use Ethernet protocol types inside libpcap; + * map them to the corresponding PPP protocol types. + */ +- switch (proto) { ++ switch (ll_proto) { + + case ETHERTYPE_IP: + /* +@@ -3322,16 +3309,15 @@ gen_linktype(compiler_state_t *cstate, int proto) + return b0; + + default: +- proto = ethertype_to_ppptype(proto); + return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, +- (bpf_int32)proto); ++ ethertype_to_ppptype(ll_proto)); + } + /*NOTREACHED*/ + + case DLT_NULL: + case DLT_LOOP: + case DLT_ENC: +- switch (proto) { ++ switch (ll_proto) { + + case ETHERTYPE_IP: + return (gen_loopback_linktype(cstate, AF_INET)); +@@ -3412,12 +3398,12 @@ gen_linktype(compiler_state_t *cstate, int proto) + * af field is host byte order in contrast to the rest of + * the packet. + */ +- if (proto == ETHERTYPE_IP) ++ if (ll_proto == ETHERTYPE_IP) + return (gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, af), +- BPF_B, (bpf_int32)AF_INET)); +- else if (proto == ETHERTYPE_IPV6) ++ BPF_B, AF_INET)); ++ else if (ll_proto == ETHERTYPE_IPV6) + return (gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, af), +- BPF_B, (bpf_int32)AF_INET6)); ++ BPF_B, AF_INET6)); + else + return gen_false(cstate); + /*NOTREACHED*/ +@@ -3429,43 +3415,43 @@ gen_linktype(compiler_state_t *cstate, int proto) + * XXX should we check for first fragment if the protocol + * uses PHDS? + */ +- switch (proto) { ++ switch (ll_proto) { + + default: + return gen_false(cstate); + + case ETHERTYPE_IPV6: + return (gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, +- (bpf_int32)ARCTYPE_INET6)); ++ ARCTYPE_INET6)); + + case ETHERTYPE_IP: + b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, +- (bpf_int32)ARCTYPE_IP); ++ ARCTYPE_IP); + b1 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, +- (bpf_int32)ARCTYPE_IP_OLD); ++ ARCTYPE_IP_OLD); + gen_or(b0, b1); + return (b1); + + case ETHERTYPE_ARP: + b0 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, +- (bpf_int32)ARCTYPE_ARP); ++ ARCTYPE_ARP); + b1 = gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, +- (bpf_int32)ARCTYPE_ARP_OLD); ++ ARCTYPE_ARP_OLD); + gen_or(b0, b1); + return (b1); + + case ETHERTYPE_REVARP: + return (gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, +- (bpf_int32)ARCTYPE_REVARP)); ++ ARCTYPE_REVARP)); + + case ETHERTYPE_ATALK: + return (gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, +- (bpf_int32)ARCTYPE_ATALK)); ++ ARCTYPE_ATALK)); + } + /*NOTREACHED*/ + + case DLT_LTALK: +- switch (proto) { ++ switch (ll_proto) { + case ETHERTYPE_ATALK: + return gen_true(cstate); + default: +@@ -3478,7 +3464,7 @@ gen_linktype(compiler_state_t *cstate, int proto) + * XXX - assumes a 2-byte Frame Relay header with + * DLCI and flags. What if the address is longer? + */ +- switch (proto) { ++ switch (ll_proto) { + + case ETHERTYPE_IP: + /* +@@ -3555,7 +3541,7 @@ gen_linktype(compiler_state_t *cstate, int proto) + return gen_mcmp(cstate, OR_LINKHDR, 0, BPF_W, 0x55FF0000, 0xffff0000); + + case DLT_IPNET: +- return gen_ipnet_linktype(cstate, proto); ++ return gen_ipnet_linktype(cstate, ll_proto); + + case DLT_LINUX_IRDA: + bpf_error(cstate, "IrDA link-layer type filtering not implemented"); +@@ -3632,7 +3618,7 @@ gen_linktype(compiler_state_t *cstate, int proto) + * it's not, it needs to be handled specially + * above.) + */ +- return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto); ++ return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, ll_proto); + /*NOTREACHED */ + } else { + /* +@@ -3691,7 +3677,7 @@ gen_llc_internal(compiler_state_t *cstate) + * Now check for the purported DSAP and SSAP not being + * 0xFF, to rule out NetWare-over-802.3. + */ +- b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_int32)0xFFFF); ++ b1 = gen_cmp(cstate, OR_LLC, 0, BPF_H, 0xFFFF); + gen_not(b1); + gen_and(b0, b1); + return b1; +@@ -3903,12 +3889,12 @@ gen_llc_u_subtype(compiler_state_t *cstate, bpf_u_int32 subtype) + * protocol ID in a SNAP header. + */ + static struct block * +-gen_llc_linktype(compiler_state_t *cstate, int proto) ++gen_llc_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto) + { + /* + * XXX - handle token-ring variable-length header. + */ +- switch (proto) { ++ switch (ll_proto) { + + case LLCSAP_IP: + case LLCSAP_ISONS: +@@ -3919,15 +3905,14 @@ gen_llc_linktype(compiler_state_t *cstate, int proto) + * DSAP, as we do for other SAP values? + */ + return gen_cmp(cstate, OR_LLC, 0, BPF_H, (bpf_u_int32) +- ((proto << 8) | proto)); ++ ((ll_proto << 8) | ll_proto)); + + case LLCSAP_IPX: + /* + * XXX - are there ever SNAP frames for IPX on + * non-Ethernet 802.x networks? + */ +- return gen_cmp(cstate, OR_LLC, 0, BPF_B, +- (bpf_int32)LLCSAP_IPX); ++ return gen_cmp(cstate, OR_LLC, 0, BPF_B, LLCSAP_IPX); + + case ETHERTYPE_ATALK: + /* +@@ -3946,12 +3931,12 @@ gen_llc_linktype(compiler_state_t *cstate, int proto) + * XXX - we don't have to check for IPX 802.3 + * here, but should we check for the IPX Ethertype? + */ +- if (proto <= ETHERMTU) { ++ if (ll_proto <= ETHERMTU) { + /* + * This is an LLC SAP value, so check + * the DSAP. + */ +- return gen_cmp(cstate, OR_LLC, 0, BPF_B, (bpf_int32)proto); ++ return gen_cmp(cstate, OR_LLC, 0, BPF_B, ll_proto); + } else { + /* + * This is an Ethernet type; we assume that it's +@@ -3966,20 +3951,20 @@ gen_llc_linktype(compiler_state_t *cstate, int proto) + * organization code of 0x000000 (encapsulated + * Ethernet), we'd do + * +- * return gen_snap(cstate, 0x000000, proto); ++ * return gen_snap(cstate, 0x000000, ll_proto); + * + * here; for now, we don't, as per the above. + * I don't know whether it's worth the extra CPU + * time to do the right check or not. + */ +- return gen_cmp(cstate, OR_LLC, 6, BPF_H, (bpf_int32)proto); ++ return gen_cmp(cstate, OR_LLC, 6, BPF_H, ll_proto); + } + } + } + + static struct block * + gen_hostop(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask, +- int dir, int proto, u_int src_off, u_int dst_off) ++ int dir, bpf_u_int32 ll_proto, u_int src_off, u_int dst_off) + { + struct block *b0, *b1; + u_int offset; +@@ -3995,15 +3980,15 @@ gen_hostop(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask, + break; + + case Q_AND: +- b0 = gen_hostop(cstate, addr, mask, Q_SRC, proto, src_off, dst_off); +- b1 = gen_hostop(cstate, addr, mask, Q_DST, proto, src_off, dst_off); ++ b0 = gen_hostop(cstate, addr, mask, Q_SRC, ll_proto, src_off, dst_off); ++ b1 = gen_hostop(cstate, addr, mask, Q_DST, ll_proto, src_off, dst_off); + gen_and(b0, b1); + return b1; + + case Q_DEFAULT: + case Q_OR: +- b0 = gen_hostop(cstate, addr, mask, Q_SRC, proto, src_off, dst_off); +- b1 = gen_hostop(cstate, addr, mask, Q_DST, proto, src_off, dst_off); ++ b0 = gen_hostop(cstate, addr, mask, Q_SRC, ll_proto, src_off, dst_off); ++ b1 = gen_hostop(cstate, addr, mask, Q_DST, ll_proto, src_off, dst_off); + gen_or(b0, b1); + return b1; + +@@ -4035,8 +4020,8 @@ gen_hostop(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask, + abort(); + /*NOTREACHED*/ + } +- b0 = gen_linktype(cstate, proto); +- b1 = gen_mcmp(cstate, OR_LINKPL, offset, BPF_W, (bpf_int32)addr, mask); ++ b0 = gen_linktype(cstate, ll_proto); ++ b1 = gen_mcmp(cstate, OR_LINKPL, offset, BPF_W, addr, mask); + gen_and(b0, b1); + return b1; + } +@@ -4044,7 +4029,8 @@ gen_hostop(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask, + #ifdef INET6 + static struct block * + gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr, +- struct in6_addr *mask, int dir, int proto, u_int src_off, u_int dst_off) ++ struct in6_addr *mask, int dir, bpf_u_int32 ll_proto, u_int src_off, ++ u_int dst_off) + { + struct block *b0, *b1; + u_int offset; +@@ -4061,15 +4047,15 @@ gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr, + break; + + case Q_AND: +- b0 = gen_hostop6(cstate, addr, mask, Q_SRC, proto, src_off, dst_off); +- b1 = gen_hostop6(cstate, addr, mask, Q_DST, proto, src_off, dst_off); ++ b0 = gen_hostop6(cstate, addr, mask, Q_SRC, ll_proto, src_off, dst_off); ++ b1 = gen_hostop6(cstate, addr, mask, Q_DST, ll_proto, src_off, dst_off); + gen_and(b0, b1); + return b1; + + case Q_DEFAULT: + case Q_OR: +- b0 = gen_hostop6(cstate, addr, mask, Q_SRC, proto, src_off, dst_off); +- b1 = gen_hostop6(cstate, addr, mask, Q_DST, proto, src_off, dst_off); ++ b0 = gen_hostop6(cstate, addr, mask, Q_SRC, ll_proto, src_off, dst_off); ++ b1 = gen_hostop6(cstate, addr, mask, Q_DST, ll_proto, src_off, dst_off); + gen_or(b0, b1); + return b1; + +@@ -4111,7 +4097,7 @@ gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr, + gen_and(b0, b1); + b0 = gen_mcmp(cstate, OR_LINKPL, offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0])); + gen_and(b0, b1); +- b0 = gen_linktype(cstate, proto); ++ b0 = gen_linktype(cstate, ll_proto); + gen_and(b0, b1); + return b1; + } +@@ -4846,24 +4832,29 @@ gen_dnhostop(compiler_state_t *cstate, bpf_u_int32 addr, int dir) + b0 = gen_linktype(cstate, ETHERTYPE_DN); + /* Check for pad = 1, long header case */ + tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_H, +- (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF)); ++ (bpf_u_int32)ntohs(0x0681), (bpf_u_int32)ntohs(0x07FF)); + b1 = gen_cmp(cstate, OR_LINKPL, 2 + 1 + offset_lh, +- BPF_H, (bpf_int32)ntohs((u_short)addr)); ++ BPF_H, (bpf_u_int32)ntohs((u_short)addr)); + gen_and(tmp, b1); + /* Check for pad = 0, long header case */ +- tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7); +- b2 = gen_cmp(cstate, OR_LINKPL, 2 + offset_lh, BPF_H, (bpf_int32)ntohs((u_short)addr)); ++ tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_B, (bpf_u_int32)0x06, ++ (bpf_u_int32)0x7); ++ b2 = gen_cmp(cstate, OR_LINKPL, 2 + offset_lh, BPF_H, ++ (bpf_u_int32)ntohs((u_short)addr)); + gen_and(tmp, b2); + gen_or(b2, b1); + /* Check for pad = 1, short header case */ + tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_H, +- (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF)); +- b2 = gen_cmp(cstate, OR_LINKPL, 2 + 1 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr)); ++ (bpf_u_int32)ntohs(0x0281), (bpf_u_int32)ntohs(0x07FF)); ++ b2 = gen_cmp(cstate, OR_LINKPL, 2 + 1 + offset_sh, BPF_H, ++ (bpf_u_int32)ntohs((u_short)addr)); + gen_and(tmp, b2); + gen_or(b2, b1); + /* Check for pad = 0, short header case */ +- tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7); +- b2 = gen_cmp(cstate, OR_LINKPL, 2 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr)); ++ tmp = gen_mcmp(cstate, OR_LINKPL, 2, BPF_B, (bpf_u_int32)0x02, ++ (bpf_u_int32)0x7); ++ b2 = gen_cmp(cstate, OR_LINKPL, 2 + offset_sh, BPF_H, ++ (bpf_u_int32)ntohs((u_short)addr)); + gen_and(tmp, b2); + gen_or(b2, b1); + +@@ -4878,13 +4869,13 @@ gen_dnhostop(compiler_state_t *cstate, bpf_u_int32 addr, int dir) + * field in the IP header. + */ + static struct block * +-gen_mpls_linktype(compiler_state_t *cstate, int proto) ++gen_mpls_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto) + { + struct block *b0, *b1; + +- switch (proto) { ++ switch (ll_proto) { + +- case Q_IP: ++ case ETHERTYPE_IP: + /* match the bottom-of-stack bit */ + b0 = gen_mcmp(cstate, OR_LINKPL, (u_int)-2, BPF_B, 0x01, 0x01); + /* match the IPv4 version number */ +@@ -4892,7 +4883,7 @@ gen_mpls_linktype(compiler_state_t *cstate, int proto) + gen_and(b0, b1); + return b1; + +- case Q_IPV6: ++ case ETHERTYPE_IPV6: + /* match the bottom-of-stack bit */ + b0 = gen_mcmp(cstate, OR_LINKPL, (u_int)-2, BPF_B, 0x01, 0x01); + /* match the IPv4 version number */ +@@ -4900,8 +4891,10 @@ gen_mpls_linktype(compiler_state_t *cstate, int proto) + gen_and(b0, b1); + return b1; + +- default: +- abort(); ++ default: ++ /* FIXME add other L3 proto IDs */ ++ bpf_error(cstate, "unsupported protocol over mpls"); ++ /*NOTREACHED*/ + } + } + +@@ -5583,46 +5576,46 @@ gen_ipfrag(compiler_state_t *cstate) + * headers). + */ + static struct block * +-gen_portatom(compiler_state_t *cstate, int off, bpf_int32 v) ++gen_portatom(compiler_state_t *cstate, int off, bpf_u_int32 v) + { + return gen_cmp(cstate, OR_TRAN_IPV4, off, BPF_H, v); + } + + static struct block * +-gen_portatom6(compiler_state_t *cstate, int off, bpf_int32 v) ++gen_portatom6(compiler_state_t *cstate, int off, bpf_u_int32 v) + { + return gen_cmp(cstate, OR_TRAN_IPV6, off, BPF_H, v); + } + +-struct block * +-gen_portop(compiler_state_t *cstate, int port, int proto, int dir) ++static struct block * ++gen_portop(compiler_state_t *cstate, u_int port, u_int proto, int dir) + { + struct block *b0, *b1, *tmp; + + /* ip proto 'proto' and not a fragment other than the first fragment */ +- tmp = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, (bpf_int32)proto); ++ tmp = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, proto); + b0 = gen_ipfrag(cstate); + gen_and(tmp, b0); + + switch (dir) { + case Q_SRC: +- b1 = gen_portatom(cstate, 0, (bpf_int32)port); ++ b1 = gen_portatom(cstate, 0, port); + break; + + case Q_DST: +- b1 = gen_portatom(cstate, 2, (bpf_int32)port); ++ b1 = gen_portatom(cstate, 2, port); + break; + + case Q_AND: +- tmp = gen_portatom(cstate, 0, (bpf_int32)port); +- b1 = gen_portatom(cstate, 2, (bpf_int32)port); ++ tmp = gen_portatom(cstate, 0, port); ++ b1 = gen_portatom(cstate, 2, port); + gen_and(tmp, b1); + break; + + case Q_DEFAULT: + case Q_OR: +- tmp = gen_portatom(cstate, 0, (bpf_int32)port); +- b1 = gen_portatom(cstate, 2, (bpf_int32)port); ++ tmp = gen_portatom(cstate, 0, port); ++ b1 = gen_portatom(cstate, 2, port); + gen_or(tmp, b1); + break; + +@@ -5660,7 +5653,7 @@ gen_portop(compiler_state_t *cstate, int port, int proto, int dir) + } + + static struct block * +-gen_port(compiler_state_t *cstate, int port, int ip_proto, int dir) ++gen_port(compiler_state_t *cstate, u_int port, int ip_proto, int dir) + { + struct block *b0, *b1, *tmp; + +@@ -5687,7 +5680,7 @@ gen_port(compiler_state_t *cstate, int port, int ip_proto, int dir) + case IPPROTO_UDP: + case IPPROTO_TCP: + case IPPROTO_SCTP: +- b1 = gen_portop(cstate, port, ip_proto, dir); ++ b1 = gen_portop(cstate, port, (u_int)ip_proto, dir); + break; + + case PROTO_UNDEF: +@@ -5706,33 +5699,33 @@ gen_port(compiler_state_t *cstate, int port, int ip_proto, int dir) + } + + struct block * +-gen_portop6(compiler_state_t *cstate, int port, int proto, int dir) ++gen_portop6(compiler_state_t *cstate, u_int port, u_int proto, int dir) + { + struct block *b0, *b1, *tmp; + + /* ip6 proto 'proto' */ + /* XXX - catch the first fragment of a fragmented packet? */ +- b0 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, (bpf_int32)proto); ++ b0 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, proto); + + switch (dir) { + case Q_SRC: +- b1 = gen_portatom6(cstate, 0, (bpf_int32)port); ++ b1 = gen_portatom6(cstate, 0, port); + break; + + case Q_DST: +- b1 = gen_portatom6(cstate, 2, (bpf_int32)port); ++ b1 = gen_portatom6(cstate, 2, port); + break; + + case Q_AND: +- tmp = gen_portatom6(cstate, 0, (bpf_int32)port); +- b1 = gen_portatom6(cstate, 2, (bpf_int32)port); ++ tmp = gen_portatom6(cstate, 0, port); ++ b1 = gen_portatom6(cstate, 2, port); + gen_and(tmp, b1); + break; + + case Q_DEFAULT: + case Q_OR: +- tmp = gen_portatom6(cstate, 0, (bpf_int32)port); +- b1 = gen_portatom6(cstate, 2, (bpf_int32)port); ++ tmp = gen_portatom6(cstate, 0, port); ++ b1 = gen_portatom6(cstate, 2, port); + gen_or(tmp, b1); + break; + +@@ -5745,7 +5738,7 @@ gen_portop6(compiler_state_t *cstate, int port, int proto, int dir) + } + + static struct block * +-gen_port6(compiler_state_t *cstate, int port, int ip_proto, int dir) ++gen_port6(compiler_state_t *cstate, u_int port, int ip_proto, int dir) + { + struct block *b0, *b1, *tmp; + +@@ -5756,7 +5749,7 @@ gen_port6(compiler_state_t *cstate, int port, int ip_proto, int dir) + case IPPROTO_UDP: + case IPPROTO_TCP: + case IPPROTO_SCTP: +- b1 = gen_portop6(cstate, port, ip_proto, dir); ++ b1 = gen_portop6(cstate, port, (u_int)ip_proto, dir); + break; + + case PROTO_UNDEF: +@@ -5776,8 +5769,8 @@ gen_port6(compiler_state_t *cstate, int port, int ip_proto, int dir) + + /* gen_portrange code */ + static struct block * +-gen_portrangeatom(compiler_state_t *cstate, int off, bpf_int32 v1, +- bpf_int32 v2) ++gen_portrangeatom(compiler_state_t *cstate, u_int off, bpf_u_int32 v1, ++ bpf_u_int32 v2) + { + struct block *b1, *b2; + +@@ -5785,7 +5778,7 @@ gen_portrangeatom(compiler_state_t *cstate, int off, bpf_int32 v1, + /* + * Reverse the order of the ports, so v1 is the lower one. + */ +- bpf_int32 vtemp; ++ bpf_u_int32 vtemp; + + vtemp = v1; + v1 = v2; +@@ -5800,36 +5793,36 @@ gen_portrangeatom(compiler_state_t *cstate, int off, bpf_int32 v1, + return b2; + } + +-struct block * +-gen_portrangeop(compiler_state_t *cstate, int port1, int port2, int proto, +- int dir) ++static struct block * ++gen_portrangeop(compiler_state_t *cstate, u_int port1, u_int port2, ++ bpf_u_int32 proto, int dir) + { + struct block *b0, *b1, *tmp; + + /* ip proto 'proto' and not a fragment other than the first fragment */ +- tmp = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, (bpf_int32)proto); ++ tmp = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, proto); + b0 = gen_ipfrag(cstate); + gen_and(tmp, b0); + + switch (dir) { + case Q_SRC: +- b1 = gen_portrangeatom(cstate, 0, (bpf_int32)port1, (bpf_int32)port2); ++ b1 = gen_portrangeatom(cstate, 0, port1, port2); + break; + + case Q_DST: +- b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2); ++ b1 = gen_portrangeatom(cstate, 2, port1, port2); + break; + + case Q_AND: +- tmp = gen_portrangeatom(cstate, 0, (bpf_int32)port1, (bpf_int32)port2); +- b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2); ++ tmp = gen_portrangeatom(cstate, 0, port1, port2); ++ b1 = gen_portrangeatom(cstate, 2, port1, port2); + gen_and(tmp, b1); + break; + + case Q_DEFAULT: + case Q_OR: +- tmp = gen_portrangeatom(cstate, 0, (bpf_int32)port1, (bpf_int32)port2); +- b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2); ++ tmp = gen_portrangeatom(cstate, 0, port1, port2); ++ b1 = gen_portrangeatom(cstate, 2, port1, port2); + gen_or(tmp, b1); + break; + +@@ -5867,7 +5860,7 @@ gen_portrangeop(compiler_state_t *cstate, int port1, int port2, int proto, + } + + static struct block * +-gen_portrange(compiler_state_t *cstate, int port1, int port2, int ip_proto, ++gen_portrange(compiler_state_t *cstate, u_int port1, u_int port2, int ip_proto, + int dir) + { + struct block *b0, *b1, *tmp; +@@ -5879,7 +5872,8 @@ gen_portrange(compiler_state_t *cstate, int port1, int port2, int ip_proto, + case IPPROTO_UDP: + case IPPROTO_TCP: + case IPPROTO_SCTP: +- b1 = gen_portrangeop(cstate, port1, port2, ip_proto, dir); ++ b1 = gen_portrangeop(cstate, port1, port2, (bpf_u_int32)ip_proto, ++ dir); + break; + + case PROTO_UNDEF: +@@ -5898,8 +5892,8 @@ gen_portrange(compiler_state_t *cstate, int port1, int port2, int ip_proto, + } + + static struct block * +-gen_portrangeatom6(compiler_state_t *cstate, int off, bpf_int32 v1, +- bpf_int32 v2) ++gen_portrangeatom6(compiler_state_t *cstate, u_int off, bpf_u_int32 v1, ++ bpf_u_int32 v2) + { + struct block *b1, *b2; + +@@ -5907,7 +5901,7 @@ gen_portrangeatom6(compiler_state_t *cstate, int off, bpf_int32 v1, + /* + * Reverse the order of the ports, so v1 is the lower one. + */ +- bpf_int32 vtemp; ++ bpf_u_int32 vtemp; + + vtemp = v1; + v1 = v2; +@@ -5922,35 +5916,35 @@ gen_portrangeatom6(compiler_state_t *cstate, int off, bpf_int32 v1, + return b2; + } + +-struct block * +-gen_portrangeop6(compiler_state_t *cstate, int port1, int port2, int proto, +- int dir) ++static struct block * ++gen_portrangeop6(compiler_state_t *cstate, u_int port1, u_int port2, ++ bpf_u_int32 proto, int dir) + { + struct block *b0, *b1, *tmp; + + /* ip6 proto 'proto' */ + /* XXX - catch the first fragment of a fragmented packet? */ +- b0 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, (bpf_int32)proto); ++ b0 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, proto); + + switch (dir) { + case Q_SRC: +- b1 = gen_portrangeatom6(cstate, 0, (bpf_int32)port1, (bpf_int32)port2); ++ b1 = gen_portrangeatom6(cstate, 0, port1, port2); + break; + + case Q_DST: +- b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2); ++ b1 = gen_portrangeatom6(cstate, 2, port1, port2); + break; + + case Q_AND: +- tmp = gen_portrangeatom6(cstate, 0, (bpf_int32)port1, (bpf_int32)port2); +- b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2); ++ tmp = gen_portrangeatom6(cstate, 0, port1, port2); ++ b1 = gen_portrangeatom6(cstate, 2, port1, port2); + gen_and(tmp, b1); + break; + + case Q_DEFAULT: + case Q_OR: +- tmp = gen_portrangeatom6(cstate, 0, (bpf_int32)port1, (bpf_int32)port2); +- b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2); ++ tmp = gen_portrangeatom6(cstate, 0, port1, port2); ++ b1 = gen_portrangeatom6(cstate, 2, port1, port2); + gen_or(tmp, b1); + break; + +@@ -5963,7 +5957,7 @@ gen_portrangeop6(compiler_state_t *cstate, int port1, int port2, int proto, + } + + static struct block * +-gen_portrange6(compiler_state_t *cstate, int port1, int port2, int ip_proto, ++gen_portrange6(compiler_state_t *cstate, u_int port1, u_int port2, int ip_proto, + int dir) + { + struct block *b0, *b1, *tmp; +@@ -5975,7 +5969,8 @@ gen_portrange6(compiler_state_t *cstate, int port1, int port2, int ip_proto, + case IPPROTO_UDP: + case IPPROTO_TCP: + case IPPROTO_SCTP: +- b1 = gen_portrangeop6(cstate, port1, port2, ip_proto, dir); ++ b1 = gen_portrangeop6(cstate, port1, port2, (bpf_u_int32)ip_proto, ++ dir); + break; + + case PROTO_UNDEF: +@@ -6045,10 +6040,10 @@ gen_joinsp(struct stmt **s, int n) + #endif + + static struct block * +-gen_protochain(compiler_state_t *cstate, int v, int proto, int dir) ++gen_protochain(compiler_state_t *cstate, bpf_u_int32 v, int proto) + { + #ifdef NO_PROTOCHAIN +- return gen_proto(cstate, v, proto, dir); ++ return gen_proto(cstate, v, proto); + #else + struct block *b0, *b; + struct slist *s[100]; +@@ -6065,8 +6060,8 @@ gen_protochain(compiler_state_t *cstate, int v, int proto, int dir) + case Q_IPV6: + break; + case Q_DEFAULT: +- b0 = gen_protochain(cstate, v, Q_IP, dir); +- b = gen_protochain(cstate, v, Q_IPV6, dir); ++ b0 = gen_protochain(cstate, v, Q_IP); ++ b = gen_protochain(cstate, v, Q_IPV6); + gen_or(b0, b); + return b; + default: +@@ -6371,7 +6366,7 @@ gen_check_802_11_data_frame(compiler_state_t *cstate) + * against Q_IP and Q_IPV6. + */ + static struct block * +-gen_proto(compiler_state_t *cstate, int v, int proto, int dir) ++gen_proto(compiler_state_t *cstate, bpf_u_int32 v, int proto, int dir) + { + struct block *b0, *b1; + #ifndef CHASE_CHAIN +@@ -6409,7 +6404,7 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir) + */ + b0 = gen_linktype(cstate, ETHERTYPE_IP); + #ifndef CHASE_CHAIN +- b1 = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, (bpf_int32)v); ++ b1 = gen_cmp(cstate, OR_LINKPL, 9, BPF_B, v); + #else + b1 = gen_protochain(cstate, v, Q_IP); + #endif +@@ -6480,9 +6475,9 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir) + * header. + */ + b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, IPPROTO_FRAGMENT); +- b1 = gen_cmp(cstate, OR_LINKPL, 40, BPF_B, (bpf_int32)v); ++ b1 = gen_cmp(cstate, OR_LINKPL, 40, BPF_B, v); + gen_and(b2, b1); +- b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, (bpf_int32)v); ++ b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, v); + gen_or(b2, b1); + #else + b1 = gen_protochain(cstate, v, Q_IPV6); +@@ -6546,13 +6541,13 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir) + */ + b0 = gen_linktype(cstate, LLCSAP_ISONS<<8 | LLCSAP_ISONS); + /* OSI in C-HDLC is stuffed with a fudge byte */ +- b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 1, BPF_B, (long)v); ++ b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 1, BPF_B, v); + gen_and(b0, b1); + return b1; + + default: + b0 = gen_linktype(cstate, LLCSAP_ISONS); +- b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 0, BPF_B, (long)v); ++ b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 0, BPF_B, v); + gen_and(b0, b1); + return b1; + } +@@ -6567,7 +6562,7 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir) + * 4 is the offset of the PDU type relative to the IS-IS + * header. + */ +- b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 4, BPF_B, (long)v); ++ b1 = gen_cmp(cstate, OR_LINKPL_NOSNAP, 4, BPF_B, v); + gen_and(b0, b1); + return b1; + +@@ -6928,7 +6923,7 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q) + case Q_PROTOCHAIN: + real_proto = lookup_proto(cstate, name, proto); + if (real_proto >= 0) +- return gen_protochain(cstate, real_proto, proto, dir); ++ return gen_protochain(cstate, real_proto, proto); + else + bpf_error(cstate, "unknown protocol: %s", name); + +@@ -6942,7 +6937,7 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q) + + struct block * + gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2, +- unsigned int masklen, struct qual q) ++ bpf_u_int32 masklen, struct qual q) + { + register int nlen, mlen; + bpf_u_int32 n, m; +@@ -7062,8 +7057,8 @@ gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q) + + { + struct block *b; +- b = gen_port(cstate, (int)v, proto, dir); +- gen_or(gen_port6(cstate, (int)v, proto, dir), b); ++ b = gen_port(cstate, v, proto, dir); ++ gen_or(gen_port6(cstate, v, proto, dir), b); + return b; + } + +@@ -7084,8 +7079,8 @@ gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q) + + { + struct block *b; +- b = gen_portrange(cstate, (int)v, (int)v, proto, dir); +- gen_or(gen_portrange6(cstate, (int)v, (int)v, proto, dir), b); ++ b = gen_portrange(cstate, v, v, proto, dir); ++ gen_or(gen_portrange6(cstate, v, v, proto, dir), b); + return b; + } + +@@ -7094,10 +7089,10 @@ gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q) + /*NOTREACHED*/ + + case Q_PROTO: +- return gen_proto(cstate, (int)v, proto, dir); ++ return gen_proto(cstate, v, proto, dir); + + case Q_PROTOCHAIN: +- return gen_protochain(cstate, (int)v, proto, dir); ++ return gen_protochain(cstate, v, proto); + + case Q_UNDEF: + syntax(cstate); +@@ -7113,7 +7108,7 @@ gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q) + #ifdef INET6 + struct block * + gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2, +- unsigned int masklen, struct qual q) ++ bpf_u_int32 masklen, struct qual q) + { + struct addrinfo *res; + struct in6_addr *addr; +@@ -7271,8 +7266,10 @@ xfer_to_a(compiler_state_t *cstate, struct arth *a) + * for "index". + */ + static struct arth * +-gen_load_internal(compiler_state_t *cstate, int proto, struct arth *inst, int size) ++gen_load_internal(compiler_state_t *cstate, int proto, struct arth *inst, ++ bpf_u_int32 size) + { ++ int size_code; + struct slist *s, *tmp; + struct block *b; + int regno = alloc_reg(cstate); +@@ -7282,17 +7279,18 @@ gen_load_internal(compiler_state_t *cstate, int proto, struct arth *inst, int si + + default: + bpf_error(cstate, "data size must be 1, 2, or 4"); ++ /*NOTREACHED*/ + + case 1: +- size = BPF_B; ++ size_code = BPF_B; + break; + + case 2: +- size = BPF_H; ++ size_code = BPF_H; + break; + + case 4: +- size = BPF_W; ++ size_code = BPF_W; + break; + } + switch (proto) { +@@ -7319,7 +7317,7 @@ gen_load_internal(compiler_state_t *cstate, int proto, struct arth *inst, int si + /* + * Load the item at that offset. + */ +- tmp = new_stmt(cstate, BPF_LD|BPF_IND|size); ++ tmp = new_stmt(cstate, BPF_LD|BPF_IND|size_code); + sappend(s, tmp); + sappend(inst->s, s); + break; +@@ -7361,7 +7359,7 @@ gen_load_internal(compiler_state_t *cstate, int proto, struct arth *inst, int si + * variable-length; that header length is what we put + * into the X register and then added to the index). + */ +- tmp = new_stmt(cstate, BPF_LD|BPF_IND|size); ++ tmp = new_stmt(cstate, BPF_LD|BPF_IND|size_code); + tmp->s.k = cstate->off_linkhdr.constant_part; + sappend(s, tmp); + sappend(inst->s, s); +@@ -7408,7 +7406,7 @@ gen_load_internal(compiler_state_t *cstate, int proto, struct arth *inst, int si + * payload, and the constant part of the offset of the + * start of the link-layer payload. + */ +- tmp = new_stmt(cstate, BPF_LD|BPF_IND|size); ++ tmp = new_stmt(cstate, BPF_LD|BPF_IND|size_code); + tmp->s.k = cstate->off_linkpl.constant_part + cstate->off_nl; + sappend(s, tmp); + sappend(inst->s, s); +@@ -7465,7 +7463,7 @@ gen_load_internal(compiler_state_t *cstate, int proto, struct arth *inst, int si + sappend(s, xfer_to_a(cstate, inst)); + sappend(s, new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_X)); + sappend(s, new_stmt(cstate, BPF_MISC|BPF_TAX)); +- sappend(s, tmp = new_stmt(cstate, BPF_LD|BPF_IND|size)); ++ sappend(s, tmp = new_stmt(cstate, BPF_LD|BPF_IND|size_code)); + tmp->s.k = cstate->off_linkpl.constant_part + cstate->off_nl; + sappend(inst->s, s); + +@@ -7527,7 +7525,7 @@ gen_load_internal(compiler_state_t *cstate, int proto, struct arth *inst, int si + * payload, and the constant part of the offset of the + * start of the link-layer payload. + */ +- tmp = new_stmt(cstate, BPF_LD|BPF_IND|size); ++ tmp = new_stmt(cstate, BPF_LD|BPF_IND|size_code); + tmp->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + 40; + + sappend(s, tmp); +@@ -7544,7 +7542,8 @@ gen_load_internal(compiler_state_t *cstate, int proto, struct arth *inst, int si + } + + struct arth * +-gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size) ++gen_load(compiler_state_t *cstate, int proto, struct arth *inst, ++ bpf_u_int32 size) + { + /* + * Catch errors reported by us and routines below us, and return NULL +@@ -7640,7 +7639,7 @@ gen_loadlen(compiler_state_t *cstate) + } + + static struct arth * +-gen_loadi_internal(compiler_state_t *cstate, int val) ++gen_loadi_internal(compiler_state_t *cstate, bpf_u_int32 val) + { + struct arth *a; + struct slist *s; +@@ -7661,7 +7660,7 @@ gen_loadi_internal(compiler_state_t *cstate, int val) + } + + struct arth * +-gen_loadi(compiler_state_t *cstate, int val) ++gen_loadi(compiler_state_t *cstate, bpf_u_int32 val) + { + /* + * Catch errors reported by us and routines below us, and return NULL +@@ -7736,13 +7735,7 @@ gen_arth(compiler_state_t *cstate, int code, struct arth *a0_arg, + 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)) ++ if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k > 31) + bpf_error(cstate, "shift by more than 31 bits"); + } + s0 = xfer_to_x(cstate, a1); +@@ -7863,7 +7856,7 @@ gen_less(compiler_state_t *cstate, int n) + * would generate code appropriate to the radio header in question. + */ + struct block * +-gen_byteop(compiler_state_t *cstate, int op, int idx, int val) ++gen_byteop(compiler_state_t *cstate, int op, int idx, bpf_u_int32 val) + { + struct block *b; + struct slist *s; +@@ -7880,14 +7873,14 @@ gen_byteop(compiler_state_t *cstate, int op, int idx, int val) + abort(); + + case '=': +- return gen_cmp(cstate, OR_LINKHDR, (u_int)idx, BPF_B, (bpf_int32)val); ++ return gen_cmp(cstate, OR_LINKHDR, (u_int)idx, BPF_B, val); + + case '<': +- b = gen_cmp_lt(cstate, OR_LINKHDR, (u_int)idx, BPF_B, (bpf_int32)val); ++ b = gen_cmp_lt(cstate, OR_LINKHDR, (u_int)idx, BPF_B, val); + return b; + + case '>': +- b = gen_cmp_gt(cstate, OR_LINKHDR, (u_int)idx, BPF_B, (bpf_int32)val); ++ b = gen_cmp_gt(cstate, OR_LINKHDR, (u_int)idx, BPF_B, val); + return b; + + case '|': +@@ -7965,9 +7958,9 @@ gen_broadcast(compiler_state_t *cstate, int proto) + bpf_error(cstate, "netmask not known, so 'ip broadcast' not supported"); + b0 = gen_linktype(cstate, ETHERTYPE_IP); + hostmask = ~cstate->netmask; +- b1 = gen_mcmp(cstate, OR_LINKPL, 16, BPF_W, (bpf_int32)0, hostmask); ++ b1 = gen_mcmp(cstate, OR_LINKPL, 16, BPF_W, 0, hostmask); + b2 = gen_mcmp(cstate, OR_LINKPL, 16, BPF_W, +- (bpf_int32)(~0 & hostmask), hostmask); ++ ~0 & hostmask, hostmask); + gen_or(b1, b2); + gen_and(b0, b2); + return b2; +@@ -8164,13 +8157,13 @@ gen_multicast(compiler_state_t *cstate, int proto) + + case Q_IP: + b0 = gen_linktype(cstate, ETHERTYPE_IP); +- b1 = gen_cmp_ge(cstate, OR_LINKPL, 16, BPF_B, (bpf_int32)224); ++ b1 = gen_cmp_ge(cstate, OR_LINKPL, 16, BPF_B, 224); + gen_and(b0, b1); + return b1; + + case Q_IPV6: + b0 = gen_linktype(cstate, ETHERTYPE_IPV6); +- b1 = gen_cmp(cstate, OR_LINKPL, 24, BPF_B, (bpf_int32)255); ++ b1 = gen_cmp(cstate, OR_LINKPL, 24, BPF_B, 255); + gen_and(b0, b1); + return b1; + } +@@ -8241,7 +8234,7 @@ gen_inbound(compiler_state_t *cstate, int dir) + #ifdef HAVE_NET_PFVAR_H + case DLT_PFLOG: + b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, dir), BPF_B, +- (bpf_int32)((dir == 0) ? PF_IN : PF_OUT)); ++ ((dir == 0) ? PF_IN : PF_OUT)); + break; + #endif + +@@ -8414,7 +8407,7 @@ gen_pf_rnr(compiler_state_t *cstate, int rnr) + } + + b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, rulenr), BPF_W, +- (bpf_int32)rnr); ++ (bpf_u_int32)rnr); + return (b0); + } + +@@ -8437,7 +8430,7 @@ gen_pf_srnr(compiler_state_t *cstate, int srnr) + } + + b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, subrulenr), BPF_W, +- (bpf_int32)srnr); ++ (bpf_u_int32)srnr); + return (b0); + } + +@@ -8460,7 +8453,7 @@ gen_pf_reason(compiler_state_t *cstate, int reason) + } + + b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, reason), BPF_B, +- (bpf_int32)reason); ++ (bpf_u_int32)reason); + return (b0); + } + +@@ -8483,7 +8476,7 @@ gen_pf_action(compiler_state_t *cstate, int action) + } + + b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, action), BPF_B, +- (bpf_int32)action); ++ (bpf_u_int32)action); + return (b0); + } + #else /* !HAVE_NET_PFVAR_H */ +@@ -8574,7 +8567,7 @@ gen_pf_action(compiler_state_t *cstate, int action _U_) + + /* IEEE 802.11 wireless header */ + struct block * +-gen_p80211_type(compiler_state_t *cstate, int type, int mask) ++gen_p80211_type(compiler_state_t *cstate, bpf_u_int32 type, bpf_u_int32 mask) + { + struct block *b0; + +@@ -8591,8 +8584,7 @@ gen_p80211_type(compiler_state_t *cstate, int type, int mask) + case DLT_PRISM_HEADER: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: +- b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, (bpf_int32)type, +- (bpf_int32)mask); ++ b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, type, mask); + break; + + default: +@@ -8604,7 +8596,7 @@ gen_p80211_type(compiler_state_t *cstate, int type, int mask) + } + + struct block * +-gen_p80211_fcdir(compiler_state_t *cstate, int fcdir) ++gen_p80211_fcdir(compiler_state_t *cstate, bpf_u_int32 fcdir) + { + struct block *b0; + +@@ -8628,8 +8620,8 @@ gen_p80211_fcdir(compiler_state_t *cstate, int fcdir) + /*NOTREACHED*/ + } + +- b0 = gen_mcmp(cstate, OR_LINKHDR, 1, BPF_B, (bpf_int32)fcdir, +- (bpf_u_int32)IEEE80211_FC1_DIR_MASK); ++ b0 = gen_mcmp(cstate, OR_LINKHDR, 1, BPF_B, fcdir, ++ IEEE80211_FC1_DIR_MASK); + + return (b0); + } +@@ -8746,7 +8738,7 @@ gen_vlan_vid_test(compiler_state_t *cstate, bpf_u_int32 vlan_num) + bpf_error(cstate, "VLAN tag %u greater than maximum %u", + vlan_num, 0x0fff); + } +- return gen_mcmp(cstate, OR_LINKPL, 0, BPF_H, (bpf_int32)vlan_num, 0x0fff); ++ return gen_mcmp(cstate, OR_LINKPL, 0, BPF_H, vlan_num, 0x0fff); + } + + static struct block * +@@ -8776,7 +8768,8 @@ gen_vlan_no_bpf_extensions(compiler_state_t *cstate, bpf_u_int32 vlan_num, + #if defined(SKF_AD_VLAN_TAG_PRESENT) + /* add v to variable part of off */ + static void +-gen_vlan_vloffset_add(compiler_state_t *cstate, bpf_abs_offset *off, int v, struct slist *s) ++gen_vlan_vloffset_add(compiler_state_t *cstate, bpf_abs_offset *off, ++ bpf_u_int32 v, struct slist *s) + { + struct slist *s2; + +@@ -9062,7 +9055,7 @@ gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num_arg, + 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, ++ b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W, label_num, + 0xfffff000); /* only compare the first 20 bits */ + gen_and(b0, b1); + b0 = b1; +@@ -9102,7 +9095,7 @@ gen_pppoed(compiler_state_t *cstate) + return (NULL); + + /* check for PPPoE discovery */ +- return gen_linktype(cstate, (bpf_int32)ETHERTYPE_PPPOED); ++ return gen_linktype(cstate, ETHERTYPE_PPPOED); + } + + struct block * +@@ -9120,7 +9113,7 @@ gen_pppoes(compiler_state_t *cstate, bpf_u_int32 sess_num, int has_sess_num) + /* + * Test against the PPPoE session link-layer type. + */ +- b0 = gen_linktype(cstate, (bpf_int32)ETHERTYPE_PPPOES); ++ b0 = gen_linktype(cstate, ETHERTYPE_PPPOES); + + /* If a specific session is requested, check PPPoE session id */ + if (has_sess_num) { +@@ -9128,8 +9121,7 @@ gen_pppoes(compiler_state_t *cstate, bpf_u_int32 sess_num, int has_sess_num) + bpf_error(cstate, "PPPoE session number %u greater than maximum %u", + sess_num, 0x0000ffff); + } +- b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W, +- (bpf_int32)sess_num, 0x0000ffff); ++ b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W, sess_num, 0x0000ffff); + gen_and(b0, b1); + b0 = b1; + } +@@ -9169,7 +9161,7 @@ gen_pppoes(compiler_state_t *cstate, bpf_u_int32 sess_num, int has_sess_num) + * specified. Parameterized to handle both IPv4 and IPv6. */ + static struct block * + gen_geneve_check(compiler_state_t *cstate, +- struct block *(*gen_portfn)(compiler_state_t *, int, int, int), ++ struct block *(*gen_portfn)(compiler_state_t *, u_int, int, int), + enum e_offrel offrel, bpf_u_int32 vni, int has_vni) + { + struct block *b0, *b1; +@@ -9179,7 +9171,7 @@ gen_geneve_check(compiler_state_t *cstate, + /* Check that we are operating on version 0. Otherwise, we + * can't decode the rest of the fields. The version is 2 bits + * in the first byte of the Geneve header. */ +- b1 = gen_mcmp(cstate, offrel, 8, BPF_B, (bpf_int32)0, 0xc0); ++ b1 = gen_mcmp(cstate, offrel, 8, BPF_B, 0, 0xc0); + gen_and(b0, b1); + b0 = b1; + +@@ -9189,8 +9181,7 @@ gen_geneve_check(compiler_state_t *cstate, + vni, 0xffffff); + } + vni <<= 8; /* VNI is in the upper 3 bytes */ +- b1 = gen_mcmp(cstate, offrel, 12, BPF_W, (bpf_int32)vni, +- 0xffffff00); ++ b1 = gen_mcmp(cstate, offrel, 12, BPF_W, vni, 0xffffff00); + gen_and(b0, b1); + b0 = b1; + } +@@ -9473,7 +9464,7 @@ gen_geneve_ll_check(compiler_state_t *cstate) + + static struct block * + gen_atmfield_code_internal(compiler_state_t *cstate, int atmfield, +- bpf_int32 jvalue, bpf_u_int32 jtype, int reverse) ++ bpf_u_int32 jvalue, int jtype, int reverse) + { + struct block *b0; + +@@ -9484,8 +9475,8 @@ gen_atmfield_code_internal(compiler_state_t *cstate, int atmfield, + bpf_error(cstate, "'vpi' supported only on raw ATM"); + if (cstate->off_vpi == OFFSET_NOT_SET) + abort(); +- b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vpi, BPF_B, 0xffffffff, jtype, +- reverse, jvalue); ++ b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vpi, BPF_B, ++ 0xffffffffU, jtype, reverse, jvalue); + break; + + case A_VCI: +@@ -9493,22 +9484,22 @@ gen_atmfield_code_internal(compiler_state_t *cstate, int atmfield, + bpf_error(cstate, "'vci' supported only on raw ATM"); + if (cstate->off_vci == OFFSET_NOT_SET) + abort(); +- b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vci, BPF_H, 0xffffffff, jtype, +- reverse, jvalue); ++ b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vci, BPF_H, ++ 0xffffffffU, jtype, reverse, jvalue); + break; + + case A_PROTOTYPE: + if (cstate->off_proto == OFFSET_NOT_SET) + abort(); /* XXX - this isn't on FreeBSD */ +- b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B, 0x0f, jtype, +- reverse, jvalue); ++ b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B, ++ 0x0fU, jtype, reverse, jvalue); + break; + + case A_MSGTYPE: + if (cstate->off_payload == OFFSET_NOT_SET) + abort(); + b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_payload + MSG_TYPE_POS, BPF_B, +- 0xffffffff, jtype, reverse, jvalue); ++ 0xffffffffU, jtype, reverse, jvalue); + break; + + case A_CALLREFTYPE: +@@ -9516,8 +9507,8 @@ gen_atmfield_code_internal(compiler_state_t *cstate, int atmfield, + bpf_error(cstate, "'callref' supported only on raw ATM"); + if (cstate->off_proto == OFFSET_NOT_SET) + abort(); +- b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B, 0xffffffff, +- jtype, reverse, jvalue); ++ b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B, ++ 0xffffffffU, jtype, reverse, jvalue); + break; + + default: +@@ -9560,7 +9551,7 @@ gen_atmtype_llc(compiler_state_t *cstate) + + struct block * + gen_atmfield_code(compiler_state_t *cstate, int atmfield, +- bpf_int32 jvalue, bpf_u_int32 jtype, int reverse) ++ bpf_u_int32 jvalue, int jtype, int reverse) + { + /* + * Catch errors reported by us and routines below us, and return NULL +@@ -9700,7 +9691,8 @@ gen_mtp2type_abbrev(compiler_state_t *cstate, int type) + (cstate->linktype != DLT_MTP2_WITH_PHDR) ) + bpf_error(cstate, "'fisu' supported only on MTP2"); + /* gen_ncmp(cstate, offrel, offset, size, mask, jtype, reverse, value) */ +- b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B, 0x3f, BPF_JEQ, 0, 0); ++ b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B, ++ 0x3fU, BPF_JEQ, 0, 0U); + break; + + case M_LSSU: +@@ -9708,8 +9700,10 @@ gen_mtp2type_abbrev(compiler_state_t *cstate, int type) + (cstate->linktype != DLT_ERF) && + (cstate->linktype != DLT_MTP2_WITH_PHDR) ) + bpf_error(cstate, "'lssu' supported only on MTP2"); +- b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B, 0x3f, BPF_JGT, 1, 2); +- b1 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B, 0x3f, BPF_JGT, 0, 0); ++ b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B, ++ 0x3fU, BPF_JGT, 1, 2U); ++ b1 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B, ++ 0x3fU, BPF_JGT, 0, 0U); + gen_and(b1, b0); + break; + +@@ -9718,7 +9712,8 @@ gen_mtp2type_abbrev(compiler_state_t *cstate, int type) + (cstate->linktype != DLT_ERF) && + (cstate->linktype != DLT_MTP2_WITH_PHDR) ) + bpf_error(cstate, "'msu' supported only on MTP2"); +- b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B, 0x3f, BPF_JGT, 0, 2); ++ b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li, BPF_B, ++ 0x3fU, BPF_JGT, 0, 2U); + break; + + case MH_FISU: +@@ -9727,7 +9722,8 @@ gen_mtp2type_abbrev(compiler_state_t *cstate, int type) + (cstate->linktype != DLT_MTP2_WITH_PHDR) ) + bpf_error(cstate, "'hfisu' supported only on MTP2_HSL"); + /* gen_ncmp(cstate, offrel, offset, size, mask, jtype, reverse, value) */ +- b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H, 0xff80, BPF_JEQ, 0, 0); ++ b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H, ++ 0xff80U, BPF_JEQ, 0, 0U); + break; + + case MH_LSSU: +@@ -9735,8 +9731,10 @@ gen_mtp2type_abbrev(compiler_state_t *cstate, int type) + (cstate->linktype != DLT_ERF) && + (cstate->linktype != DLT_MTP2_WITH_PHDR) ) + bpf_error(cstate, "'hlssu' supported only on MTP2_HSL"); +- b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H, 0xff80, BPF_JGT, 1, 0x0100); +- b1 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0); ++ b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H, ++ 0xff80U, BPF_JGT, 1, 0x0100U); ++ b1 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H, ++ 0xff80U, BPF_JGT, 0, 0U); + gen_and(b1, b0); + break; + +@@ -9745,7 +9743,8 @@ gen_mtp2type_abbrev(compiler_state_t *cstate, int type) + (cstate->linktype != DLT_ERF) && + (cstate->linktype != DLT_MTP2_WITH_PHDR) ) + bpf_error(cstate, "'hmsu' supported only on MTP2_HSL"); +- b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0x0100); ++ b0 = gen_ncmp(cstate, OR_PACKET, cstate->off_li_hsl, BPF_H, ++ 0xff80U, BPF_JGT, 0, 0x0100U); + break; + + default: +@@ -9761,7 +9760,7 @@ gen_mtp2type_abbrev(compiler_state_t *cstate, int type) + */ + struct block * + gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, +- bpf_u_int32 jvalue_arg, bpf_u_int32 jtype, int reverse) ++ bpf_u_int32 jvalue_arg, int jtype, int reverse) + { + volatile bpf_u_int32 jvalue = jvalue_arg; + struct block *b0; +@@ -9795,15 +9794,15 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, + if(jvalue > 255) + bpf_error(cstate, "sio value %u too big; max value = 255", + jvalue); +- b0 = gen_ncmp(cstate, OR_PACKET, newoff_sio, BPF_B, 0xffffffff, +- (u_int)jtype, reverse, (u_int)jvalue); ++ b0 = gen_ncmp(cstate, OR_PACKET, newoff_sio, BPF_B, 0xffffffffU, ++ jtype, reverse, jvalue); + break; + + case MH_OPC: + newoff_opc += 3; + + /* FALLTHROUGH */ +- case M_OPC: ++ case M_OPC: + if (cstate->off_opc == OFFSET_NOT_SET) + bpf_error(cstate, "'opc' supported only on SS7"); + /* opc coded on 14 bits so max value 16383 */ +@@ -9819,8 +9818,8 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, + val3 = jvalue & 0x00000003; + val3 = val3 <<22; + jvalue = val1 + val2 + val3; +- b0 = gen_ncmp(cstate, OR_PACKET, newoff_opc, BPF_W, 0x00c0ff0f, +- (u_int)jtype, reverse, (u_int)jvalue); ++ b0 = gen_ncmp(cstate, OR_PACKET, newoff_opc, BPF_W, 0x00c0ff0fU, ++ jtype, reverse, jvalue); + break; + + case MH_DPC: +@@ -9841,8 +9840,8 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, + val2 = jvalue & 0x00003f00; + val2 = val2 << 8; + jvalue = val1 + val2; +- b0 = gen_ncmp(cstate, OR_PACKET, newoff_dpc, BPF_W, 0xff3f0000, +- (u_int)jtype, reverse, (u_int)jvalue); ++ b0 = gen_ncmp(cstate, OR_PACKET, newoff_dpc, BPF_W, 0xff3f0000U, ++ jtype, reverse, jvalue); + break; + + case MH_SLS: +@@ -9859,8 +9858,8 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, + /* the following instruction is made to convert jvalue + * to the forme used to write sls in an ss7 message*/ + jvalue = jvalue << 4; +- b0 = gen_ncmp(cstate, OR_PACKET, newoff_sls, BPF_B, 0xf0, +- (u_int)jtype,reverse, (u_int)jvalue); ++ b0 = gen_ncmp(cstate, OR_PACKET, newoff_sls, BPF_B, 0xf0U, ++ jtype, reverse, jvalue); + break; + + default: +diff --git a/gencode.h b/gencode.h +index cc21e04..ef88ea1 100644 +--- a/gencode.h ++++ b/gencode.h +@@ -204,7 +204,7 @@ struct stmt { + int code; + struct slist *jt; /*only for relative jump in block*/ + struct slist *jf; /*only for relative jump in block*/ +- bpf_int32 k; ++ bpf_u_int32 k; + }; + + struct slist { +@@ -261,7 +261,7 @@ struct block { + atomset in_use; + atomset out_use; + int oval; +- int val[N_ATOMS]; ++ bpf_u_int32 val[N_ATOMS]; + }; + + /* +@@ -286,8 +286,8 @@ struct _compiler_state; + + typedef struct _compiler_state compiler_state_t; + +-struct arth *gen_loadi(compiler_state_t *, int); +-struct arth *gen_load(compiler_state_t *, int, struct arth *, int); ++struct arth *gen_loadi(compiler_state_t *, bpf_u_int32); ++struct arth *gen_load(compiler_state_t *, int, struct arth *, bpf_u_int32); + struct arth *gen_loadlen(compiler_state_t *); + struct arth *gen_neg(compiler_state_t *, struct arth *); + struct arth *gen_arth(compiler_state_t *, int, struct arth *, struct arth *); +@@ -300,10 +300,10 @@ struct block *gen_scode(compiler_state_t *, const char *, struct qual); + struct block *gen_ecode(compiler_state_t *, const char *, struct qual); + struct block *gen_acode(compiler_state_t *, const char *, struct qual); + struct block *gen_mcode(compiler_state_t *, const char *, const char *, +- unsigned int, struct qual); ++ bpf_u_int32, struct qual); + #ifdef INET6 + struct block *gen_mcode6(compiler_state_t *, const char *, const char *, +- unsigned int, struct qual); ++ bpf_u_int32, struct qual); + #endif + struct block *gen_ncode(compiler_state_t *, const char *, bpf_u_int32, + struct qual); +@@ -312,7 +312,7 @@ struct block *gen_relation(compiler_state_t *, int, struct arth *, + struct arth *, int); + struct block *gen_less(compiler_state_t *, int); + struct block *gen_greater(compiler_state_t *, int); +-struct block *gen_byteop(compiler_state_t *, int, int, int); ++struct block *gen_byteop(compiler_state_t *, int, int, bpf_u_int32); + struct block *gen_broadcast(compiler_state_t *, int); + struct block *gen_multicast(compiler_state_t *, int); + struct block *gen_inbound(compiler_state_t *, int); +@@ -332,14 +332,14 @@ struct block *gen_pppoes(compiler_state_t *, bpf_u_int32, int); + + struct block *gen_geneve(compiler_state_t *, bpf_u_int32, int); + +-struct block *gen_atmfield_code(compiler_state_t *, int, bpf_int32, +- bpf_u_int32, int); +-struct block *gen_atmtype_abbrev(compiler_state_t *, int type); +-struct block *gen_atmmulti_abbrev(compiler_state_t *, int type); ++struct block *gen_atmfield_code(compiler_state_t *, int, bpf_u_int32, ++ int, int); ++struct block *gen_atmtype_abbrev(compiler_state_t *, int); ++struct block *gen_atmmulti_abbrev(compiler_state_t *, int); + +-struct block *gen_mtp2type_abbrev(compiler_state_t *, int type); ++struct block *gen_mtp2type_abbrev(compiler_state_t *, int); + struct block *gen_mtp3field_code(compiler_state_t *, int, bpf_u_int32, +- bpf_u_int32, int); ++ int, int); + + struct block *gen_pf_ifname(compiler_state_t *, const char *); + struct block *gen_pf_rnr(compiler_state_t *, int); +@@ -348,8 +348,8 @@ struct block *gen_pf_ruleset(compiler_state_t *, char *); + struct block *gen_pf_reason(compiler_state_t *, int); + struct block *gen_pf_action(compiler_state_t *, int); + +-struct block *gen_p80211_type(compiler_state_t *, int, int); +-struct block *gen_p80211_fcdir(compiler_state_t *, int); ++struct block *gen_p80211_type(compiler_state_t *, bpf_u_int32, bpf_u_int32); ++struct block *gen_p80211_fcdir(compiler_state_t *, bpf_u_int32); + + /* + * Representation of a program as a tree of blocks, plus current mark. +@@ -385,4 +385,4 @@ int pcap_parse(void *, compiler_state_t *); + + /* XXX */ + #define JT(b) ((b)->et.succ) +-#define JF(b) ((b)->ef.succ) ++#define JF(b) ((b)->ef.succ) +\ No newline at end of file +diff --git a/grammar.y b/grammar.y +index 32cb19c..eadc8c8 100644 +--- a/grammar.y ++++ b/grammar.y +@@ -210,8 +210,17 @@ str2tok(const char *str, const struct tok *toks) + int i; + + for (i = 0; toks[i].s != NULL; i++) { +- if (pcap_strcasecmp(toks[i].s, str) == 0) ++ if (pcap_strcasecmp(toks[i].s, str) == 0) { ++ /* ++ * Just in case somebody is using this to ++ * generate values of -1/0xFFFFFFFF. ++ * That won't work, as it's indistinguishable ++ * from an error. ++ */ ++ if (toks[i].v == -1) ++ abort(); + return (toks[i].v); ++ } + } + return (-1); + } +@@ -235,7 +244,7 @@ pfreason_to_num(compiler_state_t *cstate, const char *reason) + if (pcap_strcasecmp(reason, reasons[i]) == 0) + return (i); + } +- bpf_set_error(cstate, "unknown PF reason"); ++ bpf_set_error(cstate, "unknown PF reason \"%s\"", reason); + return (-1); + } + +@@ -259,7 +268,7 @@ pfaction_to_num(compiler_state_t *cstate, const char *action) + return (PF_NORDR); + #endif + else { +- bpf_set_error(cstate, "unknown PF action"); ++ bpf_set_error(cstate, "unknown PF action \"%s\"", action); + return (-1); + } + } +@@ -307,7 +316,8 @@ DIAG_OFF_BISON_BYACC + %type head + %type pqual dqual aqual ndaqual + %type arth narth +-%type byteop pname pnum relop irelop ++%type byteop pname relop irelop ++%type pnum + %type and or paren not null prog + %type other pfvar p80211 pllc + %type atmtype atmmultitype +@@ -348,7 +358,8 @@ DIAG_OFF_BISON_BYACC + + %type ID EID AID + %type HID HID6 +-%type NUM action reason type subtype type_subtype dir ++%type NUM ++%type action reason type subtype type_subtype dir + + %left OR AND + %nonassoc '!' +@@ -378,7 +389,7 @@ and: AND { $$ = $0; } + or: OR { $$ = $0; } + ; + id: nid +- | pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1, ++ | pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, $1, + $$.q = $0.q))); } + | paren pid ')' { $$ = $2; } + ; +@@ -392,17 +403,17 @@ nid: ID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$. + /* Decide how to parse HID based on proto */ + $$.q = $0.q; + if ($$.q.addr == Q_PORT) { +- bpf_set_error(cstate, "'port' modifier applied to ip host"); +- YYABORT; ++ bpf_set_error(cstate, "'port' modifier applied to ip host"); ++ YYABORT; + } else if ($$.q.addr == Q_PORTRANGE) { +- bpf_set_error(cstate, "'portrange' modifier applied to ip host"); +- YYABORT; ++ bpf_set_error(cstate, "'portrange' modifier applied to ip host"); ++ YYABORT; + } else if ($$.q.addr == Q_PROTO) { +- bpf_set_error(cstate, "'proto' modifier applied to ip host"); +- YYABORT; ++ bpf_set_error(cstate, "'proto' modifier applied to ip host"); ++ YYABORT; + } else if ($$.q.addr == Q_PROTOCHAIN) { +- bpf_set_error(cstate, "'protochain' modifier applied to ip host"); +- YYABORT; ++ bpf_set_error(cstate, "'protochain' modifier applied to ip host"); ++ YYABORT; + } + CHECK_PTR_VAL(($$.b = gen_ncode(cstate, $1, 0, $$.q))); + } +@@ -440,7 +451,7 @@ pid: nid + | qid and id { gen_and($1.b, $3.b); $$ = $3; } + | qid or id { gen_or($1.b, $3.b); $$ = $3; } + ; +-qid: pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1, ++qid: pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, $1, + $$.q = $0.q))); } + | pid + ; +@@ -514,7 +525,7 @@ pname: LINK { $$ = Q_LINK; } + | IGRP { $$ = Q_IGRP; } + | PIM { $$ = Q_PIM; } + | VRRP { $$ = Q_VRRP; } +- | CARP { $$ = Q_CARP; } ++ | CARP { $$ = Q_CARP; } + | ATALK { $$ = Q_ATALK; } + | AARP { $$ = Q_AARP; } + | DECNET { $$ = Q_DECNET; } +@@ -549,14 +560,14 @@ other: pqual TK_BROADCAST { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); } + | CBYTE NUM byteop NUM { CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); } + | INBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); } + | OUTBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); } +- | VLAN pnum { CHECK_PTR_VAL(($$ = gen_vlan(cstate, (bpf_u_int32)$2, 1))); } ++ | VLAN pnum { CHECK_PTR_VAL(($$ = gen_vlan(cstate, $2, 1))); } + | VLAN { CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); } +- | MPLS pnum { CHECK_PTR_VAL(($$ = gen_mpls(cstate, (bpf_u_int32)$2, 1))); } ++ | MPLS pnum { CHECK_PTR_VAL(($$ = gen_mpls(cstate, $2, 1))); } + | MPLS { CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); } + | PPPOED { CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); } +- | PPPOES pnum { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, (bpf_u_int32)$2, 1))); } ++ | PPPOES pnum { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, $2, 1))); } + | PPPOES { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); } +- | GENEVE pnum { CHECK_PTR_VAL(($$ = gen_geneve(cstate, (bpf_u_int32)$2, 1))); } ++ | GENEVE pnum { CHECK_PTR_VAL(($$ = gen_geneve(cstate, $2, 1))); } + | GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); } + | pfvar { $$ = $1; } + | pqual p80211 { $$ = $2; } +@@ -586,45 +597,55 @@ p80211: TYPE type SUBTYPE subtype + | DIR dir { CHECK_PTR_VAL(($$ = gen_p80211_fcdir(cstate, $2))); } + ; + +-type: NUM ++type: NUM { if (($1 & (~IEEE80211_FC0_TYPE_MASK)) != 0) { ++ bpf_set_error(cstate, "invalid 802.11 type value 0x%02x", $1); ++ YYABORT; ++ } ++ $$ = (int)$1; ++ } + | ID { CHECK_PTR_VAL($1); +- $$ = str2tok($1, ieee80211_types); +- if ($$ == -1) { +- bpf_set_error(cstate, "unknown 802.11 type name"); +- YYABORT; +- } +- } ++ $$ = str2tok($1, ieee80211_types); ++ if ($$ == -1) { ++ bpf_set_error(cstate, "unknown 802.11 type name \"%s\"", $1); ++ YYABORT; ++ } ++ } + ; + +-subtype: NUM ++subtype: NUM { if (($1 & (~IEEE80211_FC0_SUBTYPE_MASK)) != 0) { ++ bpf_set_error(cstate, "invalid 802.11 subtype value 0x%02x", $1); ++ YYABORT; ++ } ++ $$ = (int)$1; ++ } + | ID { const struct tok *types = NULL; +- int i; +- CHECK_PTR_VAL($1); +- for (i = 0;; i++) { +- if (ieee80211_type_subtypes[i].tok == NULL) { +- /* Ran out of types */ +- bpf_set_error(cstate, "unknown 802.11 type"); ++ int i; ++ CHECK_PTR_VAL($1); ++ for (i = 0;; i++) { ++ if (ieee80211_type_subtypes[i].tok == NULL) { ++ /* Ran out of types */ ++ bpf_set_error(cstate, "unknown 802.11 type"); ++ YYABORT; ++ } ++ if (-1 == ieee80211_type_subtypes[i].type) { ++ types = ieee80211_type_subtypes[i].tok; ++ break; ++ } ++ } ++ ++ $$ = str2tok($1, types); ++ if ($$ == -1) { ++ bpf_set_error(cstate, "unknown 802.11 subtype name \"%s\"", $1); + YYABORT; ++ } + } +- if ($-1 == ieee80211_type_subtypes[i].type) { +- types = ieee80211_type_subtypes[i].tok; +- break; +- } +- } +- +- $$ = str2tok($1, types); +- if ($$ == -1) { +- bpf_set_error(cstate, "unknown 802.11 subtype name"); +- YYABORT; +- } +- } + ; + + type_subtype: ID { int i; + CHECK_PTR_VAL($1); + for (i = 0;; i++) { +- if (ieee80211_type_subtypes[i].tok == NULL) { +- /* Ran out of types */ ++ if (ieee80211_type_subtypes[i].tok == NULL) { ++ /* Ran out of types */ + bpf_set_error(cstate, "unknown 802.11 type name"); + YYABORT; + } +@@ -654,9 +675,9 @@ pllc: LLC { CHECK_PTR_VAL(($$ = gen_llc(cstate))); } + } else { + subtype = str2tok($2, llc_u_subtypes); + if (subtype == -1) { +- bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2); +- YYABORT; +- } ++ bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2); ++ YYABORT; ++ } + CHECK_PTR_VAL(($$ = gen_llc_u_subtype(cstate, subtype))); + } + } +@@ -665,7 +686,7 @@ pllc: LLC { CHECK_PTR_VAL(($$ = gen_llc(cstate))); } + | LLC PF_RNR { CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, LLC_RNR))); } + ; + +-dir: NUM ++dir: NUM { $$ = (int)$1; } + | ID { CHECK_PTR_VAL($1); + if (pcap_strcasecmp($1, "nods") == 0) + $$ = IEEE80211_FC1_DIR_NODS; +@@ -743,15 +764,15 @@ atmfield: VPI { $$.atmfieldtype = A_VPI; } + | VCI { $$.atmfieldtype = A_VCI; } + ; + atmvalue: atmfieldvalue +- | relop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0))); } +- | irelop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1))); } ++ | relop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $0.atmfieldtype, $2, $1, 0))); } ++ | irelop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $0.atmfieldtype, $2, $1, 1))); } + | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; } + ; + atmfieldvalue: NUM { + $$.atmfieldtype = $0.atmfieldtype; + if ($$.atmfieldtype == A_VPI || + $$.atmfieldtype == A_VCI) +- CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0))); ++ CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $$.atmfieldtype, $1, BPF_JEQ, 0))); + } + ; + atmlistvalue: atmfieldvalue +@@ -776,8 +797,8 @@ mtp3field: SIO { $$.mtp3fieldtype = M_SIO; } + | HSLS { $$.mtp3fieldtype = MH_SLS; } + ; + mtp3value: mtp3fieldvalue +- | relop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0))); } +- | irelop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1))); } ++ | relop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $0.mtp3fieldtype, $2, $1, 0))); } ++ | irelop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $0.mtp3fieldtype, $2, $1, 1))); } + | paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; } + ; + mtp3fieldvalue: NUM { +@@ -790,10 +811,10 @@ mtp3fieldvalue: NUM { + $$.mtp3fieldtype == MH_OPC || + $$.mtp3fieldtype == MH_DPC || + $$.mtp3fieldtype == MH_SLS) +- CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0))); ++ CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, $1, BPF_JEQ, 0))); + } + ; + mtp3listvalue: mtp3fieldvalue + | mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; } + ; +-%% ++%% +\ No newline at end of file +diff --git a/optimize.c b/optimize.c +index 448452d..c0f9ea5 100644 +--- a/optimize.c ++++ b/optimize.c +@@ -213,17 +213,17 @@ lowest_set_bit(int mask) + */ + struct valnode { + int code; +- int v0, v1; +- int val; ++ bpf_u_int32 v0, v1; ++ int val; /* the value number */ + struct valnode *next; + }; + + /* Integer constants mapped with the load immediate opcode. */ +-#define K(i) F(opt_state, BPF_LD|BPF_IMM|BPF_W, i, 0L) ++#define K(i) F(opt_state, BPF_LD|BPF_IMM|BPF_W, i, 0U) + + struct vmapinfo { + int is_const; +- bpf_int32 const_val; ++ bpf_u_int32 const_val; + }; + + typedef struct { +@@ -313,8 +313,8 @@ typedef struct { + + #define MODULUS 213 + struct valnode *hashtbl[MODULUS]; +- int curval; +- int maxval; ++ bpf_u_int32 curval; ++ bpf_u_int32 maxval; + + struct vmapinfo *vmap; + struct valnode *vnode_base; +@@ -496,8 +496,11 @@ find_closure(opt_state_t *opt_state, struct block *root) + } + + /* +- * Return the register number that is used by s. If A and X are both +- * used, return AX_ATOM. If no register is used, return -1. ++ * Return the register number that is used by s. ++ * ++ * Returns ATOM_A if A is used, ATOM_X if X is used, AX_ATOM if both A and X ++ * are used, the scratch memory location's number if a scratch memory ++ * location is used (e.g., 0 for M[0]), or -1 if none of those are used. + * + * The implementation should probably change to an array access. + */ +@@ -676,21 +679,40 @@ init_val(opt_state_t *opt_state) + memset((char *)opt_state->hashtbl, 0, sizeof opt_state->hashtbl); + } + +-/* Because we really don't have an IR, this stuff is a little messy. */ +-static int +-F(opt_state_t *opt_state, int code, int v0, int v1) ++/* ++ * Because we really don't have an IR, this stuff is a little messy. ++ * ++ * This routine looks in the table of existing value number for a value ++ * with generated from an operation with the specified opcode and ++ * the specified values. If it finds it, it returns its value number, ++ * otherwise it makes a new entry in the table and returns the ++ * value number of that entry. ++ */ ++static bpf_u_int32 ++F(opt_state_t *opt_state, int code, bpf_u_int32 v0, bpf_u_int32 v1) + { + u_int hash; +- int val; ++ bpf_u_int32 val; + struct valnode *p; + +- hash = (u_int)code ^ ((u_int)v0 << 4) ^ ((u_int)v1 << 8); ++ hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8); + hash %= MODULUS; + + for (p = opt_state->hashtbl[hash]; p; p = p->next) + if (p->code == code && p->v0 == v0 && p->v1 == v1) + return p->val; + ++ /* ++ * Not found. Allocate a new value, and assign it a new ++ * value number. ++ * ++ * opt_state->curval starts out as 0, which means VAL_UNKNOWN; we ++ * increment it before using it as the new value number, which ++ * means we never assign VAL_UNKNOWN. ++ * ++ * XXX - unless we overflow, but we probably won't have 2^32-1 ++ * values; we treat 32 bits as effectively infinite. ++ */ + val = ++opt_state->curval; + if (BPF_MODE(code) == BPF_IMM && + (BPF_CLASS(code) == BPF_LD || BPF_CLASS(code) == BPF_LDX)) { +@@ -709,7 +731,7 @@ F(opt_state_t *opt_state, int code, int v0, int v1) + } + + static inline void +-vstore(struct stmt *s, int *valp, int newval, int alter) ++vstore(struct stmt *s, bpf_u_int32 *valp, bpf_u_int32 newval, int alter) + { + if (alter && newval != VAL_UNKNOWN && *valp == newval) + s->code = NOP; +@@ -722,7 +744,7 @@ vstore(struct stmt *s, int *valp, int newval, int alter) + * (Unary operators are handled elsewhere.) + */ + static void +-fold_op(opt_state_t *opt_state, struct stmt *s, int v0, int v1) ++fold_op(opt_state_t *opt_state, struct stmt *s, bpf_u_int32 v0, bpf_u_int32 v1) + { + bpf_u_int32 a, b; + +@@ -832,7 +854,7 @@ opt_peep(opt_state_t *opt_state, struct block *b) + { + struct slist *s; + struct slist *next, *last; +- int val; ++ bpf_u_int32 val; + + s = b->stmts; + if (s == 0) +@@ -1033,7 +1055,7 @@ opt_peep(opt_state_t *opt_state, struct block *b) + if (b->s.code == (BPF_JMP|BPF_K|BPF_JSET)) { + if (b->s.k == 0) + JT(b) = JF(b); +- if ((u_int)b->s.k == 0xffffffffU) ++ if (b->s.k == 0xffffffffU) + JF(b) = JT(b); + } + /* +@@ -1043,7 +1065,7 @@ opt_peep(opt_state_t *opt_state, struct block *b) + */ + val = b->val[X_ATOM]; + if (opt_state->vmap[val].is_const && BPF_SRC(b->s.code) == BPF_X) { +- bpf_int32 v = opt_state->vmap[val].const_val; ++ bpf_u_int32 v = opt_state->vmap[val].const_val; + b->s.code &= ~BPF_X; + b->s.k = v; + } +@@ -1053,7 +1075,7 @@ opt_peep(opt_state_t *opt_state, struct block *b) + */ + val = b->val[A_ATOM]; + if (opt_state->vmap[val].is_const && BPF_SRC(b->s.code) == BPF_K) { +- bpf_int32 v = opt_state->vmap[val].const_val; ++ bpf_u_int32 v = opt_state->vmap[val].const_val; + switch (BPF_OP(b->s.code)) { + + case BPF_JEQ: +@@ -1061,11 +1083,11 @@ opt_peep(opt_state_t *opt_state, struct block *b) + break; + + case BPF_JGT: +- v = (unsigned)v > (unsigned)b->s.k; ++ v = v > b->s.k; + break; + + case BPF_JGE: +- v = (unsigned)v >= (unsigned)b->s.k; ++ v = v >= b->s.k; + break; + + case BPF_JSET: +@@ -1091,10 +1113,10 @@ opt_peep(opt_state_t *opt_state, struct block *b) + * evaluation and code transformations weren't folded together. + */ + static void +-opt_stmt(opt_state_t *opt_state, struct stmt *s, int val[], int alter) ++opt_stmt(opt_state_t *opt_state, struct stmt *s, bpf_u_int32 val[], int alter) + { + int op; +- int v; ++ bpf_u_int32 v; + + switch (s->code) { + +@@ -1159,7 +1181,7 @@ opt_stmt(opt_state_t *opt_state, struct stmt *s, int val[], int alter) + * about the result of negating 0x80000000 being + * undefined. + */ +- s->k = 0U - (bpf_u_int32)(opt_state->vmap[val[A_ATOM]].const_val); ++ s->k = 0U - opt_state->vmap[val[A_ATOM]].const_val; + val[A_ATOM] = K(s->k); + } + else +@@ -1236,14 +1258,8 @@ opt_stmt(opt_state_t *opt_state, struct stmt *s, int val[], int alter) + else { + s->code = BPF_ALU|BPF_K|op; + s->k = opt_state->vmap[val[X_ATOM]].const_val; +- /* +- * 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 ((op == BPF_LSH || op == BPF_RSH) && +- (s->k < 0 || s->k > 31)) ++ s->k > 31) + opt_error(opt_state, + "shift by more than 31 bits"); + opt_state->done = 0; +@@ -1369,7 +1385,7 @@ opt_blk(opt_state_t *opt_state, struct block *b, int do_stmts) + struct slist *s; + struct edge *p; + int i; +- bpf_int32 aval, xval; ++ bpf_u_int32 aval, xval; + + #if 0 + for (s = b->stmts; s && s->next; s = s->next) +@@ -1488,7 +1504,7 @@ static struct block * + fold_edge(struct block *child, struct edge *ep) + { + int sense; +- int aval0, aval1, oval0, oval1; ++ bpf_u_int32 aval0, aval1, oval0, oval1; + int code = ep->code; + + if (code < 0) { +@@ -1594,7 +1610,8 @@ opt_j(opt_state_t *opt_state, struct edge *ep) + static void + or_pullup(opt_state_t *opt_state, struct block *b) + { +- int val, at_top; ++ bpf_u_int32 val; ++ int at_top; + struct block *pull; + struct block **diffp, **samep; + struct edge *ep; +@@ -1686,7 +1703,8 @@ or_pullup(opt_state_t *opt_state, struct block *b) + static void + and_pullup(opt_state_t *opt_state, struct block *b) + { +- int val, at_top; ++ bpf_u_int32 val; ++ int at_top; + struct block *pull; + struct block **diffp, **samep; + struct edge *ep; +@@ -2379,7 +2397,7 @@ filled: + if (off >= 256) { + /* offset too large for branch, must add a jump */ + if (p->longjt == 0) { +- /* mark this instruction and retry */ ++ /* mark this instruction and retry */ + p->longjt++; + return(0); + } +@@ -2399,7 +2417,7 @@ filled: + if (off >= 256) { + /* offset too large for branch, must add a jump */ + if (p->longjf == 0) { +- /* mark this instruction and retry */ ++ /* mark this instruction and retry */ + p->longjf++; + return(0); + } +diff --git a/scanner.l b/scanner.l +index effcf81..f3dabac 100644 +--- a/scanner.l ++++ b/scanner.l +@@ -147,8 +147,7 @@ void pcap_set_column(int, yyscan_t); + #include "os-proto.h" + #endif + +-static int stoi(char *); +-static inline int xdtoi(int); ++static int stou(char *, YYSTYPE *, compiler_state_t *); + + /* + * Disable diagnostics in the code generated by Flex. +@@ -393,7 +392,7 @@ hsls return HSLS; + ">>" return RSH; + ${B} { yylval->s = sdup(yyextra, yytext); return AID; } + {MAC} { yylval->s = sdup(yyextra, yytext); return EID; } +-{N} { yylval->i = stoi((char *)yytext); return NUM; } ++{N} { return stou(yytext, yylval, yyextra); } + ({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) { + yylval->s = sdup(yyextra, (char *)yytext); return HID; } + {V6} { +@@ -416,62 +415,62 @@ ${B} { yylval->s = sdup(yyextra, yytext); return AID; } + return HID6; + } + {B}:+({B}:+)+ { bpf_set_error(yyextra, "bogus ethernet address %s", yytext); yylval->s = NULL; return EID; } +-icmptype { yylval->i = 0; return NUM; } +-icmpcode { yylval->i = 1; return NUM; } +-icmp-echoreply { yylval->i = 0; return NUM; } +-icmp-unreach { yylval->i = 3; return NUM; } +-icmp-sourcequench { yylval->i = 4; return NUM; } +-icmp-redirect { yylval->i = 5; return NUM; } +-icmp-echo { yylval->i = 8; return NUM; } +-icmp-routeradvert { yylval->i = 9; return NUM; } +-icmp-routersolicit { yylval->i = 10; return NUM; } +-icmp-timxceed { yylval->i = 11; return NUM; } +-icmp-paramprob { yylval->i = 12; return NUM; } +-icmp-tstamp { yylval->i = 13; return NUM; } +-icmp-tstampreply { yylval->i = 14; return NUM; } +-icmp-ireq { yylval->i = 15; return NUM; } +-icmp-ireqreply { yylval->i = 16; return NUM; } +-icmp-maskreq { yylval->i = 17; return NUM; } +-icmp-maskreply { yylval->i = 18; return NUM; } +- +-icmp6type { yylval->i = 0; return NUM; } +-icmp6code { yylval->i = 1; return NUM; } +- +-icmp6-echo { yylval->i = 128; return NUM; } +-icmp6-echoreply { yylval->i = 129; return NUM; } +-icmp6-multicastlistenerquery { yylval->i = 130; return NUM; } +-icmp6-multicastlistenerreportv1 { yylval->i = 131; return NUM; } +-icmp6-multicastlistenerdone { yylval->i = 132; return NUM; } +-icmp6-routersolicit { yylval->i = 133; return NUM; } +-icmp6-routeradvert { yylval->i = 134; return NUM; } +-icmp6-neighborsolicit { yylval->i = 135; return NUM; } +-icmp6-neighboradvert { yylval->i = 136; return NUM; } +-icmp6-redirect { yylval->i = 137; return NUM; } +-icmp6-routerrenum { yylval->i = 138; return NUM; } +-icmp6-nodeinformationquery { yylval->i = 139; return NUM; } +-icmp6-nodeinformationresponse { yylval->i = 140; return NUM; } +-icmp6-ineighbordiscoverysolicit { yylval->i = 141; return NUM; } +-icmp6-ineighbordiscoveryadvert { yylval->i = 142; return NUM; } +-icmp6-multicastlistenerreportv2 { yylval->i = 143; return NUM; } +-icmp6-homeagentdiscoveryrequest { yylval->i = 144; return NUM; } +-icmp6-homeagentdiscoveryreply { yylval->i = 145; return NUM; } +-icmp6-mobileprefixsolicit { yylval->i = 146; return NUM; } +-icmp6-mobileprefixadvert { yylval->i = 147; return NUM; } +-icmp6-certpathsolicit { yylval->i = 148; return NUM; } +-icmp6-certpathadvert { yylval->i = 149; return NUM; } +-icmp6-multicastrouteradvert { yylval->i = 151; return NUM; } +-icmp6-multicastroutersolicit { yylval->i = 152; return NUM; } +-icmp6-multicastrouterterm { yylval->i = 153; return NUM; } +- +-tcpflags { yylval->i = 13; return NUM; } +-tcp-fin { yylval->i = 0x01; return NUM; } +-tcp-syn { yylval->i = 0x02; return NUM; } +-tcp-rst { yylval->i = 0x04; return NUM; } +-tcp-push { yylval->i = 0x08; return NUM; } +-tcp-ack { yylval->i = 0x10; return NUM; } +-tcp-urg { yylval->i = 0x20; return NUM; } +-tcp-ece { yylval->i = 0x40; return NUM; } +-tcp-cwr { yylval->i = 0x80; return NUM; } ++icmptype { yylval->h = 0; return NUM; } ++icmpcode { yylval->h = 1; return NUM; } ++icmp-echoreply { yylval->h = 0; return NUM; } ++icmp-unreach { yylval->h = 3; return NUM; } ++icmp-sourcequench { yylval->h = 4; return NUM; } ++icmp-redirect { yylval->h = 5; return NUM; } ++icmp-echo { yylval->h = 8; return NUM; } ++icmp-routeradvert { yylval->h = 9; return NUM; } ++icmp-routersolicit { yylval->h = 10; return NUM; } ++icmp-timxceed { yylval->h = 11; return NUM; } ++icmp-paramprob { yylval->h = 12; return NUM; } ++icmp-tstamp { yylval->h = 13; return NUM; } ++icmp-tstampreply { yylval->h = 14; return NUM; } ++icmp-ireq { yylval->h = 15; return NUM; } ++icmp-ireqreply { yylval->h = 16; return NUM; } ++icmp-maskreq { yylval->h = 17; return NUM; } ++icmp-maskreply { yylval->h = 18; return NUM; } ++ ++icmp6type { yylval->h = 0; return NUM; } ++icmp6code { yylval->h = 1; return NUM; } ++ ++icmp6-echo { yylval->h = 128; return NUM; } ++icmp6-echoreply { yylval->h = 129; return NUM; } ++icmp6-multicastlistenerquery { yylval->h = 130; return NUM; } ++icmp6-multicastlistenerreportv1 { yylval->h = 131; return NUM; } ++icmp6-multicastlistenerdone { yylval->h = 132; return NUM; } ++icmp6-routersolicit { yylval->h = 133; return NUM; } ++icmp6-routeradvert { yylval->h = 134; return NUM; } ++icmp6-neighborsolicit { yylval->h = 135; return NUM; } ++icmp6-neighboradvert { yylval->h = 136; return NUM; } ++icmp6-redirect { yylval->h = 137; return NUM; } ++icmp6-routerrenum { yylval->h = 138; return NUM; } ++icmp6-nodeinformationquery { yylval->h = 139; return NUM; } ++icmp6-nodeinformationresponse { yylval->h = 140; return NUM; } ++icmp6-ineighbordiscoverysolicit { yylval->h = 141; return NUM; } ++icmp6-ineighbordiscoveryadvert { yylval->h = 142; return NUM; } ++icmp6-multicastlistenerreportv2 { yylval->h = 143; return NUM; } ++icmp6-homeagentdiscoveryrequest { yylval->h = 144; return NUM; } ++icmp6-homeagentdiscoveryreply { yylval->h = 145; return NUM; } ++icmp6-mobileprefixsolicit { yylval->h = 146; return NUM; } ++icmp6-mobileprefixadvert { yylval->h = 147; return NUM; } ++icmp6-certpathsolicit { yylval->h = 148; return NUM; } ++icmp6-certpathadvert { yylval->h = 149; return NUM; } ++icmp6-multicastrouteradvert { yylval->h = 151; return NUM; } ++icmp6-multicastroutersolicit { yylval->h = 152; return NUM; } ++icmp6-multicastrouterterm { yylval->h = 153; return NUM; } ++ ++tcpflags { yylval->h = 13; return NUM; } ++tcp-fin { yylval->h = 0x01; return NUM; } ++tcp-syn { yylval->h = 0x02; return NUM; } ++tcp-rst { yylval->h = 0x04; return NUM; } ++tcp-push { yylval->h = 0x08; return NUM; } ++tcp-ack { yylval->h = 0x10; return NUM; } ++tcp-urg { yylval->h = 0x20; return NUM; } ++tcp-ece { yylval->h = 0x40; return NUM; } ++tcp-cwr { yylval->h = 0x80; return NUM; } + [A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? { + yylval->s = sdup(yyextra, (char *)yytext); return ID; } + "\\"[^ !()\n\t]+ { yylval->s = sdup(yyextra, (char *)yytext + 1); return ID; } +@@ -483,40 +482,110 @@ tcp-cwr { yylval->i = 0x80; return NUM; } + */ + DIAG_ON_FLEX + +-/* Hex digit to integer. */ +-static inline int +-xdtoi(int c) +-{ +- if (isdigit(c)) +- return c - '0'; +- else if (islower(c)) +- return c - 'a' + 10; +- else +- return c - 'A' + 10; +-} +- + /* +- * Convert string to integer. Just like atoi(), but checks for ++ * Convert string to 32-bit unsigned integer. Just like atoi(), but checks for + * preceding 0x or 0 and uses hex or octal instead of decimal. ++ * ++ * On success, sets yylval->h to the value and returns NUM. ++ * On failure, sets the BPF error string and returns LEX_ERROR, to force ++ * the parse to stop. + */ + static int +-stoi(char *s) ++stou(char *yytext_arg, YYSTYPE *yylval_arg, compiler_state_t *yyextra_arg) + { +- int base = 10; +- int n = 0; +- ++ bpf_u_int32 n = 0; ++ unsigned int digit; ++ char *s = yytext_arg; ++ ++ /* ++ * yytext_arg is guaranteed either to be a string of decimal digits ++ * or 0[xX] followed by a string of hex digits. ++ */ + if (*s == '0') { + if (s[1] == 'x' || s[1] == 'X') { +- s += 2; +- base = 16; +- } +- else { +- base = 8; ++ /* ++ * Begins with 0x or 0X, so hex. ++ * Guaranteed to be all hex digits following the ++ * prefix, so anything that's not 0-9 or a-f is ++ * A-F. ++ */ ++ s += 2; /* skip the prefix */ ++ while ((digit = *s++) != '\0') { ++ if (digit >= '0' && digit <= '9') ++ digit = digit - '0'; ++ else if (digit >= 'a' && digit <= 'f') ++ digit = digit - 'a' + 10; ++ else ++ digit = digit - 'A' + 10; ++ ++ /* ++ * Check for overflow. ++ */ ++ if (n > 0xFFFFFFFU) { ++ /* ++ * We have more than 28 bits of ++ * number, and are about to ++ * add 4 more; that won't fit ++ * in 32 bits. ++ */ ++ bpf_set_error(yyextra_arg, ++ "number %s overflows 32 bits", ++ yytext_arg); ++ return LEX_ERROR; ++ } ++ n = (n << 4) + digit; ++ } ++ } else { ++ /* ++ * Begins with 0, but not 0x or 0X, so octal. ++ * Guaranteed to be all *decimal* digits following ++ * the prefix, so we need to catch 8 and 9 and ++ * report an error. ++ */ + s += 1; ++ while ((digit = *s++) != '\0') { ++ if (digit >= '0' && digit <= '7') ++ digit = digit - '0'; ++ else { ++ bpf_set_error(yyextra_arg, ++ "number %s contains non-octal digit", ++ yytext_arg); ++ return LEX_ERROR; ++ } ++ if (n > 03777777777U) { ++ /* ++ * We have more than 29 bits of ++ * number, and are about to add ++ * 3 more; that won't fit in ++ * 32 bits. ++ */ ++ bpf_set_error(yyextra_arg, ++ "number %s overflows 32 bits", ++ yytext_arg); ++ return LEX_ERROR; ++ } ++ n = (n << 3) + digit; ++ } ++ } ++ } else { ++ /* ++ * Decimal. ++ */ ++ while ((digit = *s++) != '\0') { ++ digit = digit - '0'; ++#define CUTOFF_DEC (0xFFFFFFFFU / 10U) ++#define CUTLIM_DEC (0xFFFFFFFFU % 10U) ++ if (n > CUTOFF_DEC || ++ (n == CUTOFF_DEC && digit > CUTLIM_DEC)) { ++ bpf_set_error(yyextra_arg, ++ "number %s overflows 32 bits", ++ yytext_arg); ++ return LEX_ERROR; ++ } ++ n = (n * 10) + digit; + } + } +- while (*s) +- n = n * base + xdtoi(*s++); + +- return n; ++ yylval_arg->h = n; ++ return NUM; + } +-- +2.19.1 diff --git a/fix-use-of-sizeof-on-a-pointer.patch b/fix-use-of-sizeof-on-a-pointer.patch deleted file mode 100644 index 26c5b52..0000000 --- a/fix-use-of-sizeof-on-a-pointer.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 8107ee96602992924adccc01bb2214d24d389182 Mon Sep 17 00:00:00 2001 -From: Alexander Galanin -Date: Mon, 3 Dec 2018 16:12:48 +0300 -Subject: [PATCH 259/470] fix use of sizeof on a pointer - ---- - pcap-bpf.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/pcap-bpf.c b/pcap-bpf.c -index 3b53978..13c1cf2 100644 ---- a/pcap-bpf.c -+++ b/pcap-bpf.c -@@ -1366,8 +1366,8 @@ bpf_load(char *errbuf) - - /* Check if the driver is loaded */ - memset(&cfg_ld, 0x0, sizeof(cfg_ld)); -+ pcap_snprintf(buf, sizeof(buf), "%s/%s", DRIVER_PATH, BPF_NAME); - cfg_ld.path = buf; -- pcap_snprintf(cfg_ld.path, sizeof(cfg_ld.path), "%s/%s", DRIVER_PATH, BPF_NAME); - if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) || - (cfg_ld.kmid == 0)) { - /* Driver isn't loaded, load it now */ --- -1.8.3.1 - diff --git a/ieee80215-arphrd.patch b/ieee80215-arphrd.patch index 45f24c4..1906280 100644 --- a/ieee80215-arphrd.patch +++ b/ieee80215-arphrd.patch @@ -20,3 +20,4 @@ index 58782ae..b7a813d 100644 /* ARPHRD_LAPD is unofficial and randomly allocated, if reallocation * is needed, please report it to */ + diff --git a/libpcap-1.9.0.tar.gz b/libpcap-1.9.0.tar.gz deleted file mode 100644 index 32ab5c6..0000000 Binary files a/libpcap-1.9.0.tar.gz and /dev/null differ diff --git a/libpcap-1.9.1.tar.gz b/libpcap-1.9.1.tar.gz new file mode 100644 index 0000000..a052b0f Binary files /dev/null and b/libpcap-1.9.1.tar.gz differ diff --git a/libpcap.spec b/libpcap.spec index af71249..0a68f88 100644 --- a/libpcap.spec +++ b/libpcap.spec @@ -1,103 +1,66 @@ -Name: libpcap -Epoch: 14 -Version: 1.9.0 -Release: 4 -Summary: A library for user-level packet capture -License: BSD with advertising -URL: http://www.tcpdump.org -Source: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz +Name: libpcap +Epoch: 14 +Version: 1.9.1 +Release: 3 +Summary: A system-independent interface for user-level packet capture +License: BSD with advertising +URL: http://www.tcpdump.org +Source0: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz -#ptach 1 and 2 are come from fedora -Patch0001: 0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch -Patch0002: 0002-pcap-config-mitigate-multilib-conflict.patch -#following patches are come from upstream community -Patch6000: ieee80215-arphrd.patch -Patch6001: Fix-using-uninitialised-file-descriptor.patch -Patch6002: Don-t-overflow-an-int.patch -Patch6003: Fix-leak-in-rpcap.patch -Patch6004: Fix-the-semantics-of-BPF_LSH-and-BPF_RSH-for-shifts-.patch -Patch6005: 0194-Plug-some-memory-leaks.patch -Patch6006: 0195-Plug-some-memory-leaks.patch -Patch6007: Catch-another-place-where-we-divide-by-or-take-a-mod.patch -Patch6008: Make-qerr-const.patch -Patch6009: fix-use-of-sizeof-on-a-pointer.patch -Patch6010: 0470-Plug-memory-leak.patch -Patch6011: 0012-Plug-a-file-descriptor-leak.patch -Patch6012: 0036-Use-the-snapshot-length-to-set-the-buffer-size-and-s.patch -Patch6013: 0066-Check-for-an-empty-description-by-checking-if-the-fi.patch -Patch6014: 0068-Fixed-the-fread-call-in-the-savefile.c-file.patch -Patch6015: 0069-Fixed-number-of-elements-returned.patch -Patch6016: 0070-Read-the-magic-number-into-a-byte-array.patch -Patch6017: 0075-Use-ab-rather-than-rb-for-the-pcap_dump_open_append-.patch -Patch6018: 0079-Treat-both-ENXIO-and-EIO-as-device-went-away.patch -Patch6019: 0080-Change-the-error-message-for-ENXIO-EIO-to-match-real.patch +Patch0001: 0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch +Patch0002: 0002-pcap-config-mitigate-multilib-conflict.patch +Patch0003: 0003-pcap-linux-apparently-ctc-interfaces-on-s390-has-eth.patch +Patch0004: ieee80215-arphrd.patch +Patch0005: clean-up-signed-vs-unsigned-do-more-error-checking-in-the-parser.patch -BuildRequires: bison bluez-libs-devel flex glibc-kernheaders >= 2.2.0 +BuildRequires: bison bluez-libs-devel flex gcc git glibc-kernheaders >= 2.2.0 %description -Libpcap provides functions for user-level packet capture, used in low-level -network monitoring. +This is the official web site of tcpdump, a powerful command-line +packet analyzer; and libpcap, a portable C/C++ library for +network traffic capture. -%package devel -Summary: Libraries and files for libpcap -Requires: %{name} = %{epoch}:%{version}-%{release} +%package devel +Summary: header files for libpcap +Requires: %{name} = %{epoch}:%{version}-%{release} -%description devel -This package provides files and libraries for -developing libpcap applications. +%description devel +header files for libpcap -%package help -Summary: Help information for libpcap - -%description help -This package provides help for libpcap. +%package_help %prep -%autosetup -p1 +%autosetup -n %{name}-%{version} -S git %build +export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" %configure -%make_build CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" +%make_build %install -%make_install +%make_install -%ldconfig_post -%ldconfig_postun +%delete_la_and_a + +%ldconfig_scriptlets %files +%defattr(-,root,root) %license LICENSE %{_libdir}/libpcap.so.* -%exclude %{_libdir}/libpcap.a -%files devel +%files devel +%defattr(-,root,root) %{_bindir}/pcap-config -%{_includedir}/pcap*.h -%{_includedir}/pcap +%{_includedir}/* %{_libdir}/libpcap.so %{_libdir}/pkgconfig/libpcap.pc -%files help +%files help +%defattr(-,root,root) %doc README.md CHANGES CREDITS -%{_mandir}/man1/pcap-config.1* -%{_mandir}/man3/pcap*.3* -%{_mandir}/man5/pcap*.5* -%{_mandir}/man7/pcap*.7* +%{_mandir}/man* %changelog -* Wed Sep 25 2019 openEuler Buildteam - 14:1.9.0-4 -- Type:bugfix -- ID:NA -- SUG:NA -- DESC:Plug-a-file-descriptor-leak - Use-the-snapshot-length-to-set-the-buffer-size-and-s - Check-for-an-empty-description-by-checking-if-the-fi - Fixed-the-fread-call-in-the-savefile.c-file - Fixed-number-of-elements-returned - Read-the-magic-number-into-a-byte-array - Use-ab-rather-than-rb-for-the-pcap_dump_open_append - Treat-both-ENXIO-and-EIO-as-device-went-away - Change-the-error-message-for-ENXIO-EIO-to-match-real - -* Wed Sep 11 2019 liyongqiang - 14:1.9.0-3 +* Sat Dec 21 2019 openEuler Buildteam - 14:1.9.1-3 - Package init