/* \summary: Multicast Source Discovery Protocol (MSDP) printer */
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
#include "netdissect-stdinc.h"
+#define ND_LONGJMP_FROM_TCHECK
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
unsigned int type, len;
ndo->ndo_protocol = "msdp";
- ND_TCHECK_3(sp);
+ ND_PRINT(": ");
+ nd_print_protocol(ndo);
/* See if we think we're at the beginning of a compound packet */
type = GET_U_1(sp);
len = GET_BE_U_2(sp + 1);
- if (len > 1500 || len < 3 || type == 0 || type > MSDP_TYPE_MAX)
- goto trunc; /* not really truncated, but still not decodable */
- ND_PRINT(" msdp:");
+ ND_ICHECK_U(len, >, 1500);
+ ND_ICHECK_U(len, <, 3);
+ ND_ICHECK_U(type, ==, 0);
+ ND_ICHECK_U(type, >, MSDP_TYPE_MAX);
while (length != 0) {
- ND_TCHECK_3(sp);
+ unsigned int entry_count;
+
+ ND_ICHECK_U(length, <, 3);
type = GET_U_1(sp);
len = GET_BE_U_2(sp + 1);
if (len > 1400 || ndo->ndo_vflag)
ND_PRINT(" [len %u]", len);
- if (len < 3)
- goto trunc;
- if (length < len)
- goto trunc;
- sp += 3;
- length -= 3;
+ ND_ICHECK_U(len, <, 3);
+ ND_ICHECK_U(length, <, len);
switch (type) {
case 1: /* IPv4 Source-Active */
case 3: /* IPv4 Source-Active Response */
ND_PRINT(" SA");
else
ND_PRINT(" SA-Response");
- ND_TCHECK_1(sp);
- ND_PRINT(" %u entries", GET_U_1(sp));
- if ((u_int)((GET_U_1(sp) * 12) + 8) < len) {
+
+ /* Entry Count */
+ ND_ICHECK_U(len, <, 4);
+ entry_count = GET_U_1(sp + 3);
+ ND_PRINT(" %u entries", entry_count);
+
+ /* RP Address */
+ ND_ICHECK_U(len, <, 8);
+ /* XXX -print this based on ndo_vflag? */
+ ND_TCHECK_4(sp + 4);
+
+ /* Entries */
+ ND_TCHECK_LEN(sp + 8, entry_count*12);
+
+ if (len > (8 + entry_count*12)) {
+ /* Encapsulated IP packet */
ND_PRINT(" [w/data]");
if (ndo->ndo_vflag > 1) {
ND_PRINT(" ");
- ip_print(ndo, sp +
- GET_U_1(sp) * 12 + 8 - 3,
- len - (GET_U_1(sp) * 12 + 8));
+ ip_print(ndo, sp + (8 + entry_count*12),
+ len - (8 + entry_count*12));
}
}
break;
case 2:
+ /* draft-ietf-msdp-spec-13 */
ND_PRINT(" SA-Request");
- ND_TCHECK_5(sp);
- ND_PRINT(" for %s", GET_IPADDR_STRING(sp + 1));
+
+ /* Reserved */
+ ND_ICHECK_U(len, <, 4);
+ ND_TCHECK_1(sp + 3);
+
+ /* Group Address */
+ ND_ICHECK_U(len, <, 8);
+ if (len != 8)
+ ND_PRINT("[len=%u] ", len);
+ ND_PRINT(" for %s", GET_IPADDR_STRING(sp + 4));
break;
case 4:
ND_PRINT(" Keepalive");
ND_PRINT(" [type=%u len=%u]", type, len);
break;
}
- sp += (len - 3);
- length -= (len - 3);
+ ND_TCHECK_LEN(sp, len);
+ sp += len;
+ length -= len;
}
return;
-trunc:
- nd_print_trunc(ndo);
+
+invalid:
+ nd_print_invalid(ndo);
+
}