]> The Tcpdump Group git mirrors - tcpdump/commitdiff
decode RIPv2 authentication up to RFC4822
authorDenis Ovsienko <[email protected]>
Mon, 11 Jun 2012 17:06:00 +0000 (21:06 +0400)
committerDenis Ovsienko <[email protected]>
Tue, 12 Jun 2012 10:10:05 +0000 (14:10 +0400)
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.

print-rip.c
tests/TESTLIST
tests/ripv1v2.out
tests/ripv2_auth.out [new file with mode: 0644]
tests/ripv2_auth.pcap [new file with mode: 0644]

index 84f8951ca1e373632012a6ec07a49d564332c02e..327f057a4a62815f432c8d776ec604a0ecdf3197 100644 (file)
@@ -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;
 
index 7dbb2b14f63f3cfbbc1e56ed3da306057202b834..aedaade8b24e5fdc31799cab9fc6786456a90204 100644 (file)
@@ -73,3 +73,4 @@ spb               spb.pcap                spb.out -t
 
 # RIP tests
 ripv1v2         ripv1v2.pcap            ripv1v2.out     -t -v
+ripv2_auth      ripv2_auth.pcap         ripv2_auth.out  -t -v
index 26e60975faeb4ea66ad5fa91af1f1334326a247b..65243d8af99b7a76bfccdd0ec18c0d993d8a59fb 100644 (file)
@@ -8,9 +8,9 @@ IP (tos 0xc0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 52)
          10.70.178.0, metric: 1
 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 52)
     10.0.0.20.520 > 224.0.0.9.520: 
-       RIPv2, Request, length: 24, routes: 1
+       RIPv2, Request, length: 24, routes: 1 or less
          AFI 0,         0.0.0.0/0 , tag 0x0000, metric: 16, next-hop: self
 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 52)
     10.0.0.20.520 > 224.0.0.9.520: 
-       RIPv2, Response, length: 24, routes: 1
+       RIPv2, Response, length: 24, routes: 1 or less
          AFI IPv4,     10.70.178.0/24, tag 0x0000, metric: 1, next-hop: self
