diff --git a/.gitignore b/.gitignore index fc5ef7d..6cf448d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ tcpdump-4.1.1.tar.gz /tcpdump-4.5.0-20131108gitb07944a.tar.gz /tcpdump-4.5.1.tar.gz /tcpdump-4.6.2.tar.gz +/tcpdump-4.7.3.tar.gz diff --git a/0003-Drop-root-priviledges-before-opening-first-savefile-.patch b/0003-Drop-root-priviledges-before-opening-first-savefile-.patch index 074854b..99de60a 100644 --- a/0003-Drop-root-priviledges-before-opening-first-savefile-.patch +++ b/0003-Drop-root-priviledges-before-opening-first-savefile-.patch @@ -1,19 +1,19 @@ -From 964bd27d3544cf952db1820c0badb79a71227b12 Mon Sep 17 00:00:00 2001 +From ec4e1a40fcf43d96a121a1ead877f2db4953dabb Mon Sep 17 00:00:00 2001 From: rpm-build -Date: Mon, 20 Oct 2014 14:32:43 +0200 -Subject: [PATCH 3/7] Drop root priviledges before opening first savefile if +Date: Wed, 25 Mar 2015 13:13:49 +0100 +Subject: [PATCH] Drop root priviledges before opening first savefile if running with -Z root --- tcpdump.1.in | 7 ++++++- - tcpdump.c | 34 +++++++++++++++++++++++++++++++--- - 2 files changed, 37 insertions(+), 4 deletions(-) + tcpdump.c | 35 ++++++++++++++++++++++++++++++++--- + 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/tcpdump.1.in b/tcpdump.1.in -index a966469..e3a6ef4 100644 +index f9522cb..3f1bc5f 100644 --- a/tcpdump.1.in +++ b/tcpdump.1.in -@@ -241,6 +241,9 @@ have the name specified with the +@@ -249,6 +249,9 @@ have the name specified with the flag, with a number after it, starting at 1 and continuing upward. The units of \fIfile_size\fP are millions of bytes (1,000,000 bytes, not 1,048,576 bytes). @@ -23,7 +23,7 @@ index a966469..e3a6ef4 100644 .TP .B \-d Dump the compiled packet-matching code in a human readable form to -@@ -848,7 +851,9 @@ but before opening any savefiles for output, change the user ID to +@@ -865,7 +868,9 @@ but before opening any savefiles for output, change the user ID to and the group ID to the primary group of .IR user . .IP @@ -35,40 +35,47 @@ index a966469..e3a6ef4 100644 .RS selects which packets will be dumped. diff --git a/tcpdump.c b/tcpdump.c -index 8d615d7..9110ccf 100644 +index 2fd1617..4cbeb05 100644 --- a/tcpdump.c +++ b/tcpdump.c -@@ -1699,11 +1699,24 @@ main(int argc, char **argv) - } - #endif /* HAVE_CAP_NG_H */ - -- if (getuid() == 0 || geteuid() == 0) { +@@ -1029,6 +1029,7 @@ main(int argc, char **argv) + cap_rights_t rights; + int cansandbox; + #endif /* HAVE_CAPSICUM */ ++ int chown_flag; + + #ifdef WIN32 + if(wsockinit() != 0) return 1; +@@ -1841,10 +1842,23 @@ main(int argc, char **argv) + } + capng_apply(CAPNG_SELECT_BOTH); + #endif /* HAVE_LIBCAP_NG */ - if (username || chroot_dir) -+ /* If user is running tcpdump as root and wants to write to the savefile, -+ * we will check if -C is set and if it is, we will drop root -+ * privileges right away and consequent call to pcap_dump_open() -+ * will most likely fail for the first file. If -C flag is not set we -+ * will create file as root then change ownership of file to proper -+ * user(default tcpdump) and drop root privileges. -+ */ -+ int chown_flag = 0; -+ -+ if (WFileName && (getuid() == 0 || geteuid() == 0)) -+ if (Cflag && (username || chroot_dir)) -+ droproot(username, chroot_dir); -+ else -+ chown_flag = 1; -+ else -+ if ((getuid() == 0 || geteuid() == 0) && (username || chroot_dir)) - droproot(username, chroot_dir); - +- droproot(username, chroot_dir); ++ /* If user is running tcpdump as root and wants to write to the savefile, ++ * we will check if -C is set and if it is, we will drop root ++ * privileges right away and consequent call to pcap_dump_open() ++ * will most likely fail for the first file. If -C flag is not set we ++ * will create file as root then change ownership of file to proper ++ * user(default tcpdump) and drop root privileges. ++ */ ++ if (WFileName) ++ if (Cflag && (username || chroot_dir)) ++ droproot(username, chroot_dir); ++ else ++ chown_flag = 1; ++ else ++ if (username || chroot_dir) ++ droproot(username, chroot_dir); ++ } + - } #endif /* WIN32 */ - + if (pcap_setfilter(pd, &fcode) < 0) -@@ -1738,6 +1751,21 @@ main(int argc, char **argv) +@@ -1879,6 +1893,21 @@ main(int argc, char **argv) MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0); - + p = pcap_dump_open(pd, dumpinfo.CurrentFileName); + + /* Change ownership of file and drop root privileges */ @@ -85,9 +92,8 @@ index 8d615d7..9110ccf 100644 + if (username || chroot_dir) + droproot(username, chroot_dir); + } - #ifdef HAVE_CAP_NG_H - /* Give up capabilities, clear Effective set */ - capng_clear(CAPNG_EFFECTIVE); --- -1.8.3.1 - + #ifdef HAVE_LIBCAP_NG + /* Give up CAP_DAC_OVERRIDE capability. + * Only allow it to be restored if the -C or -G flag have been +-- +2.3.4 diff --git a/0004-tcpslice-update-tcpslice-patch-to-1.2a3.patch b/0004-tcpslice-update-tcpslice-patch-to-1.2a3.patch index 1482a9f..30539aa 100644 --- a/0004-tcpslice-update-tcpslice-patch-to-1.2a3.patch +++ b/0004-tcpslice-update-tcpslice-patch-to-1.2a3.patch @@ -18,9 +18,9 @@ index 1e2d051..23aa105 100644 */ -#define PACKET_HDR_LEN (sizeof( struct pcap_pkthdr )) +#define PACKET_HDR_LEN (sizeof( struct pcap_sf_pkthdr )) - + extern int snaplen; - + @@ -111,16 +111,24 @@ reasonable_header( struct pcap_pkthdr *hdr, time_t first_time, time_t last_time static void extract_header( pcap_t *p, u_char *buf, struct pcap_pkthdr *hdr ) @@ -29,7 +29,7 @@ index 1e2d051..23aa105 100644 + struct pcap_sf_pkthdr hdri; + + memcpy((char *) &hdri, (char *) buf, sizeof(struct pcap_sf_pkthdr)); - + if ( pcap_is_swapped( p ) ) { - hdr->ts.tv_sec = SWAPLONG(hdr->ts.tv_sec); @@ -58,8 +58,8 @@ index de4a01c..9b220de 100644 +++ b/tcpslice-1.2a3/tcpslice.h @@ -20,6 +20,26 @@ */ - - + + +#include +/* #include */ + @@ -68,7 +68,7 @@ index de4a01c..9b220de 100644 + * It has to use the same types everywhere, independent of the actual + * `struct timeval' + */ -+ ++ +struct pcap_timeval { + bpf_int32 tv_sec; /* seconds */ + bpf_int32 tv_usec; /* microseconds */ @@ -81,8 +81,7 @@ index de4a01c..9b220de 100644 +}; + time_t gwtm2secs( struct tm *tm ); - - int sf_find_end( struct pcap *p, struct timeval *first_timestamp, --- -1.8.3.1 + int sf_find_end( struct pcap *p, struct timeval *first_timestamp, +-- +1.8.3.1 diff --git a/0008-Don-t-print-out-we-dropped-root-we-are-always-droppi.patch b/0008-Don-t-print-out-we-dropped-root-we-are-always-droppi.patch index 371e4e3..8aeb96a 100644 --- a/0008-Don-t-print-out-we-dropped-root-we-are-always-droppi.patch +++ b/0008-Don-t-print-out-we-dropped-root-we-are-always-droppi.patch @@ -1,39 +1,36 @@ -From 780db0477c304196a700894bdfd9a3096b5857fd Mon Sep 17 00:00:00 2001 -From: Michal Sekletar -Date: Tue, 21 Oct 2014 13:37:24 +0200 -Subject: [PATCH 8/8] Don't print out we dropped root, we are always dropping - it. +From 6a204e4e6d2268594858c85c642d98c082190787 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Wed, 25 Mar 2015 13:38:54 +0100 +Subject: [PATCH] Don't print out we dropped root, we are always dropping it --- - tcpdump.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) + tcpdump.c | 6 ------ + 1 file changed, 6 deletions(-) diff --git a/tcpdump.c b/tcpdump.c -index 9110ccf..8ce9102 100644 +index 1a17361..7d45924 100644 --- a/tcpdump.c +++ b/tcpdump.c -@@ -726,9 +726,7 @@ droproot(const char *username, const char *chroot_dir) +@@ -758,9 +758,6 @@ droproot(const char *username, const char *chroot_dir) if (ret < 0) { fprintf(stderr, "error : ret %d\n", ret); } - else { -- printf("dropped privs to %s\n", username); +- fprintf(stderr, "dropped privs to %s\n", username); - } -+ - /* We don't need CAP_SETUID and CAP_SETGID */ - capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_SETUID); - capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_SETUID); -@@ -746,9 +744,7 @@ droproot(const char *username, const char *chroot_dir) + #else + if (initgroups(pw->pw_name, pw->pw_gid) != 0 || + setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) { +@@ -771,9 +768,6 @@ droproot(const char *username, const char *chroot_dir) pcap_strerror(errno)); exit(1); } - else { -- printf("dropped privs to %s\n", username); +- fprintf(stderr, "dropped privs to %s\n", username); - } -+ - #endif /* HAVE_CAP_NG_H */ + #endif /* HAVE_LIBCAP_NG */ } else { -- -1.8.3.1 +2.3.4 diff --git a/0009-Do-more-bounds-checking-and-length-checking.patch b/0009-Do-more-bounds-checking-and-length-checking.patch deleted file mode 100644 index a97b109..0000000 --- a/0009-Do-more-bounds-checking-and-length-checking.patch +++ /dev/null @@ -1,183 +0,0 @@ -From 3b223228a87434f214ea3f80d9af420491a76434 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Tue, 11 Nov 2014 16:49:39 -0800 -Subject: [PATCH 9/9] Do more bounds checking and length checking. - -Don't run past the end of the captured data, and don't run past the end -of the packet (i.e., don't make the length variable go negative). - -Also, stop dissecting if the message length isn't valid. ---- - print-olsr.c | 56 +++++++++++++++++++++++++++++++++++++++++++------------- - 1 file changed, 43 insertions(+), 13 deletions(-) - -diff --git a/print-olsr.c b/print-olsr.c -index 6fa0d76..6d2d65f 100644 ---- a/print-olsr.c -+++ b/print-olsr.c -@@ -178,7 +178,7 @@ struct olsr_lq_neighbor6 { - /* - * print a neighbor list with LQ extensions. - */ --static void -+static int - olsr_print_lq_neighbor4(netdissect_options *ndo, - const u_char *msg_data, u_int hello_len) - { -@@ -187,6 +187,8 @@ olsr_print_lq_neighbor4(netdissect_options *ndo, - while (hello_len >= sizeof(struct olsr_lq_neighbor4)) { - - lq_neighbor = (struct olsr_lq_neighbor4 *)msg_data; -+ if (!ND_TTEST(*lq_neighbor)) -+ return (-1); - - ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2lf%%" - ", neighbor-link-quality %.2lf%%", -@@ -197,10 +199,11 @@ olsr_print_lq_neighbor4(netdissect_options *ndo, - msg_data += sizeof(struct olsr_lq_neighbor4); - hello_len -= sizeof(struct olsr_lq_neighbor4); - } -+ return (0); - } - - #if INET6 --static void -+static int - olsr_print_lq_neighbor6(netdissect_options *ndo, - const u_char *msg_data, u_int hello_len) - { -@@ -209,6 +212,8 @@ olsr_print_lq_neighbor6(netdissect_options *ndo, - while (hello_len >= sizeof(struct olsr_lq_neighbor6)) { - - lq_neighbor = (struct olsr_lq_neighbor6 *)msg_data; -+ if (!ND_TTEST(*lq_neighbor)) -+ return (-1); - - ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2lf%%" - ", neighbor-link-quality %.2lf%%", -@@ -219,13 +224,14 @@ olsr_print_lq_neighbor6(netdissect_options *ndo, - msg_data += sizeof(struct olsr_lq_neighbor6); - hello_len -= sizeof(struct olsr_lq_neighbor6); - } -+ return (0); - } - #endif /* INET6 */ - - /* - * print a neighbor list. - */ --static void -+static int - olsr_print_neighbor(netdissect_options *ndo, - const u_char *msg_data, u_int hello_len) - { -@@ -236,6 +242,8 @@ olsr_print_neighbor(netdissect_options *ndo, - - while (hello_len >= sizeof(struct in_addr)) { - -+ if (!ND_TTEST2(*msg_data, sizeof(struct in_addr))) -+ return (-1); - /* print 4 neighbors per line */ - - ND_PRINT((ndo, "%s%s", ipaddr_string(ndo, msg_data), -@@ -244,6 +252,7 @@ olsr_print_neighbor(netdissect_options *ndo, - msg_data += sizeof(struct in_addr); - hello_len -= sizeof(struct in_addr); - } -+ return (0); - } - - -@@ -326,6 +335,9 @@ olsr_print(netdissect_options *ndo, - ME_TO_DOUBLE(msgptr.v6->vtime), - EXTRACT_16BITS(msgptr.v6->msg_seq), - msg_len, (msg_len_valid == 0) ? " (invalid)" : "")); -+ if (!msg_len_valid) { -+ return; -+ } - - msg_tlen = msg_len - sizeof(struct olsr_msg6); - msg_data = tptr + sizeof(struct olsr_msg6); -@@ -354,6 +366,9 @@ olsr_print(netdissect_options *ndo, - ME_TO_DOUBLE(msgptr.v4->vtime), - EXTRACT_16BITS(msgptr.v4->msg_seq), - msg_len, (msg_len_valid == 0) ? " (invalid)" : "")); -+ if (!msg_len_valid) { -+ return; -+ } - - msg_tlen = msg_len - sizeof(struct olsr_msg4); - msg_data = tptr + sizeof(struct olsr_msg4); -@@ -362,6 +377,8 @@ olsr_print(netdissect_options *ndo, - switch (msg_type) { - case OLSR_HELLO_MSG: - case OLSR_HELLO_LQ_MSG: -+ if (msg_tlen < sizeof(struct olsr_hello)) -+ goto trunc; - ND_TCHECK2(*msg_data, sizeof(struct olsr_hello)); - - ptr.hello = (struct olsr_hello *)msg_data; -@@ -401,15 +418,21 @@ olsr_print(netdissect_options *ndo, - msg_tlen -= sizeof(struct olsr_hello_link); - hello_len -= sizeof(struct olsr_hello_link); - -+ ND_TCHECK2(*msg_data, hello_len); - if (msg_type == OLSR_HELLO_MSG) { -- olsr_print_neighbor(ndo, msg_data, hello_len); -+ if (olsr_print_neighbor(ndo, msg_data, hello_len) == -1) -+ goto trunc; - } else { - #if INET6 -- if (is_ipv6) -- olsr_print_lq_neighbor6(ndo, msg_data, hello_len); -- else -+ if (is_ipv6) { -+ if (olsr_print_lq_neighbor6(ndo, msg_data, hello_len) == -1) -+ goto trunc; -+ } else - #endif -- olsr_print_lq_neighbor4(ndo, msg_data, hello_len); -+ { -+ if (olsr_print_lq_neighbor4(ndo, msg_data, hello_len) == -1) -+ goto trunc; -+ } - } - - msg_data += hello_len; -@@ -419,6 +442,8 @@ olsr_print(netdissect_options *ndo, - - case OLSR_TC_MSG: - case OLSR_TC_LQ_MSG: -+ if (msg_tlen < sizeof(struct olsr_tc)) -+ goto trunc; - ND_TCHECK2(*msg_data, sizeof(struct olsr_tc)); - - ptr.tc = (struct olsr_tc *)msg_data; -@@ -428,14 +453,19 @@ olsr_print(netdissect_options *ndo, - msg_tlen -= sizeof(struct olsr_tc); - - if (msg_type == OLSR_TC_MSG) { -- olsr_print_neighbor(ndo, msg_data, msg_tlen); -+ if (olsr_print_neighbor(ndo, msg_data, msg_tlen) == -1) -+ goto trunc; - } else { - #if INET6 -- if (is_ipv6) -- olsr_print_lq_neighbor6(ndo, msg_data, msg_tlen); -- else -+ if (is_ipv6) { -+ if (olsr_print_lq_neighbor6(ndo, msg_data, msg_tlen) == -1) -+ goto trunc; -+ } else - #endif -- olsr_print_lq_neighbor4(ndo, msg_data, msg_tlen); -+ { -+ if (olsr_print_lq_neighbor4(ndo, msg_data, msg_tlen) == -1) -+ goto trunc; -+ } - } - break; - --- -1.8.3.1 - diff --git a/0010-Do-bounds-checking-and-length-checking.patch b/0010-Do-bounds-checking-and-length-checking.patch deleted file mode 100644 index fff7bfb..0000000 --- a/0010-Do-bounds-checking-and-length-checking.patch +++ /dev/null @@ -1,343 +0,0 @@ -From 9255c9b05b0a04b8d89739b3efcb9f393a617fe9 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Tue, 11 Nov 2014 15:51:54 -0800 -Subject: [PATCH] Do bounds checking and length checking. - -Don't run past the end of the captured data, and don't run past the end -of the packet (i.e., don't make the length variable go negative). ---- - print-geonet.c | 270 ++++++++++++++++++++++++++++++++------------------------- - 1 file changed, 151 insertions(+), 119 deletions(-) - -diff --git a/print-geonet.c b/print-geonet.c -index d902066..edfb7f2 100644 ---- a/print-geonet.c -+++ b/print-geonet.c -@@ -56,16 +56,12 @@ static const struct tok msg_type_values[] = { - - static void - print_btp_body(netdissect_options *ndo, -- const u_char *bp, u_int length) -+ const u_char *bp) - { - int version; - int msg_type; - const char *msg_type_str; - -- if (length <= 2) { -- return; -- } -- - /* Assuming ItsDpuHeader */ - version = bp[0]; - msg_type = bp[1]; -@@ -83,7 +79,7 @@ print_btp(netdissect_options *ndo, - ND_PRINT((ndo, "; BTP Dst:%u Src:%u", dest, src)); - } - --static void -+static int - print_long_pos_vector(netdissect_options *ndo, - const u_char *bp) - { -@@ -91,10 +87,13 @@ print_long_pos_vector(netdissect_options *ndo, - - ND_PRINT((ndo, "GN_ADDR:%s ", linkaddr_string (ndo, bp, 0, GEONET_ADDR_LEN))); - -+ if (!ND_TTEST2(*(bp+12), 8)) -+ return (-1); - lat = EXTRACT_32BITS(bp+12); - ND_PRINT((ndo, "lat:%d ", lat)); - lon = EXTRACT_32BITS(bp+16); - ND_PRINT((ndo, "lon:%d", lon)); -+ return (0); - } - - -@@ -105,137 +104,170 @@ print_long_pos_vector(netdissect_options *ndo, - void - geonet_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int length) - { -+ int version; -+ int next_hdr; -+ int hdr_type; -+ int hdr_subtype; -+ uint16_t payload_length; -+ int hop_limit; -+ const char *next_hdr_txt = "Unknown"; -+ const char *hdr_type_txt = "Unknown"; -+ int hdr_size = -1; -+ - ND_PRINT((ndo, "GeoNet src:%s; ", etheraddr_string(ndo, eth+6))); - -- if (length >= 36) { -- /* Process Common Header */ -- int version = bp[0] >> 4; -- int next_hdr = bp[0] & 0x0f; -- int hdr_type = bp[1] >> 4; -- int hdr_subtype = bp[1] & 0x0f; -- uint16_t payload_length = EXTRACT_16BITS(bp+4); -- int hop_limit = bp[7]; -- const char *next_hdr_txt = "Unknown"; -- const char *hdr_type_txt = "Unknown"; -- int hdr_size = -1; -+ /* Process Common Header */ -+ if (length < 36) -+ goto malformed; -+ -+ ND_TCHECK2(*bp, 7); -+ version = bp[0] >> 4; -+ next_hdr = bp[0] & 0x0f; -+ hdr_type = bp[1] >> 4; -+ hdr_subtype = bp[1] & 0x0f; -+ payload_length = EXTRACT_16BITS(bp+4); -+ hop_limit = bp[7]; - -- switch (next_hdr) { -- case 0: next_hdr_txt = "Any"; break; -- case 1: next_hdr_txt = "BTP-A"; break; -- case 2: next_hdr_txt = "BTP-B"; break; -- case 3: next_hdr_txt = "IPv6"; break; -- } -+ switch (next_hdr) { -+ case 0: next_hdr_txt = "Any"; break; -+ case 1: next_hdr_txt = "BTP-A"; break; -+ case 2: next_hdr_txt = "BTP-B"; break; -+ case 3: next_hdr_txt = "IPv6"; break; -+ } - -- switch (hdr_type) { -- case 0: hdr_type_txt = "Any"; break; -- case 1: hdr_type_txt = "Beacon"; break; -- case 2: hdr_type_txt = "GeoUnicast"; break; -- case 3: switch (hdr_subtype) { -- case 0: hdr_type_txt = "GeoAnycastCircle"; break; -- case 1: hdr_type_txt = "GeoAnycastRect"; break; -- case 2: hdr_type_txt = "GeoAnycastElipse"; break; -- } -- break; -- case 4: switch (hdr_subtype) { -- case 0: hdr_type_txt = "GeoBroadcastCircle"; break; -- case 1: hdr_type_txt = "GeoBroadcastRect"; break; -- case 2: hdr_type_txt = "GeoBroadcastElipse"; break; -- } -- break; -- case 5: switch (hdr_subtype) { -- case 0: hdr_type_txt = "TopoScopeBcast-SH"; break; -- case 1: hdr_type_txt = "TopoScopeBcast-MH"; break; -- } -- break; -- case 6: switch (hdr_subtype) { -- case 0: hdr_type_txt = "LocService-Request"; break; -- case 1: hdr_type_txt = "LocService-Reply"; break; -- } -- break; -- } -+ switch (hdr_type) { -+ case 0: hdr_type_txt = "Any"; break; -+ case 1: hdr_type_txt = "Beacon"; break; -+ case 2: hdr_type_txt = "GeoUnicast"; break; -+ case 3: switch (hdr_subtype) { -+ case 0: hdr_type_txt = "GeoAnycastCircle"; break; -+ case 1: hdr_type_txt = "GeoAnycastRect"; break; -+ case 2: hdr_type_txt = "GeoAnycastElipse"; break; -+ } -+ break; -+ case 4: switch (hdr_subtype) { -+ case 0: hdr_type_txt = "GeoBroadcastCircle"; break; -+ case 1: hdr_type_txt = "GeoBroadcastRect"; break; -+ case 2: hdr_type_txt = "GeoBroadcastElipse"; break; -+ } -+ break; -+ case 5: switch (hdr_subtype) { -+ case 0: hdr_type_txt = "TopoScopeBcast-SH"; break; -+ case 1: hdr_type_txt = "TopoScopeBcast-MH"; break; -+ } -+ break; -+ case 6: switch (hdr_subtype) { -+ case 0: hdr_type_txt = "LocService-Request"; break; -+ case 1: hdr_type_txt = "LocService-Reply"; break; -+ } -+ break; -+ } -+ -+ ND_PRINT((ndo, "v:%d ", version)); -+ ND_PRINT((ndo, "NH:%d-%s ", next_hdr, next_hdr_txt)); -+ ND_PRINT((ndo, "HT:%d-%d-%s ", hdr_type, hdr_subtype, hdr_type_txt)); -+ ND_PRINT((ndo, "HopLim:%d ", hop_limit)); -+ ND_PRINT((ndo, "Payload:%d ", payload_length)); -+ if (print_long_pos_vector(ndo, bp + 8) == -1) -+ goto trunc; - -- ND_PRINT((ndo, "v:%d ", version)); -- ND_PRINT((ndo, "NH:%d-%s ", next_hdr, next_hdr_txt)); -- ND_PRINT((ndo, "HT:%d-%d-%s ", hdr_type, hdr_subtype, hdr_type_txt)); -- ND_PRINT((ndo, "HopLim:%d ", hop_limit)); -- ND_PRINT((ndo, "Payload:%d ", payload_length)); -- print_long_pos_vector(ndo, bp + 8); -+ /* Skip Common Header */ -+ length -= 36; -+ bp += 36; - -- /* Skip Common Header */ -- length -= 36; -- bp += 36; -+ /* Process Extended Headers */ -+ switch (hdr_type) { -+ case 0: /* Any */ -+ hdr_size = 0; -+ break; -+ case 1: /* Beacon */ -+ hdr_size = 0; -+ break; -+ case 2: /* GeoUnicast */ -+ break; -+ case 3: switch (hdr_subtype) { -+ case 0: /* GeoAnycastCircle */ -+ break; -+ case 1: /* GeoAnycastRect */ -+ break; -+ case 2: /* GeoAnycastElipse */ -+ break; -+ } -+ break; -+ case 4: switch (hdr_subtype) { -+ case 0: /* GeoBroadcastCircle */ -+ break; -+ case 1: /* GeoBroadcastRect */ -+ break; -+ case 2: /* GeoBroadcastElipse */ -+ break; -+ } -+ break; -+ case 5: switch (hdr_subtype) { -+ case 0: /* TopoScopeBcast-SH */ -+ hdr_size = 0; -+ break; -+ case 1: /* TopoScopeBcast-MH */ -+ hdr_size = 68 - 36; -+ break; -+ } -+ break; -+ case 6: switch (hdr_subtype) { -+ case 0: /* LocService-Request */ -+ break; -+ case 1: /* LocService-Reply */ -+ break; -+ } -+ break; -+ } - -- /* Process Extended Headers */ -- switch (hdr_type) { -+ /* Skip Extended headers */ -+ if (hdr_size >= 0) { -+ if (length < (u_int)hdr_size) -+ goto malformed; -+ ND_TCHECK2(*bp, hdr_size); -+ length -= hdr_size; -+ bp += hdr_size; -+ switch (next_hdr) { - case 0: /* Any */ -- hdr_size = 0; -- break; -- case 1: /* Beacon */ -- hdr_size = 0; -- break; -- case 2: /* GeoUnicast */ - break; -- case 3: switch (hdr_subtype) { -- case 0: /* GeoAnycastCircle */ -- break; -- case 1: /* GeoAnycastRect */ -- break; -- case 2: /* GeoAnycastElipse */ -- break; -+ case 1: -+ case 2: /* BTP A/B */ -+ if (length < 4) -+ goto malformed; -+ ND_TCHECK2(*bp, 4); -+ print_btp(ndo, bp); -+ length -= 4; -+ bp += 4; -+ if (length >= 2) { -+ /* -+ * XXX - did print_btp_body() -+ * return if length < 2 -+ * because this is optional, -+ * or was that just not -+ * reporting genuine errors? -+ */ -+ ND_TCHECK2(*bp, 2); -+ print_btp_body(ndo, bp); - } - break; -- case 4: switch (hdr_subtype) { -- case 0: /* GeoBroadcastCircle */ -- break; -- case 1: /* GeoBroadcastRect */ -- break; -- case 2: /* GeoBroadcastElipse */ -- break; -- } -- break; -- case 5: switch (hdr_subtype) { -- case 0: /* TopoScopeBcast-SH */ -- hdr_size = 0; -- break; -- case 1: /* TopoScopeBcast-MH */ -- hdr_size = 68 - 36; -- break; -- } -- break; -- case 6: switch (hdr_subtype) { -- case 0: /* LocService-Request */ -- break; -- case 1: /* LocService-Reply */ -- break; -- } -+ case 3: /* IPv6 */ - break; - } -- -- /* Skip Extended headers */ -- if (hdr_size >= 0) { -- length -= hdr_size; -- bp += hdr_size; -- switch (next_hdr) { -- case 0: /* Any */ -- break; -- case 1: -- case 2: /* BTP A/B */ -- print_btp(ndo, bp); -- length -= 4; -- bp += 4; -- print_btp_body(ndo, bp, length); -- break; -- case 3: /* IPv6 */ -- break; -- } -- } -- } else { -- ND_PRINT((ndo, "Malformed (small) ")); - } - - /* Print user data part */ - if (ndo->ndo_vflag) - ND_DEFAULTPRINT(bp, length); -+ return; -+ -+malformed: -+ ND_PRINT((ndo, " Malformed (small) ")); -+ /* XXX - print the remaining data as hex? */ -+ return; -+ -+trunc: -+ ND_PRINT((ndo, "[|geonet]")); - } - - --- -1.8.3.1 - diff --git a/0011-Add-initial-bounds-check-get-rid-of-union-aodv.patch b/0011-Add-initial-bounds-check-get-rid-of-union-aodv.patch deleted file mode 100644 index a7ce9e4..0000000 --- a/0011-Add-initial-bounds-check-get-rid-of-union-aodv.patch +++ /dev/null @@ -1,516 +0,0 @@ -From ab4e52b94aac6cb729a5a695aa612d5ebda2ec3a Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Tue, 11 Nov 2014 17:24:12 -0800 -Subject: [PATCH] Add initial bounds check, get rid of union aodv. - -Fetch the type field without using a structure, and check to make sure -it's not past the end of the packet. - -Pass to each dissection routine a pointer to the appropriate message -type structure, rather than a pointer to a union of all the message type -structures. ---- - print-aodv.c | 274 ++++++++++++++++++++++++++++------------------------------- - 1 file changed, 130 insertions(+), 144 deletions(-) - -diff --git a/print-aodv.c b/print-aodv.c -index 093e174..da5b169 100644 ---- a/print-aodv.c -+++ b/print-aodv.c -@@ -163,19 +163,6 @@ struct aodv_rrep_ack { - uint8_t ra_zero0; - }; - --union aodv { -- struct aodv_rreq rreq; -- struct aodv_rrep rrep; -- struct aodv_rerr rerr; -- struct aodv_rrep_ack rrep_ack; --#ifdef INET6 -- struct aodv_rreq6 rreq6; -- struct aodv_rreq6_draft_01 rreq6_draft_01; -- struct aodv_rrep6 rrep6; -- struct aodv_rrep6_draft_01 rrep6_draft_01; --#endif --}; -- - #define AODV_RREQ 1 /* route request */ - #define AODV_RREP 2 /* route response */ - #define AODV_RERR 3 /* error report */ -@@ -232,7 +219,7 @@ aodv_extension(netdissect_options *ndo, - - static void - aodv_rreq(netdissect_options *ndo, -- const union aodv *ap, const u_char *dat, u_int length) -+ const struct aodv_rreq *ap, const u_char *dat, u_int length) - { - u_int i; - -@@ -241,31 +228,31 @@ aodv_rreq(netdissect_options *ndo, - return; - } - i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(ap->rreq)) { -+ if (i < sizeof(*ap)) { - ND_PRINT((ndo, " [|rreq]")); - return; - } -- i -= sizeof(ap->rreq); -+ i -= sizeof(*ap); - ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n" - "\tdst %s seq %lu src %s seq %lu", length, -- ap->rreq.rreq_type & RREQ_JOIN ? "[J]" : "", -- ap->rreq.rreq_type & RREQ_REPAIR ? "[R]" : "", -- ap->rreq.rreq_type & RREQ_GRAT ? "[G]" : "", -- ap->rreq.rreq_type & RREQ_DEST ? "[D]" : "", -- ap->rreq.rreq_type & RREQ_UNKNOWN ? "[U] " : " ", -- ap->rreq.rreq_hops, -- (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_id), -- ipaddr_string(ndo, &ap->rreq.rreq_da), -- (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_ds), -- ipaddr_string(ndo, &ap->rreq.rreq_oa), -- (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_os))); -+ ap->rreq_type & RREQ_JOIN ? "[J]" : "", -+ ap->rreq_type & RREQ_REPAIR ? "[R]" : "", -+ ap->rreq_type & RREQ_GRAT ? "[G]" : "", -+ ap->rreq_type & RREQ_DEST ? "[D]" : "", -+ ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", -+ ap->rreq_hops, -+ (unsigned long)EXTRACT_32BITS(&ap->rreq_id), -+ ipaddr_string(ndo, &ap->rreq_da), -+ (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), -+ ipaddr_string(ndo, &ap->rreq_oa), -+ (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); - if (i >= sizeof(struct aodv_ext)) -- aodv_extension(ndo, (void *)(&ap->rreq + 1), i); -+ aodv_extension(ndo, (void *)(ap + 1), i); - } - - static void - aodv_rrep(netdissect_options *ndo, -- const union aodv *ap, const u_char *dat, u_int length) -+ const struct aodv_rrep *ap, const u_char *dat, u_int length) - { - u_int i; - -@@ -274,28 +261,28 @@ aodv_rrep(netdissect_options *ndo, - return; - } - i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(ap->rrep)) { -+ if (i < sizeof(*ap)) { - ND_PRINT((ndo, " [|rrep]")); - return; - } -- i -= sizeof(ap->rrep); -+ i -= sizeof(*ap); - ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" - "\tdst %s dseq %lu src %s %lu ms", length, -- ap->rrep.rrep_type & RREP_REPAIR ? "[R]" : "", -- ap->rrep.rrep_type & RREP_ACK ? "[A] " : " ", -- ap->rrep.rrep_ps & RREP_PREFIX_MASK, -- ap->rrep.rrep_hops, -- ipaddr_string(ndo, &ap->rrep.rrep_da), -- (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_ds), -- ipaddr_string(ndo, &ap->rrep.rrep_oa), -- (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_life))); -+ ap->rrep_type & RREP_REPAIR ? "[R]" : "", -+ ap->rrep_type & RREP_ACK ? "[A] " : " ", -+ ap->rrep_ps & RREP_PREFIX_MASK, -+ ap->rrep_hops, -+ ipaddr_string(ndo, &ap->rrep_da), -+ (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), -+ ipaddr_string(ndo, &ap->rrep_oa), -+ (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); - if (i >= sizeof(struct aodv_ext)) -- aodv_extension(ndo, (void *)(&ap->rrep + 1), i); -+ aodv_extension(ndo, (void *)(ap + 1), i); - } - - static void - aodv_rerr(netdissect_options *ndo, -- const union aodv *ap, const u_char *dat, u_int length) -+ const struct aodv_rerr *ap, const u_char *dat, u_int length) - { - u_int i; - const struct rerr_unreach *dp = NULL; -@@ -311,14 +298,14 @@ aodv_rerr(netdissect_options *ndo, - return; - } - i -= offsetof(struct aodv_rerr, r); -- dp = &ap->rerr.r.dest[0]; -- n = ap->rerr.rerr_dc * sizeof(ap->rerr.r.dest[0]); -+ dp = &ap->r.dest[0]; -+ n = ap->rerr_dc * sizeof(ap->r.dest[0]); - ND_PRINT((ndo, " rerr %s [items %u] [%u]:", -- ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "", -- ap->rerr.rerr_dc, length)); -- trunc = n - (i/sizeof(ap->rerr.r.dest[0])); -- for (; i >= sizeof(ap->rerr.r.dest[0]); -- ++dp, i -= sizeof(ap->rerr.r.dest[0])) { -+ ap->rerr_flags & RERR_NODELETE ? "[D]" : "", -+ ap->rerr_dc, length)); -+ trunc = n - (i/sizeof(ap->r.dest[0])); -+ for (; i >= sizeof(ap->r.dest[0]); -+ ++dp, i -= sizeof(ap->r.dest[0])) { - ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da), - (unsigned long)EXTRACT_32BITS(&dp->u_ds))); - } -@@ -329,10 +316,10 @@ aodv_rerr(netdissect_options *ndo, - static void - #ifdef INET6 - aodv_v6_rreq(netdissect_options *ndo, -- const union aodv *ap, const u_char *dat, u_int length) -+ const struct aodv_rreq6 *ap, const u_char *dat, u_int length) - #else - aodv_v6_rreq(netdissect_options *ndo, -- const union aodv *ap _U_, const u_char *dat _U_, u_int length) -+ const struct aodv_rreq6 *ap _U_, const u_char *dat _U_, u_int length) - #endif - { - #ifdef INET6 -@@ -343,26 +330,26 @@ aodv_v6_rreq(netdissect_options *ndo, - return; - } - i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(ap->rreq6)) { -+ if (i < sizeof(*ap)) { - ND_PRINT((ndo, " [|rreq6]")); - return; - } -- i -= sizeof(ap->rreq6); -+ i -= sizeof(*ap); - ND_PRINT((ndo, " v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n" - "\tdst %s seq %lu src %s seq %lu", length, -- ap->rreq6.rreq_type & RREQ_JOIN ? "[J]" : "", -- ap->rreq6.rreq_type & RREQ_REPAIR ? "[R]" : "", -- ap->rreq6.rreq_type & RREQ_GRAT ? "[G]" : "", -- ap->rreq6.rreq_type & RREQ_DEST ? "[D]" : "", -- ap->rreq6.rreq_type & RREQ_UNKNOWN ? "[U] " : " ", -- ap->rreq6.rreq_hops, -- (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_id), -- ip6addr_string(ndo, &ap->rreq6.rreq_da), -- (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_ds), -- ip6addr_string(ndo, &ap->rreq6.rreq_oa), -- (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_os))); -+ ap->rreq_type & RREQ_JOIN ? "[J]" : "", -+ ap->rreq_type & RREQ_REPAIR ? "[R]" : "", -+ ap->rreq_type & RREQ_GRAT ? "[G]" : "", -+ ap->rreq_type & RREQ_DEST ? "[D]" : "", -+ ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", -+ ap->rreq_hops, -+ (unsigned long)EXTRACT_32BITS(&ap->rreq_id), -+ ip6addr_string(ndo, &ap->rreq_da), -+ (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), -+ ip6addr_string(ndo, &ap->rreq_oa), -+ (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); - if (i >= sizeof(struct aodv_ext)) -- aodv_extension(ndo, (void *)(&ap->rreq6 + 1), i); -+ aodv_extension(ndo, (void *)(ap + 1), i); - #else - ND_PRINT((ndo, " v6 rreq %u", length)); - #endif -@@ -371,10 +358,10 @@ aodv_v6_rreq(netdissect_options *ndo, - static void - #ifdef INET6 - aodv_v6_rrep(netdissect_options *ndo, -- const union aodv *ap, const u_char *dat, u_int length) -+ const struct aodv_rrep6 *ap, const u_char *dat, u_int length) - #else - aodv_v6_rrep(netdissect_options *ndo, -- const union aodv *ap _U_, const u_char *dat _U_, u_int length) -+ const struct aodv_rrep6 *ap _U_, const u_char *dat _U_, u_int length) - #endif - { - #ifdef INET6 -@@ -385,23 +372,23 @@ aodv_v6_rrep(netdissect_options *ndo, - return; - } - i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(ap->rrep6)) { -+ if (i < sizeof(*ap)) { - ND_PRINT((ndo, " [|rrep6]")); - return; - } -- i -= sizeof(ap->rrep6); -+ i -= sizeof(*ap); - ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" - "\tdst %s dseq %lu src %s %lu ms", length, -- ap->rrep6.rrep_type & RREP_REPAIR ? "[R]" : "", -- ap->rrep6.rrep_type & RREP_ACK ? "[A] " : " ", -- ap->rrep6.rrep_ps & RREP_PREFIX_MASK, -- ap->rrep6.rrep_hops, -- ip6addr_string(ndo, &ap->rrep6.rrep_da), -- (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_ds), -- ip6addr_string(ndo, &ap->rrep6.rrep_oa), -- (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_life))); -+ ap->rrep_type & RREP_REPAIR ? "[R]" : "", -+ ap->rrep_type & RREP_ACK ? "[A] " : " ", -+ ap->rrep_ps & RREP_PREFIX_MASK, -+ ap->rrep_hops, -+ ip6addr_string(ndo, &ap->rrep_da), -+ (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), -+ ip6addr_string(ndo, &ap->rrep_oa), -+ (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); - if (i >= sizeof(struct aodv_ext)) -- aodv_extension(ndo, (void *)(&ap->rrep6 + 1), i); -+ aodv_extension(ndo, (void *)(ap + 1), i); - #else - ND_PRINT((ndo, " rrep %u", length)); - #endif -@@ -410,10 +397,10 @@ aodv_v6_rrep(netdissect_options *ndo, - static void - #ifdef INET6 - aodv_v6_rerr(netdissect_options *ndo, -- const union aodv *ap, u_int length) -+ const struct aodv_rerr *ap, u_int length) - #else - aodv_v6_rerr(netdissect_options *ndo, -- const union aodv *ap _U_, u_int length) -+ const struct aodv_rerr *ap _U_, u_int length) - #endif - { - #ifdef INET6 -@@ -421,12 +408,12 @@ aodv_v6_rerr(netdissect_options *ndo, - int i, j, n, trunc; - - i = length - offsetof(struct aodv_rerr, r); -- j = sizeof(ap->rerr.r.dest6[0]); -- dp6 = &ap->rerr.r.dest6[0]; -- n = ap->rerr.rerr_dc * j; -+ j = sizeof(ap->r.dest6[0]); -+ dp6 = &ap->r.dest6[0]; -+ n = ap->rerr_dc * j; - ND_PRINT((ndo, " rerr %s [items %u] [%u]:", -- ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "", -- ap->rerr.rerr_dc, length)); -+ ap->rerr_flags & RERR_NODELETE ? "[D]" : "", -+ ap->rerr_dc, length)); - trunc = n - (i/j); - for (; i -= j >= 0; ++dp6) { - ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), -@@ -442,11 +429,10 @@ aodv_v6_rerr(netdissect_options *ndo, - static void - #ifdef INET6 - aodv_v6_draft_01_rreq(netdissect_options *ndo, -- const union aodv *ap, const u_char *dat, u_int length) -+ const struct aodv_rreq6_draft_01 *ap, const u_char *dat, u_int length) - #else - aodv_v6_draft_01_rreq(netdissect_options *ndo, -- const union aodv *ap _U_, const u_char *dat _U_, -- u_int length) -+ const struct aodv_rreq6_draft_01 *ap _U_, const u_char *dat _U_, u_int length) - #endif - { - #ifdef INET6 -@@ -457,26 +443,26 @@ aodv_v6_draft_01_rreq(netdissect_options *ndo, - return; - } - i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(ap->rreq6_draft_01)) { -+ if (i < sizeof(*ap)) { - ND_PRINT((ndo, " [|rreq6]")); - return; - } -- i -= sizeof(ap->rreq6_draft_01); -+ i -= sizeof(*ap); - ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n" - "\tdst %s seq %lu src %s seq %lu", length, -- ap->rreq6_draft_01.rreq_type & RREQ_JOIN ? "[J]" : "", -- ap->rreq6_draft_01.rreq_type & RREQ_REPAIR ? "[R]" : "", -- ap->rreq6_draft_01.rreq_type & RREQ_GRAT ? "[G]" : "", -- ap->rreq6_draft_01.rreq_type & RREQ_DEST ? "[D]" : "", -- ap->rreq6_draft_01.rreq_type & RREQ_UNKNOWN ? "[U] " : " ", -- ap->rreq6_draft_01.rreq_hops, -- (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_id), -- ip6addr_string(ndo, &ap->rreq6_draft_01.rreq_da), -- (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_ds), -- ip6addr_string(ndo, &ap->rreq6_draft_01.rreq_oa), -- (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_os))); -+ ap->rreq_type & RREQ_JOIN ? "[J]" : "", -+ ap->rreq_type & RREQ_REPAIR ? "[R]" : "", -+ ap->rreq_type & RREQ_GRAT ? "[G]" : "", -+ ap->rreq_type & RREQ_DEST ? "[D]" : "", -+ ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", -+ ap->rreq_hops, -+ (unsigned long)EXTRACT_32BITS(&ap->rreq_id), -+ ip6addr_string(ndo, &ap->rreq_da), -+ (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), -+ ip6addr_string(ndo, &ap->rreq_oa), -+ (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); - if (i >= sizeof(struct aodv_ext)) -- aodv_extension(ndo, (void *)(&ap->rreq6_draft_01 + 1), i); -+ aodv_extension(ndo, (void *)(ap + 1), i); - #else - ND_PRINT((ndo, " rreq %u", length)); - #endif -@@ -485,11 +471,10 @@ aodv_v6_draft_01_rreq(netdissect_options *ndo, - static void - #ifdef INET6 - aodv_v6_draft_01_rrep(netdissect_options *ndo, -- const union aodv *ap, const u_char *dat, u_int length) -+ const struct aodv_rrep6_draft_01 *ap, const u_char *dat, u_int length) - #else - aodv_v6_draft_01_rrep(netdissect_options *ndo, -- const union aodv *ap _U_, const u_char *dat _U_, -- u_int length) -+ const struct aodv_rrep6_draft_01 *ap _U_, const u_char *dat _U_, u_int length) - #endif - { - #ifdef INET6 -@@ -500,23 +485,23 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo, - return; - } - i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(ap->rrep6_draft_01)) { -+ if (i < sizeof(*ap)) { - ND_PRINT((ndo, " [|rrep6]")); - return; - } -- i -= sizeof(ap->rrep6_draft_01); -+ i -= sizeof(*ap); - ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" - "\tdst %s dseq %lu src %s %lu ms", length, -- ap->rrep6_draft_01.rrep_type & RREP_REPAIR ? "[R]" : "", -- ap->rrep6_draft_01.rrep_type & RREP_ACK ? "[A] " : " ", -- ap->rrep6_draft_01.rrep_ps & RREP_PREFIX_MASK, -- ap->rrep6_draft_01.rrep_hops, -- ip6addr_string(ndo, &ap->rrep6_draft_01.rrep_da), -- (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_ds), -- ip6addr_string(ndo, &ap->rrep6_draft_01.rrep_oa), -- (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_life))); -+ ap->rrep_type & RREP_REPAIR ? "[R]" : "", -+ ap->rrep_type & RREP_ACK ? "[A] " : " ", -+ ap->rrep_ps & RREP_PREFIX_MASK, -+ ap->rrep_hops, -+ ip6addr_string(ndo, &ap->rrep_da), -+ (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), -+ ip6addr_string(ndo, &ap->rrep_oa), -+ (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); - if (i >= sizeof(struct aodv_ext)) -- aodv_extension(ndo, (void *)(&ap->rrep6_draft_01 + 1), i); -+ aodv_extension(ndo, (void *)(ap + 1), i); - #else - ND_PRINT((ndo, " rrep %u", length)); - #endif -@@ -525,10 +510,10 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo, - static void - #ifdef INET6 - aodv_v6_draft_01_rerr(netdissect_options *ndo, -- const union aodv *ap, u_int length) -+ const struct aodv_rerr *ap, u_int length) - #else - aodv_v6_draft_01_rerr(netdissect_options *ndo, -- const union aodv *ap _U_, u_int length) -+ const struct aodv_rerr *ap _U_, u_int length) - #endif - { - #ifdef INET6 -@@ -536,12 +521,12 @@ aodv_v6_draft_01_rerr(netdissect_options *ndo, - int i, j, n, trunc; - - i = length - offsetof(struct aodv_rerr, r); -- j = sizeof(ap->rerr.r.dest6_draft_01[0]); -- dp6 = &ap->rerr.r.dest6_draft_01[0]; -- n = ap->rerr.rerr_dc * j; -+ j = sizeof(ap->r.dest6_draft_01[0]); -+ dp6 = &ap->r.dest6_draft_01[0]; -+ n = ap->rerr_dc * j; - ND_PRINT((ndo, " rerr %s [items %u] [%u]:", -- ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "", -- ap->rerr.rerr_dc, length)); -+ ap->rerr_flags & RERR_NODELETE ? "[D]" : "", -+ ap->rerr_dc, length)); - trunc = n - (i/j); - for (; i -= j >= 0; ++dp6) { - ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), -@@ -558,40 +543,37 @@ void - aodv_print(netdissect_options *ndo, - const u_char *dat, u_int length, int is_ip6) - { -- const union aodv *ap; -- -- ap = (union aodv *)dat; -- if (ndo->ndo_snapend < dat) { -- ND_PRINT((ndo, " [|aodv]")); -- return; -- } -- if (min(length, (u_int)(ndo->ndo_snapend - dat)) < sizeof(ap->rrep_ack)) { -- ND_PRINT((ndo, " [|aodv]")); -- return; -- } -+ uint8_t msg_type; -+ -+ /* -+ * The message type is the first byte; make sure we have it -+ * and then fetch it. -+ */ -+ ND_TCHECK(*dat); -+ msg_type = *dat; - ND_PRINT((ndo, " aodv")); - -- switch (ap->rerr.rerr_type) { -+ switch (msg_type) { - - case AODV_RREQ: - if (is_ip6) -- aodv_v6_rreq(ndo, ap, dat, length); -+ aodv_v6_rreq(ndo, (const struct aodv_rreq6 *)dat, dat, length); - else -- aodv_rreq(ndo, ap, dat, length); -+ aodv_rreq(ndo, (const struct aodv_rreq *)dat, dat, length); - break; - - case AODV_RREP: - if (is_ip6) -- aodv_v6_rrep(ndo, ap, dat, length); -+ aodv_v6_rrep(ndo, (const struct aodv_rrep6 *)dat, dat, length); - else -- aodv_rrep(ndo, ap, dat, length); -+ aodv_rrep(ndo, (const struct aodv_rrep *)dat, dat, length); - break; - - case AODV_RERR: - if (is_ip6) -- aodv_v6_rerr(ndo, ap, length); -+ aodv_v6_rerr(ndo, (const struct aodv_rerr *)dat, length); - else -- aodv_rerr(ndo, ap, dat, length); -+ aodv_rerr(ndo, (const struct aodv_rerr *)dat, dat, length); - break; - - case AODV_RREP_ACK: -@@ -599,15 +581,15 @@ aodv_print(netdissect_options *ndo, - break; - - case AODV_V6_DRAFT_01_RREQ: -- aodv_v6_draft_01_rreq(ndo, ap, dat, length); -+ aodv_v6_draft_01_rreq(ndo, (const struct aodv_rreq6_draft_01 *)dat, dat, length); - break; - - case AODV_V6_DRAFT_01_RREP: -- aodv_v6_draft_01_rrep(ndo, ap, dat, length); -+ aodv_v6_draft_01_rrep(ndo, (const struct aodv_rrep6_draft_01 *)dat, dat, length); - break; - - case AODV_V6_DRAFT_01_RERR: -- aodv_v6_draft_01_rerr(ndo, ap, length); -+ aodv_v6_draft_01_rerr(ndo, (const struct aodv_rerr *)dat, length); - break; - - case AODV_V6_DRAFT_01_RREP_ACK: -@@ -615,6 +597,10 @@ aodv_print(netdissect_options *ndo, - break; - - default: -- ND_PRINT((ndo, " %u %u", ap->rreq.rreq_type, length)); -+ ND_PRINT((ndo, " type %u %u", msg_type, length)); - } -+ return; -+ -+trunc: -+ ND_PRINT((ndo, " [|aodv]")); - } --- -1.8.3.1 - diff --git a/0012-Clean-up-error-message-printing.patch b/0012-Clean-up-error-message-printing.patch deleted file mode 100644 index 02d8958..0000000 --- a/0012-Clean-up-error-message-printing.patch +++ /dev/null @@ -1,190 +0,0 @@ -From 3e8a443c3671baa37ae7870f08fb9b4bf386fd24 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Tue, 11 Nov 2014 18:37:35 -0800 -Subject: [PATCH 1/4] Clean up error message printing. - -Have "struct aodv_rerr" just be the header, not including the actual -destinations. - -Simplify the logic somewhat, and make it similar in the print routines -for the three types of error messages. ---- - print-aodv.c | 88 +++++++++++++++++++++++++++++++----------------------------- - 1 file changed, 46 insertions(+), 42 deletions(-) - -diff --git a/print-aodv.c b/print-aodv.c -index da5b169..da26473 100644 ---- a/print-aodv.c -+++ b/print-aodv.c -@@ -146,13 +146,6 @@ struct aodv_rerr { - uint8_t rerr_flags; /* various flags */ - uint8_t rerr_zero0; /* reserved, set to zero */ - uint8_t rerr_dc; /* destination count */ -- union { -- struct rerr_unreach dest[1]; --#ifdef INET6 -- struct rerr_unreach6 dest6[1]; -- struct rerr_unreach6_draft_01 dest6_draft_01[1]; --#endif -- } r; - }; - - #define RERR_NODELETE 0x80 /* don't delete the link */ -@@ -284,32 +277,29 @@ static void - aodv_rerr(netdissect_options *ndo, - const struct aodv_rerr *ap, const u_char *dat, u_int length) - { -- u_int i; -- const struct rerr_unreach *dp = NULL; -- int n, trunc; -+ u_int i, dc; -+ const struct rerr_unreach *dp; - - if (ndo->ndo_snapend < dat) { - ND_PRINT((ndo, " [|aodv]")); - return; - } - i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < offsetof(struct aodv_rerr, r)) { -+ if (i < sizeof(*ap)) { - ND_PRINT((ndo, " [|rerr]")); - return; - } -- i -= offsetof(struct aodv_rerr, r); -- dp = &ap->r.dest[0]; -- n = ap->rerr_dc * sizeof(ap->r.dest[0]); -+ i -= sizeof(*ap); - ND_PRINT((ndo, " rerr %s [items %u] [%u]:", - ap->rerr_flags & RERR_NODELETE ? "[D]" : "", - ap->rerr_dc, length)); -- trunc = n - (i/sizeof(ap->r.dest[0])); -- for (; i >= sizeof(ap->r.dest[0]); -- ++dp, i -= sizeof(ap->r.dest[0])) { -+ dp = (struct rerr_unreach *)(void *)(ap + 1); -+ for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp); -+ ++dp, --dc, i -= sizeof(*dp)) { - ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da), - (unsigned long)EXTRACT_32BITS(&dp->u_ds))); - } -- if (trunc) -+ if ((i % sizeof(*dp)) != 0) - ND_PRINT((ndo, "[|rerr]")); - } - -@@ -397,29 +387,36 @@ aodv_v6_rrep(netdissect_options *ndo, - static void - #ifdef INET6 - aodv_v6_rerr(netdissect_options *ndo, -- const struct aodv_rerr *ap, u_int length) -+ const struct aodv_rerr *ap, const u_char *dat, u_int length) - #else - aodv_v6_rerr(netdissect_options *ndo, -- const struct aodv_rerr *ap _U_, u_int length) -+ const struct aodv_rerr *ap _U_, const u_char *dat, u_int length) - #endif - { - #ifdef INET6 -- const struct rerr_unreach6 *dp6 = NULL; -- int i, j, n, trunc; -+ u_int i, dc; -+ const struct rerr_unreach6 *dp6; - -- i = length - offsetof(struct aodv_rerr, r); -- j = sizeof(ap->r.dest6[0]); -- dp6 = &ap->r.dest6[0]; -- n = ap->rerr_dc * j; -+ if (ndo->ndo_snapend < dat) { -+ ND_PRINT((ndo, " [|aodv]")); -+ return; -+ } -+ i = min(length, (u_int)(ndo->ndo_snapend - dat)); -+ if (i < sizeof(*ap)) { -+ ND_PRINT((ndo, " [|rerr]")); -+ return; -+ } -+ i -= sizeof(*ap); - ND_PRINT((ndo, " rerr %s [items %u] [%u]:", - ap->rerr_flags & RERR_NODELETE ? "[D]" : "", - ap->rerr_dc, length)); -- trunc = n - (i/j); -- for (; i -= j >= 0; ++dp6) { -+ dp6 = (struct rerr_unreach6 *)(void *)(ap + 1); -+ for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6); -+ ++dp6, --dc, i -= sizeof(*dp6)) { - ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), - (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); - } -- if (trunc) -+ if ((i % sizeof(*dp6)) != 0) - ND_PRINT((ndo, "[|rerr]")); - #else - ND_PRINT((ndo, " rerr %u", length)); -@@ -510,29 +507,36 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo, - static void - #ifdef INET6 - aodv_v6_draft_01_rerr(netdissect_options *ndo, -- const struct aodv_rerr *ap, u_int length) -+ const struct aodv_rerr *ap, const u_char *dat, u_int length) - #else - aodv_v6_draft_01_rerr(netdissect_options *ndo, -- const struct aodv_rerr *ap _U_, u_int length) -+ const struct aodv_rerr *ap _U_, const u_char *dat, u_int length) - #endif - { - #ifdef INET6 -- const struct rerr_unreach6_draft_01 *dp6 = NULL; -- int i, j, n, trunc; -+ u_int i, dc; -+ const struct rerr_unreach6_draft_01 *dp6; - -- i = length - offsetof(struct aodv_rerr, r); -- j = sizeof(ap->r.dest6_draft_01[0]); -- dp6 = &ap->r.dest6_draft_01[0]; -- n = ap->rerr_dc * j; -+ if (ndo->ndo_snapend < dat) { -+ ND_PRINT((ndo, " [|aodv]")); -+ return; -+ } -+ i = min(length, (u_int)(ndo->ndo_snapend - dat)); -+ if (i < sizeof(*ap)) { -+ ND_PRINT((ndo, " [|rerr]")); -+ return; -+ } -+ i -= sizeof(*ap); - ND_PRINT((ndo, " rerr %s [items %u] [%u]:", - ap->rerr_flags & RERR_NODELETE ? "[D]" : "", - ap->rerr_dc, length)); -- trunc = n - (i/j); -- for (; i -= j >= 0; ++dp6) { -+ dp6 = (struct rerr_unreach6_draft_01 *)(void *)(ap + 1); -+ for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6); -+ ++dp6, --dc, i -= sizeof(*dp6)) { - ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), - (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); - } -- if (trunc) -+ if ((i % sizeof(*dp6)) != 0) - ND_PRINT((ndo, "[|rerr]")); - #else - ND_PRINT((ndo, " rerr %u", length)); -@@ -571,7 +575,7 @@ aodv_print(netdissect_options *ndo, - - case AODV_RERR: - if (is_ip6) -- aodv_v6_rerr(ndo, (const struct aodv_rerr *)dat, length); -+ aodv_v6_rerr(ndo, (const struct aodv_rerr *)dat, dat, length); - else - aodv_rerr(ndo, (const struct aodv_rerr *)dat, dat, length); - break; -@@ -589,7 +593,7 @@ aodv_print(netdissect_options *ndo, - break; - - case AODV_V6_DRAFT_01_RERR: -- aodv_v6_draft_01_rerr(ndo, (const struct aodv_rerr *)dat, length); -+ aodv_v6_draft_01_rerr(ndo, (const struct aodv_rerr *)dat, dat, length); - break; - - case AODV_V6_DRAFT_01_RREP_ACK: --- -1.8.3.1 - diff --git a/0013-Further-cleanups.patch b/0013-Further-cleanups.patch deleted file mode 100644 index 1b8c653..0000000 --- a/0013-Further-cleanups.patch +++ /dev/null @@ -1,524 +0,0 @@ -From e302ff0e4a6bde6915bee1c89373aa14c823dd60 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Tue, 11 Nov 2014 19:05:48 -0800 -Subject: [PATCH 2/4] Further cleanups. - -Use ND_TCHECK() rather than home-brew bounds checks. Do simpler length -checks. - -Let i be the length of the actual remaining packet data; use ND_TCHECK() -inside loops that iterate over the remaining data. - -Let the printers for particular message types cast the raw data pointer -to a pointer of the appropriate type, rather than passing two pointers, -with different types, to the same data. ---- - print-aodv.c | 277 +++++++++++++++++++++++++++-------------------------------- - 1 file changed, 126 insertions(+), 151 deletions(-) - -diff --git a/print-aodv.c b/print-aodv.c -index da26473..2649936 100644 ---- a/print-aodv.c -+++ b/print-aodv.c -@@ -184,22 +184,14 @@ static void - aodv_extension(netdissect_options *ndo, - const struct aodv_ext *ep, u_int length) - { -- u_int i; - const struct aodv_hello *ah; - - switch (ep->type) { - case AODV_EXT_HELLO: -- if (ndo->ndo_snapend < (u_char *) ep) { -- ND_PRINT((ndo, " [|hello]")); -- return; -- } -- i = min(length, (u_int)(ndo->ndo_snapend - (u_char *)ep)); -- if (i < sizeof(struct aodv_hello)) { -- ND_PRINT((ndo, " [|hello]")); -- return; -- } -- i -= sizeof(struct aodv_hello); -- ah = (void *)ep; -+ ah = (const struct aodv_hello *)(const void *)ep; -+ ND_TCHECK(*ah); -+ if (length < sizeof(struct aodv_hello)) -+ goto trunc; - ND_PRINT((ndo, "\n\text HELLO %ld ms", - (unsigned long)EXTRACT_32BITS(&ah->interval))); - break; -@@ -208,24 +200,21 @@ aodv_extension(netdissect_options *ndo, - ND_PRINT((ndo, "\n\text %u %u", ep->type, ep->length)); - break; - } -+ return; -+ -+trunc: -+ ND_PRINT((ndo, " [|hello]")); - } - - static void --aodv_rreq(netdissect_options *ndo, -- const struct aodv_rreq *ap, const u_char *dat, u_int length) -+aodv_rreq(netdissect_options *ndo, const u_char *dat, u_int length) - { - u_int i; -+ const struct aodv_rreq *ap = (const struct aodv_rreq *)dat; - -- if (ndo->ndo_snapend < dat) { -- ND_PRINT((ndo, " [|aodv]")); -- return; -- } -- i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(*ap)) { -- ND_PRINT((ndo, " [|rreq]")); -- return; -- } -- i -= sizeof(*ap); -+ ND_TCHECK(*ap); -+ if (length < sizeof(*ap)) -+ goto trunc; - ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n" - "\tdst %s seq %lu src %s seq %lu", length, - ap->rreq_type & RREQ_JOIN ? "[J]" : "", -@@ -239,26 +228,24 @@ aodv_rreq(netdissect_options *ndo, - (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), - ipaddr_string(ndo, &ap->rreq_oa), - (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); -+ i = length - sizeof(*ap); - if (i >= sizeof(struct aodv_ext)) -- aodv_extension(ndo, (void *)(ap + 1), i); -+ aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); -+ return; -+ -+trunc: -+ ND_PRINT((ndo, " [|rreq")); - } - - static void --aodv_rrep(netdissect_options *ndo, -- const struct aodv_rrep *ap, const u_char *dat, u_int length) -+aodv_rrep(netdissect_options *ndo, const u_char *dat, u_int length) - { - u_int i; -+ const struct aodv_rrep *ap = (const struct aodv_rrep *)dat; - -- if (ndo->ndo_snapend < dat) { -- ND_PRINT((ndo, " [|aodv]")); -- return; -- } -- i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(*ap)) { -- ND_PRINT((ndo, " [|rrep]")); -- return; -- } -- i -= sizeof(*ap); -+ ND_TCHECK(*ap); -+ if (length < sizeof(*ap)) -+ goto trunc; - ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" - "\tdst %s dseq %lu src %s %lu ms", length, - ap->rrep_type & RREP_REPAIR ? "[R]" : "", -@@ -269,62 +256,58 @@ aodv_rrep(netdissect_options *ndo, - (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), - ipaddr_string(ndo, &ap->rrep_oa), - (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); -+ i = length - sizeof(*ap); - if (i >= sizeof(struct aodv_ext)) -- aodv_extension(ndo, (void *)(ap + 1), i); -+ aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); -+ return; -+ -+trunc: -+ ND_PRINT((ndo, " [|rreq")); - } - - static void --aodv_rerr(netdissect_options *ndo, -- const struct aodv_rerr *ap, const u_char *dat, u_int length) -+aodv_rerr(netdissect_options *ndo, const u_char *dat, u_int length) - { - u_int i, dc; -+ const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; - const struct rerr_unreach *dp; - -- if (ndo->ndo_snapend < dat) { -- ND_PRINT((ndo, " [|aodv]")); -- return; -- } -- i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(*ap)) { -- ND_PRINT((ndo, " [|rerr]")); -- return; -- } -- i -= sizeof(*ap); -+ ND_TCHECK(*ap); -+ if (length < sizeof(*ap)) -+ goto trunc; - ND_PRINT((ndo, " rerr %s [items %u] [%u]:", - ap->rerr_flags & RERR_NODELETE ? "[D]" : "", - ap->rerr_dc, length)); -- dp = (struct rerr_unreach *)(void *)(ap + 1); -+ dp = (struct rerr_unreach *)(dat + sizeof(*ap)); -+ i = length - sizeof(*ap); - for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp); - ++dp, --dc, i -= sizeof(*dp)) { -+ ND_TCHECK(*dp); - ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da), - (unsigned long)EXTRACT_32BITS(&dp->u_ds))); - } - if ((i % sizeof(*dp)) != 0) -- ND_PRINT((ndo, "[|rerr]")); -+ goto trunc; -+ return; -+ -+trunc: -+ ND_PRINT((ndo, "[|rerr]")); - } - - static void - #ifdef INET6 --aodv_v6_rreq(netdissect_options *ndo, -- const struct aodv_rreq6 *ap, const u_char *dat, u_int length) -+aodv_v6_rreq(netdissect_options *ndo, const u_char *dat, u_int length) - #else --aodv_v6_rreq(netdissect_options *ndo, -- const struct aodv_rreq6 *ap _U_, const u_char *dat _U_, u_int length) -+aodv_v6_rreq(netdissect_options *ndo, const u_char *dat _U_, u_int length) - #endif - { - #ifdef INET6 - u_int i; -+ const struct aodv_rreq6 *ap = (const struct aodv_rreq6 *)dat; - -- if (ndo->ndo_snapend < dat) { -- ND_PRINT((ndo, " [|aodv]")); -- return; -- } -- i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(*ap)) { -- ND_PRINT((ndo, " [|rreq6]")); -- return; -- } -- i -= sizeof(*ap); -+ ND_TCHECK(*ap); -+ if (length < sizeof(*ap)) -+ goto trunc; - ND_PRINT((ndo, " v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n" - "\tdst %s seq %lu src %s seq %lu", length, - ap->rreq_type & RREQ_JOIN ? "[J]" : "", -@@ -338,8 +321,13 @@ aodv_v6_rreq(netdissect_options *ndo, - (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), - ip6addr_string(ndo, &ap->rreq_oa), - (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); -+ i = length - sizeof(*ap); - if (i >= sizeof(struct aodv_ext)) -- aodv_extension(ndo, (void *)(ap + 1), i); -+ aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); -+ return; -+ -+trunc: -+ ND_PRINT((ndo, " [|rreq")); - #else - ND_PRINT((ndo, " v6 rreq %u", length)); - #endif -@@ -347,26 +335,18 @@ aodv_v6_rreq(netdissect_options *ndo, - - static void - #ifdef INET6 --aodv_v6_rrep(netdissect_options *ndo, -- const struct aodv_rrep6 *ap, const u_char *dat, u_int length) -+aodv_v6_rrep(netdissect_options *ndo, const u_char *dat, u_int length) - #else --aodv_v6_rrep(netdissect_options *ndo, -- const struct aodv_rrep6 *ap _U_, const u_char *dat _U_, u_int length) -+aodv_v6_rrep(netdissect_options *ndo, const u_char *dat _U_, u_int length) - #endif - { - #ifdef INET6 - u_int i; -+ const struct aodv_rrep6 *ap = (const struct aodv_rrep6 *)dat; - -- if (ndo->ndo_snapend < dat) { -- ND_PRINT((ndo, " [|aodv]")); -- return; -- } -- i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(*ap)) { -- ND_PRINT((ndo, " [|rrep6]")); -- return; -- } -- i -= sizeof(*ap); -+ ND_TCHECK(*ap); -+ if (length < sizeof(*ap)) -+ goto trunc; - ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" - "\tdst %s dseq %lu src %s %lu ms", length, - ap->rrep_type & RREP_REPAIR ? "[R]" : "", -@@ -377,8 +357,13 @@ aodv_v6_rrep(netdissect_options *ndo, - (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), - ip6addr_string(ndo, &ap->rrep_oa), - (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); -+ i = length - sizeof(*ap); - if (i >= sizeof(struct aodv_ext)) -- aodv_extension(ndo, (void *)(ap + 1), i); -+ aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); -+ return; -+ -+trunc: -+ ND_PRINT((ndo, " [|rreq")); - #else - ND_PRINT((ndo, " rrep %u", length)); - #endif -@@ -386,38 +371,36 @@ aodv_v6_rrep(netdissect_options *ndo, - - static void - #ifdef INET6 --aodv_v6_rerr(netdissect_options *ndo, -- const struct aodv_rerr *ap, const u_char *dat, u_int length) -+aodv_v6_rerr(netdissect_options *ndo, const u_char *dat, u_int length) - #else --aodv_v6_rerr(netdissect_options *ndo, -- const struct aodv_rerr *ap _U_, const u_char *dat, u_int length) -+aodv_v6_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length) - #endif - { - #ifdef INET6 - u_int i, dc; -+ const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; - const struct rerr_unreach6 *dp6; - -- if (ndo->ndo_snapend < dat) { -- ND_PRINT((ndo, " [|aodv]")); -- return; -- } -- i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(*ap)) { -- ND_PRINT((ndo, " [|rerr]")); -- return; -- } -- i -= sizeof(*ap); -+ ND_TCHECK(*ap); -+ if (length < sizeof(*ap)) -+ goto trunc; - ND_PRINT((ndo, " rerr %s [items %u] [%u]:", - ap->rerr_flags & RERR_NODELETE ? "[D]" : "", - ap->rerr_dc, length)); - dp6 = (struct rerr_unreach6 *)(void *)(ap + 1); -+ i = length - sizeof(*ap); - for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6); - ++dp6, --dc, i -= sizeof(*dp6)) { -+ ND_TCHECK(*dp6); - ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), - (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); - } - if ((i % sizeof(*dp6)) != 0) -- ND_PRINT((ndo, "[|rerr]")); -+ goto trunc; -+ return; -+ -+trunc: -+ ND_PRINT((ndo, "[|rerr]")); - #else - ND_PRINT((ndo, " rerr %u", length)); - #endif -@@ -425,26 +408,18 @@ aodv_v6_rerr(netdissect_options *ndo, - - static void - #ifdef INET6 --aodv_v6_draft_01_rreq(netdissect_options *ndo, -- const struct aodv_rreq6_draft_01 *ap, const u_char *dat, u_int length) -+aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat, u_int length) - #else --aodv_v6_draft_01_rreq(netdissect_options *ndo, -- const struct aodv_rreq6_draft_01 *ap _U_, const u_char *dat _U_, u_int length) -+aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat _U_, u_int length) - #endif - { - #ifdef INET6 - u_int i; -+ const struct aodv_rreq6_draft_01 *ap = (const struct aodv_rreq6_draft_01 *)dat; - -- if (ndo->ndo_snapend < dat) { -- ND_PRINT((ndo, " [|aodv]")); -- return; -- } -- i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(*ap)) { -- ND_PRINT((ndo, " [|rreq6]")); -- return; -- } -- i -= sizeof(*ap); -+ ND_TCHECK(*ap); -+ if (length < sizeof(*ap)) -+ goto trunc; - ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n" - "\tdst %s seq %lu src %s seq %lu", length, - ap->rreq_type & RREQ_JOIN ? "[J]" : "", -@@ -458,8 +433,13 @@ aodv_v6_draft_01_rreq(netdissect_options *ndo, - (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), - ip6addr_string(ndo, &ap->rreq_oa), - (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); -+ i = length - sizeof(*ap); - if (i >= sizeof(struct aodv_ext)) -- aodv_extension(ndo, (void *)(ap + 1), i); -+ aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); -+ return; -+ -+trunc: -+ ND_PRINT((ndo, " [|rreq")); - #else - ND_PRINT((ndo, " rreq %u", length)); - #endif -@@ -467,26 +447,18 @@ aodv_v6_draft_01_rreq(netdissect_options *ndo, - - static void - #ifdef INET6 --aodv_v6_draft_01_rrep(netdissect_options *ndo, -- const struct aodv_rrep6_draft_01 *ap, const u_char *dat, u_int length) -+aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat, u_int length) - #else --aodv_v6_draft_01_rrep(netdissect_options *ndo, -- const struct aodv_rrep6_draft_01 *ap _U_, const u_char *dat _U_, u_int length) -+aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat _U_, u_int length) - #endif - { - #ifdef INET6 - u_int i; -+ const struct aodv_rrep6_draft_01 *ap = (const struct aodv_rrep6_draft_01 *)dat; - -- if (ndo->ndo_snapend < dat) { -- ND_PRINT((ndo, " [|aodv]")); -- return; -- } -- i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(*ap)) { -- ND_PRINT((ndo, " [|rrep6]")); -- return; -- } -- i -= sizeof(*ap); -+ ND_TCHECK(*ap); -+ if (length < sizeof(*ap)) -+ goto trunc; - ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" - "\tdst %s dseq %lu src %s %lu ms", length, - ap->rrep_type & RREP_REPAIR ? "[R]" : "", -@@ -497,8 +469,13 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo, - (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), - ip6addr_string(ndo, &ap->rrep_oa), - (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); -+ i = length - sizeof(*ap); - if (i >= sizeof(struct aodv_ext)) -- aodv_extension(ndo, (void *)(ap + 1), i); -+ aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); -+ return; -+ -+trunc: -+ ND_PRINT((ndo, " [|rreq")); - #else - ND_PRINT((ndo, " rrep %u", length)); - #endif -@@ -506,38 +483,36 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo, - - static void - #ifdef INET6 --aodv_v6_draft_01_rerr(netdissect_options *ndo, -- const struct aodv_rerr *ap, const u_char *dat, u_int length) -+aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat, u_int length) - #else --aodv_v6_draft_01_rerr(netdissect_options *ndo, -- const struct aodv_rerr *ap _U_, const u_char *dat, u_int length) -+aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length) - #endif - { - #ifdef INET6 - u_int i, dc; -+ const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; - const struct rerr_unreach6_draft_01 *dp6; - -- if (ndo->ndo_snapend < dat) { -- ND_PRINT((ndo, " [|aodv]")); -- return; -- } -- i = min(length, (u_int)(ndo->ndo_snapend - dat)); -- if (i < sizeof(*ap)) { -- ND_PRINT((ndo, " [|rerr]")); -- return; -- } -- i -= sizeof(*ap); -+ ND_TCHECK(*ap); -+ if (length < sizeof(*ap)) -+ goto trunc; - ND_PRINT((ndo, " rerr %s [items %u] [%u]:", - ap->rerr_flags & RERR_NODELETE ? "[D]" : "", - ap->rerr_dc, length)); - dp6 = (struct rerr_unreach6_draft_01 *)(void *)(ap + 1); -+ i = length - sizeof(*ap); - for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6); - ++dp6, --dc, i -= sizeof(*dp6)) { -+ ND_TCHECK(*dp6); - ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), - (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); - } - if ((i % sizeof(*dp6)) != 0) -- ND_PRINT((ndo, "[|rerr]")); -+ goto trunc; -+ return; -+ -+trunc: -+ ND_PRINT((ndo, "[|rerr]")); - #else - ND_PRINT((ndo, " rerr %u", length)); - #endif -@@ -561,23 +536,23 @@ aodv_print(netdissect_options *ndo, - - case AODV_RREQ: - if (is_ip6) -- aodv_v6_rreq(ndo, (const struct aodv_rreq6 *)dat, dat, length); -+ aodv_v6_rreq(ndo, dat, length); - else -- aodv_rreq(ndo, (const struct aodv_rreq *)dat, dat, length); -+ aodv_rreq(ndo, dat, length); - break; - - case AODV_RREP: - if (is_ip6) -- aodv_v6_rrep(ndo, (const struct aodv_rrep6 *)dat, dat, length); -+ aodv_v6_rrep(ndo, dat, length); - else -- aodv_rrep(ndo, (const struct aodv_rrep *)dat, dat, length); -+ aodv_rrep(ndo, dat, length); - break; - - case AODV_RERR: - if (is_ip6) -- aodv_v6_rerr(ndo, (const struct aodv_rerr *)dat, dat, length); -+ aodv_v6_rerr(ndo, dat, length); - else -- aodv_rerr(ndo, (const struct aodv_rerr *)dat, dat, length); -+ aodv_rerr(ndo, dat, length); - break; - - case AODV_RREP_ACK: -@@ -585,15 +560,15 @@ aodv_print(netdissect_options *ndo, - break; - - case AODV_V6_DRAFT_01_RREQ: -- aodv_v6_draft_01_rreq(ndo, (const struct aodv_rreq6_draft_01 *)dat, dat, length); -+ aodv_v6_draft_01_rreq(ndo, dat, length); - break; - - case AODV_V6_DRAFT_01_RREP: -- aodv_v6_draft_01_rrep(ndo, (const struct aodv_rrep6_draft_01 *)dat, dat, length); -+ aodv_v6_draft_01_rrep(ndo, dat, length); - break; - - case AODV_V6_DRAFT_01_RERR: -- aodv_v6_draft_01_rerr(ndo, (const struct aodv_rerr *)dat, dat, length); -+ aodv_v6_draft_01_rerr(ndo, dat, length); - break; - - case AODV_V6_DRAFT_01_RREP_ACK: --- -1.8.3.1 - diff --git a/0014-Not-using-offsetof-any-more-so-no-need-for-stddef.h.patch b/0014-Not-using-offsetof-any-more-so-no-need-for-stddef.h.patch deleted file mode 100644 index 3a33914..0000000 --- a/0014-Not-using-offsetof-any-more-so-no-need-for-stddef.h.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 54d2912c19240a1a1866ba1519889086868038c4 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Tue, 11 Nov 2014 19:18:12 -0800 -Subject: [PATCH 3/4] Not using offsetof() any more, so no need for . - ---- - print-aodv.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/print-aodv.c b/print-aodv.c -index 2649936..9b3523a 100644 ---- a/print-aodv.c -+++ b/print-aodv.c -@@ -37,9 +37,6 @@ - - #include - --/* for offsetof */ --#include -- - #include "interface.h" - #include "addrtoname.h" - #include "extract.h" /* must come after interface.h */ --- -1.8.3.1 - diff --git a/0015-Report-a-too-long-unreachable-destination-list.patch b/0015-Report-a-too-long-unreachable-destination-list.patch deleted file mode 100644 index 9a24a0b..0000000 --- a/0015-Report-a-too-long-unreachable-destination-list.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 3f5693a2bb783b1caa2a308e64ee34d167f36f05 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Wed, 12 Nov 2014 01:09:27 -0800 -Subject: [PATCH 4/4] Report a too-long unreachable destination list. - -Running out of packet length before running out of unreachable -destinations is an error; report it as such. - -Don't worry about leftover data past the end of the list of unreachable -destinations. ---- - print-aodv.c | 27 +++++++++++++++------------ - 1 file changed, 15 insertions(+), 12 deletions(-) - -diff --git a/print-aodv.c b/print-aodv.c -index 9b3523a..ef27eee 100644 ---- a/print-aodv.c -+++ b/print-aodv.c -@@ -277,14 +277,15 @@ aodv_rerr(netdissect_options *ndo, const u_char *dat, u_int length) - ap->rerr_dc, length)); - dp = (struct rerr_unreach *)(dat + sizeof(*ap)); - i = length - sizeof(*ap); -- for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp); -- ++dp, --dc, i -= sizeof(*dp)) { -+ for (dc = ap->rerr_dc; dc != 0; dc--) { - ND_TCHECK(*dp); -+ if (i < sizeof(*dp)) -+ goto trunc; - ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da), - (unsigned long)EXTRACT_32BITS(&dp->u_ds))); -+ dp++; -+ i -= sizeof(*dp); - } -- if ((i % sizeof(*dp)) != 0) -- goto trunc; - return; - - trunc: -@@ -386,14 +387,15 @@ aodv_v6_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length) - ap->rerr_dc, length)); - dp6 = (struct rerr_unreach6 *)(void *)(ap + 1); - i = length - sizeof(*ap); -- for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6); -- ++dp6, --dc, i -= sizeof(*dp6)) { -+ for (dc = ap->rerr_dc; dc != 0; dc--) { - ND_TCHECK(*dp6); -+ if (i < sizeof(*dp6)) -+ goto trunc; - ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), - (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); -+ dp6++; -+ i -= sizeof(*dp6); - } -- if ((i % sizeof(*dp6)) != 0) -- goto trunc; - return; - - trunc: -@@ -498,14 +500,15 @@ aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int leng - ap->rerr_dc, length)); - dp6 = (struct rerr_unreach6_draft_01 *)(void *)(ap + 1); - i = length - sizeof(*ap); -- for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6); -- ++dp6, --dc, i -= sizeof(*dp6)) { -+ for (dc = ap->rerr_dc; dc != 0; dc--) { - ND_TCHECK(*dp6); -+ if (i < sizeof(*dp6)) -+ goto trunc; - ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), - (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); -+ dp6++; -+ i -= sizeof(*dp6); - } -- if ((i % sizeof(*dp6)) != 0) -- goto trunc; - return; - - trunc: --- -1.8.3.1 - diff --git a/0016-Do-bounds-checking-when-unescaping-PPP.patch b/0016-Do-bounds-checking-when-unescaping-PPP.patch deleted file mode 100644 index c10eb1b..0000000 --- a/0016-Do-bounds-checking-when-unescaping-PPP.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 34303452e4286e4894117adbfa017897597cbbb6 Mon Sep 17 00:00:00 2001 -From: Guy Harris -Date: Wed, 22 Oct 2014 12:31:21 -0700 -Subject: [PATCH] Do bounds checking when unescaping PPP. - -Clean up a const issue while we're at it. ---- - print-ppp.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/print-ppp.c b/print-ppp.c -index b858b73..eacba34 100644 ---- a/print-ppp.c -+++ b/print-ppp.c -@@ -1351,14 +1351,15 @@ static void - ppp_hdlc(netdissect_options *ndo, - const u_char *p, int length) - { -- u_char *b, *s, *t, c; -+ u_char *b, *t, c; -+ const u_char *s; - int i, proto; - const void *se; - - if (length <= 0) - return; - -- b = (uint8_t *)malloc(length); -+ b = (u_char *)malloc(length); - if (b == NULL) - return; - -@@ -1367,14 +1368,13 @@ ppp_hdlc(netdissect_options *ndo, - * Do this so that we dont overwrite the original packet - * contents. - */ -- for (s = (u_char *)p, t = b, i = length; i > 0; i--) { -+ for (s = p, t = b, i = length; i > 0 && ND_TTEST(*s); i--) { - c = *s++; - if (c == 0x7d) { -- if (i > 1) { -- i--; -- c = *s++ ^ 0x20; -- } else -- continue; -+ if (i <= 1 || !ND_TTEST(*s)) -+ break; -+ i--; -+ c = *s++ ^ 0x20; - } - *t++ = c; - } --- -1.8.3.1 - diff --git a/sources b/sources index c965793..f7da555 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -74d0d3728b3cdc60db872d842e7f1598 tcpdump-4.6.2.tar.gz +334a4761594b29f80793c1303f0f4acc tcpdump-4.7.3.tar.gz e329cbeb7e589f132d92c3447c477190 tcpslice-1.2a3.tar.gz diff --git a/tcpdump.spec b/tcpdump.spec index 94fcc42..41c8bbc 100644 --- a/tcpdump.spec +++ b/tcpdump.spec @@ -1,8 +1,8 @@ Summary: A network traffic monitoring tool Name: tcpdump Epoch: 14 -Version: 4.6.2 -Release: 3%{?dist} +Version: 4.7.3 +Release: 1%{?dist} License: BSD with advertising URL: http://www.tcpdump.org Group: Applications/Internet @@ -20,14 +20,6 @@ Patch0005: 0005-tcpslice-remove-unneeded-include.patch Patch0006: 0006-tcpslice-don-t-test-the-pointer-but-pointee-for-NULL.patch Patch0007: 0007-Introduce-nn-option.patch Patch0008: 0008-Don-t-print-out-we-dropped-root-we-are-always-droppi.patch -Patch0009: 0009-Do-more-bounds-checking-and-length-checking.patch -Patch0010: 0010-Do-bounds-checking-and-length-checking.patch -Patch0011: 0011-Add-initial-bounds-check-get-rid-of-union-aodv.patch -Patch0012: 0012-Clean-up-error-message-printing.patch -Patch0013: 0013-Further-cleanups.patch -Patch0014: 0014-Not-using-offsetof-any-more-so-no-need-for-stddef.h.patch -Patch0015: 0015-Report-a-too-long-unreachable-destination-list.patch -Patch0016: 0016-Do-bounds-checking-when-unescaping-PPP.patch %define tcpslice_dir tcpslice-1.2a3 @@ -90,6 +82,10 @@ exit 0 %{_mandir}/man8/tcpdump.8* %changelog +* Wed Mar 25 2015 Michal Sekletar - 14:4.7.3-1 +- rebase to 4.7.3 (#1201573) +- contains fixes for CVE-2015-0261 CVE-2015-2154 CVE-2015-2153 CVE-2015-2155 (#1201799,#1201792,#1201795,#1201797) + * Wed Dec 03 2014 Michal Sekletar - 14:4.6.2-3 - fix for CVE-2014-9140