static void gre_print_0(netdissect_options *, const u_char *, u_int);
static void gre_print_1(netdissect_options *, const u_char *, u_int);
-static void gre_sre_print(netdissect_options *, uint16_t, uint8_t, uint8_t, const u_char *, u_int);
-static void gre_sre_ip_print(netdissect_options *, uint8_t, uint8_t, const u_char *, u_int);
-static void gre_sre_asn_print(netdissect_options *, uint8_t, uint8_t, const u_char *, u_int);
+static int gre_sre_print(netdissect_options *, uint16_t, uint8_t, uint8_t, const u_char *, u_int);
+static int gre_sre_ip_print(netdissect_options *, uint8_t, uint8_t, const u_char *, u_int);
+static int gre_sre_asn_print(netdissect_options *, uint8_t, uint8_t, const u_char *, u_int);
void
gre_print(netdissect_options *ndo, const u_char *bp, u_int length)
{
u_int len = length, vers;
- if (len < 2) {
- ND_PRINT((ndo, "%s", tstr));
- return;
- }
+ ND_TCHECK2(*bp, 2);
+ if (len < 2)
+ goto trunc;
vers = EXTRACT_16BITS(bp) & GRE_VERS_MASK;
ND_PRINT((ndo, "GREv%u",vers));
ND_PRINT((ndo, " ERROR: unknown-version"));
break;
}
+ return;
+
+trunc:
+ ND_PRINT((ndo, "%s", tstr));
+ return;
}
static void
len -= 2;
bp += 2;
+ ND_TCHECK2(*bp, 2);
if (len < 2)
goto trunc;
prot = EXTRACT_16BITS(bp);
bp += 2;
if ((flags & GRE_CP) | (flags & GRE_RP)) {
+ ND_TCHECK2(*bp, 2);
if (len < 2)
goto trunc;
if (ndo->ndo_vflag)
bp += 2;
len -= 2;
+ ND_TCHECK2(*bp, 2);
if (len < 2)
goto trunc;
ND_PRINT((ndo, ", off 0x%x", EXTRACT_16BITS(bp)));
}
if (flags & GRE_KP) {
+ ND_TCHECK2(*bp, 4);
if (len < 4)
goto trunc;
ND_PRINT((ndo, ", key=0x%x", EXTRACT_32BITS(bp)));
}
if (flags & GRE_SP) {
+ ND_TCHECK2(*bp, 4);
if (len < 4)
goto trunc;
ND_PRINT((ndo, ", seq %u", EXTRACT_32BITS(bp)));
uint8_t sreoff;
uint8_t srelen;
+ ND_TCHECK2(*bp, 4);
if (len < 4)
goto trunc;
af = EXTRACT_16BITS(bp);
if (af == 0 && srelen == 0)
break;
- gre_sre_print(ndo, af, sreoff, srelen, bp, len);
+ if (!gre_sre_print(ndo, af, sreoff, srelen, bp, len))
+ goto trunc;
if (len < srelen)
goto trunc;
ND_PRINT((ndo, ", Flags [%s]",
bittok2str(gre_flag_values,"none",flags)));
+ ND_TCHECK2(*bp, 2);
if (len < 2)
goto trunc;
prot = EXTRACT_16BITS(bp);
if (flags & GRE_KP) {
uint32_t k;
+ ND_TCHECK2(*bp, 4);
if (len < 4)
goto trunc;
k = EXTRACT_32BITS(bp);
}
if (flags & GRE_SP) {
+ ND_TCHECK2(*bp, 4);
if (len < 4)
goto trunc;
ND_PRINT((ndo, ", seq %u", EXTRACT_32BITS(bp)));
}
if (flags & GRE_AP) {
+ ND_TCHECK2(*bp, 4);
if (len < 4)
goto trunc;
ND_PRINT((ndo, ", ack %u", EXTRACT_32BITS(bp)));
ND_PRINT((ndo, "%s", tstr));
}
-static void
+static int
gre_sre_print(netdissect_options *ndo, uint16_t af, uint8_t sreoff,
uint8_t srelen, const u_char *bp, u_int len)
{
+ int ret;
+
switch (af) {
case GRESRE_IP:
ND_PRINT((ndo, ", (rtaf=ip"));
- gre_sre_ip_print(ndo, sreoff, srelen, bp, len);
+ ret = gre_sre_ip_print(ndo, sreoff, srelen, bp, len);
ND_PRINT((ndo, ")"));
break;
case GRESRE_ASN:
ND_PRINT((ndo, ", (rtaf=asn"));
- gre_sre_asn_print(ndo, sreoff, srelen, bp, len);
+ ret = gre_sre_asn_print(ndo, sreoff, srelen, bp, len);
ND_PRINT((ndo, ")"));
break;
default:
ND_PRINT((ndo, ", (rtaf=0x%x)", af));
+ ret = 1;
}
+ return (ret);
}
-static void
+static int
gre_sre_ip_print(netdissect_options *ndo, uint8_t sreoff, uint8_t srelen,
const u_char *bp, u_int len)
{
if (sreoff & 3) {
ND_PRINT((ndo, ", badoffset=%u", sreoff));
- return;
+ return (1);
}
if (srelen & 3) {
ND_PRINT((ndo, ", badlength=%u", srelen));
- return;
+ return (1);
}
if (sreoff >= srelen) {
ND_PRINT((ndo, ", badoff/len=%u/%u", sreoff, srelen));
- return;
+ return (1);
}
- for (;;) {
- if (len < 4 || srelen == 0)
- return;
+ while (srelen != 0) {
+ if (!ND_TTEST2(*bp, sizeof(struct in_addr)))
+ return (0);
+ if (len < 4)
+ return (0);
addrtostr(bp, buf, sizeof(buf));
ND_PRINT((ndo, " %s%s",
len -= 4;
srelen -= 4;
}
+ return (1);
}
-static void
+static int
gre_sre_asn_print(netdissect_options *ndo, uint8_t sreoff, uint8_t srelen,
const u_char *bp, u_int len)
{
if (sreoff & 1) {
ND_PRINT((ndo, ", badoffset=%u", sreoff));
- return;
+ return (1);
}
if (srelen & 1) {
ND_PRINT((ndo, ", badlength=%u", srelen));
- return;
+ return (1);
}
if (sreoff >= srelen) {
ND_PRINT((ndo, ", badoff/len=%u/%u", sreoff, srelen));
- return;
+ return (1);
}
- for (;;) {
- if (len < 2 || srelen == 0)
- return;
+ while (srelen != 0) {
+ if (!ND_TTEST2(*bp, 2))
+ return (0);
+ if (len < 2)
+ return (0);
ND_PRINT((ndo, " %s%x",
((bp - up) == sreoff) ? "*" : "",
len -= 2;
srelen -= 2;
}
+ return (1);
}