#include <config.h>
#endif
-#include <netdissect-stdinc.h>
+#include "netdissect-stdinc.h"
+#define ND_LONGJMP_FROM_TCHECK
#include "netdissect.h"
#include "addrtoname.h"
"CTM IE", /* 0x32 */
"Timestamp IE", /* 0x33 */
"Timestamp Difference IE", /* 0x34 */
- "TMCTP Sepcification IE", /* 0x35 */
+ "TMCTP Specification IE", /* 0x35 */
"RCC PHY Operating Mode IE", /* 0x36 */
"Reserved 0x37", /* 0x37 */
"Reserved 0x38", /* 0x38 */
/*
* IEEE 802.15.4 CRC 16 function. This is using CCITT polynomical of 0x1021,
* but the initial value is 0, and the bits are reversed for both in and out.
- * See secton 7.2.10 of 802.15.4-2015 for more information.
+ * See section 7.2.10 of 802.15.4-2015 for more information.
*/
static uint16_t
-ieee802_15_4_crc16(const u_char *p,
+ieee802_15_4_crc16(netdissect_options *ndo, const u_char *p,
u_int data_len)
{
uint16_t crc;
u_char x, y;
-
+
crc = 0x0000; /* Note, initial value is 0x0000 not 0xffff. */
-
- while (data_len--){
- y = *p++;
+
+ while (data_len != 0){
+ y = GET_U_1(p);
+ p++;
/* Reverse bits on input */
y = (((y & 0xaa) >> 1) | ((y & 0x55) << 1));
y = (((y & 0xcc) >> 2) | ((y & 0x33) << 2));
/* Update CRC */
x = crc >> 8 ^ y;
x ^= x >> 4;
- crc = (crc << 8) ^
- ((unsigned short)(x << 12)) ^
- ((unsigned short)(x <<5)) ^
- ((unsigned short)x);
+ crc = ((uint16_t)(crc << 8)) ^
+ ((uint16_t)(x << 12)) ^
+ ((uint16_t)(x << 5)) ^
+ ((uint16_t)x);
+ data_len--;
}
/* Reverse bits on output */
crc = (((crc & 0xaaaa) >> 1) | ((crc & 0x5555) << 1));
/*
* IEEE 802.15.4 CRC 32 function. This is using ANSI X3.66-1979 polynomical of
* 0x04C11DB7, but the initial value is 0, and the bits are reversed for both
- * in and out. See secton 7.2.10 of 802.15.4-2015 for more information.
+ * in and out. See section 7.2.10 of 802.15.4-2015 for more information.
*/
static uint32_t
-ieee802_15_4_crc32(const u_char *p,
+ieee802_15_4_crc32(netdissect_options *ndo, const u_char *p,
u_int data_len)
{
uint32_t crc, byte;
int b;
-
+
crc = 0x00000000; /* Note, initial value is 0x00000000 not 0xffffffff */
-
- while (data_len--){
- byte = *p++;
+
+ while (data_len != 0){
+ byte = GET_U_1(p);
+ p++;
/* Reverse bits on input */
byte = ieee802_15_4_reverse32(byte);
/* Update CRC */
crc = crc << 1;
byte = byte << 1;
}
+ data_len--;
}
/* Reverse bits on output */
crc = ieee802_15_4_reverse32(crc);
ND_PRINT("none");
break;
case 2:
- ND_PRINT("%04x", EXTRACT_LE_U_2(p));
+ ND_PRINT("%04x", GET_LE_U_2(p));
break;
case 8:
- ND_PRINT("%s", le64addr_string(ndo, p));
+ ND_PRINT("%s", GET_LE64ADDR_STRING(p));
break;
}
- return;
}
/*
((ss >> 8) & 0xf));
if (CHECK_BIT(ss, 12)) { ND_PRINT(", BLE enabled"); }
if (CHECK_BIT(ss, 14)) { ND_PRINT(", PAN Coordinator"); }
- if (CHECK_BIT(ss, 15)) { ND_PRINT(", Assocation Permit"); }
+ if (CHECK_BIT(ss, 15)) { ND_PRINT(", Association Permit"); }
}
/*
uint8_t gts_spec, gts_cnt;
u_int len;
int i;
-
- gts_spec = EXTRACT_U_1(p);
+
+ gts_spec = GET_U_1(p);
gts_cnt = gts_spec & 0x7;
-
+
if (gts_cnt == 0) {
if (ndo->ndo_vflag > 0) {
ND_PRINT("\n\tGTS Descriptor Count = %d, ", gts_cnt);
return 1;
}
len = 1 + 1 + gts_cnt * 3;
-
+
if (data_len < len) {
ND_PRINT(" [ERROR: Truncated GTS Info List]");
return -1;
}
ND_PRINT("GTS Descriptor Count = %d, ", gts_cnt);
ND_PRINT("GTS Directions Mask = %02x, [ ",
- EXTRACT_U_1(p + 1) & 0x7f);
-
+ GET_U_1(p + 1) & 0x7f);
+
for(i = 0; i < gts_cnt; i++) {
ND_PRINT("[ ");
ieee802_15_4_print_addr(ndo, p + 2 + i * 3, 2);
ND_PRINT(", Start slot = %d, Length = %d ] ",
- EXTRACT_U_1(p + 2 + i * 3 + 1) & 0x0f,
- (EXTRACT_U_1(p + 2 + i * 3 + 1) >> 4) & 0x0f);
+ GET_U_1(p + 2 + i * 3 + 1) & 0x0f,
+ (GET_U_1(p + 2 + i * 3 + 1) >> 4) & 0x0f);
}
ND_PRINT("]");
return len;
u_int data_len)
{
uint8_t pas, s_cnt, e_cnt, len, i;
-
- pas = EXTRACT_U_1(p);
+
+ pas = GET_U_1(p);
s_cnt = pas & 0x7;
e_cnt = (pas >> 4) & 0x7;
len = 1 + s_cnt * 2 + e_cnt * 8;
}
ND_PRINT("]");
}
- if (s_cnt != 0) {
+ if (e_cnt != 0) {
ND_PRINT(", Extended address list = [ ");
for(i = 0; i < e_cnt; i++) {
ieee802_15_4_print_addr(ndo, p + 1 + s_cnt * 2 +
- e_cnt * 8, 8);
+ i * 8, 8);
ND_PRINT(" ");
}
ND_PRINT("]");
int element_id)
{
int i;
-
+
switch (element_id) {
case 0x00: /* Vendor Specific Header IE */
if (ie_len < 3) {
ND_PRINT("[ERROR: Vendor OUI missing]");
} else {
- ND_PRINT("OUI = 0x%02x%02x%02x, ", EXTRACT_U_1(p),
- EXTRACT_U_1(p + 1), EXTRACT_U_1(p + 2));
+ ND_PRINT("OUI = 0x%02x%02x%02x, ", GET_U_1(p),
+ GET_U_1(p + 1), GET_U_1(p + 2));
ND_PRINT("Data = ");
for(i = 3; i < ie_len; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ", GET_U_1(p + i));
}
}
break;
ND_PRINT("[ERROR: Truncated CSL IE]");
} else {
ND_PRINT("CSL Phase = %d, CSL Period = %d",
- EXTRACT_LE_U_2(p), EXTRACT_LE_U_2(p + 2));
+ GET_LE_U_2(p), GET_LE_U_2(p + 2));
if (ie_len >= 6) {
ND_PRINT(", Rendezvous time = %d",
- EXTRACT_LE_U_2(p + 4));
+ GET_LE_U_2(p + 4));
}
if (ie_len != 4 && ie_len != 6) {
ND_PRINT(" [ERROR: CSL IE length wrong]");
ND_PRINT("[ERROR: Truncated RIT IE]");
} else {
ND_PRINT("Time to First Listen = %d, # of Repeat Listen = %d, Repeat Listen Interval = %d",
- EXTRACT_U_1(p),
- EXTRACT_U_1(p + 1),
- EXTRACT_LE_U_2(p + 2));
+ GET_U_1(p),
+ GET_U_1(p + 1),
+ GET_LE_U_2(p + 2));
}
break;
case 0x1c: /* DSME PAN Descriptor IE */
/*FALLTHROUGH*/
- case 0x21: /* Extended DSME PAN descriptior IE */
+ case 0x21: /* Extended DSME PAN descriptor IE */
if (ie_len < 2) {
ND_PRINT("[ERROR: Truncated DSME PAN IE]");
} else {
uint16_t ss, ptr, ulen;
int16_t len;
int hopping_present;
-
+
hopping_present = 0;
-
- ss = EXTRACT_LE_U_2(p);
+
+ ss = GET_LE_U_2(p);
ieee802_15_4_print_superframe_specification(ndo, ss);
if (ie_len < 3) {
ND_PRINT("[ERROR: Truncated before pending addresses field]");
break;
}
ptr += len;
-
+
if (element_id == 0x21) {
/* Extended version. */
if (ie_len < ptr + 2) {
ND_PRINT("[ERROR: Truncated before DSME Superframe Specification]");
break;
}
- ss = EXTRACT_LE_U_2(p + ptr);
+ ss = GET_LE_U_2(p + ptr);
ptr += 2;
ND_PRINT("Multi-superframe Order = %d", ss & 0xff);
ND_PRINT(", %s", ((ss & 0x100) ?
ND_PRINT("[ERROR: Truncated before DSME Superframe Specification]");
break;
}
- ss = EXTRACT_U_1(p + ptr);
+ ss = GET_U_1(p + ptr);
ptr++;
ND_PRINT("Multi-superframe Order = %d",
ss & 0x0f);
}
}
if (ie_len < ptr + 8) {
- ND_PRINT(" [ERROR: Truncated before Time syncronization specification]");
+ ND_PRINT(" [ERROR: Truncated before Time synchronization specification]");
break;
}
ND_PRINT("Beacon timestamp = %" PRIu64 ", offset = %d",
- EXTRACT_LE_U_6(p + ptr),
- EXTRACT_LE_U_2(p + ptr + 6));
+ GET_LE_U_6(p + ptr),
+ GET_LE_U_2(p + ptr + 6));
ptr += 8;
if (ie_len < ptr + 4) {
ND_PRINT(" [ERROR: Truncated before Beacon Bitmap]");
break;
}
-
- ulen = EXTRACT_LE_U_2(p + ptr + 2);
+
+ ulen = GET_LE_U_2(p + ptr + 2);
ND_PRINT("SD Index = %d, Bitmap len = %d, ",
- EXTRACT_LE_U_2(p + ptr), ulen);
+ GET_LE_U_2(p + ptr), ulen);
ptr += 4;
if (ie_len < ptr + ulen) {
ND_PRINT(" [ERROR: Truncated in SD bitmap]");
}
ND_PRINT(" SD Bitmap = ");
for(i = 0; i < ulen; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + ptr + i));
+ ND_PRINT("%02x ", GET_U_1(p + ptr + i));
}
ptr += ulen;
-
+
if (ie_len < ptr + 5) {
ND_PRINT(" [ERROR: Truncated before Channel hopping specification]");
break;
}
-
- ulen = EXTRACT_LE_U_2(p + ptr + 4);
+
+ ulen = GET_LE_U_2(p + ptr + 4);
ND_PRINT("Hopping Seq ID = %d, PAN Coordinator BSN = %d, "
"Channel offset = %d, Bitmap length = %d, ",
- EXTRACT_U_1(p + ptr),
- EXTRACT_U_1(p + ptr + 1),
- EXTRACT_LE_U_2(p + ptr + 2),
+ GET_U_1(p + ptr),
+ GET_U_1(p + ptr + 1),
+ GET_LE_U_2(p + ptr + 2),
ulen);
ptr += 5;
if (ie_len < ptr + ulen) {
}
ND_PRINT(" Channel offset bitmap = ");
for(i = 0; i < ulen; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + ptr + i));
+ ND_PRINT("%02x ", GET_U_1(p + ptr + i));
}
ptr += ulen;
if (hopping_present) {
ND_PRINT(" [ERROR: Truncated in Hopping Sequence length]");
break;
}
- ulen = EXTRACT_U_1(p + ptr);
+ ulen = GET_U_1(p + ptr);
ptr++;
ND_PRINT("Hopping Seq length = %d [ ", ulen);
-
+
/* The specification is not clear how the
hopping sequence is encoded, I assume two
octet unsigned integers for each channel. */
-
+
if (ie_len < ptr + ulen * 2) {
ND_PRINT(" [ERROR: Truncated in Channel offset bitmap]");
break;
}
for(i = 0; i < ulen; i++) {
- ND_PRINT("%02x ", EXTRACT_LE_U_2(p + ptr + i * 2));
+ ND_PRINT("%02x ",
+ GET_LE_U_2(p + ptr + i * 2));
}
ND_PRINT("]");
ptr += ulen * 2;
ND_PRINT("[ERROR: Length != 2]");
} else {
uint16_t r_time, w_u_interval;
- r_time = EXTRACT_LE_U_2(p);
- w_u_interval = EXTRACT_LE_U_2(p + 2);
-
+ r_time = GET_LE_U_2(p);
+ w_u_interval = GET_LE_U_2(p + 2);
+
ND_PRINT("Rendezvous time = %d, Wake-up Interval = %d",
r_time, w_u_interval);
}
} else {
uint16_t val;
int16_t timecorr;
-
- val = EXTRACT_LE_U_2(p);
+
+ val = GET_LE_U_2(p);
if (val & 0x8000) { ND_PRINT("Negative "); }
val &= 0xfff;
val <<= 4;
timecorr = val;
timecorr >>= 4;
-
+
ND_PRINT("Ack time correction = %d, ", timecorr);
}
break;
- case 0x22: /* Frament Sequence Content Description IE */
+ case 0x22: /* Fragment Sequence Content Description IE */
/* XXX Not implemented */
case 0x23: /* Simplified Superframe Specification IE */
/* XXX Not implemented */
default:
ND_PRINT("IE Data = ");
for(i = 0; i < ie_len; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ", GET_U_1(p + i));
}
break;
}
{
int len, ie, element_id, i;
uint16_t ie_len;
-
+
*payload_ie_present = 0;
len = 0;
do {
return -1;
}
/* Extract IE Header */
- ie = EXTRACT_LE_U_2(p);
+ ie = GET_LE_U_2(p);
if (CHECK_BIT(ie, 15)) {
ND_PRINT("[ERROR: Header IE with type 1] ");
}
h_ie_names[element_id], ie_len);
}
}
- if (caplen < ie_len) {
+ if (caplen < 2U + ie_len) {
ND_PRINT("[ERROR: Truncated IE data]");
return -1;
}
/* Skip header */
p += 2;
-
+
/* Parse and print content. */
if (ndo->ndo_vflag > 3 && ie_len != 0) {
ieee802_15_4_print_header_ie(ndo, p,
if (ie_len != 0) {
ND_PRINT("IE Data = ");
for(i = 0; i < ie_len; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ", GET_U_1(p + i));
}
}
}
if (element_id == 0x7f) {
break;
}
- } while (caplen > 0);
+ } while (caplen != 0);
return len;
}
{
int i, j;
uint16_t len;
-
+
/* Note, as there is no overlap with the long and short
MLME sub IDs, we can just use one switch here. */
switch (sub_id) {
ND_PRINT("[ERROR: Vendor OUI missing]");
} else {
ND_PRINT("OUI = 0x%02x%02x%02x, ",
- EXTRACT_U_1(p),
- EXTRACT_U_1(p + 1),
- EXTRACT_U_1(p + 2));
+ GET_U_1(p),
+ GET_U_1(p + 1),
+ GET_U_1(p + 2));
ND_PRINT("Data = ");
for(i = 3; i < sub_ie_len; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ", GET_U_1(p + i));
}
}
break;
if (sub_ie_len < 1) {
ND_PRINT("[ERROR: Hopping sequence ID missing]");
} else if (sub_ie_len == 1) {
- ND_PRINT("Hopping Sequence ID = %d", EXTRACT_U_1(p));
+ ND_PRINT("Hopping Sequence ID = %d", GET_U_1(p));
p++;
sub_ie_len--;
} else {
uint16_t channel_page, number_of_channels;
-
- ND_PRINT("Hopping Sequence ID = %d", EXTRACT_U_1(p));
+
+ ND_PRINT("Hopping Sequence ID = %d", GET_U_1(p));
p++;
sub_ie_len--;
if (sub_ie_len < 7) {
ND_PRINT("[ERROR: IE truncated]");
break;
}
- channel_page = EXTRACT_U_1(p);
- number_of_channels = EXTRACT_LE_U_2(p + 1);
+ channel_page = GET_U_1(p);
+ number_of_channels = GET_LE_U_2(p + 1);
ND_PRINT("Channel Page = %d, Number of Channels = %d, ",
channel_page, number_of_channels);
ND_PRINT("Phy Configuration = 0x%08x, ",
- EXTRACT_LE_U_4(p + 3));
+ GET_LE_U_4(p + 3));
p += 7;
sub_ie_len -= 7;
if (channel_page == 9 || channel_page == 10) {
}
ND_PRINT("Extended bitmap = 0x");
for(i = 0; i < len; i++) {
- ND_PRINT("%02x", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x", GET_U_1(p + i));
}
ND_PRINT(", ");
p += len;
ND_PRINT("[ERROR: IE truncated]");
break;
}
- len = EXTRACT_LE_U_2(p);
+ len = GET_LE_U_2(p);
p += 2;
sub_ie_len -= 2;
ND_PRINT("Hopping Seq length = %d [ ", len);
-
+
if (sub_ie_len < len * 2) {
ND_PRINT(" [ERROR: IE truncated]");
break;
}
for(i = 0; i < len; i++) {
- ND_PRINT("%02x ", EXTRACT_LE_U_2(p + i * 2));
+ ND_PRINT("%02x ", GET_LE_U_2(p + i * 2));
}
ND_PRINT("]");
p += len * 2;
ND_PRINT("[ERROR: IE truncated]");
break;
}
- ND_PRINT("Current hop = %d", EXTRACT_LE_U_2(p));
+ ND_PRINT("Current hop = %d", GET_LE_U_2(p));
}
-
+
break;
- case 0x1a: /* TSCH Syncronization IE. */
+ case 0x1a: /* TSCH Synchronization IE. */
if (sub_ie_len < 6) {
ND_PRINT("[ERROR: Length != 6]");
}
ND_PRINT("ASN = %010" PRIx64 ", Join Metric = %d ",
- EXTRACT_LE_U_5(p), EXTRACT_U_1(p + 5));
+ GET_LE_U_5(p), GET_U_1(p + 5));
break;
case 0x1b: /* TSCH Slotframe and Link IE. */
{
int sf_num, off, links, opts;
-
+
if (sub_ie_len < 1) {
ND_PRINT("[ERROR: Truncated IE]");
break;
}
- sf_num = EXTRACT_U_1(p);
+ sf_num = GET_U_1(p);
ND_PRINT("Slotframes = %d ", sf_num);
off = 1;
for(i = 0; i < sf_num; i++) {
ND_PRINT("[ERROR: Truncated IE before slotframes]");
break;
}
- links = EXTRACT_U_1(p + off + 3);
+ links = GET_U_1(p + off + 3);
ND_PRINT("\n\t\t\t[ Handle %d, size = %d, links = %d ",
- EXTRACT_U_1(p + off),
- EXTRACT_LE_U_2(p + off + 1),
+ GET_U_1(p + off),
+ GET_LE_U_2(p + off + 1),
links);
off += 4;
for(j = 0; j < links; j++) {
ND_PRINT("[ERROR: Truncated IE links]");
break;
}
- opts = EXTRACT_U_1(p + off + 4);
+ opts = GET_U_1(p + off + 4);
ND_PRINT("\n\t\t\t\t[ Timeslot = %d, Offset = %d, Options = ",
- EXTRACT_LE_U_2(p + off),
- EXTRACT_LE_U_2(p + off + 2));
+ GET_LE_U_2(p + off),
+ GET_LE_U_2(p + off + 2));
if (opts & 0x1) { ND_PRINT("TX "); }
if (opts & 0x2) { ND_PRINT("RX "); }
if (opts & 0x4) { ND_PRINT("Shared "); }
break;
case 0x1c: /* TSCH Timeslot IE. */
if (sub_ie_len == 1) {
- ND_PRINT("Time slot ID = %d ", EXTRACT_U_1(p));
+ ND_PRINT("Time slot ID = %d ", GET_U_1(p));
} else if (sub_ie_len == 25) {
ND_PRINT("Time slot ID = %d, CCA Offset = %d, CCA = %d, TX Offset = %d, RX Offset = %d, RX Ack Delay = %d, TX Ack Delay = %d, RX Wait = %d, Ack Wait = %d, RX TX = %d, Max Ack = %d, Max TX = %d, Time slot Length = %d ",
- EXTRACT_U_1(p),
- EXTRACT_LE_U_2(p + 1),
- EXTRACT_LE_U_2(p + 3),
- EXTRACT_LE_U_2(p + 5),
- EXTRACT_LE_U_2(p + 7),
- EXTRACT_LE_U_2(p + 9),
- EXTRACT_LE_U_2(p + 11),
- EXTRACT_LE_U_2(p + 13),
- EXTRACT_LE_U_2(p + 15),
- EXTRACT_LE_U_2(p + 17),
- EXTRACT_LE_U_2(p + 19),
- EXTRACT_LE_U_2(p + 21),
- EXTRACT_LE_U_2(p + 23));
+ GET_U_1(p),
+ GET_LE_U_2(p + 1),
+ GET_LE_U_2(p + 3),
+ GET_LE_U_2(p + 5),
+ GET_LE_U_2(p + 7),
+ GET_LE_U_2(p + 9),
+ GET_LE_U_2(p + 11),
+ GET_LE_U_2(p + 13),
+ GET_LE_U_2(p + 15),
+ GET_LE_U_2(p + 17),
+ GET_LE_U_2(p + 19),
+ GET_LE_U_2(p + 21),
+ GET_LE_U_2(p + 23));
} else if (sub_ie_len == 27) {
ND_PRINT("Time slot ID = %d, CCA Offset = %d, CCA = %d, TX Offset = %d, RX Offset = %d, RX Ack Delay = %d, TX Ack Delay = %d, RX Wait = %d, Ack Wait = %d, RX TX = %d, Max Ack = %d, Max TX = %d, Time slot Length = %d ",
- EXTRACT_U_1(p),
- EXTRACT_LE_U_2(p + 1),
- EXTRACT_LE_U_2(p + 3),
- EXTRACT_LE_U_2(p + 5),
- EXTRACT_LE_U_2(p + 7),
- EXTRACT_LE_U_2(p + 9),
- EXTRACT_LE_U_2(p + 11),
- EXTRACT_LE_U_2(p + 13),
- EXTRACT_LE_U_2(p + 15),
- EXTRACT_LE_U_2(p + 17),
- EXTRACT_LE_U_2(p + 19),
- EXTRACT_LE_U_3(p + 21),
- EXTRACT_LE_U_3(p + 24));
+ GET_U_1(p),
+ GET_LE_U_2(p + 1),
+ GET_LE_U_2(p + 3),
+ GET_LE_U_2(p + 5),
+ GET_LE_U_2(p + 7),
+ GET_LE_U_2(p + 9),
+ GET_LE_U_2(p + 11),
+ GET_LE_U_2(p + 13),
+ GET_LE_U_2(p + 15),
+ GET_LE_U_2(p + 17),
+ GET_LE_U_2(p + 19),
+ GET_LE_U_3(p + 21),
+ GET_LE_U_3(p + 24));
} else {
ND_PRINT("[ERROR: Length not 1, 25, or 27]");
ND_PRINT("\n\t\t\tIE Data = ");
for(i = 0; i < sub_ie_len; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ", GET_U_1(p + i));
}
}
break;
/* XXX Not implemented */
case 0x2c: /* TVWS Device Capabilities IE */
/* XXX Not implemented */
- case 0x2d: /* TVWS Device Catagory IE */
+ case 0x2d: /* TVWS Device Category IE */
/* XXX Not implemented */
case 0x2e: /* TVWS Device Identification IE */
/* XXX Not implemented */
default:
ND_PRINT("IE Data = ");
for(i = 0; i < sub_ie_len; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ", GET_U_1(p + i));
}
break;
}
{
int ie, sub_id, i, type;
uint16_t sub_ie_len;
-
+
do {
if (ie_len < 2) {
ND_PRINT("[ERROR: Truncated MLME IE]");
return;
}
/* Extract IE header */
- ie = EXTRACT_LE_U_2(p);
+ ie = GET_LE_U_2(p);
type = CHECK_BIT(ie, 15);
if (type) {
/* Long type */
sub_ie_len = ie & 0xff;
sub_id = (ie >> 8) & 0x7f;
}
-
+
/* Skip the IE header */
p += 2;
-
+
if (type == 0) {
ND_PRINT("\n\t\t%s [ length = %d, ",
p_mlme_short_names[sub_id], sub_ie_len);
ND_PRINT("\n\t\t%s [ length = %d, ",
p_mlme_long_names[sub_id], sub_ie_len);
}
-
- if (ie_len < sub_ie_len) {
+
+ if (ie_len < 2 + sub_ie_len) {
ND_PRINT("[ERROR: Truncated IE data]");
return;
}
} else if (ndo->ndo_vflag > 2) {
ND_PRINT("IE Data = ");
for(i = 0; i < sub_ie_len; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ", GET_U_1(p + i));
}
}
}
p += sub_ie_len;
ie_len -= 2 + sub_ie_len;
} while (ie_len > 0);
- return;
}
/*
ND_PRINT("[ERROR: Transaction control byte missing]");
return;
}
-
- transfer_type = EXTRACT_U_1(p) & 0x7;
- tid = EXTRACT_U_1(p) >> 3;
+
+ transfer_type = GET_U_1(p) & 0x7;
+ tid = GET_U_1(p) >> 3;
switch (transfer_type) {
case 0x00: /* Full upper layer frame. */
case 0x01: /* Full upper layer frame with small Multiplex ID. */
if (ie_len < 3) {
ND_PRINT("[ERROR: Multiplex ID missing]");
return;
- }
+ }
data_start = 3;
ND_PRINT("tid = 0x%02x, Multiplex ID = 0x%04x, ",
- tid, EXTRACT_LE_U_2(p + 1));
+ tid, GET_LE_U_2(p + 1));
} else {
data_start = 1;
ND_PRINT("Multiplex ID = 0x%04x, ", tid);
ND_PRINT("[ERROR: fragment number missing]");
return;
}
-
- fragment_number = EXTRACT_U_1(p + 1);
+
+ fragment_number = GET_U_1(p + 1);
ND_PRINT("Type = %s, tid = 0x%02x, fragment = 0x%02x, ",
(transfer_type == 0x02 ?
(fragment_number == 0 ?
data_start = 2;
if (fragment_number == 0) {
int total_size, multiplex_id;
-
+
if (ie_len < 6) {
ND_PRINT("[ERROR: Total upper layer size or multiplex ID missing]");
return;
}
- total_size = EXTRACT_LE_U_2(p + 2);
- multiplex_id = EXTRACT_LE_U_2(p + 4);
+ total_size = GET_LE_U_2(p + 2);
+ multiplex_id = GET_LE_U_2(p + 4);
ND_PRINT("Total upper layer size = 0x%04x, Multiplex ID = 0x%04x, ",
total_size, multiplex_id);
data_start = 6;
tid);
} else if (ie_len == 3) {
ND_PRINT("Type = Abort, tid = 0x%02x, max size = 0x%04x",
- tid, EXTRACT_LE_U_2(p + 1));
+ tid, GET_LE_U_2(p + 1));
} else {
ND_PRINT("Type = Abort, tid = 0x%02x, invalid length = %d (not 1 or 3)",
tid, ie_len);
ND_PRINT("Abort data = ");
for(i = 1; i < ie_len; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ", GET_U_1(p + i));
}
}
return;
ND_PRINT("Upper layer data = ");
for(i = data_start; i < ie_len; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ", GET_U_1(p + i));
}
}
{
int len, ie, group_id, i;
uint16_t ie_len;
-
+
len = 0;
do {
if (caplen < 2) {
return -1;
}
/* Extract IE header */
- ie = EXTRACT_LE_U_2(p);
+ ie = GET_LE_U_2(p);
if ((CHECK_BIT(ie, 15)) == 0) {
ND_PRINT("[ERROR: Payload IE with type 0] ");
}
ie_len = ie & 0x3ff;
group_id = (ie >> 11) & 0x0f;
-
+
/* Skip the IE header */
p += 2;
if (ie_len == 0) {
ND_PRINT("\n\t%s [ length = %d, ",
p_ie_names[group_id], ie_len);
}
- if (caplen < ie_len) {
+ if (caplen < 2U + ie_len) {
ND_PRINT("[ERROR: Truncated IE data]");
return -1;
}
ND_PRINT("[ERROR: Vendor OUI missing]");
} else {
ND_PRINT("OUI = 0x%02x%02x%02x, ",
- EXTRACT_U_1(p),
- EXTRACT_U_1(p + 1),
- EXTRACT_U_1(p + 2));
+ GET_U_1(p),
+ GET_U_1(p + 1),
+ GET_U_1(p + 2));
ND_PRINT("Data = ");
for(i = 3; i < ie_len; i++) {
ND_PRINT("%02x ",
- EXTRACT_U_1(p + i));
+ GET_U_1(p + i));
}
}
break;
case 0x5: /* IETF IE */
if (ie_len < 1) {
ND_PRINT("[ERROR: Subtype ID missing]");
- } else {
+ } else {
ND_PRINT("Subtype ID = 0x%02x, Subtype content = ",
- EXTRACT_U_1(p));
+ GET_U_1(p));
for(i = 1; i < ie_len; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ",
+ GET_U_1(p + i));
}
}
break;
default:
ND_PRINT("IE Data = ");
for(i = 0; i < ie_len; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ", GET_U_1(p + i));
}
break;
}
if (ie_len != 0) {
ND_PRINT("IE Data = ");
for(i = 0; i < ie_len; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ", GET_U_1(p + i));
}
}
}
int *security_level)
{
int sc, key_id_mode, len;
-
+
if (caplen < 1) {
ND_PRINT("[ERROR: Truncated before Aux Security Header]");
return -1;
}
- sc = EXTRACT_U_1(p);
+ sc = GET_U_1(p);
len = 1;
*security_level = sc & 0x7;
key_id_mode = (sc >> 3) & 0x3;
-
+
caplen -= 1;
p += 1;
-
+
if (ndo->ndo_vflag > 0) {
ND_PRINT("\n\tSecurity Level %d, Key Id Mode %d, ",
*security_level, key_id_mode);
ND_PRINT("[ERROR: Truncated before Frame Counter]");
return -1;
}
- len += 4;
- caplen -= 4;
- p += 4;
if (ndo->ndo_vflag > 1) {
ND_PRINT("Frame Counter 0x%08x ",
- EXTRACT_LE_U_4(p + 1));
+ GET_LE_U_4(p));
}
+ p += 4;
+ caplen -= 4;
+ len += 4;
}
switch (key_id_mode) {
case 0x00: /* Implicit. */
}
if (ndo->ndo_vflag > 1) {
ND_PRINT("KeySource 0x%04x:%0x4x, ",
- EXTRACT_LE_U_2(p), EXTRACT_LE_U_2(p + 2));
+ GET_LE_U_2(p), GET_LE_U_2(p + 2));
}
p += 4;
caplen -= 4;
return -1;
}
if (ndo->ndo_vflag > 1) {
- ND_PRINT("KeySource %s, ", le64addr_string(ndo, p));
+ ND_PRINT("KeySource %s, ", GET_LE64ADDR_STRING(p));
}
p += 4;
caplen -= 4;
return -1;
}
if (ndo->ndo_vflag > 1) {
- ND_PRINT("KeyIndex 0x%02x, ", EXTRACT_U_1(p));
+ ND_PRINT("KeyIndex 0x%02x, ", GET_U_1(p));
}
caplen -= 1;
p += 1;
u_int caplen)
{
u_int i;
-
+
switch (command_id) {
- case 0x01: /* Assocation Request */
+ case 0x01: /* Association Request */
if (caplen != 1) {
- ND_PRINT("Invalid Assocation request command length");
+ ND_PRINT("Invalid Association request command length");
return -1;
} else {
uint8_t cap_info;
- cap_info = EXTRACT_U_1(p);
+ cap_info = GET_U_1(p);
ND_PRINT("%s%s%s%s%s%s",
((cap_info & 0x02) ?
"FFD, " : "RFD, "),
return caplen;
}
break;
- case 0x02: /* Assocation Response */
+ case 0x02: /* Association Response */
if (caplen != 3) {
- ND_PRINT("Invalid Assocation response command length");
+ ND_PRINT("Invalid Association response command length");
return -1;
} else {
ND_PRINT("Short address = ");
ieee802_15_4_print_addr(ndo, p, 2);
- switch (EXTRACT_U_1(p + 2)) {
+ switch (GET_U_1(p + 2)) {
case 0x00:
ND_PRINT(", Association successful");
break;
break;
default:
ND_PRINT(", Status = 0x%02x",
- EXTRACT_U_1(p + 2));
+ GET_U_1(p + 2));
break;
}
return caplen;
ND_PRINT("Invalid Disassociation Notification command length");
return -1;
} else {
- switch (EXTRACT_U_1(p)) {
+ switch (GET_U_1(p)) {
case 0x00:
ND_PRINT("Reserved");
break;
ND_PRINT("Reason = The device wishes to leave the PAN");
break;
default:
- ND_PRINT("Reason = 0x%02x", EXTRACT_U_1(p + 2));
+ ND_PRINT("Reason = 0x%02x", GET_U_1(p + 2));
break;
}
return caplen;
}
-
+
/* Following ones do not have any data. */
case 0x04: /* Data Request command */
case 0x05: /* PAN ID Conflict Notification command */
return -1;
} else {
uint16_t channel, page;
-
+
ND_PRINT("Pan ID = 0x%04x, Coordinator short address = ",
- EXTRACT_LE_U_2(p));
+ GET_LE_U_2(p));
ieee802_15_4_print_addr(ndo, p + 2, 2);
- channel = EXTRACT_U_1(p + 4);
-
+ channel = GET_U_1(p + 4);
+
if (caplen == 8) {
- page = EXTRACT_U_1(p + 7);
+ page = GET_U_1(p + 7);
} else {
page = 0x80;
}
return -1;
} else {
uint8_t gts;
-
- gts = EXTRACT_U_1(p);
+
+ gts = GET_U_1(p);
ND_PRINT("GTS Length = %d, %s, %s",
gts & 0xf,
(CHECK_BIT(gts, 4) ?
/* XXX Not implemented */
case 0x16: /* DSME GTS Response command */
/* XXX Not implemented */
- case 0x17: /* DSME GTS GTS Notify command */
+ case 0x17: /* DSME GTS Notify command */
/* XXX Not implemented */
case 0x18: /* DSME Information Request command */
/* XXX Not implemented */
default:
ND_PRINT("Command Data = ");
for(i = 0; i < caplen; i++) {
- ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+ ND_PRINT("%02x ", GET_U_1(p + i));
}
break;
}
}
/*
- * Parse and print frames folloing standard format.
+ * Parse and print frames following standard format.
*
* Returns FALSE in case of error.
*/
int len, frame_version, pan_id_comp;
int frame_type;
int src_pan, dst_pan, src_addr_len, dst_addr_len;
- int security_level, miclen = 0;
+ int security_level;
+ u_int miclen = 0;
int payload_ie_present;
uint8_t seq;
uint32_t fcs, crc_check;
const u_char *mic_start = NULL;
-
+
payload_ie_present = 0;
crc_check = 0;
fcs = 0;
} else {
/* Test for 4 octet FCS. */
- fcs = EXTRACT_LE_U_4(p + caplen - 4);
- crc_check = ieee802_15_4_crc32(p, caplen - 4);
+ fcs = GET_LE_U_4(p + caplen - 4);
+ crc_check = ieee802_15_4_crc32(ndo, p, caplen - 4);
if (crc_check == fcs) {
/* Remove FCS */
caplen -= 4;
} else {
/* Test for 2 octet FCS. */
- fcs = EXTRACT_LE_U_2(p + caplen - 2);
- crc_check = ieee802_15_4_crc16(p, caplen - 2);
+ fcs = GET_LE_U_2(p + caplen - 2);
+ crc_check = ieee802_15_4_crc16(ndo, p, caplen - 2);
if (crc_check == fcs) {
/* Remove FCS */
caplen -= 2;
}
}
}
-
+
/* Frame version. */
frame_version = FC_FRAME_VERSION(fc);
frame_type = FC_FRAME_TYPE(fc);
ND_PRINT("v%d ", frame_version);
-
+
if (ndo->ndo_vflag > 2) {
if (CHECK_BIT(fc, 3)) { ND_PRINT("Security Enabled, "); }
if (CHECK_BIT(fc, 4)) { ND_PRINT("Frame Pending, "); }
if (CHECK_BIT(fc, 8)) { ND_PRINT("Sequence Number Suppression, "); }
if (CHECK_BIT(fc, 9)) { ND_PRINT("IE present, "); }
}
-
- /* Check for the sequence number supression. */
+
+ /* Check for the sequence number suppression. */
if (CHECK_BIT(fc, 8)) {
/* Sequence number is suppressed. */
if (frame_version < 2) {
- /* Sequence number can only be supressed for frame
+ /* Sequence number can only be suppressed for frame
version 2 or higher, this is invalid frame. */
ND_PRINT("[ERROR: Sequence number suppressed on frames where version < 2]");
}
if (ndo->ndo_vflag)
ND_PRINT("seq suppressed ");
+ if (caplen < 2) {
+ nd_print_trunc(ndo);
+ return 0;
+ }
p += 2;
caplen -= 2;
} else {
- seq = EXTRACT_U_1(p + 2);
- p += 3;
- caplen -= 3;
+ seq = GET_U_1(p + 2);
if (ndo->ndo_vflag)
ND_PRINT("seq %02x ", seq);
+ if (caplen < 3) {
+ nd_print_trunc(ndo);
+ return 0;
+ }
+ p += 3;
+ caplen -= 3;
}
-
+
/* See which parts of addresses we have. */
dst_addr_len = ieee802_15_4_addr_len((fc >> 10) & 0x3);
src_addr_len = ieee802_15_4_addr_len((fc >> 14) & 0x3);
src_pan = 0;
dst_pan = 0;
pan_id_comp = CHECK_BIT(fc, 6);
-
+
/* The PAN ID Compression rules are complicated. */
-
+
/* First check old versions, where the rules are simple. */
if (frame_version < 2) {
if (pan_id_comp) {
#endif /* BROKEN_6TISCH_PAN_ID_COMPRESSION */
}
}
-
+
/* Print dst PAN and address. */
if (dst_pan) {
if (caplen < 2) {
ND_PRINT("[ERROR: Truncated before dst_pan]");
return 0;
}
- ND_PRINT("%04x:", EXTRACT_LE_U_2(p));
+ ND_PRINT("%04x:", GET_LE_U_2(p));
p += 2;
caplen -= 2;
} else {
ieee802_15_4_print_addr(ndo, p, dst_addr_len);
p += dst_addr_len;
caplen -= dst_addr_len;
-
+
ND_PRINT(" < ");
-
+
/* Print src PAN and address. */
if (src_pan) {
if (caplen < 2) {
ND_PRINT("[ERROR: Truncated before dst_pan]");
return 0;
}
- ND_PRINT("%04x:", EXTRACT_LE_U_2(p));
+ ND_PRINT("%04x:", GET_LE_U_2(p));
p += 2;
caplen -= 2;
} else {
p += src_addr_len;
caplen -= src_addr_len;
if (CHECK_BIT(fc, 3)) {
+ /*
+ * XXX - if frame_version is 0, this is the 2003
+ * spec, and you don't have the auxiliary security
+ * header, you have a frame counter and key index
+ * for the AES-CTR and AES-CCM security suites but
+ * not for the AES-CBC-MAC security suite.
+ */
len = ieee802_15_4_print_aux_sec_header(ndo, p, caplen,
&security_level);
if (len < 0) {
return 0;
}
+ ND_TCHECK_LEN(p, len);
p += len;
caplen -= len;
} else {
security_level = 0;
}
-
+
switch (security_level) {
case 0: /*FALLTHOUGH */
case 4:
miclen = 16;
break;
}
-
+
/* Remove MIC */
- if (miclen > 0) {
- if (caplen < (u_int) miclen) {
+ if (miclen != 0) {
+ if (caplen < miclen) {
ND_PRINT("[ERROR: Truncated before MIC]");
return 0;
}
caplen -= miclen;
mic_start = p + caplen;
}
-
+
/* Parse Information elements if present */
if (CHECK_BIT(fc, 9)) {
/* Yes we have those. */
p += len;
caplen -= len;
}
-
+
if (payload_ie_present) {
if (security_level >= 4) {
ND_PRINT("Payload IEs present, but encrypted, cannot print ");
caplen -= len;
}
}
-
+
/* Print MIC */
if (ndo->ndo_vflag > 2 && miclen != 0) {
ND_PRINT("\n\tMIC ");
-
- for(len = 0; len < miclen; len++) {
- ND_PRINT("%02x", EXTRACT_U_1(mic_start + len));
+
+ for (u_int micoffset = 0; micoffset < miclen; micoffset++) {
+ ND_PRINT("%02x", GET_U_1(mic_start + micoffset));
}
ND_PRINT(" ");
}
-
+
/* Print FCS */
if (ndo->ndo_vflag > 2) {
if (crc_check == fcs) {
fcs, crc_check);
}
}
-
+
/* Payload print */
switch (frame_type) {
case 0x00: /* Beacon */
break;
} else {
uint16_t ss;
-
- ss = EXTRACT_LE_U_2(p);
+
+ ss = GET_LE_U_2(p);
ieee802_15_4_print_superframe_specification(ndo, ss);
p += 2;
caplen -= 2;
-
+
/* GTS */
if (caplen < 1) {
ND_PRINT("[ERROR: Truncated before GTS info]");
break;
}
-
+
len = ieee802_15_4_print_gts_info(ndo, p, caplen);
if (len < 0) {
break;
}
-
+
p += len;
caplen -= len;
-
+
/* Pending Addresses */
if (caplen < 1) {
ND_PRINT("[ERROR: Truncated before pending addresses]");
if (len < 0) {
break;
}
+ ND_TCHECK_LEN(p, len);
p += len;
caplen -= len;
}
}
if (!ndo->ndo_suppress_default_print)
ND_DEFAULTPRINT(p, caplen);
-
+
break;
case 0x01: /* Data */
case 0x02: /* Acknowledgement */
ND_PRINT("[ERROR: Truncated before Command ID]");
} else {
uint8_t command_id;
-
- command_id = EXTRACT_U_1(p);
+
+ command_id = GET_U_1(p);
if (command_id >= 0x30) {
ND_PRINT("Command ID = Reserved 0x%02x ",
command_id);
{
int len, frame_version, pan_id_present;
int src_addr_len, dst_addr_len;
- int security_level, miclen = 0;
+ int security_level;
+ u_int miclen = 0;
int ie_present, payload_ie_present, security_enabled;
uint8_t seq;
uint32_t fcs, crc_check;
const u_char *mic_start = NULL;
-
+
pan_id_present = 0;
ie_present = 0;
payload_ie_present = 0;
security_enabled = 0;
crc_check = 0;
-
+
/* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not
know about that. */
if (caplen < 3) {
} else {
if (caplen > 4) {
/* Test for 4 octet FCS. */
- fcs = EXTRACT_LE_U_4(p + caplen - 4);
- crc_check = ieee802_15_4_crc32(p, caplen - 4);
+ fcs = GET_LE_U_4(p + caplen - 4);
+ crc_check = ieee802_15_4_crc32(ndo, p, caplen - 4);
if (crc_check == fcs) {
/* Remove FCS */
caplen -= 4;
} else {
- fcs = EXTRACT_LE_U_2(p + caplen - 2);
- crc_check = ieee802_15_4_crc16(p, caplen - 2);
+ fcs = GET_LE_U_2(p + caplen - 2);
+ crc_check = ieee802_15_4_crc16(ndo, p, caplen - 2);
if (crc_check == fcs) {
/* Remove FCS */
caplen -= 2;
}
}
} else {
- fcs = EXTRACT_LE_U_2(p + caplen - 2);
- crc_check = ieee802_15_4_crc16(p, caplen - 2);
+ fcs = GET_LE_U_2(p + caplen - 2);
+ crc_check = ieee802_15_4_crc16(ndo, p, caplen - 2);
if (crc_check == fcs) {
/* Remove FCS */
caplen -= 2;
}
}
}
-
+
if (CHECK_BIT(fc, 3)) {
/* Long Frame Control */
-
+
/* Frame version. */
frame_version = FC_FRAME_VERSION(fc);
ND_PRINT("v%d ", frame_version);
-
+
pan_id_present = CHECK_BIT(fc, 8);
ie_present = CHECK_BIT(fc, 15);
security_enabled = CHECK_BIT(fc, 9);
-
+
if (ndo->ndo_vflag > 2) {
if (security_enabled) { ND_PRINT("Security Enabled, "); }
if (CHECK_BIT(fc, 11)) { ND_PRINT("Frame Pending, "); }
}
if (ie_present) { ND_PRINT("IE present, "); }
}
-
- /* Check for the sequence number supression. */
+
+ /* Check for the sequence number suppression. */
if (CHECK_BIT(fc, 10)) {
/* Sequence number is suppressed, but long version. */
+ if (caplen < 2) {
+ nd_print_trunc(ndo);
+ return 0;
+ }
p += 2;
caplen -= 2;
} else {
- seq = EXTRACT_U_1(p + 2);
- p += 3;
- caplen -= 3;
+ seq = GET_U_1(p + 2);
if (ndo->ndo_vflag)
ND_PRINT("seq %02x ", seq);
+ if (caplen < 3) {
+ nd_print_trunc(ndo);
+ return 0;
+ }
+ p += 3;
+ caplen -= 3;
}
} else {
/* Short format of header, but with seq no */
- seq = EXTRACT_U_1(p + 1);
+ seq = GET_U_1(p + 1);
p += 2;
caplen -= 2;
if (ndo->ndo_vflag)
ND_PRINT("seq %02x ", seq);
}
-
+
/* See which parts of addresses we have. */
dst_addr_len = ieee802_15_4_addr_len((fc >> 4) & 0x3);
src_addr_len = ieee802_15_4_addr_len((fc >> 6) & 0x3);
ND_PRINT("[ERROR: Invalid dst address mode]");
return 0;
}
-
+
/* Print dst PAN and address. */
if (pan_id_present) {
if (caplen < 2) {
ND_PRINT("[ERROR: Truncated before dst_pan]");
return 0;
}
- ND_PRINT("%04x:", EXTRACT_LE_U_2(p));
+ ND_PRINT("%04x:", GET_LE_U_2(p));
p += 2;
caplen -= 2;
} else {
ieee802_15_4_print_addr(ndo, p, dst_addr_len);
p += dst_addr_len;
caplen -= dst_addr_len;
-
+
ND_PRINT(" < ");
-
+
/* Print src PAN and address. */
ND_PRINT(" -:");
if (caplen < (u_int) src_addr_len) {
ND_PRINT(" ");
p += src_addr_len;
caplen -= src_addr_len;
-
+
if (security_enabled) {
len = ieee802_15_4_print_aux_sec_header(ndo, p, caplen,
&security_level);
if (len < 0) {
return 0;
}
+ ND_TCHECK_LEN(p, len);
p += len;
caplen -= len;
} else {
security_level = 0;
}
-
+
switch (security_level) {
case 0: /*FALLTHOUGH */
case 4:
miclen = 16;
break;
}
-
+
/* Remove MIC */
- if (miclen > 0) {
- if (caplen < (u_int) miclen) {
+ if (miclen != 0) {
+ if (caplen < miclen) {
ND_PRINT("[ERROR: Truncated before MIC]");
return 0;
}
caplen -= miclen;
mic_start = p + caplen;
}
-
+
/* Parse Information elements if present */
if (ie_present) {
/* Yes we have those. */
p += len;
caplen -= len;
}
-
+
if (payload_ie_present) {
if (security_level >= 4) {
ND_PRINT("Payload IEs present, but encrypted, cannot print ");
caplen -= len;
}
}
-
+
/* Print MIC */
if (ndo->ndo_vflag > 2 && miclen != 0) {
ND_PRINT("\n\tMIC ");
-
- for(len = 0; len < miclen; len++) {
- ND_PRINT("%02x", EXTRACT_U_1(mic_start + len));
+
+ for (u_int micoffset = 0; micoffset < miclen; micoffset++) {
+ ND_PRINT("%02x", GET_U_1(mic_start + micoffset));
}
ND_PRINT(" ");
}
-
-
+
+
/* Print FCS */
if (ndo->ndo_vflag > 2) {
if (crc_check == fcs) {
fcs, crc_check);
}
}
-
+
if (!ndo->ndo_suppress_default_print)
ND_DEFAULTPRINT(p, caplen);
-
+
return 1;
}
}
/*
- * Interal call to dissector taking packet + len instead of pcap_pkthdr.
+ * Internal call to dissector taking packet + len instead of pcap_pkthdr.
*
* Returns FALSE in case of error.
*/
{
int frame_type;
uint16_t fc;
-
- ndo->ndo_protocol ="802.15.4";
+
+ ndo->ndo_protocol = "802.15.4";
if (caplen < 2) {
nd_print_trunc(ndo);
return caplen;
}
-
- fc = EXTRACT_LE_U_2(p);
-
+
+ fc = GET_LE_U_2(p);
+
/* First we need to check the frame type to know how to parse the rest
of the FC. Frame type is the first 3 bit of the frame control field.
*/
-
+
frame_type = FC_FRAME_TYPE(fc);
ND_PRINT("IEEE 802.15.4 %s packet ", ftypes[frame_type]);
-
+
switch (frame_type) {
case 0x00: /* Beacon */
case 0x01: /* Data */
* Main function to print packets.
*/
-u_int
+void
ieee802_15_4_if_print(netdissect_options *ndo,
const struct pcap_pkthdr *h, const u_char *p)
{
u_int caplen = h->caplen;
- ndo->ndo_protocol ="802.15.4_if";
- return ieee802_15_4_print(ndo, p, caplen);
+ ndo->ndo_protocol = "802.15.4";
+ ndo->ndo_ll_hdr_len += ieee802_15_4_print(ndo, p, caplen);
}
-/*
- * Local Variables:
- * c-style: whitesmith
- * c-basic-offset: 8
- * End:
- */
+/* For DLT_IEEE802_15_4_TAP */
+/* https://github.com/jkcko/ieee802.15.4-tap */
+void
+ieee802_15_4_tap_if_print(netdissect_options *ndo,
+ const struct pcap_pkthdr *h, const u_char *p)
+{
+ uint8_t version;
+ uint16_t length;
+
+ ndo->ndo_protocol = "802.15.4_tap";
+ if (h->caplen < 4) {
+ nd_print_trunc(ndo);
+ ndo->ndo_ll_hdr_len += h->caplen;
+ return;
+ }
+
+ version = GET_U_1(p);
+ length = GET_LE_U_2(p + 2);
+ if (version != 0 || length < 4) {
+ nd_print_invalid(ndo);
+ return;
+ }
+
+ if (h->caplen < length) {
+ nd_print_trunc(ndo);
+ ndo->ndo_ll_hdr_len += h->caplen;
+ return;
+ }
+
+ ndo->ndo_ll_hdr_len += ieee802_15_4_print(ndo, p+length, h->caplen-length) + length;
+}