]> The Tcpdump Group git mirrors - tcpdump/commitdiff
RIPng: Modernize packet parsing style.
authorDenis Ovsienko <[email protected]>
Sun, 11 Oct 2020 11:47:34 +0000 (12:47 +0100)
committerDenis Ovsienko <[email protected]>
Sun, 11 Oct 2020 11:47:34 +0000 (12:47 +0100)
Lose the unused trace file props in struct rip6. Make rip6_entry_print()
void as its return value was discarded anyway; always fetch all fields of
RTE. In ripng_print() just tell rip6_entry_print() whether to print the
metric or not instead of fetching it; validate the version before
decoding the command, not after; consider an unknown command invalid; add
and use a standard invalid label. Lose all ND_TCHECK*() instances as they
are excess now. Update a test.

print-ripng.c
tests/hoobr_ripng_print.out

index 9e5c504672022896fb6fa65183c97be007c9dccf..c4f4ea3a1db2178d1ec4d35546f9f82704551812 100644 (file)
@@ -21,6 +21,8 @@
 
 /* \summary: IPv6 Routing Information Protocol (RIPng) printer */
 
+/* specification: RFC 2080 */
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -75,12 +77,7 @@ struct       rip6 {
        nd_uint8_t      rip6_cmd;
        nd_uint8_t      rip6_vers;
        nd_byte         rip6_res1[2];
-       union {
-               struct  netinfo6        ru6_nets[1];
-               nd_byte ru6_tracefile[1];
-       } rip6un;
-#define        rip6_nets       rip6un.ru6_nets
-#define        rip6_tracefile  rip6un.ru6_tracefile
+       struct netinfo6 rip6_nets[1];
 };
 
 #define        HOPCNT_INFINITY6        16
@@ -91,43 +88,48 @@ static int ND_IN6_IS_ADDR_UNSPECIFIED(const nd_ipv6 *addr)
     return (memcmp(addr, &in6addr_any_val, sizeof(*addr)) == 0);
 }
 
-static int
-rip6_entry_print(netdissect_options *ndo, const struct netinfo6 *ni, u_int metric)
+static void
+rip6_entry_print(netdissect_options *ndo,
+                 const struct netinfo6 *ni, const u_int print_metric)
 {
-       int l;
        uint16_t tag;
+       uint8_t metric;
 
-       l = ND_PRINT("%s/%u", GET_IP6ADDR_STRING(ni->rip6_dest),
-                    GET_U_1(ni->rip6_plen));
+       ND_PRINT("%s/%u", GET_IP6ADDR_STRING(ni->rip6_dest),
+                GET_U_1(ni->rip6_plen));
        tag = GET_BE_U_2(ni->rip6_tag);
        if (tag)
-               l += ND_PRINT(" [%u]", tag);
-       if (metric)
-               l += ND_PRINT(" (%u)", metric);
-       return l;
+               ND_PRINT(" [%u]", tag);
+       metric = GET_U_1(ni->rip6_metric);
+       if (metric && print_metric)
+               ND_PRINT(" (%u)", metric);
 }
 
 void
 ripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length)
 {
        const struct rip6 *rp = (const struct rip6 *)dat;
-       uint8_t cmd;
+       uint8_t cmd, vers;
        const struct netinfo6 *ni;
        unsigned int length_left;
        u_int j;
 
        ndo->ndo_protocol = "ripng";
+       vers = GET_U_1(rp->rip6_vers);
+       if (vers != RIP6_VERSION) {
+               ND_PRINT(" [vers %u]", vers);
+               goto invalid;
+       }
        cmd = GET_U_1(rp->rip6_cmd);
        switch (cmd) {
 
        case RIP6_REQUEST:
                length_left = length;
                if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6)))
-                       goto trunc;
+                       goto invalid;
                length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6));
                j = length_left / sizeof(*ni);
                if (j == 1) {
-                       ND_TCHECK_SIZE(rp->rip6_nets);
                        if (GET_U_1(rp->rip6_nets->rip6_metric) == HOPCNT_INFINITY6
                            && ND_IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
                                ND_PRINT(" ripng-req dump");
@@ -140,20 +142,19 @@ ripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length)
                        ND_PRINT(" ripng-req %u:", j);
                for (ni = rp->rip6_nets; length_left >= sizeof(*ni);
                    length_left -= sizeof(*ni), ++ni) {
-                       ND_TCHECK_SIZE(ni);
                        if (ndo->ndo_vflag > 1)
                                ND_PRINT("\n\t");
                        else
                                ND_PRINT(" ");
-                       rip6_entry_print(ndo, ni, 0);
+                       rip6_entry_print(ndo, ni, FALSE);
                }
                if (length_left != 0)
-                       goto trunc;
+                       goto invalid;
                break;
        case RIP6_RESPONSE:
                length_left = length;
                if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6)))
-                       goto trunc;
+                       goto invalid;
                length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6));
                j = length_left / sizeof(*ni);
                if (j * sizeof(*ni) != length_left)
@@ -162,24 +163,21 @@ ripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length)
                        ND_PRINT(" ripng-resp %u:", j);
                for (ni = rp->rip6_nets; length_left >= sizeof(*ni);
                    length_left -= sizeof(*ni), ++ni) {
-                       ND_TCHECK_SIZE(ni);
                        if (ndo->ndo_vflag > 1)
                                ND_PRINT("\n\t");
                        else
                                ND_PRINT(" ");
-                       rip6_entry_print(ndo, ni, GET_U_1(ni->rip6_metric));
+                       rip6_entry_print(ndo, ni, TRUE);
                }
                if (length_left != 0)
-                       goto trunc;
+                       goto invalid;
                break;
        default:
                ND_PRINT(" ripng-%u ?? %u", cmd, length);
-               break;
+               goto invalid;
        }
-       if (GET_U_1(rp->rip6_vers) != RIP6_VERSION)
-               ND_PRINT(" [vers %u]", GET_U_1(rp->rip6_vers));
        return;
 
-trunc:
-       nd_print_trunc(ndo);
+invalid:
+       nd_print_invalid(ndo);
 }
index f0fee9db9a548a13acb79c8d6e222e0271ffb5ff..309cf8c9251982d013445e2a3183108924d3d19a 100644 (file)
@@ -1 +1 @@
-    1  05:27:12.808464432 IP 48.48.48.48.521 > 48.48.48.48.12336:  [|ripng]
+    1  05:27:12.808464432 IP 48.48.48.48.521 > 48.48.48.48.12336:  [vers 48] (invalid)