X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/50b4920bc51263ce3a2647b6a1d2289629650854..1fb50928ce27360c1c987312774f686b23c69b51:/print-rip.c diff --git a/print-rip.c b/print-rip.c index c66c86db..cf661d03 100644 --- a/print-rip.c +++ b/print-rip.c @@ -19,30 +19,28 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-rip.c,v 1.58 2006-02-21 10:27:40 hannes Exp $ (LBL)"; -#endif +/* \summary: Routing Information Protocol (RIP) printer */ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include -#include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #include "af.h" +static const char tstr[] = "[|rip]"; + struct rip { - u_int8_t rip_cmd; /* request/response */ - u_int8_t rip_vers; /* protocol version # */ - u_int8_t unused[2]; /* unused */ + uint8_t rip_cmd; /* request/response */ + uint8_t rip_vers; /* protocol version # */ + uint8_t unused[2]; /* unused */ }; #define RIPCMD_REQUEST 1 /* want info */ @@ -67,7 +65,7 @@ static const struct tok rip_cmd_values[] = { /* * rfc 1723 - * + * * 0 1 2 3 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -87,104 +85,121 @@ static const struct tok rip_cmd_values[] = { */ struct rip_netinfo { - u_int16_t rip_family; - u_int16_t rip_tag; - u_int32_t rip_dest; - u_int32_t rip_dest_mask; - u_int32_t rip_router; - u_int32_t rip_metric; /* cost of route */ + uint16_t rip_family; + uint16_t rip_tag; + uint32_t rip_dest; + uint32_t rip_dest_mask; + uint32_t rip_router; + uint32_t rip_metric; /* cost of route */ }; static void -rip_entry_print_v1(register const struct rip_netinfo *ni) +rip_entry_print_v1(netdissect_options *ndo, + register const struct rip_netinfo *ni) { register u_short family; /* RFC 1058 */ family = EXTRACT_16BITS(&ni->rip_family); - if (family != AF_INET) { - printf("\n\t AFI %s, ", tok2str(af_values, "Unknown (%u)", family)); - print_unknown_data((u_int8_t *)&ni->rip_family,"\n\t ",RIP_ROUTELEN); + if (family != BSD_AFNUM_INET && family != 0) { + ND_PRINT((ndo, "\n\t AFI %s, ", tok2str(bsd_af_values, "Unknown (%u)", family))); + print_unknown_data(ndo, (const uint8_t *)&ni->rip_family, "\n\t ", RIP_ROUTELEN); return; } if (EXTRACT_16BITS(&ni->rip_tag) || EXTRACT_32BITS(&ni->rip_dest_mask) || EXTRACT_32BITS(&ni->rip_router)) { /* MBZ fields not zero */ - print_unknown_data((u_int8_t *)&ni->rip_family,"\n\t ",RIP_ROUTELEN); + print_unknown_data(ndo, (const uint8_t *)&ni->rip_family, "\n\t ", RIP_ROUTELEN); + return; + } + if (family == 0) { + ND_PRINT((ndo, "\n\t AFI 0, %s, metric: %u", + ipaddr_string(ndo, &ni->rip_dest), + EXTRACT_32BITS(&ni->rip_metric))); return; - } /* AF_INET */ - printf("\n\t %s, metric: %u", - ipaddr_string(&ni->rip_dest), - EXTRACT_32BITS(&ni->rip_metric)); + } /* BSD_AFNUM_INET */ + ND_PRINT((ndo, "\n\t %s, metric: %u", + ipaddr_string(ndo, &ni->rip_dest), + EXTRACT_32BITS(&ni->rip_metric))); } -static void -rip_entry_print_v2(register const struct rip_netinfo *ni) +static unsigned +rip_entry_print_v2(netdissect_options *ndo, + register const struct rip_netinfo *ni, const unsigned remaining) { - register u_char *p; register u_short family; - u_char buf[RIP_AUTHLEN]; family = EXTRACT_16BITS(&ni->rip_family); - if (family == 0xFFFF) { /* 16 bytes authentication ? */ - if (EXTRACT_16BITS(&ni->rip_tag) == 2) { /* simple text authentication ? */ - memcpy(buf, &ni->rip_dest, sizeof(buf)); - buf[sizeof(buf)-1] = '\0'; - for (p = buf; *p; p++) { - if (!isprint(*p)) - break; - } - printf("\n\t Simple Text Authentication data: %s", buf); - } else { - printf("\n\t Unknown (%u) Authentication data:", - EXTRACT_16BITS(&ni->rip_tag)); - print_unknown_data((u_int8_t *)&ni->rip_dest,"\n\t ",RIP_AUTHLEN); + if (family == 0xFFFF) { /* variable-sized authentication structures */ + uint16_t auth_type = EXTRACT_16BITS(&ni->rip_tag); + if (auth_type == 2) { + register const u_char *p = (const u_char *)&ni->rip_dest; + u_int i = 0; + ND_PRINT((ndo, "\n\t Simple Text Authentication data: ")); + for (; i < RIP_AUTHLEN; p++, i++) + ND_PRINT((ndo, "%c", ND_ISPRINT(*p) ? *p : '.')); + } else if (auth_type == 3) { + ND_PRINT((ndo, "\n\t Auth header:")); + ND_PRINT((ndo, " Packet Len %u,", EXTRACT_16BITS((const uint8_t *)ni + 4))); + ND_PRINT((ndo, " Key-ID %u,", *((const uint8_t *)ni + 6))); + ND_PRINT((ndo, " Auth Data Len %u,", *((const uint8_t *)ni + 7))); + ND_PRINT((ndo, " SeqNo %u,", EXTRACT_32BITS(&ni->rip_dest_mask))); + ND_PRINT((ndo, " MBZ %u,", EXTRACT_32BITS(&ni->rip_router))); + ND_PRINT((ndo, " MBZ %u", EXTRACT_32BITS(&ni->rip_metric))); + } else if (auth_type == 1) { + ND_PRINT((ndo, "\n\t Auth trailer:")); + print_unknown_data(ndo, (const uint8_t *)&ni->rip_dest, "\n\t ", remaining); + return remaining; /* AT spans till the packet end */ + } else { + ND_PRINT((ndo, "\n\t Unknown (%u) Authentication data:", + EXTRACT_16BITS(&ni->rip_tag))); + print_unknown_data(ndo, (const uint8_t *)&ni->rip_dest, "\n\t ", remaining); } - } else if (family != AF_INET) { - printf("\n\t AFI %s", tok2str(af_values, "Unknown (%u)", family)); - print_unknown_data((u_int8_t *)&ni->rip_tag,"\n\t ",RIP_ROUTELEN-2); - return; - } else { /* AF_INET */ - printf("\n\t AFI %s, %15s/%-2d, tag 0x%04x, metric: %u, next-hop: ", - tok2str(af_values, "Unknown (%u)", family), - ipaddr_string(&ni->rip_dest), + } else if (family != BSD_AFNUM_INET && family != 0) { + ND_PRINT((ndo, "\n\t AFI %s", tok2str(bsd_af_values, "Unknown (%u)", family))); + print_unknown_data(ndo, (const uint8_t *)&ni->rip_tag, "\n\t ", RIP_ROUTELEN-2); + } else { /* BSD_AFNUM_INET or AFI 0 */ + ND_PRINT((ndo, "\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_32BITS(&ni->rip_dest_mask)), EXTRACT_16BITS(&ni->rip_tag), - EXTRACT_32BITS(&ni->rip_metric)); + EXTRACT_32BITS(&ni->rip_metric))); if (EXTRACT_32BITS(&ni->rip_router)) - printf("%s", ipaddr_string(&ni->rip_router)); - else - printf("self"); + ND_PRINT((ndo, "%s", ipaddr_string(ndo, &ni->rip_router))); + else + ND_PRINT((ndo, "self")); } + return sizeof (*ni); } void -rip_print(const u_char *dat, u_int length) +rip_print(netdissect_options *ndo, + const u_char *dat, u_int length) { register const struct rip *rp; register const struct rip_netinfo *ni; register u_int i, j; - register int trunc; - if (snapend < dat) { - printf(" [|rip]"); + if (ndo->ndo_snapend < dat) { + ND_PRINT((ndo, " %s", tstr)); return; } - i = snapend - dat; + i = ndo->ndo_snapend - dat; if (i > length) i = length; if (i < sizeof(*rp)) { - printf(" [|rip]"); + ND_PRINT((ndo, " %s", tstr)); return; } i -= sizeof(*rp); - rp = (struct rip *)dat; + rp = (const struct rip *)dat; - printf("%sRIPv%u", - (vflag >= 1) ? "\n\t" : "", - rp->rip_vers); + ND_PRINT((ndo, "%sRIPv%u", + (ndo->ndo_vflag >= 1) ? "\n\t" : "", + rp->rip_vers)); switch (rp->rip_vers) { case 0: @@ -199,39 +214,40 @@ rip_print(const u_char *dat, u_int length) * * so perhaps we should just dump the packet, in hex. */ - print_unknown_data((u_int8_t *)&rp->rip_cmd,"\n\t",length); + print_unknown_data(ndo, (const uint8_t *)&rp->rip_cmd, "\n\t", length); break; default: /* dump version and lets see if we know the commands name*/ - printf(", %s, length: %u", + ND_PRINT((ndo, ", %s, length: %u", tok2str(rip_cmd_values, "unknown command (%u)", rp->rip_cmd), - length); + length)); - if (vflag < 1) + if (ndo->ndo_vflag < 1) return; switch (rp->rip_cmd) { + case RIPCMD_REQUEST: case RIPCMD_RESPONSE: j = length / sizeof(*ni); - printf(", routes: %u",j); - trunc = (i / sizeof(*ni)) != j; - ni = (struct rip_netinfo *)(rp + 1); + ND_PRINT((ndo, ", routes: %u%s", j, rp->rip_vers == 2 ? " or less" : "")); + ni = (const struct rip_netinfo *)(rp + 1); for (; i >= sizeof(*ni); ++ni) { if (rp->rip_vers == 1) - rip_entry_print_v1(ni); + { + rip_entry_print_v1(ndo, ni); + i -= sizeof(*ni); + } else if (rp->rip_vers == 2) - rip_entry_print_v2(ni); + i -= rip_entry_print_v2(ndo, ni, i); else break; - i -= sizeof(*ni); } - if (trunc) - printf("[|rip]"); + if (i) + ND_PRINT((ndo, "%s", tstr)); break; - case RIPCMD_REQUEST: case RIPCMD_TRACEOFF: case RIPCMD_POLL: case RIPCMD_POLLENTRY: @@ -240,15 +256,15 @@ rip_print(const u_char *dat, u_int length) case RIPCMD_TRACEON: /* fall through */ default: - if (vflag <= 1) { - if(!print_unknown_data((u_int8_t *)rp,"\n\t",length)) + if (ndo->ndo_vflag <= 1) { + if(!print_unknown_data(ndo, (const uint8_t *)rp, "\n\t", length)) return; } break; } /* do we want to see an additionally hexdump ? */ - if (vflag> 1) { - if(!print_unknown_data((u_int8_t *)rp,"\n\t",length)) + if (ndo->ndo_vflag> 1) { + if(!print_unknown_data(ndo, (const uint8_t *)rp, "\n\t", length)) return; } }