diff --git a/tests/ripv2_auth.out b/tests/ripv2_auth.out
new file mode 100644 (file)
index 0000000..618e4a7
--- /dev/null
@@ -0,0 +1,94 @@
+IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 72)
+    10.0.0.20.520 > 224.0.0.9.520: 
+       RIPv2, Request, length: 44, routes: 2 or less
+         Simple Text Authentication data: abcdefghijklmnop
+         AFI 0,         0.0.0.0/0 , tag 0x0000, metric: 16, next-hop: self
+IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 72)
+    10.0.0.20.520 > 224.0.0.9.520: 
+       RIPv2, Response, length: 44, routes: 2 or less
+         Simple Text Authentication data: abcdefghijklmnop
+         AFI IPv4,     10.70.178.0/24, tag 0x0000, metric: 1, next-hop: self
+IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 92)
+    10.0.0.20.520 > 224.0.0.9.520: 
+       RIPv2, Request, length: 64, routes: 3 or less
+         Auth header: Packet Len 44, Key-ID 45, Auth Data Len 16, SeqNo 1339429688, MBZ 0, MBZ 0
+         AFI 0,         0.0.0.0/0 , tag 0x0000, metric: 16, next-hop: self
+         Auth trailer:
+         0x0000:  a2fe c865 f120 8808 2326 1369 d6c2 3593
+IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 92)
+    10.0.0.20.520 > 224.0.0.9.520: 
+       RIPv2, Response, length: 64, routes: 3 or less
+         Auth header: Packet Len 44, Key-ID 45, Auth Data Len 16, SeqNo 1339429692, MBZ 0, MBZ 0
+         AFI IPv4,     10.70.178.0/24, tag 0x0000, metric: 1, next-hop: self
+         Auth trailer:
+         0x0000:  6d21 5dd5 6d27 a6f4 8a51 e2c2 fcc2 af0f
+IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 96)
+    10.0.0.20.520 > 224.0.0.9.520: 
+       RIPv2, Request, length: 68, routes: 3 or less
+         Auth header: Packet Len 44, Key-ID 45, Auth Data Len 20, SeqNo 1339429713, MBZ 0, MBZ 0
+         AFI 0,         0.0.0.0/0 , tag 0x0000, metric: 16, next-hop: self
+         Auth trailer:
+         0x0000:  728c 5b16 9a1b 3913 0021 a73f 7a73 bc1b
+         0x0010:  eee0 e6a2
+IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 96)
+    10.0.0.20.520 > 224.0.0.9.520: 
+       RIPv2, Response, length: 68, routes: 3 or less
+         Auth header: Packet Len 44, Key-ID 45, Auth Data Len 20, SeqNo 1339429716, MBZ 0, MBZ 0
+         AFI IPv4,     10.70.178.0/24, tag 0x0000, metric: 1, next-hop: self
+         Auth trailer:
+         0x0000:  375c 8a50 f77f 543b 2425 a695 a27d 6b95
+         0x0010:  3375 fc89
+IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 108)
+    10.0.0.20.520 > 224.0.0.9.520: 
+       RIPv2, Request, length: 80, routes: 4 or less
+         Auth header: Packet Len 44, Key-ID 45, Auth Data Len 32, SeqNo 1339429740, MBZ 0, MBZ 0
+         AFI 0,         0.0.0.0/0 , tag 0x0000, metric: 16, next-hop: self
+         Auth trailer:
+         0x0000:  4ae5 fb9c 9702 03b8 5a93 812d 0258 6740
+         0x0010:  451a bd20 cee4 8a3d a466 17a0 e550 5b4b
+IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 108)
+    10.0.0.20.520 > 224.0.0.9.520: 
+       RIPv2, Response, length: 80, routes: 4 or less
+         Auth header: Packet Len 44, Key-ID 45, Auth Data Len 32, SeqNo 1339429744, MBZ 0, MBZ 0
+         AFI IPv4,     10.70.178.0/24, tag 0x0000, metric: 1, next-hop: self
+         Auth trailer:
+         0x0000:  3965 b755 535a 3375 e83a 973c 60c9 1693
+         0x0010:  f2de 8132 9e87 3f7f b763 3cb0 b3dc 3ba2
+IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 124)
+    10.0.0.20.520 > 224.0.0.9.520: 
+       RIPv2, Request, length: 96, routes: 4 or less
+         Auth header: Packet Len 44, Key-ID 45, Auth Data Len 48, SeqNo 1339429761, MBZ 0, MBZ 0
+         AFI 0,         0.0.0.0/0 , tag 0x0000, metric: 16, next-hop: self
+         Auth trailer:
+         0x0000:  a1f2 20f6 6f72 f45b e8e0 291f 2322 a198
+         0x0010:  1b6b 67bc 9279 7d3b 8e05 c683 8b7e 05bc
+         0x0020:  230c abc8 1470 8e30 5470 fb27 6fe3 4506
+IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 124)
+    10.0.0.20.520 > 224.0.0.9.520: 
+       RIPv2, Response, length: 96, routes: 4 or less
+         Auth header: Packet Len 44, Key-ID 45, Auth Data Len 48, SeqNo 1339429765, MBZ 0, MBZ 0
+         AFI IPv4,     10.70.178.0/24, tag 0x0000, metric: 1, next-hop: self
+         Auth trailer:
+         0x0000:  64de 1dec 3632 e210 0258 2404 0b32 a947
+         0x0010:  aa86 59a1 fef3 9248 3115 c266 0386 f183
+         0x0020:  4f31 1df0 0681 e1cc ba10 b4c1 7795 9773
+IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 140)
+    10.0.0.20.520 > 224.0.0.9.520: 
+       RIPv2, Request, length: 112, routes: 5 or less
+         Auth header: Packet Len 44, Key-ID 45, Auth Data Len 64, SeqNo 1339429781, MBZ 0, MBZ 0
+         AFI 0,         0.0.0.0/0 , tag 0x0000, metric: 16, next-hop: self
+         Auth trailer:
+         0x0000:  73ad b6e3 5fe6 07bd 0bc5 ca25 41cc 63ec
+         0x0010:  bd06 55b1 77a4 e223 ef52 8ea2 7480 e39c
+         0x0020:  ee51 96bd 4e35 8cb7 f185 ba49 9892 e683
+         0x0030:  e756 788d aa23 bf90 0b01 5c2d 241d 2d8e
+IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto UDP (17), length 140)
+    10.0.0.20.520 > 224.0.0.9.520: 
+       RIPv2, Response, length: 112, routes: 5 or less
+         Auth header: Packet Len 44, Key-ID 45, Auth Data Len 64, SeqNo 1339429785, MBZ 0, MBZ 0
+         AFI IPv4,     10.70.178.0/24, tag 0x0000, metric: 1, next-hop: self
+         Auth trailer:
+         0x0000:  ad5a 5d8a a1a8 b023 1ec3 5c1c ba6a 45fb
+         0x0010:  bee1 5584 6b1c 724d b1b7 f02e 7365 f038
+         0x0020:  7558 0914 6762 00d1 a92f d499 5da2 43ad
+         0x0030:  202c 7a9b 8065 49ad 260b 2142 0f8d d83f
diff --git a/tests/ripv2_auth.pcap b/tests/ripv2_auth.pcap
new file mode 100644 (file)
index 0000000..57b5a41
Binary files /dev/null and b/tests/ripv2_auth.pcap differ