X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/0dad1934af3db3f97d4371463089c8725dbfa26d..cda9bf8c5f842fc7110fbbf2234bcc898f78c0bd:/print-rip.c diff --git a/print-rip.c b/print-rip.c index ad913aca..c8d17c3e 100644 --- a/print-rip.c +++ b/print-rip.c @@ -37,7 +37,6 @@ #include "af.h" -static const char tstr[] = "[|rip]"; /* * RFC 1058 and RFC 2453 header of packet. @@ -181,7 +180,7 @@ struct rip_auth_crypto_v2 { static unsigned rip_entry_print_v1(netdissect_options *ndo, const u_char *p, - unsigned remaining) + unsigned remaining) { const struct rip_entry_header *eh = (const struct rip_entry_header *)p; u_short family; @@ -190,34 +189,37 @@ rip_entry_print_v1(netdissect_options *ndo, const u_char *p, /* RFC 1058 */ if (remaining < RIP_ROUTELEN) return (0); - family = EXTRACT_BE_U_2(ni->rip_family); + ND_TCHECK_SIZE(ni); + family = GET_BE_U_2(ni->rip_family); if (family != BSD_AFNUM_INET && family != 0) { ND_PRINT("\n\t AFI %s, ", tok2str(bsd_af_values, "Unknown (%u)", family)); - print_unknown_data(ndo, p + sizeof(*eh), "\n\t ", RIP_ROUTELEN - sizeof(*eh)); + print_unknown_data(ndo, p + sizeof(*eh), "\n\t ", RIP_ROUTELEN - sizeof(*eh)); return (RIP_ROUTELEN); } - if (EXTRACT_BE_U_2(ni->rip_mbz1) || - EXTRACT_BE_U_4(ni->rip_mbz2) || - EXTRACT_BE_U_4(ni->rip_mbz3)) { + if (GET_BE_U_2(ni->rip_mbz1) || + GET_BE_U_4(ni->rip_mbz2) || + GET_BE_U_4(ni->rip_mbz3)) { /* MBZ fields not zero */ - print_unknown_data(ndo, p, "\n\t ", RIP_ROUTELEN); + print_unknown_data(ndo, p, "\n\t ", RIP_ROUTELEN); return (RIP_ROUTELEN); } if (family == 0) { ND_PRINT("\n\t AFI 0, %s, metric: %u", - ipaddr_string(ndo, ni->rip_dest), - EXTRACT_BE_U_4(ni->rip_metric)); + ipaddr_string(ndo, ni->rip_dest), + GET_BE_U_4(ni->rip_metric)); return (RIP_ROUTELEN); } /* BSD_AFNUM_INET */ ND_PRINT("\n\t %s, metric: %u", - ipaddr_string(ndo, ni->rip_dest), - EXTRACT_BE_U_4(ni->rip_metric)); + ipaddr_string(ndo, ni->rip_dest), + GET_BE_U_4(ni->rip_metric)); return (RIP_ROUTELEN); +trunc: + return 0; } static unsigned rip_entry_print_v2(netdissect_options *ndo, const u_char *p, - unsigned remaining) + unsigned remaining) { const struct rip_entry_header *eh = (const struct rip_entry_header *)p; u_short family; @@ -225,89 +227,98 @@ rip_entry_print_v2(netdissect_options *ndo, const u_char *p, if (remaining < sizeof(*eh)) return (0); - family = EXTRACT_BE_U_2(eh->rip_family); + ND_TCHECK_SIZE(eh); + family = GET_BE_U_2(eh->rip_family); if (family == 0xFFFF) { /* variable-sized authentication structures */ - uint16_t auth_type = EXTRACT_BE_U_2(eh->rip_tag); + uint16_t auth_type = GET_BE_U_2(eh->rip_tag); p += sizeof(*eh); remaining -= sizeof(*eh); if (auth_type == 2) { ND_PRINT("\n\t Simple Text Authentication data: "); - if (fn_printzp(ndo, p, RIP_AUTHLEN, p + remaining)) + if (nd_printzp(ndo, p, RIP_AUTHLEN, p + remaining)) return (0); } else if (auth_type == 3) { const struct rip_auth_crypto_v2 *ch; ch = (const struct rip_auth_crypto_v2 *)p; + ND_TCHECK_SIZE(ch); if (remaining < sizeof(*ch)) return (0); ND_PRINT("\n\t Auth header:"); - ND_PRINT(" Packet Len %u,", EXTRACT_BE_U_2(ch->rip_packet_len)); - ND_PRINT(" Key-ID %u,", EXTRACT_U_1(ch->rip_key_id)); - ND_PRINT(" Auth Data Len %u,", EXTRACT_U_1(ch->rip_auth_data_len)); - ND_PRINT(" SeqNo %u,", EXTRACT_BE_U_4(ch->rip_seq_num)); - ND_PRINT(" MBZ %u,", EXTRACT_BE_U_4(ch->rip_mbz1)); - ND_PRINT(" MBZ %u", EXTRACT_BE_U_4(ch->rip_mbz2)); + ND_PRINT(" Packet Len %u,", + GET_BE_U_2(ch->rip_packet_len)); + ND_PRINT(" Key-ID %u,", GET_U_1(ch->rip_key_id)); + ND_PRINT(" Auth Data Len %u,", + GET_U_1(ch->rip_auth_data_len)); + ND_PRINT(" SeqNo %u,", GET_BE_U_4(ch->rip_seq_num)); + ND_PRINT(" MBZ %u,", GET_BE_U_4(ch->rip_mbz1)); + ND_PRINT(" MBZ %u", GET_BE_U_4(ch->rip_mbz2)); } else if (auth_type == 1) { ND_PRINT("\n\t Auth trailer:"); print_unknown_data(ndo, p, "\n\t ", remaining); return (sizeof(*eh) + remaining); /* AT spans till the packet end */ } else { ND_PRINT("\n\t Unknown (%u) Authentication data:", - auth_type); + auth_type); print_unknown_data(ndo, p, "\n\t ", remaining); return (sizeof(*eh) + remaining); /* we don't know how long this is, so we go to the packet end */ } } else if (family != BSD_AFNUM_INET && family != 0) { ND_PRINT("\n\t AFI %s", tok2str(bsd_af_values, "Unknown (%u)", family)); - print_unknown_data(ndo, p + sizeof(*eh), "\n\t ", RIP_ROUTELEN - sizeof(*eh)); + print_unknown_data(ndo, p + sizeof(*eh), "\n\t ", RIP_ROUTELEN - sizeof(*eh)); } else { /* BSD_AFNUM_INET or AFI 0 */ ni = (const struct rip_netinfo_v2 *)p; + ND_TCHECK_SIZE(ni); if (remaining < sizeof(*ni)) return (0); ND_PRINT("\n\t AFI %s, %15s/%-2d, tag 0x%04x, metric: %u, next-hop: ", - tok2str(bsd_af_values, "%u", family), - ipaddr_string(ndo, ni->rip_dest), - mask2plen(EXTRACT_BE_U_4(ni->rip_dest_mask)), - EXTRACT_BE_U_2(ni->rip_tag), - EXTRACT_BE_U_4(ni->rip_metric)); - if (EXTRACT_BE_U_4(ni->rip_router)) + tok2str(bsd_af_values, "%u", family), + ipaddr_string(ndo, ni->rip_dest), + mask2plen(GET_BE_U_4(ni->rip_dest_mask)), + GET_BE_U_2(ni->rip_tag), + GET_BE_U_4(ni->rip_metric)); + if (GET_BE_U_4(ni->rip_router)) ND_PRINT("%s", ipaddr_string(ndo, ni->rip_router)); else ND_PRINT("self"); } return (RIP_ROUTELEN); +trunc: + return 0; } void rip_print(netdissect_options *ndo, - const u_char *dat, u_int length) + const u_char *dat, u_int length) { const struct rip *rp; uint8_t vers, cmd; const u_char *p; - u_int i, j; + u_int len, routecount; unsigned entry_size; + ndo->ndo_protocol = "rip"; if (ndo->ndo_snapend < dat) { - ND_PRINT(" %s", tstr); + nd_print_trunc(ndo); return; } - i = ndo->ndo_snapend - dat; - if (i > length) - i = length; - if (i < sizeof(*rp)) { - ND_PRINT(" %s", tstr); + len = ndo->ndo_snapend - dat; + if (len > length) + len = length; + if (len < sizeof(*rp)) { + nd_print_trunc(ndo); return; } - i -= sizeof(*rp); + len -= sizeof(*rp); rp = (const struct rip *)dat; - vers = EXTRACT_U_1(rp->rip_vers); + ND_TCHECK_SIZE(rp); + vers = GET_U_1(rp->rip_vers); ND_PRINT("%sRIPv%u", - (ndo->ndo_vflag >= 1) ? "\n\t" : "", - vers); + (ndo->ndo_vflag >= 1) ? "\n\t" : "", + vers); if (vers == 0) { /* @@ -326,7 +337,7 @@ rip_print(netdissect_options *ndo, } /* dump version and lets see if we know the commands name*/ - cmd = EXTRACT_U_1(rp->rip_cmd); + cmd = GET_U_1(rp->rip_cmd); ND_PRINT(", %s, length: %u", tok2str(rip_cmd_values, "unknown command (%u)", cmd), length); @@ -341,40 +352,46 @@ rip_print(netdissect_options *ndo, switch (vers) { case 1: - j = length / RIP_ROUTELEN; - ND_PRINT(", routes: %u", j); + routecount = length / RIP_ROUTELEN; + ND_PRINT(", routes: %u", routecount); p = (const u_char *)(rp + 1); - while (i != 0) { - entry_size = rip_entry_print_v1(ndo, p, i); + while (len != 0) { + entry_size = rip_entry_print_v1(ndo, p, len); if (entry_size == 0) { /* Error */ - ND_PRINT("%s", tstr); + nd_print_trunc(ndo); + break; + } + if (len < entry_size) { + ND_PRINT(" [remaining entries length %u < %u]", + len, entry_size); + nd_print_invalid(ndo); break; } p += entry_size; - i -= entry_size; + len -= entry_size; } break; case 2: - j = length / RIP_ROUTELEN; - ND_PRINT(", routes: %u or less", j); + routecount = length / RIP_ROUTELEN; + ND_PRINT(", routes: %u or less", routecount); p = (const u_char *)(rp + 1); - while (i != 0) { - entry_size = rip_entry_print_v2(ndo, p, i); + while (len != 0) { + entry_size = rip_entry_print_v2(ndo, p, len); if (entry_size == 0) { /* Error */ - ND_PRINT("%s", tstr); + nd_print_trunc(ndo); break; } -#if 0 - if (i < entry_size) { - ND_PRINT("WTF?"); + if (len < entry_size) { + ND_PRINT(" [remaining entries length %u < %u]", + len, entry_size); + nd_print_invalid(ndo); break; } -#endif p += entry_size; - i -= entry_size; + len -= entry_size; } break; @@ -403,4 +420,6 @@ rip_print(netdissect_options *ndo, if (!print_unknown_data(ndo, (const uint8_t *)rp, "\n\t", length)) return; } +trunc: + return; }