X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/ed85e20e4d6a27d5405f37366dd34b64c10a9211..0845bc813c1cc48b18cdefff0b387c110647463c:/print-mobility.c diff --git a/print-mobility.c b/print-mobility.c index 806346c5..58dabe11 100644 --- a/print-mobility.c +++ b/print-mobility.c @@ -27,7 +27,6 @@ * SUCH DAMAGE. */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -36,9 +35,9 @@ #include #include "ip6.h" -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" /* Mobility header */ struct ip6_mobility { @@ -49,7 +48,7 @@ struct ip6_mobility { uint16_t ip6m_cksum; /* sum of IPv6 pseudo-header and MH */ union { uint16_t ip6m_un_data16[1]; /* type-specific field */ - uint8_t ip6m_un_data8[2]; /* type-specific fiedl */ + uint8_t ip6m_un_data8[2]; /* type-specific field */ } ip6m_dataun; }; @@ -69,11 +68,30 @@ struct ip6_mobility { #define IP6M_BINDING_UPDATE 5 /* Binding Update */ #define IP6M_BINDING_ACK 6 /* Binding Acknowledgement */ #define IP6M_BINDING_ERROR 7 /* Binding Error */ +#define IP6M_MAX 7 -/* XXX: unused */ -#define IP6MOPT_BU_MINLEN 10 -#define IP6MOPT_BA_MINLEN 13 -#define IP6MOPT_BR_MINLEN 2 +static const struct tok ip6m_str[] = { + { IP6M_BINDING_REQUEST, "BRR" }, + { IP6M_HOME_TEST_INIT, "HoTI" }, + { IP6M_CAREOF_TEST_INIT, "CoTI" }, + { IP6M_HOME_TEST, "HoT" }, + { IP6M_CAREOF_TEST, "CoT" }, + { IP6M_BINDING_UPDATE, "BU" }, + { IP6M_BINDING_ACK, "BA" }, + { IP6M_BINDING_ERROR, "BE" }, + { 0, NULL } +}; + +static const unsigned ip6m_hdrlen[IP6M_MAX + 1] = { + IP6M_MINLEN, /* IP6M_BINDING_REQUEST */ + IP6M_MINLEN + 8, /* IP6M_HOME_TEST_INIT */ + IP6M_MINLEN + 8, /* IP6M_CAREOF_TEST_INIT */ + IP6M_MINLEN + 16, /* IP6M_HOME_TEST */ + IP6M_MINLEN + 16, /* IP6M_CAREOF_TEST */ + IP6M_MINLEN + 4, /* IP6M_BINDING_UPDATE */ + IP6M_MINLEN + 4, /* IP6M_BINDING_ACK */ + IP6M_MINLEN + 16, /* IP6M_BINDING_ERROR */ +}; /* Mobility Header Options */ #define IP6MOPT_MINLEN 2 @@ -95,16 +113,20 @@ mobility_opt_print(netdissect_options *ndo, unsigned i, optlen; for (i = 0; i < len; i += optlen) { + ND_TCHECK(bp[i]); if (bp[i] == IP6MOPT_PAD1) optlen = 1; else { - if (i + 1 < len) + if (i + 1 < len) { + ND_TCHECK(bp[i + 1]); optlen = bp[i + 1] + 2; + } else goto trunc; } if (i + optlen > len) goto trunc; + ND_TCHECK(bp[i + optlen]); switch (bp[i]) { case IP6MOPT_PAD1: @@ -176,7 +198,7 @@ mobility_print(netdissect_options *ndo, unsigned mhlen, hlen; uint8_t type; - mh = (struct ip6_mobility *)bp; + mh = (const struct ip6_mobility *)bp; /* 'ep' points to the end of available data. */ ep = ndo->ndo_snapend; @@ -203,15 +225,17 @@ mobility_print(netdissect_options *ndo, ND_TCHECK(mh->ip6m_type); type = mh->ip6m_type; + if (type <= IP6M_MAX && mhlen < ip6m_hdrlen[type]) { + ND_PRINT((ndo, "(header length %u is too small for type %u)", mhlen, type)); + goto trunc; + } + ND_PRINT((ndo, "mobility: %s", tok2str(ip6m_str, "type-#%u", type))); switch (type) { case IP6M_BINDING_REQUEST: - ND_PRINT((ndo, "mobility: BRR")); hlen = IP6M_MINLEN; break; case IP6M_HOME_TEST_INIT: case IP6M_CAREOF_TEST_INIT: - ND_PRINT((ndo, "mobility: %soTI", - type == IP6M_HOME_TEST_INIT ? "H" : "C")); hlen = IP6M_MINLEN; if (ndo->ndo_vflag) { ND_TCHECK2(*mh, hlen + 8); @@ -224,8 +248,6 @@ mobility_print(netdissect_options *ndo, break; case IP6M_HOME_TEST: case IP6M_CAREOF_TEST: - ND_PRINT((ndo, "mobility: %soT", - type == IP6M_HOME_TEST ? "H" : "C")); ND_TCHECK(mh->ip6m_data16[0]); ND_PRINT((ndo, " nonce id=0x%x", EXTRACT_16BITS(&mh->ip6m_data16[0]))); hlen = IP6M_MINLEN; @@ -247,7 +269,6 @@ mobility_print(netdissect_options *ndo, hlen += 8; break; case IP6M_BINDING_UPDATE: - ND_PRINT((ndo, "mobility: BU")); ND_TCHECK(mh->ip6m_data16[0]); ND_PRINT((ndo, " seq#=%u", EXTRACT_16BITS(&mh->ip6m_data16[0]))); hlen = IP6M_MINLEN; @@ -272,7 +293,6 @@ mobility_print(netdissect_options *ndo, hlen += 2; break; case IP6M_BINDING_ACK: - ND_PRINT((ndo, "mobility: BA")); ND_TCHECK(mh->ip6m_data8[0]); ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0])); if (mh->ip6m_data8[1] & 0x80) @@ -288,7 +308,6 @@ mobility_print(netdissect_options *ndo, hlen += 2; break; case IP6M_BINDING_ERROR: - ND_PRINT((ndo, "mobility: BE")); ND_TCHECK(mh->ip6m_data8[0]); ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0])); /* Reserved */ @@ -298,7 +317,7 @@ mobility_print(netdissect_options *ndo, hlen += 16; break; default: - ND_PRINT((ndo, "mobility: type-#%u len=%u", type, mh->ip6m_len)); + ND_PRINT((ndo, " len=%u", mh->ip6m_len)); return(mhlen); break; }