]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-zep.c
CI: Add warning exemptions for Sun C (suncc-5.14) on Solaris 10
[tcpdump] / print-zep.c
index 8954d7fd386fe535e271bc4babe82bf37e71a216..20a1e2ae6ddfa50ac08fe7ecd552428250f717e5 100644 (file)
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+/* \summary: ZigBee Encapsulation Protocol (ZEP) printer */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include <config.h>
 
-#include <netdissect-stdinc.h>
+#include "netdissect-stdinc.h"
 
+#define ND_LONGJMP_FROM_TCHECK
 #include "netdissect.h"
 
 #include "extract.h"
 
+#include "ntp.h"
+
 /* From wireshark packet-zep.c:
  *
  ***********************************************************************
@@ -42,7 +44,6 @@
  ***********************************************************************
  *
  * ZEP v1 Header will have the following format:
- *
  * |Preamble|Version|Channel ID|Device ID|CRC/LQI Mode|LQI Val|Reserved|Length|
  * |2 bytes |1 byte |  1 byte  | 2 bytes |   1 byte   |1 byte |7 bytes |1 byte|
  *
  *------------------------------------------------------------
  */
 
-#define     FMAXINT (4294967296.0)  /* floating point rep. of MAXINT */
-#define     JAN_1970        2208988800U
-
-/* Print timestamp */
-static void zep_print_ts(netdissect_options *ndo, const u_char *p)
-{
-  int32_t i;
-  uint32_t uf;
-  uint32_t f;
-  float ff;
-
-  i = EXTRACT_32BITS(p);
-  uf = EXTRACT_32BITS(p + 4);
-  ff = uf;
-  if (ff < 0.0)           /* some compilers are buggy */
-    ff += FMAXINT;
-  ff = ff / FMAXINT;      /* shift radix point by 32 bits */
-  f = ff * 1000000000.0;  /* treat fraction as parts per billion */
-  ND_PRINT((ndo, "%u.%09d", i, f));
-
-#ifdef HAVE_STRFTIME
-  /*
-   * print the time in human-readable format.
-   */
-  if (i) {
-    time_t seconds = i - JAN_1970;
-    struct tm *tm;
-    char time_buf[128];
-
-    tm = localtime(&seconds);
-    strftime(time_buf, sizeof (time_buf), "%Y/%m/%d %H:%M:%S", tm);
-    ND_PRINT((ndo, " (%s)", time_buf));
-  }
-#endif
-}
-
 /*
  * Main function to print packets.
  */
