summaryrefslogtreecommitdiffstats
path: root/freebsd/contrib
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-20 15:53:03 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:39 +0200
commit18fa92c2dcc6c52e0bf27d214d80f0c25a89b47d (patch)
treea3020ac5b1f366f2f0920941b589808e435dbcee /freebsd/contrib
parentUpdate to FreeBSD head 2017-12-01 (diff)
downloadrtems-libbsd-18fa92c2dcc6c52e0bf27d214d80f0c25a89b47d.tar.bz2
Update to FreeBSD head 2018-02-01
Git mirror commit d079ae0442af8fa3cfd6d7ede190d04e64a2c0d4. Update #3472.
Diffstat (limited to 'freebsd/contrib')
-rw-r--r--freebsd/contrib/tcpdump/addrtoname.c80
-rw-r--r--freebsd/contrib/tcpdump/addrtoname.h3
-rw-r--r--freebsd/contrib/tcpdump/addrtostr.c17
-rw-r--r--freebsd/contrib/tcpdump/af.c2
-rw-r--r--freebsd/contrib/tcpdump/af.h2
-rw-r--r--freebsd/contrib/tcpdump/checksum.c2
-rw-r--r--freebsd/contrib/tcpdump/extract.h60
-rw-r--r--freebsd/contrib/tcpdump/funcattrs.h122
-rw-r--r--freebsd/contrib/tcpdump/gmpls.c2
-rw-r--r--freebsd/contrib/tcpdump/gmpls.h2
-rw-r--r--freebsd/contrib/tcpdump/ip6.h13
-rw-r--r--freebsd/contrib/tcpdump/ipproto.c308
-rw-r--r--freebsd/contrib/tcpdump/ipproto.h3
-rw-r--r--freebsd/contrib/tcpdump/l2vpn.c2
-rw-r--r--freebsd/contrib/tcpdump/l2vpn.h2
-rw-r--r--freebsd/contrib/tcpdump/netdissect-stdinc.h5
-rw-r--r--freebsd/contrib/tcpdump/netdissect.h16
-rw-r--r--freebsd/contrib/tcpdump/nlpid.c2
-rw-r--r--freebsd/contrib/tcpdump/nlpid.h2
-rw-r--r--freebsd/contrib/tcpdump/oui.c2
-rw-r--r--freebsd/contrib/tcpdump/oui.h2
-rw-r--r--freebsd/contrib/tcpdump/print-802_11.c15
-rw-r--r--freebsd/contrib/tcpdump/print-802_15_4.c240
-rw-r--r--freebsd/contrib/tcpdump/print-aodv.c9
-rw-r--r--freebsd/contrib/tcpdump/print-arp.c89
-rw-r--r--freebsd/contrib/tcpdump/print-atm.c2
-rw-r--r--freebsd/contrib/tcpdump/print-beep.c26
-rw-r--r--freebsd/contrib/tcpdump/print-bfd.c2
-rw-r--r--freebsd/contrib/tcpdump/print-bgp.c55
-rw-r--r--freebsd/contrib/tcpdump/print-bootp.c1
-rw-r--r--freebsd/contrib/tcpdump/print-cfm.c73
-rw-r--r--freebsd/contrib/tcpdump/print-chdlc.c24
-rw-r--r--freebsd/contrib/tcpdump/print-cnfp.c33
-rw-r--r--freebsd/contrib/tcpdump/print-decnet.c2
-rw-r--r--freebsd/contrib/tcpdump/print-dhcp6.c4
-rw-r--r--freebsd/contrib/tcpdump/print-domain.c37
-rw-r--r--freebsd/contrib/tcpdump/print-eap.c18
-rw-r--r--freebsd/contrib/tcpdump/print-eigrp.c49
-rw-r--r--freebsd/contrib/tcpdump/print-esp.c99
-rw-r--r--freebsd/contrib/tcpdump/print-ether.c2
-rw-r--r--freebsd/contrib/tcpdump/print-fr.c2
-rw-r--r--freebsd/contrib/tcpdump/print-frag6.c5
-rw-r--r--freebsd/contrib/tcpdump/print-gre.c2
-rw-r--r--freebsd/contrib/tcpdump/print-hncp.c8
-rw-r--r--freebsd/contrib/tcpdump/print-icmp.c18
-rw-r--r--freebsd/contrib/tcpdump/print-icmp6.c3
-rw-r--r--freebsd/contrib/tcpdump/print-ip.c39
-rw-r--r--freebsd/contrib/tcpdump/print-ip6.c11
-rw-r--r--freebsd/contrib/tcpdump/print-ip6opts.c4
-rw-r--r--freebsd/contrib/tcpdump/print-isakmp.c231
-rw-r--r--freebsd/contrib/tcpdump/print-isoclns.c534
-rw-r--r--freebsd/contrib/tcpdump/print-juniper.c57
-rw-r--r--freebsd/contrib/tcpdump/print-l2tp.c223
-rw-r--r--freebsd/contrib/tcpdump/print-ldp.c2
-rw-r--r--freebsd/contrib/tcpdump/print-llc.c2
-rw-r--r--freebsd/contrib/tcpdump/print-lldp.c22
-rw-r--r--freebsd/contrib/tcpdump/print-lmp.c434
-rw-r--r--freebsd/contrib/tcpdump/print-lspping.c3
-rw-r--r--freebsd/contrib/tcpdump/print-m3ua.c2
-rw-r--r--freebsd/contrib/tcpdump/print-mobility.c46
-rw-r--r--freebsd/contrib/tcpdump/print-mpcp.c2
-rw-r--r--freebsd/contrib/tcpdump/print-mpls.c2
-rw-r--r--freebsd/contrib/tcpdump/print-mptcp.c84
-rw-r--r--freebsd/contrib/tcpdump/print-nfs.c25
-rw-r--r--freebsd/contrib/tcpdump/print-null.c2
-rw-r--r--freebsd/contrib/tcpdump/print-olsr.c23
-rw-r--r--freebsd/contrib/tcpdump/print-ospf6.c4
-rw-r--r--freebsd/contrib/tcpdump/print-pgm.c218
-rw-r--r--freebsd/contrib/tcpdump/print-pim.c426
-rw-r--r--freebsd/contrib/tcpdump/print-pktap.c6
-rw-r--r--freebsd/contrib/tcpdump/print-ppp.c39
-rw-r--r--freebsd/contrib/tcpdump/print-radius.c14
-rw-r--r--freebsd/contrib/tcpdump/print-resp.c24
-rw-r--r--freebsd/contrib/tcpdump/print-ripng.c71
-rw-r--r--freebsd/contrib/tcpdump/print-rpki-rtr.c171
-rw-r--r--freebsd/contrib/tcpdump/print-rsvp.c24
-rw-r--r--freebsd/contrib/tcpdump/print-rt6.c8
-rw-r--r--freebsd/contrib/tcpdump/print-rx.c36
-rw-r--r--freebsd/contrib/tcpdump/print-sip.c2
-rw-r--r--freebsd/contrib/tcpdump/print-sl.c25
-rw-r--r--freebsd/contrib/tcpdump/print-slow.c2
-rw-r--r--freebsd/contrib/tcpdump/print-stp.c2
-rw-r--r--freebsd/contrib/tcpdump/print-syslog.c2
-rw-r--r--freebsd/contrib/tcpdump/print-telnet.c1
-rw-r--r--freebsd/contrib/tcpdump/print-tftp.c63
-rw-r--r--freebsd/contrib/tcpdump/print-vqp.c14
-rw-r--r--freebsd/contrib/tcpdump/print-vtp.c144
-rw-r--r--freebsd/contrib/tcpdump/print-wb.c9
-rw-r--r--freebsd/contrib/tcpdump/print-zephyr.c48
-rw-r--r--freebsd/contrib/tcpdump/print.c27
-rw-r--r--freebsd/contrib/tcpdump/rtems-bsd-tcpdump-addrtoname-data.h2
-rw-r--r--freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h1
-rw-r--r--freebsd/contrib/tcpdump/rtems-bsd-tcpdump-tcpdump-data.h2
-rw-r--r--freebsd/contrib/tcpdump/signature.c2
-rw-r--r--freebsd/contrib/tcpdump/signature.h2
-rw-r--r--freebsd/contrib/tcpdump/smbutil.c1
-rw-r--r--freebsd/contrib/tcpdump/tcpdump.c37
-rw-r--r--freebsd/contrib/tcpdump/util-print.c27
98 files changed, 3158 insertions, 1511 deletions
diff --git a/freebsd/contrib/tcpdump/addrtoname.c b/freebsd/contrib/tcpdump/addrtoname.c
index fb4550cc..a47b3615 100644
--- a/freebsd/contrib/tcpdump/addrtoname.c
+++ b/freebsd/contrib/tcpdump/addrtoname.c
@@ -156,13 +156,23 @@ struct enamemem {
u_short e_addr2;
const char *e_name;
u_char *e_nsap; /* used only for nsaptable[] */
-#define e_bs e_nsap /* for bytestringtable */
struct enamemem *e_nxt;
};
static struct enamemem enametable[HASHNAMESIZE];
static struct enamemem nsaptable[HASHNAMESIZE];
-static struct enamemem bytestringtable[HASHNAMESIZE];
+
+struct bsnamemem {
+ u_short bs_addr0;
+ u_short bs_addr1;
+ u_short bs_addr2;
+ const char *bs_name;
+ u_char *bs_bytes;
+ unsigned int bs_nbytes;
+ struct bsnamemem *bs_nxt;
+};
+
+static struct bsnamemem bytestringtable[HASHNAMESIZE];
struct protoidmem {
uint32_t p_oui;
@@ -348,7 +358,7 @@ getname6(netdissect_options *ndo, const u_char *ap)
return (p->name);
}
-static const char hex[] = "0123456789abcdef";
+static const char hex[16] = "0123456789abcdef";
/* Find the hash node that corresponds the ether address 'ep' */
@@ -386,11 +396,11 @@ lookup_emem(netdissect_options *ndo, const u_char *ep)
* with length 'nlen'
*/
-static inline struct enamemem *
+static inline struct bsnamemem *
lookup_bytestring(netdissect_options *ndo, register const u_char *bs,
const unsigned int nlen)
{
- struct enamemem *tp;
+ struct bsnamemem *tp;
register u_int i, j, k;
if (nlen >= 6) {
@@ -405,26 +415,28 @@ lookup_bytestring(netdissect_options *ndo, register const u_char *bs,
i = j = k = 0;
tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)];
- while (tp->e_nxt)
- if (tp->e_addr0 == i &&
- tp->e_addr1 == j &&
- tp->e_addr2 == k &&
- memcmp((const char *)bs, (const char *)(tp->e_bs), nlen) == 0)
+ while (tp->bs_nxt)
+ if (nlen == tp->bs_nbytes &&
+ tp->bs_addr0 == i &&
+ tp->bs_addr1 == j &&
+ tp->bs_addr2 == k &&
+ memcmp((const char *)bs, (const char *)(tp->bs_bytes), nlen) == 0)
return tp;
else
- tp = tp->e_nxt;
+ tp = tp->bs_nxt;
- tp->e_addr0 = i;
- tp->e_addr1 = j;
- tp->e_addr2 = k;
+ tp->bs_addr0 = i;
+ tp->bs_addr1 = j;
+ tp->bs_addr2 = k;
- tp->e_bs = (u_char *) calloc(1, nlen + 1);
- if (tp->e_bs == NULL)
+ tp->bs_bytes = (u_char *) calloc(1, nlen);
+ if (tp->bs_bytes == NULL)
(*ndo->ndo_error)(ndo, "lookup_bytestring: calloc");
- memcpy(tp->e_bs, bs, nlen);
- tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
- if (tp->e_nxt == NULL)
+ memcpy(tp->bs_bytes, bs, nlen);
+ tp->bs_nbytes = nlen;
+ tp->bs_nxt = (struct bsnamemem *)calloc(1, sizeof(*tp));
+ if (tp->bs_nxt == NULL)
(*ndo->ndo_error)(ndo, "lookup_bytestring: calloc");
return tp;
@@ -451,11 +463,11 @@ lookup_nsap(netdissect_options *ndo, register const u_char *nsap,
tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
while (tp->e_nxt)
- if (tp->e_addr0 == i &&
+ if (nsap_length == tp->e_nsap[0] &&
+ tp->e_addr0 == i &&
tp->e_addr1 == j &&
tp->e_addr2 == k &&
- tp->e_nsap[0] == nsap_length &&
- memcmp((const char *)&(nsap[1]),
+ memcmp((const char *)nsap,
(char *)&(tp->e_nsap[1]), nsap_length) == 0)
return tp;
else
@@ -555,12 +567,12 @@ le64addr_string(netdissect_options *ndo, const u_char *ep)
const unsigned int len = 8;
register u_int i;
register char *cp;
- register struct enamemem *tp;
+ register struct bsnamemem *tp;
char buf[BUFSIZE];
tp = lookup_bytestring(ndo, ep, len);
- if (tp->e_name)
- return (tp->e_name);
+ if (tp->bs_name)
+ return (tp->bs_name);
cp = buf;
for (i = len; i > 0 ; --i) {
@@ -572,11 +584,11 @@ le64addr_string(netdissect_options *ndo, const u_char *ep)
*cp = '\0';
- tp->e_name = strdup(buf);
- if (tp->e_name == NULL)
+ tp->bs_name = strdup(buf);
+ if (tp->bs_name == NULL)
(*ndo->ndo_error)(ndo, "le64addr_string: strdup(buf)");
- return (tp->e_name);
+ return (tp->bs_name);
}
const char *
@@ -585,7 +597,7 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep,
{
register u_int i;
register char *cp;
- register struct enamemem *tp;
+ register struct bsnamemem *tp;
if (len == 0)
return ("<empty>");
@@ -597,11 +609,11 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep,
return (q922_string(ndo, ep, len));
tp = lookup_bytestring(ndo, ep, len);
- if (tp->e_name)
- return (tp->e_name);
+ if (tp->bs_name)
+ return (tp->bs_name);
- tp->e_name = cp = (char *)malloc(len*3);
- if (tp->e_name == NULL)
+ tp->bs_name = cp = (char *)malloc(len*3);
+ if (tp->bs_name == NULL)
(*ndo->ndo_error)(ndo, "linkaddr_string: malloc");
*cp++ = hex[*ep >> 4];
*cp++ = hex[*ep++ & 0xf];
@@ -611,7 +623,7 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep,
*cp++ = hex[*ep++ & 0xf];
}
*cp = '\0';
- return (tp->e_name);
+ return (tp->bs_name);
}
const char *
diff --git a/freebsd/contrib/tcpdump/addrtoname.h b/freebsd/contrib/tcpdump/addrtoname.h
index 72e5ef19..fe8b6bbe 100644
--- a/freebsd/contrib/tcpdump/addrtoname.h
+++ b/freebsd/contrib/tcpdump/addrtoname.h
@@ -33,7 +33,8 @@ enum {
LINKADDR_ETHER,
LINKADDR_FRELAY,
LINKADDR_IEEE1394,
- LINKADDR_ATM
+ LINKADDR_ATM,
+ LINKADDR_OTHER
};
#define BUFSIZE 128
diff --git a/freebsd/contrib/tcpdump/addrtostr.c b/freebsd/contrib/tcpdump/addrtostr.c
index bf829bb4..c5fea233 100644
--- a/freebsd/contrib/tcpdump/addrtostr.c
+++ b/freebsd/contrib/tcpdump/addrtostr.c
@@ -116,25 +116,24 @@ addrtostr6 (const void *src, char *dst, size_t size)
size_t space_left, added_space;
int snprintfed;
struct {
- long base;
- long len;
+ int base;
+ int len;
} best, cur;
- u_long words [IN6ADDRSZ / INT16SZ];
+ uint16_t words [IN6ADDRSZ / INT16SZ];
int i;
/* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
- memset (words, 0, sizeof(words));
- for (i = 0; i < IN6ADDRSZ; i++)
- words[i/2] |= (srcaddr[i] << ((1 - (i % 2)) << 3));
+ for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
+ words[i] = (srcaddr[2*i] << 8) | srcaddr[2*i + 1];
best.len = 0;
best.base = -1;
cur.len = 0;
cur.base = -1;
- for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
+ for (i = 0; i < (int)(IN6ADDRSZ / INT16SZ); i++)
{
if (words[i] == 0)
{
@@ -167,7 +166,7 @@ addrtostr6 (const void *src, char *dst, size_t size)
*dp++ = c; \
space_left--; \
}
- for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
+ for (i = 0; i < (int)(IN6ADDRSZ / INT16SZ); i++)
{
/* Are we inside the best run of 0x00's?
*/
@@ -198,7 +197,7 @@ addrtostr6 (const void *src, char *dst, size_t size)
space_left -= added_space;
break;
}
- snprintfed = snprintf (dp, space_left, "%lx", words[i]);
+ snprintfed = snprintf (dp, space_left, "%x", words[i]);
if (snprintfed < 0)
return (NULL);
if ((size_t) snprintfed >= space_left)
diff --git a/freebsd/contrib/tcpdump/af.c b/freebsd/contrib/tcpdump/af.c
index dfa02dd5..e4f5416b 100644
--- a/freebsd/contrib/tcpdump/af.c
+++ b/freebsd/contrib/tcpdump/af.c
@@ -18,7 +18,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/freebsd/contrib/tcpdump/af.h b/freebsd/contrib/tcpdump/af.h
index 1bde577e..6365b126 100644
--- a/freebsd/contrib/tcpdump/af.h
+++ b/freebsd/contrib/tcpdump/af.h
@@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
extern const struct tok af_values[];
diff --git a/freebsd/contrib/tcpdump/checksum.c b/freebsd/contrib/tcpdump/checksum.c
index 87448b5b..84ce8a77 100644
--- a/freebsd/contrib/tcpdump/checksum.c
+++ b/freebsd/contrib/tcpdump/checksum.c
@@ -20,7 +20,7 @@
*
* miscellaneous checksumming routines
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/freebsd/contrib/tcpdump/extract.h b/freebsd/contrib/tcpdump/extract.h
index 23623c28..5969c225 100644
--- a/freebsd/contrib/tcpdump/extract.h
+++ b/freebsd/contrib/tcpdump/extract.h
@@ -20,8 +20,48 @@
*/
/*
- * Macros to extract possibly-unaligned big-endian integral values.
+ * For 8-bit values; provided for the sake of completeness. Byte order
+ * isn't relevant, and alignment isn't an issue.
*/
+#define EXTRACT_8BITS(p) (*(p))
+#define EXTRACT_LE_8BITS(p) (*(p))
+
+/*
+ * Inline functions or macros to extract possibly-unaligned big-endian
+ * integral values.
+ */
+#include "funcattrs.h"
+
+/*
+ * If we have versions of GCC or Clang that support an __attribute__
+ * to say "if we're building with unsigned behavior sanitization,
+ * don't complain about undefined behavior in this function", we
+ * label these functions with that attribute - we *know* it's undefined
+ * in the C standard, but we *also* know it does what we want with
+ * the ISA we're targeting and the compiler we're using.
+ *
+ * For GCC 4.9.0 and later, we use __attribute__((no_sanitize_undefined));
+ * pre-5.0 GCC doesn't have __has_attribute, and I'm not sure whether
+ * GCC or Clang first had __attribute__((no_sanitize(XXX)).
+ *
+ * For Clang, we check for __attribute__((no_sanitize(XXX)) with
+ * __has_attribute, as there are versions of Clang that support
+ * __attribute__((no_sanitize("undefined")) but don't support
+ * __attribute__((no_sanitize_undefined)).
+ *
+ * We define this here, rather than in funcattrs.h, because we
+ * only want it used here, we don't want it to be broadly used.
+ * (Any printer will get this defined, but this should at least
+ * make it harder for people to find.)
+ */
+#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 409)
+#define UNALIGNED_OK __attribute__((no_sanitize_undefined))
+#elif __has_attribute(no_sanitize)
+#define UNALIGNED_OK __attribute__((no_sanitize("undefined")))
+#else
+#define UNALIGNED_OK
+#endif
+
#ifdef LBL_ALIGN
/*
* The processor doesn't natively handle unaligned loads.
@@ -31,7 +71,7 @@
defined(__mips) || defined(__mips__))
/*
- * This is a GCC-compatible compiler and we have __attribute__, which
+* This is a GCC-compatible compiler and we have __attribute__, which
* we assume that mean we have __attribute__((packed)), and this is
* MIPS or Alpha, which has instructions that can help when doing
* unaligned loads.
@@ -88,19 +128,19 @@ typedef struct {
uint32_t val;
} __attribute__((packed)) unaligned_uint32_t;
-static inline uint16_t
+UNALIGNED_OK static inline uint16_t
EXTRACT_16BITS(const void *p)
{
return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val));
}
-static inline uint32_t
+UNALIGNED_OK static inline uint32_t
EXTRACT_32BITS(const void *p)
{
return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val));
}
-static inline uint64_t
+UNALIGNED_OK static inline uint64_t
EXTRACT_64BITS(const void *p)
{
return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 |
@@ -138,19 +178,19 @@ EXTRACT_64BITS(const void *p)
* The processor natively handles unaligned loads, so we can just
* cast the pointer and fetch through it.
*/
-static inline uint16_t
+static inline uint16_t UNALIGNED_OK
EXTRACT_16BITS(const void *p)
{
return ((uint16_t)ntohs(*(const uint16_t *)(p)));
}
-static inline uint32_t
+static inline uint32_t UNALIGNED_OK
EXTRACT_32BITS(const void *p)
{
return ((uint32_t)ntohl(*(const uint32_t *)(p)));
}
-static inline uint64_t
+static inline uint64_t UNALIGNED_OK
EXTRACT_64BITS(const void *p)
{
return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 |
@@ -193,7 +233,6 @@ EXTRACT_64BITS(const void *p)
* Macros to extract possibly-unaligned little-endian integral values.
* XXX - do loads on little-endian machines that support unaligned loads?
*/
-#define EXTRACT_LE_8BITS(p) (*(p))
#define EXTRACT_LE_16BITS(p) \
((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 0)) << 0)))
@@ -242,3 +281,6 @@ EXTRACT_64BITS(const void *p)
#define ND_TTEST_64BITS(p) ND_TTEST2(*(p), 8)
#define ND_TCHECK_64BITS(p) ND_TCHECK2(*(p), 8)
+
+#define ND_TTEST_128BITS(p) ND_TTEST2(*(p), 16)
+#define ND_TCHECK_128BITS(p) ND_TCHECK2(*(p), 16)
diff --git a/freebsd/contrib/tcpdump/funcattrs.h b/freebsd/contrib/tcpdump/funcattrs.h
new file mode 100644
index 00000000..63d3f565
--- /dev/null
+++ b/freebsd/contrib/tcpdump/funcattrs.h
@@ -0,0 +1,122 @@
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lib_funcattrs_h
+#define lib_funcattrs_h
+
+/*
+ * Attributes to apply to functions and their arguments, using various
+ * compiler-specific extensions.
+ */
+
+/*
+ * This was introduced by Clang:
+ *
+ * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
+ *
+ * in some version (which version?); it has been picked up by GCC 5.0.
+ */
+#ifndef __has_attribute
+ /*
+ * It's a macro, so you can check whether it's defined to check
+ * whether it's supported.
+ *
+ * If it's not, define it to always return 0, so that we move on to
+ * the fallback checks.
+ */
+ #define __has_attribute(x) 0
+#endif
+
+/*
+ * NORETURN, before a function declaration, means "this function
+ * never returns". (It must go before the function declaration, e.g.
+ * "extern NORETURN func(...)" rather than after the function
+ * declaration, as the MSVC version has to go before the declaration.)
+ */
+#if __has_attribute(noreturn) \
+ || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
+ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) \
+ || (defined(__xlC__) && __xlC__ >= 0x0A01) \
+ || (defined(__HP_aCC) && __HP_aCC >= 61000)
+ /*
+ * Compiler with support for __attribute((noreturn)), or GCC 2.5 and
+ * later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1
+ * and later (do any earlier versions of XL C support this?), or
+ * HP aCC A.06.10 and later.
+ */
+ #define NORETURN __attribute((noreturn))
+#elif defined(_MSC_VER)
+ /*
+ * MSVC.
+ */
+ #define NORETURN __declspec(noreturn)
+#else
+ #define NORETURN
+#endif
+
+/*
+ * PRINTFLIKE(x,y), after a function declaration, means "this function
+ * does printf-style formatting, with the xth argument being the format
+ * string and the yth argument being the first argument for the format
+ * string".
+ */
+#if __has_attribute(__format__) \
+ || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \
+ || (defined(__xlC__) && __xlC__ >= 0x0A01) \
+ || (defined(__HP_aCC) && __HP_aCC >= 61000)
+ /*
+ * Compiler with support for it, or GCC 2.3 and later, or IBM XL C 10.1
+ * and later (do any earlier versions of XL C support this?),
+ * or HP aCC A.06.10 and later.
+ */
+ #define PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y)))
+#else
+ #define PRINTFLIKE(x,y)
+#endif
+
+/*
+ * For flagging arguments as format strings in MSVC.
+ */
+#if _MSC_VER >= 1400
+ #include <sal.h>
+ #if _MSC_VER > 1400
+ #define FORMAT_STRING(p) _Printf_format_string_ p
+ #else
+ #define FORMAT_STRING(p) __format_string p
+ #endif
+#else
+ #define FORMAT_STRING(p) p
+#endif
+
+#endif /* lib_funcattrs_h */
diff --git a/freebsd/contrib/tcpdump/gmpls.c b/freebsd/contrib/tcpdump/gmpls.c
index 4b45ba26..e8cb7ff0 100644
--- a/freebsd/contrib/tcpdump/gmpls.c
+++ b/freebsd/contrib/tcpdump/gmpls.c
@@ -16,7 +16,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/freebsd/contrib/tcpdump/gmpls.h b/freebsd/contrib/tcpdump/gmpls.h
index 8b44f949..32fa8114 100644
--- a/freebsd/contrib/tcpdump/gmpls.h
+++ b/freebsd/contrib/tcpdump/gmpls.h
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#define GMPLS_PSC1 1
diff --git a/freebsd/contrib/tcpdump/ip6.h b/freebsd/contrib/tcpdump/ip6.h
index 2ea1d0ab..9a24ef14 100644
--- a/freebsd/contrib/tcpdump/ip6.h
+++ b/freebsd/contrib/tcpdump/ip6.h
@@ -178,14 +178,13 @@ struct ip6_rthdr {
/* Type 0 Routing header */
/* Also used for Type 2 */
struct ip6_rthdr0 {
- uint8_t ip6r0_nxt; /* next header */
- uint8_t ip6r0_len; /* length in units of 8 octets */
- uint8_t ip6r0_type; /* always zero */
- uint8_t ip6r0_segleft; /* segments left */
- uint8_t ip6r0_reserved; /* reserved field */
- uint8_t ip6r0_slmap[3]; /* strict/loose bit map */
+ nd_uint8_t ip6r0_nxt; /* next header */
+ nd_uint8_t ip6r0_len; /* length in units of 8 octets */
+ nd_uint8_t ip6r0_type; /* always zero */
+ nd_uint8_t ip6r0_segleft; /* segments left */
+ nd_uint32_t ip6r0_reserved; /* reserved field */
struct in6_addr ip6r0_addr[1]; /* up to 23 addresses */
-} UNALIGNED;
+};
/* Fragment header */
struct ip6_frag {
diff --git a/freebsd/contrib/tcpdump/ipproto.c b/freebsd/contrib/tcpdump/ipproto.c
index 44fae5d6..38c5de80 100644
--- a/freebsd/contrib/tcpdump/ipproto.c
+++ b/freebsd/contrib/tcpdump/ipproto.c
@@ -16,7 +16,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
@@ -61,6 +61,312 @@ const struct tok ipproto_values[] = {
{ 0, NULL }
};
+/*
+ * For completeness the number space in the array below comes from IANA:
+ * https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
+ * However, the spelling tries to match that of /etc/protocols to achieve as
+ * much consistency as possible with the previously implemented behaviour,
+ * which was based on getprotobynumber (3).
+ */
+static const char *const netdb_protocol_names[256] = {
+ "hopopt", /* 0 (IPPROTO_HOPOPTS, IPv6 Hop-by-Hop Option) */
+ "icmp", /* 1 (IPPROTO_ICMP, Internet Control Message) */
+ "igmp", /* 2 (IPPROTO_IGMP, Internet Group Management) */
+ "ggp", /* 3 (Gateway-to-Gateway) */
+ "ipencap", /* 4 (IPPROTO_IPV4, IPv4 encapsulation) */
+ "st", /* 5 (Stream, ST datagram mode) */
+ "tcp", /* 6 (IPPROTO_TCP, Transmission Control) */
+ "cbt", /* 7 (CBT) */
+ "egp", /* 8 (IPPROTO_EGP, Exterior Gateway Protocol) */
+ "igp", /* 9 (IPPROTO_PIGP, "any private interior gateway
+ * (used by Cisco for their IGRP)")
+ */
+ "bbn-rcc-mon", /* 10 (BBN RCC Monitoring) */
+ "nvp-ii", /* 11 (Network Voice Protocol) */
+ "pup", /* 12 (PARC universal packet protocol) */
+ "argus", /* 13 (ARGUS) */
+ "emcon", /* 14 (EMCON) */
+ "xnet", /* 15 (Cross Net Debugger) */
+ "chaos", /* 16 (Chaos) */
+ "udp", /* 17 (IPPROTO_UDP, User Datagram) */
+ "mux", /* 18 (Multiplexing) */
+ "dcn-meas", /* 19 (DCN Measurement Subsystems) */
+ "hmp", /* 20 (Host Monitoring) */
+ "prm", /* 21 (Packet Radio Measurement) */
+ "xns-idp", /* 22 (XEROX NS IDP) */
+ "trunk-1", /* 23 (Trunk-1) */
+ "trunk-2", /* 24 (Trunk-2) */
+ "leaf-1", /* 25 (Leaf-1) */
+ "leaf-2", /* 26 (Leaf-2) */
+ "rdp", /* 27 (Reliable Data Protocol) */
+ "irtp", /* 28 (Internet Reliable Transaction) */
+ "iso-tp4", /* 29 (ISO Transport Protocol Class 4) */
+ "netblt", /* 30 (Bulk Data Transfer Protocol) */
+ "mfe-nsp", /* 31 (MFE Network Services Protocol) */
+ "merit-inp", /* 32 (MERIT Internodal Protocol) */
+ "dccp", /* 33 (IPPROTO_DCCP, Datagram Congestion
+ * Control Protocol)
+ */
+ "3pc", /* 34 (Third Party Connect Protocol) */
+ "idpr", /* 35 (Inter-Domain Policy Routing Protocol) */
+ "xtp", /* 36 (Xpress Transfer Protocol) */
+ "ddp", /* 37 (Datagram Delivery Protocol) */
+ "idpr-cmtp", /* 38 (IDPR Control Message Transport Proto) */
+ "tp++", /* 39 (TP++ Transport Protocol) */
+ "il", /* 40 (IL Transport Protocol) */
+ "ipv6", /* 41 (IPPROTO_IPV6, IPv6 encapsulation) */
+ "sdrp", /* 42 (Source Demand Routing Protocol) */
+ "ipv6-route", /* 43 (IPPROTO_ROUTING, Routing Header for IPv6) */
+ "ipv6-frag", /* 44 (IPPROTO_FRAGMENT, Fragment Header for
+ * IPv6)
+ */
+ "idrp", /* 45 (Inter-Domain Routing Protocol) */
+ "rsvp", /* 46 (IPPROTO_RSVP, Reservation Protocol) */
+ "gre", /* 47 (IPPROTO_GRE, Generic Routing
+ * Encapsulation)
+ */
+ "dsr", /* 48 (Dynamic Source Routing Protocol) */
+ "bna", /* 49 (BNA) */
+ "esp", /* 50 (IPPROTO_ESP, Encap Security Payload) */
+ "ah", /* 51 (IPPROTO_AH, Authentication Header) */
+ "i-nlsp", /* 52 (Integrated Net Layer Security TUBA) */
+ "swipe", /* 53 (IP with Encryption) */
+ "narp", /* 54 (NBMA Address Resolution Protocol) */
+ "mobile", /* 55 (IPPROTO_MOBILE, IP Mobility) */
+ "tlsp", /* 56 (Transport Layer Security Protocol using
+ * Kryptonet key management)
+ */
+ "skip", /* 57 (SKIP) */
+ "ipv6-icmp", /* 58 (IPPROTO_ICMPV6, ICMP for IPv6) */
+ "ipv6-nonxt", /* 59 (IPPROTO_NONE, No Next Header for IPv6) */
+ "ipv6-opts", /* 60 (IPPROTO_DSTOPTS, Destination Options for
+ * IPv6)
+ */
+ NULL, /* 61 (any host internal protocol) */
+ "cftp", /* 62 (IPPROTO_MOBILITY_OLD, CFTP, see the note
+ * in ipproto.h)
+ */
+ NULL, /* 63 (any local network) */
+ "sat-expak", /* 64 (SATNET and Backroom EXPAK) */
+ "kryptolan", /* 65 (Kryptolan) */
+ "rvd", /* 66 (MIT Remote Virtual Disk Protocol) */
+ "ippc", /* 67 (Internet Pluribus Packet Core) */
+ NULL, /* 68 (any distributed file system) */
+ "sat-mon", /* 69 (SATNET Monitoring) */
+ "visa", /* 70 (VISA Protocol) */
+ "ipcv", /* 71 (Internet Packet Core Utility) */
+ "cpnx", /* 72 (Computer Protocol Network Executive) */
+ "rspf", /* 73 (Radio Shortest Path First, CPHB -- Computer
+ * Protocol Heart Beat -- in IANA)
+ */
+ "wsn", /* 74 (Wang Span Network) */
+ "pvp", /* 75 (Packet Video Protocol) */
+ "br-sat-mon", /* 76 (Backroom SATNET Monitoring) */
+ "sun-nd", /* 77 (IPPROTO_ND, SUN ND PROTOCOL-Temporary) */
+ "wb-mon", /* 78 (WIDEBAND Monitoring) */
+ "wb-expak", /* 79 (WIDEBAND EXPAK) */
+ "iso-ip", /* 80 (ISO Internet Protocol) */
+ "vmtp", /* 81 (Versatile Message Transport) */
+ "secure-vmtp", /* 82 (Secure VMTP) */
+ "vines", /* 83 (VINES) */
+ "ttp", /* 84 (Transaction Transport Protocol, also IPTM --
+ * Internet Protocol Traffic Manager)
+ */
+ "nsfnet-igp", /* 85 (NSFNET-IGP) */
+ "dgp", /* 86 (Dissimilar Gateway Protocol) */
+ "tcf", /* 87 (TCF) */
+ "eigrp", /* 88 (IPPROTO_EIGRP, Cisco EIGRP) */
+ "ospf", /* 89 (IPPROTO_OSPF, Open Shortest Path First
+ * IGP)
+ */
+ "sprite-rpc", /* 90 (Sprite RPC Protocol) */
+ "larp", /* 91 (Locus Address Resolution Protocol) */
+ "mtp", /* 92 (Multicast Transport Protocol) */
+ "ax.25", /* 93 (AX.25 Frames) */
+ "ipip", /* 94 (IP-within-IP Encapsulation Protocol) */
+ "micp", /* 95 (Mobile Internetworking Control Pro.) */
+ "scc-sp", /* 96 (Semaphore Communications Sec. Pro.) */
+ "etherip", /* 97 (Ethernet-within-IP Encapsulation) */
+ "encap", /* 98 (Encapsulation Header) */
+ NULL, /* 99 (any private encryption scheme) */
+ "gmtp", /* 100 (GMTP) */
+ "ifmp", /* 101 (Ipsilon Flow Management Protocol) */
+ "pnni", /* 102 (PNNI over IP) */
+ "pim", /* 103 (IPPROTO_PIM, Protocol Independent
+ * Multicast)
+ */
+ "aris", /* 104 (ARIS) */
+ "scps", /* 105 (SCPS) */
+ "qnx", /* 106 (QNX) */
+ "a/n", /* 107 (Active Networks) */
+ "ipcomp", /* 108 (IPPROTO_IPCOMP, IP Payload Compression
+ * Protocol)
+ */
+ "snp", /* 109 (Sitara Networks Protocol) */
+ "compaq-peer", /* 110 (Compaq Peer Protocol) */
+ "ipx-in-ip", /* 111 (IPX in IP) */
+ "vrrp", /* 112 (IPPROTO_VRRP, Virtual Router Redundancy
+ * Protocol)
+ */
+ "pgm", /* 113 (IPPROTO_PGM, PGM Reliable Transport
+ * Protocol)
+ */
+ NULL, /* 114 (any 0-hop protocol) */
+ "l2tp", /* 115 (Layer Two Tunneling Protocol) */
+ "ddx", /* 116 (D-II Data Exchange (DDX)) */
+ "iatp", /* 117 (Interactive Agent Transfer Protocol) */
+ "stp", /* 118 (Schedule Transfer Protocol) */
+ "srp", /* 119 (SpectraLink Radio Protocol) */
+ "uti", /* 120 (UTI) */
+ "smp", /* 121 (Simple Message Protocol) */
+ "sm", /* 122 (Simple Multicast Protocol) */
+ "ptp", /* 123 (Performance Transparency Protocol) */
+ "isis", /* 124 (ISIS over IPv4) */
+ "fire", /* 125 (FIRE) */
+ "crtp", /* 126 (Combat Radio Transport Protocol) */
+ "crudp", /* 127 (Combat Radio User Datagram) */
+ "sscopmce", /* 128 (SSCOPMCE) */
+ "iplt", /* 129 (IPLT) */
+ "sps", /* 130 (Secure Packet Shield) */
+ "pipe", /* 131 (Private IP Encapsulation within IP) */
+ "sctp", /* 132 (IPPROTO_SCTP, Stream Control Transmission
+ * Protocol)
+ */
+ "fc", /* 133 (Fibre Channel) */
+ "rsvp-e2e-ignore", /* 134 (RSVP-E2E-IGNORE) */
+ "mobility-header", /* 135 (IPPROTO_MOBILITY, Mobility Header) */
+ "udplite", /* 136 (UDPLite) */
+ "mpls-in-ip", /* 137 (MPLS-in-IP) */
+ "manet", /* 138 (MANET Protocols) */
+ "hip", /* 139 (Host Identity Protocol) */
+ "shim6", /* 140 (Shim6 Protocol) */
+ "wesp", /* 141 (Wrapped Encapsulating Security Payload) */
+ "rohc", /* 142 (Robust Header Compression) */
+ NULL, /* 143 (unassigned) */
+ NULL, /* 144 (unassigned) */
+ NULL, /* 145 (unassigned) */
+ NULL, /* 146 (unassigned) */
+ NULL, /* 147 (unassigned) */
+ NULL, /* 148 (unassigned) */
+ NULL, /* 149 (unassigned) */
+ NULL, /* 150 (unassigned) */
+ NULL, /* 151 (unassigned) */
+ NULL, /* 152 (unassigned) */
+ NULL, /* 153 (unassigned) */
+ NULL, /* 154 (unassigned) */
+ NULL, /* 155 (unassigned) */
+ NULL, /* 156 (unassigned) */
+ NULL, /* 157 (unassigned) */
+ NULL, /* 158 (unassigned) */
+ NULL, /* 159 (unassigned) */
+ NULL, /* 160 (unassigned) */
+ NULL, /* 161 (unassigned) */
+ NULL, /* 162 (unassigned) */
+ NULL, /* 163 (unassigned) */
+ NULL, /* 164 (unassigned) */
+ NULL, /* 165 (unassigned) */
+ NULL, /* 166 (unassigned) */
+ NULL, /* 167 (unassigned) */
+ NULL, /* 168 (unassigned) */
+ NULL, /* 169 (unassigned) */
+ NULL, /* 170 (unassigned) */
+ NULL, /* 171 (unassigned) */
+ NULL, /* 172 (unassigned) */
+ NULL, /* 173 (unassigned) */
+ NULL, /* 174 (unassigned) */
+ NULL, /* 175 (unassigned) */
+ NULL, /* 176 (unassigned) */
+ NULL, /* 177 (unassigned) */
+ NULL, /* 178 (unassigned) */
+ NULL, /* 179 (unassigned) */
+ NULL, /* 180 (unassigned) */
+ NULL, /* 181 (unassigned) */
+ NULL, /* 182 (unassigned) */
+ NULL, /* 183 (unassigned) */
+ NULL, /* 184 (unassigned) */
+ NULL, /* 185 (unassigned) */
+ NULL, /* 186 (unassigned) */
+ NULL, /* 187 (unassigned) */
+ NULL, /* 188 (unassigned) */
+ NULL, /* 189 (unassigned) */
+ NULL, /* 190 (unassigned) */
+ NULL, /* 191 (unassigned) */
+ NULL, /* 192 (unassigned) */
+ NULL, /* 193 (unassigned) */
+ NULL, /* 194 (unassigned) */
+ NULL, /* 195 (unassigned) */
+ NULL, /* 196 (unassigned) */
+ NULL, /* 197 (unassigned) */
+ NULL, /* 198 (unassigned) */
+ NULL, /* 199 (unassigned) */
+ NULL, /* 200 (unassigned) */
+ NULL, /* 201 (unassigned) */
+ NULL, /* 202 (unassigned) */
+ NULL, /* 203 (unassigned) */
+ NULL, /* 204 (unassigned) */
+ NULL, /* 205 (unassigned) */
+ NULL, /* 206 (unassigned) */
+ NULL, /* 207 (unassigned) */
+ NULL, /* 208 (unassigned) */
+ NULL, /* 209 (unassigned) */
+ NULL, /* 210 (unassigned) */
+ NULL, /* 211 (unassigned) */
+ NULL, /* 212 (unassigned) */
+ NULL, /* 213 (unassigned) */
+ NULL, /* 214 (unassigned) */
+ NULL, /* 215 (unassigned) */
+ NULL, /* 216 (unassigned) */
+ NULL, /* 217 (unassigned) */
+ NULL, /* 218 (unassigned) */
+ NULL, /* 219 (unassigned) */
+ NULL, /* 220 (unassigned) */
+ NULL, /* 221 (unassigned) */
+ NULL, /* 222 (unassigned) */
+ NULL, /* 223 (unassigned) */
+ NULL, /* 224 (unassigned) */
+ NULL, /* 225 (unassigned) */
+ NULL, /* 226 (unassigned) */
+ NULL, /* 227 (unassigned) */
+ NULL, /* 228 (unassigned) */
+ NULL, /* 229 (unassigned) */
+ NULL, /* 230 (unassigned) */
+ NULL, /* 231 (unassigned) */
+ NULL, /* 232 (unassigned) */
+ NULL, /* 233 (unassigned) */
+ NULL, /* 234 (unassigned) */
+ NULL, /* 235 (unassigned) */
+ NULL, /* 236 (unassigned) */
+ NULL, /* 237 (unassigned) */
+ NULL, /* 238 (unassigned) */
+ NULL, /* 239 (unassigned) */
+ NULL, /* 240 (unassigned) */
+ NULL, /* 241 (unassigned) */
+ NULL, /* 242 (unassigned) */
+ NULL, /* 243 (unassigned) */
+ NULL, /* 244 (unassigned) */
+ NULL, /* 245 (unassigned) */
+ NULL, /* 246 (unassigned) */
+ NULL, /* 247 (unassigned) */
+ NULL, /* 248 (unassigned) */
+ NULL, /* 249 (unassigned) */
+ NULL, /* 250 (unassigned) */
+ NULL, /* 251 (unassigned) */
+ NULL, /* 252 (unassigned) */
+ "exptest-253", /* 253 (Use for experimentation and testing,
+ * RFC 3692)
+ */
+ "exptest-254", /* 254 (Use for experimentation and testing,
+ * RFC 3692)
+ */
+ "reserved", /* 255 (reserved) */
+};
+
+/* The function enforces the array index to be 8-bit. */
+const char *
+netdb_protoname (const nd_uint8_t protoid)
+{
+ return netdb_protocol_names[protoid];
+}
#ifdef __rtems__
#include "rtems-bsd-tcpdump-ipproto-data.h"
#endif /* __rtems__ */
diff --git a/freebsd/contrib/tcpdump/ipproto.h b/freebsd/contrib/tcpdump/ipproto.h
index 4719d4d3..aeefc809 100644
--- a/freebsd/contrib/tcpdump/ipproto.h
+++ b/freebsd/contrib/tcpdump/ipproto.h
@@ -36,6 +36,7 @@
*/
extern const struct tok ipproto_values[];
+extern const char *netdb_protoname (const nd_uint8_t);
#ifndef IPPROTO_IP
#define IPPROTO_IP 0 /* dummy for IP */
@@ -109,7 +110,7 @@ extern const struct tok ipproto_values[];
* It appears that 62 used to be used, even though that's assigned to
* a protocol called CFTP; however, the only reference for CFTP is a
* Network Message from BBN back in 1982, so, for now, we support 62,
- * aas well as 135, as a protocol number for mobility headers.
+ * as well as 135, as a protocol number for mobility headers.
*/
#define IPPROTO_MOBILITY_OLD 62
#endif
diff --git a/freebsd/contrib/tcpdump/l2vpn.c b/freebsd/contrib/tcpdump/l2vpn.c
index 5a77136b..72831bf8 100644
--- a/freebsd/contrib/tcpdump/l2vpn.c
+++ b/freebsd/contrib/tcpdump/l2vpn.c
@@ -16,7 +16,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/freebsd/contrib/tcpdump/l2vpn.h b/freebsd/contrib/tcpdump/l2vpn.h
index d93abf15..98b6fcc8 100644
--- a/freebsd/contrib/tcpdump/l2vpn.h
+++ b/freebsd/contrib/tcpdump/l2vpn.h
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
extern const struct tok l2vpn_encaps_values[];
diff --git a/freebsd/contrib/tcpdump/netdissect-stdinc.h b/freebsd/contrib/tcpdump/netdissect-stdinc.h
index c7070f0a..8282c584 100644
--- a/freebsd/contrib/tcpdump/netdissect-stdinc.h
+++ b/freebsd/contrib/tcpdump/netdissect-stdinc.h
@@ -394,6 +394,11 @@ struct in6_addr {
* end of Apple deprecation workaround macros
*/
+/*
+ * Function attributes, for various compilers.
+ */
+#include "funcattrs.h"
+
#ifndef min
#define min(a,b) ((a)>(b)?(b):(a))
#endif
diff --git a/freebsd/contrib/tcpdump/netdissect.h b/freebsd/contrib/tcpdump/netdissect.h
index 1d28c0b7..105c490a 100644
--- a/freebsd/contrib/tcpdump/netdissect.h
+++ b/freebsd/contrib/tcpdump/netdissect.h
@@ -82,19 +82,13 @@ extern int32_t thiszone; /* seconds offset from gmt to local time */
extern const char istr[];
#if !defined(HAVE_SNPRINTF)
-int snprintf (char *str, size_t sz, const char *format, ...)
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 3, 4)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
+int snprintf (char *str, size_t sz, FORMAT_STRING(const char *format), ...)
+ PRINTFLIKE(3, 4);
#endif /* !defined(HAVE_SNPRINTF) */
#if !defined(HAVE_VSNPRINTF)
-int vsnprintf (char *str, size_t sz, const char *format, va_list ap)
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 3, 0)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
+int vsnprintf (char *str, size_t sz, FORMAT_STRING(const char *format),
+ va_list ap) PRINTFLIKE(3, 0);
#endif /* !defined(HAVE_VSNPRINTF) */
#ifndef HAVE_STRLCAT
@@ -531,7 +525,7 @@ extern void ipx_netbios_print(netdissect_options *, const u_char *, u_int);
extern void ipx_print(netdissect_options *, const u_char *, u_int);
extern void isakmp_print(netdissect_options *, const u_char *, u_int, const u_char *);
extern void isakmp_rfc3948_print(netdissect_options *, const u_char *, u_int, const u_char *);
-extern void isoclns_print(netdissect_options *, const u_char *, u_int, u_int);
+extern void isoclns_print(netdissect_options *, const u_char *, u_int);
extern void krb_print(netdissect_options *, const u_char *);
extern void l2tp_print(netdissect_options *, const u_char *, u_int);
extern void lane_print(netdissect_options *, const u_char *, u_int, u_int);
diff --git a/freebsd/contrib/tcpdump/nlpid.c b/freebsd/contrib/tcpdump/nlpid.c
index 5060aae6..6ba92f4e 100644
--- a/freebsd/contrib/tcpdump/nlpid.c
+++ b/freebsd/contrib/tcpdump/nlpid.c
@@ -16,7 +16,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/freebsd/contrib/tcpdump/nlpid.h b/freebsd/contrib/tcpdump/nlpid.h
index 63a2e709..a3a69054 100644
--- a/freebsd/contrib/tcpdump/nlpid.h
+++ b/freebsd/contrib/tcpdump/nlpid.h
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
extern const struct tok nlpid_values[];
diff --git a/freebsd/contrib/tcpdump/oui.c b/freebsd/contrib/tcpdump/oui.c
index 9fb86c6f..922c6e9e 100644
--- a/freebsd/contrib/tcpdump/oui.c
+++ b/freebsd/contrib/tcpdump/oui.c
@@ -16,7 +16,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/freebsd/contrib/tcpdump/oui.h b/freebsd/contrib/tcpdump/oui.h
index a85f883d..a9f732a7 100644
--- a/freebsd/contrib/tcpdump/oui.h
+++ b/freebsd/contrib/tcpdump/oui.h
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
extern const struct tok oui_values[];
diff --git a/freebsd/contrib/tcpdump/print-802_11.c b/freebsd/contrib/tcpdump/print-802_11.c
index 3310eb16..990b5777 100644
--- a/freebsd/contrib/tcpdump/print-802_11.c
+++ b/freebsd/contrib/tcpdump/print-802_11.c
@@ -1045,10 +1045,6 @@ parse_elements(netdissect_options *ndo,
if (ssid.length != 0) {
if (ssid.length > sizeof(ssid.ssid) - 1)
return 0;
- if (!ND_TTEST2(*(p + offset), ssid.length))
- return 0;
- if (length < ssid.length)
- return 0;
memcpy(&ssid.ssid, p + offset, ssid.length);
offset += ssid.length;
length -= ssid.length;
@@ -1074,10 +1070,6 @@ parse_elements(netdissect_options *ndo,
if (challenge.length >
sizeof(challenge.text) - 1)
return 0;
- if (!ND_TTEST2(*(p + offset), challenge.length))
- return 0;
- if (length < challenge.length)
- return 0;
memcpy(&challenge.text, p + offset,
challenge.length);
offset += challenge.length;
@@ -1103,10 +1095,6 @@ parse_elements(netdissect_options *ndo,
if (rates.length != 0) {
if (rates.length > sizeof rates.rate)
return 0;
- if (!ND_TTEST2(*(p + offset), rates.length))
- return 0;
- if (length < rates.length)
- return 0;
memcpy(&rates.rate, p + offset, rates.length);
offset += rates.length;
length -= rates.length;
@@ -1195,8 +1183,7 @@ parse_elements(netdissect_options *ndo,
offset += 3;
length -= 3;
- memcpy(tim.bitmap, p + (tim.length - 3),
- (tim.length - 3));
+ memcpy(tim.bitmap, p + offset, tim.length - 3);
offset += tim.length - 3;
length -= tim.length - 3;
/*
diff --git a/freebsd/contrib/tcpdump/print-802_15_4.c b/freebsd/contrib/tcpdump/print-802_15_4.c
index e1c8b7b5..2b4a6bb2 100644
--- a/freebsd/contrib/tcpdump/print-802_15_4.c
+++ b/freebsd/contrib/tcpdump/print-802_15_4.c
@@ -44,146 +44,188 @@ static const char *ftypes[] = {
"Data", /* 1 */
"ACK", /* 2 */
"Command", /* 3 */
- "Reserved", /* 4 */
- "Reserved", /* 5 */
- "Reserved", /* 6 */
- "Reserved", /* 7 */
+ "Reserved (0x4)", /* 4 */
+ "Reserved (0x5)", /* 5 */
+ "Reserved (0x6)", /* 6 */
+ "Reserved (0x7)", /* 7 */
};
-static int
-extract_header_length(uint16_t fc)
-{
- int len = 0;
-
- switch ((fc >> 10) & 0x3) {
- case 0x00:
- if (fc & (1 << 6)) /* intra-PAN with none dest addr */
- return -1;
- break;
- case 0x01:
- return -1;
- case 0x02:
- len += 4;
- break;
- case 0x03:
- len += 10;
- break;
- }
-
- switch ((fc >> 14) & 0x3) {
- case 0x00:
- break;
- case 0x01:
- return -1;
- case 0x02:
- len += 4;
- break;
- case 0x03:
- len += 10;
- break;
- }
-
- if (fc & (1 << 6)) {
- if (len < 2)
- return -1;
- len -= 2;
- }
-
- return len;
-}
-
+/*
+ * Frame Control subfields.
+ */
+#define FC_FRAME_TYPE(fc) ((fc) & 0x7)
+#define FC_SECURITY_ENABLED 0x0008
+#define FC_FRAME_PENDING 0x0010
+#define FC_ACK_REQUEST 0x0020
+#define FC_PAN_ID_COMPRESSION 0x0040
+#define FC_DEST_ADDRESSING_MODE(fc) (((fc) >> 10) & 0x3)
+#define FC_FRAME_VERSION(fc) (((fc) >> 12) & 0x3)
+#define FC_SRC_ADDRESSING_MODE(fc) (((fc) >> 14) & 0x3)
+
+#define FC_ADDRESSING_MODE_NONE 0x00
+#define FC_ADDRESSING_MODE_RESERVED 0x01
+#define FC_ADDRESSING_MODE_SHORT 0x02
+#define FC_ADDRESSING_MODE_LONG 0x03
u_int
ieee802_15_4_if_print(netdissect_options *ndo,
const struct pcap_pkthdr *h, const u_char *p)
{
u_int caplen = h->caplen;
- int hdrlen;
+ u_int hdrlen;
uint16_t fc;
uint8_t seq;
+ uint16_t panid = 0;
if (caplen < 3) {
- ND_PRINT((ndo, "[|802.15.4] %x", caplen));
+ ND_PRINT((ndo, "[|802.15.4]"));
return caplen;
}
+ hdrlen = 3;
fc = EXTRACT_LE_16BITS(p);
- hdrlen = extract_header_length(fc);
-
seq = EXTRACT_LE_8BITS(p + 2);
p += 3;
caplen -= 3;
- ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[fc & 0x7]));
+ ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[FC_FRAME_TYPE(fc)]));
if (ndo->ndo_vflag)
ND_PRINT((ndo,"seq %02x ", seq));
- if (hdrlen == -1) {
- ND_PRINT((ndo,"invalid! "));
- return caplen;
- }
-
-
- if (!ndo->ndo_vflag) {
- p+= hdrlen;
- caplen -= hdrlen;
- } else {
- uint16_t panid = 0;
- switch ((fc >> 10) & 0x3) {
- case 0x00:
+ /*
+ * Destination address and PAN ID, if present.
+ */
+ switch (FC_DEST_ADDRESSING_MODE(fc)) {
+ case FC_ADDRESSING_MODE_NONE:
+ if (fc & FC_PAN_ID_COMPRESSION) {
+ /*
+ * PAN ID compression; this requires that both
+ * the source and destination addresses be present,
+ * but the destination address is missing.
+ */
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
ND_PRINT((ndo,"none "));
- break;
- case 0x01:
+ break;
+ case FC_ADDRESSING_MODE_RESERVED:
+ if (ndo->ndo_vflag)
ND_PRINT((ndo,"reserved destination addressing mode"));
- return 0;
- case 0x02:
- panid = EXTRACT_LE_16BITS(p);
- p += 2;
+ return hdrlen;
+ case FC_ADDRESSING_MODE_SHORT:
+ if (caplen < 2) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
+ }
+ panid = EXTRACT_LE_16BITS(p);
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ if (caplen < 2) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
- p += 2;
- break;
- case 0x03:
- panid = EXTRACT_LE_16BITS(p);
- p += 2;
- ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
- p += 8;
- break;
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ break;
+ case FC_ADDRESSING_MODE_LONG:
+ if (caplen < 2) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
+ }
+ panid = EXTRACT_LE_16BITS(p);
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ if (caplen < 8) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
}
+ if (ndo->ndo_vflag)
+ ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
+ p += 8;
+ caplen -= 8;
+ hdrlen += 8;
+ break;
+ }
+ if (ndo->ndo_vflag)
ND_PRINT((ndo,"< "));
- switch ((fc >> 14) & 0x3) {
- case 0x00:
+ /*
+ * Source address and PAN ID, if present.
+ */
+ switch (FC_SRC_ADDRESSING_MODE(fc)) {
+ case FC_ADDRESSING_MODE_NONE:
+ if (ndo->ndo_vflag)
ND_PRINT((ndo,"none "));
- break;
- case 0x01:
+ break;
+ case FC_ADDRESSING_MODE_RESERVED:
+ if (ndo->ndo_vflag)
ND_PRINT((ndo,"reserved source addressing mode"));
- return 0;
- case 0x02:
- if (!(fc & (1 << 6))) {
- panid = EXTRACT_LE_16BITS(p);
- p += 2;
+ return 0;
+ case FC_ADDRESSING_MODE_SHORT:
+ if (!(fc & FC_PAN_ID_COMPRESSION)) {
+ /*
+ * The source PAN ID is not compressed out, so
+ * fetch it. (Otherwise, we'll use the destination
+ * PAN ID, fetched above.)
+ */
+ if (caplen < 2) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
}
- ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
+ panid = EXTRACT_LE_16BITS(p);
p += 2;
- break;
- case 0x03:
- if (!(fc & (1 << 6))) {
- panid = EXTRACT_LE_16BITS(p);
- p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ }
+ if (caplen < 2) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
+ ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ break;
+ case FC_ADDRESSING_MODE_LONG:
+ if (!(fc & FC_PAN_ID_COMPRESSION)) {
+ /*
+ * The source PAN ID is not compressed out, so
+ * fetch it. (Otherwise, we'll use the destination
+ * PAN ID, fetched above.)
+ */
+ if (caplen < 2) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
}
- ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
- p += 8;
- break;
+ panid = EXTRACT_LE_16BITS(p);
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
}
-
- caplen -= hdrlen;
+ if (caplen < 8) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
+ ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
+ p += 8;
+ caplen -= 8;
+ hdrlen += 8;
+ break;
}
if (!ndo->ndo_suppress_default_print)
ND_DEFAULTPRINT(p, caplen);
- return 0;
+ return hdrlen;
}
#ifdef __rtems__
#include "rtems-bsd-tcpdump-print-802_15_4-data.h"
diff --git a/freebsd/contrib/tcpdump/print-aodv.c b/freebsd/contrib/tcpdump/print-aodv.c
index b1a977c1..98677d5b 100644
--- a/freebsd/contrib/tcpdump/print-aodv.c
+++ b/freebsd/contrib/tcpdump/print-aodv.c
@@ -48,7 +48,9 @@
#include "addrtoname.h"
#include "extract.h"
-
+/*
+ * RFC 3561
+ */
struct aodv_rreq {
uint8_t rreq_type; /* AODV message type (1) */
uint8_t rreq_flags; /* various flags */
@@ -184,12 +186,17 @@ aodv_extension(netdissect_options *ndo,
{
const struct aodv_hello *ah;
+ ND_TCHECK(*ep);
switch (ep->type) {
case AODV_EXT_HELLO:
ah = (const struct aodv_hello *)(const void *)ep;
ND_TCHECK(*ah);
if (length < sizeof(struct aodv_hello))
goto trunc;
+ if (ep->length < 4) {
+ ND_PRINT((ndo, "\n\text HELLO - bad length %u", ep->length));
+ break;
+ }
ND_PRINT((ndo, "\n\text HELLO %ld ms",
(unsigned long)EXTRACT_32BITS(&ah->interval)));
break;
diff --git a/freebsd/contrib/tcpdump/print-arp.c b/freebsd/contrib/tcpdump/print-arp.c
index 86da2bcc..b19e1036 100644
--- a/freebsd/contrib/tcpdump/print-arp.c
+++ b/freebsd/contrib/tcpdump/print-arp.c
@@ -84,7 +84,7 @@ struct arp_pkthdr {
u_char ar_tha[]; /* target hardware address */
u_char ar_tpa[]; /* target protocol address */
#endif
-#define ar_sha(ap) (((const u_char *)((ap)+1))+0)
+#define ar_sha(ap) (((const u_char *)((ap)+1))+ 0)
#define ar_spa(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln)
#define ar_tha(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln+(ap)->ar_pln)
#define ar_tpa(ap) (((const u_char *)((ap)+1))+2*(ap)->ar_hln+(ap)->ar_pln)
@@ -196,6 +196,30 @@ isnonzero(const u_char *a, size_t len)
}
static void
+tpaddr_print_ip(netdissect_options *ndo,
+ const struct arp_pkthdr *ap, u_short pro)
+{
+ if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
+ ND_PRINT((ndo, "<wrong proto type>"));
+ else if (PROTO_LEN(ap) != 4)
+ ND_PRINT((ndo, "<wrong len>"));
+ else
+ ND_PRINT((ndo, "%s", ipaddr_string(ndo, TPA(ap))));
+}
+
+static void
+spaddr_print_ip(netdissect_options *ndo,
+ const struct arp_pkthdr *ap, u_short pro)
+{
+ if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
+ ND_PRINT((ndo, "<wrong proto type>"));
+ else if (PROTO_LEN(ap) != 4)
+ ND_PRINT((ndo, "<wrong len>"));
+ else
+ ND_PRINT((ndo, "%s", ipaddr_string(ndo, SPA(ap))));
+}
+
+static void
atmarp_addr_print(netdissect_options *ndo,
const u_char *ha, u_int ha_len, const u_char *srca,
u_int srca_len)
@@ -211,6 +235,30 @@ atmarp_addr_print(netdissect_options *ndo,
}
static void
+atmarp_tpaddr_print(netdissect_options *ndo,
+ const struct atmarp_pkthdr *ap, u_short pro)
+{
+ if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
+ ND_PRINT((ndo, "<wrong proto type>"));
+ else if (ATMTPROTO_LEN(ap) != 4)
+ ND_PRINT((ndo, "<wrong tplen>"));
+ else
+ ND_PRINT((ndo, "%s", ipaddr_string(ndo, ATMTPA(ap))));
+}
+
+static void
+atmarp_spaddr_print(netdissect_options *ndo,
+ const struct atmarp_pkthdr *ap, u_short pro)
+{
+ if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
+ ND_PRINT((ndo, "<wrong proto type>"));
+ else if (ATMSPROTO_LEN(ap) != 4)
+ ND_PRINT((ndo, "<wrong splen>"));
+ else
+ ND_PRINT((ndo, "%s", ipaddr_string(ndo, ATMSPA(ap))));
+}
+
+static void
atmarp_print(netdissect_options *ndo,
const u_char *bp, u_int length, u_int caplen)
{
@@ -258,18 +306,21 @@ atmarp_print(netdissect_options *ndo,
switch (op) {
case ARPOP_REQUEST:
- ND_PRINT((ndo, "who-has %s", ipaddr_string(ndo, ATMTPA(ap))));
+ ND_PRINT((ndo, "who-has "));
+ atmarp_tpaddr_print(ndo, ap, pro);
if (ATMTHRD_LEN(ap) != 0) {
ND_PRINT((ndo, " ("));
atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap),
ATMTSA(ap), ATMTSLN(ap));
ND_PRINT((ndo, ")"));
}
- ND_PRINT((ndo, "tell %s", ipaddr_string(ndo, ATMSPA(ap))));
+ ND_PRINT((ndo, " tell "));
+ atmarp_spaddr_print(ndo, ap, pro);
break;
case ARPOP_REPLY:
- ND_PRINT((ndo, "%s is-at ", ipaddr_string(ndo, ATMSPA(ap))));
+ atmarp_spaddr_print(ndo, ap, pro);
+ ND_PRINT((ndo, " is-at "));
atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap),
ATMSSLN(ap));
break;
@@ -286,11 +337,13 @@ atmarp_print(netdissect_options *ndo,
case ARPOP_INVREPLY:
atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap),
ATMSSLN(ap));
- ND_PRINT((ndo, "at %s", ipaddr_string(ndo, ATMSPA(ap))));
+ ND_PRINT((ndo, "at "));
+ atmarp_spaddr_print(ndo, ap, pro);
break;
case ARPOP_NAK:
- ND_PRINT((ndo, "for %s", ipaddr_string(ndo, ATMSPA(ap))));
+ ND_PRINT((ndo, "for "));
+ atmarp_spaddr_print(ndo, ap, pro);
break;
default:
@@ -338,7 +391,7 @@ arp_print(netdissect_options *ndo,
break;
}
- if (!ND_TTEST2(*ar_tpa(ap), PROTO_LEN(ap))) {
+ if (!ND_TTEST2(*TPA(ap), PROTO_LEN(ap))) {
ND_PRINT((ndo, "%s", tstr));
ND_DEFAULTPRINT((const u_char *)ap, length);
return;
@@ -373,16 +426,18 @@ arp_print(netdissect_options *ndo,
switch (op) {
case ARPOP_REQUEST:
- ND_PRINT((ndo, "who-has %s", ipaddr_string(ndo, TPA(ap))));
+ ND_PRINT((ndo, "who-has "));
+ tpaddr_print_ip(ndo, ap, pro);
if (isnonzero((const u_char *)THA(ap), HRD_LEN(ap)))
ND_PRINT((ndo, " (%s)",
linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap))));
- ND_PRINT((ndo, " tell %s", ipaddr_string(ndo, SPA(ap))));
+ ND_PRINT((ndo, " tell "));
+ spaddr_print_ip(ndo, ap, pro);
break;
case ARPOP_REPLY:
- ND_PRINT((ndo, "%s is-at %s",
- ipaddr_string(ndo, SPA(ap)),
+ spaddr_print_ip(ndo, ap, pro);
+ ND_PRINT((ndo, " is-at %s",
linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap))));
break;
@@ -393,9 +448,9 @@ arp_print(netdissect_options *ndo,
break;
case ARPOP_REVREPLY:
- ND_PRINT((ndo, "%s at %s",
- linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap)),
- ipaddr_string(ndo, TPA(ap))));
+ ND_PRINT((ndo, "%s at ",
+ linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap))));
+ tpaddr_print_ip(ndo, ap, pro);
break;
case ARPOP_INVREQUEST:
@@ -405,9 +460,9 @@ arp_print(netdissect_options *ndo,
break;
case ARPOP_INVREPLY:
- ND_PRINT((ndo,"%s at %s",
- linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap)),
- ipaddr_string(ndo, SPA(ap))));
+ ND_PRINT((ndo,"%s at ",
+ linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap))));
+ spaddr_print_ip(ndo, ap, pro);
break;
default:
diff --git a/freebsd/contrib/tcpdump/print-atm.c b/freebsd/contrib/tcpdump/print-atm.c
index 1d1578f6..a846c83b 100644
--- a/freebsd/contrib/tcpdump/print-atm.c
+++ b/freebsd/contrib/tcpdump/print-atm.c
@@ -268,7 +268,7 @@ atm_if_print(netdissect_options *ndo,
if (*p == LLC_UI) {
if (ndo->ndo_eflag)
ND_PRINT((ndo, "CNLPID "));
- isoclns_print(ndo, p + 1, length - 1, caplen - 1);
+ isoclns_print(ndo, p + 1, length - 1);
return hdrlen;
}
diff --git a/freebsd/contrib/tcpdump/print-beep.c b/freebsd/contrib/tcpdump/print-beep.c
index 9a95fbb7..e3a21f51 100644
--- a/freebsd/contrib/tcpdump/print-beep.c
+++ b/freebsd/contrib/tcpdump/print-beep.c
@@ -34,9 +34,17 @@
*/
static int
-l_strnstart(const char *tstr1, u_int tl1, const char *str2, u_int l2)
+l_strnstart(netdissect_options *ndo, const char *tstr1, u_int tl1,
+ const char *str2, u_int l2)
{
-
+ if (!ND_TTEST2(*str2, tl1)) {
+ /*
+ * We don't have tl1 bytes worth of captured data
+ * for the string, so we can't check for this
+ * string.
+ */
+ return 0;
+ }
if (tl1 > l2)
return 0;
@@ -47,19 +55,19 @@ void
beep_print(netdissect_options *ndo, const u_char *bp, u_int length)
{
- if (l_strnstart("MSG", 4, (const char *)bp, length)) /* A REQuest */
+ if (l_strnstart(ndo, "MSG", 4, (const char *)bp, length)) /* A REQuest */
ND_PRINT((ndo, " BEEP MSG"));
- else if (l_strnstart("RPY ", 4, (const char *)bp, length))
+ else if (l_strnstart(ndo, "RPY ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP RPY"));
- else if (l_strnstart("ERR ", 4, (const char *)bp, length))
+ else if (l_strnstart(ndo, "ERR ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP ERR"));
- else if (l_strnstart("ANS ", 4, (const char *)bp, length))
+ else if (l_strnstart(ndo, "ANS ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP ANS"));
- else if (l_strnstart("NUL ", 4, (const char *)bp, length))
+ else if (l_strnstart(ndo, "NUL ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP NUL"));
- else if (l_strnstart("SEQ ", 4, (const char *)bp, length))
+ else if (l_strnstart(ndo, "SEQ ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP SEQ"));
- else if (l_strnstart("END", 4, (const char *)bp, length))
+ else if (l_strnstart(ndo, "END", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP END"));
else
ND_PRINT((ndo, " BEEP (payload or undecoded)"));
diff --git a/freebsd/contrib/tcpdump/print-bfd.c b/freebsd/contrib/tcpdump/print-bfd.c
index 5eb8d174..bec521c1 100644
--- a/freebsd/contrib/tcpdump/print-bfd.c
+++ b/freebsd/contrib/tcpdump/print-bfd.c
@@ -16,7 +16,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: Bidirectional Forwarding Detection (BFD) printer */
diff --git a/freebsd/contrib/tcpdump/print-bgp.c b/freebsd/contrib/tcpdump/print-bgp.c
index ae80d6b7..3d1e2f4d 100644
--- a/freebsd/contrib/tcpdump/print-bgp.c
+++ b/freebsd/contrib/tcpdump/print-bgp.c
@@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Extensively modified by Hannes Gredler (hannes@juniper.net) for more
+ * Extensively modified by Hannes Gredler (hannes@gredler.at) for more
* complete BGP support.
*/
@@ -762,11 +762,18 @@ decode_rt_routing_info(netdissect_options *ndo,
{
uint8_t route_target[8];
u_int plen;
+ char asbuf[sizeof(astostr)]; /* bgp_vpn_rd_print() overwrites astostr */
+ /* NLRI "prefix length" from RFC 2858 Section 4. */
ND_TCHECK(pptr[0]);
plen = pptr[0]; /* get prefix length */
+ /* NLRI "prefix" (ibid), valid lengths are { 0, 32, 33, ..., 96 } bits.
+ * RFC 4684 Section 4 defines the layout of "origin AS" and "route
+ * target" fields inside the "prefix" depending on its length.
+ */
if (0 == plen) {
+ /* Without "origin AS", without "route target". */
snprintf(buf, buflen, "default route target");
return 1;
}
@@ -774,20 +781,29 @@ decode_rt_routing_info(netdissect_options *ndo,
if (32 > plen)
return -1;
+ /* With at least "origin AS", possibly with "route target". */
+ ND_TCHECK_32BITS(pptr + 1);
+ as_printf(ndo, asbuf, sizeof(asbuf), EXTRACT_32BITS(pptr + 1));
+
plen-=32; /* adjust prefix length */
if (64 < plen)
return -1;
+ /* From now on (plen + 7) / 8 evaluates to { 0, 1, 2, ..., 8 }
+ * and gives the number of octets in the variable-length "route
+ * target" field inside this NLRI "prefix". Look for it.
+ */
memset(&route_target, 0, sizeof(route_target));
- ND_TCHECK2(pptr[1], (plen + 7) / 8);
- memcpy(&route_target, &pptr[1], (plen + 7) / 8);
+ ND_TCHECK2(pptr[5], (plen + 7) / 8);
+ memcpy(&route_target, &pptr[5], (plen + 7) / 8);
+ /* Which specification says to do this? */
if (plen % 8) {
((u_char *)&route_target)[(plen + 7) / 8 - 1] &=
((0xff00 >> (plen % 8)) & 0xff);
}
snprintf(buf, buflen, "origin AS: %s, route target %s",
- as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(pptr+1)),
+ asbuf,
bgp_vpn_rd_print(ndo, (u_char *)&route_target));
return 5 + (plen + 7) / 8;
@@ -901,6 +917,7 @@ static const struct tok bgp_multicast_vpn_route_type_values[] = {
{ BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"},
{ BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"},
{ BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"},
+ { 0, NULL}
};
static int
@@ -965,13 +982,13 @@ decode_multicast_vpn(netdissect_options *ndo,
case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */
case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN:
- ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN);
+ ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4);
offset = strlen(buf);
snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
bgp_vpn_rd_print(ndo, pptr),
as_printf(ndo, astostr, sizeof(astostr),
EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
- pptr += BGP_VPN_RD_LEN;
+ pptr += BGP_VPN_RD_LEN + 4;
bgp_vpn_sg_print(ndo, pptr, buf, buflen);
break;
@@ -1406,6 +1423,7 @@ bgp_attr_print(netdissect_options *ndo,
ND_TCHECK(tptr[0]);
ND_PRINT((ndo, "%s", tok2str(bgp_as_path_segment_open_values,
"?", tptr[0])));
+ ND_TCHECK(tptr[1]);
for (i = 0; i < tptr[1] * as_size; i += as_size) {
ND_TCHECK2(tptr[2 + i], as_size);
ND_PRINT((ndo, "%s ",
@@ -1725,7 +1743,7 @@ bgp_attr_print(netdissect_options *ndo,
ND_PRINT((ndo, ", no SNPA"));
}
- while (len - (tptr - pptr) > 0) {
+ while (tptr < pptr + len) {
switch (af<<8 | safi) {
case (AFNUM_INET<<8 | SAFNUM_UNICAST):
case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
@@ -1893,7 +1911,7 @@ bgp_attr_print(netdissect_options *ndo,
tptr += 3;
- while (len - (tptr - pptr) > 0) {
+ while (tptr < pptr + len) {
switch (af<<8 | safi) {
case (AFNUM_INET<<8 | SAFNUM_UNICAST):
case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
@@ -2122,11 +2140,11 @@ bgp_attr_print(netdissect_options *ndo,
{
uint8_t tunnel_type, flags;
+ ND_TCHECK2(tptr[0], 5);
tunnel_type = *(tptr+1);
flags = *tptr;
tlen = len;
- ND_TCHECK2(tptr[0], 5);
ND_PRINT((ndo, "\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u",
tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type),
tunnel_type,
@@ -2181,35 +2199,42 @@ bgp_attr_print(netdissect_options *ndo,
uint8_t type;
uint16_t length;
- ND_TCHECK2(tptr[0], 3);
-
tlen = len;
while (tlen >= 3) {
+ ND_TCHECK2(tptr[0], 3);
+
type = *tptr;
length = EXTRACT_16BITS(tptr+1);
+ tptr += 3;
+ tlen -= 3;
ND_PRINT((ndo, "\n\t %s TLV (%u), length %u",
tok2str(bgp_aigp_values, "Unknown", type),
type, length));
+ if (length < 3)
+ goto trunc;
+ length -= 3;
+
/*
* Check if we can read the TLV data.
*/
- ND_TCHECK2(tptr[3], length - 3);
+ ND_TCHECK2(tptr[3], length);
switch (type) {
case BGP_AIGP_TLV:
- ND_TCHECK2(tptr[3], 8);
+ if (length < 8)
+ goto trunc;
ND_PRINT((ndo, ", metric %" PRIu64,
- EXTRACT_64BITS(tptr+3)));
+ EXTRACT_64BITS(tptr)));
break;
default:
if (ndo->ndo_vflag <= 1) {
- print_unknown_data(ndo, tptr+3,"\n\t ", length-3);
+ print_unknown_data(ndo, tptr,"\n\t ", length);
}
}
diff --git a/freebsd/contrib/tcpdump/print-bootp.c b/freebsd/contrib/tcpdump/print-bootp.c
index 3f061769..c9f687ff 100644
--- a/freebsd/contrib/tcpdump/print-bootp.c
+++ b/freebsd/contrib/tcpdump/print-bootp.c
@@ -328,6 +328,7 @@ bootp_print(netdissect_options *ndo,
if (EXTRACT_16BITS(&bp->bp_secs))
ND_PRINT((ndo, ", secs %d", EXTRACT_16BITS(&bp->bp_secs)));
+ ND_TCHECK(bp->bp_flags);
ND_PRINT((ndo, ", Flags [%s]",
bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags))));
if (ndo->ndo_vflag > 1)
diff --git a/freebsd/contrib/tcpdump/print-cfm.c b/freebsd/contrib/tcpdump/print-cfm.c
index ddb91e06..897dc032 100644
--- a/freebsd/contrib/tcpdump/print-cfm.c
+++ b/freebsd/contrib/tcpdump/print-cfm.c
@@ -18,7 +18,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: IEEE 802.1ag Connectivity Fault Management (CFM) protocols printer */
@@ -223,7 +223,7 @@ static const struct tok cfm_tlv_senderid_chassisid_values[] = {
static int
cfm_network_addr_print(netdissect_options *ndo,
- register const u_char *tptr)
+ register const u_char *tptr, const u_int length)
{
u_int network_addr_type;
u_int hexdump = FALSE;
@@ -233,6 +233,11 @@ cfm_network_addr_print(netdissect_options *ndo,
* 802.1ab specifies that this field width
* is only once octet
*/
+ if (length < 1) {
+ ND_PRINT((ndo, "\n\t Network Address Type (invalid, no data"));
+ return hexdump;
+ }
+ /* The calling function must make any due ND_TCHECK calls. */
network_addr_type = *tptr;
ND_PRINT((ndo, "\n\t Network Address Type %s (%u)",
tok2str(af_values, "Unknown", network_addr_type),
@@ -243,10 +248,20 @@ cfm_network_addr_print(netdissect_options *ndo,
*/
switch(network_addr_type) {
case AFNUM_INET:
+ if (length != 1 + 4) {
+ ND_PRINT((ndo, "(invalid IPv4 address length %u)", length - 1));
+ hexdump = TRUE;
+ break;
+ }
ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr + 1)));
break;
case AFNUM_INET6:
+ if (length != 1 + 16) {
+ ND_PRINT((ndo, "(invalid IPv6 address length %u)", length - 1));
+ hexdump = TRUE;
+ break;
+ }
ND_PRINT((ndo, ", %s", ip6addr_string(ndo, tptr + 1)));
break;
@@ -374,8 +389,11 @@ cfm_print(netdissect_options *ndo,
md_nameformat,
md_namelength));
- /* -2 for the MA short name format and length */
- if (md_namelength > names_data_remaining - 2) {
+ /*
+ * -3 for the MA short name format and length and one byte
+ * of MA short name.
+ */
+ if (md_namelength > names_data_remaining - 3) {
ND_PRINT((ndo, " (too large, must be <= %u)", names_data_remaining - 2));
return;
}
@@ -587,11 +605,12 @@ cfm_print(netdissect_options *ndo,
if (cfm_tlv_len < 1) {
ND_PRINT((ndo, " (too short, must be >= 1)"));
- return;
+ goto next_tlv;
}
/*
* Get the Chassis ID length and check it.
+ * IEEE 802.1Q-2014 Section 21.5.3.1
*/
chassis_id_length = *tptr;
tptr++;
@@ -599,9 +618,14 @@ cfm_print(netdissect_options *ndo,
cfm_tlv_len--;
if (chassis_id_length) {
+ /*
+ * IEEE 802.1Q-2014 Section 21.5.3.2: Chassis ID Subtype, references
+ * IEEE 802.1AB-2005 Section 9.5.2.2, subsequently
+ * IEEE 802.1AB-2016 Section 8.5.2.2: chassis ID subtype
+ */
if (cfm_tlv_len < 1) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
- return;
+ goto next_tlv;
}
chassis_id_type = *tptr;
cfm_tlv_len--;
@@ -614,16 +638,22 @@ cfm_print(netdissect_options *ndo,
if (cfm_tlv_len < chassis_id_length) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
- return;
+ goto next_tlv;
}
+ /* IEEE 802.1Q-2014 Section 21.5.3.3: Chassis ID */
switch (chassis_id_type) {
case CFM_CHASSIS_ID_MAC_ADDRESS:
+ if (chassis_id_length != ETHER_ADDR_LEN) {
+ ND_PRINT((ndo, " (invalid MAC address length)"));
+ hexdump = TRUE;
+ break;
+ }
ND_PRINT((ndo, "\n\t MAC %s", etheraddr_string(ndo, tptr + 1)));
break;
case CFM_CHASSIS_ID_NETWORK_ADDRESS:
- hexdump |= cfm_network_addr_print(ndo, tptr);
+ hexdump |= cfm_network_addr_print(ndo, tptr + 1, chassis_id_length);
break;
case CFM_CHASSIS_ID_INTERFACE_NAME: /* fall through */
@@ -646,38 +676,53 @@ cfm_print(netdissect_options *ndo,
/*
* Check if there is a Management Address.
+ * IEEE 802.1Q-2014 Section 21.5.3.4: Management Address Domain Length
+ * This and all subsequent fields are not present if the TLV length
+ * allows only the above fields.
*/
if (cfm_tlv_len == 0) {
/* No, there isn't; we're done. */
- return;
+ break;
}
+ /* Here mgmt_addr_length stands for the management domain length. */
mgmt_addr_length = *tptr;
tptr++;
tlen--;
cfm_tlv_len--;
+ ND_PRINT((ndo, "\n\t Management Address Domain Length %u", mgmt_addr_length));
if (mgmt_addr_length) {
+ /* IEEE 802.1Q-2014 Section 21.5.3.5: Management Address Domain */
if (cfm_tlv_len < mgmt_addr_length) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
- return;
+ goto next_tlv;
}
cfm_tlv_len -= mgmt_addr_length;
/*
* XXX - this is an OID; print it as such.
*/
+ hex_print(ndo, "\n\t Management Address Domain: ", tptr, mgmt_addr_length);
tptr += mgmt_addr_length;
tlen -= mgmt_addr_length;
+ /*
+ * IEEE 802.1Q-2014 Section 21.5.3.6: Management Address Length
+ * This field is present if Management Address Domain Length is not 0.
+ */
if (cfm_tlv_len < 1) {
- ND_PRINT((ndo, "\n\t (TLV too short)"));
- return;
+ ND_PRINT((ndo, " (Management Address Length is missing)"));
+ hexdump = TRUE;
+ break;
}
-
+
+ /* Here mgmt_addr_length stands for the management address length. */
mgmt_addr_length = *tptr;
tptr++;
tlen--;
cfm_tlv_len--;
+ ND_PRINT((ndo, "\n\t Management Address Length %u", mgmt_addr_length));
if (mgmt_addr_length) {
+ /* IEEE 802.1Q-2014 Section 21.5.3.7: Management Address */
if (cfm_tlv_len < mgmt_addr_length) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
return;
@@ -686,6 +731,7 @@ cfm_print(netdissect_options *ndo,
/*
* XXX - this is a TransportDomain; print it as such.
*/
+ hex_print(ndo, "\n\t Management Address: ", tptr, mgmt_addr_length);
tptr += mgmt_addr_length;
tlen -= mgmt_addr_length;
}
@@ -709,6 +755,7 @@ cfm_print(netdissect_options *ndo,
if (hexdump || ndo->ndo_vflag > 1)
print_unknown_data(ndo, tlv_ptr, "\n\t ", cfm_tlv_len);
+next_tlv:
tptr+=cfm_tlv_len;
tlen-=cfm_tlv_len;
}
diff --git a/freebsd/contrib/tcpdump/print-chdlc.c b/freebsd/contrib/tcpdump/print-chdlc.c
index 5ccb849f..03ae73f6 100644
--- a/freebsd/contrib/tcpdump/print-chdlc.c
+++ b/freebsd/contrib/tcpdump/print-chdlc.c
@@ -52,21 +52,18 @@ static const struct tok chdlc_cast_values[] = {
u_int
chdlc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p)
{
- register u_int length = h->len;
- register u_int caplen = h->caplen;
-
- if (caplen < CHDLC_HDRLEN) {
- ND_PRINT((ndo, "[|chdlc]"));
- return (caplen);
- }
- return (chdlc_print(ndo, p,length));
+ return chdlc_print(ndo, p, h->len);
}
u_int
chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length)
{
u_int proto;
+ const u_char *bp = p;
+ if (length < CHDLC_HDRLEN)
+ goto trunc;
+ ND_TCHECK2(*p, CHDLC_HDRLEN);
proto = EXTRACT_16BITS(&p[2]);
if (ndo->ndo_eflag) {
ND_PRINT((ndo, "%s, ethertype %s (0x%04x), length %u: ",
@@ -100,12 +97,15 @@ chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length)
break;
case ETHERTYPE_ISO:
/* is the fudge byte set ? lets verify by spotting ISO headers */
+ if (length < 2)
+ goto trunc;
+ ND_TCHECK_16BITS(p);
if (*(p+1) == 0x81 ||
*(p+1) == 0x82 ||
*(p+1) == 0x83)
- isoclns_print(ndo, p + 1, length - 1, ndo->ndo_snapend - p - 1);
+ isoclns_print(ndo, p + 1, length - 1);
else
- isoclns_print(ndo, p, length, ndo->ndo_snapend - p);
+ isoclns_print(ndo, p, length);
break;
default:
if (!ndo->ndo_eflag)
@@ -114,6 +114,10 @@ chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length)
}
return (CHDLC_HDRLEN);
+
+trunc:
+ ND_PRINT((ndo, "[|chdlc]"));
+ return ndo->ndo_snapend - bp;
}
/*
diff --git a/freebsd/contrib/tcpdump/print-cnfp.c b/freebsd/contrib/tcpdump/print-cnfp.c
index b590afae..9e946f6e 100644
--- a/freebsd/contrib/tcpdump/print-cnfp.c
+++ b/freebsd/contrib/tcpdump/print-cnfp.c
@@ -165,7 +165,7 @@ cnfp_v1_print(netdissect_options *ndo, const u_char *cp)
{
register const struct nfhdr_v1 *nh;
register const struct nfrec_v1 *nr;
- struct protoent *pent;
+ const char *p_name;
int nrecs, ver;
#if 0
time_t t;
@@ -217,14 +217,13 @@ cnfp_v1_print(netdissect_options *ndo, const u_char *cp)
ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr)));
- pent = getprotobynumber(nr->proto);
- if (!pent || ndo->ndo_nflag)
- ND_PRINT((ndo, "%u ", nr->proto));
+ if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL)
+ ND_PRINT((ndo, "%s ", p_name));
else
- ND_PRINT((ndo, "%s ", pent->p_name));
+ ND_PRINT((ndo, "%u ", nr->proto));
/* tcp flags for tcp only */
- if (pent && pent->p_proto == IPPROTO_TCP) {
+ if (nr->proto == IPPROTO_TCP) {
int flags;
flags = nr->tcp_flags;
ND_PRINT((ndo, "%s%s%s%s%s%s%s",
@@ -255,7 +254,7 @@ cnfp_v5_print(netdissect_options *ndo, const u_char *cp)
{
register const struct nfhdr_v5 *nh;
register const struct nfrec_v5 *nr;
- struct protoent *pent;
+ const char *p_name;
int nrecs, ver;
#if 0
time_t t;
@@ -314,14 +313,13 @@ cnfp_v5_print(netdissect_options *ndo, const u_char *cp)
ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr)));
- pent = getprotobynumber(nr->proto);
- if (!pent || ndo->ndo_nflag)
- ND_PRINT((ndo, "%u ", nr->proto));
+ if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL)
+ ND_PRINT((ndo, "%s ", p_name));
else
- ND_PRINT((ndo, "%s ", pent->p_name));
+ ND_PRINT((ndo, "%u ", nr->proto));
/* tcp flags for tcp only */
- if (pent && pent->p_proto == IPPROTO_TCP) {
+ if (nr->proto == IPPROTO_TCP) {
int flags;
flags = nr->tcp_flags;
ND_PRINT((ndo, "%s%s%s%s%s%s%s",
@@ -352,7 +350,7 @@ cnfp_v6_print(netdissect_options *ndo, const u_char *cp)
{
register const struct nfhdr_v6 *nh;
register const struct nfrec_v6 *nr;
- struct protoent *pent;
+ const char *p_name;
int nrecs, ver;
#if 0
time_t t;
@@ -411,14 +409,13 @@ cnfp_v6_print(netdissect_options *ndo, const u_char *cp)
ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr)));
- pent = getprotobynumber(nr->proto);
- if (!pent || ndo->ndo_nflag)
- ND_PRINT((ndo, "%u ", nr->proto));
+ if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL)
+ ND_PRINT((ndo, "%s ", p_name));
else
- ND_PRINT((ndo, "%s ", pent->p_name));
+ ND_PRINT((ndo, "%u ", nr->proto));
/* tcp flags for tcp only */
- if (pent && pent->p_proto == IPPROTO_TCP) {
+ if (nr->proto == IPPROTO_TCP) {
int flags;
flags = nr->tcp_flags;
ND_PRINT((ndo, "%s%s%s%s%s%s%s",
diff --git a/freebsd/contrib/tcpdump/print-decnet.c b/freebsd/contrib/tcpdump/print-decnet.c
index 4d052626..af50492b 100644
--- a/freebsd/contrib/tcpdump/print-decnet.c
+++ b/freebsd/contrib/tcpdump/print-decnet.c
@@ -548,6 +548,7 @@ decnet_print(netdissect_options *ndo,
length -= padlen;
caplen -= padlen;
rhp = (const union routehdr *)&(ap[sizeof(short)]);
+ ND_TCHECK(rhp->rh_short.sh_flags);
mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
}
@@ -619,6 +620,7 @@ print_decnet_ctlmsg(netdissect_options *ndo,
register const union routehdr *rhp, u_int length,
u_int caplen)
{
+ /* Our caller has already checked for mflags */
int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
register const union controlmsg *cmp = (const union controlmsg *)rhp;
int src, dst, info, blksize, eco, ueco, hello, other, vers;
diff --git a/freebsd/contrib/tcpdump/print-dhcp6.c b/freebsd/contrib/tcpdump/print-dhcp6.c
index 8c7a0974..9815a167 100644
--- a/freebsd/contrib/tcpdump/print-dhcp6.c
+++ b/freebsd/contrib/tcpdump/print-dhcp6.c
@@ -524,6 +524,10 @@ dhcp6opt_print(netdissect_options *ndo,
ND_PRINT((ndo, "...)"));
break;
case DH6OPT_RECONF_MSG:
+ if (optlen != 1) {
+ ND_PRINT((ndo, " ?)"));
+ break;
+ }
tp = (const u_char *)(dh6o + 1);
switch (*tp) {
case DH6_RENEW:
diff --git a/freebsd/contrib/tcpdump/print-domain.c b/freebsd/contrib/tcpdump/print-domain.c
index 904468c4..52348a17 100644
--- a/freebsd/contrib/tcpdump/print-domain.c
+++ b/freebsd/contrib/tcpdump/print-domain.c
@@ -157,15 +157,14 @@ ns_nprint(netdissect_options *ndo,
register u_int i, l;
register const u_char *rp = NULL;
register int compress = 0;
- int chars_processed;
int elt;
- int data_size = ndo->ndo_snapend - bp;
+ u_int offset, max_offset;
if ((l = labellen(ndo, cp)) == (u_int)-1)
return(NULL);
if (!ND_TTEST2(*cp, 1))
return(NULL);
- chars_processed = 1;
+ max_offset = (u_int)(cp - bp);
if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) {
compress = 0;
rp = cp + l;
@@ -180,24 +179,28 @@ ns_nprint(netdissect_options *ndo,
}
if (!ND_TTEST2(*cp, 1))
return(NULL);
- cp = bp + (((i << 8) | *cp) & 0x3fff);
+ offset = (((i << 8) | *cp) & 0x3fff);
+ /*
+ * This must move backwards in the packet.
+ * No RFC explicitly says that, but BIND's
+ * name decompression code requires it,
+ * as a way of preventing infinite loops
+ * and other bad behavior, and it's probably
+ * what was intended (compress by pointing
+ * to domain name suffixes already seen in
+ * the packet).
+ */
+ if (offset >= max_offset) {
+ ND_PRINT((ndo, "<BAD PTR>"));
+ return(NULL);
+ }
+ max_offset = offset;
+ cp = bp + offset;
if ((l = labellen(ndo, cp)) == (u_int)-1)
return(NULL);
if (!ND_TTEST2(*cp, 1))
return(NULL);
i = *cp++;
- chars_processed++;
-
- /*
- * If we've looked at every character in
- * the message, this pointer will make
- * us look at some character again,
- * which means we're looping.
- */
- if (chars_processed >= data_size) {
- ND_PRINT((ndo, "<LOOP>"));
- return (NULL);
- }
continue;
}
if ((i & INDIR_MASK) == EDNS0_MASK) {
@@ -218,14 +221,12 @@ ns_nprint(netdissect_options *ndo,
}
cp += l;
- chars_processed += l;
ND_PRINT((ndo, "."));
if ((l = labellen(ndo, cp)) == (u_int)-1)
return(NULL);
if (!ND_TTEST2(*cp, 1))
return(NULL);
i = *cp++;
- chars_processed++;
if (!compress)
rp += l + 1;
}
diff --git a/freebsd/contrib/tcpdump/print-eap.c b/freebsd/contrib/tcpdump/print-eap.c
index 78fbef43..1de61b79 100644
--- a/freebsd/contrib/tcpdump/print-eap.c
+++ b/freebsd/contrib/tcpdump/print-eap.c
@@ -188,7 +188,9 @@ eap_print(netdissect_options *ndo,
switch (eap->type) {
case EAP_FRAME_TYPE_PACKET:
+ ND_TCHECK_8BITS(tptr);
type = *(tptr);
+ ND_TCHECK_16BITS(tptr+2);
len = EXTRACT_16BITS(tptr+2);
ND_PRINT((ndo, ", %s (%u), id %u, len %u",
tok2str(eap_code_values, "unknown", type),
@@ -199,10 +201,11 @@ eap_print(netdissect_options *ndo,
ND_TCHECK2(*tptr, len);
if (type <= 2) { /* For EAP_REQUEST and EAP_RESPONSE only */
+ ND_TCHECK_8BITS(tptr+4);
subtype = *(tptr+4);
ND_PRINT((ndo, "\n\t\t Type %s (%u)",
- tok2str(eap_type_values, "unknown", *(tptr+4)),
- *(tptr + 4)));
+ tok2str(eap_type_values, "unknown", subtype),
+ subtype));
switch (subtype) {
case EAP_TYPE_IDENTITY:
@@ -228,6 +231,7 @@ eap_print(netdissect_options *ndo,
* type one octet per type
*/
while (count < len) {
+ ND_TCHECK_8BITS(tptr+count);
ND_PRINT((ndo, " %s (%u),",
tok2str(eap_type_values, "unknown", *(tptr+count)),
*(tptr + count)));
@@ -236,19 +240,23 @@ eap_print(netdissect_options *ndo,
break;
case EAP_TYPE_TTLS:
- ND_PRINT((ndo, " TTLSv%u",
- EAP_TTLS_VERSION(*(tptr + 5)))); /* fall through */
case EAP_TYPE_TLS:
+ ND_TCHECK_8BITS(tptr + 5);
+ if (subtype == EAP_TYPE_TTLS)
+ ND_PRINT((ndo, " TTLSv%u",
+ EAP_TTLS_VERSION(*(tptr + 5))));
ND_PRINT((ndo, " flags [%s] 0x%02x,",
bittok2str(eap_tls_flags_values, "none", *(tptr+5)),
*(tptr + 5)));
if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) {
+ ND_TCHECK_32BITS(tptr + 6);
ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6)));
}
break;
case EAP_TYPE_FAST:
+ ND_TCHECK_8BITS(tptr + 5);
ND_PRINT((ndo, " FASTv%u",
EAP_TTLS_VERSION(*(tptr + 5))));
ND_PRINT((ndo, " flags [%s] 0x%02x,",
@@ -256,6 +264,7 @@ eap_print(netdissect_options *ndo,
*(tptr + 5)));
if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) {
+ ND_TCHECK_32BITS(tptr + 6);
ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6)));
}
@@ -264,6 +273,7 @@ eap_print(netdissect_options *ndo,
case EAP_TYPE_AKA:
case EAP_TYPE_SIM:
+ ND_TCHECK_8BITS(tptr + 5);
ND_PRINT((ndo, " subtype [%s] 0x%02x,",
tok2str(eap_aka_subtype_values, "unknown", *(tptr+5)),
*(tptr + 5)));
diff --git a/freebsd/contrib/tcpdump/print-eigrp.c b/freebsd/contrib/tcpdump/print-eigrp.c
index 14a14b8f..2b1ea588 100644
--- a/freebsd/contrib/tcpdump/print-eigrp.c
+++ b/freebsd/contrib/tcpdump/print-eigrp.c
@@ -5,7 +5,7 @@
#include "rtems-bsd-tcpdump-namespace.h"
#endif /* __rtems__ */
/*
- * Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org>
+ * Copyright (c) 1998-2004 Hannes Gredler <hannes@gredler.at>
* The TCPDUMP project
*
* Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,7 @@
/*
* packet format documented at
* http://www.rhyshaden.com/eigrp.htm
+ * RFC 7868
*/
struct eigrp_common_header {
@@ -252,6 +253,12 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
/* ok they seem to want to know everything - lets fully decode it */
+ if (len < sizeof(struct eigrp_common_header)) {
+ ND_PRINT((ndo, "EIGRP %s, length: %u (too short, < %u)",
+ tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode),
+ len, (u_int) sizeof(struct eigrp_common_header)));
+ return;
+ }
tlen=len-sizeof(struct eigrp_common_header);
/* FIXME print other header info */
@@ -292,6 +299,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
eigrp_tlv_type,
eigrp_tlv_len));
+ if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) sizeof(struct eigrp_tlv_header)));
+ break;
+ }
tlv_tptr=tptr+sizeof(struct eigrp_tlv_header);
tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header);
@@ -302,6 +314,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_GENERAL_PARM:
tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_general_parm)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_general_parm))));
+ break;
+ }
ND_PRINT((ndo, "\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u",
EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime),
@@ -314,6 +331,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_SW_VERSION:
tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_sw_version)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_sw_version))));
+ break;
+ }
ND_PRINT((ndo, "\n\t IOS version: %u.%u, EIGRP version %u.%u",
tlv_ptr.eigrp_tlv_sw_version->ios_major,
@@ -324,6 +346,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_IP_INT:
tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_int)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_int))));
+ break;
+ }
bit_length = tlv_ptr.eigrp_tlv_ip_int->plen;
if (bit_length > 32) {
@@ -353,6 +380,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_IP_EXT:
tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_ext)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_ext))));
+ break;
+ }
bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen;
if (bit_length > 32) {
@@ -390,6 +422,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_AT_CABLE_SETUP:
tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup))));
+ break;
+ }
ND_PRINT((ndo, "\n\t Cable-range: %u-%u, Router-ID %u",
EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start),
@@ -399,6 +436,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_AT_INT:
tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_int)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_int))));
+ break;
+ }
ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ",
EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start),
@@ -422,6 +464,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_AT_EXT:
tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_ext)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_ext))));
+ break;
+ }
ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ",
EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start),
diff --git a/freebsd/contrib/tcpdump/print-esp.c b/freebsd/contrib/tcpdump/print-esp.c
index bab7cb52..c92d6fbe 100644
--- a/freebsd/contrib/tcpdump/print-esp.c
+++ b/freebsd/contrib/tcpdump/print-esp.c
@@ -151,6 +151,39 @@ EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
}
#endif
+#ifdef HAVE_EVP_CIPHERINIT_EX
+/*
+ * Initialize the cipher by calling EVP_CipherInit_ex(), because
+ * calling EVP_CipherInit() will reset the cipher context, clearing
+ * the cipher, so calling it twice, with the second call having a
+ * null cipher, will clear the already-set cipher. EVP_CipherInit_ex(),
+ * however, won't reset the cipher context, so you can use it to specify
+ * the IV oin a second call after a first call to EVP_CipherInit_ex()
+ * to set the cipher and the key.
+ *
+ * XXX - is there some reason why we need to make two calls?
+ */
+static int
+set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc);
+}
+#else
+/*
+ * Initialize the cipher by calling EVP_CipherInit(), because we don't
+ * have EVP_CipherInit_ex(); we rely on it not trashing the context.
+ */
+static int
+set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ return EVP_CipherInit(ctx, cipher, key, iv, enc);
+}
+#endif
+
/*
* this will adjust ndo_packetp and ndo_snapend to new buffer!
*/
@@ -162,8 +195,10 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
{
struct sa_list *sa;
const u_char *iv;
- int len;
+ unsigned int len;
EVP_CIPHER_CTX *ctx;
+ unsigned int block_size, output_buffer_size;
+ u_char *output_buffer;
/* initiator arg is any non-zero value */
if(initiator) initiator=1;
@@ -194,17 +229,36 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL)
return 0;
- if (EVP_CipherInit(ctx, sa->evp, sa->secret, NULL, 0) < 0)
+ if (set_cipher_parameters(ctx, sa->evp, sa->secret, NULL, 0) < 0)
(*ndo->ndo_warning)(ndo, "espkey init failed");
- EVP_CipherInit(ctx, NULL, NULL, iv, 0);
- EVP_Cipher(ctx, __DECONST(u_char *, buf), buf, len);
+ set_cipher_parameters(ctx, NULL, NULL, iv, 0);
+ /*
+ * Allocate a buffer for the decrypted data.
+ * The output buffer must be separate from the input buffer, and
+ * its size must be a multiple of the cipher block size.
+ */
+ block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
+ output_buffer_size = len + (block_size - len % block_size);
+ output_buffer = (u_char *)malloc(output_buffer_size);
+ if (output_buffer == NULL) {
+ (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
+ EVP_CIPHER_CTX_free(ctx);
+ return 0;
+ }
+ EVP_Cipher(ctx, output_buffer, buf, len);
EVP_CIPHER_CTX_free(ctx);
+ /*
+ * XXX - of course this is wrong, because buf is a const buffer,
+ * but changing this would require a more complicated fix.
+ */
+ memcpy(__DECONST(u_char *, buf), output_buffer, len);
+ free(output_buffer);
+
ndo->ndo_packetp = buf;
ndo->ndo_snapend = end;
return 1;
-
}
USES_APPLE_RST
@@ -612,6 +666,8 @@ esp_print(netdissect_options *ndo,
const u_char *ivoff;
const u_char *p;
EVP_CIPHER_CTX *ctx;
+ unsigned int block_size, output_buffer_size;
+ u_char *output_buffer;
#endif
esp = (const struct newesp *)bp;
@@ -709,7 +765,9 @@ esp_print(netdissect_options *ndo,
ep = bp2 + len;
}
+ /* pointer to the IV, if there is one */
ivoff = (const u_char *)(esp + 1) + 0;
+ /* length of the IV, if there is one; 0, if there isn't */
ivlen = sa->ivlen;
secret = sa->secret;
ep = ep - sa->authlen;
@@ -717,14 +775,37 @@ esp_print(netdissect_options *ndo,
if (sa->evp) {
ctx = EVP_CIPHER_CTX_new();
if (ctx != NULL) {
- if (EVP_CipherInit(ctx, sa->evp, secret, NULL, 0) < 0)
+ if (set_cipher_parameters(ctx, sa->evp, secret, NULL, 0) < 0)
(*ndo->ndo_warning)(ndo, "espkey init failed");
p = ivoff;
- EVP_CipherInit(ctx, NULL, NULL, p, 0);
- EVP_Cipher(ctx, __DECONST(u_char *, p + ivlen),
- p + ivlen, ep - (p + ivlen));
+ set_cipher_parameters(ctx, NULL, NULL, p, 0);
+ len = ep - (p + ivlen);
+
+ /*
+ * Allocate a buffer for the decrypted data.
+ * The output buffer must be separate from the
+ * input buffer, and its size must be a multiple
+ * of the cipher block size.
+ */
+ block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
+ output_buffer_size = len + (block_size - len % block_size);
+ output_buffer = (u_char *)malloc(output_buffer_size);
+ if (output_buffer == NULL) {
+ (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
+ EVP_CIPHER_CTX_free(ctx);
+ return -1;
+ }
+
+ EVP_Cipher(ctx, output_buffer, p + ivlen, len);
EVP_CIPHER_CTX_free(ctx);
+ /*
+ * XXX - of course this is wrong, because buf is a
+ * const buffer, but changing this would require a
+ * more complicated fix.
+ */
+ memcpy(__DECONST(u_char *, p + ivlen), output_buffer, len);
+ free(output_buffer);
advance = ivoff - (const u_char *)esp + ivlen;
} else
advance = sizeof(struct newesp);
diff --git a/freebsd/contrib/tcpdump/print-ether.c b/freebsd/contrib/tcpdump/print-ether.c
index 2a72830c..cf996cd3 100644
--- a/freebsd/contrib/tcpdump/print-ether.c
+++ b/freebsd/contrib/tcpdump/print-ether.c
@@ -372,7 +372,7 @@ ethertype_print(netdissect_options *ndo,
ND_PRINT((ndo, " [|osi]"));
return (1);
}
- isoclns_print(ndo, p + 1, length - 1, caplen - 1);
+ isoclns_print(ndo, p + 1, length - 1);
return(1);
case ETHERTYPE_PPPOED:
diff --git a/freebsd/contrib/tcpdump/print-fr.c b/freebsd/contrib/tcpdump/print-fr.c
index 11457ab0..25e0219a 100644
--- a/freebsd/contrib/tcpdump/print-fr.c
+++ b/freebsd/contrib/tcpdump/print-fr.c
@@ -335,7 +335,7 @@ fr_print(netdissect_options *ndo,
case NLPID_CLNP:
case NLPID_ESIS:
case NLPID_ISIS:
- isoclns_print(ndo, p - 1, length + 1, ndo->ndo_snapend - p + 1); /* OSI printers need the NLPID field */
+ isoclns_print(ndo, p - 1, length + 1); /* OSI printers need the NLPID field */
break;
case NLPID_SNAP:
diff --git a/freebsd/contrib/tcpdump/print-frag6.c b/freebsd/contrib/tcpdump/print-frag6.c
index 11f97ad2..fb364c4d 100644
--- a/freebsd/contrib/tcpdump/print-frag6.c
+++ b/freebsd/contrib/tcpdump/print-frag6.c
@@ -33,10 +33,11 @@
#include <netdissect-stdinc.h>
-#include "ip6.h"
#include "netdissect.h"
#include "extract.h"
+#include "ip6.h"
+
int
frag6_print(netdissect_options *ndo, register const u_char *bp, register const u_char *bp2)
{
@@ -46,7 +47,7 @@ frag6_print(netdissect_options *ndo, register const u_char *bp, register const u
dp = (const struct ip6_frag *)bp;
ip6 = (const struct ip6_hdr *)bp2;
- ND_TCHECK(dp->ip6f_offlg);
+ ND_TCHECK(*dp);
if (ndo->ndo_vflag) {
ND_PRINT((ndo, "frag (0x%08x:%d|%ld)",
diff --git a/freebsd/contrib/tcpdump/print-gre.c b/freebsd/contrib/tcpdump/print-gre.c
index 2a13d435..04ad5d2a 100644
--- a/freebsd/contrib/tcpdump/print-gre.c
+++ b/freebsd/contrib/tcpdump/print-gre.c
@@ -232,7 +232,7 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length)
atalk_print(ndo, bp, len);
break;
case ETHERTYPE_GRE_ISO:
- isoclns_print(ndo, bp, len, ndo->ndo_snapend - bp);
+ isoclns_print(ndo, bp, len);
break;
case ETHERTYPE_TEB:
ether_print(ndo, bp, len, ndo->ndo_snapend - bp, NULL, NULL);
diff --git a/freebsd/contrib/tcpdump/print-hncp.c b/freebsd/contrib/tcpdump/print-hncp.c
index 83ee2fd9..34297772 100644
--- a/freebsd/contrib/tcpdump/print-hncp.c
+++ b/freebsd/contrib/tcpdump/print-hncp.c
@@ -276,6 +276,8 @@ dhcpv4_print(netdissect_options *ndo,
i = 0;
while (i < length) {
+ if (i + 2 > length)
+ return -1;
tlv = cp + i;
type = (uint8_t)tlv[0];
optlen = (uint8_t)tlv[1];
@@ -287,6 +289,8 @@ dhcpv4_print(netdissect_options *ndo,
ND_PRINT((ndo, "%s", tok2str(dh4opt_str, "Unknown", type)));
ND_PRINT((ndo," (%u)", optlen + 2 ));
+ if (i + 2 + optlen > length)
+ return -1;
switch (type) {
case DH4OPT_DNS_SERVERS:
@@ -324,6 +328,8 @@ dhcpv6_print(netdissect_options *ndo,
i = 0;
while (i < length) {
+ if (i + 4 > length)
+ return -1;
tlv = cp + i;
type = EXTRACT_16BITS(tlv);
optlen = EXTRACT_16BITS(tlv + 2);
@@ -335,6 +341,8 @@ dhcpv6_print(netdissect_options *ndo,
ND_PRINT((ndo, "%s", tok2str(dh6opt_str, "Unknown", type)));
ND_PRINT((ndo," (%u)", optlen + 4 ));
+ if (i + 4 + optlen > length)
+ return -1;
switch (type) {
case DH6OPT_DNS_SERVERS:
diff --git a/freebsd/contrib/tcpdump/print-icmp.c b/freebsd/contrib/tcpdump/print-icmp.c
index fc4906eb..ce22ce81 100644
--- a/freebsd/contrib/tcpdump/print-icmp.c
+++ b/freebsd/contrib/tcpdump/print-icmp.c
@@ -588,6 +588,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
ip = (const struct ip *)bp;
ndo->ndo_snaplen = ndo->ndo_snapend - bp;
snapend_save = ndo->ndo_snapend;
+ ND_TCHECK_16BITS(&ip->ip_len);
ip_print(ndo, bp, EXTRACT_16BITS(&ip->ip_len));
ndo->ndo_snapend = snapend_save;
}
@@ -605,7 +606,8 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
* to check if an extension header is present. This is expedient,
* however not all implementations set the length field proper.
*/
- if (!ext_dp->icmp_length) {
+ if (!ext_dp->icmp_length &&
+ ND_TTEST2(ext_dp->icmp_ext_version_res, plen - ICMP_EXTD_MINLEN)) {
vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
vec[0].len = plen - ICMP_EXTD_MINLEN;
if (in_cksum(vec, 1)) {
@@ -626,12 +628,14 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
}
hlen = plen - ICMP_EXTD_MINLEN;
- vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
- vec[0].len = hlen;
- ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u",
- EXTRACT_16BITS(ext_dp->icmp_ext_checksum),
- in_cksum(vec, 1) ? "in" : "",
- hlen));
+ if (ND_TTEST2(ext_dp->icmp_ext_version_res, hlen)) {
+ vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
+ vec[0].len = hlen;
+ ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u",
+ EXTRACT_16BITS(ext_dp->icmp_ext_checksum),
+ in_cksum(vec, 1) ? "in" : "",
+ hlen));
+ }
hlen -= 4; /* subtract common header size */
obj_tptr = (const uint8_t *)ext_dp->icmp_ext_data;
diff --git a/freebsd/contrib/tcpdump/print-icmp6.c b/freebsd/contrib/tcpdump/print-icmp6.c
index 2e6756cf..e2d44dfb 100644
--- a/freebsd/contrib/tcpdump/print-icmp6.c
+++ b/freebsd/contrib/tcpdump/print-icmp6.c
@@ -1137,6 +1137,7 @@ icmp6_print(netdissect_options *ndo,
if (ndo->ndo_vflag) {
ND_TCHECK(dp->icmp6_data16[0]);
ND_PRINT((ndo,", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0])));
+ ND_TCHECK(dp->icmp6_data16[1]);
if (dp->icmp6_data16[1] & 0xc0)
ND_PRINT((ndo," "));
if (dp->icmp6_data16[1] & 0x80)
@@ -1704,6 +1705,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp,
needcomma = 0;
+ ND_TCHECK2(*dp, sizeof(*ni6));
ni6 = (const struct icmp6_nodeinfo *)dp;
ND_PRINT((ndo," node information reply"));
ND_PRINT((ndo," (")); /*)*/
@@ -1758,6 +1760,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp,
ND_PRINT((ndo,", "));
ND_PRINT((ndo,"DNS name"));
cp = (const u_char *)(ni6 + 1) + 4;
+ ND_TCHECK(cp[0]);
if (cp[0] == ep - cp - 1) {
/* icmp-name-lookup-03, pascal string */
if (ndo->ndo_vflag)
diff --git a/freebsd/contrib/tcpdump/print-ip.c b/freebsd/contrib/tcpdump/print-ip.c
index 6aa5692e..677ed942 100644
--- a/freebsd/contrib/tcpdump/print-ip.c
+++ b/freebsd/contrib/tcpdump/print-ip.c
@@ -60,7 +60,7 @@ static const struct tok ip_option_values[] = {
/*
* print the recorded route in an IP RR, LSRR or SSRR option.
*/
-static void
+static int
ip_printroute(netdissect_options *ndo,
register const u_char *cp, u_int length)
{
@@ -69,19 +69,25 @@ ip_printroute(netdissect_options *ndo,
if (length < 3) {
ND_PRINT((ndo, " [bad length %u]", length));
- return;
+ return (0);
}
if ((length + 1) & 3)
ND_PRINT((ndo, " [bad length %u]", length));
+ ND_TCHECK(cp[2]);
ptr = cp[2] - 1;
if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
ND_PRINT((ndo, " [bad ptr %u]", cp[2]));
for (len = 3; len < length; len += 4) {
+ ND_TCHECK2(cp[len], 4);
ND_PRINT((ndo, " %s", ipaddr_string(ndo, &cp[len])));
if (ptr > len)
ND_PRINT((ndo, ","));
}
+ return (0);
+
+trunc:
+ return (-1);
}
/*
@@ -168,7 +174,7 @@ nextproto4_cksum(netdissect_options *ndo,
return (in_cksum(vec, 2));
}
-static void
+static int
ip_printts(netdissect_options *ndo,
register const u_char *cp, u_int length)
{
@@ -179,16 +185,18 @@ ip_printts(netdissect_options *ndo,
if (length < 4) {
ND_PRINT((ndo, "[bad length %u]", length));
- return;
+ return (0);
}
ND_PRINT((ndo, " TS{"));
hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
if ((length - 4) & (hoplen-1))
ND_PRINT((ndo, "[bad length %u]", length));
+ ND_TCHECK(cp[2]);
ptr = cp[2] - 1;
len = 0;
if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1)
ND_PRINT((ndo, "[bad ptr %u]", cp[2]));
+ ND_TCHECK(cp[3]);
switch (cp[3]&0xF) {
case IPOPT_TS_TSONLY:
ND_PRINT((ndo, "TSONLY"));
@@ -217,6 +225,7 @@ ip_printts(netdissect_options *ndo,
for (len = 4; len < length; len += hoplen) {
if (ptr == len)
type = " ^ ";
+ ND_TCHECK2(cp[len], hoplen);
ND_PRINT((ndo, "%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]),
hoplen!=8 ? "" : ipaddr_string(ndo, &cp[len])));
type = " ";
@@ -229,6 +238,10 @@ done:
ND_PRINT((ndo, " [%d hops not recorded]} ", cp[3]>>4));
else
ND_PRINT((ndo, "}"));
+ return (0);
+
+trunc:
+ return (-1);
}
/*
@@ -278,13 +291,15 @@ ip_optprint(netdissect_options *ndo,
return;
case IPOPT_TS:
- ip_printts(ndo, cp, option_len);
+ if (ip_printts(ndo, cp, option_len) == -1)
+ goto trunc;
break;
case IPOPT_RR: /* fall through */
case IPOPT_SSRR:
case IPOPT_LSRR:
- ip_printroute(ndo, cp, option_len);
+ if (ip_printroute(ndo, cp, option_len) == -1)
+ goto trunc;
break;
case IPOPT_RA:
@@ -330,7 +345,7 @@ static void
ip_print_demux(netdissect_options *ndo,
struct ip_print_demux_state *ipds)
{
- struct protoent *proto;
+ const char *p_name;
again:
switch (ipds->nh) {
@@ -496,8 +511,8 @@ again:
#endif
default:
- if (ndo->ndo_nflag==0 && (proto = getprotobynumber(ipds->nh)) != NULL)
- ND_PRINT((ndo, " %s", proto->p_name));
+ if (ndo->ndo_nflag==0 && (p_name = netdb_protoname(ipds->nh)) != NULL)
+ ND_PRINT((ndo, " %s", p_name));
else
ND_PRINT((ndo, " ip-proto-%d", ipds->nh));
ND_PRINT((ndo, " %d", ipds->len));
@@ -538,7 +553,7 @@ ip_print(netdissect_options *ndo,
u_int hlen;
struct cksum_vec vec[1];
uint16_t sum, ip_sum;
- struct protoent *proto;
+ const char *p_name;
ipds->ip = (const struct ip *)bp;
ND_TCHECK(ipds->ip->ip_vhl);
@@ -683,8 +698,8 @@ ip_print(netdissect_options *ndo,
*/
ND_PRINT((ndo, "%s > %s:", ipaddr_string(ndo, &ipds->ip->ip_src),
ipaddr_string(ndo, &ipds->ip->ip_dst)));
- if (!ndo->ndo_nflag && (proto = getprotobynumber(ipds->ip->ip_p)) != NULL)
- ND_PRINT((ndo, " %s", proto->p_name));
+ if (!ndo->ndo_nflag && (p_name = netdb_protoname(ipds->ip->ip_p)) != NULL)
+ ND_PRINT((ndo, " %s", p_name));
else
ND_PRINT((ndo, " ip-proto-%d", ipds->ip->ip_p));
}
diff --git a/freebsd/contrib/tcpdump/print-ip6.c b/freebsd/contrib/tcpdump/print-ip6.c
index c82ead12..047ddfc0 100644
--- a/freebsd/contrib/tcpdump/print-ip6.c
+++ b/freebsd/contrib/tcpdump/print-ip6.c
@@ -286,6 +286,8 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
advance = sizeof(struct ip6_hdr);
nh = ip6->ip6_nxt;
while (cp < ndo->ndo_snapend && advance > 0) {
+ if (len < (u_int)advance)
+ goto trunc;
cp += advance;
len -= advance;
@@ -328,10 +330,15 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
* mobility header.
*/
advance = mobility_print(ndo, cp, (const u_char *)ip6);
+ if (advance < 0)
+ return;
nh = *cp;
return;
case IPPROTO_ROUTING:
+ ND_TCHECK(*cp);
advance = rt6_print(ndo, cp, (const u_char *)ip6);
+ if (advance < 0)
+ return;
nh = *cp;
break;
case IPPROTO_SCTP:
@@ -351,12 +358,16 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
return;
case IPPROTO_AH:
advance = ah_print(ndo, cp);
+ if (advance < 0)
+ return;
nh = *cp;
break;
case IPPROTO_ESP:
{
int enh, padlen;
advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen);
+ if (advance < 0)
+ return;
nh = enh & 0xff;
len -= padlen;
break;
diff --git a/freebsd/contrib/tcpdump/print-ip6opts.c b/freebsd/contrib/tcpdump/print-ip6opts.c
index 782ac550..a35111fa 100644
--- a/freebsd/contrib/tcpdump/print-ip6opts.c
+++ b/freebsd/contrib/tcpdump/print-ip6opts.c
@@ -41,12 +41,12 @@
#include <netdissect-stdinc.h>
-#include "ip6.h"
-
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
+#include "ip6.h"
+
static void
ip6_sopt_print(netdissect_options *ndo, const u_char *bp, int len)
{
diff --git a/freebsd/contrib/tcpdump/print-isakmp.c b/freebsd/contrib/tcpdump/print-isakmp.c
index c004eea9..fd78bf86 100644
--- a/freebsd/contrib/tcpdump/print-isakmp.c
+++ b/freebsd/contrib/tcpdump/print-isakmp.c
@@ -57,6 +57,7 @@
#include "ip.h"
#include "ip6.h"
+#include "ipproto.h"
/* refer to RFC 2408 */
@@ -433,7 +434,7 @@ struct notify_messages {
char *msg;
};
-/* 3.8 Notification Payload */
+/* 3.8 Authentication Payload */
struct ikev2_auth {
struct isakmp_gen h;
uint8_t auth_method; /* Protocol-ID */
@@ -921,21 +922,25 @@ struct attrmap {
static const u_char *
ikev1_attrmap_print(netdissect_options *ndo,
- const u_char *p, const u_char *ep,
+ const u_char *p, const u_char *ep2,
const struct attrmap *map, size_t nmap)
{
int totlen;
uint32_t t, v;
+ ND_TCHECK(p[0]);
if (p[0] & 0x80)
totlen = 4;
- else
+ else {
+ ND_TCHECK_16BITS(&p[2]);
totlen = 4 + EXTRACT_16BITS(&p[2]);
- if (ep < p + totlen) {
+ }
+ if (ep2 < p + totlen) {
ND_PRINT((ndo,"[|attr]"));
- return ep + 1;
+ return ep2 + 1;
}
+ ND_TCHECK_16BITS(&p[0]);
ND_PRINT((ndo,"("));
t = EXTRACT_16BITS(&p[0]) & 0x7fff;
if (map && t < nmap && map[t].type)
@@ -944,47 +949,71 @@ ikev1_attrmap_print(netdissect_options *ndo,
ND_PRINT((ndo,"type=#%d ", t));
if (p[0] & 0x80) {
ND_PRINT((ndo,"value="));
+ ND_TCHECK_16BITS(&p[2]);
v = EXTRACT_16BITS(&p[2]);
if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
ND_PRINT((ndo,"%s", map[t].value[v]));
- else
- rawprint(ndo, (const uint8_t *)&p[2], 2);
+ else {
+ if (!rawprint(ndo, (const uint8_t *)&p[2], 2)) {
+ ND_PRINT((ndo,")"));
+ goto trunc;
+ }
+ }
} else {
- ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
- rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2]));
+ ND_PRINT((ndo,"len=%d value=", totlen - 4));
+ if (!rawprint(ndo, (const uint8_t *)&p[4], totlen - 4)) {
+ ND_PRINT((ndo,")"));
+ goto trunc;
+ }
}
ND_PRINT((ndo,")"));
return p + totlen;
+
+trunc:
+ return NULL;
}
static const u_char *
-ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep)
+ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep2)
{
int totlen;
uint32_t t;
+ ND_TCHECK(p[0]);
if (p[0] & 0x80)
totlen = 4;
- else
+ else {
+ ND_TCHECK_16BITS(&p[2]);
totlen = 4 + EXTRACT_16BITS(&p[2]);
- if (ep < p + totlen) {
+ }
+ if (ep2 < p + totlen) {
ND_PRINT((ndo,"[|attr]"));
- return ep + 1;
+ return ep2 + 1;
}
+ ND_TCHECK_16BITS(&p[0]);
ND_PRINT((ndo,"("));
t = EXTRACT_16BITS(&p[0]) & 0x7fff;
ND_PRINT((ndo,"type=#%d ", t));
if (p[0] & 0x80) {
ND_PRINT((ndo,"value="));
t = p[2];
- rawprint(ndo, (const uint8_t *)&p[2], 2);
+ if (!rawprint(ndo, (const uint8_t *)&p[2], 2)) {
+ ND_PRINT((ndo,")"));
+ goto trunc;
+ }
} else {
- ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
- rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2]));
+ ND_PRINT((ndo,"len=%d value=", totlen - 4));
+ if (!rawprint(ndo, (const uint8_t *)&p[4], totlen - 4)) {
+ ND_PRINT((ndo,")"));
+ goto trunc;
+ }
}
ND_PRINT((ndo,")"));
return p + totlen;
+
+trunc:
+ return NULL;
}
static const u_char *
@@ -1265,11 +1294,12 @@ ikev1_t_print(netdissect_options *ndo, u_char tpay _U_,
cp = (const u_char *)(p + 1);
ep2 = (const u_char *)p + item_len;
while (cp < ep && cp < ep2) {
- if (map && nmap) {
- cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
- map, nmap);
- } else
- cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
+ if (map && nmap)
+ cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
+ else
+ cp = ikev1_attr_print(ndo, cp, ep2);
+ if (cp == NULL)
+ goto trunc;
}
if (ep < ep2)
ND_PRINT((ndo,"..."));
@@ -1293,6 +1323,7 @@ ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@@ -1356,16 +1387,15 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
{
const struct ipsecdoi_id *doi_p;
struct ipsecdoi_id doi_id;
- struct protoent *pe;
+ const char *p_name;
doi_p = (const struct ipsecdoi_id *)ext;
ND_TCHECK(*doi_p);
UNALIGNED_MEMCPY(&doi_id, ext, sizeof(doi_id));
ND_PRINT((ndo," idtype=%s", STR_OR_ID(doi_id.type, ipsecidtypestr)));
/* A protocol ID of 0 DOES NOT mean IPPROTO_IP! */
- pe = doi_id.proto_id ? getprotobynumber(doi_id.proto_id) : NULL;
- if (pe)
- ND_PRINT((ndo," protoid=%s", pe->p_name));
+ if (!ndo->ndo_nflag && doi_id.proto_id && (p_name = netdb_protoname(doi_id.proto_id)) != NULL)
+ ND_PRINT((ndo," protoid=%s", p_name));
else
ND_PRINT((ndo," protoid=%u", doi_id.proto_id));
ND_PRINT((ndo," port=%d", ntohs(doi_id.port)));
@@ -1416,8 +1446,8 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
case IPSECDOI_ID_IPV6_ADDR_SUBNET:
{
const u_char *mask;
- if (len < 20)
- ND_PRINT((ndo," len=%d [bad: < 20]", len));
+ if (len < 32)
+ ND_PRINT((ndo," len=%d [bad: < 32]", len));
else {
mask = (const u_char *)(data + sizeof(struct in6_addr));
/*XXX*/
@@ -1496,6 +1526,7 @@ ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
ND_PRINT((ndo," len=%d", item_len - 4));
ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
if (2 < ndo->ndo_vflag && 4 < item_len) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
goto trunc;
@@ -1528,6 +1559,7 @@ ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
ND_PRINT((ndo," len=%d", item_len - 4));
ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
if (2 < ndo->ndo_vflag && 4 < item_len) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
goto trunc;
@@ -1552,6 +1584,7 @@ ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@@ -1576,6 +1609,7 @@ ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@@ -1600,15 +1634,20 @@ ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_,
ND_TCHECK(*ext);
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
- ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4));
- if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
- ND_PRINT((ndo," "));
- if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
- goto trunc;
- } else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
- ND_PRINT((ndo," "));
- if (!ike_show_somedata(ndo, (const u_char *)(const uint8_t *)(ext + 1), ep))
- goto trunc;
+ /*
+ * Our caller has ensured that the length is >= 4.
+ */
+ ND_PRINT((ndo," n len=%u", ntohs(e.len) - 4));
+ if (ntohs(e.len) > 4) {
+ if (ndo->ndo_vflag > 2) {
+ ND_PRINT((ndo, " "));
+ if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
+ goto trunc;
+ } else if (ndo->ndo_vflag > 1) {
+ ND_PRINT((ndo, " "));
+ if (!ike_show_somedata(ndo, (const u_char *)(ext + 1), ep))
+ goto trunc;
+ }
}
return (const u_char *)ext + ntohs(e.len);
trunc:
@@ -1619,8 +1658,8 @@ trunc:
static const u_char *
ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
const struct isakmp_gen *ext, u_int item_len,
- const u_char *ep, uint32_t phase, uint32_t doi0 _U_,
- uint32_t proto0 _U_, int depth)
+ const u_char *ep, uint32_t phase _U_, uint32_t doi0 _U_,
+ uint32_t proto0 _U_, int depth _U_)
{
const struct ikev1_pl_n *p;
struct ikev1_pl_n n;
@@ -1722,35 +1761,44 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
ep2 = (const u_char *)p + item_len;
if (cp < ep) {
- ND_PRINT((ndo," orig=("));
switch (ntohs(n.type)) {
case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
{
const struct attrmap *map = oakley_t_map;
size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
+ ND_PRINT((ndo," attrs=("));
while (cp < ep && cp < ep2) {
- cp = ikev1_attrmap_print(ndo, cp,
- (ep < ep2) ? ep : ep2, map, nmap);
+ cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
+ if (cp == NULL) {
+ ND_PRINT((ndo,")"));
+ goto trunc;
+ }
}
+ ND_PRINT((ndo,")"));
break;
}
case IPSECDOI_NTYPE_REPLAY_STATUS:
+ ND_PRINT((ndo," status=("));
ND_PRINT((ndo,"replay detection %sabled",
EXTRACT_32BITS(cp) ? "en" : "dis"));
- break;
- case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
- if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA,
- (const struct isakmp_gen *)cp, ep, phase, doi, proto,
- depth) == NULL)
- return NULL;
+ ND_PRINT((ndo,")"));
break;
default:
- /* NULL is dummy */
- isakmp_print(ndo, cp,
- item_len - sizeof(*p) - n.spi_size,
- NULL);
+ /*
+ * XXX - fill in more types here; see, for example,
+ * draft-ietf-ipsec-notifymsg-04.
+ */
+ if (ndo->ndo_vflag > 3) {
+ ND_PRINT((ndo," data=("));
+ if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
+ goto trunc;
+ ND_PRINT((ndo,")"));
+ } else {
+ if (!ike_show_somedata(ndo, cp, ep))
+ goto trunc;
+ }
+ break;
}
- ND_PRINT((ndo,")"));
}
return (const u_char *)ext + item_len;
trunc:
@@ -1817,6 +1865,7 @@ ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@@ -1851,6 +1900,7 @@ ikev2_gen_print(netdissect_options *ndo, u_char tpay,
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@@ -1925,10 +1975,11 @@ ikev2_t_print(netdissect_options *ndo, int tcount,
ep2 = (const u_char *)p + item_len;
while (cp < ep && cp < ep2) {
if (map && nmap) {
- cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
- map, nmap);
+ cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
} else
- cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
+ cp = ikev1_attr_print(ndo, cp, ep2);
+ if (cp == NULL)
+ goto trunc;
}
if (ep < ep2)
ND_PRINT((ndo,"..."));
@@ -1988,7 +2039,6 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
if (prop_length < sizeof(*ext))
goto toolong;
ND_TCHECK(*ext);
-
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
/*
@@ -2075,7 +2125,6 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay,
if (sa_length < sizeof(*ext))
goto toolong;
ND_TCHECK(*ext);
-
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
/*
@@ -2136,7 +2185,7 @@ ikev2_ke_print(netdissect_options *ndo, u_char tpay,
const struct ikev2_ke *k;
k = (const struct ikev2_ke *)ext;
- ND_TCHECK(*ext);
+ ND_TCHECK(*k);
UNALIGNED_MEMCPY(&ke, ext, sizeof(ke));
ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical);
@@ -2161,12 +2210,14 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay,
uint32_t phase _U_, uint32_t doi _U_,
uint32_t proto _U_, int depth _U_)
{
+ const struct ikev2_id *idp;
struct ikev2_id id;
int id_len, idtype_len, i;
unsigned int dumpascii, dumphex;
const unsigned char *typedata;
- ND_TCHECK(*ext);
+ idp = (const struct ikev2_id *)ext;
+ ND_TCHECK(*idp);
UNALIGNED_MEMCPY(&id, ext, sizeof(id));
ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
@@ -2174,6 +2225,7 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay,
ND_PRINT((ndo," len=%d", id_len - 4));
if (2 < ndo->ndo_vflag && 4 < id_len) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), id_len - 4))
goto trunc;
@@ -2269,21 +2321,26 @@ ikev2_auth_print(netdissect_options *ndo, u_char tpay,
const u_char *authdata = (const u_char*)ext + sizeof(a);
unsigned int len;
- ND_TCHECK(*ext);
+ ND_TCHECK2(*ext, sizeof(a));
UNALIGNED_MEMCPY(&a, ext, sizeof(a));
ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
len = ntohs(a.h.len);
- ND_PRINT((ndo," len=%d method=%s", len-4,
+ /*
+ * Our caller has ensured that the length is >= 4.
+ */
+ ND_PRINT((ndo," len=%u method=%s", len-4,
STR_OR_ID(a.auth_method, v2_auth)));
-
- if (1 < ndo->ndo_vflag && 4 < len) {
- ND_PRINT((ndo," authdata=("));
- if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a)))
- goto trunc;
- ND_PRINT((ndo,") "));
- } else if(ndo->ndo_vflag && 4 < len) {
- if(!ike_show_somedata(ndo, authdata, ep)) goto trunc;
+ if (len > 4) {
+ if (ndo->ndo_vflag > 1) {
+ ND_PRINT((ndo, " authdata=("));
+ if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a)))
+ goto trunc;
+ ND_PRINT((ndo, ") "));
+ } else if (ndo->ndo_vflag) {
+ if (!ike_show_somedata(ndo, authdata, ep))
+ goto trunc;
+ }
}
return (const u_char *)ext + len;
@@ -2332,7 +2389,7 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
const struct ikev2_n *p;
struct ikev2_n n;
const u_char *cp;
- u_char showspi, showdata, showsomedata;
+ u_char showspi, showsomedata;
const char *notify_name;
uint32_t type;
@@ -2342,7 +2399,6 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical);
showspi = 1;
- showdata = 0;
showsomedata=0;
notify_name=NULL;
@@ -2456,7 +2512,6 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
notify_name = "cookie";
showspi = 1;
showsomedata= 1;
- showdata= 0;
break;
case IV2_NOTIFY_USE_TRANSPORT_MODE:
@@ -2509,19 +2564,17 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
cp = (const u_char *)(p + 1) + n.spi_size;
- if(3 < ndo->ndo_vflag) {
- showdata = 1;
- }
-
- if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) {
- ND_PRINT((ndo," data=("));
- if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
- goto trunc;
-
- ND_PRINT((ndo,")"));
+ if (cp < ep) {
+ if (ndo->ndo_vflag > 3 || (showsomedata && ep-cp < 30)) {
+ ND_PRINT((ndo," data=("));
+ if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
+ goto trunc;
- } else if(showsomedata && cp < ep) {
- if(!ike_show_somedata(ndo, cp, ep)) goto trunc;
+ ND_PRINT((ndo,")"));
+ } else if (showsomedata) {
+ if (!ike_show_somedata(ndo, cp, ep))
+ goto trunc;
+ }
}
return (const u_char *)ext + item_len;
@@ -2564,6 +2617,7 @@ ikev2_vid_print(netdissect_options *ndo, u_char tpay,
else ND_PRINT((ndo, "."));
}
if (2 < ndo->ndo_vflag && 4 < len) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@@ -2729,7 +2783,6 @@ ikev1_sub_print(netdissect_options *ndo,
while (np) {
ND_TCHECK(*ext);
-
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_TCHECK2(*ext, ntohs(e.len));
@@ -2897,7 +2950,6 @@ ikev2_sub_print(netdissect_options *ndo,
cp = (const u_char *)ext;
while (np) {
ND_TCHECK(*ext);
-
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_TCHECK2(*ext, ntohs(e.len));
@@ -3051,7 +3103,7 @@ isakmp_rfc3948_print(netdissect_options *ndo,
const u_char *bp, u_int length,
const u_char *bp2)
{
-
+ ND_TCHECK(bp[0]);
if(length == 1 && bp[0]==0xff) {
ND_PRINT((ndo, "isakmp-nat-keep-alive"));
return;
@@ -3060,6 +3112,7 @@ isakmp_rfc3948_print(netdissect_options *ndo,
if(length < 4) {
goto trunc;
}
+ ND_TCHECK(bp[3]);
/*
* see if this is an IKE packet
@@ -3100,10 +3153,6 @@ trunc:
* c-basic-offset: 8
* End:
*/
-
-
-
-
#ifdef __rtems__
#include "rtems-bsd-tcpdump-print-isakmp-data.h"
#endif /* __rtems__ */
diff --git a/freebsd/contrib/tcpdump/print-isoclns.c b/freebsd/contrib/tcpdump/print-isoclns.c
index 7fec66e0..480e5f19 100644
--- a/freebsd/contrib/tcpdump/print-isoclns.c
+++ b/freebsd/contrib/tcpdump/print-isoclns.c
@@ -26,7 +26,7 @@
*
* Original code by Matt Thomas, Digital Equipment Corporation
*
- * Extensively modified by Hannes Gredler (hannes@juniper.net) for more
+ * Extensively modified by Hannes Gredler (hannes@gredler.at) for more
* complete IS-IS & CLNP support.
*/
@@ -570,8 +570,8 @@ struct isis_tlv_ptp_adj {
uint8_t neighbor_extd_local_circuit_id[4];
};
-static int osi_print_cksum(netdissect_options *, const uint8_t *pptr,
- uint16_t checksum, int checksum_offset, int length);
+static void osi_print_cksum(netdissect_options *, const uint8_t *pptr,
+ uint16_t checksum, int checksum_offset, u_int length);
static int clnp_print(netdissect_options *, const uint8_t *, u_int);
static void esis_print(netdissect_options *, const uint8_t *, u_int);
static int isis_print(netdissect_options *, const uint8_t *, u_int);
@@ -676,10 +676,9 @@ struct isis_tlv_lsp {
#define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
void
-isoclns_print(netdissect_options *ndo,
- const uint8_t *p, u_int length, u_int caplen)
+isoclns_print(netdissect_options *ndo, const uint8_t *p, u_int length)
{
- if (caplen <= 1) { /* enough bytes on the wire ? */
+ if (!ND_TTEST(*p)) { /* enough bytes on the wire ? */
ND_PRINT((ndo, "|OSI"));
return;
}
@@ -691,7 +690,7 @@ isoclns_print(netdissect_options *ndo,
case NLPID_CLNP:
if (!clnp_print(ndo, p, length))
- print_unknown_data(ndo, p, "\n\t", caplen);
+ print_unknown_data(ndo, p, "\n\t", length);
break;
case NLPID_ESIS:
@@ -700,7 +699,7 @@ isoclns_print(netdissect_options *ndo,
case NLPID_ISIS:
if (!isis_print(ndo, p, length))
- print_unknown_data(ndo, p, "\n\t", caplen);
+ print_unknown_data(ndo, p, "\n\t", length);
break;
case NLPID_NULLNS:
@@ -727,8 +726,8 @@ isoclns_print(netdissect_options *ndo,
if (!ndo->ndo_eflag)
ND_PRINT((ndo, "OSI NLPID 0x%02x unknown", *p));
ND_PRINT((ndo, "%slength: %u", ndo->ndo_eflag ? "" : ", ", length));
- if (caplen > 1)
- print_unknown_data(ndo, p, "\n\t", caplen);
+ if (length > 1)
+ print_unknown_data(ndo, p, "\n\t", length);
break;
}
}
@@ -871,9 +870,8 @@ clnp_print(netdissect_options *ndo,
EXTRACT_16BITS(clnp_header->segment_length),
EXTRACT_16BITS(clnp_header->cksum)));
- if (osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7,
- clnp_header->length_indicator) == 0)
- goto trunc;
+ osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7,
+ clnp_header->length_indicator);
ND_PRINT((ndo, "\n\tFlags [%s]",
bittok2str(clnp_flag_values, "none", clnp_flags)));
@@ -1159,8 +1157,7 @@ esis_print(netdissect_options *ndo,
ND_PRINT((ndo, ", v: %u%s", esis_header->version, esis_header->version == ESIS_VERSION ? "" : "unsupported" ));
ND_PRINT((ndo, ", checksum: 0x%04x", EXTRACT_16BITS(esis_header->cksum)));
- if (osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li) == 0)
- goto trunc;
+ osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li);
ND_PRINT((ndo, ", holding time: %us, length indicator: %u",
EXTRACT_16BITS(esis_header->holdtime), li));
@@ -1226,10 +1223,18 @@ esis_print(netdissect_options *ndo,
pptr += netal;
li -= netal;
- if (netal == 0)
- ND_PRINT((ndo, "\n\t %s", etheraddr_string(ndo, snpa)));
+ if (snpal == 6)
+ ND_PRINT((ndo, "\n\t SNPA (length: %u): %s",
+ snpal,
+ etheraddr_string(ndo, snpa)));
else
- ND_PRINT((ndo, "\n\t %s", isonsap_string(ndo, neta, netal)));
+ ND_PRINT((ndo, "\n\t SNPA (length: %u): %s",
+ snpal,
+ linkaddr_string(ndo, snpa, LINKADDR_OTHER, snpal)));
+ if (netal != 0)
+ ND_PRINT((ndo, "\n\t NET (length: %u) %s",
+ netal,
+ isonsap_string(ndo, neta, netal)));
break;
}
@@ -1335,7 +1340,7 @@ esis_print(netdissect_options *ndo,
case ESIS_OPTION_PROTOCOLS:
while (opli>0) {
- ND_TCHECK(*pptr);
+ ND_TCHECK(*tptr);
ND_PRINT((ndo, "%s (0x%02x)",
tok2str(nlpid_values,
"unknown",
@@ -1368,7 +1373,7 @@ esis_print(netdissect_options *ndo,
pptr += opli;
}
trunc:
- return;
+ ND_PRINT((ndo, "[|esis]"));
}
static void
@@ -1404,6 +1409,7 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
while (len > 2)
{
+ ND_TCHECK2(*tptr, 2);
stlv_type = *(tptr++);
stlv_len = *(tptr++);
@@ -1416,11 +1422,18 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
/*len -= TLV_TYPE_LEN_OFFSET;*/
len = len -2;
+ /* Make sure the subTLV fits within the space left */
+ if (len < stlv_len)
+ goto trunc;
+ /* Make sure the entire subTLV is in the captured data */
+ ND_TCHECK2(*(tptr), stlv_len);
+
switch (stlv_type)
{
case ISIS_SUBTLV_SPB_MCID:
{
- ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN);
+ if (stlv_len < ISIS_SUBTLV_SPB_MCID_MIN_LEN)
+ goto trunc;
subtlv_spb_mcid = (const struct isis_subtlv_spb_mcid *)tptr;
@@ -1435,15 +1448,17 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
/*tptr += SPB_MCID_MIN_LEN;
len -= SPB_MCID_MIN_LEN; */
- tptr = tptr + sizeof(struct isis_subtlv_spb_mcid);
- len = len - sizeof(struct isis_subtlv_spb_mcid);
+ tptr = tptr + ISIS_SUBTLV_SPB_MCID_MIN_LEN;
+ len = len - ISIS_SUBTLV_SPB_MCID_MIN_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_MCID_MIN_LEN;
break;
}
case ISIS_SUBTLV_SPB_DIGEST:
{
- ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN);
+ if (stlv_len < ISIS_SUBTLV_SPB_DIGEST_MIN_LEN)
+ goto trunc;
ND_PRINT((ndo, "\n\t RES: %d V: %d A: %d D: %d",
(*(tptr) >> 5), (((*tptr)>> 4) & 0x01),
@@ -1462,18 +1477,15 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
}
len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
break;
}
case ISIS_SUBTLV_SPB_BVID:
{
- ND_TCHECK2(*(tptr), stlv_len);
-
- while (len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN)
+ while (stlv_len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN)
{
- ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN);
-
ND_PRINT((ndo, "\n\t ECT: %08x",
EXTRACT_32BITS(tptr)));
@@ -1486,14 +1498,17 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
tptr = tptr + 2;
len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
}
break;
}
default:
- break;
+ break;
}
+ tptr += stlv_len;
+ len -= stlv_len;
}
return 0;
@@ -1512,6 +1527,7 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
while (len > 2)
{
+ ND_TCHECK2(*tptr, 2);
stlv_type = *(tptr++);
stlv_len = *(tptr++);
@@ -1523,11 +1539,17 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
len = len - 2;
+ /* Make sure the subTLV fits within the space left */
+ if (len < stlv_len)
+ goto trunc;
+ /* Make sure the entire subTLV is in the captured data */
+ ND_TCHECK2(*(tptr), stlv_len);
+
switch (stlv_type)
{
case ISIS_SUBTLV_SPB_INSTANCE:
-
- ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN);
+ if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN)
+ goto trunc;
ND_PRINT((ndo, "\n\t CIST Root-ID: %08x", EXTRACT_32BITS(tptr)));
tptr = tptr+4;
@@ -1549,10 +1571,12 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
tmp = *(tptr++);
len = len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
while (tmp)
{
- ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN);
+ if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN)
+ goto trunc;
ND_PRINT((ndo, "\n\t U:%d, M:%d, A:%d, RES:%d",
*(tptr) >> 7, (*(tptr) >> 6) & 0x01,
@@ -1570,14 +1594,15 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
tptr = tptr + 3;
len = len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
tmp--;
}
break;
case ISIS_SUBTLV_SPBM_SI:
-
- ND_TCHECK2(*tptr, 8);
+ if (stlv_len < 8)
+ goto trunc;
ND_PRINT((ndo, "\n\t BMAC: %08x", EXTRACT_32BITS(tptr)));
tptr = tptr+4;
@@ -1609,6 +1634,8 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
default:
break;
}
+ tptr += stlv_len;
+ len -= stlv_len;
}
return 0;
@@ -1625,8 +1652,12 @@ isis_print_id(const uint8_t *cp, int id_len)
int i;
static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")];
char *pos = id;
+ int sysid_len;
- for (i = 1; i <= SYSTEM_ID_LEN; i++) {
+ sysid_len = SYSTEM_ID_LEN;
+ if (sysid_len > id_len)
+ sysid_len = id_len;
+ for (i = 1; i <= sysid_len; i++) {
snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++);
pos += strlen(pos);
if (i == 2 || i == 4)
@@ -1836,6 +1867,8 @@ isis_print_is_reach_subtlv(netdissect_options *ndo,
break;
case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */
case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD:
+ if (subl == 0)
+ break;
ND_PRINT((ndo, "%sBandwidth Constraints Model ID: %s (%u)",
ident,
tok2str(diffserv_te_bc_values, "unknown", *tptr),
@@ -1843,7 +1876,6 @@ isis_print_is_reach_subtlv(netdissect_options *ndo,
tptr++;
/* decode BCs until the subTLV ends */
for (te_class = 0; te_class < (subl-1)/4; te_class++) {
- ND_TCHECK2(*tptr, 4);
bw.i = EXTRACT_32BITS(tptr);
ND_PRINT((ndo, "%s Bandwidth constraint CT%u: %.3f Mbps",
ident,
@@ -1905,13 +1937,15 @@ isis_print_is_reach_subtlv(netdissect_options *ndo,
case GMPLS_PSC2:
case GMPLS_PSC3:
case GMPLS_PSC4:
- ND_TCHECK2(*tptr, 6);
+ if (subl < 6)
+ break;
bw.i = EXTRACT_32BITS(tptr);
ND_PRINT((ndo, "%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000));
ND_PRINT((ndo, "%s Interface MTU: %u", ident, EXTRACT_16BITS(tptr + 4)));
break;
case GMPLS_TSC:
- ND_TCHECK2(*tptr, 8);
+ if (subl < 8)
+ break;
bw.i = EXTRACT_32BITS(tptr);
ND_PRINT((ndo, "%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000));
ND_PRINT((ndo, "%s Indication %s", ident,
@@ -2047,7 +2081,7 @@ isis_print_extd_ip_reach(netdissect_options *ndo,
}
processed++;
} else if (afi == AF_INET6) {
- if (!ND_TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */
+ if (!ND_TTEST2(*tptr, 2)) /* fetch status & prefix_len byte */
return (0);
status_byte=*(tptr++);
bit_length=*(tptr++);
@@ -2170,6 +2204,8 @@ isis_print(netdissect_options *ndo,
TLV verification */
isis_header = (const struct isis_common_header *)p;
ND_TCHECK(*isis_header);
+ if (length < ISIS_COMMON_HEADER_SIZE)
+ goto trunc;
pptr = p+(ISIS_COMMON_HEADER_SIZE);
header_iih_lan = (const struct isis_iih_lan_header *)pptr;
header_iih_ptp = (const struct isis_iih_ptp_header *)pptr;
@@ -2200,6 +2236,16 @@ isis_print(netdissect_options *ndo,
return (0);
}
+ if (length < isis_header->fixed_len) {
+ ND_PRINT((ndo, "fixed header length %u > packet length %u", isis_header->fixed_len, length));
+ return (0);
+ }
+
+ if (isis_header->fixed_len < ISIS_COMMON_HEADER_SIZE) {
+ ND_PRINT((ndo, "fixed header length %u < minimum header size %u", isis_header->fixed_len, (u_int)ISIS_COMMON_HEADER_SIZE));
+ return (0);
+ }
+
max_area = isis_header->max_area;
switch(max_area) {
case 0:
@@ -2242,254 +2288,255 @@ isis_print(netdissect_options *ndo,
pdu_type=isis_header->pdu_type;
/* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/
- if (ndo->ndo_vflag < 1) {
+ if (ndo->ndo_vflag == 0) {
ND_PRINT((ndo, "%s%s",
ndo->ndo_eflag ? "" : ", ",
tok2str(isis_pdu_values, "unknown PDU-Type %u", pdu_type)));
+ } else {
+ /* ok they seem to want to know everything - lets fully decode it */
+ ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length));
- switch (pdu_type) {
-
- case ISIS_PDU_L1_LAN_IIH:
- case ISIS_PDU_L2_LAN_IIH:
- ND_TCHECK(*header_iih_lan);
- ND_PRINT((ndo, ", src-id %s",
- isis_print_id(header_iih_lan->source_id, SYSTEM_ID_LEN)));
- ND_PRINT((ndo, ", lan-id %s, prio %u",
- isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN),
- header_iih_lan->priority));
- break;
- case ISIS_PDU_PTP_IIH:
- ND_TCHECK(*header_iih_ptp);
- ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN)));
- break;
- case ISIS_PDU_L1_LSP:
- case ISIS_PDU_L2_LSP:
- ND_TCHECK(*header_lsp);
- ND_PRINT((ndo, ", lsp-id %s, seq 0x%08x, lifetime %5us",
- isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
- EXTRACT_32BITS(header_lsp->sequence_number),
- EXTRACT_16BITS(header_lsp->remaining_lifetime)));
- break;
- case ISIS_PDU_L1_CSNP:
- case ISIS_PDU_L2_CSNP:
- ND_TCHECK(*header_csnp);
- ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN)));
- break;
- case ISIS_PDU_L1_PSNP:
- case ISIS_PDU_L2_PSNP:
- ND_TCHECK(*header_psnp);
- ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN)));
- break;
-
- }
- ND_PRINT((ndo, ", length %u", length));
-
- return(1);
- }
-
- /* ok they seem to want to know everything - lets fully decode it */
- ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length));
-
- ND_PRINT((ndo, "\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
- tok2str(isis_pdu_values,
- "unknown, type %u",
- pdu_type),
- isis_header->fixed_len,
- isis_header->version,
- isis_header->pdu_version,
- id_length,
- isis_header->id_length,
- max_area,
- isis_header->max_area));
-
- if (ndo->ndo_vflag > 1) {
- if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */
- return(0); /* for optionally debugging the common header */
+ ND_PRINT((ndo, "\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
+ tok2str(isis_pdu_values,
+ "unknown, type %u",
+ pdu_type),
+ isis_header->fixed_len,
+ isis_header->version,
+ isis_header->pdu_version,
+ id_length,
+ isis_header->id_length,
+ max_area,
+ isis_header->max_area));
+
+ if (ndo->ndo_vflag > 1) {
+ if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */
+ return (0); /* for optionally debugging the common header */
+ }
}
switch (pdu_type) {
case ISIS_PDU_L1_LAN_IIH:
case ISIS_PDU_L2_LAN_IIH:
- if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
- ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
- isis_header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE));
- return (0);
- }
-
- ND_TCHECK(*header_iih_lan);
- pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
- if (packet_len>pdu_len) {
- packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
- length=pdu_len;
- }
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
+ ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)));
+ return (0);
+ }
+ ND_TCHECK(*header_iih_lan);
+ if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)
+ goto trunc;
+ if (ndo->ndo_vflag == 0) {
+ ND_PRINT((ndo, ", src-id %s",
+ isis_print_id(header_iih_lan->source_id, SYSTEM_ID_LEN)));
+ ND_PRINT((ndo, ", lan-id %s, prio %u",
+ isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN),
+ header_iih_lan->priority));
+ ND_PRINT((ndo, ", length %u", length));
+ return (1);
+ }
+ pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
+ if (packet_len>pdu_len) {
+ packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
+ length=pdu_len;
+ }
- ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
- isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN),
- EXTRACT_16BITS(header_iih_lan->holding_time),
- tok2str(isis_iih_circuit_type_values,
- "unknown circuit type 0x%02x",
- header_iih_lan->circuit_type)));
+ ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
+ isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN),
+ EXTRACT_16BITS(header_iih_lan->holding_time),
+ tok2str(isis_iih_circuit_type_values,
+ "unknown circuit type 0x%02x",
+ header_iih_lan->circuit_type)));
- ND_PRINT((ndo, "\n\t lan-id: %s, Priority: %u, PDU length: %u",
- isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN),
- (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK,
- pdu_len));
+ ND_PRINT((ndo, "\n\t lan-id: %s, Priority: %u, PDU length: %u",
+ isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN),
+ (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK,
+ pdu_len));
- if (ndo->ndo_vflag > 1) {
- if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_LAN_HEADER_SIZE))
- return(0);
- }
+ if (ndo->ndo_vflag > 1) {
+ if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_LAN_HEADER_SIZE))
+ return (0);
+ }
- packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
- pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
- break;
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
+ break;
case ISIS_PDU_PTP_IIH:
- if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
- ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
- isis_header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE));
- return (0);
- }
-
- ND_TCHECK(*header_iih_ptp);
- pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
- if (packet_len>pdu_len) {
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
+ ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)));
+ return (0);
+ }
+ ND_TCHECK(*header_iih_ptp);
+ if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)
+ goto trunc;
+ if (ndo->ndo_vflag == 0) {
+ ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN)));
+ ND_PRINT((ndo, ", length %u", length));
+ return (1);
+ }
+ pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
+ if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
- }
+ }
- ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
- isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN),
- EXTRACT_16BITS(header_iih_ptp->holding_time),
- tok2str(isis_iih_circuit_type_values,
- "unknown circuit type 0x%02x",
- header_iih_ptp->circuit_type)));
+ ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
+ isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN),
+ EXTRACT_16BITS(header_iih_ptp->holding_time),
+ tok2str(isis_iih_circuit_type_values,
+ "unknown circuit type 0x%02x",
+ header_iih_ptp->circuit_type)));
- ND_PRINT((ndo, "\n\t circuit-id: 0x%02x, PDU length: %u",
- header_iih_ptp->circuit_id,
- pdu_len));
+ ND_PRINT((ndo, "\n\t circuit-id: 0x%02x, PDU length: %u",
+ header_iih_ptp->circuit_id,
+ pdu_len));
- if (ndo->ndo_vflag > 1) {
- if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE))
- return(0);
- }
+ if (ndo->ndo_vflag > 1) {
+ if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE))
+ return (0);
+ }
- packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
- pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
- break;
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
+ break;
case ISIS_PDU_L1_LSP:
case ISIS_PDU_L2_LSP:
- if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
- ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
- isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE));
- return (0);
- }
-
- ND_TCHECK(*header_lsp);
- pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
- if (packet_len>pdu_len) {
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
+ ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE));
+ return (0);
+ }
+ ND_TCHECK(*header_lsp);
+ if (length < ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)
+ goto trunc;
+ if (ndo->ndo_vflag == 0) {
+ ND_PRINT((ndo, ", lsp-id %s, seq 0x%08x, lifetime %5us",
+ isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
+ EXTRACT_32BITS(header_lsp->sequence_number),
+ EXTRACT_16BITS(header_lsp->remaining_lifetime)));
+ ND_PRINT((ndo, ", length %u", length));
+ return (1);
+ }
+ pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
+ if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
- }
+ }
- ND_PRINT((ndo, "\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x",
+ ND_PRINT((ndo, "\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x",
isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
EXTRACT_32BITS(header_lsp->sequence_number),
EXTRACT_16BITS(header_lsp->remaining_lifetime),
EXTRACT_16BITS(header_lsp->checksum)));
- if (osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id,
- EXTRACT_16BITS(header_lsp->checksum),
- 12, length-12) == 0)
- goto trunc;
+ osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id,
+ EXTRACT_16BITS(header_lsp->checksum),
+ 12, length-12);
- ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s",
+ ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s",
pdu_len,
ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""));
- if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
- ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""));
- ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""));
- ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""));
- ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""));
- ND_PRINT((ndo, "ATT bit set, "));
- }
- ND_PRINT((ndo, "%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""));
- ND_PRINT((ndo, "%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)",
- ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))));
+ if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
+ ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""));
+ ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""));
+ ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""));
+ ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""));
+ ND_PRINT((ndo, "ATT bit set, "));
+ }
+ ND_PRINT((ndo, "%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""));
+ ND_PRINT((ndo, "%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)",
+ ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))));
- if (ndo->ndo_vflag > 1) {
- if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_LSP_HEADER_SIZE))
- return(0);
- }
+ if (ndo->ndo_vflag > 1) {
+ if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_LSP_HEADER_SIZE))
+ return (0);
+ }
- packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
- pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
- break;
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
+ break;
case ISIS_PDU_L1_CSNP:
case ISIS_PDU_L2_CSNP:
- if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
- ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
- isis_header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE));
- return (0);
- }
-
- ND_TCHECK(*header_csnp);
- pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
- if (packet_len>pdu_len) {
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
+ ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)));
+ return (0);
+ }
+ ND_TCHECK(*header_csnp);
+ if (length < ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)
+ goto trunc;
+ if (ndo->ndo_vflag == 0) {
+ ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN)));
+ ND_PRINT((ndo, ", length %u", length));
+ return (1);
+ }
+ pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
+ if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
- }
+ }
- ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
+ ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
isis_print_id(header_csnp->source_id, NODE_ID_LEN),
pdu_len));
- ND_PRINT((ndo, "\n\t start lsp-id: %s",
+ ND_PRINT((ndo, "\n\t start lsp-id: %s",
isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN)));
- ND_PRINT((ndo, "\n\t end lsp-id: %s",
+ ND_PRINT((ndo, "\n\t end lsp-id: %s",
isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN)));
- if (ndo->ndo_vflag > 1) {
- if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_CSNP_HEADER_SIZE))
- return(0);
- }
+ if (ndo->ndo_vflag > 1) {
+ if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_CSNP_HEADER_SIZE))
+ return (0);
+ }
- packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
- pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
break;
case ISIS_PDU_L1_PSNP:
case ISIS_PDU_L2_PSNP:
- if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
- ND_PRINT((ndo, "- bogus fixed header length %u should be %lu",
- isis_header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE));
- return (0);
- }
-
- ND_TCHECK(*header_psnp);
- pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
- if (packet_len>pdu_len) {
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
+ ND_PRINT((ndo, "- bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)));
+ return (0);
+ }
+ ND_TCHECK(*header_psnp);
+ if (length < ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)
+ goto trunc;
+ if (ndo->ndo_vflag == 0) {
+ ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN)));
+ ND_PRINT((ndo, ", length %u", length));
+ return (1);
+ }
+ pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
+ if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
- }
+ }
- ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
+ ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
isis_print_id(header_psnp->source_id, NODE_ID_LEN),
pdu_len));
- if (ndo->ndo_vflag > 1) {
- if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_PSNP_HEADER_SIZE))
- return(0);
- }
+ if (ndo->ndo_vflag > 1) {
+ if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_PSNP_HEADER_SIZE))
+ return (0);
+ }
- packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
- pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
- break;
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
+ break;
default:
+ if (ndo->ndo_vflag == 0) {
+ ND_PRINT((ndo, ", length %u", length));
+ return (1);
+ }
(void)print_unknown_data(ndo, pptr, "\n\t ", length);
return (0);
}
@@ -2498,20 +2545,15 @@ isis_print(netdissect_options *ndo,
* Now print the TLV's.
*/
- while (packet_len >= 2) {
- if (pptr == ndo->ndo_snapend) {
- return (1);
- }
-
+ while (packet_len > 0) {
ND_TCHECK2(*pptr, 2);
+ if (packet_len < 2)
+ goto trunc;
tlv_type = *pptr++;
tlv_len = *pptr++;
tmp =tlv_len; /* copy temporary len & pointer to packet data */
tptr = pptr;
packet_len -= 2;
- if (tlv_len > packet_len) {
- break;
- }
/* first lets see if we know the TLVs name*/
ND_PRINT((ndo, "\n\t %s TLV #%u, length: %u",
@@ -2524,12 +2566,16 @@ isis_print(netdissect_options *ndo,
if (tlv_len == 0) /* something is invalid */
continue;
+ if (packet_len < tlv_len)
+ goto trunc;
+
/* now check if we have a decoder otherwise do a hexdump at the end*/
switch (tlv_type) {
case ISIS_TLV_AREA_ADDR:
ND_TCHECK2(*tptr, 1);
alen = *tptr++;
while (tmp && alen < tmp) {
+ ND_TCHECK2(*tptr, alen);
ND_PRINT((ndo, "\n\t Area address (length: %u): %s",
alen,
isonsap_string(ndo, tptr, alen)));
@@ -2912,9 +2958,8 @@ isis_print(netdissect_options *ndo,
* to avoid conflicts the checksum TLV is zeroed.
* see rfc3358 for details
*/
- if (osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr,
- length) == 0)
- goto trunc;
+ osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr,
+ length);
break;
case ISIS_TLV_POI:
@@ -3108,40 +3153,33 @@ isis_print(netdissect_options *ndo,
return(1);
}
-static int
+static void
osi_print_cksum(netdissect_options *ndo, const uint8_t *pptr,
- uint16_t checksum, int checksum_offset, int length)
+ uint16_t checksum, int checksum_offset, u_int length)
{
uint16_t calculated_checksum;
/* do not attempt to verify the checksum if it is zero,
- * if the total length is nonsense,
* if the offset is nonsense,
* or the base pointer is not sane
*/
if (!checksum
- || length < 0
|| checksum_offset < 0
- || length > ndo->ndo_snaplen
- || checksum_offset > ndo->ndo_snaplen
- || checksum_offset > length) {
+ || !ND_TTEST2(*(pptr + checksum_offset), 2)
+ || (u_int)checksum_offset > length
+ || !ND_TTEST2(*pptr, length)) {
ND_PRINT((ndo, " (unverified)"));
- return 1;
} else {
#if 0
- printf("\nosi_print_cksum: %p %u %u %u\n", pptr, checksum_offset, length, ndo->ndo_snaplen);
+ printf("\nosi_print_cksum: %p %u %u\n", pptr, checksum_offset, length);
#endif
- ND_TCHECK2(*pptr, length);
calculated_checksum = create_osi_cksum(pptr, checksum_offset, length);
if (checksum == calculated_checksum) {
ND_PRINT((ndo, " (correct)"));
} else {
ND_PRINT((ndo, " (incorrect should be 0x%04x)", calculated_checksum));
}
- return 1;
}
-trunc:
- return 0;
}
/*
diff --git a/freebsd/contrib/tcpdump/print-juniper.c b/freebsd/contrib/tcpdump/print-juniper.c
index 647110ef..db252a9d 100644
--- a/freebsd/contrib/tcpdump/print-juniper.c
+++ b/freebsd/contrib/tcpdump/print-juniper.c
@@ -18,7 +18,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: DLT_JUNIPER_* printers */
@@ -478,6 +478,7 @@ juniper_ggsn_print(netdissect_options *ndo,
p+=l2info.header_len;
gh = (struct juniper_ggsn_header *)&l2info.cookie;
+ ND_TCHECK(*gh);
if (ndo->ndo_eflag) {
ND_PRINT((ndo, "proto %s (%u), vlan %u: ",
tok2str(juniper_protocol_values,"Unknown",gh->proto),
@@ -498,6 +499,10 @@ juniper_ggsn_print(netdissect_options *ndo,
}
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_services]"));
+ return l2info.header_len;
}
#endif
@@ -525,6 +530,7 @@ juniper_es_print(netdissect_options *ndo,
p+=l2info.header_len;
ih = (const struct juniper_ipsec_header *)p;
+ ND_TCHECK(*ih);
switch (ih->type) {
case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE:
case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE:
@@ -570,6 +576,10 @@ juniper_es_print(netdissect_options *ndo,
ip_print(ndo, p, l2info.length);
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_services]"));
+ return l2info.header_len;
}
#endif
@@ -594,6 +604,7 @@ juniper_monitor_print(netdissect_options *ndo,
p+=l2info.header_len;
mh = (const struct juniper_monitor_header *)p;
+ ND_TCHECK(*mh);
if (ndo->ndo_eflag)
ND_PRINT((ndo, "service-id %u, iif %u, pkt-type %u: ",
EXTRACT_32BITS(&mh->service_id),
@@ -604,6 +615,10 @@ juniper_monitor_print(netdissect_options *ndo,
ip_heuristic_guess (ndo, p, l2info.length);
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_services]"));
+ return l2info.header_len;
}
#endif
@@ -628,6 +643,7 @@ juniper_services_print(netdissect_options *ndo,
p+=l2info.header_len;
sh = (const struct juniper_services_header *)p;
+ ND_TCHECK(*sh);
if (ndo->ndo_eflag)
ND_PRINT((ndo, "service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
sh->svc_id,
@@ -639,6 +655,10 @@ juniper_services_print(netdissect_options *ndo,
ip_heuristic_guess (ndo, p, l2info.length);
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_services]"));
+ return l2info.header_len;
}
#endif
@@ -746,6 +766,7 @@ juniper_pppoe_atm_print(netdissect_options *ndo,
p+=l2info.header_len;
+ ND_TCHECK2(p[0], 2);
extracted_ethertype = EXTRACT_16BITS(p);
/* this DLT contains nothing but raw PPPoE frames,
* prepended with a type field*/
@@ -758,6 +779,10 @@ juniper_pppoe_atm_print(netdissect_options *ndo,
ND_PRINT((ndo, "unknown ethertype 0x%04x", extracted_ethertype));
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_pppoe_atm]"));
+ return l2info.header_len;
}
#endif
@@ -799,7 +824,7 @@ juniper_mlppp_print(netdissect_options *ndo,
mpls_print(ndo, p, l2info.length);
return l2info.header_len;
case JUNIPER_LSQ_L3_PROTO_ISO:
- isoclns_print(ndo, p, l2info.length, l2info.caplen);
+ isoclns_print(ndo, p, l2info.length);
return l2info.header_len;
default:
break;
@@ -854,7 +879,7 @@ juniper_mfr_print(netdissect_options *ndo,
mpls_print(ndo, p, l2info.length);
return l2info.header_len;
case JUNIPER_LSQ_L3_PROTO_ISO:
- isoclns_print(ndo, p, l2info.length, l2info.caplen);
+ isoclns_print(ndo, p, l2info.length);
return l2info.header_len;
default:
break;
@@ -867,13 +892,13 @@ juniper_mfr_print(netdissect_options *ndo,
ND_PRINT((ndo, "Bundle-ID %u, ", l2info.bundle));
switch (l2info.proto) {
case (LLCSAP_ISONS<<8 | LLCSAP_ISONS):
- isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
+ isoclns_print(ndo, p + 1, l2info.length - 1);
break;
case (LLC_UI<<8 | NLPID_Q933):
case (LLC_UI<<8 | NLPID_IP):
case (LLC_UI<<8 | NLPID_IP6):
/* pass IP{4,6} to the OSI layer for proper link-layer printing */
- isoclns_print(ndo, p - 1, l2info.length + 1, l2info.caplen + 1);
+ isoclns_print(ndo, p - 1, l2info.length + 1);
break;
default:
ND_PRINT((ndo, "unknown protocol 0x%04x, length %u", l2info.proto, l2info.length));
@@ -902,13 +927,13 @@ juniper_mlfr_print(netdissect_options *ndo,
switch (l2info.proto) {
case (LLC_UI):
case (LLC_UI<<8):
- isoclns_print(ndo, p, l2info.length, l2info.caplen);
+ isoclns_print(ndo, p, l2info.length);
break;
case (LLC_UI<<8 | NLPID_Q933):
case (LLC_UI<<8 | NLPID_IP):
case (LLC_UI<<8 | NLPID_IP6):
/* pass IP{4,6} to the OSI layer for proper link-layer printing */
- isoclns_print(ndo, p - 1, l2info.length + 1, l2info.caplen + 1);
+ isoclns_print(ndo, p - 1, l2info.length + 1);
break;
default:
ND_PRINT((ndo, "unknown protocol 0x%04x, length %u", l2info.proto, l2info.length));
@@ -946,6 +971,7 @@ juniper_atm1_print(netdissect_options *ndo,
return l2info.header_len;
}
+ ND_TCHECK2(p[0], 3);
if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
@@ -955,7 +981,7 @@ juniper_atm1_print(netdissect_options *ndo,
}
if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
- isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
+ isoclns_print(ndo, p + 1, l2info.length - 1);
/* FIXME check if frame was recognized */
return l2info.header_len;
}
@@ -964,6 +990,10 @@ juniper_atm1_print(netdissect_options *ndo,
return l2info.header_len;
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_atm1]"));
+ return l2info.header_len;
}
#endif
@@ -995,6 +1025,7 @@ juniper_atm2_print(netdissect_options *ndo,
return l2info.header_len;
}
+ ND_TCHECK2(p[0], 3);
if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
@@ -1010,7 +1041,7 @@ juniper_atm2_print(netdissect_options *ndo,
}
if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
- isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
+ isoclns_print(ndo, p + 1, l2info.length - 1);
/* FIXME check if frame was recognized */
return l2info.header_len;
}
@@ -1022,6 +1053,10 @@ juniper_atm2_print(netdissect_options *ndo,
return l2info.header_len;
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_atm2]"));
+ return l2info.header_len;
}
#endif
@@ -1286,6 +1321,7 @@ juniper_parse_header(netdissect_options *ndo,
l2info->caplen -= l2info->header_len;
/* search through the cookie table and copy values matching for our PIC type */
+ ND_TCHECK(p[0]);
while (lp->s != NULL) {
if (lp->pictype == l2info->pictype) {
@@ -1337,6 +1373,7 @@ juniper_parse_header(netdissect_options *ndo,
if (ndo->ndo_eflag) ND_PRINT((ndo, ": ")); /* print demarc b/w L2/L3*/
+ ND_TCHECK_16BITS(p+l2info->cookie_len);
l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len);
break;
}
@@ -1366,6 +1403,7 @@ juniper_parse_header(netdissect_options *ndo,
case DLT_JUNIPER_MLFR:
switch (l2info->cookie_type) {
case LS_COOKIE_ID:
+ ND_TCHECK2(p[0], 2);
l2info->bundle = l2info->cookie[1];
l2info->proto = EXTRACT_16BITS(p);
l2info->header_len += 2;
@@ -1389,6 +1427,7 @@ juniper_parse_header(netdissect_options *ndo,
case DLT_JUNIPER_MFR:
switch (l2info->cookie_type) {
case LS_COOKIE_ID:
+ ND_TCHECK2(p[0], 2);
l2info->bundle = l2info->cookie[1];
l2info->proto = EXTRACT_16BITS(p);
l2info->header_len += 2;
diff --git a/freebsd/contrib/tcpdump/print-l2tp.c b/freebsd/contrib/tcpdump/print-l2tp.c
index a4ea2061..f2100fa7 100644
--- a/freebsd/contrib/tcpdump/print-l2tp.c
+++ b/freebsd/contrib/tcpdump/print-l2tp.c
@@ -303,10 +303,14 @@ print_32bits_val(netdissect_options *ndo, const uint32_t *dat)
/* AVP-specific print out routines */
/***********************************/
static void
-l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat)
+l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
ND_PRINT((ndo, "%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
EXTRACT_16BITS(ptr))));
}
@@ -316,28 +320,53 @@ l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
- ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr))); ptr++; /* Result Code */
- if (length > 2) { /* Error Code (opt) */
- ND_PRINT((ndo, "/%u", EXTRACT_16BITS(ptr))); ptr++;
+ /* Result Code */
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
}
- if (length > 4) { /* Error Message (opt) */
- ND_PRINT((ndo, " "));
- print_string(ndo, (const u_char *)ptr, length - 4);
+ ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr)));
+ ptr++;
+ length -= 2;
+
+ /* Error Code (opt) */
+ if (length == 0)
+ return;
+ if (length < 2) {
+ ND_PRINT((ndo, " AVP too short"));
+ return;
}
+ ND_PRINT((ndo, "/%u", EXTRACT_16BITS(ptr)));
+ ptr++;
+ length -= 2;
+
+ /* Error Message (opt) */
+ if (length == 0)
+ return;
+ ND_PRINT((ndo, " "));
+ print_string(ndo, (const u_char *)ptr, length);
}
static void
-l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat)
+l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat, u_int length)
{
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
ND_PRINT((ndo, "%u.%u", (EXTRACT_16BITS(dat) >> 8),
(EXTRACT_16BITS(dat) & 0xff)));
}
static void
-l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat)
+l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint32_t *ptr = (const uint32_t *)dat;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) {
ND_PRINT((ndo, "A"));
}
@@ -347,10 +376,14 @@ l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat)
}
static void
-l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat)
+l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint32_t *ptr = (const uint32_t *)dat;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) {
ND_PRINT((ndo, "A"));
}
@@ -362,19 +395,29 @@ l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat)
static void
l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
+ if (length < 3) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
print_16bits_val(ndo, (const uint16_t *)dat);
ND_PRINT((ndo, ", %02x", dat[2]));
- if (length > 3) {
+ dat += 3;
+ length -= 3;
+ if (length != 0) {
ND_PRINT((ndo, " "));
- print_string(ndo, dat+3, length-3);
+ print_string(ndo, dat, length);
}
}
static void
-l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat)
+l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint32_t *ptr = (const uint32_t *)dat;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) {
ND_PRINT((ndo, "A"));
}
@@ -384,10 +427,14 @@ l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat)
}
static void
-l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat)
+l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint32_t *ptr = (const uint32_t *)dat;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) {
ND_PRINT((ndo, "A"));
}
@@ -403,67 +450,117 @@ l2tp_packet_proc_delay_print(netdissect_options *ndo)
}
static void
-l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat)
+l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
ND_PRINT((ndo, "%s", tok2str(l2tp_authentype2str,
"AuthType-#%u", EXTRACT_16BITS(ptr))));
}
static void
-l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat)
+l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK));
}
static void
-l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat)
+l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
uint16_t val_h, val_l;
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
ptr++; /* skip "Reserved" */
+ length -= 2;
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
+ val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "CRCErr=%u ", (val_h<<16) + val_l));
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
+ val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "FrameErr=%u ", (val_h<<16) + val_l));
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
+ val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "HardOver=%u ", (val_h<<16) + val_l));
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
+ val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "BufOver=%u ", (val_h<<16) + val_l));
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
+ val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "Timeout=%u ", (val_h<<16) + val_l));
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
val_h = EXTRACT_16BITS(ptr); ptr++;
val_l = EXTRACT_16BITS(ptr); ptr++;
ND_PRINT((ndo, "AlignErr=%u ", (val_h<<16) + val_l));
}
static void
-l2tp_accm_print(netdissect_options *ndo, const u_char *dat)
+l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
uint16_t val_h, val_l;
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
ptr++; /* skip "Reserved" */
+ length -= 2;
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
+ val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "send=%08x ", (val_h<<16) + val_l));
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
val_h = EXTRACT_16BITS(ptr); ptr++;
val_l = EXTRACT_16BITS(ptr); ptr++;
ND_PRINT((ndo, "recv=%08x ", (val_h<<16) + val_l));
@@ -474,14 +571,27 @@ l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int lengt
{
const uint16_t *ptr = (const uint16_t *)dat;
- ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(ptr))); ptr++; /* Disconnect Code */
- ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(ptr))); ptr++; /* Control Protocol Number */
+ if (length < 5) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ /* Disconnect Code */
+ ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(dat)));
+ dat += 2;
+ length -= 2;
+ /* Control Protocol Number */
+ ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(dat)));
+ dat += 2;
+ length -= 2;
+ /* Direction */
ND_PRINT((ndo, "%s", tok2str(l2tp_cc_direction2str,
- "Direction-#%u", *((const u_char *)ptr++))));
+ "Direction-#%u", EXTRACT_8BITS(ptr))));
+ ptr++;
+ length--;
- if (length > 5) {
+ if (length != 0) {
ND_PRINT((ndo, " "));
- print_string(ndo, (const u_char *)ptr, length-5);
+ print_string(ndo, (const u_char *)ptr, length);
}
}
@@ -514,7 +624,12 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
/* If it goes past the end of the remaining length of the captured
data, we'll give up. */
ND_TCHECK2(*ptr, len);
- /* After this point, no need to worry about truncation */
+
+ /*
+ * After this point, we don't need to check whether we go past
+ * the length of the captured data; however, we *do* need to
+ * check whether we go past the end of the AVP.
+ */
if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
ND_PRINT((ndo, "*"));
@@ -543,27 +658,35 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
} else {
switch (attr_type) {
case L2TP_AVP_MSGTYPE:
- l2tp_msgtype_print(ndo, (const u_char *)ptr);
+ l2tp_msgtype_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_RESULT_CODE:
l2tp_result_code_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_PROTO_VER:
- l2tp_proto_ver_print(ndo, ptr);
+ l2tp_proto_ver_print(ndo, ptr, len-6);
break;
case L2TP_AVP_FRAMING_CAP:
- l2tp_framing_cap_print(ndo, (const u_char *)ptr);
+ l2tp_framing_cap_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_BEARER_CAP:
- l2tp_bearer_cap_print(ndo, (const u_char *)ptr);
+ l2tp_bearer_cap_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_TIE_BREAKER:
+ if (len-6 < 8) {
+ ND_PRINT((ndo, "AVP too short"));
+ break;
+ }
print_octets(ndo, (const u_char *)ptr, 8);
break;
case L2TP_AVP_FIRM_VER:
case L2TP_AVP_ASSND_TUN_ID:
case L2TP_AVP_RECV_WIN_SIZE:
case L2TP_AVP_ASSND_SESS_ID:
+ if (len-6 < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ break;
+ }
print_16bits_val(ndo, ptr);
break;
case L2TP_AVP_HOST_NAME:
@@ -588,6 +711,10 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
l2tp_q931_cc_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_CHALLENGE_RESP:
+ if (len-6 < 16) {
+ ND_PRINT((ndo, "AVP too short"));
+ break;
+ }
print_octets(ndo, (const u_char *)ptr, 16);
break;
case L2TP_AVP_CALL_SER_NUM:
@@ -596,28 +723,32 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
case L2TP_AVP_TX_CONN_SPEED:
case L2TP_AVP_PHY_CHANNEL_ID:
case L2TP_AVP_RX_CONN_SPEED:
+ if (len-6 < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ break;
+ }
print_32bits_val(ndo, (const uint32_t *)ptr);
break;
case L2TP_AVP_BEARER_TYPE:
- l2tp_bearer_type_print(ndo, (const u_char *)ptr);
+ l2tp_bearer_type_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_FRAMING_TYPE:
- l2tp_framing_type_print(ndo, (const u_char *)ptr);
+ l2tp_framing_type_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_PACKET_PROC_DELAY:
l2tp_packet_proc_delay_print(ndo);
break;
case L2TP_AVP_PROXY_AUTH_TYPE:
- l2tp_proxy_auth_type_print(ndo, (const u_char *)ptr);
+ l2tp_proxy_auth_type_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_PROXY_AUTH_ID:
- l2tp_proxy_auth_id_print(ndo, (const u_char *)ptr);
+ l2tp_proxy_auth_id_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_CALL_ERRORS:
- l2tp_call_errors_print(ndo, (const u_char *)ptr);
+ l2tp_call_errors_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_ACCM:
- l2tp_accm_print(ndo, (const u_char *)ptr);
+ l2tp_accm_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_SEQ_REQUIRED:
break; /* No Attribute Value */
diff --git a/freebsd/contrib/tcpdump/print-ldp.c b/freebsd/contrib/tcpdump/print-ldp.c
index 6fe626f8..b0975868 100644
--- a/freebsd/contrib/tcpdump/print-ldp.c
+++ b/freebsd/contrib/tcpdump/print-ldp.c
@@ -16,7 +16,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
* and Steinar Haug (sthaug@nethelp.no)
*/
diff --git a/freebsd/contrib/tcpdump/print-llc.c b/freebsd/contrib/tcpdump/print-llc.c
index 210bc908..f243f468 100644
--- a/freebsd/contrib/tcpdump/print-llc.c
+++ b/freebsd/contrib/tcpdump/print-llc.c
@@ -330,7 +330,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
#endif
if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS
&& control == LLC_UI) {
- isoclns_print(ndo, p, length, caplen);
+ isoclns_print(ndo, p, length);
return (hdrlen);
}
diff --git a/freebsd/contrib/tcpdump/print-lldp.c b/freebsd/contrib/tcpdump/print-lldp.c
index b48cb3cc..213fd57e 100644
--- a/freebsd/contrib/tcpdump/print-lldp.c
+++ b/freebsd/contrib/tcpdump/print-lldp.c
@@ -18,7 +18,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
* IEEE and TIA extensions by Carles Kishimoto <carles.kishimoto@gmail.com>
* DCBX extensions by Kaladhar Musunuru <kaladharm@sourceforge.net>
*/
@@ -596,6 +596,7 @@ static const struct tok lldp_evb_mode_values[]={
{ LLDP_EVB_MODE_EVB_BRIDGE, "EVB Bridge"},
{ LLDP_EVB_MODE_EVB_STATION, "EVB Staion"},
{ LLDP_EVB_MODE_RESERVED, "Reserved for future Standardization"},
+ { 0, NULL},
};
#define NO_OF_BITS 8
@@ -656,7 +657,7 @@ lldp_private_8021_print(netdissect_options *ndo,
int subtype, hexdump = FALSE;
u_int sublen;
u_int tval;
- uint8_t i;
+ u_int i;
if (tlv_len < 4) {
return hexdump;
@@ -792,9 +793,9 @@ lldp_private_8021_print(netdissect_options *ndo,
ND_PRINT((ndo, "\n\t Application Priority Table"));
while(i<sublen) {
tval=*(tptr+i+5);
- ND_PRINT((ndo, "\n\t Priority: %d, RES: %d, Sel: %d",
- tval >> 5, (tval >> 3) & 0x03, (tval & 0x07)));
- ND_PRINT((ndo, "Protocol ID: %d", EXTRACT_16BITS(tptr + i + 5)));
+ ND_PRINT((ndo, "\n\t Priority: %u, RES: %u, Sel: %u, Protocol ID: %u",
+ tval >> 5, (tval >> 3) & 0x03, (tval & 0x07),
+ EXTRACT_16BITS(tptr + i + 5)));
i=i+3;
}
break;
@@ -903,6 +904,9 @@ lldp_private_8023_print(netdissect_options *ndo,
break;
case LLDP_PRIVATE_8023_SUBTYPE_MTU:
+ if (tlv_len < 6) {
+ return hexdump;
+ }
ND_PRINT((ndo, "\n\t MTU size %u", EXTRACT_16BITS(tptr + 4)));
break;
@@ -932,7 +936,7 @@ lldp_extract_latlon(const u_char *tptr)
* (right now there is only one)
*/
-
+
static int
lldp_private_iana_print(netdissect_options *ndo,
const u_char *tptr, u_int tlv_len)
@@ -956,12 +960,12 @@ lldp_private_iana_print(netdissect_options *ndo,
default:
hexdump=TRUE;
}
-
+
return hexdump;
}
-
+
/*
* Print private TIA extensions.
*/
@@ -1406,7 +1410,7 @@ lldp_mgmt_addr_tlv_print(netdissect_options *ndo,
if (tlen) {
oid_len = *tptr;
- if (tlen < oid_len) {
+ if (tlen < 1U + oid_len) {
return 0;
}
if (oid_len) {
diff --git a/freebsd/contrib/tcpdump/print-lmp.c b/freebsd/contrib/tcpdump/print-lmp.c
index 1ea898ee..031fdb96 100644
--- a/freebsd/contrib/tcpdump/print-lmp.c
+++ b/freebsd/contrib/tcpdump/print-lmp.c
@@ -16,14 +16,15 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
- * Support for LMP service discovery extensions (defined by UNI 1.0) added
- * by Manu Pathak (mapathak@cisco.com), May 2005
+ * Original code by Hannes Gredler (hannes@gredler.at)
+ * Support for LMP service discovery extensions (defined by OIF UNI 1.0)
+ * added by Manu Pathak (mapathak@cisco.com), May 2005
*/
/* \summary: Link Management Protocol (LMP) printer */
/* specification: RFC 4204 */
+/* OIF UNI 1.0: http://www.oiforum.com/public/documents/OIF-UNI-01.0.pdf */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -359,6 +360,73 @@ static const struct tok lmp_ctype_values[] = {
{ 0, NULL}
};
+static int
+lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr,
+ int total_subobj_len, int offset)
+{
+ int hexdump = FALSE;
+ int subobj_type, subobj_len;
+
+ union { /* int to float conversion buffer */
+ float f;
+ uint32_t i;
+ } bw;
+
+ while (total_subobj_len > 0 && hexdump == FALSE ) {
+ subobj_type = EXTRACT_8BITS(obj_tptr+offset);
+ subobj_len = EXTRACT_8BITS(obj_tptr+offset+1);
+ ND_PRINT((ndo, "\n\t Subobject, Type: %s (%u), Length: %u",
+ tok2str(lmp_data_link_subobj,
+ "Unknown",
+ subobj_type),
+ subobj_type,
+ subobj_len));
+ if (subobj_len < 4) {
+ ND_PRINT((ndo, " (too short)"));
+ break;
+ }
+ if ((subobj_len % 4) != 0) {
+ ND_PRINT((ndo, " (not a multiple of 4)"));
+ break;
+ }
+ if (total_subobj_len < subobj_len) {
+ ND_PRINT((ndo, " (goes past the end of the object)"));
+ break;
+ }
+ switch(subobj_type) {
+ case INT_SWITCHING_TYPE_SUBOBJ:
+ ND_PRINT((ndo, "\n\t Switching Type: %s (%u)",
+ tok2str(gmpls_switch_cap_values,
+ "Unknown",
+ EXTRACT_8BITS(obj_tptr+offset+2)),
+ EXTRACT_8BITS(obj_tptr+offset+2)));
+ ND_PRINT((ndo, "\n\t Encoding Type: %s (%u)",
+ tok2str(gmpls_encoding_values,
+ "Unknown",
+ EXTRACT_8BITS(obj_tptr+offset+3)),
+ EXTRACT_8BITS(obj_tptr+offset+3)));
+ bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
+ ND_PRINT((ndo, "\n\t Min Reservable Bandwidth: %.3f Mbps",
+ bw.f*8/1000000));
+ bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
+ ND_PRINT((ndo, "\n\t Max Reservable Bandwidth: %.3f Mbps",
+ bw.f*8/1000000));
+ break;
+ case WAVELENGTH_SUBOBJ:
+ ND_PRINT((ndo, "\n\t Wavelength: %u",
+ EXTRACT_32BITS(obj_tptr+offset+4)));
+ break;
+ default:
+ /* Any Unknown Subobject ==> Exit loop */
+ hexdump=TRUE;
+ break;
+ }
+ total_subobj_len-=subobj_len;
+ offset+=subobj_len;
+ }
+ return (hexdump);
+}
+
void
lmp_print(netdissect_options *ndo,
register const u_char *pptr, register u_int len)
@@ -366,10 +434,10 @@ lmp_print(netdissect_options *ndo,
const struct lmp_common_header *lmp_com_header;
const struct lmp_object_header *lmp_obj_header;
const u_char *tptr,*obj_tptr;
- int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
+ u_int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
int hexdump;
- int offset,subobj_type,subobj_len,total_subobj_len;
- int link_type;
+ u_int offset;
+ u_int link_type;
union { /* int to float conversion buffer */
float f;
@@ -407,6 +475,14 @@ lmp_print(netdissect_options *ndo,
tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type),
bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags),
tlen));
+ if (tlen < sizeof(const struct lmp_common_header)) {
+ ND_PRINT((ndo, " (too short)"));
+ return;
+ }
+ if (tlen > len) {
+ ND_PRINT((ndo, " (too long)"));
+ tlen = len;
+ }
tptr+=sizeof(const struct lmp_common_header);
tlen-=sizeof(const struct lmp_common_header);
@@ -419,9 +495,6 @@ lmp_print(netdissect_options *ndo,
lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length);
lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f;
- if(lmp_obj_len % 4 || lmp_obj_len < 4)
- return;
-
ND_PRINT((ndo, "\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u",
tok2str(lmp_obj_values,
"Unknown",
@@ -434,6 +507,15 @@ lmp_print(netdissect_options *ndo,
(lmp_obj_header->ctype)&0x80 ? "" : "non-",
lmp_obj_len));
+ if (lmp_obj_len < 4) {
+ ND_PRINT((ndo, " (too short)"));
+ return;
+ }
+ if ((lmp_obj_len % 4) != 0) {
+ ND_PRINT((ndo, " (not a multiple of 4)"));
+ return;
+ }
+
obj_tptr=tptr+sizeof(struct lmp_object_header);
obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header);
@@ -447,6 +529,10 @@ lmp_print(netdissect_options *ndo,
switch(lmp_obj_ctype) {
case LMP_CTYPE_LOC:
case LMP_CTYPE_RMT:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Control Channel ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr)));
@@ -462,18 +548,30 @@ lmp_print(netdissect_options *ndo,
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4_LOC:
case LMP_CTYPE_IPV4_RMT:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t IPv4 Link ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr),
EXTRACT_32BITS(obj_tptr)));
break;
case LMP_CTYPE_IPV6_LOC:
case LMP_CTYPE_IPV6_RMT:
+ if (obj_tlen != 16) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t IPv6 Link ID: %s (0x%08x)",
ip6addr_string(ndo, obj_tptr),
EXTRACT_32BITS(obj_tptr)));
break;
case LMP_CTYPE_UNMD_LOC:
case LMP_CTYPE_UNMD_RMT:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Link ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr)));
@@ -486,11 +584,19 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_MESSAGE_ID:
switch(lmp_obj_ctype) {
case LMP_CTYPE_1:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Message ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr)));
break;
case LMP_CTYPE_2:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Message ID Ack: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr)));
@@ -504,6 +610,10 @@ lmp_print(netdissect_options *ndo,
switch(lmp_obj_ctype) {
case LMP_CTYPE_LOC:
case LMP_CTYPE_RMT:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Node ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr),
EXTRACT_32BITS(obj_tptr)));
@@ -517,6 +627,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_CONFIG:
switch(lmp_obj_ctype) {
case LMP_CTYPE_HELLO_CONFIG:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Hello Interval: %u\n\t Hello Dead Interval: %u",
EXTRACT_16BITS(obj_tptr),
EXTRACT_16BITS(obj_tptr+2)));
@@ -530,6 +644,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_HELLO:
switch(lmp_obj_ctype) {
case LMP_CTYPE_HELLO:
+ if (obj_tlen != 8) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Tx Seq: %u, Rx Seq: %u",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr+4)));
@@ -541,13 +659,17 @@ lmp_print(netdissect_options *ndo,
break;
case LMP_OBJ_TE_LINK:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_IPV4:
+ if (obj_tlen != 12) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Flags: [%s]",
- bittok2str(lmp_obj_te_link_flag_values,
+ bittok2str(lmp_obj_te_link_flag_values,
"none",
- EXTRACT_16BITS(obj_tptr)>>8)));
+ EXTRACT_8BITS(obj_tptr))));
- switch(lmp_obj_ctype) {
- case LMP_CTYPE_IPV4:
ND_PRINT((ndo, "\n\t Local Link-ID: %s (0x%08x)"
"\n\t Remote Link-ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr+4),
@@ -557,21 +679,57 @@ lmp_print(netdissect_options *ndo,
break;
case LMP_CTYPE_IPV6:
+ if (obj_tlen != 36) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
+ ND_PRINT((ndo, "\n\t Flags: [%s]",
+ bittok2str(lmp_obj_te_link_flag_values,
+ "none",
+ EXTRACT_8BITS(obj_tptr))));
+
+ ND_PRINT((ndo, "\n\t Local Link-ID: %s (0x%08x)"
+ "\n\t Remote Link-ID: %s (0x%08x)",
+ ip6addr_string(ndo, obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+4),
+ ip6addr_string(ndo, obj_tptr+20),
+ EXTRACT_32BITS(obj_tptr+20)));
+ break;
+
case LMP_CTYPE_UNMD:
+ if (obj_tlen != 12) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
+ ND_PRINT((ndo, "\n\t Flags: [%s]",
+ bittok2str(lmp_obj_te_link_flag_values,
+ "none",
+ EXTRACT_8BITS(obj_tptr))));
+
+ ND_PRINT((ndo, "\n\t Local Link-ID: %u (0x%08x)"
+ "\n\t Remote Link-ID: %u (0x%08x)",
+ EXTRACT_32BITS(obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+8),
+ EXTRACT_32BITS(obj_tptr+8)));
+ break;
+
default:
hexdump=TRUE;
}
break;
case LMP_OBJ_DATA_LINK:
- ND_PRINT((ndo, "\n\t Flags: [%s]",
- bittok2str(lmp_obj_data_link_flag_values,
- "none",
- EXTRACT_16BITS(obj_tptr)>>8)));
-
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4:
- case LMP_CTYPE_UNMD:
+ if (obj_tlen < 12) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
+ ND_PRINT((ndo, "\n\t Flags: [%s]",
+ bittok2str(lmp_obj_data_link_flag_values,
+ "none",
+ EXTRACT_8BITS(obj_tptr))));
ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)"
"\n\t Remote Interface ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr+4),
@@ -579,51 +737,50 @@ lmp_print(netdissect_options *ndo,
ipaddr_string(ndo, obj_tptr+8),
EXTRACT_32BITS(obj_tptr+8)));
- total_subobj_len = lmp_obj_len - 16;
- offset = 12;
- while (total_subobj_len > 0 && hexdump == FALSE ) {
- subobj_type = EXTRACT_16BITS(obj_tptr+offset)>>8;
- subobj_len = EXTRACT_16BITS(obj_tptr+offset)&0x00FF;
- ND_PRINT((ndo, "\n\t Subobject, Type: %s (%u), Length: %u",
- tok2str(lmp_data_link_subobj,
- "Unknown",
- subobj_type),
- subobj_type,
- subobj_len));
- switch(subobj_type) {
- case INT_SWITCHING_TYPE_SUBOBJ:
- ND_PRINT((ndo, "\n\t Switching Type: %s (%u)",
- tok2str(gmpls_switch_cap_values,
- "Unknown",
- EXTRACT_16BITS(obj_tptr+offset+2)>>8),
- EXTRACT_16BITS(obj_tptr+offset+2)>>8));
- ND_PRINT((ndo, "\n\t Encoding Type: %s (%u)",
- tok2str(gmpls_encoding_values,
- "Unknown",
- EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF),
- EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF));
- bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
- ND_PRINT((ndo, "\n\t Min Reservable Bandwidth: %.3f Mbps",
- bw.f*8/1000000));
- bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
- ND_PRINT((ndo, "\n\t Max Reservable Bandwidth: %.3f Mbps",
- bw.f*8/1000000));
- break;
- case WAVELENGTH_SUBOBJ:
- ND_PRINT((ndo, "\n\t Wavelength: %u",
- EXTRACT_32BITS(obj_tptr+offset+4)));
- break;
- default:
- /* Any Unknown Subobject ==> Exit loop */
- hexdump=TRUE;
- break;
- }
- total_subobj_len-=subobj_len;
- offset+=subobj_len;
- }
-
+ if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
+ hexdump=TRUE;
break;
+
case LMP_CTYPE_IPV6:
+ if (obj_tlen < 36) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
+ ND_PRINT((ndo, "\n\t Flags: [%s]",
+ bittok2str(lmp_obj_data_link_flag_values,
+ "none",
+ EXTRACT_8BITS(obj_tptr))));
+ ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)"
+ "\n\t Remote Interface ID: %s (0x%08x)",
+ ip6addr_string(ndo, obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+4),
+ ip6addr_string(ndo, obj_tptr+20),
+ EXTRACT_32BITS(obj_tptr+20)));
+
+ if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36))
+ hexdump=TRUE;
+ break;
+
+ case LMP_CTYPE_UNMD:
+ if (obj_tlen < 12) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
+ ND_PRINT((ndo, "\n\t Flags: [%s]",
+ bittok2str(lmp_obj_data_link_flag_values,
+ "none",
+ EXTRACT_8BITS(obj_tptr))));
+ ND_PRINT((ndo, "\n\t Local Interface ID: %u (0x%08x)"
+ "\n\t Remote Interface ID: %u (0x%08x)",
+ EXTRACT_32BITS(obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+8),
+ EXTRACT_32BITS(obj_tptr+8)));
+
+ if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
+ hexdump=TRUE;
+ break;
+
default:
hexdump=TRUE;
}
@@ -632,6 +789,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_VERIFY_BEGIN:
switch(lmp_obj_ctype) {
case LMP_CTYPE_1:
+ if (obj_tlen != 20) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Flags: %s",
bittok2str(lmp_obj_begin_verify_flag_values,
"none",
@@ -660,6 +821,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_VERIFY_BEGIN_ACK:
switch(lmp_obj_ctype) {
case LMP_CTYPE_1:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Verify Dead Interval: %u"
"\n\t Verify Transport Response: %u",
EXTRACT_16BITS(obj_tptr),
@@ -674,6 +839,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_VERIFY_ID:
switch(lmp_obj_ctype) {
case LMP_CTYPE_1:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Verify ID: %u",
EXTRACT_32BITS(obj_tptr)));
break;
@@ -686,19 +855,20 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_CHANNEL_STATUS:
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4:
- case LMP_CTYPE_UNMD:
offset = 0;
/* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
- while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
+ while (offset+8 <= obj_tlen) {
ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr+offset),
EXTRACT_32BITS(obj_tptr+offset)));
- ND_PRINT((ndo, "\n\t\t Active: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
+ ND_PRINT((ndo, "\n\t\t Active: %s (%u)",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
"Allocated" : "Non-allocated",
(EXTRACT_32BITS(obj_tptr+offset+4)>>31)));
- ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
+ ND_PRINT((ndo, "\n\t\t Direction: %s (%u)",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
"Transmit" : "Receive",
(EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1));
@@ -710,7 +880,61 @@ lmp_print(netdissect_options *ndo,
offset+=8;
}
break;
+
case LMP_CTYPE_IPV6:
+ offset = 0;
+ /* Decode pairs: <Interface_ID (16 bytes), Channel_status (4 bytes)> */
+ while (offset+20 <= obj_tlen) {
+ ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)",
+ ip6addr_string(ndo, obj_tptr+offset),
+ EXTRACT_32BITS(obj_tptr+offset)));
+
+ ND_PRINT((ndo, "\n\t\t Active: %s (%u)",
+ (EXTRACT_32BITS(obj_tptr+offset+16)>>31) ?
+ "Allocated" : "Non-allocated",
+ (EXTRACT_32BITS(obj_tptr+offset+16)>>31)));
+
+ ND_PRINT((ndo, "\n\t\t Direction: %s (%u)",
+ (EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1 ?
+ "Transmit" : "Receive",
+ (EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1));
+
+ ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)",
+ tok2str(lmp_obj_channel_status_values,
+ "Unknown",
+ EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF),
+ EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF));
+ offset+=20;
+ }
+ break;
+
+ case LMP_CTYPE_UNMD:
+ offset = 0;
+ /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
+ while (offset+8 <= obj_tlen) {
+ ND_PRINT((ndo, "\n\t Interface ID: %u (0x%08x)",
+ EXTRACT_32BITS(obj_tptr+offset),
+ EXTRACT_32BITS(obj_tptr+offset)));
+
+ ND_PRINT((ndo, "\n\t\t Active: %s (%u)",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
+ "Allocated" : "Non-allocated",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>31)));
+
+ ND_PRINT((ndo, "\n\t\t Direction: %s (%u)",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
+ "Transmit" : "Receive",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1));
+
+ ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)",
+ tok2str(lmp_obj_channel_status_values,
+ "Unknown",
+ EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF),
+ EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF));
+ offset+=8;
+ }
+ break;
+
default:
hexdump=TRUE;
}
@@ -719,16 +943,35 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_CHANNEL_STATUS_REQ:
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4:
- case LMP_CTYPE_UNMD:
offset = 0;
- while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
+ while (offset+4 <= obj_tlen) {
ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr+offset),
EXTRACT_32BITS(obj_tptr+offset)));
offset+=4;
}
break;
+
case LMP_CTYPE_IPV6:
+ offset = 0;
+ while (offset+16 <= obj_tlen) {
+ ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)",
+ ip6addr_string(ndo, obj_tptr+offset),
+ EXTRACT_32BITS(obj_tptr+offset)));
+ offset+=16;
+ }
+ break;
+
+ case LMP_CTYPE_UNMD:
+ offset = 0;
+ while (offset+4 <= obj_tlen) {
+ ND_PRINT((ndo, "\n\t Interface ID: %u (0x%08x)",
+ EXTRACT_32BITS(obj_tptr+offset),
+ EXTRACT_32BITS(obj_tptr+offset)));
+ offset+=4;
+ }
+ break;
+
default:
hexdump=TRUE;
}
@@ -737,6 +980,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_ERROR_CODE:
switch(lmp_obj_ctype) {
case LMP_CTYPE_BEGIN_VERIFY_ERROR:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Error Code: %s",
bittok2str(lmp_obj_begin_verify_error_values,
"none",
@@ -744,6 +991,10 @@ lmp_print(netdissect_options *ndo,
break;
case LMP_CTYPE_LINK_SUMMARY_ERROR:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Error Code: %s",
bittok2str(lmp_obj_link_summary_error_values,
"none",
@@ -757,51 +1008,60 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_SERVICE_CONFIG:
switch (lmp_obj_ctype) {
case LMP_CTYPE_SERVICE_CONFIG_SP:
-
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Flags: %s",
bittok2str(lmp_obj_service_config_sp_flag_values,
"none",
- EXTRACT_16BITS(obj_tptr)>>8)));
+ EXTRACT_8BITS(obj_tptr))));
ND_PRINT((ndo, "\n\t UNI Version: %u",
- EXTRACT_16BITS(obj_tptr) & 0x00FF));
+ EXTRACT_8BITS(obj_tptr+1)));
break;
case LMP_CTYPE_SERVICE_CONFIG_CPSA:
+ if (obj_tlen != 16) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
- link_type = EXTRACT_16BITS(obj_tptr)>>8;
+ link_type = EXTRACT_8BITS(obj_tptr);
ND_PRINT((ndo, "\n\t Link Type: %s (%u)",
tok2str(lmp_sd_service_config_cpsa_link_type_values,
"Unknown", link_type),
link_type));
- if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH) {
+ switch (link_type) {
+ case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH:
ND_PRINT((ndo, "\n\t Signal Type: %s (%u)",
tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values,
"Unknown",
- EXTRACT_16BITS(obj_tptr) & 0x00FF),
- EXTRACT_16BITS(obj_tptr) & 0x00FF));
- }
+ EXTRACT_8BITS(obj_tptr+1)),
+ EXTRACT_8BITS(obj_tptr+1)));
+ break;
- if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET) {
+ case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET:
ND_PRINT((ndo, "\n\t Signal Type: %s (%u)",
tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values,
"Unknown",
- EXTRACT_16BITS(obj_tptr) & 0x00FF),
- EXTRACT_16BITS(obj_tptr) & 0x00FF));
+ EXTRACT_8BITS(obj_tptr+1)),
+ EXTRACT_8BITS(obj_tptr+1)));
+ break;
}
ND_PRINT((ndo, "\n\t Transparency: %s",
bittok2str(lmp_obj_service_config_cpsa_tp_flag_values,
"none",
- EXTRACT_16BITS(obj_tptr+2)>>8)));
+ EXTRACT_8BITS(obj_tptr+2))));
ND_PRINT((ndo, "\n\t Contiguous Concatenation Types: %s",
bittok2str(lmp_obj_service_config_cpsa_cct_flag_values,
"none",
- EXTRACT_16BITS(obj_tptr+2)>>8 & 0x00FF)));
+ EXTRACT_8BITS(obj_tptr+3))));
ND_PRINT((ndo, "\n\t Minimum NCC: %u",
EXTRACT_16BITS(obj_tptr+4)));
@@ -822,6 +1082,10 @@ lmp_print(netdissect_options *ndo,
break;
case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM:
+ if (obj_tlen != 8) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Transparency Flags: %s",
bittok2str(
@@ -833,17 +1097,21 @@ lmp_print(netdissect_options *ndo,
bittok2str(
lmp_obj_service_config_nsa_tcm_flag_values,
"none",
- EXTRACT_16BITS(obj_tptr+6) & 0x00FF)));
+ EXTRACT_8BITS(obj_tptr+7))));
break;
case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Diversity: Flags: %s",
bittok2str(
lmp_obj_service_config_nsa_network_diversity_flag_values,
"none",
- EXTRACT_16BITS(obj_tptr+2) & 0x00FF)));
+ EXTRACT_8BITS(obj_tptr+3))));
break;
default:
diff --git a/freebsd/contrib/tcpdump/print-lspping.c b/freebsd/contrib/tcpdump/print-lspping.c
index eb1cc77d..2972df2a 100644
--- a/freebsd/contrib/tcpdump/print-lspping.c
+++ b/freebsd/contrib/tcpdump/print-lspping.c
@@ -16,7 +16,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: MPLS LSP PING printer */
@@ -110,6 +110,7 @@ static const struct tok lspping_return_code_values[] = {
{ 11, "No label entry at stack-depth"},
{ 12, "Protocol not associated with interface at FEC stack depth"},
{ 13, "Premature termination of ping due to label stack shrinking to a single label"},
+ { 0, NULL},
};
diff --git a/freebsd/contrib/tcpdump/print-m3ua.c b/freebsd/contrib/tcpdump/print-m3ua.c
index e7d7b300..9e363779 100644
--- a/freebsd/contrib/tcpdump/print-m3ua.c
+++ b/freebsd/contrib/tcpdump/print-m3ua.c
@@ -73,7 +73,7 @@ static const struct tok MessageClasses[] = {
{ M3UA_MSGC_SSNM, "SS7" },
{ M3UA_MSGC_ASPSM, "ASP" },
{ M3UA_MSGC_ASPTM, "ASP" },
- { M3UA_MSGC_RKM, "Routing Key Managment" },
+ { M3UA_MSGC_RKM, "Routing Key Management"},
{ 0, NULL }
};
diff --git a/freebsd/contrib/tcpdump/print-mobility.c b/freebsd/contrib/tcpdump/print-mobility.c
index e43dc3f0..57435041 100644
--- a/freebsd/contrib/tcpdump/print-mobility.c
+++ b/freebsd/contrib/tcpdump/print-mobility.c
@@ -34,6 +34,7 @@
*/
/* \summary: IPv6 mobility printer */
+/* RFC 3775 */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -41,11 +42,12 @@
#include <netdissect-stdinc.h>
-#include "ip6.h"
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
+#include "ip6.h"
+
static const char tstr[] = "[|MOBILITY]";
/* Mobility header */
@@ -154,6 +156,7 @@ mobility_opt_print(netdissect_options *ndo,
goto trunc;
}
/* units of 4 secs */
+ ND_TCHECK_16BITS(&bp[i+2]);
ND_PRINT((ndo, "(refresh: %u)",
EXTRACT_16BITS(&bp[i+2]) << 2));
break;
@@ -162,6 +165,7 @@ mobility_opt_print(netdissect_options *ndo,
ND_PRINT((ndo, "(altcoa: trunc)"));
goto trunc;
}
+ ND_TCHECK_128BITS(&bp[i+2]);
ND_PRINT((ndo, "(alt-CoA: %s)", ip6addr_string(ndo, &bp[i+2])));
break;
case IP6MOPT_NONCEID:
@@ -169,6 +173,8 @@ mobility_opt_print(netdissect_options *ndo,
ND_PRINT((ndo, "(ni: trunc)"));
goto trunc;
}
+ ND_TCHECK_16BITS(&bp[i+2]);
+ ND_TCHECK_16BITS(&bp[i+4]);
ND_PRINT((ndo, "(ni: ho=0x%04x co=0x%04x)",
EXTRACT_16BITS(&bp[i+2]),
EXTRACT_16BITS(&bp[i+4])));
@@ -247,7 +253,7 @@ mobility_print(netdissect_options *ndo,
case IP6M_CAREOF_TEST_INIT:
hlen = IP6M_MINLEN;
if (ndo->ndo_vflag) {
- ND_TCHECK2(*mh, hlen + 8);
+ ND_TCHECK_32BITS(&bp[hlen + 4]);
ND_PRINT((ndo, " %s Init Cookie=%08x:%08x",
type == IP6M_HOME_TEST_INIT ? "Home" : "Care-of",
EXTRACT_32BITS(&bp[hlen]),
@@ -261,7 +267,7 @@ mobility_print(netdissect_options *ndo,
ND_PRINT((ndo, " nonce id=0x%x", EXTRACT_16BITS(&mh->ip6m_data16[0])));
hlen = IP6M_MINLEN;
if (ndo->ndo_vflag) {
- ND_TCHECK2(*mh, hlen + 8);
+ ND_TCHECK_32BITS(&bp[hlen + 4]);
ND_PRINT((ndo, " %s Init Cookie=%08x:%08x",
type == IP6M_HOME_TEST ? "Home" : "Care-of",
EXTRACT_32BITS(&bp[hlen]),
@@ -269,7 +275,7 @@ mobility_print(netdissect_options *ndo,
}
hlen += 8;
if (ndo->ndo_vflag) {
- ND_TCHECK2(*mh, hlen + 8);
+ ND_TCHECK_32BITS(&bp[hlen + 4]);
ND_PRINT((ndo, " %s Keygen Token=%08x:%08x",
type == IP6M_HOME_TEST ? "Home" : "Care-of",
EXTRACT_32BITS(&bp[hlen]),
@@ -281,22 +287,23 @@ mobility_print(netdissect_options *ndo,
ND_TCHECK(mh->ip6m_data16[0]);
ND_PRINT((ndo, " seq#=%u", EXTRACT_16BITS(&mh->ip6m_data16[0])));
hlen = IP6M_MINLEN;
- ND_TCHECK2(*mh, hlen + 1);
- if (bp[hlen] & 0xf0)
+ ND_TCHECK_16BITS(&bp[hlen]);
+ if (bp[hlen] & 0xf0) {
ND_PRINT((ndo, " "));
- if (bp[hlen] & 0x80)
- ND_PRINT((ndo, "A"));
- if (bp[hlen] & 0x40)
- ND_PRINT((ndo, "H"));
- if (bp[hlen] & 0x20)
- ND_PRINT((ndo, "L"));
- if (bp[hlen] & 0x10)
- ND_PRINT((ndo, "K"));
+ if (bp[hlen] & 0x80)
+ ND_PRINT((ndo, "A"));
+ if (bp[hlen] & 0x40)
+ ND_PRINT((ndo, "H"));
+ if (bp[hlen] & 0x20)
+ ND_PRINT((ndo, "L"));
+ if (bp[hlen] & 0x10)
+ ND_PRINT((ndo, "K"));
+ }
/* Reserved (4bits) */
hlen += 1;
/* Reserved (8bits) */
hlen += 1;
- ND_TCHECK2(*mh, hlen + 2);
+ ND_TCHECK_16BITS(&bp[hlen]);
/* units of 4 secs */
ND_PRINT((ndo, " lifetime=%u", EXTRACT_16BITS(&bp[hlen]) << 2));
hlen += 2;
@@ -304,14 +311,15 @@ mobility_print(netdissect_options *ndo,
case IP6M_BINDING_ACK:
ND_TCHECK(mh->ip6m_data8[0]);
ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0]));
+ ND_TCHECK(mh->ip6m_data8[1]);
if (mh->ip6m_data8[1] & 0x80)
ND_PRINT((ndo, " K"));
/* Reserved (7bits) */
hlen = IP6M_MINLEN;
- ND_TCHECK2(*mh, hlen + 2);
+ ND_TCHECK_16BITS(&bp[hlen]);
ND_PRINT((ndo, " seq#=%u", EXTRACT_16BITS(&bp[hlen])));
hlen += 2;
- ND_TCHECK2(*mh, hlen + 2);
+ ND_TCHECK_16BITS(&bp[hlen]);
/* units of 4 secs */
ND_PRINT((ndo, " lifetime=%u", EXTRACT_16BITS(&bp[hlen]) << 2));
hlen += 2;
@@ -321,7 +329,7 @@ mobility_print(netdissect_options *ndo,
ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0]));
/* Reserved */
hlen = IP6M_MINLEN;
- ND_TCHECK2(*mh, hlen + 16);
+ ND_TCHECK2(bp[hlen], 16);
ND_PRINT((ndo, " homeaddr %s", ip6addr_string(ndo, &bp[hlen])));
hlen += 16;
break;
@@ -338,7 +346,7 @@ mobility_print(netdissect_options *ndo,
trunc:
ND_PRINT((ndo, "%s", tstr));
- return(mhlen);
+ return(-1);
}
#ifdef __rtems__
#include "rtems-bsd-tcpdump-print-mobility-data.h"
diff --git a/freebsd/contrib/tcpdump/print-mpcp.c b/freebsd/contrib/tcpdump/print-mpcp.c
index 55d1fc63..45b36767 100644
--- a/freebsd/contrib/tcpdump/print-mpcp.c
+++ b/freebsd/contrib/tcpdump/print-mpcp.c
@@ -18,7 +18,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: IEEE 802.3ah Multi-Point Control Protocol (MPCP) printer */
diff --git a/freebsd/contrib/tcpdump/print-mpls.c b/freebsd/contrib/tcpdump/print-mpls.c
index a3dadfff..f20f7599 100644
--- a/freebsd/contrib/tcpdump/print-mpls.c
+++ b/freebsd/contrib/tcpdump/print-mpls.c
@@ -207,7 +207,7 @@ mpls_print(netdissect_options *ndo, const u_char *bp, u_int length)
break;
case PT_OSI:
- isoclns_print(ndo, p, length, length);
+ isoclns_print(ndo, p, length);
break;
default:
diff --git a/freebsd/contrib/tcpdump/print-mptcp.c b/freebsd/contrib/tcpdump/print-mptcp.c
index 54669708..4dcf8129 100644
--- a/freebsd/contrib/tcpdump/print-mptcp.c
+++ b/freebsd/contrib/tcpdump/print-mptcp.c
@@ -184,7 +184,7 @@ mp_capable_print(netdissect_options *ndo,
{
const struct mp_capable *mpc = (const struct mp_capable *) opt;
- if (!(opt_len == 12 && flags & TH_SYN) &&
+ if (!(opt_len == 12 && (flags & TH_SYN)) &&
!(opt_len == 20 && (flags & (TH_SYN | TH_ACK)) == TH_ACK))
return 0;
@@ -208,9 +208,9 @@ mp_join_print(netdissect_options *ndo,
{
const struct mp_join *mpj = (const struct mp_join *) opt;
- if (!(opt_len == 12 && flags & TH_SYN) &&
+ if (!(opt_len == 12 && (flags & TH_SYN)) &&
!(opt_len == 16 && (flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) &&
- !(opt_len == 24 && flags & TH_ACK))
+ !(opt_len == 24 && (flags & TH_ACK)))
return 0;
if (opt_len != 24) {
@@ -242,76 +242,92 @@ mp_join_print(netdissect_options *ndo,
return 1;
}
-static u_int mp_dss_len(const struct mp_dss *m, int csum)
-{
- u_int len;
-
- len = 4;
- if (m->flags & MP_DSS_A) {
- /* Ack present - 4 or 8 octets */
- len += (m->flags & MP_DSS_a) ? 8 : 4;
- }
- if (m->flags & MP_DSS_M) {
- /*
- * Data Sequence Number (DSN), Subflow Sequence Number (SSN),
- * Data-Level Length present, and Checksum possibly present.
- * All but the Checksum are 10 bytes if the m flag is
- * clear (4-byte DSN) and 14 bytes if the m flag is set
- * (8-byte DSN).
- */
- len += (m->flags & MP_DSS_m) ? 14 : 10;
-
- /*
- * The Checksum is present only if negotiated.
- */
- if (csum)
- len += 2;
- }
- return len;
-}
-
static int
mp_dss_print(netdissect_options *ndo,
const u_char *opt, u_int opt_len, u_char flags)
{
const struct mp_dss *mdss = (const struct mp_dss *) opt;
- if ((opt_len != mp_dss_len(mdss, 1) &&
- opt_len != mp_dss_len(mdss, 0)) || flags & TH_SYN)
+ /* We need the flags, at a minimum. */
+ if (opt_len < 4)
+ return 0;
+
+ if (flags & TH_SYN)
return 0;
if (mdss->flags & MP_DSS_F)
ND_PRINT((ndo, " fin"));
opt += 4;
+ opt_len -= 4;
if (mdss->flags & MP_DSS_A) {
+ /* Ack present */
ND_PRINT((ndo, " ack "));
+ /*
+ * If the a flag is set, we have an 8-byte ack; if it's
+ * clear, we have a 4-byte ack.
+ */
if (mdss->flags & MP_DSS_a) {
+ if (opt_len < 8)
+ return 0;
ND_PRINT((ndo, "%" PRIu64, EXTRACT_64BITS(opt)));
opt += 8;
+ opt_len -= 8;
} else {
+ if (opt_len < 4)
+ return 0;
ND_PRINT((ndo, "%u", EXTRACT_32BITS(opt)));
opt += 4;
+ opt_len -= 4;
}
}
if (mdss->flags & MP_DSS_M) {
+ /*
+ * Data Sequence Number (DSN), Subflow Sequence Number (SSN),
+ * Data-Level Length present, and Checksum possibly present.
+ */
ND_PRINT((ndo, " seq "));
+ /*
+ * If the m flag is set, we have an 8-byte NDS; if it's clear,
+ * we have a 4-byte DSN.
+ */
if (mdss->flags & MP_DSS_m) {
+ if (opt_len < 8)
+ return 0;
ND_PRINT((ndo, "%" PRIu64, EXTRACT_64BITS(opt)));
opt += 8;
+ opt_len -= 8;
} else {
+ if (opt_len < 4)
+ return 0;
ND_PRINT((ndo, "%u", EXTRACT_32BITS(opt)));
opt += 4;
+ opt_len -= 4;
}
+ if (opt_len < 4)
+ return 0;
ND_PRINT((ndo, " subseq %u", EXTRACT_32BITS(opt)));
opt += 4;
+ opt_len -= 4;
+ if (opt_len < 2)
+ return 0;
ND_PRINT((ndo, " len %u", EXTRACT_16BITS(opt)));
opt += 2;
+ opt_len -= 2;
- if (opt_len == mp_dss_len(mdss, 1))
+ /*
+ * The Checksum is present only if negotiated.
+ * If there are at least 2 bytes left, process the next 2
+ * bytes as the Checksum.
+ */
+ if (opt_len >= 2) {
ND_PRINT((ndo, " csum 0x%x", EXTRACT_16BITS(opt)));
+ opt_len -= 2;
+ }
}
+ if (opt_len != 0)
+ return 0;
return 1;
}
diff --git a/freebsd/contrib/tcpdump/print-nfs.c b/freebsd/contrib/tcpdump/print-nfs.c
index 10de4358..97748dce 100644
--- a/freebsd/contrib/tcpdump/print-nfs.c
+++ b/freebsd/contrib/tcpdump/print-nfs.c
@@ -634,17 +634,15 @@ nfsreq_print_noaddr(netdissect_options *ndo,
if ((dp = parsereq(ndo, rp, length)) != NULL &&
(dp = parsefh(ndo, dp, v3)) != NULL) {
if (v3) {
- ND_TCHECK(dp[2]);
+ ND_TCHECK(dp[4]);
ND_PRINT((ndo, " %u (%u) bytes @ %" PRIu64,
EXTRACT_32BITS(&dp[4]),
EXTRACT_32BITS(&dp[2]),
EXTRACT_64BITS(&dp[0])));
if (ndo->ndo_vflag) {
- dp += 3;
- ND_TCHECK(dp[0]);
ND_PRINT((ndo, " <%s>",
tok2str(nfsv3_writemodes,
- NULL, EXTRACT_32BITS(dp))));
+ NULL, EXTRACT_32BITS(&dp[3]))));
}
} else {
ND_TCHECK(dp[3]);
@@ -815,11 +813,15 @@ nfs_printfh(netdissect_options *ndo,
if (sfsname) {
/* file system ID is ASCII, not numeric, for this server OS */
- static char temp[NFSX_V3FHMAX+1];
+ char temp[NFSX_V3FHMAX+1];
+ u_int stringlen;
/* Make sure string is null-terminated */
- strncpy(temp, sfsname, NFSX_V3FHMAX);
- temp[sizeof(temp) - 1] = '\0';
+ stringlen = len;
+ if (stringlen > NFSX_V3FHMAX)
+ stringlen = NFSX_V3FHMAX;
+ strncpy(temp, sfsname, stringlen);
+ temp[stringlen] = '\0';
/* Remove trailing spaces */
spacep = strchr(temp, ' ');
if (spacep)
@@ -874,7 +876,7 @@ xid_map_enter(netdissect_options *ndo,
const struct ip6_hdr *ip6 = NULL;
struct xid_map_entry *xmep;
- if (!ND_TTEST(rp->rm_call.cb_vers))
+ if (!ND_TTEST(rp->rm_call.cb_proc))
return (0);
switch (IP_V((const struct ip *)bp)) {
case 4:
@@ -1008,11 +1010,11 @@ parserep(netdissect_options *ndo,
* skip past the ar_verf credentials.
*/
dp += (len + (2*sizeof(uint32_t) + 3)) / sizeof(uint32_t);
- ND_TCHECK2(dp[0], 0);
/*
* now we can check the ar_stat field
*/
+ ND_TCHECK(dp[0]);
astat = (enum sunrpc_accept_stat) EXTRACT_32BITS(dp);
if (astat != SUNRPC_SUCCESS) {
ND_PRINT((ndo, " %s", tok2str(sunrpc_str, "ar_stat %d", astat)));
@@ -1249,6 +1251,7 @@ static const uint32_t *
parse_wcc_attr(netdissect_options *ndo,
const uint32_t *dp)
{
+ /* Our caller has already checked this */
ND_PRINT((ndo, " sz %" PRIu64, EXTRACT_64BITS(&dp[0])));
ND_PRINT((ndo, " mtime %u.%06u ctime %u.%06u",
EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[3]),
@@ -1517,8 +1520,10 @@ interp_reply(netdissect_options *ndo,
ND_PRINT((ndo, " attr:"));
if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag)))
break;
- if (!er)
+ if (!er) {
+ ND_TCHECK(dp[0]);
ND_PRINT((ndo, " c %04x", EXTRACT_32BITS(&dp[0])));
+ }
return;
case NFSPROC_READLINK:
diff --git a/freebsd/contrib/tcpdump/print-null.c b/freebsd/contrib/tcpdump/print-null.c
index 9287709d..53aa294f 100644
--- a/freebsd/contrib/tcpdump/print-null.c
+++ b/freebsd/contrib/tcpdump/print-null.c
@@ -123,7 +123,7 @@ null_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char
break;
case BSD_AFNUM_ISO:
- isoclns_print(ndo, p, length, caplen);
+ isoclns_print(ndo, p, length);
break;
case BSD_AFNUM_APPLETALK:
diff --git a/freebsd/contrib/tcpdump/print-olsr.c b/freebsd/contrib/tcpdump/print-olsr.c
index de757a8e..ab53a632 100644
--- a/freebsd/contrib/tcpdump/print-olsr.c
+++ b/freebsd/contrib/tcpdump/print-olsr.c
@@ -19,7 +19,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler <hannes@juniper.net>
+ * Original code by Hannes Gredler <hannes@gredler.at>
* IPv6 additions by Florian Forster <octo at verplant.org>
*/
@@ -365,10 +365,9 @@ olsr_print(netdissect_options *ndo,
} msgptr;
int msg_len_valid = 0;
- ND_TCHECK2(*tptr, sizeof(struct olsr_msg4));
-
if (is_ipv6)
{
+ ND_TCHECK2(*tptr, sizeof(struct olsr_msg6));
msgptr.v6 = (const struct olsr_msg6 *) tptr;
msg_type = msgptr.v6->msg_type;
msg_len = EXTRACT_16BITS(msgptr.v6->msg_len);
@@ -399,6 +398,7 @@ olsr_print(netdissect_options *ndo,
}
else /* (!is_ipv6) */
{
+ ND_TCHECK2(*tptr, sizeof(struct olsr_msg4));
msgptr.v4 = (const struct olsr_msg4 *) tptr;
msg_type = msgptr.v4->msg_type;
msg_len = EXTRACT_16BITS(msgptr.v4->msg_len);
@@ -622,22 +622,25 @@ olsr_print(netdissect_options *ndo,
case OLSR_NAMESERVICE_MSG:
{
- u_int name_entries = EXTRACT_16BITS(msg_data+2);
- u_int addr_size = 4;
- int name_entries_valid = 0;
+ u_int name_entries;
+ u_int addr_size;
+ int name_entries_valid;
u_int i;
+ if (msg_tlen < 4)
+ goto trunc;
+ ND_TCHECK2(*msg_data, 4);
+
+ name_entries = EXTRACT_16BITS(msg_data+2);
+ addr_size = 4;
if (is_ipv6)
addr_size = 16;
+ name_entries_valid = 0;
if ((name_entries > 0)
&& ((name_entries * (4 + addr_size)) <= msg_tlen))
name_entries_valid = 1;
- if (msg_tlen < 4)
- goto trunc;
- ND_TCHECK2(*msg_data, 4);
-
ND_PRINT((ndo, "\n\t Version %u, Entries %u%s",
EXTRACT_16BITS(msg_data),
name_entries, (name_entries_valid == 0) ? " (invalid)" : ""));
diff --git a/freebsd/contrib/tcpdump/print-ospf6.c b/freebsd/contrib/tcpdump/print-ospf6.c
index bd3efe9a..333ac774 100644
--- a/freebsd/contrib/tcpdump/print-ospf6.c
+++ b/freebsd/contrib/tcpdump/print-ospf6.c
@@ -654,6 +654,7 @@ ospf6_print_lsa(netdissect_options *ndo,
if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix))
return (1);
lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix);
+ ND_TCHECK(llsap->llsa_nprefix);
prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix);
ND_PRINT((ndo, "\n\t Priority %d, Link-local address %s, Prefixes %d:",
llsap->llsa_priority,
@@ -741,6 +742,7 @@ ospf6_decode_v3(netdissect_options *ndo,
case OSPF_TYPE_HELLO: {
register const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN);
+ ND_TCHECK_32BITS(&hellop->hello_options);
ND_PRINT((ndo, "\n\tOptions [%s]",
bittok2str(ospf6_option_values, "none",
EXTRACT_32BITS(&hellop->hello_options))));
@@ -939,10 +941,12 @@ ospf6_decode_v3_trailer(netdissect_options *ndo,
if (op->ospf6_type == OSPF_TYPE_HELLO) {
const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN);
+ ND_TCHECK(hellop->hello_options);
if (EXTRACT_32BITS(&hellop->hello_options) & OSPF6_OPTION_L)
lls_hello = 1;
} else if (op->ospf6_type == OSPF_TYPE_DD) {
const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN);
+ ND_TCHECK(ddp->db_options);
if (EXTRACT_32BITS(&ddp->db_options) & OSPF6_OPTION_L)
lls_dd = 1;
}
diff --git a/freebsd/contrib/tcpdump/print-pgm.c b/freebsd/contrib/tcpdump/print-pgm.c
index e6c2a18f..b9ace2c0 100644
--- a/freebsd/contrib/tcpdump/print-pgm.c
+++ b/freebsd/contrib/tcpdump/print-pgm.c
@@ -175,13 +175,12 @@ pgm_print(netdissect_options *ndo,
ND_PRINT((ndo, "%s > %s: [|pgm]",
ip6addr_string(ndo, &ip6->ip6_src),
ip6addr_string(ndo, &ip6->ip6_dst)));
- return;
} else {
ND_PRINT((ndo, "%s > %s: [|pgm]",
ipaddr_string(ndo, &ip->ip_src),
ipaddr_string(ndo, &ip->ip_dst)));
- return;
}
+ return;
}
sport = EXTRACT_16BITS(&pgm->pgm_sport);
@@ -368,6 +367,7 @@ pgm_print(netdissect_options *ndo,
* and stopping if we don't have enough.
*/
bp += (2 * sizeof(uint16_t));
+ ND_TCHECK_16BITS(bp);
switch (EXTRACT_16BITS(bp)) {
case AFNUM_INET:
ND_TCHECK2(*bp, sizeof(struct in_addr));
@@ -463,6 +463,10 @@ pgm_print(netdissect_options *ndo,
ND_PRINT((ndo, "[Total option length leaves no room for final option]"));
return;
}
+ if (!ND_TTEST2(*bp, 2)) {
+ ND_PRINT((ndo, " [|OPT]"));
+ return;
+ }
opt_type = *bp++;
opt_len = *bp++;
if (opt_len < PGM_MIN_OPT_LEN) {
@@ -481,112 +485,130 @@ pgm_print(netdissect_options *ndo,
switch (opt_type & PGM_OPT_MASK) {
case PGM_OPT_LENGTH:
- if (opt_len != 4) {
- ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != 4]", opt_len));
+#define PGM_OPT_LENGTH_LEN (2+2)
+ if (opt_len != PGM_OPT_LENGTH_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != %u]",
+ opt_len, PGM_OPT_LENGTH_LEN));
return;
}
ND_PRINT((ndo, " OPTS LEN (extra?) %d", EXTRACT_16BITS(bp)));
- bp += sizeof(uint16_t);
- opts_len -= 4;
+ bp += 2;
+ opts_len -= PGM_OPT_LENGTH_LEN;
break;
case PGM_OPT_FRAGMENT:
- if (opt_len != 16) {
- ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != 16]", opt_len));
+#define PGM_OPT_FRAGMENT_LEN (2+2+4+4+4)
+ if (opt_len != PGM_OPT_FRAGMENT_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != %u]",
+ opt_len, PGM_OPT_FRAGMENT_LEN));
return;
}
bp += 2;
seq = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
offset = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
len = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " FRAG seq %u off %u len %u", seq, offset, len));
- opts_len -= 16;
+ opts_len -= PGM_OPT_FRAGMENT_LEN;
break;
case PGM_OPT_NAK_LIST:
bp += 2;
- opt_len -= sizeof(uint32_t); /* option header */
+ opt_len -= 4; /* option header */
ND_PRINT((ndo, " NAK LIST"));
while (opt_len) {
- if (opt_len < sizeof(uint32_t)) {
+ if (opt_len < 4) {
ND_PRINT((ndo, "[Option length not a multiple of 4]"));
return;
}
- ND_TCHECK2(*bp, sizeof(uint32_t));
+ ND_TCHECK2(*bp, 4);
ND_PRINT((ndo, " %u", EXTRACT_32BITS(bp)));
- bp += sizeof(uint32_t);
- opt_len -= sizeof(uint32_t);
- opts_len -= sizeof(uint32_t);
+ bp += 4;
+ opt_len -= 4;
+ opts_len -= 4;
}
break;
case PGM_OPT_JOIN:
- if (opt_len != 8) {
- ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != 8]", opt_len));
+#define PGM_OPT_JOIN_LEN (2+2+4)
+ if (opt_len != PGM_OPT_JOIN_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != %u]",
+ opt_len, PGM_OPT_JOIN_LEN));
return;
}
bp += 2;
seq = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " JOIN %u", seq));
- opts_len -= 8;
+ opts_len -= PGM_OPT_JOIN_LEN;
break;
case PGM_OPT_NAK_BO_IVL:
- if (opt_len != 12) {
- ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len));
+#define PGM_OPT_NAK_BO_IVL_LEN (2+2+4+4)
+ if (opt_len != PGM_OPT_NAK_BO_IVL_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != %u]",
+ opt_len, PGM_OPT_NAK_BO_IVL_LEN));
return;
}
bp += 2;
offset = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
seq = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " BACKOFF ivl %u ivlseq %u", offset, seq));
- opts_len -= 12;
+ opts_len -= PGM_OPT_NAK_BO_IVL_LEN;
break;
case PGM_OPT_NAK_BO_RNG:
- if (opt_len != 12) {
- ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len));
+#define PGM_OPT_NAK_BO_RNG_LEN (2+2+4+4)
+ if (opt_len != PGM_OPT_NAK_BO_RNG_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != %u]",
+ opt_len, PGM_OPT_NAK_BO_RNG_LEN));
return;
}
bp += 2;
offset = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
seq = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " BACKOFF max %u min %u", offset, seq));
- opts_len -= 12;
+ opts_len -= PGM_OPT_NAK_BO_RNG_LEN;
break;
case PGM_OPT_REDIRECT:
+#define PGM_OPT_REDIRECT_FIXED_LEN (2+2+2+2)
+ if (opt_len < PGM_OPT_REDIRECT_FIXED_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u < %u]",
+ opt_len, PGM_OPT_REDIRECT_FIXED_LEN));
+ return;
+ }
bp += 2;
nla_afnum = EXTRACT_16BITS(bp);
- bp += (2 * sizeof(uint16_t));
+ bp += 2+2;
switch (nla_afnum) {
case AFNUM_INET:
- if (opt_len != 4 + sizeof(struct in_addr)) {
- ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len));
+ if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in_addr)) {
+ ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != %u + address size]",
+ opt_len, PGM_OPT_REDIRECT_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in_addr));
addrtostr(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in_addr);
- opts_len -= 4 + sizeof(struct in_addr);
+ opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in_addr);
break;
case AFNUM_INET6:
- if (opt_len != 4 + sizeof(struct in6_addr)) {
- ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len));
+ if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in6_addr)) {
+ ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != %u + address size]",
+ PGM_OPT_REDIRECT_FIXED_LEN, opt_len));
return;
}
ND_TCHECK2(*bp, sizeof(struct in6_addr));
addrtostr6(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in6_addr);
- opts_len -= 4 + sizeof(struct in6_addr);
+ opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in6_addr);
break;
default:
goto trunc;
@@ -597,49 +619,57 @@ pgm_print(netdissect_options *ndo,
break;
case PGM_OPT_PARITY_PRM:
- if (opt_len != 8) {
- ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len));
+#define PGM_OPT_PARITY_PRM_LEN (2+2+4)
+ if (opt_len != PGM_OPT_PARITY_PRM_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != %u]",
+ opt_len, PGM_OPT_PARITY_PRM_LEN));
return;
}
bp += 2;
len = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " PARITY MAXTGS %u", len));
- opts_len -= 8;
+ opts_len -= PGM_OPT_PARITY_PRM_LEN;
break;
case PGM_OPT_PARITY_GRP:
- if (opt_len != 8) {
- ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len));
+#define PGM_OPT_PARITY_GRP_LEN (2+2+4)
+ if (opt_len != PGM_OPT_PARITY_GRP_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != %u]",
+ opt_len, PGM_OPT_PARITY_GRP_LEN));
return;
}
bp += 2;
seq = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " PARITY GROUP %u", seq));
- opts_len -= 8;
+ opts_len -= PGM_OPT_PARITY_GRP_LEN;
break;
case PGM_OPT_CURR_TGSIZE:
- if (opt_len != 8) {
- ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len));
+#define PGM_OPT_CURR_TGSIZE_LEN (2+2+4)
+ if (opt_len != PGM_OPT_CURR_TGSIZE_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != %u]",
+ opt_len, PGM_OPT_CURR_TGSIZE_LEN));
return;
}
bp += 2;
len = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " PARITY ATGS %u", len));
- opts_len -= 8;
+ opts_len -= PGM_OPT_CURR_TGSIZE_LEN;
break;
case PGM_OPT_NBR_UNREACH:
- if (opt_len != 4) {
- ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len));
+#define PGM_OPT_NBR_UNREACH_LEN (2+2)
+ if (opt_len != PGM_OPT_NBR_UNREACH_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != %u]",
+ opt_len, PGM_OPT_NBR_UNREACH_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " NBR_UNREACH"));
- opts_len -= 4;
+ opts_len -= PGM_OPT_NBR_UNREACH_LEN;
break;
case PGM_OPT_PATH_NLA:
@@ -649,33 +679,39 @@ pgm_print(netdissect_options *ndo,
break;
case PGM_OPT_SYN:
- if (opt_len != 4) {
- ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != 4]", opt_len));
+#define PGM_OPT_SYN_LEN (2+2)
+ if (opt_len != PGM_OPT_SYN_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != %u]",
+ opt_len, PGM_OPT_SYN_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " SYN"));
- opts_len -= 4;
+ opts_len -= PGM_OPT_SYN_LEN;
break;
case PGM_OPT_FIN:
- if (opt_len != 4) {
- ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != 4]", opt_len));
+#define PGM_OPT_FIN_LEN (2+2)
+ if (opt_len != PGM_OPT_FIN_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != %u]",
+ opt_len, PGM_OPT_FIN_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " FIN"));
- opts_len -= 4;
+ opts_len -= PGM_OPT_FIN_LEN;
break;
case PGM_OPT_RST:
- if (opt_len != 4) {
- ND_PRINT((ndo, "[Bad OPT_RST option, length %u != 4]", opt_len));
+#define PGM_OPT_RST_LEN (2+2)
+ if (opt_len != PGM_OPT_RST_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_RST option, length %u != %u]",
+ opt_len, PGM_OPT_RST_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " RST"));
- opts_len -= 4;
+ opts_len -= PGM_OPT_RST_LEN;
break;
case PGM_OPT_CR:
@@ -685,41 +721,51 @@ pgm_print(netdissect_options *ndo,
break;
case PGM_OPT_CRQST:
- if (opt_len != 4) {
- ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != 4]", opt_len));
+#define PGM_OPT_CRQST_LEN (2+2)
+ if (opt_len != PGM_OPT_CRQST_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != %u]",
+ opt_len, PGM_OPT_CRQST_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " CRQST"));
- opts_len -= 4;
+ opts_len -= PGM_OPT_CRQST_LEN;
break;
case PGM_OPT_PGMCC_DATA:
+#define PGM_OPT_PGMCC_DATA_FIXED_LEN (2+2+4+2+2)
+ if (opt_len < PGM_OPT_PGMCC_DATA_FIXED_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u < %u]",
+ opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN));
+ return;
+ }
bp += 2;
offset = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
nla_afnum = EXTRACT_16BITS(bp);
- bp += (2 * sizeof(uint16_t));
+ bp += 2+2;
switch (nla_afnum) {
case AFNUM_INET:
- if (opt_len != 12 + sizeof(struct in_addr)) {
- ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
+ if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in_addr)) {
+ ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != %u + address size]",
+ opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in_addr));
addrtostr(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in_addr);
- opts_len -= 12 + sizeof(struct in_addr);
+ opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in_addr);
break;
case AFNUM_INET6:
- if (opt_len != 12 + sizeof(struct in6_addr)) {
- ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
+ if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in6_addr)) {
+ ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != %u + address size]",
+ opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in6_addr));
addrtostr6(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in6_addr);
- opts_len -= 12 + sizeof(struct in6_addr);
+ opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in6_addr);
break;
default:
goto trunc;
@@ -730,31 +776,39 @@ pgm_print(netdissect_options *ndo,
break;
case PGM_OPT_PGMCC_FEEDBACK:
+#define PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN (2+2+4+2+2)
+ if (opt_len < PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN) {
+ ND_PRINT((ndo, "[Bad PGM_OPT_PGMCC_FEEDBACK option, length %u < %u]",
+ opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN));
+ return;
+ }
bp += 2;
offset = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
nla_afnum = EXTRACT_16BITS(bp);
- bp += (2 * sizeof(uint16_t));
+ bp += 2+2;
switch (nla_afnum) {
case AFNUM_INET:
- if (opt_len != 12 + sizeof(struct in_addr)) {
- ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
+ if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in_addr)) {
+ ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]",
+ opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in_addr));
addrtostr(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in_addr);
- opts_len -= 12 + sizeof(struct in_addr);
+ opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in_addr);
break;
case AFNUM_INET6:
- if (opt_len != 12 + sizeof(struct in6_addr)) {
- ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
+ if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in6_addr)) {
+ ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]",
+ opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in6_addr));
addrtostr6(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in6_addr);
- opts_len -= 12 + sizeof(struct in6_addr);
+ opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in6_addr);
break;
default:
goto trunc;
diff --git a/freebsd/contrib/tcpdump/print-pim.c b/freebsd/contrib/tcpdump/print-pim.c
index 1762436a..2fa38842 100644
--- a/freebsd/contrib/tcpdump/print-pim.c
+++ b/freebsd/contrib/tcpdump/print-pim.c
@@ -175,20 +175,28 @@ pimv1_join_prune_print(netdissect_options *ndo,
return;
}
+ if (len < sizeof(struct in_addr))
+ goto trunc;
ND_TCHECK2(bp[0], sizeof(struct in_addr));
if (ndo->ndo_vflag > 1)
ND_PRINT((ndo, "\n"));
ND_PRINT((ndo, " Upstream Nbr: %s", ipaddr_string(ndo, bp)));
- ND_TCHECK2(bp[6], 2);
+ bp += 4;
+ len -= 4;
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK2(bp[2], 2);
if (ndo->ndo_vflag > 1)
ND_PRINT((ndo, "\n"));
ND_PRINT((ndo, " Hold time: "));
- unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[6]));
+ unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2]));
if (ndo->ndo_vflag < 2)
return;
- bp += 8;
- len -= 8;
+ bp += 4;
+ len -= 4;
+ if (len < 4)
+ goto trunc;
ND_TCHECK2(bp[0], 4);
ngroups = bp[3];
bp += 4;
@@ -198,17 +206,27 @@ pimv1_join_prune_print(netdissect_options *ndo,
* XXX - does the address have length "addrlen" and the
* mask length "maddrlen"?
*/
+ if (len < 4)
+ goto trunc;
ND_TCHECK2(bp[0], sizeof(struct in_addr));
ND_PRINT((ndo, "\n\tGroup: %s", ipaddr_string(ndo, bp)));
- ND_TCHECK2(bp[4], sizeof(struct in_addr));
- if (EXTRACT_32BITS(&bp[4]) != 0xffffffff)
- ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[4])));
- ND_TCHECK2(bp[8], 4);
- njoin = EXTRACT_16BITS(&bp[8]);
- nprune = EXTRACT_16BITS(&bp[10]);
+ bp += 4;
+ len -= 4;
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK2(bp[0], sizeof(struct in_addr));
+ if (EXTRACT_32BITS(&bp[0]) != 0xffffffff)
+ ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[0])));
+ bp += 4;
+ len -= 4;
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK2(bp[0], 4);
+ njoin = EXTRACT_16BITS(&bp[0]);
+ nprune = EXTRACT_16BITS(&bp[2]);
ND_PRINT((ndo, " joined: %d pruned: %d", njoin, nprune));
- bp += 12;
- len -= 12;
+ bp += 4;
+ len -= 4;
for (njp = 0; njp < (njoin + nprune); njp++) {
const char *type;
@@ -216,12 +234,15 @@ pimv1_join_prune_print(netdissect_options *ndo,
type = "Join ";
else
type = "Prune";
+ if (len < 6)
+ goto trunc;
ND_TCHECK2(bp[0], 6);
ND_PRINT((ndo, "\n\t%s %s%s%s%s/%d", type,
(bp[0] & 0x01) ? "Sparse " : "Dense ",
(bp[1] & 0x80) ? "WC " : "",
(bp[1] & 0x40) ? "RP " : "SPT ",
- ipaddr_string(ndo, &bp[2]), bp[1] & 0x3f));
+ ipaddr_string(ndo, &bp[2]),
+ bp[1] & 0x3f));
bp += 6;
len -= 6;
}
@@ -236,13 +257,8 @@ void
pimv1_print(netdissect_options *ndo,
register const u_char *bp, register u_int len)
{
- register const u_char *ep;
register u_char type;
- ep = (const u_char *)ndo->ndo_snapend;
- if (bp >= ep)
- return;
-
ND_TCHECK(bp[1]);
type = bp[1];
@@ -308,10 +324,14 @@ pimv1_print(netdissect_options *ndo,
case PIMV1_TYPE_JOIN_PRUNE:
case PIMV1_TYPE_GRAFT:
case PIMV1_TYPE_GRAFT_ACK:
- if (ndo->ndo_vflag)
+ if (ndo->ndo_vflag) {
+ if (len < 8)
+ goto trunc;
pimv1_join_prune_print(ndo, &bp[8], len - 8);
+ }
break;
}
+ ND_TCHECK(bp[4]);
if ((bp[4] >> 4) != 1)
ND_PRINT((ndo, " [v%d]", bp[4] >> 4));
return;
@@ -335,6 +355,8 @@ cisco_autorp_print(netdissect_options *ndo,
int numrps;
int hold;
+ if (len < 8)
+ goto trunc;
ND_TCHECK(bp[0]);
ND_PRINT((ndo, " auto-rp "));
type = bp[0];
@@ -382,10 +404,16 @@ cisco_autorp_print(netdissect_options *ndo,
int nentries;
char s;
+ if (len < 4)
+ goto trunc;
ND_TCHECK2(bp[0], 4);
ND_PRINT((ndo, " RP %s", ipaddr_string(ndo, bp)));
- ND_TCHECK(bp[4]);
- switch (bp[4] & 0x3) {
+ bp += 4;
+ len -= 4;
+ if (len < 1)
+ goto trunc;
+ ND_TCHECK(bp[0]);
+ switch (bp[0] & 0x3) {
case 0: ND_PRINT((ndo, " PIMv?"));
break;
case 1: ND_PRINT((ndo, " PIMv1"));
@@ -395,13 +423,20 @@ cisco_autorp_print(netdissect_options *ndo,
case 3: ND_PRINT((ndo, " PIMv1+2"));
break;
}
- if (bp[4] & 0xfc)
- ND_PRINT((ndo, " [rsvd=0x%02x]", bp[4] & 0xfc));
- ND_TCHECK(bp[5]);
- nentries = bp[5];
- bp += 6; len -= 6;
+ if (bp[0] & 0xfc)
+ ND_PRINT((ndo, " [rsvd=0x%02x]", bp[0] & 0xfc));
+ bp += 1;
+ len -= 1;
+ if (len < 1)
+ goto trunc;
+ ND_TCHECK(bp[0]);
+ nentries = bp[0];
+ bp += 1;
+ len -= 1;
s = ' ';
for (; nentries; nentries--) {
+ if (len < 6)
+ goto trunc;
ND_TCHECK2(bp[0], 6);
ND_PRINT((ndo, "%c%s%s/%d", s, bp[0] & 1 ? "!" : "",
ipaddr_string(ndo, &bp[2]), bp[1]));
@@ -426,16 +461,13 @@ void
pim_print(netdissect_options *ndo,
register const u_char *bp, register u_int len, const u_char *bp2)
{
- register const u_char *ep;
register const struct pim *pim = (const struct pim *)bp;
- ep = (const u_char *)ndo->ndo_snapend;
- if (bp >= ep)
- return;
#ifdef notyet /* currently we see only version and type */
ND_TCHECK(pim->pim_rsv);
#endif
+ ND_TCHECK(pim->pim_typever);
switch (PIM_VER(pim->pim_typever)) {
case 2:
if (!ndo->ndo_vflag) {
@@ -459,6 +491,10 @@ pim_print(netdissect_options *ndo,
break;
}
return;
+
+trunc:
+ ND_PRINT((ndo, "[|pim]"));
+ return;
}
/*
@@ -501,8 +537,6 @@ pim_print(netdissect_options *ndo,
*
*/
-static int pimv2_addr_len;
-
enum pimv2_addrtype {
pimv2_unicast, pimv2_group, pimv2_source
};
@@ -529,23 +563,24 @@ enum pimv2_addrtype {
*/
static int
pimv2_addr_print(netdissect_options *ndo,
- const u_char *bp, enum pimv2_addrtype at, int silent)
+ const u_char *bp, u_int len, enum pimv2_addrtype at,
+ u_int addr_len, int silent)
{
int af;
- int len, hdrlen;
-
- ND_TCHECK(bp[0]);
+ int hdrlen;
- if (pimv2_addr_len == 0) {
+ if (addr_len == 0) {
+ if (len < 2)
+ goto trunc;
ND_TCHECK(bp[1]);
switch (bp[0]) {
case 1:
af = AF_INET;
- len = sizeof(struct in_addr);
+ addr_len = (u_int)sizeof(struct in_addr);
break;
case 2:
af = AF_INET6;
- len = sizeof(struct in6_addr);
+ addr_len = (u_int)sizeof(struct in6_addr);
break;
default:
return -1;
@@ -554,7 +589,7 @@ pimv2_addr_print(netdissect_options *ndo,
return -1;
hdrlen = 2;
} else {
- switch (pimv2_addr_len) {
+ switch (addr_len) {
case sizeof(struct in_addr):
af = AF_INET;
break;
@@ -565,14 +600,16 @@ pimv2_addr_print(netdissect_options *ndo,
return -1;
break;
}
- len = pimv2_addr_len;
hdrlen = 0;
}
bp += hdrlen;
+ len -= hdrlen;
switch (at) {
case pimv2_unicast:
- ND_TCHECK2(bp[0], len);
+ if (len < addr_len)
+ goto trunc;
+ ND_TCHECK2(bp[0], addr_len);
if (af == AF_INET) {
if (!silent)
ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp)));
@@ -581,10 +618,12 @@ pimv2_addr_print(netdissect_options *ndo,
if (!silent)
ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp)));
}
- return hdrlen + len;
+ return hdrlen + addr_len;
case pimv2_group:
case pimv2_source:
- ND_TCHECK2(bp[0], len + 2);
+ if (len < addr_len + 2)
+ goto trunc;
+ ND_TCHECK2(bp[0], addr_len + 2);
if (af == AF_INET) {
if (!silent) {
ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp + 2)));
@@ -613,7 +652,7 @@ pimv2_addr_print(netdissect_options *ndo,
ND_PRINT((ndo, ")"));
}
}
- return hdrlen + 2 + len;
+ return hdrlen + 2 + addr_len;
default:
return -1;
}
@@ -661,21 +700,21 @@ static void
pimv2_print(netdissect_options *ndo,
register const u_char *bp, register u_int len, const u_char *bp2)
{
- register const u_char *ep;
register const struct pim *pim = (const struct pim *)bp;
int advance;
enum checksum_status cksum_status;
+ int pimv2_addr_len;
- ep = (const u_char *)ndo->ndo_snapend;
- if (bp >= ep)
- return;
- if (ep > bp + len)
- ep = bp + len;
+ if (len < 2)
+ goto trunc;
ND_TCHECK(pim->pim_rsv);
pimv2_addr_len = pim->pim_rsv;
if (pimv2_addr_len != 0)
ND_PRINT((ndo, ", RFC2117-encoding"));
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK(pim->pim_cksum);
ND_PRINT((ndo, ", cksum 0x%04x ", EXTRACT_16BITS(&pim->pim_cksum)));
if (EXTRACT_16BITS(&pim->pim_cksum) == 0) {
ND_PRINT((ndo, "(unverified)"));
@@ -716,26 +755,36 @@ pimv2_print(netdissect_options *ndo,
break;
}
}
+ bp += 4;
+ len -= 4;
switch (PIM_TYPE(pim->pim_typever)) {
case PIMV2_TYPE_HELLO:
{
uint16_t otype, olen;
- bp += 4;
- while (bp < ep) {
+ while (len > 0) {
+ if (len < 4)
+ goto trunc;
ND_TCHECK2(bp[0], 4);
otype = EXTRACT_16BITS(&bp[0]);
olen = EXTRACT_16BITS(&bp[2]);
- ND_TCHECK2(bp[0], 4 + olen);
ND_PRINT((ndo, "\n\t %s Option (%u), length %u, Value: ",
tok2str(pimv2_hello_option_values, "Unknown", otype),
otype,
olen));
bp += 4;
+ len -= 4;
+ if (len < olen)
+ goto trunc;
+ ND_TCHECK2(bp[0], olen);
switch (otype) {
case PIMV2_HELLO_OPTION_HOLDTIME:
- unsigned_relts_print(ndo, EXTRACT_16BITS(bp));
+ if (olen != 2) {
+ ND_PRINT((ndo, "ERROR: Option Length != 2 Bytes (%u)", olen));
+ } else {
+ unsigned_relts_print(ndo, EXTRACT_16BITS(bp));
+ }
break;
case PIMV2_HELLO_OPTION_LANPRUNEDELAY:
@@ -769,17 +818,25 @@ pimv2_print(netdissect_options *ndo,
break;
case PIMV2_HELLO_OPTION_GENID:
- ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(bp)));
+ if (olen != 4) {
+ ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen));
+ } else {
+ ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(bp)));
+ }
break;
case PIMV2_HELLO_OPTION_REFRESH_CAP:
- ND_PRINT((ndo, "v%d", *bp));
- if (*(bp+1) != 0) {
- ND_PRINT((ndo, ", interval "));
- unsigned_relts_print(ndo, *(bp+1));
- }
- if (EXTRACT_16BITS(bp+2) != 0) {
- ND_PRINT((ndo, " ?0x%04x?", EXTRACT_16BITS(bp+2)));
+ if (olen != 4) {
+ ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen));
+ } else {
+ ND_PRINT((ndo, "v%d", *bp));
+ if (*(bp+1) != 0) {
+ ND_PRINT((ndo, ", interval "));
+ unsigned_relts_print(ndo, *(bp+1));
+ }
+ if (EXTRACT_16BITS(bp+2) != 0) {
+ ND_PRINT((ndo, " ?0x%04x?", EXTRACT_16BITS(bp+2)));
+ }
}
break;
@@ -790,14 +847,14 @@ pimv2_print(netdissect_options *ndo,
case PIMV2_HELLO_OPTION_ADDRESS_LIST:
if (ndo->ndo_vflag > 1) {
const u_char *ptr = bp;
+ u_int plen = len;
while (ptr < (bp+olen)) {
ND_PRINT((ndo, "\n\t "));
- advance = pimv2_addr_print(ndo, ptr, pimv2_unicast, 0);
- if (advance < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ advance = pimv2_addr_print(ndo, ptr, plen, pimv2_unicast, pimv2_addr_len, 0);
+ if (advance < 0)
+ goto trunc;
ptr += advance;
+ plen -= advance;
}
}
break;
@@ -810,6 +867,7 @@ pimv2_print(netdissect_options *ndo,
if (ndo->ndo_vflag> 1)
print_unknown_data(ndo, bp, "\n\t ", olen);
bp += olen;
+ len -= olen;
}
break;
}
@@ -818,18 +876,24 @@ pimv2_print(netdissect_options *ndo,
{
const struct ip *ip;
- ND_TCHECK2(*(bp + 4), PIMV2_REGISTER_FLAG_LEN);
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK2(*bp, PIMV2_REGISTER_FLAG_LEN);
ND_PRINT((ndo, ", Flags [ %s ]\n\t",
tok2str(pimv2_register_flag_values,
"none",
- EXTRACT_32BITS(bp+4))));
+ EXTRACT_32BITS(bp))));
- bp += 8; len -= 8;
+ bp += 4; len -= 4;
/* encapsulated multicast packet */
+ if (len == 0)
+ goto trunc;
ip = (const struct ip *)bp;
+ ND_TCHECK(ip->ip_vhl);
switch (IP_V(ip)) {
case 0: /* Null header */
+ ND_TCHECK(ip->ip_dst);
ND_PRINT((ndo, "IP-Null-header %s > %s",
ipaddr_string(ndo, &ip->ip_src),
ipaddr_string(ndo, &ip->ip_dst)));
@@ -851,22 +915,13 @@ pimv2_print(netdissect_options *ndo,
}
case PIMV2_TYPE_REGISTER_STOP:
- bp += 4; len -= 4;
- if (bp >= ep)
- break;
ND_PRINT((ndo, " group="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
- if (bp >= ep)
- break;
ND_PRINT((ndo, " source="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
break;
@@ -917,19 +972,15 @@ pimv2_print(netdissect_options *ndo,
uint16_t nprune;
int i, j;
- bp += 4; len -= 4;
if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/
- if (bp >= ep)
- break;
ND_PRINT((ndo, ", upstream-neighbor: "));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
}
- if (bp + 4 > ep)
- break;
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK2(*bp, 4);
ngroup = bp[1];
holdtime = EXTRACT_16BITS(&bp[2]);
ND_PRINT((ndo, "\n\t %u group(s)", ngroup));
@@ -942,139 +993,125 @@ pimv2_print(netdissect_options *ndo,
}
bp += 4; len -= 4;
for (i = 0; i < ngroup; i++) {
- if (bp >= ep)
- goto jp_done;
ND_PRINT((ndo, "\n\t group #%u: ", i+1));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) {
- ND_PRINT((ndo, "...)"));
- goto jp_done;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
- if (bp + 4 > ep) {
- ND_PRINT((ndo, "...)"));
- goto jp_done;
- }
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK2(*bp, 4);
njoin = EXTRACT_16BITS(&bp[0]);
nprune = EXTRACT_16BITS(&bp[2]);
ND_PRINT((ndo, ", joined sources: %u, pruned sources: %u", njoin, nprune));
bp += 4; len -= 4;
for (j = 0; j < njoin; j++) {
ND_PRINT((ndo, "\n\t joined source #%u: ", j+1));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_source, 0)) < 0) {
- ND_PRINT((ndo, "...)"));
- goto jp_done;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_source, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
}
for (j = 0; j < nprune; j++) {
ND_PRINT((ndo, "\n\t pruned source #%u: ", j+1));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_source, 0)) < 0) {
- ND_PRINT((ndo, "...)"));
- goto jp_done;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_source, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
}
}
- jp_done:
break;
}
case PIMV2_TYPE_BOOTSTRAP:
{
int i, j, frpcnt;
- bp += 4;
/* Fragment Tag, Hash Mask len, and BSR-priority */
- if (bp + sizeof(uint16_t) >= ep) break;
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, " tag=%x", EXTRACT_16BITS(bp)));
- bp += sizeof(uint16_t);
- if (bp >= ep) break;
+ bp += 2;
+ len -= 2;
+ if (len < 1)
+ goto trunc;
+ ND_TCHECK(bp[0]);
ND_PRINT((ndo, " hashmlen=%d", bp[0]));
- if (bp + 1 >= ep) break;
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK(bp[2]);
ND_PRINT((ndo, " BSRprio=%d", bp[1]));
bp += 2;
+ len -= 2;
/* Encoded-Unicast-BSR-Address */
- if (bp >= ep) break;
ND_PRINT((ndo, " BSR="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
- for (i = 0; bp < ep; i++) {
+ for (i = 0; len > 0; i++) {
/* Encoded-Group Address */
ND_PRINT((ndo, " (group%d: ", i));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0))
- < 0) {
- ND_PRINT((ndo, "...)"));
- goto bs_done;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
/* RP-Count, Frag RP-Cnt, and rsvd */
- if (bp >= ep) {
- ND_PRINT((ndo, "...)"));
- goto bs_done;
- }
+ if (len < 1)
+ goto trunc;
+ ND_TCHECK(bp[0]);
ND_PRINT((ndo, " RPcnt=%d", bp[0]));
- if (bp + 1 >= ep) {
- ND_PRINT((ndo, "...)"));
- goto bs_done;
- }
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK(bp[1]);
ND_PRINT((ndo, " FRPcnt=%d", frpcnt = bp[1]));
+ if (len < 4)
+ goto trunc;
bp += 4;
+ len -= 4;
- for (j = 0; j < frpcnt && bp < ep; j++) {
+ for (j = 0; j < frpcnt && len > 0; j++) {
/* each RP info */
ND_PRINT((ndo, " RP%d=", j));
- if ((advance = pimv2_addr_print(ndo, bp,
+ if ((advance = pimv2_addr_print(ndo, bp, len,
pimv2_unicast,
- 0)) < 0) {
- ND_PRINT((ndo, "...)"));
- goto bs_done;
- }
+ pimv2_addr_len,
+ 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
- if (bp + 1 >= ep) {
- ND_PRINT((ndo, "...)"));
- goto bs_done;
- }
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, ",holdtime="));
unsigned_relts_print(ndo, EXTRACT_16BITS(bp));
- if (bp + 2 >= ep) {
- ND_PRINT((ndo, "...)"));
- goto bs_done;
- }
+ if (len < 3)
+ goto trunc;
+ ND_TCHECK(bp[2]);
ND_PRINT((ndo, ",prio=%d", bp[2]));
+ if (len < 4)
+ goto trunc;
bp += 4;
+ len -= 4;
}
ND_PRINT((ndo, ")"));
}
- bs_done:
break;
}
case PIMV2_TYPE_ASSERT:
- bp += 4; len -= 4;
- if (bp >= ep)
- break;
ND_PRINT((ndo, " group="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
- if (bp >= ep)
- break;
ND_PRINT((ndo, " src="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
- if (bp + 8 > ep)
- break;
+ if (len < 8)
+ goto trunc;
+ ND_TCHECK2(*bp, 8);
if (bp[0] & 0x80)
ND_PRINT((ndo, " RPT"));
ND_PRINT((ndo, " pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff));
@@ -1084,61 +1121,62 @@ pimv2_print(netdissect_options *ndo,
case PIMV2_TYPE_CANDIDATE_RP:
{
int i, pfxcnt;
- bp += 4;
/* Prefix-Cnt, Priority, and Holdtime */
- if (bp >= ep) break;
+ if (len < 1)
+ goto trunc;
+ ND_TCHECK(bp[0]);
ND_PRINT((ndo, " prefix-cnt=%d", bp[0]));
pfxcnt = bp[0];
- if (bp + 1 >= ep) break;
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK(bp[1]);
ND_PRINT((ndo, " prio=%d", bp[1]));
- if (bp + 3 >= ep) break;
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK_16BITS(&bp[2]);
ND_PRINT((ndo, " holdtime="));
unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2]));
bp += 4;
+ len -= 4;
/* Encoded-Unicast-RP-Address */
- if (bp >= ep) break;
ND_PRINT((ndo, " RP="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
/* Encoded-Group Addresses */
- for (i = 0; i < pfxcnt && bp < ep; i++) {
+ for (i = 0; i < pfxcnt && len > 0; i++) {
ND_PRINT((ndo, " Group%d=", i));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0))
- < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
}
break;
}
case PIMV2_TYPE_PRUNE_REFRESH:
ND_PRINT((ndo, " src="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
ND_PRINT((ndo, " grp="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
ND_PRINT((ndo, " forwarder="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
- ND_TCHECK2(bp[0], 2);
+ len -= advance;
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, " TUNR "));
unsigned_relts_print(ndo, EXTRACT_16BITS(bp));
break;
diff --git a/freebsd/contrib/tcpdump/print-pktap.c b/freebsd/contrib/tcpdump/print-pktap.c
index 3bccd567..a0d69769 100644
--- a/freebsd/contrib/tcpdump/print-pktap.c
+++ b/freebsd/contrib/tcpdump/print-pktap.c
@@ -110,6 +110,7 @@ pktap_if_print(netdissect_options *ndo,
u_int length = h->len;
if_printer printer;
const pktap_header_t *hdr;
+ struct pcap_pkthdr nhdr;
if (caplen < sizeof(pktap_header_t) || length < sizeof(pktap_header_t)) {
ND_PRINT((ndo, "[|pktap]"));
@@ -150,7 +151,10 @@ pktap_if_print(netdissect_options *ndo,
case PKT_REC_PACKET:
if ((printer = lookup_printer(dlt)) != NULL) {
- hdrlen += printer(ndo, h, p);
+ nhdr = *h;
+ nhdr.caplen = caplen;
+ nhdr.len = length;
+ hdrlen += printer(ndo, &nhdr, p);
} else {
if (!ndo->ndo_eflag)
pktap_header_print(ndo, (const u_char *)hdr,
diff --git a/freebsd/contrib/tcpdump/print-ppp.c b/freebsd/contrib/tcpdump/print-ppp.c
index ab88944d..724cf72b 100644
--- a/freebsd/contrib/tcpdump/print-ppp.c
+++ b/freebsd/contrib/tcpdump/print-ppp.c
@@ -617,7 +617,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 6)"));
return len;
}
- ND_TCHECK2(*(p + 2), 3);
+ ND_TCHECK_24BITS(p + 2);
ND_PRINT((ndo, ": Vendor: %s (%u)",
tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)),
EXTRACT_24BITS(p + 2)));
@@ -636,7 +636,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 4)"));
return len;
}
- ND_TCHECK2(*(p + 2), 2);
+ ND_TCHECK_16BITS(p + 2);
ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2)));
break;
case LCPOPT_ACCM:
@@ -644,7 +644,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 6)"));
return len;
}
- ND_TCHECK2(*(p + 2), 4);
+ ND_TCHECK_32BITS(p + 2);
ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2)));
break;
case LCPOPT_AP:
@@ -652,7 +652,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return len;
}
- ND_TCHECK2(*(p + 2), 2);
+ ND_TCHECK_16BITS(p + 2);
ND_PRINT((ndo, ": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_16BITS(p + 2))));
switch (EXTRACT_16BITS(p+2)) {
@@ -674,7 +674,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return 0;
}
- ND_TCHECK2(*(p + 2), 2);
+ ND_TCHECK_16BITS(p+2);
if (EXTRACT_16BITS(p+2) == PPP_LQM)
ND_PRINT((ndo, ": LQR"));
else
@@ -685,7 +685,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 6)"));
return 0;
}
- ND_TCHECK2(*(p + 2), 4);
+ ND_TCHECK_32BITS(p + 2);
ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2)));
break;
case LCPOPT_PFC:
@@ -697,7 +697,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 4)"));
return 0;
}
- ND_TCHECK2(*(p + 2), 2);
+ ND_TCHECK_16BITS(p + 2);
ND_PRINT((ndo, ": 0x%04x", EXTRACT_16BITS(p + 2)));
break;
case LCPOPT_CBACK:
@@ -716,7 +716,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 4)"));
return 0;
}
- ND_TCHECK2(*(p + 2), 2);
+ ND_TCHECK_16BITS(p + 2);
ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2)));
break;
case LCPOPT_MLED:
@@ -817,6 +817,15 @@ handle_mlppp(netdissect_options *ndo,
if (!ndo->ndo_eflag)
ND_PRINT((ndo, "MLPPP, "));
+ if (length < 2) {
+ ND_PRINT((ndo, "[|mlppp]"));
+ return;
+ }
+ if (!ND_TTEST_16BITS(p)) {
+ ND_PRINT((ndo, "[|mlppp]"));
+ return;
+ }
+
ND_PRINT((ndo, "seq 0x%03x, Flags [%s], length %u",
(EXTRACT_16BITS(p))&0x0fff, /* only support 12-Bit sequence space for now */
bittok2str(ppp_ml_flag_values, "none", *p & 0xc0),
@@ -1061,7 +1070,7 @@ print_ipcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return 0;
}
- ND_TCHECK2(*(p + 2), 2);
+ ND_TCHECK_16BITS(p+2);
compproto = EXTRACT_16BITS(p+2);
ND_PRINT((ndo, ": %s (0x%02x):",
@@ -1247,7 +1256,7 @@ print_ccp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 3)"));
return len;
}
- ND_TCHECK2(*(p + 2), 1);
+ ND_TCHECK(p[2]);
ND_PRINT((ndo, ": Version: %u, Dictionary Bits: %u",
p[2] >> 5, p[2] & 0x1f));
break;
@@ -1256,7 +1265,7 @@ print_ccp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return len;
}
- ND_TCHECK2(*(p + 2), 1);
+ ND_TCHECK(p[3]);
ND_PRINT((ndo, ": Features: %u, PxP: %s, History: %u, #CTX-ID: %u",
(p[2] & 0xc0) >> 6,
(p[2] & 0x20) ? "Enabled" : "Disabled",
@@ -1267,10 +1276,10 @@ print_ccp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return len;
}
- ND_TCHECK2(*(p + 2), 1);
+ ND_TCHECK(p[3]);
ND_PRINT((ndo, ": Window: %uK, Method: %s (0x%x), MBZ: %u, CHK: %u",
(p[2] & 0xf0) >> 4,
- ((p[2] & 0x0f) == 8) ? "zlib" : "unkown",
+ ((p[2] & 0x0f) == 8) ? "zlib" : "unknown",
p[2] & 0x0f, (p[3] & 0xfc) >> 2, p[3] & 0x03));
break;
@@ -1342,7 +1351,7 @@ print_bacp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 6)"));
return len;
}
- ND_TCHECK2(*(p + 2), 4);
+ ND_TCHECK_32BITS(p + 2);
ND_PRINT((ndo, ": Magic-Num 0x%08x", EXTRACT_32BITS(p + 2)));
break;
default:
@@ -1490,7 +1499,7 @@ handle_ppp(netdissect_options *ndo,
ipx_print(ndo, p, length);
break;
case PPP_OSI:
- isoclns_print(ndo, p, length, length);
+ isoclns_print(ndo, p, length);
break;
case PPP_MPLS_UCAST:
case PPP_MPLS_MCAST:
diff --git a/freebsd/contrib/tcpdump/print-radius.c b/freebsd/contrib/tcpdump/print-radius.c
index 56b692ec..2efbfab4 100644
--- a/freebsd/contrib/tcpdump/print-radius.c
+++ b/freebsd/contrib/tcpdump/print-radius.c
@@ -502,10 +502,7 @@ print_attr_string(netdissect_options *ndo,
{
case TUNNEL_PASS:
if (length < 3)
- {
- ND_PRINT((ndo, "%s", tstr));
- return;
- }
+ goto trunc;
if (*data && (*data <=0x1F) )
ND_PRINT((ndo, "Tag[%u] ", *data));
else
@@ -525,10 +522,7 @@ print_attr_string(netdissect_options *ndo,
if (*data <= 0x1F)
{
if (length < 1)
- {
- ND_PRINT((ndo, "%s", tstr));
- return;
- }
+ goto trunc;
if (*data)
ND_PRINT((ndo, "Tag[%u] ", *data));
else
@@ -538,6 +532,8 @@ print_attr_string(netdissect_options *ndo,
}
break;
case EGRESS_VLAN_NAME:
+ if (length < 1)
+ goto trunc;
ND_PRINT((ndo, "%s (0x%02x) ",
tok2str(rfc4675_tagged,"Unknown tag",*data),
*data));
@@ -546,7 +542,7 @@ print_attr_string(netdissect_options *ndo,
break;
}
- for (i=0; *data && i < length ; i++, data++)
+ for (i=0; i < length && *data; i++, data++)
ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data));
return;
diff --git a/freebsd/contrib/tcpdump/print-resp.c b/freebsd/contrib/tcpdump/print-resp.c
index bb89e13f..96e80b20 100644
--- a/freebsd/contrib/tcpdump/print-resp.c
+++ b/freebsd/contrib/tcpdump/print-resp.c
@@ -487,8 +487,10 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con
ND_TCHECK(*bp);
c = *bp;
if (!(c >= '0' && c <= '9')) {
- if (!saw_digit)
+ if (!saw_digit) {
+ bp++;
goto invalid;
+ }
break;
}
c -= '0';
@@ -497,7 +499,7 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con
too_large = 1;
} else {
result *= 10;
- if (result == INT_MAX && c > (INT_MAX % 10)) {
+ if (result == ((INT_MAX / 10) * 10) && c > (INT_MAX % 10)) {
/* This will overflow an int when we add c */
too_large = 1;
} else
@@ -507,24 +509,24 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con
len--;
saw_digit = 1;
}
- if (!saw_digit)
- goto invalid;
/*
- * OK, the next thing should be \r\n.
+ * OK, we found a non-digit character. It should be a \r, followed
+ * by a \n.
*/
- if (len == 0)
- goto trunc;
- ND_TCHECK(*bp);
- if (*bp != '\r')
+ if (*bp != '\r') {
+ bp++;
goto invalid;
+ }
bp++;
len--;
if (len == 0)
goto trunc;
ND_TCHECK(*bp);
- if (*bp != '\n')
+ if (*bp != '\n') {
+ bp++;
goto invalid;
+ }
bp++;
len--;
*endp = bp;
@@ -537,9 +539,11 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con
return (too_large ? -3 : result);
trunc:
+ *endp = bp;
return (-2);
invalid:
+ *endp = bp;
return (-5);
}
#ifdef __rtems__
diff --git a/freebsd/contrib/tcpdump/print-ripng.c b/freebsd/contrib/tcpdump/print-ripng.c
index 95ec8322..87996c4f 100644
--- a/freebsd/contrib/tcpdump/print-ripng.c
+++ b/freebsd/contrib/tcpdump/print-ripng.c
@@ -116,67 +116,76 @@ ripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length)
{
register const struct rip6 *rp = (const struct rip6 *)dat;
register const struct netinfo6 *ni;
- register u_int amt;
- register u_int i;
- int j;
- int trunc;
-
- if (ndo->ndo_snapend < dat)
- return;
- amt = ndo->ndo_snapend - dat;
- i = min(length, amt);
- if (i < (sizeof(struct rip6) - sizeof(struct netinfo6)))
- return;
- i -= (sizeof(struct rip6) - sizeof(struct netinfo6));
+ unsigned int length_left;
+ u_int j;
+ ND_TCHECK(rp->rip6_cmd);
switch (rp->rip6_cmd) {
case RIP6_REQUEST:
- j = length / sizeof(*ni);
- if (j == 1
- && rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
- && IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
- ND_PRINT((ndo, " ripng-req dump"));
- break;
+ length_left = length;
+ if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6)))
+ goto trunc;
+ length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6));
+ j = length_left / sizeof(*ni);
+ if (j == 1) {
+ ND_TCHECK(rp->rip6_nets);
+ if (rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
+ && IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
+ ND_PRINT((ndo, " ripng-req dump"));
+ break;
+ }
}
- if (j * sizeof(*ni) != length - 4)
- ND_PRINT((ndo, " ripng-req %d[%u]:", j, length));
+ if (j * sizeof(*ni) != length_left)
+ ND_PRINT((ndo, " ripng-req %u[%u]:", j, length));
else
- ND_PRINT((ndo, " ripng-req %d:", j));
- trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
- for (ni = rp->rip6_nets; i >= sizeof(*ni);
- i -= sizeof(*ni), ++ni) {
+ ND_PRINT((ndo, " ripng-req %u:", j));
+ for (ni = rp->rip6_nets; length_left >= sizeof(*ni);
+ length_left -= sizeof(*ni), ++ni) {
+ ND_TCHECK(*ni);
if (ndo->ndo_vflag > 1)
ND_PRINT((ndo, "\n\t"));
else
ND_PRINT((ndo, " "));
rip6_entry_print(ndo, ni, 0);
}
+ if (length_left != 0)
+ goto trunc;
break;
case RIP6_RESPONSE:
- j = length / sizeof(*ni);
- if (j * sizeof(*ni) != length - 4)
+ length_left = length;
+ if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6)))
+ goto trunc;
+ length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6));
+ j = length_left / sizeof(*ni);
+ if (j * sizeof(*ni) != length_left)
ND_PRINT((ndo, " ripng-resp %d[%u]:", j, length));
else
ND_PRINT((ndo, " ripng-resp %d:", j));
- trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
- for (ni = rp->rip6_nets; i >= sizeof(*ni);
- i -= sizeof(*ni), ++ni) {
+ for (ni = rp->rip6_nets; length_left >= sizeof(*ni);
+ length_left -= sizeof(*ni), ++ni) {
+ ND_TCHECK(*ni);
if (ndo->ndo_vflag > 1)
ND_PRINT((ndo, "\n\t"));
else
ND_PRINT((ndo, " "));
rip6_entry_print(ndo, ni, ni->rip6_metric);
}
- if (trunc)
- ND_PRINT((ndo, "[|ripng]"));
+ if (length_left != 0)
+ goto trunc;
break;
default:
ND_PRINT((ndo, " ripng-%d ?? %u", rp->rip6_cmd, length));
break;
}
+ ND_TCHECK(rp->rip6_vers);
if (rp->rip6_vers != RIP6_VERSION)
ND_PRINT((ndo, " [vers %d]", rp->rip6_vers));
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|ripng]"));
+ return;
}
#ifdef __rtems__
#include "rtems-bsd-tcpdump-print-ripng-data.h"
diff --git a/freebsd/contrib/tcpdump/print-rpki-rtr.c b/freebsd/contrib/tcpdump/print-rpki-rtr.c
index 17a9a566..e21f67dc 100644
--- a/freebsd/contrib/tcpdump/print-rpki-rtr.c
+++ b/freebsd/contrib/tcpdump/print-rpki-rtr.c
@@ -18,7 +18,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: Resource Public Key Infrastructure (RPKI) to Router Protocol printer */
@@ -88,6 +88,9 @@ typedef struct rpki_rtr_pdu_ipv6_prefix_ {
typedef struct rpki_rtr_pdu_error_report_ {
rpki_rtr_pdu pdu_header;
u_char encapsulated_pdu_length[4]; /* Encapsulated PDU length */
+ /* Copy of Erroneous PDU (variable, optional) */
+ /* Length of Error Text (4 octets in network byte order) */
+ /* Arbitrary Text of Error Diagnostic Message (variable, optional) */
} rpki_rtr_pdu_error_report;
/*
@@ -177,17 +180,38 @@ indent_string (u_int indent)
/*
* Print a single PDU.
*/
-static int
-rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
+static u_int
+rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len,
+ const u_char recurse, const u_int indent)
{
const rpki_rtr_pdu *pdu_header;
u_int pdu_type, pdu_len, hexdump;
const u_char *msg;
+ /* Protocol Version */
+ ND_TCHECK_8BITS(tptr);
+ if (*tptr != 0) {
+ /* Skip the rest of the input buffer because even if this is
+ * a well-formed PDU of a future RPKI-Router protocol version
+ * followed by a well-formed PDU of RPKI-Router protocol
+ * version 0, there is no way to know exactly how to skip the
+ * current PDU.
+ */
+ ND_PRINT((ndo, "%sRPKI-RTRv%u (unknown)", indent_string(8), *tptr));
+ return len;
+ }
+ if (len < sizeof(rpki_rtr_pdu)) {
+ ND_PRINT((ndo, "(%u bytes is too few to decode)", len));
+ goto invalid;
+ }
+ ND_TCHECK2(*tptr, sizeof(rpki_rtr_pdu));
pdu_header = (const rpki_rtr_pdu *)tptr;
pdu_type = pdu_header->pdu_type;
pdu_len = EXTRACT_32BITS(pdu_header->length);
- ND_TCHECK2(*tptr, pdu_len);
+ /* Do not check bounds with pdu_len yet, do it in the case blocks
+ * below to make it possible to decode at least the beginning of
+ * a truncated Error Report PDU or a truncated encapsulated PDU.
+ */
hexdump = FALSE;
ND_PRINT((ndo, "%sRPKI-RTRv%u, %s PDU (%u), length: %u",
@@ -195,6 +219,8 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
pdu_header->version,
tok2str(rpki_rtr_pdu_values, "Unknown", pdu_type),
pdu_type, pdu_len));
+ if (pdu_len < sizeof(rpki_rtr_pdu) || pdu_len > len)
+ goto invalid;
switch (pdu_type) {
@@ -204,6 +230,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
case RPKI_RTR_SERIAL_NOTIFY_PDU:
case RPKI_RTR_SERIAL_QUERY_PDU:
case RPKI_RTR_END_OF_DATA_PDU:
+ if (pdu_len != sizeof(rpki_rtr_pdu) + 4)
+ goto invalid;
+ ND_TCHECK2(*tptr, pdu_len);
msg = (const u_char *)(pdu_header + 1);
ND_PRINT((ndo, "%sSession ID: 0x%04x, Serial: %u",
indent_string(indent+2),
@@ -216,6 +245,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
*/
case RPKI_RTR_RESET_QUERY_PDU:
case RPKI_RTR_CACHE_RESET_PDU:
+ if (pdu_len != sizeof(rpki_rtr_pdu))
+ goto invalid;
+ /* no additional boundary to check */
/*
* Zero payload PDUs.
@@ -223,6 +255,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
break;
case RPKI_RTR_CACHE_RESPONSE_PDU:
+ if (pdu_len != sizeof(rpki_rtr_pdu))
+ goto invalid;
+ /* no additional boundary to check */
ND_PRINT((ndo, "%sSession ID: 0x%04x",
indent_string(indent+2),
EXTRACT_16BITS(pdu_header->u.session_id)));
@@ -232,6 +267,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
{
const rpki_rtr_pdu_ipv4_prefix *pdu;
+ if (pdu_len != sizeof(rpki_rtr_pdu) + 12)
+ goto invalid;
+ ND_TCHECK2(*tptr, pdu_len);
pdu = (const rpki_rtr_pdu_ipv4_prefix *)tptr;
ND_PRINT((ndo, "%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
indent_string(indent+2),
@@ -245,6 +283,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
{
const rpki_rtr_pdu_ipv6_prefix *pdu;
+ if (pdu_len != sizeof(rpki_rtr_pdu) + 24)
+ goto invalid;
+ ND_TCHECK2(*tptr, pdu_len);
pdu = (const rpki_rtr_pdu_ipv6_prefix *)tptr;
ND_PRINT((ndo, "%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
indent_string(indent+2),
@@ -259,10 +300,17 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
const rpki_rtr_pdu_error_report *pdu;
u_int encapsulated_pdu_length, text_length, tlen, error_code;
+ tlen = sizeof(rpki_rtr_pdu);
+ /* Do not test for the "Length of Error Text" data element yet. */
+ if (pdu_len < tlen + 4)
+ goto invalid;
+ ND_TCHECK2(*tptr, tlen + 4);
+ /* Safe up to and including the "Length of Encapsulated PDU"
+ * data element, more data elements may be present.
+ */
pdu = (const rpki_rtr_pdu_error_report *)tptr;
encapsulated_pdu_length = EXTRACT_32BITS(pdu->encapsulated_pdu_length);
- ND_TCHECK2(*tptr, encapsulated_pdu_length);
- tlen = pdu_len;
+ tlen += 4;
error_code = EXTRACT_16BITS(pdu->pdu_header.u.error_code);
ND_PRINT((ndo, "%sError code: %s (%u), Encapsulated PDU length: %u",
@@ -270,41 +318,58 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
tok2str(rpki_rtr_error_codes, "Unknown", error_code),
error_code, encapsulated_pdu_length));
- tptr += sizeof(*pdu);
- tlen -= sizeof(*pdu);
-
- /*
- * Recurse if there is an encapsulated PDU.
- */
- if (encapsulated_pdu_length &&
- (encapsulated_pdu_length <= tlen)) {
- ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4)));
- if (rpki_rtr_pdu_print(ndo, tptr, indent+2))
- goto trunc;
+ if (encapsulated_pdu_length) {
+ /* Section 5.10 of RFC 6810 says:
+ * "An Error Report PDU MUST NOT be sent for an Error Report PDU."
+ *
+ * However, as far as the protocol encoding goes Error Report PDUs can
+ * happen to be nested in each other, however many times, in which case
+ * the decoder should still print such semantically incorrect PDUs.
+ *
+ * That said, "the Erroneous PDU field MAY be truncated" (ibid), thus
+ * to keep things simple this implementation decodes only the two
+ * outermost layers of PDUs and makes bounds checks in the outer and
+ * the inner PDU independently.
+ */
+ if (pdu_len < tlen + encapsulated_pdu_length)
+ goto invalid;
+ if (! recurse) {
+ ND_TCHECK2(*tptr, tlen + encapsulated_pdu_length);
+ }
+ else {
+ ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4)));
+ rpki_rtr_pdu_print(ndo, tptr + tlen,
+ encapsulated_pdu_length, 0, indent + 2);
+ }
+ tlen += encapsulated_pdu_length;
}
- tptr += encapsulated_pdu_length;
- tlen -= encapsulated_pdu_length;
+ if (pdu_len < tlen + 4)
+ goto invalid;
+ ND_TCHECK2(*tptr, tlen + 4);
+ /* Safe up to and including the "Length of Error Text" data element,
+ * one more data element may be present.
+ */
/*
* Extract, trail-zero and print the Error message.
*/
- text_length = 0;
- if (tlen > 4) {
- text_length = EXTRACT_32BITS(tptr);
- tptr += 4;
- tlen -= 4;
- }
- ND_TCHECK2(*tptr, text_length);
- if (text_length && (text_length <= tlen )) {
+ text_length = EXTRACT_32BITS(tptr + tlen);
+ tlen += 4;
+
+ if (text_length) {
+ if (pdu_len < tlen + text_length)
+ goto invalid;
+ /* fn_printn() makes the bounds check */
ND_PRINT((ndo, "%sError text: ", indent_string(indent+2)));
- if (fn_printn(ndo, tptr, text_length, ndo->ndo_snapend))
+ if (fn_printn(ndo, tptr + tlen, text_length, ndo->ndo_snapend))
goto trunc;
}
}
break;
default:
+ ND_TCHECK2(*tptr, pdu_len);
/*
* Unknown data, please hexdump.
@@ -316,57 +381,29 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) {
print_unknown_data(ndo,tptr,"\n\t ", pdu_len);
}
- return 0;
+ return pdu_len;
+invalid:
+ ND_PRINT((ndo, "%s", istr));
+ ND_TCHECK2(*tptr, len);
+ return len;
trunc:
- return 1;
+ ND_PRINT((ndo, "\n\t%s", tstr));
+ return len;
}
void
rpki_rtr_print(netdissect_options *ndo, register const u_char *pptr, register u_int len)
{
- u_int tlen, pdu_type, pdu_len;
- const u_char *tptr;
- const rpki_rtr_pdu *pdu_header;
-
- tptr = pptr;
- tlen = len;
-
if (!ndo->ndo_vflag) {
ND_PRINT((ndo, ", RPKI-RTR"));
return;
}
-
- while (tlen >= sizeof(rpki_rtr_pdu)) {
-
- ND_TCHECK2(*tptr, sizeof(rpki_rtr_pdu));
-
- pdu_header = (const rpki_rtr_pdu *)tptr;
- pdu_type = pdu_header->pdu_type;
- pdu_len = EXTRACT_32BITS(pdu_header->length);
- ND_TCHECK2(*tptr, pdu_len);
-
- /* infinite loop check */
- if (!pdu_type || !pdu_len) {
- break;
- }
-
- if (tlen < pdu_len) {
- goto trunc;
- }
-
- /*
- * Print the PDU.
- */
- if (rpki_rtr_pdu_print(ndo, tptr, 8))
- goto trunc;
-
- tlen -= pdu_len;
- tptr += pdu_len;
+ while (len) {
+ u_int pdu_len = rpki_rtr_pdu_print(ndo, pptr, len, 1, 8);
+ len -= pdu_len;
+ pptr += pdu_len;
}
- return;
-trunc:
- ND_PRINT((ndo, "\n\t%s", tstr));
}
/*
diff --git a/freebsd/contrib/tcpdump/print-rsvp.c b/freebsd/contrib/tcpdump/print-rsvp.c
index 727f2db1..102757d0 100644
--- a/freebsd/contrib/tcpdump/print-rsvp.c
+++ b/freebsd/contrib/tcpdump/print-rsvp.c
@@ -18,7 +18,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: Resource ReSerVation Protocol (RSVP) printer */
@@ -1211,6 +1211,17 @@ rsvp_obj_print(netdissect_options *ndo,
/* read variable length subobjects */
total_subobj_len = obj_tlen;
while(total_subobj_len > 0) {
+ /* If RFC 3476 Section 3.1 defined that a sub-object of the
+ * GENERALIZED_UNI RSVP object must have the Length field as
+ * a multiple of 4, instead of the check below it would be
+ * better to test total_subobj_len only once before the loop.
+ * So long as it does not define it and this while loop does
+ * not implement such a requirement, let's accept that within
+ * each iteration subobj_len may happen to be a multiple of 1
+ * and test it and total_subobj_len respectively.
+ */
+ if (total_subobj_len < 4)
+ goto invalid;
subobj_len = EXTRACT_16BITS(obj_tptr);
subobj_type = (EXTRACT_16BITS(obj_tptr+2))>>8;
af = (EXTRACT_16BITS(obj_tptr+2))&0x00FF;
@@ -1222,7 +1233,13 @@ rsvp_obj_print(netdissect_options *ndo,
tok2str(af_values, "Unknown", af), af,
subobj_len));
- if(subobj_len == 0)
+ /* In addition to what is explained above, the same spec does not
+ * explicitly say that the same Length field includes the 4-octet
+ * sub-object header, but as long as this while loop implements it
+ * as it does include, let's keep the check below consistent with
+ * the rest of the code.
+ */
+ if(subobj_len < 4 || subobj_len > total_subobj_len)
goto invalid;
switch(subobj_type) {
@@ -1478,12 +1495,12 @@ rsvp_obj_print(netdissect_options *ndo,
case RSVP_OBJ_FASTREROUTE:
/* the differences between c-type 1 and 7 are minor */
obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr;
- bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
switch(rsvp_obj_ctype) {
case RSVP_CTYPE_1: /* new style */
if (obj_tlen < sizeof(struct rsvp_obj_frr_t))
return-1;
+ bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
ident,
(int)obj_ptr.rsvp_obj_frr->setup_prio,
@@ -1502,6 +1519,7 @@ rsvp_obj_print(netdissect_options *ndo,
case RSVP_CTYPE_TUNNEL_IPV4: /* old style */
if (obj_tlen < 16)
return-1;
+ bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
ident,
(int)obj_ptr.rsvp_obj_frr->setup_prio,
diff --git a/freebsd/contrib/tcpdump/print-rt6.c b/freebsd/contrib/tcpdump/print-rt6.c
index 5ab86c6c..09784ab9 100644
--- a/freebsd/contrib/tcpdump/print-rt6.c
+++ b/freebsd/contrib/tcpdump/print-rt6.c
@@ -35,12 +35,12 @@
#include <string.h>
-#include "ip6.h"
-
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
+#include "ip6.h"
+
int
rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2 _U_)
{
@@ -51,13 +51,13 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2
register const struct in6_addr *addr;
dp = (const struct ip6_rthdr *)bp;
- len = dp->ip6r_len;
/* 'ep' points to the end of available data. */
ep = ndo->ndo_snapend;
ND_TCHECK(dp->ip6r_segleft);
+ len = dp->ip6r_len;
ND_PRINT((ndo, "srcrt (len=%d", dp->ip6r_len)); /*)*/
ND_PRINT((ndo, ", type=%d", dp->ip6r_type));
ND_PRINT((ndo, ", segleft=%d", dp->ip6r_segleft));
@@ -68,7 +68,7 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2
dp0 = (const struct ip6_rthdr0 *)dp;
ND_TCHECK(dp0->ip6r0_reserved);
- if (dp0->ip6r0_reserved || ndo->ndo_vflag) {
+ if (EXTRACT_32BITS(dp0->ip6r0_reserved) || ndo->ndo_vflag) {
ND_PRINT((ndo, ", rsv=0x%0x",
EXTRACT_32BITS(&dp0->ip6r0_reserved)));
}
diff --git a/freebsd/contrib/tcpdump/print-rx.c b/freebsd/contrib/tcpdump/print-rx.c
index 46342c2e..e7e369bf 100644
--- a/freebsd/contrib/tcpdump/print-rx.c
+++ b/freebsd/contrib/tcpdump/print-rx.c
@@ -81,12 +81,12 @@
#define PRSFS_ADMINISTER 64 /* Change ACL's */
struct rx_header {
- uint32_t epoch;
- uint32_t cid;
- uint32_t callNumber;
- uint32_t seq;
- uint32_t serial;
- uint8_t type;
+ nd_uint32_t epoch;
+ nd_uint32_t cid;
+ nd_uint32_t callNumber;
+ nd_uint32_t seq;
+ nd_uint32_t serial;
+ nd_uint8_t type;
#define RX_PACKET_TYPE_DATA 1
#define RX_PACKET_TYPE_ACK 2
#define RX_PACKET_TYPE_BUSY 3
@@ -97,7 +97,7 @@ struct rx_header {
#define RX_PACKET_TYPE_DEBUG 8
#define RX_PACKET_TYPE_PARAMS 9
#define RX_PACKET_TYPE_VERSION 13
- uint8_t flags;
+ nd_uint8_t flags;
#define RX_CLIENT_INITIATED 1
#define RX_REQUEST_ACK 2
#define RX_LAST_PACKET 4
@@ -105,10 +105,10 @@ struct rx_header {
#define RX_FREE_PACKET 16
#define RX_SLOW_START_OK 32
#define RX_JUMBO_PACKET 32
- uint8_t userStatus;
- uint8_t securityIndex;
- uint16_t spare; /* How clever: even though the AFS */
- uint16_t serviceId; /* header files indicate that the */
+ nd_uint8_t userStatus;
+ nd_uint8_t securityIndex;
+ nd_uint16_t spare; /* How clever: even though the AFS */
+ nd_uint16_t serviceId; /* header files indicate that the */
}; /* serviceId is first, it's really */
/* encoded _after_ the spare field */
/* I wasted a day figuring that out! */
@@ -696,11 +696,11 @@ rx_cache_insert(netdissect_options *ndo,
if (++rx_cache_next >= RX_CACHE_SIZE)
rx_cache_next = 0;
- rxent->callnum = rxh->callNumber;
+ rxent->callnum = EXTRACT_32BITS(&rxh->callNumber);
UNALIGNED_MEMCPY(&rxent->client, &ip->ip_src, sizeof(uint32_t));
UNALIGNED_MEMCPY(&rxent->server, &ip->ip_dst, sizeof(uint32_t));
rxent->dport = dport;
- rxent->serviceId = rxh->serviceId;
+ rxent->serviceId = EXTRACT_32BITS(&rxh->serviceId);
rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header));
}
@@ -728,10 +728,10 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport,
i = rx_cache_hint;
do {
rxent = &rx_cache[i];
- if (rxent->callnum == rxh->callNumber &&
+ if (rxent->callnum == EXTRACT_32BITS(&rxh->callNumber) &&
rxent->client.s_addr == clip &&
rxent->server.s_addr == sip &&
- rxent->serviceId == rxh->serviceId &&
+ rxent->serviceId == EXTRACT_32BITS(&rxh->serviceId) &&
rxent->dport == sport) {
/* We got a match! */
@@ -1268,6 +1268,7 @@ cb_print(netdissect_options *ndo,
if (j == 0)
ND_PRINT((ndo, " <none!>"));
+ ND_TCHECK_32BITS(bp);
j = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
@@ -2539,6 +2540,10 @@ ubik_print(netdissect_options *ndo,
* gleaned from ubik/ubik_int.xg
*/
+ /* Every function that calls this function first makes a bounds check
+ * for (sizeof(rx_header) + 4) bytes, so long as it remains this way
+ * the line below will not over-read.
+ */
ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
ND_PRINT((ndo, " ubik call %s", tok2str(ubik_req, "op#%d", ubik_op)));
@@ -2583,6 +2588,7 @@ ubik_print(netdissect_options *ndo,
INTOUT();
ND_PRINT((ndo, " length"));
INTOUT();
+ ND_TCHECK_32BITS(bp);
temp = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
tok2str(ubik_lock_types, "type %d", temp);
diff --git a/freebsd/contrib/tcpdump/print-sip.c b/freebsd/contrib/tcpdump/print-sip.c
index 6f968bca..a922d87a 100644
--- a/freebsd/contrib/tcpdump/print-sip.c
+++ b/freebsd/contrib/tcpdump/print-sip.c
@@ -16,7 +16,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
* Turned into common "text protocol" code, which this uses, by
* Guy Harris.
*/
diff --git a/freebsd/contrib/tcpdump/print-sl.c b/freebsd/contrib/tcpdump/print-sl.c
index b318f322..faaa5ba7 100644
--- a/freebsd/contrib/tcpdump/print-sl.c
+++ b/freebsd/contrib/tcpdump/print-sl.c
@@ -137,8 +137,21 @@ sliplink_print(netdissect_options *ndo,
u_int hlen;
dir = p[SLX_DIR];
- ND_PRINT((ndo, dir == SLIPDIR_IN ? "I " : "O "));
+ switch (dir) {
+ case SLIPDIR_IN:
+ ND_PRINT((ndo, "I "));
+ break;
+
+ case SLIPDIR_OUT:
+ ND_PRINT((ndo, "O "));
+ break;
+
+ default:
+ ND_PRINT((ndo, "Invalid direction %d ", dir));
+ dir = -1;
+ break;
+ }
if (ndo->ndo_nflag) {
/* XXX just dump the header */
register int i;
@@ -161,13 +174,21 @@ sliplink_print(netdissect_options *ndo,
* has restored the IP header copy to IPPROTO_TCP.
*/
lastconn = ((const struct ip *)&p[SLX_CHDR])->ip_p;
+ ND_PRINT((ndo, "utcp %d: ", lastconn));
+ if (dir == -1) {
+ /* Direction is bogus, don't use it */
+ return;
+ }
hlen = IP_HL(ip);
hlen += TH_OFF((const struct tcphdr *)&((const int *)ip)[hlen]);
lastlen[dir][lastconn] = length - (hlen << 2);
- ND_PRINT((ndo, "utcp %d: ", lastconn));
break;
default:
+ if (dir == -1) {
+ /* Direction is bogus, don't use it */
+ return;
+ }
if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) {
compressed_sl_print(ndo, &p[SLX_CHDR], ip,
length, dir);
diff --git a/freebsd/contrib/tcpdump/print-slow.c b/freebsd/contrib/tcpdump/print-slow.c
index fe54052f..a5417c0b 100644
--- a/freebsd/contrib/tcpdump/print-slow.c
+++ b/freebsd/contrib/tcpdump/print-slow.c
@@ -21,7 +21,7 @@
* support for the IEEE "slow protocols" LACP, MARKER as per 802.3ad
* OAM as per 802.3ah
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: IEEE "slow protocols" (802.3ad/802.3ah) printer */
diff --git a/freebsd/contrib/tcpdump/print-stp.c b/freebsd/contrib/tcpdump/print-stp.c
index e816cf98..ef7f36c8 100644
--- a/freebsd/contrib/tcpdump/print-stp.c
+++ b/freebsd/contrib/tcpdump/print-stp.c
@@ -262,6 +262,7 @@ stp_print_mstp_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu,
return 1;
}
+ ND_TCHECK(stp_bpdu->flags);
ND_PRINT((ndo, "\n\tport-role %s, ",
tok2str(rstp_obj_port_role_values, "Unknown",
RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags))));
@@ -481,6 +482,7 @@ stp_print(netdissect_options *ndo, const u_char *p, u_int length)
if (stp_bpdu->protocol_version == STP_PROTO_SPB)
{
/* Validate v4 length */
+ ND_TCHECK_16BITS(p + MST_BPDU_VER3_LEN_OFFSET + mstp_len);
spb_len = EXTRACT_16BITS (p + MST_BPDU_VER3_LEN_OFFSET + mstp_len);
spb_len += 2;
if (length < (sizeof(struct stp_bpdu_) + mstp_len + spb_len) ||
diff --git a/freebsd/contrib/tcpdump/print-syslog.c b/freebsd/contrib/tcpdump/print-syslog.c
index a79a1660..81140339 100644
--- a/freebsd/contrib/tcpdump/print-syslog.c
+++ b/freebsd/contrib/tcpdump/print-syslog.c
@@ -5,7 +5,7 @@
#include "rtems-bsd-tcpdump-namespace.h"
#endif /* __rtems__ */
/*
- * Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org>
+ * Copyright (c) 1998-2004 Hannes Gredler <hannes@gredler.at>
* The TCPDUMP project
*
* Redistribution and use in source and binary forms, with or without
diff --git a/freebsd/contrib/tcpdump/print-telnet.c b/freebsd/contrib/tcpdump/print-telnet.c
index 4d5ab780..5d1e52cd 100644
--- a/freebsd/contrib/tcpdump/print-telnet.c
+++ b/freebsd/contrib/tcpdump/print-telnet.c
@@ -448,6 +448,7 @@ telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print)
break;
p++;
}
+ ND_TCHECK(*p);
if (*p != IAC)
goto pktend;
diff --git a/freebsd/contrib/tcpdump/print-tftp.c b/freebsd/contrib/tcpdump/print-tftp.c
index a2577e3f..bf4ac34e 100644
--- a/freebsd/contrib/tcpdump/print-tftp.c
+++ b/freebsd/contrib/tcpdump/print-tftp.c
@@ -52,21 +52,6 @@
#define TFTP_ERROR 05 /* error code */
#define OACK 06 /* option acknowledgement */
-struct tftphdr {
- unsigned short th_opcode; /* packet type */
- union {
- unsigned short tu_block; /* block # */
- unsigned short tu_code; /* error code */
- char tu_stuff[1]; /* request packet stuff */
- } th_u;
- char th_data[1]; /* data or error string */
-};
-
-#define th_block th_u.tu_block
-#define th_code th_u.tu_code
-#define th_stuff th_u.tu_stuff
-#define th_msg th_data
-
/*
* Error codes.
*/
@@ -112,80 +97,75 @@ void
tftp_print(netdissect_options *ndo,
register const u_char *bp, u_int length)
{
- register const struct tftphdr *tp;
register const char *cp;
- register const u_char *p;
register int opcode;
u_int ui;
- tp = (const struct tftphdr *)bp;
-
/* Print length */
ND_PRINT((ndo, " %d", length));
/* Print tftp request type */
if (length < 2)
goto trunc;
- ND_TCHECK(tp->th_opcode);
- opcode = EXTRACT_16BITS(&tp->th_opcode);
+ ND_TCHECK_16BITS(bp);
+ opcode = EXTRACT_16BITS(bp);
cp = tok2str(op2str, "tftp-#%d", opcode);
- length -= 2;
ND_PRINT((ndo, " %s", cp));
/* Bail if bogus opcode */
if (*cp == 't')
return;
+ bp += 2;
+ length -= 2;
switch (opcode) {
case RRQ:
case WRQ:
- p = (const u_char *)tp->th_stuff;
if (length == 0)
goto trunc;
ND_PRINT((ndo, " "));
/* Print filename */
ND_PRINT((ndo, "\""));
- ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+ ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
ND_PRINT((ndo, "\""));
if (ui == 0)
goto trunc;
- p += ui;
+ bp += ui;
length -= ui;
/* Print the mode - RRQ and WRQ only */
if (length == 0)
goto trunc; /* no mode */
ND_PRINT((ndo, " "));
- ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+ ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
if (ui == 0)
goto trunc;
- p += ui;
+ bp += ui;
length -= ui;
/* Print options, if any */
while (length != 0) {
- ND_TCHECK(*p);
- if (*p != '\0')
+ ND_TCHECK(*bp);
+ if (*bp != '\0')
ND_PRINT((ndo, " "));
- ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+ ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
if (ui == 0)
goto trunc;
- p += ui;
+ bp += ui;
length -= ui;
}
break;
case OACK:
- p = (const u_char *)tp->th_stuff;
/* Print options */
while (length != 0) {
- ND_TCHECK(*p);
- if (*p != '\0')
+ ND_TCHECK(*bp);
+ if (*bp != '\0')
ND_PRINT((ndo, " "));
- ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+ ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
if (ui == 0)
goto trunc;
- p += ui;
+ bp += ui;
length -= ui;
}
break;
@@ -194,23 +174,24 @@ tftp_print(netdissect_options *ndo,
case DATA:
if (length < 2)
goto trunc; /* no block number */
- ND_TCHECK(tp->th_block);
- ND_PRINT((ndo, " block %d", EXTRACT_16BITS(&tp->th_block)));
+ ND_TCHECK_16BITS(bp);
+ ND_PRINT((ndo, " block %d", EXTRACT_16BITS(bp)));
break;
case TFTP_ERROR:
/* Print error code string */
if (length < 2)
goto trunc; /* no error code */
- ND_TCHECK(tp->th_code);
+ ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, " %s", tok2str(err2str, "tftp-err-#%d \"",
- EXTRACT_16BITS(&tp->th_code))));
+ EXTRACT_16BITS(bp))));
+ bp += 2;
length -= 2;
/* Print error message string */
if (length == 0)
goto trunc; /* no error message */
ND_PRINT((ndo, " \""));
- ui = fn_printztn(ndo, (const u_char *)tp->th_data, length, ndo->ndo_snapend);
+ ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
ND_PRINT((ndo, "\""));
if (ui == 0)
goto trunc;
diff --git a/freebsd/contrib/tcpdump/print-vqp.c b/freebsd/contrib/tcpdump/print-vqp.c
index 7c4e40da..5a7ca2d1 100644
--- a/freebsd/contrib/tcpdump/print-vqp.c
+++ b/freebsd/contrib/tcpdump/print-vqp.c
@@ -32,6 +32,7 @@
#include "netdissect.h"
#include "extract.h"
#include "addrtoname.h"
+#include "ether.h"
#define VQP_VERSION 1
#define VQP_EXTRACT_VERSION(x) ((x)&0xFF)
@@ -111,13 +112,15 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l
const u_char *tptr;
uint16_t vqp_obj_len;
uint32_t vqp_obj_type;
- int tlen;
+ u_int tlen;
uint8_t nitems;
tptr=pptr;
tlen = len;
vqp_common_header = (const struct vqp_common_header_t *)pptr;
ND_TCHECK(*vqp_common_header);
+ if (sizeof(struct vqp_common_header_t) > tlen)
+ goto trunc;
/*
* Sanity checking of the header.
@@ -157,6 +160,9 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l
while (nitems > 0 && tlen > 0) {
vqp_obj_tlv = (const struct vqp_obj_tlv_t *)tptr;
+ ND_TCHECK(*vqp_obj_tlv);
+ if (sizeof(struct vqp_obj_tlv_t) > tlen)
+ goto trunc;
vqp_obj_type = EXTRACT_32BITS(vqp_obj_tlv->obj_type);
vqp_obj_len = EXTRACT_16BITS(vqp_obj_tlv->obj_length);
tptr+=sizeof(struct vqp_obj_tlv_t);
@@ -173,9 +179,13 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l
/* did we capture enough for fully decoding the object ? */
ND_TCHECK2(*tptr, vqp_obj_len);
+ if (vqp_obj_len > tlen)
+ goto trunc;
switch(vqp_obj_type) {
case VQP_OBJ_IP_ADDRESS:
+ if (vqp_obj_len != 4)
+ goto trunc;
ND_PRINT((ndo, "%s (0x%08x)", ipaddr_string(ndo, tptr), EXTRACT_32BITS(tptr)));
break;
/* those objects have similar semantics - fall through */
@@ -188,6 +198,8 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l
/* those objects have similar semantics - fall through */
case VQP_OBJ_MAC_ADDRESS:
case VQP_OBJ_MAC_NULL:
+ if (vqp_obj_len != ETHER_ADDR_LEN)
+ goto trunc;
ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr)));
break;
default:
diff --git a/freebsd/contrib/tcpdump/print-vtp.c b/freebsd/contrib/tcpdump/print-vtp.c
index 18e2d925..8f8d236b 100644
--- a/freebsd/contrib/tcpdump/print-vtp.c
+++ b/freebsd/contrib/tcpdump/print-vtp.c
@@ -19,9 +19,8 @@
* FOR A PARTICULAR PURPOSE.
*
* Reference documentation:
- * http://www.cisco.com/en/US/tech/tk389/tk689/technologies_tech_note09186a0080094c52.shtml
- * http://www.cisco.com/warp/public/473/21.html
- * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm
+ * http://www.cisco.com/c/en/us/support/docs/lan-switching/vtp/10558-21.html
+ * http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm
*
* Original code ode by Carles Kishimoto <carles.kishimoto@gmail.com>
*/
@@ -42,7 +41,7 @@
#define VTP_DOMAIN_NAME_LEN 32
#define VTP_MD5_DIGEST_LEN 16
#define VTP_UPDATE_TIMESTAMP_LEN 12
-#define VTP_VLAN_INFO_OFFSET 12
+#define VTP_VLAN_INFO_FIXED_PART_LEN 12 /* length of VLAN info before VLAN name */
#define VTP_SUMMARY_ADV 0x01
#define VTP_SUBSET_ADV 0x02
@@ -229,6 +228,7 @@ vtp_print (netdissect_options *ndo,
*
*/
+ ND_TCHECK_32BITS(tptr);
ND_PRINT((ndo, ", Config Rev %x", EXTRACT_32BITS(tptr)));
/*
@@ -249,6 +249,7 @@ vtp_print (netdissect_options *ndo,
tptr += 4;
while (tptr < (pptr+length)) {
+ ND_TCHECK_8BITS(tptr);
len = *tptr;
if (len == 0)
break;
@@ -256,6 +257,8 @@ vtp_print (netdissect_options *ndo,
ND_TCHECK2(*tptr, len);
vtp_vlan = (const struct vtp_vlan_*)tptr;
+ if (len < VTP_VLAN_INFO_FIXED_PART_LEN)
+ goto trunc;
ND_TCHECK(*vtp_vlan);
ND_PRINT((ndo, "\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name ",
tok2str(vtp_vlan_status,"Unknown",vtp_vlan->status),
@@ -263,22 +266,33 @@ vtp_print (netdissect_options *ndo,
EXTRACT_16BITS(&vtp_vlan->vlanid),
EXTRACT_16BITS(&vtp_vlan->mtu),
EXTRACT_32BITS(&vtp_vlan->index)));
- fn_printzp(ndo, tptr + VTP_VLAN_INFO_OFFSET, vtp_vlan->name_len, NULL);
-
- /*
- * Vlan names are aligned to 32-bit boundaries.
- */
- len -= VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4);
- tptr += VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4);
+ len -= VTP_VLAN_INFO_FIXED_PART_LEN;
+ tptr += VTP_VLAN_INFO_FIXED_PART_LEN;
+ if (len < 4*((vtp_vlan->name_len + 3)/4))
+ goto trunc;
+ ND_TCHECK2(*tptr, vtp_vlan->name_len);
+ fn_printzp(ndo, tptr, vtp_vlan->name_len, NULL);
+
+ /*
+ * Vlan names are aligned to 32-bit boundaries.
+ */
+ len -= 4*((vtp_vlan->name_len + 3)/4);
+ tptr += 4*((vtp_vlan->name_len + 3)/4);
/* TLV information follows */
while (len > 0) {
/*
- * Cisco specs says 2 bytes for type + 2 bytes for length, take only 1
- * See: http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm
+ * Cisco specs say 2 bytes for type + 2 bytes for length;
+ * see http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm
+ * However, actual packets on the wire appear to use 1
+ * byte for the type and 1 byte for the length, so that's
+ * what we do.
*/
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK2(*tptr, 2);
type = *tptr;
tlv_len = *(tptr+1);
@@ -286,59 +300,65 @@ vtp_print (netdissect_options *ndo,
tok2str(vtp_vlan_tlv_values, "Unknown", type),
type));
- /*
- * infinite loop check
- */
- if (type == 0 || tlv_len == 0) {
+ if (len < tlv_len * 2 + 2) {
+ ND_PRINT((ndo, " (TLV goes past the end of the packet)"));
return;
}
-
ND_TCHECK2(*tptr, tlv_len * 2 +2);
- tlv_value = EXTRACT_16BITS(tptr+2);
-
- switch (type) {
- case VTP_VLAN_STE_HOP_COUNT:
- ND_PRINT((ndo, ", %u", tlv_value));
- break;
-
- case VTP_VLAN_PRUNING:
- ND_PRINT((ndo, ", %s (%u)",
- tlv_value == 1 ? "Enabled" : "Disabled",
- tlv_value));
- break;
-
- case VTP_VLAN_STP_TYPE:
- ND_PRINT((ndo, ", %s (%u)",
- tok2str(vtp_stp_type_values, "Unknown", tlv_value),
- tlv_value));
- break;
-
- case VTP_VLAN_BRIDGE_TYPE:
- ND_PRINT((ndo, ", %s (%u)",
- tlv_value == 1 ? "SRB" : "SRT",
- tlv_value));
- break;
-
- case VTP_VLAN_BACKUP_CRF_MODE:
- ND_PRINT((ndo, ", %s (%u)",
- tlv_value == 1 ? "Backup" : "Not backup",
- tlv_value));
- break;
-
- /*
- * FIXME those are the defined TLVs that lack a decoder
- * you are welcome to contribute code ;-)
- */
-
- case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER:
- case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER:
- case VTP_VLAN_PARENT_VLAN:
- case VTP_VLAN_TRANS_BRIDGED_VLAN:
- case VTP_VLAN_ARP_HOP_COUNT:
- default:
- print_unknown_data(ndo, tptr, "\n\t\t ", 2 + tlv_len*2);
- break;
+ /*
+ * We assume the value is a 2-byte integer; the length is
+ * in units of 16-bit words.
+ */
+ if (tlv_len != 1) {
+ ND_PRINT((ndo, " (invalid TLV length %u != 1)", tlv_len));
+ return;
+ } else {
+ tlv_value = EXTRACT_16BITS(tptr+2);
+
+ switch (type) {
+ case VTP_VLAN_STE_HOP_COUNT:
+ ND_PRINT((ndo, ", %u", tlv_value));
+ break;
+
+ case VTP_VLAN_PRUNING:
+ ND_PRINT((ndo, ", %s (%u)",
+ tlv_value == 1 ? "Enabled" : "Disabled",
+ tlv_value));
+ break;
+
+ case VTP_VLAN_STP_TYPE:
+ ND_PRINT((ndo, ", %s (%u)",
+ tok2str(vtp_stp_type_values, "Unknown", tlv_value),
+ tlv_value));
+ break;
+
+ case VTP_VLAN_BRIDGE_TYPE:
+ ND_PRINT((ndo, ", %s (%u)",
+ tlv_value == 1 ? "SRB" : "SRT",
+ tlv_value));
+ break;
+
+ case VTP_VLAN_BACKUP_CRF_MODE:
+ ND_PRINT((ndo, ", %s (%u)",
+ tlv_value == 1 ? "Backup" : "Not backup",
+ tlv_value));
+ break;
+
+ /*
+ * FIXME those are the defined TLVs that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+
+ case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER:
+ case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER:
+ case VTP_VLAN_PARENT_VLAN:
+ case VTP_VLAN_TRANS_BRIDGED_VLAN:
+ case VTP_VLAN_ARP_HOP_COUNT:
+ default:
+ print_unknown_data(ndo, tptr, "\n\t\t ", 2 + tlv_len*2);
+ break;
+ }
}
len -= 2 + tlv_len*2;
tptr += 2 + tlv_len*2;
diff --git a/freebsd/contrib/tcpdump/print-wb.c b/freebsd/contrib/tcpdump/print-wb.c
index 60892bbd..aeab01c3 100644
--- a/freebsd/contrib/tcpdump/print-wb.c
+++ b/freebsd/contrib/tcpdump/print-wb.c
@@ -269,9 +269,8 @@ wb_prep(netdissect_options *ndo,
const u_char *ep = ndo->ndo_snapend;
ND_PRINT((ndo, " wb-prep:"));
- if (len < sizeof(*prep)) {
+ if (len < sizeof(*prep) || !ND_TTEST(*prep))
return (-1);
- }
n = EXTRACT_32BITS(&prep->pp_n);
ps = (const struct pgstate *)(prep + 1);
while (--n >= 0 && ND_TTEST(*ps)) {
@@ -425,31 +424,37 @@ wb_print(netdissect_options *ndo,
case PT_ID:
if (wb_id(ndo, (const struct pkt_id *)(ph + 1), len) >= 0)
return;
+ ND_PRINT((ndo, "%s", tstr));
break;
case PT_RREQ:
if (wb_rreq(ndo, (const struct pkt_rreq *)(ph + 1), len) >= 0)
return;
+ ND_PRINT((ndo, "%s", tstr));
break;
case PT_RREP:
if (wb_rrep(ndo, (const struct pkt_rrep *)(ph + 1), len) >= 0)
return;
+ ND_PRINT((ndo, "%s", tstr));
break;
case PT_DRAWOP:
if (wb_drawop(ndo, (const struct pkt_dop *)(ph + 1), len) >= 0)
return;
+ ND_PRINT((ndo, "%s", tstr));
break;
case PT_PREQ:
if (wb_preq(ndo, (const struct pkt_preq *)(ph + 1), len) >= 0)
return;
+ ND_PRINT((ndo, "%s", tstr));
break;
case PT_PREP:
if (wb_prep(ndo, (const struct pkt_prep *)(ph + 1), len) >= 0)
return;
+ ND_PRINT((ndo, "%s", tstr));
break;
default:
diff --git a/freebsd/contrib/tcpdump/print-zephyr.c b/freebsd/contrib/tcpdump/print-zephyr.c
index f44c3057..630c7095 100644
--- a/freebsd/contrib/tcpdump/print-zephyr.c
+++ b/freebsd/contrib/tcpdump/print-zephyr.c
@@ -82,30 +82,41 @@ static const struct tok z_types[] = {
{ Z_PACKET_SERVACK, "serv-ack" },
{ Z_PACKET_SERVNAK, "serv-nak" },
{ Z_PACKET_CLIENTACK, "client-ack" },
- { Z_PACKET_STAT, "stat" }
+ { Z_PACKET_STAT, "stat" },
+ { 0, NULL }
};
static char z_buf[256];
static const char *
-parse_field(netdissect_options *ndo, const char **pptr, int *len)
+parse_field(netdissect_options *ndo, const char **pptr, int *len, int *truncated)
{
const char *s;
- if (*len <= 0 || !pptr || !*pptr)
- return NULL;
- if (*pptr > (const char *) ndo->ndo_snapend)
- return NULL;
-
+ /* Start of string */
s = *pptr;
- while (*pptr <= (const char *) ndo->ndo_snapend && *len >= 0 && **pptr) {
+ /* Scan for the NUL terminator */
+ for (;;) {
+ if (*len == 0) {
+ /* Ran out of packet data without finding it */
+ return NULL;
+ }
+ if (!ND_TTEST(**pptr)) {
+ /* Ran out of captured data without finding it */
+ *truncated = 1;
+ return NULL;
+ }
+ if (**pptr == '\0') {
+ /* Found it */
+ break;
+ }
+ /* Keep scanning */
(*pptr)++;
(*len)--;
}
+ /* Skip the NUL terminator */
(*pptr)++;
(*len)--;
- if (*len < 0 || *pptr > (const char *) ndo->ndo_snapend)
- return NULL;
return s;
}
@@ -144,6 +155,7 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length)
int parselen = length;
const char *s;
int lose = 0;
+ int truncated = 0;
/* squelch compiler warnings */
@@ -154,8 +166,9 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length)
z.sender = 0;
z.recipient = 0;
-#define PARSE_STRING \
- s = parse_field(ndo, &parse, &parselen); \
+#define PARSE_STRING \
+ s = parse_field(ndo, &parse, &parselen, &truncated); \
+ if (truncated) goto trunc; \
if (!s) lose = 1;
#define PARSE_FIELD_INT(field) \
@@ -188,10 +201,8 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length)
PARSE_FIELD_INT(z.multi);
PARSE_FIELD_STR(z.multi_uid);
- if (lose) {
- ND_PRINT((ndo, " [|zephyr] (%d)", length));
- return;
- }
+ if (lose)
+ goto trunc;
ND_PRINT((ndo, " zephyr"));
if (strncmp(z.version+4, "0.2", 3)) {
@@ -323,6 +334,11 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length)
ND_PRINT((ndo, " to %s", z_triple(z.class, z.inst, z.recipient)));
if (*z.opcode)
ND_PRINT((ndo, " op %s", z.opcode));
+ return;
+
+trunc:
+ ND_PRINT((ndo, " [|zephyr] (%d)", length));
+ return;
}
#ifdef __rtems__
#include "rtems-bsd-tcpdump-print-zephyr-data.h"
diff --git a/freebsd/contrib/tcpdump/print.c b/freebsd/contrib/tcpdump/print.c
index 767a235e..2bbfc04b 100644
--- a/freebsd/contrib/tcpdump/print.c
+++ b/freebsd/contrib/tcpdump/print.c
@@ -232,23 +232,16 @@ static const struct printer printers[] = {
static void ndo_default_print(netdissect_options *ndo, const u_char *bp,
u_int length);
-static void ndo_error(netdissect_options *ndo, const char *fmt, ...)
- __attribute__((noreturn))
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 2, 3)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
-static void ndo_warning(netdissect_options *ndo, const char *fmt, ...)
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 2, 3)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
-
-static int ndo_printf(netdissect_options *ndo, const char *fmt, ...)
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute ((format (printf, 2, 3)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
+static void ndo_error(netdissect_options *ndo,
+ FORMAT_STRING(const char *fmt), ...)
+ NORETURN PRINTFLIKE(2, 3);
+static void ndo_warning(netdissect_options *ndo,
+ FORMAT_STRING(const char *fmt), ...)
+ PRINTFLIKE(2, 3);
+
+static int ndo_printf(netdissect_options *ndo,
+ FORMAT_STRING(const char *fmt), ...)
+ PRINTFLIKE(2, 3);
void
init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask,
diff --git a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-addrtoname-data.h b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-addrtoname-data.h
index 19986243..9b6b1d8c 100644
--- a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-addrtoname-data.h
+++ b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-addrtoname-data.h
@@ -2,7 +2,7 @@
#include <rtems/linkersets.h>
#include "rtems-bsd-tcpdump-data.h"
/* addrtoname.c */
-RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static struct enamemem bytestringtable[]);
+RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static struct bsnamemem bytestringtable[]);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static struct enamemem enametable[]);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static struct enamemem nsaptable[]);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static struct h6namemem h6nametable[]);
diff --git a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h
index b0ed4329..bb4ed207 100644
--- a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h
+++ b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h
@@ -46,6 +46,7 @@
#define in_cksum _bsd_tcpdump_in_cksum
#define in_cksum_shouldbe _bsd_tcpdump_in_cksum_shouldbe
/* ipproto.c */
+#define netdb_protoname _bsd_tcpdump_netdb_protoname
/* l2vpn.c */
/* machdep.c */
#define abort_on_misalignment _bsd_tcpdump_abort_on_misalignment
diff --git a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-tcpdump-data.h b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-tcpdump-data.h
index 17b75076..126e0f46 100644
--- a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-tcpdump-data.h
+++ b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-tcpdump-data.h
@@ -4,7 +4,6 @@
/* tcpdump.c */
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static char *zflag);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int Bflag);
-RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int Cflag);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int Cflag_count);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int Dflag);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int Gflag);
@@ -23,6 +22,7 @@ RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int infoprint);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int jflag);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int pflag);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int supports_monitor_mode);
+RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static long int Cflag);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static pcap_t *pd);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static time_t Gflag_time);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static u_int packets_captured);
diff --git a/freebsd/contrib/tcpdump/signature.c b/freebsd/contrib/tcpdump/signature.c
index 2e654aea..861f59cd 100644
--- a/freebsd/contrib/tcpdump/signature.c
+++ b/freebsd/contrib/tcpdump/signature.c
@@ -18,7 +18,7 @@
*
* Functions for signature and digest verification.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/freebsd/contrib/tcpdump/signature.h b/freebsd/contrib/tcpdump/signature.h
index 239ee3e8..bbb63edf 100644
--- a/freebsd/contrib/tcpdump/signature.h
+++ b/freebsd/contrib/tcpdump/signature.h
@@ -12,7 +12,7 @@
*
* Functions for signature and digest verification.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* for netdissect_options */
diff --git a/freebsd/contrib/tcpdump/smbutil.c b/freebsd/contrib/tcpdump/smbutil.c
index b1f9b098..5ed188b6 100644
--- a/freebsd/contrib/tcpdump/smbutil.c
+++ b/freebsd/contrib/tcpdump/smbutil.c
@@ -243,6 +243,7 @@ name_len(netdissect_options *ndo,
return(-1); /* name goes past the end of the buffer */
ND_TCHECK2(*s, 1);
s += (*s) + 1;
+ ND_TCHECK2(*s, 1);
}
return(PTR_DIFF(s, s0) + 1);
diff --git a/freebsd/contrib/tcpdump/tcpdump.c b/freebsd/contrib/tcpdump/tcpdump.c
index 52fd2260..26761ad7 100644
--- a/freebsd/contrib/tcpdump/tcpdump.c
+++ b/freebsd/contrib/tcpdump/tcpdump.c
@@ -156,7 +156,7 @@ The Regents of the University of California. All rights reserved.\n";
#endif
static int Bflag; /* buffer size */
-static int Cflag; /* rotate dump files after this many bytes */
+static long Cflag; /* rotate dump files after this many bytes */
static int Cflag_count; /* Keep track of which file number we're writing */
static int Dflag; /* list available devices and exit */
/*
@@ -204,26 +204,17 @@ cap_channel_t *capdns;
#endif
/* Forwards */
-static void error(const char *, ...)
- __attribute__((noreturn))
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 1, 2)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
-static void warning(const char *, ...)
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 1, 2)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
-static void exit_tcpdump(int) __attribute__((noreturn));
+static void error(FORMAT_STRING(const char *), ...) NORETURN PRINTFLIKE(1, 2);
+static void warning(FORMAT_STRING(const char *), ...) PRINTFLIKE(1, 2);
+static void exit_tcpdump(int) NORETURN;
static RETSIGTYPE cleanup(int);
static RETSIGTYPE child_cleanup(int);
static void print_version(void);
static void print_usage(void);
-static void show_tstamp_types_and_exit(pcap_t *, const char *device) __attribute__((noreturn));
-static void show_dlts_and_exit(pcap_t *, const char *device) __attribute__((noreturn));
+static void show_tstamp_types_and_exit(pcap_t *, const char *device) NORETURN;
+static void show_dlts_and_exit(pcap_t *, const char *device) NORETURN;
#ifdef HAVE_PCAP_FINDALLDEVS
-static void show_devices_and_exit (void) __attribute__((noreturn));
+static void show_devices_and_exit (void) NORETURN;
#endif
static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
@@ -2063,10 +2054,10 @@ main(int argc, char **argv)
/*
* The various libpcap devices use a combination of
- * read (bpf), ioctl (bpf, netmap), poll (netmap).
- * Grant the relevant access rights, sorted by name.
+ * read (bpf), ioctl (bpf, netmap), poll (netmap)
+ * so we add the relevant access rights.
*/
- cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ);
+ cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_EVENT);
if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
errno != ENOSYS) {
error("unable to limit pcap descriptor");
@@ -2819,6 +2810,14 @@ print_version(void)
smi_version_string = nd_smi_version_string();
if (smi_version_string != NULL)
(void)fprintf (stderr, "SMI-library: %s\n", smi_version_string);
+
+#if defined(__SANITIZE_ADDRESS__)
+ (void)fprintf (stderr, "Compiled with AddressSanitizer/GCC.\n");
+#elif defined(__has_feature)
+# if __has_feature(address_sanitizer)
+ (void)fprintf (stderr, "Compiled with AddressSanitizer/CLang.\n");
+# endif
+#endif /* __SANITIZE_ADDRESS__ or __has_feature */
}
USES_APPLE_RST
diff --git a/freebsd/contrib/tcpdump/util-print.c b/freebsd/contrib/tcpdump/util-print.c
index a4b482ff..7a5269dd 100644
--- a/freebsd/contrib/tcpdump/util-print.c
+++ b/freebsd/contrib/tcpdump/util-print.c
@@ -27,7 +27,7 @@
/*
* txtproto_print() derived from original code by Hannes Gredler
- * (hannes@juniper.net):
+ * (hannes@gredler.at):
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code
@@ -527,8 +527,9 @@ static char *
bittok2str_internal(register const struct tok *lp, register const char *fmt,
register u_int v, const char *sep)
{
- static char buf[256]; /* our stringbuffer */
- int buflen=0;
+ static char buf[1024+1]; /* our string buffer */
+ char *bufp = buf;
+ size_t space_left = sizeof(buf), string_size;
register u_int rotbit; /* this is the bit we rotate through all bitpositions */
register u_int tokval;
const char * sepstr = "";
@@ -543,8 +544,20 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt,
*/
if (tokval == (v&rotbit)) {
/* ok we have found something */
- buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s",
- sepstr, lp->s);
+ if (space_left <= 1)
+ return (buf); /* only enough room left for NUL, if that */
+ string_size = strlcpy(bufp, sepstr, space_left);
+ if (string_size >= space_left)
+ return (buf); /* we ran out of room */
+ bufp += string_size;
+ space_left -= string_size;
+ if (space_left <= 1)
+ return (buf); /* only enough room left for NUL, if that */
+ string_size = strlcpy(bufp, lp->s, space_left);
+ if (string_size >= space_left)
+ return (buf); /* we ran out of room */
+ bufp += string_size;
+ space_left -= string_size;
sepstr = sep;
break;
}
@@ -553,7 +566,7 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt,
lp++;
}
- if (buflen == 0)
+ if (bufp == buf)
/* bummer - lets print the "unknown" message as advised in the fmt string if we got one */
(void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v);
return (buf);
@@ -908,7 +921,7 @@ safeputs(netdissect_options *ndo,
{
u_int idx = 0;
- while (*s && idx < maxlen) {
+ while (idx < maxlen && *s) {
safeputchar(ndo, *s);
idx++;
s++;