summaryrefslogtreecommitdiff
path: root/print-rip.c
diff options
context:
space:
mode:
authorDenis Ovsienko <infrastation@yandex.ru>2012-06-11 21:06:00 +0400
committerDenis Ovsienko <infrastation@yandex.ru>2012-06-12 14:10:05 +0400
commit33808c66905cc32682dfb2b209d507dffa6cd8ff (patch)
tree6ccad25712873c256f108860e78ad25d06f3b256 /print-rip.c
parentc4830eb85e0eb243eb37212b254433a65333c342 (diff)
downloadtcpdump-33808c66905cc32682dfb2b209d507dffa6cd8ff.tar.gz
decode RIPv2 authentication up to RFC4822
This change addresses a few issues in rip_entry_print_v2() and rip_print(): 1. In the case of Simple Password (RFC2453) authentication the last (16th) character of a password was never printed. Other password characters were printed regardless of existing isprint() test. 2. In the case of Cryptographic (RFC4822) authentication there were no details available for fixed-size auth header and variable-size auth trailer. 3. Depending on particular hash function used, a normal authentication trailer "RTE" may be 20 or more bytes long. Iteration over packet RTEs should stop once a trailer is decoded. Exact number of RTEs in a message cannot be told from message size any more. Test cases are added for Request and Response messages with Simple Password, Keyed-MD5, HMAC-SHA-1, HMAC-SHA-256, HMAC-SHA-384 and HMAC-SHA-512 authentication modes. Earlier test case is updated to match new "number of routes" output format.
Diffstat (limited to 'print-rip.c')
-rw-r--r--print-rip.c51
1 files changed, 30 insertions, 21 deletions
diff --git a/print-rip.c b/print-rip.c
index 84f8951c..327f057a 100644
--- a/print-rip.c
+++ b/print-rip.c
@@ -125,32 +125,40 @@ rip_entry_print_v1(register const struct rip_netinfo *ni)
EXTRACT_32BITS(&ni->rip_metric));
}
-static void
-rip_entry_print_v2(register const struct rip_netinfo *ni)
+static unsigned
+rip_entry_print_v2(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);
+ if (family == 0xFFFF) { /* variable-sized authentication structures */
+ u_int16_t auth_type = EXTRACT_16BITS(&ni->rip_tag);
+ if (auth_type == 2) {
+ register u_char *p = (u_char *)&ni->rip_dest;
+ u_int i = 0;
+ printf("\n\t Simple Text Authentication data: ");
+ for (; i < RIP_AUTHLEN; p++, i++)
+ putchar (isprint(*p) ? *p : '.');
+ } else if (auth_type == 3) {
+ printf("\n\t Auth header:");
+ printf(" Packet Len %u,", EXTRACT_16BITS(&ni->rip_dest));
+ printf(" Key-ID %u,", *((u_int8_t *)ni + 6));
+ printf(" Auth Data Len %u,", *((u_int8_t *)ni + 7));
+ printf(" SeqNo %u,", EXTRACT_32BITS(&ni->rip_dest_mask));
+ printf(" MBZ %u,", EXTRACT_32BITS(&ni->rip_router));
+ printf(" MBZ %u", EXTRACT_32BITS(&ni->rip_metric));
+ } else if (auth_type == 1) {
+ printf("\n\t Auth trailer:");
+ print_unknown_data((u_int8_t *)&ni->rip_dest,"\n\t ",remaining);
+ return remaining; /* AT spans till the packet end */
} 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);
+ print_unknown_data((u_int8_t *)&ni->rip_dest,"\n\t ",remaining);
}
} else if (family != BSD_AFNUM_INET && family != 0) {
printf("\n\t AFI %s", tok2str(bsd_af_values, "Unknown (%u)", family));
print_unknown_data((u_int8_t *)&ni->rip_tag,"\n\t ",RIP_ROUTELEN-2);
- return;
} else { /* BSD_AFNUM_INET or AFI 0 */
printf("\n\t AFI %s, %15s/%-2d, tag 0x%04x, metric: %u, next-hop: ",
tok2str(bsd_af_values, "%u", family),
@@ -163,6 +171,7 @@ rip_entry_print_v2(register const struct rip_netinfo *ni)
else
printf("self");
}
+ return sizeof (*ni);
}
void
@@ -171,7 +180,6 @@ rip_print(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]");
@@ -222,19 +230,20 @@ rip_print(const u_char *dat, u_int length)
case RIPCMD_REQUEST:
case RIPCMD_RESPONSE:
j = length / sizeof(*ni);
- printf(", routes: %u",j);
- trunc = (i / sizeof(*ni)) != j;
+ printf(", routes: %u%s", j, rp->rip_vers == 2 ? " or less" : "");
ni = (struct rip_netinfo *)(rp + 1);
for (; i >= sizeof(*ni); ++ni) {
if (rp->rip_vers == 1)
+ {
rip_entry_print_v1(ni);
+ i -= sizeof(*ni);
+ }
else if (rp->rip_vers == 2)
- rip_entry_print_v2(ni);
+ i -= rip_entry_print_v2(ni, i);
else
break;
- i -= sizeof(*ni);
}
- if (trunc)
+ if (i)
printf("[|rip]");
break;