+
 void
 zep_print(netdissect_options *ndo,
          const u_char *bp, u_int len)
 {
-    uint8_t version, inner_len;
-    uint32_t seq_no;
-    
-    ND_PRINT((ndo, "ZEP"));
-    
-    ND_TCHECK2(*bp, 8);
-
-    if (*bp != 'E' || *(bp+1) != 'X') goto trunc;
-    
-    version = *(bp + 2);
-    ND_PRINT((ndo, "v%d ", version));
-
-    if (version == 1) {
-      /* ZEP v1 packet. */
-      ND_TCHECK2(*bp, 16);
-      ND_PRINT((ndo, "Channel ID %d, Device ID 0x%04x, ",
-               *(bp + 3), EXTRACT_16BITS(bp + 4)));
-      if (*(bp + 6))
-       ND_PRINT((ndo, "CRC, "));
-      else
-       ND_PRINT((ndo, "LQI %d, ", *(bp + 7)));
-      inner_len = *(bp + 15);
-      ND_PRINT((ndo, "inner len = %d", inner_len));
-
-      bp += 16;
-      len -= 16;
-    } else {
-      /* ZEP v2 packet. */
-      if (*(bp + 3) == 2) {
-       /* ZEP v2 ack. */
-       seq_no = EXTRACT_32BITS(bp + 4);
-       ND_PRINT((ndo, "ACK, seq# = %d", seq_no));
-       inner_len = 0;
-       bp += 8;
-       len -= 8;
-      } else {
-       /* ZEP v2 data, or some other. */
-       ND_TCHECK2(*bp, 32);
-       
-       ND_PRINT((ndo, "Type %d, Channel ID %d, Device ID 0x%04x, ",
-                 *(bp + 3), *(bp + 4), EXTRACT_16BITS(bp + 5)));
-       if (*(bp + 7))
-         ND_PRINT((ndo, "CRC, "));
-       else
-         ND_PRINT((ndo, "LQI %d, ", *(bp + 8)));
-       
-       zep_print_ts(ndo, bp + 9);
-       seq_no = EXTRACT_32BITS(bp + 17);
-       inner_len = *(bp + 31);
-       ND_PRINT((ndo, ", seq# = %d, inner len = %d", seq_no, inner_len));
-       bp += 32;
-       len -= 32;
-      }
-    }
-
-    if (inner_len != 0) {
-      /* Call 802.15.4 dissector. */
-      ND_PRINT((ndo, "\n\t"));
-      if (ieee802_15_4_print(ndo, bp, inner_len)) {
-       bp += len;
-       len = 0;
-      }
-    }
-    
-    if (!ndo->ndo_suppress_default_print)
-      ND_DEFAULTPRINT(bp, len);
-    
-    return;    
- trunc:
-    ND_PRINT((ndo, " [|ZEP]"));
+       uint8_t version, inner_len;
+       uint32_t seq_no;
+
+       ndo->ndo_protocol = "zep";
+
+       nd_print_protocol_caps(ndo);
+
+       /* Preamble Code (must be "EX") */
+       if (GET_U_1(bp) != 'E' || GET_U_1(bp + 1) != 'X') {
+               ND_PRINT(" [Preamble Code: ");
+               fn_print_char(ndo, GET_U_1(bp));
+               fn_print_char(ndo, GET_U_1(bp + 1));
+               ND_PRINT("]");
+               nd_print_invalid(ndo);
+               return;
+       }
+
+       version = GET_U_1(bp + 2);
+       ND_PRINT("v%u ", version);
+
+       if (version == 1) {
+               /* ZEP v1 packet. */
+               ND_ICHECK_U(len, <, 16);
+               ND_PRINT("Channel ID %u, Device ID 0x%04x, ",
+                        GET_U_1(bp + 3), GET_BE_U_2(bp + 4));
+               if (GET_U_1(bp + 6))
+                       ND_PRINT("CRC, ");
+               else
+                       ND_PRINT("LQI %u, ", GET_U_1(bp + 7));
+               inner_len = GET_U_1(bp + 15);
+               ND_PRINT("inner len = %u", inner_len);
+
+               bp += 16;
+               len -= 16;
+       } else {
+               /* ZEP v2 packet. */
+               if (GET_U_1(bp + 3) == 2) {
+                       /* ZEP v2 ack. */
+                       ND_ICHECK_U(len, <, 8);
+                       seq_no = GET_BE_U_4(bp + 4);
+                       ND_PRINT("ACK, seq# = %u", seq_no);
+                       inner_len = 0;
+                       bp += 8;
+                       len -= 8;
+               } else {
+                       /* ZEP v2 data, or some other. */
+                       ND_ICHECK_U(len, <, 32);
+                       ND_PRINT("Type %u, Channel ID %u, Device ID 0x%04x, ",
+                                GET_U_1(bp + 3), GET_U_1(bp + 4),
+                                GET_BE_U_2(bp + 5));
+                       if (GET_U_1(bp + 7))
+                               ND_PRINT("CRC, ");
+                       else
+                               ND_PRINT("LQI %u, ", GET_U_1(bp + 8));
+
+                       /*
+                        * XXX - why a space rather than a "T"
+                        * between the date and time?
+                        */
+                       p_ntp_time_fmt(ndo, "%Y-%m-%d %H:%M:%S",
+                           (const struct l_fixedpt *)(bp + 9));
+                       seq_no = GET_BE_U_4(bp + 17);
+                       inner_len = GET_U_1(bp + 31);
+                       ND_PRINT(", seq# = %u, inner len = %u",
+                                seq_no, inner_len);
+                       bp += 32;
+                       len -= 32;
+               }
+       }
+
+       if (inner_len != 0) {
+               /* Call 802.15.4 dissector. */
+               ND_PRINT("\n\t");
+               if (ieee802_15_4_print(ndo, bp, inner_len)) {
+                       ND_TCHECK_LEN(bp, len);
+                       bp += len;
+                       len = 0;
+               }
+       }
+
+       if (!ndo->ndo_suppress_default_print)
+               ND_DEFAULTPRINT(bp, len);
+       return;
+invalid:
+       nd_print_invalid(ndo);
 }