Hello community,

here is the log from the commit of package tcpdump for openSUSE:Factory checked 
in at 2015-02-12 10:20:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/tcpdump (Old)
 and      /work/SRC/openSUSE:Factory/.tcpdump.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "tcpdump"

Changes:
--------
--- /work/SRC/openSUSE:Factory/tcpdump/tcpdump.changes  2014-09-09 
18:59:43.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.tcpdump.new/tcpdump.changes     2015-02-12 
10:20:39.000000000 +0100
@@ -1,0 +2,14 @@
+Fri Feb  6 12:31:23 UTC 2015 - vci...@suse.com
+
+- fix CVE-2014-8767 (bnc#905870)
+  * denial of service in verbose mode using malformed OLSR payload
+  * added tcpdump-CVE-2014-8767.patch
+- fix CVE-2014-8768 (bnc#905871)
+  * denial of service in verbose mode using malformed Geonet payload
+  * added tcpdump-CVE-2014-8768.patch
+- fix CVE-2014-8769 (bnc#905872)
+  * unreliable output using malformed AOVD payload
+  * added tcpdump-CVE-2014-8769.patch
+  * added 0001-Clean-up-error-message-printing.patch
+
+-------------------------------------------------------------------

New:
----
  0001-Clean-up-error-message-printing.patch
  tcpdump-CVE-2014-8767.patch
  tcpdump-CVE-2014-8768.patch
  tcpdump-CVE-2014-8769.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ tcpdump.spec ++++++
--- /var/tmp/diff_new_pack.8WDoUx/_old  2015-02-12 10:20:40.000000000 +0100
+++ /var/tmp/diff_new_pack.8WDoUx/_new  2015-02-12 10:20:40.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package tcpdump
 #
-# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -30,6 +30,10 @@
 Source1:        tcpdump-qeth
 Source2:        http://www.tcpdump.org/release/%{name}-%{version}.tar.gz.sig
 Source3:        http://www.tcpdump.org/tcpdump-workers.asc#/%{name}.keyring
+Patch3:         tcpdump-CVE-2014-8767.patch
+Patch4:         tcpdump-CVE-2014-8768.patch
+Patch5:         tcpdump-CVE-2014-8769.patch
+Patch6:         0001-Clean-up-error-message-printing.patch
 BuildRequires:  libpcap-devel >= %{min_libpcap_version}
 BuildRequires:  libsmi-devel
 BuildRequires:  openssl-devel
@@ -42,6 +46,10 @@
 
 %prep
 %setup -q
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
 
 %build
 export CFLAGS="%{optflags} -Wall -DGUESS_TSO -fstack-protector 
-fno-strict-aliasing"

++++++ 0001-Clean-up-error-message-printing.patch ++++++
>From 3e8a443c3671baa37ae7870f08fb9b4bf386fd24 Mon Sep 17 00:00:00 2001
From: Guy Harris <g...@alum.mit.edu>
Date: Tue, 11 Nov 2014 18:37:35 -0800
Subject: [PATCH] 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:
-- 
2.1.2


++++++ tcpdump-CVE-2014-8767.patch ++++++
>From 4038f83ebf654804829b258dde5e0a508c1c2003 Mon Sep 17 00:00:00 2001
From: Guy Harris <g...@alum.mit.edu>
Date: Tue, 11 Nov 2014 16:49:39 -0800
Subject: [PATCH 2/3] 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;
 
-- 
2.1.2

++++++ tcpdump-CVE-2014-8768.patch ++++++
>From 9255c9b05b0a04b8d89739b3efcb9f393a617fe9 Mon Sep 17 00:00:00 2001
From: Guy Harris <g...@alum.mit.edu>
Date: Tue, 11 Nov 2014 15:51:54 -0800
Subject: [PATCH 1/3] 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]"));
 }
 
 
-- 
2.1.2

++++++ tcpdump-CVE-2014-8769.patch ++++++
>From ab4e52b94aac6cb729a5a695aa612d5ebda2ec3a Mon Sep 17 00:00:00 2001
From: Guy Harris <g...@alum.mit.edu>
Date: Tue, 11 Nov 2014 17:24:12 -0800
Subject: [PATCH 3/3] 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]"));
 }
-- 
2.1.2


-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to