* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+/* \summary: ZigBee Encapsulation Protocol (ZEP) printer */
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
-#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:
*
***********************************************************************
***********************************************************************
*
* 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_BE_U_4(p);
- uf = EXTRACT_BE_U_4(p + 4);
- ff = (float) uf;
- if (ff < 0.0) /* some compilers are buggy */
- ff += FMAXINT;
- ff = (float) (ff / FMAXINT); /* shift radix point by 32 bits */
- f = (uint32_t) (ff * 1000000000.0); /* treat fraction as parts per
- billion */
- ND_PRINT("%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(" (%s)", time_buf);
- }
-#endif
-}
-
/*
* Main function to print packets.
*/
{
uint8_t version, inner_len;
uint32_t seq_no;
-
- ndo->ndo_protocol ="ZEP";
-
- ND_PRINT("ZEP");
-
- ND_TCHECK_LEN(bp, 8);
-
- if (EXTRACT_U_1(bp) != 'E' || EXTRACT_U_1(bp + 1) != 'X')
- goto trunc;
-
- version = EXTRACT_U_1(bp + 2);
- ND_PRINT("v%d ", version);
-
+
+ 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_TCHECK_LEN(bp, 16);
- ND_PRINT("Channel ID %d, Device ID 0x%04x, ",
- EXTRACT_U_1(bp + 3), EXTRACT_BE_U_2(bp + 4));
- if (EXTRACT_U_1(bp + 6))
+ 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 %d, ", EXTRACT_U_1(bp + 7));
- inner_len = EXTRACT_U_1(bp + 15);
- ND_PRINT("inner len = %d", inner_len);
-
+ 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 (EXTRACT_U_1(bp + 3) == 2) {
+ if (GET_U_1(bp + 3) == 2) {
/* ZEP v2 ack. */
- seq_no = EXTRACT_BE_U_4(bp + 4);
- ND_PRINT("ACK, seq# = %d", seq_no);
+ 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_TCHECK_LEN(bp, 32);
-
- ND_PRINT("Type %d, Channel ID %d, Device ID 0x%04x, ",
- EXTRACT_U_1(bp + 3), EXTRACT_U_1(bp + 4),
- EXTRACT_BE_U_2(bp + 5));
- if (EXTRACT_U_1(bp + 7))
+ 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 %d, ", EXTRACT_U_1(bp + 8));
-
- zep_print_ts(ndo, bp + 9);
- seq_no = EXTRACT_BE_U_4(bp + 17);
- inner_len = EXTRACT_U_1(bp + 31);
- ND_PRINT(", seq# = %d, inner len = %d",
+ 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;
- trunc:
- ND_PRINT(" [|ZEP]");
+ return;
+invalid:
+ nd_print_invalid(ndo);
}
-
-/*
- * Local Variables:
- * c-style: whitesmith
- * c-basic-offset: 8
- * End:
- */