]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-loopback.c
CHANGES: Add/move change(s) backported to 4.99
[tcpdump] / print-loopback.c
index 9a74ae611397c537fe32ab5c4968e51ce51747a5..b96b638856420b179d6609a7ffa900990b378165 100644 (file)
@@ -1,9 +1,4 @@
 /*
- * This module implements decoding of the Loopback Protocol, originally
- * defined as the Configuration Testing Protocol. It is based on the following
- * specification:
- * http://www.mit.edu/people/jhawk/ctp.pdf
- *
  * Copyright (c) 2014 The TCPDUMP project
  * All rights reserved.
  *
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#define NETDISSECT_REWORKED
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+/* \summary: Loopback Protocol printer */
 
-#include <tcpdump-stdinc.h>
+/*
+ * originally defined as the Ethernet Configuration Testing Protocol.
+ * specification:
+ * https://web.archive.org/web/20060919181108/http://www.mit.edu/people/jhawk/ctp.pdf
+ */
 
-#include "interface.h"
+#include <config.h>
+
+#include "netdissect-stdinc.h"
+
+#define ND_LONGJMP_FROM_TCHECK
+#include "netdissect.h"
 #include "extract.h"
-#include "ether.h"
 #include "addrtoname.h"
 
-static const char tstr[] = " [|loopback]";
-static const char cstr[] = " (corrupt)";
 
 #define LOOPBACK_REPLY   1
 #define LOOPBACK_FWDDATA 2
@@ -55,82 +53,82 @@ static const struct tok fcode_str[] = {
 };
 
 static void
-loopback_message_print(netdissect_options *ndo, const u_char *cp, const u_int len)
+loopback_message_print(netdissect_options *ndo,
+                       const u_char *cp, u_int len)
 {
-       const u_char *ep = cp + len;
        uint16_t function;
 
        if (len < 2)
-               goto corrupt;
+               goto invalid;
        /* function */
-       ND_TCHECK2(*cp, 2);
-       function = EXTRACT_LE_16BITS(cp);
+       function = GET_LE_U_2(cp);
        cp += 2;
-       ND_PRINT((ndo, ", %s", tok2str(fcode_str, " invalid (%u)", function)));
+       len -= 2;
+       ND_PRINT(", %s", tok2str(fcode_str, " invalid (%u)", function));
 
        switch (function) {
                case LOOPBACK_REPLY:
-                       if (len < 4)
-                               goto corrupt;
+                       if (len < 2)
+                               goto invalid;
                        /* receipt number */
-                       ND_TCHECK2(*cp, 2);
-                       ND_PRINT((ndo, ", receipt number %u", EXTRACT_LE_16BITS(cp)));
+                       ND_PRINT(", receipt number %u", GET_LE_U_2(cp));
                        cp += 2;
+                       len -= 2;
                        /* data */
-                       ND_PRINT((ndo, ", data (%u octets)", len - 4));
-                       ND_TCHECK2(*cp, len - 4);
+                       ND_PRINT(", data (%u octets)", len);
+                       ND_TCHECK_LEN(cp, len);
                        break;
                case LOOPBACK_FWDDATA:
-                       if (len < 8)
-                               goto corrupt;
+                       if (len < MAC_ADDR_LEN)
+                               goto invalid;
                        /* forwarding address */
-                       ND_TCHECK2(*cp, ETHER_ADDR_LEN);
-                       ND_PRINT((ndo, ", forwarding address %s", etheraddr_string(ndo, cp)));
-                       cp += ETHER_ADDR_LEN;
+                       ND_PRINT(", forwarding address %s", GET_ETHERADDR_STRING(cp));
+                       cp += MAC_ADDR_LEN;
+                       len -= MAC_ADDR_LEN;
                        /* data */
-                       ND_PRINT((ndo, ", data (%u octets)", len - 8));
-                       ND_TCHECK2(*cp, len - 8);
+                       ND_PRINT(", data (%u octets)", len);
+                       ND_TCHECK_LEN(cp, len);
                        break;
                default:
-                       ND_TCHECK2(*cp, len - 2);
+                       ND_TCHECK_LEN(cp, len);
                        break;
        }
        return;
 
-corrupt:
-       ND_PRINT((ndo, "%s", cstr));
-       ND_TCHECK2(*cp, ep - cp);
-       return;
-trunc:
-       ND_PRINT((ndo, "%s", tstr));
+invalid:
+       nd_print_invalid(ndo);
+       ND_TCHECK_LEN(cp, len);
 }
 
 void
-loopback_print(netdissect_options *ndo, const u_char *cp, const u_int len)
+loopback_print(netdissect_options *ndo,
+               const u_char *cp, u_int len)
 {
-       const u_char *ep = cp + len;
        uint16_t skipCount;
 
-       ND_PRINT((ndo, "Loopback"));
+       ndo->ndo_protocol = "loopback";
+       ND_PRINT("Loopback");
        if (len < 2)
-               goto corrupt;
+               goto invalid;
        /* skipCount */
-       ND_TCHECK2(*cp, 2);
-       skipCount = EXTRACT_LE_16BITS(cp);
+       skipCount = GET_LE_U_2(cp);
        cp += 2;
-       ND_PRINT((ndo, ", skipCount %u", skipCount));
+       len -= 2;
+       ND_PRINT(", skipCount %u", skipCount);
        if (skipCount % 8)
-               ND_PRINT((ndo, " (bogus)"));
-       if (skipCount > len - 2)
-               goto corrupt;
-       loopback_message_print(ndo, cp + skipCount, len - 2 - skipCount);
+               ND_PRINT(" (bogus)");
+       if (skipCount > len)
+               goto invalid;
+       /* the octets to skip */
+       ND_TCHECK_LEN(cp, skipCount);
+       cp += skipCount;
+       len -= skipCount;
+       /* the first message to decode */
+       loopback_message_print(ndo, cp, len);
        return;
 
-corrupt:
-       ND_PRINT((ndo, "%s", cstr));
-       ND_TCHECK2(*cp, ep - cp);
-       return;
-trunc:
-       ND_PRINT((ndo, "%s", tstr));
+invalid:
+       nd_print_invalid(ndo);
+       ND_TCHECK_LEN(cp, len);
 }