]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ripng.c
CI: Add warning exemptions for Sun C (suncc-5.14) on Solaris 10
[tcpdump] / print-ripng.c
index be9c1b504cf162182bc2281ea303facac40f7ccf..c6955cb8ef145da036143d3d19db65085b1a43f5 100644 (file)
@@ -21,9 +21,9 @@
 
 /* \summary: IPv6 Routing Information Protocol (RIPng) printer */
 
-#ifdef HAVE_CONFIG_H
+/* specification: RFC 2080 */
+
 #include <config.h>
-#endif
 
 #include "netdissect-stdinc.h"
 
@@ -75,12 +75,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,44 +86,49 @@ 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";
-       ND_TCHECK_1(rp->rip6_cmd);
+       vers = GET_U_1(rp->rip6_vers);
+       if (vers != RIP6_VERSION) {
+               nd_print_protocol(ndo);
+               ND_PRINT(" [version %u, must be %u]", vers, RIP6_VERSION);
+               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);
+               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");
@@ -141,20 +141,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)
@@ -163,26 +162,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;
        }
-       ND_TCHECK_1(rp->rip6_vers);
-       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);
-       return;
+invalid:
+       nd_print_invalid(ndo);
 }