]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-802_15_4.c
Makefile.in: don't remove configure and config.h.in in make distclean.
[tcpdump] / print-802_15_4.c
index abb8b2e920aec5003000405bbfbe2af911a50c8f..1895be7ca19b9a8a420ffb0fd3c4723088180d2a 100644 (file)
 /* \summary: IEEE 802.15.4 printer */
 
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
-#include <netdissect-stdinc.h>
+#include "netdissect-stdinc.h"
 
+#define ND_LONGJMP_FROM_TCHECK
 #include "netdissect.h"
 #include "addrtoname.h"
 
 
 /* Frame types from Table 7-1 of 802.15.4-2015 */
 static const char *ftypes[] = {
-  "Beacon",                    /* 0 */
-  "Data",                      /* 1 */
-  "ACK",                       /* 2 */
-  "Command",                   /* 3 */
-  "Reserved",                  /* 4 */
-  "Multipurpose",              /* 5 */
-  "Fragment",                  /* 6 */
-  "Extended"                   /* 7 */
+       "Beacon",                       /* 0 */
+       "Data",                         /* 1 */
+       "ACK",                          /* 2 */
+       "Command",                      /* 3 */
+       "Reserved",                     /* 4 */
+       "Multipurpose",                 /* 5 */
+       "Fragment",                     /* 6 */
+       "Extended"                      /* 7 */
 };
 
 /* Element IDs for Header IEs from Table 7-7 of 802.15.4-2015 */
 static const char *h_ie_names[] = {
-  "Vendor Specific Header IE",                 /* 0x00 */
-  "Reserved 0x01",                             /* 0x01 */
-  "Reserved 0x02",                             /* 0x02 */
-  "Reserved 0x03",                             /* 0x03 */
-  "Reserved 0x04",                             /* 0x04 */
-  "Reserved 0x05",                             /* 0x05 */
-  "Reserved 0x06",                             /* 0x06 */
-  "Reserved 0x07",                             /* 0x07 */
-  "Reserved 0x08",                             /* 0x08 */
-  "Reserved 0x09",                             /* 0x09 */
-  "Reserved 0x0a",                             /* 0x0a */
-  "Reserved 0x0b",                             /* 0x0b */
-  "Reserved 0x0c",                             /* 0x0c */
-  "Reserved 0x0d",                             /* 0x0d */
-  "Reserved 0x0e",                             /* 0x0e */
-  "Reserved 0x0f",                             /* 0x0f */
-  "Reserved 0x10",                             /* 0x10 */
-  "Reserved 0x11",                             /* 0x11 */
-  "Reserved 0x12",                             /* 0x12 */
-  "Reserved 0x13",                             /* 0x13 */
-  "Reserved 0x14",                             /* 0x14 */
-  "Reserved 0x15",                             /* 0x15 */
-  "Reserved 0x16",                             /* 0x16 */
-  "Reserved 0x17",                             /* 0x17 */
-  "Reserved 0x18",                             /* 0x18 */
-  "Reserved 0x19",                             /* 0x19 */
-  "LE CSL IE",                                 /* 0x1a */
-  "LE RIT IE",                                 /* 0x1b */
-  "DSME PAN descriptor IE",                    /* 0x1c */
-  "Rendezvous Time IE",                                /* 0x1d */
-  "Time Correction IE",                                /* 0x1e */
-  "Reserved 0x1f",                             /* 0x1f */
-  "Reserved 0x20",                             /* 0x20 */
-  "Extended DSME PAN descriptor IE",           /* 0x21 */
-  "Fragment Sequence Context Description IE",   /* 0x22 */
-  "Simplified Superframe Specification IE",    /* 0x23 */
-  "Simplified GTS Specification IE",           /* 0x24 */
-  "LECIM Capabilities IE",                     /* 0x25 */
-  "TRLE Descriptor IE",                        /* 0x26 */
-  "RCC Capabilities IE",                       /* 0x27 */
-  "RCCN Descriptor IE",                        /* 0x28 */
-  "Global Time IE",                            /* 0x29 */
-  "Omnibus Header IE",                                 /* 0x2a */
-  "DA IE",                                     /* 0x2b */
-  "Reserved 0x2c",                             /* 0x2c */
-  "Reserved 0x2d",                             /* 0x2d */
-  "Reserved 0x2e",                             /* 0x2e */
-  "Reserved 0x2f",                             /* 0x2f */
-  "Reserved 0x30",                             /* 0x30 */
-  "Reserved 0x31",                             /* 0x31 */
-  "Reserved 0x32",                             /* 0x32 */
-  "Reserved 0x33",                             /* 0x33 */
-  "Reserved 0x34",                             /* 0x34 */
-  "Reserved 0x35",                             /* 0x35 */
-  "Reserved 0x36",                             /* 0x36 */
-  "Reserved 0x37",                             /* 0x37 */
-  "Reserved 0x38",                             /* 0x38 */
-  "Reserved 0x39",                             /* 0x39 */
-  "Reserved 0x3a",                             /* 0x3a */
-  "Reserved 0x3b",                             /* 0x3b */
-  "Reserved 0x3c",                             /* 0x3c */
-  "Reserved 0x3d",                             /* 0x3d */
-  "Reserved 0x3e",                             /* 0x3e */
-  "Reserved 0x3f",                             /* 0x3f */
-  "Reserved 0x40",                             /* 0x40 */
-  "Reserved 0x41",                             /* 0x41 */
-  "Reserved 0x42",                             /* 0x42 */
-  "Reserved 0x43",                             /* 0x43 */
-  "Reserved 0x44",                             /* 0x44 */
-  "Reserved 0x45",                             /* 0x45 */
-  "Reserved 0x46",                             /* 0x46 */
-  "Reserved 0x47",                             /* 0x47 */
-  "Reserved 0x48",                             /* 0x48 */
-  "Reserved 0x49",                             /* 0x49 */
-  "Reserved 0x4a",                             /* 0x4a */
-  "Reserved 0x4b",                             /* 0x4b */
-  "Reserved 0x4c",                             /* 0x4c */
-  "Reserved 0x4d",                             /* 0x4d */
-  "Reserved 0x4e",                             /* 0x4e */
-  "Reserved 0x4f",                             /* 0x4f */
-  "Reserved 0x50",                             /* 0x50 */
-  "Reserved 0x51",                             /* 0x51 */
-  "Reserved 0x52",                             /* 0x52 */
-  "Reserved 0x53",                             /* 0x53 */
-  "Reserved 0x54",                             /* 0x54 */
-  "Reserved 0x55",                             /* 0x55 */
-  "Reserved 0x56",                             /* 0x56 */
-  "Reserved 0x57",                             /* 0x57 */
-  "Reserved 0x58",                             /* 0x58 */
-  "Reserved 0x59",                             /* 0x59 */
-  "Reserved 0x5a",                             /* 0x5a */
-  "Reserved 0x5b",                             /* 0x5b */
-  "Reserved 0x5c",                             /* 0x5c */
-  "Reserved 0x5d",                             /* 0x5d */
-  "Reserved 0x5e",                             /* 0x5e */
-  "Reserved 0x5f",                             /* 0x5f */
-  "Reserved 0x60",                             /* 0x60 */
-  "Reserved 0x61",                             /* 0x61 */
-  "Reserved 0x62",                             /* 0x62 */
-  "Reserved 0x63",                             /* 0x63 */
-  "Reserved 0x64",                             /* 0x64 */
-  "Reserved 0x65",                             /* 0x65 */
-  "Reserved 0x66",                             /* 0x66 */
-  "Reserved 0x67",                             /* 0x67 */
-  "Reserved 0x68",                             /* 0x68 */
-  "Reserved 0x69",                             /* 0x69 */
-  "Reserved 0x6a",                             /* 0x6a */
-  "Reserved 0x6b",                             /* 0x6b */
-  "Reserved 0x6c",                             /* 0x6c */
-  "Reserved 0x6d",                             /* 0x6d */
-  "Reserved 0x6e",                             /* 0x6e */
-  "Reserved 0x6f",                             /* 0x6f */
-  "Reserved 0x70",                             /* 0x70 */
-  "Reserved 0x71",                             /* 0x71 */
-  "Reserved 0x72",                             /* 0x72 */
-  "Reserved 0x73",                             /* 0x73 */
-  "Reserved 0x74",                             /* 0x74 */
-  "Reserved 0x75",                             /* 0x75 */
-  "Reserved 0x76",                             /* 0x76 */
-  "Reserved 0x77",                             /* 0x77 */
-  "Reserved 0x78",                             /* 0x78 */
-  "Reserved 0x79",                             /* 0x79 */
-  "Reserved 0x7a",                             /* 0x7a */
-  "Reserved 0x7b",                             /* 0x7b */
-  "Reserved 0x7c",                             /* 0x7c */
-  "Reserved 0x7d",                             /* 0x7d */
-  "Header Termination 1 IE",                   /* 0x7e */
-  "Header Termination 2 IE"                    /* 0x7f */
+       "Vendor Specific Header IE",                    /* 0x00 */
+       "Reserved 0x01",                                /* 0x01 */
+       "Reserved 0x02",                                /* 0x02 */
+       "Reserved 0x03",                                /* 0x03 */
+       "Reserved 0x04",                                /* 0x04 */
+       "Reserved 0x05",                                /* 0x05 */
+       "Reserved 0x06",                                /* 0x06 */
+       "Reserved 0x07",                                /* 0x07 */
+       "Reserved 0x08",                                /* 0x08 */
+       "Reserved 0x09",                                /* 0x09 */
+       "Reserved 0x0a",                                /* 0x0a */
+       "Reserved 0x0b",                                /* 0x0b */
+       "Reserved 0x0c",                                /* 0x0c */
+       "Reserved 0x0d",                                /* 0x0d */
+       "Reserved 0x0e",                                /* 0x0e */
+       "Reserved 0x0f",                                /* 0x0f */
+       "Reserved 0x10",                                /* 0x10 */
+       "Reserved 0x11",                                /* 0x11 */
+       "Reserved 0x12",                                /* 0x12 */
+       "Reserved 0x13",                                /* 0x13 */
+       "Reserved 0x14",                                /* 0x14 */
+       "Reserved 0x15",                                /* 0x15 */
+       "Reserved 0x16",                                /* 0x16 */
+       "Reserved 0x17",                                /* 0x17 */
+       "Reserved 0x18",                                /* 0x18 */
+       "Reserved 0x19",                                /* 0x19 */
+       "LE CSL IE",                                    /* 0x1a */
+       "LE RIT IE",                                    /* 0x1b */
+       "DSME PAN descriptor IE",                       /* 0x1c */
+       "Rendezvous Time IE",                           /* 0x1d */
+       "Time Correction IE",                           /* 0x1e */
+       "Reserved 0x1f",                                /* 0x1f */
+       "Reserved 0x20",                                /* 0x20 */
+       "Extended DSME PAN descriptor IE",              /* 0x21 */
+       "Fragment Sequence Context Description IE",     /* 0x22 */
+       "Simplified Superframe Specification IE",       /* 0x23 */
+       "Simplified GTS Specification IE",              /* 0x24 */
+       "LECIM Capabilities IE",                        /* 0x25 */
+       "TRLE Descriptor IE",                           /* 0x26 */
+       "RCC Capabilities IE",                          /* 0x27 */
+       "RCCN Descriptor IE",                           /* 0x28 */
+       "Global Time IE",                               /* 0x29 */
+       "Omnibus Header IE",                            /* 0x2a */
+       "DA IE",                                        /* 0x2b */
+       "Reserved 0x2c",                                /* 0x2c */
+       "Reserved 0x2d",                                /* 0x2d */
+       "Reserved 0x2e",                                /* 0x2e */
+       "Reserved 0x2f",                                /* 0x2f */
+       "Reserved 0x30",                                /* 0x30 */
+       "Reserved 0x31",                                /* 0x31 */
+       "Reserved 0x32",                                /* 0x32 */
+       "Reserved 0x33",                                /* 0x33 */
+       "Reserved 0x34",                                /* 0x34 */
+       "Reserved 0x35",                                /* 0x35 */
+       "Reserved 0x36",                                /* 0x36 */
+       "Reserved 0x37",                                /* 0x37 */
+       "Reserved 0x38",                                /* 0x38 */
+       "Reserved 0x39",                                /* 0x39 */
+       "Reserved 0x3a",                                /* 0x3a */
+       "Reserved 0x3b",                                /* 0x3b */
+       "Reserved 0x3c",                                /* 0x3c */
+       "Reserved 0x3d",                                /* 0x3d */
+       "Reserved 0x3e",                                /* 0x3e */
+       "Reserved 0x3f",                                /* 0x3f */
+       "Reserved 0x40",                                /* 0x40 */
+       "Reserved 0x41",                                /* 0x41 */
+       "Reserved 0x42",                                /* 0x42 */
+       "Reserved 0x43",                                /* 0x43 */
+       "Reserved 0x44",                                /* 0x44 */
+       "Reserved 0x45",                                /* 0x45 */
+       "Reserved 0x46",                                /* 0x46 */
+       "Reserved 0x47",                                /* 0x47 */
+       "Reserved 0x48",                                /* 0x48 */
+       "Reserved 0x49",                                /* 0x49 */
+       "Reserved 0x4a",                                /* 0x4a */
+       "Reserved 0x4b",                                /* 0x4b */
+       "Reserved 0x4c",                                /* 0x4c */
+       "Reserved 0x4d",                                /* 0x4d */
+       "Reserved 0x4e",                                /* 0x4e */
+       "Reserved 0x4f",                                /* 0x4f */
+       "Reserved 0x50",                                /* 0x50 */
+       "Reserved 0x51",                                /* 0x51 */
+       "Reserved 0x52",                                /* 0x52 */
+       "Reserved 0x53",                                /* 0x53 */
+       "Reserved 0x54",                                /* 0x54 */
+       "Reserved 0x55",                                /* 0x55 */
+       "Reserved 0x56",                                /* 0x56 */
+       "Reserved 0x57",                                /* 0x57 */
+       "Reserved 0x58",                                /* 0x58 */
+       "Reserved 0x59",                                /* 0x59 */
+       "Reserved 0x5a",                                /* 0x5a */
+       "Reserved 0x5b",                                /* 0x5b */
+       "Reserved 0x5c",                                /* 0x5c */
+       "Reserved 0x5d",                                /* 0x5d */
+       "Reserved 0x5e",                                /* 0x5e */
+       "Reserved 0x5f",                                /* 0x5f */
+       "Reserved 0x60",                                /* 0x60 */
+       "Reserved 0x61",                                /* 0x61 */
+       "Reserved 0x62",                                /* 0x62 */
+       "Reserved 0x63",                                /* 0x63 */
+       "Reserved 0x64",                                /* 0x64 */
+       "Reserved 0x65",                                /* 0x65 */
+       "Reserved 0x66",                                /* 0x66 */
+       "Reserved 0x67",                                /* 0x67 */
+       "Reserved 0x68",                                /* 0x68 */
+       "Reserved 0x69",                                /* 0x69 */
+       "Reserved 0x6a",                                /* 0x6a */
+       "Reserved 0x6b",                                /* 0x6b */
+       "Reserved 0x6c",                                /* 0x6c */
+       "Reserved 0x6d",                                /* 0x6d */
+       "Reserved 0x6e",                                /* 0x6e */
+       "Reserved 0x6f",                                /* 0x6f */
+       "Reserved 0x70",                                /* 0x70 */
+       "Reserved 0x71",                                /* 0x71 */
+       "Reserved 0x72",                                /* 0x72 */
+       "Reserved 0x73",                                /* 0x73 */
+       "Reserved 0x74",                                /* 0x74 */
+       "Reserved 0x75",                                /* 0x75 */
+       "Reserved 0x76",                                /* 0x76 */
+       "Reserved 0x77",                                /* 0x77 */
+       "Reserved 0x78",                                /* 0x78 */
+       "Reserved 0x79",                                /* 0x79 */
+       "Reserved 0x7a",                                /* 0x7a */
+       "Reserved 0x7b",                                /* 0x7b */
+       "Reserved 0x7c",                                /* 0x7c */
+       "Reserved 0x7d",                                /* 0x7d */
+       "Header Termination 1 IE",                      /* 0x7e */
+       "Header Termination 2 IE"                       /* 0x7f */
 };
 
 /* Payload IE Group IDs from Table 7-15 of 802.15.4-2015 */
 static const char *p_ie_names[] = {
-  "ESDU IE",                   /* 0x00 */
-  "MLME IE",                   /* 0x01 */
-  "Vendor Specific Nested IE", /* 0x02 */
-  "Multiplexed IE (802.15.9)", /* 0x03 */
-  "Omnibus Payload Group IE",  /* 0x04 */
-  "IETF IE",                   /* 0x05 */
-  "Reserved 0x06",             /* 0x06 */
-  "Reserved 0x07",             /* 0x07 */
-  "Reserved 0x08",             /* 0x08 */
-  "Reserved 0x09",             /* 0x09 */
-  "Reserved 0x0a",             /* 0x0a */
-  "Reserved 0x0b",             /* 0x0b */
-  "Reserved 0x0c",             /* 0x0c */
-  "Reserved 0x0d",             /* 0x0d */
-  "Reserved 0x0e",             /* 0x0e */
-  "List termination"           /* 0x0f */
+       "ESDU IE",                      /* 0x00 */
+       "MLME IE",                      /* 0x01 */
+       "Vendor Specific Nested IE",    /* 0x02 */
+       "Multiplexed IE (802.15.9)",    /* 0x03 */
+       "Omnibus Payload Group IE",     /* 0x04 */
+       "IETF IE",                      /* 0x05 */
+       "Reserved 0x06",                /* 0x06 */
+       "Reserved 0x07",                /* 0x07 */
+       "Reserved 0x08",                /* 0x08 */
+       "Reserved 0x09",                /* 0x09 */
+       "Reserved 0x0a",                /* 0x0a */
+       "Reserved 0x0b",                /* 0x0b */
+       "Reserved 0x0c",                /* 0x0c */
+       "Reserved 0x0d",                /* 0x0d */
+       "Reserved 0x0e",                /* 0x0e */
+       "List termination"              /* 0x0f */
 };
 
 /* Sub-ID for short format from Table 7-16 of 802.15.4-2015 */
 static const char *p_mlme_short_names[] = {
-  "Reserved for long format 0x0",              /* 0x00 */
-  "Reserved for long format 0x1",              /* 0x01 */
-  "Reserved for long format 0x2",              /* 0x02 */
-  "Reserved for long format 0x3",              /* 0x03 */
-  "Reserved for long format 0x4",              /* 0x04 */
-  "Reserved for long format 0x5",              /* 0x05 */
-  "Reserved for long format 0x6",              /* 0x06 */
-  "Reserved for long format 0x7",              /* 0x07 */
-  "Reserved for long format 0x8",              /* 0x08 */
-  "Reserved for long format 0x9",              /* 0x09 */
-  "Reserved for long format 0xa",              /* 0x0a */
-  "Reserved for long format 0xb",              /* 0x0b */
-  "Reserved for long format 0xc",              /* 0x0c */
-  "Reserved for long format 0xd",              /* 0x0d */
-  "Reserved for long format 0xe",              /* 0x0e */
-  "Reserved for long format 0xf",              /* 0x0f */
-  "Reserved 0x10",                             /* 0x10 */
-  "Reserved 0x11",                             /* 0x11 */
-  "Reserved 0x12",                             /* 0x12 */
-  "Reserved 0x13",                             /* 0x13 */
-  "Reserved 0x14",                             /* 0x14 */
-  "Reserved 0x15",                             /* 0x15 */
-  "Reserved 0x16",                             /* 0x16 */
-  "Reserved 0x17",                             /* 0x17 */
-  "Reserved 0x18",                             /* 0x18 */
-  "Reserved 0x19",                             /* 0x19 */
-  "TSCH Synchronization IE",                   /* 0x1a */
-  "TSCH Slotframe and Link IE",                        /* 0x1b */
-  "TSCH Timeslot IE",                          /* 0x1c */
-  "Hopping timing IE",                         /* 0x1d */
-  "Enhanced Beacon Filter IE",                 /* 0x1e */
-  "MAC Metrics IE",                            /* 0x1f */
-  "All MAC Metrics IE",                                /* 0x20 */
-  "Coexistence Specification IE",              /* 0x21 */
-  "SUN Device Capabilities IE",                        /* 0x22 */
-  "SUN FSK Generic PHY IE",                    /* 0x23 */
-  "Mode Switch Parameter IE",                  /* 0x24 */
-  "PHY Parameter Change IE",                   /* 0x25 */
-  "O-QPSK PHY Mode IE",                        /* 0x26 */
-  "PCA Allocation IE",                                 /* 0x27 */
-  "LECIM DSSS Operating Mode IE",              /* 0x28 */
-  "LECIM FSK Operating Mode IE",               /* 0x29 */
-  "Reserved 0x2a",                             /* 0x2a */
-  "TVWS PHY Operating Mode Description IE",    /* 0x2b */
-  "TVWS Device Capabilities IE",               /* 0x2c */
-  "TVWS Device Category IE",                   /* 0x2d */
-  "TVWS Device Identiication IE",              /* 0x2e */
-  "TVWS Device Location IE",                   /* 0x2f */
-  "TVWS Channel Information Query IE",         /* 0x30 */
-  "TVWS Channel Information Source IE",                /* 0x31 */
-  "CTM IE",                                    /* 0x32 */
-  "Timestamp IE",                              /* 0x33 */
-  "Timestamp Difference IE",                   /* 0x34 */
-  "TMCTP Sepcification IE",                    /* 0x35 */
-  "RCC PHY Operating Mode IE",                 /* 0x36 */
-  "Reserved 0x37",                             /* 0x37 */
-  "Reserved 0x38",                             /* 0x38 */
-  "Reserved 0x39",                             /* 0x39 */
-  "Reserved 0x3a",                             /* 0x3a */
-  "Reserved 0x3b",                             /* 0x3b */
-  "Reserved 0x3c",                             /* 0x3c */
-  "Reserved 0x3d",                             /* 0x3d */
-  "Reserved 0x3e",                             /* 0x3e */
-  "Reserved 0x3f",                             /* 0x3f */
-  "Reserved 0x40",                             /* 0x40 */
-  "Reserved 0x41",                             /* 0x41 */
-  "Reserved 0x42",                             /* 0x42 */
-  "Reserved 0x43",                             /* 0x43 */
-  "Reserved 0x44",                             /* 0x44 */
-  "Reserved 0x45",                             /* 0x45 */
-  "Reserved 0x46",                             /* 0x46 */
-  "Reserved 0x47",                             /* 0x47 */
-  "Reserved 0x48",                             /* 0x48 */
-  "Reserved 0x49",                             /* 0x49 */
-  "Reserved 0x4a",                             /* 0x4a */
-  "Reserved 0x4b",                             /* 0x4b */
-  "Reserved 0x4c",                             /* 0x4c */
-  "Reserved 0x4d",                             /* 0x4d */
-  "Reserved 0x4e",                             /* 0x4e */
-  "Reserved 0x4f",                             /* 0x4f */
-  "Reserved 0x50",                             /* 0x50 */
-  "Reserved 0x51",                             /* 0x51 */
-  "Reserved 0x52",                             /* 0x52 */
-  "Reserved 0x53",                             /* 0x53 */
-  "Reserved 0x54",                             /* 0x54 */
-  "Reserved 0x55",                             /* 0x55 */
-  "Reserved 0x56",                             /* 0x56 */
-  "Reserved 0x57",                             /* 0x57 */
-  "Reserved 0x58",                             /* 0x58 */
-  "Reserved 0x59",                             /* 0x59 */
-  "Reserved 0x5a",                             /* 0x5a */
-  "Reserved 0x5b",                             /* 0x5b */
-  "Reserved 0x5c",                             /* 0x5c */
-  "Reserved 0x5d",                             /* 0x5d */
-  "Reserved 0x5e",                             /* 0x5e */
-  "Reserved 0x5f",                             /* 0x5f */
-  "Reserved 0x60",                             /* 0x60 */
-  "Reserved 0x61",                             /* 0x61 */
-  "Reserved 0x62",                             /* 0x62 */
-  "Reserved 0x63",                             /* 0x63 */
-  "Reserved 0x64",                             /* 0x64 */
-  "Reserved 0x65",                             /* 0x65 */
-  "Reserved 0x66",                             /* 0x66 */
-  "Reserved 0x67",                             /* 0x67 */
-  "Reserved 0x68",                             /* 0x68 */
-  "Reserved 0x69",                             /* 0x69 */
-  "Reserved 0x6a",                             /* 0x6a */
-  "Reserved 0x6b",                             /* 0x6b */
-  "Reserved 0x6c",                             /* 0x6c */
-  "Reserved 0x6d",                             /* 0x6d */
-  "Reserved 0x6e",                             /* 0x6e */
-  "Reserved 0x6f",                             /* 0x6f */
-  "Reserved 0x70",                             /* 0x70 */
-  "Reserved 0x71",                             /* 0x71 */
-  "Reserved 0x72",                             /* 0x72 */
-  "Reserved 0x73",                             /* 0x73 */
-  "Reserved 0x74",                             /* 0x74 */
-  "Reserved 0x75",                             /* 0x75 */
-  "Reserved 0x76",                             /* 0x76 */
-  "Reserved 0x77",                             /* 0x77 */
-  "Reserved 0x78",                             /* 0x78 */
-  "Reserved 0x79",                             /* 0x79 */
-  "Reserved 0x7a",                             /* 0x7a */
-  "Reserved 0x7b",                             /* 0x7b */
-  "Reserved 0x7c",                             /* 0x7c */
-  "Reserved 0x7d",                             /* 0x7d */
-  "Reserved 0x7e",                             /* 0x7e */
-  "Reserved 0x7f"                              /* 0x7f */
+       "Reserved for long format 0x0",                 /* 0x00 */
+       "Reserved for long format 0x1",                 /* 0x01 */
+       "Reserved for long format 0x2",                 /* 0x02 */
+       "Reserved for long format 0x3",                 /* 0x03 */
+       "Reserved for long format 0x4",                 /* 0x04 */
+       "Reserved for long format 0x5",                 /* 0x05 */
+       "Reserved for long format 0x6",                 /* 0x06 */
+       "Reserved for long format 0x7",                 /* 0x07 */
+       "Reserved for long format 0x8",                 /* 0x08 */
+       "Reserved for long format 0x9",                 /* 0x09 */
+       "Reserved for long format 0xa",                 /* 0x0a */
+       "Reserved for long format 0xb",                 /* 0x0b */
+       "Reserved for long format 0xc",                 /* 0x0c */
+       "Reserved for long format 0xd",                 /* 0x0d */
+       "Reserved for long format 0xe",                 /* 0x0e */
+       "Reserved for long format 0xf",                 /* 0x0f */
+       "Reserved 0x10",                                /* 0x10 */
+       "Reserved 0x11",                                /* 0x11 */
+       "Reserved 0x12",                                /* 0x12 */
+       "Reserved 0x13",                                /* 0x13 */
+       "Reserved 0x14",                                /* 0x14 */
+       "Reserved 0x15",                                /* 0x15 */
+       "Reserved 0x16",                                /* 0x16 */
+       "Reserved 0x17",                                /* 0x17 */
+       "Reserved 0x18",                                /* 0x18 */
+       "Reserved 0x19",                                /* 0x19 */
+       "TSCH Synchronization IE",                      /* 0x1a */
+       "TSCH Slotframe and Link IE",                   /* 0x1b */
+       "TSCH Timeslot IE",                             /* 0x1c */
+       "Hopping timing IE",                            /* 0x1d */
+       "Enhanced Beacon Filter IE",                    /* 0x1e */
+       "MAC Metrics IE",                               /* 0x1f */
+       "All MAC Metrics IE",                           /* 0x20 */
+       "Coexistence Specification IE",                 /* 0x21 */
+       "SUN Device Capabilities IE",                   /* 0x22 */
+       "SUN FSK Generic PHY IE",                       /* 0x23 */
+       "Mode Switch Parameter IE",                     /* 0x24 */
+       "PHY Parameter Change IE",                      /* 0x25 */
+       "O-QPSK PHY Mode IE",                           /* 0x26 */
+       "PCA Allocation IE",                            /* 0x27 */
+       "LECIM DSSS Operating Mode IE",                 /* 0x28 */
+       "LECIM FSK Operating Mode IE",                  /* 0x29 */
+       "Reserved 0x2a",                                /* 0x2a */
+       "TVWS PHY Operating Mode Description IE",       /* 0x2b */
+       "TVWS Device Capabilities IE",                  /* 0x2c */
+       "TVWS Device Category IE",                      /* 0x2d */
+       "TVWS Device Identiication IE",                 /* 0x2e */
+       "TVWS Device Location IE",                      /* 0x2f */
+       "TVWS Channel Information Query IE",            /* 0x30 */
+       "TVWS Channel Information Source IE",           /* 0x31 */
+       "CTM IE",                                       /* 0x32 */
+       "Timestamp IE",                                 /* 0x33 */
+       "Timestamp Difference IE",                      /* 0x34 */
+       "TMCTP Specification IE",                       /* 0x35 */
+       "RCC PHY Operating Mode IE",                    /* 0x36 */
+       "Reserved 0x37",                                /* 0x37 */
+       "Reserved 0x38",                                /* 0x38 */
+       "Reserved 0x39",                                /* 0x39 */
+       "Reserved 0x3a",                                /* 0x3a */
+       "Reserved 0x3b",                                /* 0x3b */
+       "Reserved 0x3c",                                /* 0x3c */
+       "Reserved 0x3d",                                /* 0x3d */
+       "Reserved 0x3e",                                /* 0x3e */
+       "Reserved 0x3f",                                /* 0x3f */
+       "Reserved 0x40",                                /* 0x40 */
+       "Reserved 0x41",                                /* 0x41 */
+       "Reserved 0x42",                                /* 0x42 */
+       "Reserved 0x43",                                /* 0x43 */
+       "Reserved 0x44",                                /* 0x44 */
+       "Reserved 0x45",                                /* 0x45 */
+       "Reserved 0x46",                                /* 0x46 */
+       "Reserved 0x47",                                /* 0x47 */
+       "Reserved 0x48",                                /* 0x48 */
+       "Reserved 0x49",                                /* 0x49 */
+       "Reserved 0x4a",                                /* 0x4a */
+       "Reserved 0x4b",                                /* 0x4b */
+       "Reserved 0x4c",                                /* 0x4c */
+       "Reserved 0x4d",                                /* 0x4d */
+       "Reserved 0x4e",                                /* 0x4e */
+       "Reserved 0x4f",                                /* 0x4f */
+       "Reserved 0x50",                                /* 0x50 */
+       "Reserved 0x51",                                /* 0x51 */
+       "Reserved 0x52",                                /* 0x52 */
+       "Reserved 0x53",                                /* 0x53 */
+       "Reserved 0x54",                                /* 0x54 */
+       "Reserved 0x55",                                /* 0x55 */
+       "Reserved 0x56",                                /* 0x56 */
+       "Reserved 0x57",                                /* 0x57 */
+       "Reserved 0x58",                                /* 0x58 */
+       "Reserved 0x59",                                /* 0x59 */
+       "Reserved 0x5a",                                /* 0x5a */
+       "Reserved 0x5b",                                /* 0x5b */
+       "Reserved 0x5c",                                /* 0x5c */
+       "Reserved 0x5d",                                /* 0x5d */
+       "Reserved 0x5e",                                /* 0x5e */
+       "Reserved 0x5f",                                /* 0x5f */
+       "Reserved 0x60",                                /* 0x60 */
+       "Reserved 0x61",                                /* 0x61 */
+       "Reserved 0x62",                                /* 0x62 */
+       "Reserved 0x63",                                /* 0x63 */
+       "Reserved 0x64",                                /* 0x64 */
+       "Reserved 0x65",                                /* 0x65 */
+       "Reserved 0x66",                                /* 0x66 */
+       "Reserved 0x67",                                /* 0x67 */
+       "Reserved 0x68",                                /* 0x68 */
+       "Reserved 0x69",                                /* 0x69 */
+       "Reserved 0x6a",                                /* 0x6a */
+       "Reserved 0x6b",                                /* 0x6b */
+       "Reserved 0x6c",                                /* 0x6c */
+       "Reserved 0x6d",                                /* 0x6d */
+       "Reserved 0x6e",                                /* 0x6e */
+       "Reserved 0x6f",                                /* 0x6f */
+       "Reserved 0x70",                                /* 0x70 */
+       "Reserved 0x71",                                /* 0x71 */
+       "Reserved 0x72",                                /* 0x72 */
+       "Reserved 0x73",                                /* 0x73 */
+       "Reserved 0x74",                                /* 0x74 */
+       "Reserved 0x75",                                /* 0x75 */
+       "Reserved 0x76",                                /* 0x76 */
+       "Reserved 0x77",                                /* 0x77 */
+       "Reserved 0x78",                                /* 0x78 */
+       "Reserved 0x79",                                /* 0x79 */
+       "Reserved 0x7a",                                /* 0x7a */
+       "Reserved 0x7b",                                /* 0x7b */
+       "Reserved 0x7c",                                /* 0x7c */
+       "Reserved 0x7d",                                /* 0x7d */
+       "Reserved 0x7e",                                /* 0x7e */
+       "Reserved 0x7f"                                 /* 0x7f */
 };
 
 /* Sub-ID for long format from Table 7-17 of 802.15.4-2015 */
 static const char *p_mlme_long_names[] = {
-  "Reserved 0x00",                     /* 0x00 */
-  "Reserved 0x01",                     /* 0x01 */
-  "Reserved 0x02",                     /* 0x02 */
-  "Reserved 0x03",                     /* 0x03 */
-  "Reserved 0x04",                     /* 0x04 */
-  "Reserved 0x05",                     /* 0x05 */
-  "Reserved 0x06",                     /* 0x06 */
-  "Reserved 0x07",                     /* 0x07 */
-  "Vendor Specific MLME Nested IE",    /* 0x08 */
-  "Channel Hopping IE",                        /* 0x09 */
-  "Reserved 0x0a",                     /* 0x0a */
-  "Reserved 0x0b",                     /* 0x0b */
-  "Reserved 0x0c",                     /* 0x0c */
-  "Reserved 0x0d",                     /* 0x0d */
-  "Reserved 0x0e",                     /* 0x0e */
-  "Reserved 0x0f"                      /* 0x0f */
+       "Reserved 0x00",                        /* 0x00 */
+       "Reserved 0x01",                        /* 0x01 */
+       "Reserved 0x02",                        /* 0x02 */
+       "Reserved 0x03",                        /* 0x03 */
+       "Reserved 0x04",                        /* 0x04 */
+       "Reserved 0x05",                        /* 0x05 */
+       "Reserved 0x06",                        /* 0x06 */
+       "Reserved 0x07",                        /* 0x07 */
+       "Vendor Specific MLME Nested IE",       /* 0x08 */
+       "Channel Hopping IE",                   /* 0x09 */
+       "Reserved 0x0a",                        /* 0x0a */
+       "Reserved 0x0b",                        /* 0x0b */
+       "Reserved 0x0c",                        /* 0x0c */
+       "Reserved 0x0d",                        /* 0x0d */
+       "Reserved 0x0e",                        /* 0x0e */
+       "Reserved 0x0f"                         /* 0x0f */
 };
 
 /* MAC commands from Table 7-49 of 802.15.4-2015 */
 static const char *mac_c_names[] = {
-  "Reserved 0x00",                             /* 0x00 */
-  "Association Request command",               /* 0x01 */
-  "Association Response command",              /* 0x02 */
-  "Disassociation Notification command",       /* 0x03 */
-  "Data Request command",                      /* 0x04 */
-  "PAN ID Conflict Notification command",      /* 0x05 */
-  "Orphan Notification command",               /* 0x06 */
-  "Beacon Request command",                    /* 0x07 */
-  "Coordinator realignment command",           /* 0x08 */
-  "GTS request command",                       /* 0x09 */
-  "TRLE Management Request command",           /* 0x0a */
-  "TRLE Management Response command",          /* 0x0b */
-  "Reserved 0x0c",                             /* 0x0c */
-  "Reserved 0x0d",                             /* 0x0d */
-  "Reserved 0x0e",                             /* 0x0e */
-  "Reserved 0x0f",                             /* 0x0f */
-  "Reserved 0x10",                             /* 0x10 */
-  "Reserved 0x11",                             /* 0x11 */
-  "Reserved 0x12",                             /* 0x12 */
-  "DSME Association Request command",          /* 0x13 */
-  "DSME Association Response command",         /* 0x14 */
-  "DSME GTS Request command",                  /* 0x15 */
-  "DSME GTS Response command",                 /* 0x16 */
-  "DSME GTS Notify command",                   /* 0x17 */
-  "DSME Information Request command",          /* 0x18 */
-  "DSME Information Response command",         /* 0x19 */
-  "DSME Beacon Allocation Notification command",/* 0x1a */
-  "DSME Beacon Collision Notification command",        /* 0x1b */
-  "DSME Link Report command",                  /* 0x1c */
-  "Reserved 0x1d",                             /* 0x1d */
-  "Reserved 0x1e",                             /* 0x1e */
-  "Reserved 0x1f",                             /* 0x1f */
-  "RIT Data Request command",                  /* 0x20 */
-  "DBS Request command",                       /* 0x21 */
-  "DBS Response command",                      /* 0x22 */
-  "RIT Data Response command",                         /* 0x23 */
-  "Vendor Specific command",                   /* 0x24 */
-  "Reserved 0x25",                             /* 0x25 */
-  "Reserved 0x26",                             /* 0x26 */
-  "Reserved 0x27",                             /* 0x27 */
-  "Reserved 0x28",                             /* 0x28 */
-  "Reserved 0x29",                             /* 0x29 */
-  "Reserved 0x2a",                             /* 0x2a */
-  "Reserved 0x2b",                             /* 0x2b */
-  "Reserved 0x2c",                             /* 0x2c */
-  "Reserved 0x2d",                             /* 0x2d */
-  "Reserved 0x2e",                             /* 0x2e */
-  "Reserved 0x2f"                              /* 0x2f */
+       "Reserved 0x00",                                /* 0x00 */
+       "Association Request command",                  /* 0x01 */
+       "Association Response command",                 /* 0x02 */
+       "Disassociation Notification command",          /* 0x03 */
+       "Data Request command",                         /* 0x04 */
+       "PAN ID Conflict Notification command",         /* 0x05 */
+       "Orphan Notification command",                  /* 0x06 */
+       "Beacon Request command",                       /* 0x07 */
+       "Coordinator realignment command",              /* 0x08 */
+       "GTS request command",                          /* 0x09 */
+       "TRLE Management Request command",              /* 0x0a */
+       "TRLE Management Response command",             /* 0x0b */
+       "Reserved 0x0c",                                /* 0x0c */
+       "Reserved 0x0d",                                /* 0x0d */
+       "Reserved 0x0e",                                /* 0x0e */
+       "Reserved 0x0f",                                /* 0x0f */
+       "Reserved 0x10",                                /* 0x10 */
+       "Reserved 0x11",                                /* 0x11 */
+       "Reserved 0x12",                                /* 0x12 */
+       "DSME Association Request command",             /* 0x13 */
+       "DSME Association Response command",            /* 0x14 */
+       "DSME GTS Request command",                     /* 0x15 */
+       "DSME GTS Response command",                    /* 0x16 */
+       "DSME GTS Notify command",                      /* 0x17 */
+       "DSME Information Request command",             /* 0x18 */
+       "DSME Information Response command",            /* 0x19 */
+       "DSME Beacon Allocation Notification command",  /* 0x1a */
+       "DSME Beacon Collision Notification command",   /* 0x1b */
+       "DSME Link Report command",                     /* 0x1c */
+       "Reserved 0x1d",                                /* 0x1d */
+       "Reserved 0x1e",                                /* 0x1e */
+       "Reserved 0x1f",                                /* 0x1f */
+       "RIT Data Request command",                     /* 0x20 */
+       "DBS Request command",                          /* 0x21 */
+       "DBS Response command",                         /* 0x22 */
+       "RIT Data Response command",                    /* 0x23 */
+       "Vendor Specific command",                      /* 0x24 */
+       "Reserved 0x25",                                /* 0x25 */
+       "Reserved 0x26",                                /* 0x26 */
+       "Reserved 0x27",                                /* 0x27 */
+       "Reserved 0x28",                                /* 0x28 */
+       "Reserved 0x29",                                /* 0x29 */
+       "Reserved 0x2a",                                /* 0x2a */
+       "Reserved 0x2b",                                /* 0x2b */
+       "Reserved 0x2c",                                /* 0x2c */
+       "Reserved 0x2d",                                /* 0x2d */
+       "Reserved 0x2e",                                /* 0x2e */
+       "Reserved 0x2f"                         /* 0x2f */
 };
 
+/*
+ * Frame Control subfields.
+ */
+#define FC_FRAME_TYPE(fc)              ((fc) & 0x7)
+#define FC_FRAME_VERSION(fc)           (((fc) >> 12) & 0x3)
+
+#define FC_ADDRESSING_MODE_NONE         0x00
+#define FC_ADDRESSING_MODE_RESERVED     0x01
+#define FC_ADDRESSING_MODE_SHORT        0x02
+#define FC_ADDRESSING_MODE_LONG         0x03
 
 /*
  * 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,
-                  uint16_t data_len)
+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 != 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));
+               y = (((y & 0xf0) >> 4) | ((y & 0x0f) << 4));
+               /* Update CRC */
+               x = crc >> 8 ^ y;
+               x ^= x >> 4;
+               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));
+       crc = (((crc & 0xcccc) >> 2) | ((crc & 0x3333) << 2));
+       crc = (((crc & 0xf0f0) >> 4) | ((crc & 0x0f0f) << 4));
+       crc = (((crc & 0xff00) >> 8) | ((crc & 0x00ff) << 8));
+       return crc;
+}
+
+/*
+ * Reverses the bits of the 32-bit word.
+ */
+static uint32_t
+ieee802_15_4_reverse32(uint32_t x)
 {
-  uint16_t crc;
-  u_char x, y;
-
-  crc = 0x0000; /* Note, initial value is 0x0000 not 0xffff. */
-
-  while (data_len--){
-    y = *p++;
-    /* Reverse bits on input */
-    y = (((y & 0xaa) >> 1) | ((y & 0x55) << 1));
-    y = (((y & 0xcc) >> 2) | ((y & 0x33) << 2));
-    y = (((y & 0xf0) >> 4) | ((y & 0x0f) << 4));
-    /* Update CRC */
-    x = crc >> 8 ^ y;
-    x ^= x >> 4;
-    crc = (crc << 8) ^
-      ((unsigned short)(x << 12)) ^
-      ((unsigned short)(x <<5)) ^
-      ((unsigned short)x);
-  }
-  /* Reverse bits on output */
-  crc = (((crc & 0xaaaa) >> 1) | ((crc & 0x5555) << 1));
-  crc = (((crc & 0xcccc) >> 2) | ((crc & 0x3333) << 2));
-  crc = (((crc & 0xf0f0) >> 4) | ((crc & 0x0f0f) << 4));
-  crc = (((crc & 0xff00) >> 8) | ((crc & 0x00ff) << 8));
-  return crc;
+       x = ((x & 0x55555555) <<  1) | ((x >>  1) & 0x55555555);
+       x = ((x & 0x33333333) <<  2) | ((x >>  2) & 0x33333333);
+       x = ((x & 0x0F0F0F0F) <<  4) | ((x >>  4) & 0x0F0F0F0F);
+       x = (x << 24) | ((x & 0xFF00) << 8) |
+               ((x >> 8) & 0xFF00) | (x >> 24);
+       return x;
+}
+
+/*
+ * 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 section 7.2.10 of 802.15.4-2015 for more information.
+ */
+static uint32_t
+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 != 0){
+               byte = GET_U_1(p);
+               p++;
+               /* Reverse bits on input */
+               byte = ieee802_15_4_reverse32(byte);
+               /* Update CRC */
+               for(b = 0; b <= 7; b++) {
+                 if ((int) (crc ^ byte) < 0)
+                   crc = (crc << 1) ^ 0x04C11DB7;
+                 else
+                   crc = crc << 1;
+                 byte = byte << 1;
+               }
+               data_len--;
+       }
+       /* Reverse bits on output */
+       crc = ieee802_15_4_reverse32(crc);
+       return crc;
 }
 
 /*
@@ -449,23 +510,25 @@ ieee802_15_4_crc16(const u_char *p,
 static int
 ieee802_15_4_addr_len(uint16_t addr_type)
 {
-  switch (addr_type) {
-  case 0x00: /* None. */
-    return 0;
-    break;
-  case 0x01: /* Reserved, there used to be 8-bit address type in one
-             * amendment, but that and the feature using it was removed
-             * during 802.15.4-2015 maintenance process. */
-    return -1;
-    break;
-  case 0x02: /* Short. */
-    return 2;
-    break;
-  case 0x03: /* Extended. */
-    return 8;
-    break;
-  }
-  return 0;
+       switch (addr_type) {
+       case FC_ADDRESSING_MODE_NONE: /* None. */
+               return 0;
+               break;
+       case FC_ADDRESSING_MODE_RESERVED: /* Reserved, there used to be 8-bit
+                                          * address type in one amendment, but
+                                          * that and the feature using it was
+                                          * removed during 802.15.4-2015
+                                          * maintenance process. */
+               return -1;
+               break;
+       case FC_ADDRESSING_MODE_SHORT: /* Short. */
+               return 2;
+               break;
+       case FC_ADDRESSING_MODE_LONG: /* Extended. */
+               return 8;
+               break;
+       }
+       return 0;
 }
 
 /*
@@ -475,18 +538,17 @@ static void
 ieee802_15_4_print_addr(netdissect_options *ndo, const u_char *p,
                        int dst_addr_len)
 {
-  switch (dst_addr_len) {
-  case 0:
-    ND_PRINT((ndo, "none"));
-    break;
-  case 2:
-    ND_PRINT((ndo, "%04x", EXTRACT_LE_16BITS(p)));
-    break;
-  case 8:
-    ND_PRINT((ndo, "%s", le64addr_string(ndo, p)));
-    break;
-  }
-  return;
+       switch (dst_addr_len) {
+       case 0:
+               ND_PRINT("none");
+               break;
+       case 2:
+               ND_PRINT("%04x", GET_LE_U_2(p));
+               break;
+       case 8:
+               ND_PRINT("%s", GET_LE64ADDR_STRING(p));
+               break;
+       }
 }
 
 /*
@@ -498,16 +560,16 @@ static void
 ieee802_15_4_print_superframe_specification(netdissect_options *ndo,
                                            uint16_t ss)
 {
-  if (ndo->ndo_vflag < 1) {
-    return;
-  }
-  ND_PRINT((ndo, "\n\tBeacon order = %d, Superframe order = %d, ",
-           (ss & 0xf), ((ss >> 4) & 0xf)));
-  ND_PRINT((ndo, "Final CAP Slot = %d",
-           ((ss >> 8) & 0xf)));
-  if (CHECK_BIT(ss, 12)) { ND_PRINT((ndo, ", BLE enabled")); }
-  if (CHECK_BIT(ss, 14)) { ND_PRINT((ndo, ", PAN Coordinator")); }
-  if (CHECK_BIT(ss, 15)) { ND_PRINT((ndo, ", Assocation Permit")); }
+       if (ndo->ndo_vflag < 1) {
+               return;
+       }
+       ND_PRINT("\n\tBeacon order = %d, Superframe order = %d, ",
+                (ss & 0xf), ((ss >> 4) & 0xf));
+       ND_PRINT("Final CAP Slot = %d",
+                ((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(", Association Permit"); }
 }
 
 /*
@@ -519,42 +581,43 @@ ieee802_15_4_print_superframe_specification(netdissect_options *ndo,
 static int
 ieee802_15_4_print_gts_info(netdissect_options *ndo,
                            const u_char *p,
-                           uint16_t data_len)
+                           u_int data_len)
 {
-  uint8_t gts_spec, gts_cnt;
-  int len, i;
-
-  gts_spec = EXTRACT_LE_8BITS(p);
-  gts_cnt = gts_spec & 0x7;
-
-  if (gts_cnt == 0) {
-    if (ndo->ndo_vflag > 0) {
-      ND_PRINT((ndo, "\n\tGTS Descriptor Count = %d, ", gts_cnt));
-    }
-    return 1;
-  }
-  len = 1 + 1 + gts_cnt * 3;
-
-  if (data_len < len) {
-    ND_PRINT((ndo, " [ERROR: Truncated GTS Info List]"));
-    return -1;
-  }
-  if (ndo->ndo_vflag < 2) {
-    return len;
-  }
-  ND_PRINT((ndo, "GTS Descriptor Count = %d, ", gts_cnt));
-  ND_PRINT((ndo, "GTS Directions Mask = %02x, [ ",
-           EXTRACT_LE_8BITS(p + 1) & 0x7f));
-
-  for(i = 0; i < gts_cnt; i++) {
-    ND_PRINT((ndo, "[ "));
-    ieee802_15_4_print_addr(ndo, p + 2 + i * 3, 2);
-    ND_PRINT((ndo, ", Start slot = %d, Length = %d ] ",
-             EXTRACT_LE_8BITS(p + 2 + i * 3 + 1) & 0x0f,
-             (EXTRACT_LE_8BITS(p + 2 + i * 3 + 1) >> 4) & 0x0f));
-  }
-  ND_PRINT((ndo, "]"));
-  return len;
+       uint8_t gts_spec, gts_cnt;
+       u_int len;
+       int i;
+
+       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;
+       }
+       if (ndo->ndo_vflag < 2) {
+               return len;
+       }
+       ND_PRINT("GTS Descriptor Count = %d, ", gts_cnt);
+       ND_PRINT("GTS Directions Mask = %02x, [ ",
+                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 ] ",
+                        GET_U_1(p + 2 + i * 3 + 1) & 0x0f,
+                        (GET_U_1(p + 2 + i * 3 + 1) >> 4) & 0x0f);
+       }
+       ND_PRINT("]");
+       return len;
 }
 
 /*
@@ -563,47 +626,47 @@ ieee802_15_4_print_gts_info(netdissect_options *ndo,
  *
  * Returns number of byts consumed from the packet or -1 in case of error.
  */
-static int
+static int16_t
 ieee802_15_4_print_pending_addresses(netdissect_options *ndo,
                                     const u_char *p,
-                                    uint16_t data_len)
+                                    u_int data_len)
 {
-  uint8_t pas, s_cnt, e_cnt, len, i;
-
-  pas = EXTRACT_LE_8BITS(p);
-  s_cnt = pas & 0x7;
-  e_cnt = (pas >> 4) & 0x7;
-  len = 1 + s_cnt * 2 + e_cnt * 8;
-  if (ndo->ndo_vflag > 0) {
-    ND_PRINT((ndo, "\n\tPending address list, "
-             "# short addresses = %d, # extended addresses = %d",
-             s_cnt, e_cnt));
-  }
-  if (data_len < len) {
-    ND_PRINT((ndo, " [ERROR: Pending address list truncated]"));
-    return -1;
-  }
-  if (ndo->ndo_vflag < 2) {
-    return len;
-  }
-  if (s_cnt != 0) {
-    ND_PRINT((ndo, ", Short address list = [ "));
-    for(i = 0; i < s_cnt; i++) {
-      ieee802_15_4_print_addr(ndo, p + 1 + i * 2, 2);
-      ND_PRINT((ndo, " "));
-    }
-    ND_PRINT((ndo, "]"));
-  }
-  if (s_cnt != 0) {
-    ND_PRINT((ndo, ", 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);
-      ND_PRINT((ndo, " "));
-    }
-    ND_PRINT((ndo, "]"));
-  }
-  return len;
+       uint8_t pas, s_cnt, e_cnt, len, i;
+
+       pas = GET_U_1(p);
+       s_cnt = pas & 0x7;
+       e_cnt = (pas >> 4) & 0x7;
+       len = 1 + s_cnt * 2 + e_cnt * 8;
+       if (ndo->ndo_vflag > 0) {
+               ND_PRINT("\n\tPending address list, "
+                        "# short addresses = %d, # extended addresses = %d",
+                        s_cnt, e_cnt);
+       }
+       if (data_len < len) {
+               ND_PRINT(" [ERROR: Pending address list truncated]");
+               return -1;
+       }
+       if (ndo->ndo_vflag < 2) {
+               return len;
+       }
+       if (s_cnt != 0) {
+               ND_PRINT(", Short address list = [ ");
+               for(i = 0; i < s_cnt; i++) {
+                       ieee802_15_4_print_addr(ndo, p + 1 + i * 2, 2);
+                       ND_PRINT(" ");
+               }
+               ND_PRINT("]");
+       }
+       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 +
+                                               i * 8, 8);
+                       ND_PRINT(" ");
+               }
+               ND_PRINT("]");
+       }
+       return len;
 }
 
 /*
@@ -615,228 +678,244 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
                             uint16_t ie_len,
                             int element_id)
 {
-  int i;
-
-  switch (element_id) {
-  case 0x00: /* Vendor Specific Header IE */
-    if (ie_len < 3) {
-      ND_PRINT((ndo, "[ERROR: Vendor OUI missing]"));
-    } else {
-      ND_PRINT((ndo, "OUI = 0x%02x%02x%02x, ", EXTRACT_LE_8BITS(p),
-               EXTRACT_LE_8BITS(p + 1), EXTRACT_LE_8BITS(p + 2)));
-      ND_PRINT((ndo, "Data = "));
-      for(i = 3; i < ie_len; i++) {
-       ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-      }
-    }
-    break;
-  case 0x1a: /* LE CSL IE */
-    if (ie_len < 4) {
-      ND_PRINT((ndo, "[ERROR: Truncated CSL IE]"));
-    } else {
-      ND_PRINT((ndo, "CSL Phase = %d, CSL Period = %d",
-               EXTRACT_LE_16BITS(p), EXTRACT_LE_16BITS(p + 2)));
-      if (ie_len >= 6) {
-       ND_PRINT((ndo, ", Rendezvous time = %d", EXTRACT_LE_16BITS(p + 4)));
-      }
-      if (ie_len != 4 && ie_len != 6) {
-       ND_PRINT((ndo, " [ERROR: CSL IE length wrong]"));
-      }
-    }
-    break;
-  case 0x1b: /* LE RIT IE */
-    if (ie_len < 4) {
-      ND_PRINT((ndo, "[ERROR: Truncated RIT IE]"));
-    } else {
-      ND_PRINT((ndo, "Time to First Listen = %d, # of Repeat Listen = %d, Repeat Listen Interval = %d",
-               EXTRACT_LE_8BITS(p),
-               EXTRACT_LE_8BITS(p + 1),
-               EXTRACT_LE_16BITS(p + 2)));
-    }
-    break;
-  case 0x1c: /* DSME PAN Descriptor IE */
-    /*FALLTHROUGH*/
-  case 0x21: /* Extended DSME PAN descriptior IE */
-    if (ie_len < 2) {
-      ND_PRINT((ndo, "[ERROR: Truncated DSME PAN IE]"));
-    } else {
-      uint16_t ss, ptr;
-      int len, hopping_present;
-    
-      hopping_present = 0;
-    
-      ss = EXTRACT_LE_16BITS(p);
-      ieee802_15_4_print_superframe_specification(ndo, ss);
-      if (ie_len < 3) {
-       ND_PRINT((ndo, "[ERROR: Truncated before pending addresses field]"));
-       break;
-      }
-      ptr = 2;
-      len = ieee802_15_4_print_pending_addresses(ndo, p + ptr, ie_len - ptr);
-      if (len < 0) {
-       break;
-      }
-      ptr += len;
-    
-      if (element_id == 0x21) {
-       /* Extended version. */
-       if (ie_len < ptr + 2) {
-         ND_PRINT((ndo, "[ERROR: Truncated before DSME Superframe Specification]"));
-         break;
-       }
-       ss = EXTRACT_LE_16BITS(p + ptr);
-       ptr += 2;
-       ND_PRINT((ndo, "Multi-superframe Order = %d", ss & 0xff));
-       ND_PRINT((ndo, ", %s", ((ss & 0x100) ? "Channel hopping mode" :
-                               "Channel adaptation mode")));
-       if (ss & 0x400) { ND_PRINT((ndo, ", CAP reduction enabled")); }
-       if (ss & 0x800) { ND_PRINT((ndo, ", Deferred beacon enabled")); }
-       if (ss & 0x1000) {
-         ND_PRINT((ndo, ", Hopping Sequence Present"));
-         hopping_present = 1;
-       }
-      } else {
-       if (ie_len < ptr + 1) {
-         ND_PRINT((ndo, "[ERROR: Truncated before DSME Superframe Specification]"));
-         break;
-       }
-       ss = EXTRACT_LE_8BITS(p + ptr);
-       ptr++;
-       ND_PRINT((ndo, "Multi-superframe Order = %d", ss & 0x0f));
-       ND_PRINT((ndo, ", %s", ((ss & 0x10) ? "Channel hopping mode" :
-                               "Channel adaptation mode")));
-       if (ss & 0x40) { ND_PRINT((ndo, ", CAP reduction enabled")); }
-       if (ss & 0x80) { ND_PRINT((ndo, ", Deferred beacon enabled")); }
-      }
-      if (ie_len < ptr + 8) {
-       ND_PRINT((ndo, " [ERROR: Truncated before Time syncronization specification]"));
-       break;
-      }
-      ND_PRINT((ndo, "Beacon timestamp = %" PRIu64 ", offset = %d",
-               EXTRACT_LE_48BITS(p + ptr),
-               EXTRACT_LE_16BITS(p + ptr + 6)));
-      ptr += 8;
-      if (ie_len < ptr + 4) {
-       ND_PRINT((ndo, " [ERROR: Truncated before Beacon Bitmap]"));
-       break;
-      }
-    
-      len = EXTRACT_LE_16BITS(p + ptr + 2);
-      ND_PRINT((ndo, "SD Index = %d, Bitmap len = %d, ",
-               EXTRACT_LE_16BITS(p + ptr), len));
-      ptr += 4;
-      if (ie_len < ptr + len) {
-       ND_PRINT((ndo, " [ERROR: Truncated in SD bitmap]"));
-       break;
-      }
-      ND_PRINT((ndo, " SD Bitmap = "));
-      for(i = 0; i < len; i++) {
-       ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + ptr + i)));
-      }
-      ptr += len;
-    
-      if (ie_len < ptr + 5) {
-       ND_PRINT((ndo, " [ERROR: Truncated before Channel hopping specification]"));
-       break;
-      }
-    
-      len = EXTRACT_LE_16BITS(p + ptr + 4);
-      ND_PRINT((ndo, "Hopping Seq ID = %d, PAN Coordinator BSN = %d, "
-               "Channel offset = %d, Bitmap length = %d, ",
-               EXTRACT_LE_8BITS(p + ptr),
-               EXTRACT_LE_8BITS(p + ptr + 1),
-               EXTRACT_LE_16BITS(p + ptr + 2),
-               len));
-      ptr += 5;
-      if (ie_len < ptr + len) {
-       ND_PRINT((ndo, " [ERROR: Truncated in Channel offset bitmap]"));
-       break;
-      }
-      ND_PRINT((ndo, " Channel offset bitmap = "));
-      for(i = 0; i < len; i++) {
-       ND_PRINT((ndo, "%02x ",
-                 EXTRACT_LE_8BITS(p + ptr + i)));
-      }
-      ptr += len;
-      if (hopping_present) {
-       if (ie_len < ptr + 1) {
-         ND_PRINT((ndo, " [ERROR: Truncated in Hopping Sequence length]"));
-         break;
-       }
-       len = EXTRACT_LE_8BITS(p + ptr);
-       ptr++;
-       ND_PRINT((ndo, "Hopping Seq length = %d [ ", len));
+       int i;
 
-       /* The specification is not clear how the
-          hopping sequence is encoded, I assume two octet
-          unsigned integers for each channel. */
+       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, ", 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 ", GET_U_1(p + i));
+                       }
+               }
+               break;
+       case 0x1a: /* LE CSL IE */
+               if (ie_len < 4) {
+                       ND_PRINT("[ERROR: Truncated CSL IE]");
+               } else {
+                       ND_PRINT("CSL Phase = %d, CSL Period = %d",
+                                GET_LE_U_2(p), GET_LE_U_2(p + 2));
+                       if (ie_len >= 6) {
+                               ND_PRINT(", Rendezvous time = %d",
+                                        GET_LE_U_2(p + 4));
+                       }
+                       if (ie_len != 4 && ie_len != 6) {
+                               ND_PRINT(" [ERROR: CSL IE length wrong]");
+                       }
+               }
+               break;
+       case 0x1b: /* LE RIT IE */
+               if (ie_len < 4) {
+                       ND_PRINT("[ERROR: Truncated RIT IE]");
+               } else {
+                       ND_PRINT("Time to First Listen = %d, # of Repeat Listen = %d, Repeat Listen Interval = %d",
+                                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 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 = 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 = 2;
+                       len = ieee802_15_4_print_pending_addresses(ndo,
+                                                                  p + ptr,
+                                                                  ie_len -
+                                                                  ptr);
+                       if (len < 0) {
+                               break;
+                       }
+                       ptr += len;
+
+                       if (element_id == 0x21) {
+                               /* Extended version. */
+                               if (ie_len < ptr + 2) {
+                                       ND_PRINT("[ERROR: Truncated before DSME Superframe Specification]");
+                                       break;
+                               }
+                               ss = GET_LE_U_2(p + ptr);
+                               ptr += 2;
+                               ND_PRINT("Multi-superframe Order = %d", ss & 0xff);
+                               ND_PRINT(", %s", ((ss & 0x100) ?
+                                                 "Channel hopping mode" :
+                                                 "Channel adaptation mode"));
+                               if (ss & 0x400) {
+                                       ND_PRINT(", CAP reduction enabled");
+                               }
+                               if (ss & 0x800) {
+                                       ND_PRINT(", Deferred beacon enabled");
+                               }
+                               if (ss & 0x1000) {
+                                       ND_PRINT(", Hopping Sequence Present");
+                                       hopping_present = 1;
+                               }
+                       } else {
+                               if (ie_len < ptr + 1) {
+                                       ND_PRINT("[ERROR: Truncated before DSME Superframe Specification]");
+                                       break;
+                               }
+                               ss = GET_U_1(p + ptr);
+                               ptr++;
+                               ND_PRINT("Multi-superframe Order = %d",
+                                        ss & 0x0f);
+                               ND_PRINT(", %s", ((ss & 0x10) ?
+                                                 "Channel hopping mode" :
+                                                 "Channel adaptation mode"));
+                               if (ss & 0x40) {
+                                       ND_PRINT(", CAP reduction enabled");
+                               }
+                               if (ss & 0x80) {
+                                       ND_PRINT(", Deferred beacon enabled");
+                               }
+                       }
+                       if (ie_len < ptr + 8) {
+                               ND_PRINT(" [ERROR: Truncated before Time synchronization specification]");
+                               break;
+                       }
+                       ND_PRINT("Beacon timestamp = %" PRIu64 ", offset = %d",
+                                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 = GET_LE_U_2(p + ptr + 2);
+                       ND_PRINT("SD Index = %d, Bitmap len = %d, ",
+                                GET_LE_U_2(p + ptr), ulen);
+                       ptr += 4;
+                       if (ie_len < ptr + ulen) {
+                               ND_PRINT(" [ERROR: Truncated in SD bitmap]");
+                               break;
+                       }
+                       ND_PRINT(" SD Bitmap = ");
+                       for(i = 0; i < ulen; 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 = GET_LE_U_2(p + ptr + 4);
+                       ND_PRINT("Hopping Seq ID = %d, PAN Coordinator BSN = %d, "
+                                "Channel offset = %d, Bitmap length = %d, ",
+                                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(" [ERROR: Truncated in Channel offset bitmap]");
+                               break;
+                       }
+                       ND_PRINT(" Channel offset bitmap = ");
+                       for(i = 0; i < ulen; i++) {
+                               ND_PRINT("%02x ", GET_U_1(p + ptr + i));
+                       }
+                       ptr += ulen;
+                       if (hopping_present) {
+                               if (ie_len < ptr + 1) {
+                                       ND_PRINT(" [ERROR: Truncated in Hopping Sequence length]");
+                                       break;
+                               }
+                               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 ",
+                                                GET_LE_U_2(p + ptr + i * 2));
+                               }
+                               ND_PRINT("]");
+                               ptr += ulen * 2;
+                       }
+               }
+               break;
+       case 0x1d: /* Rendezvous Tome IE */
+               if (ie_len != 4) {
+                       ND_PRINT("[ERROR: Length != 2]");
+               } else {
+                       uint16_t r_time, w_u_interval;
+                       r_time = GET_LE_U_2(p);
+                       w_u_interval = GET_LE_U_2(p + 2);
 
-       if (ie_len < ptr + len * 2) {
-         ND_PRINT((ndo, " [ERROR: Truncated in Channel offset bitmap]"));
-         break;
-       }
-       for(i = 0; i < len; i++) {
-         ND_PRINT((ndo, "%02x ", EXTRACT_LE_16BITS(p + ptr + i * 2)));
+                       ND_PRINT("Rendezvous time = %d, Wake-up Interval = %d",
+                                r_time, w_u_interval);
+               }
+               break;
+       case 0x1e: /* Time correction IE */
+               if (ie_len != 2) {
+                       ND_PRINT("[ERROR: Length != 2]");
+               } else {
+                       uint16_t val;
+                       int16_t timecorr;
+
+                       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: /* Fragment Sequence Content Description IE */
+               /* XXX Not implemented */
+       case 0x23: /* Simplified Superframe Specification IE */
+               /* XXX Not implemented */
+       case 0x24: /* Simplified GTS Specification IE */
+               /* XXX Not implemented */
+       case 0x25: /* LECIM Capabilities IE */
+               /* XXX Not implemented */
+       case 0x26: /* TRLE Descriptor IE */
+               /* XXX Not implemented */
+       case 0x27: /* RCC Capabilities IE */
+               /* XXX Not implemented */
+       case 0x28: /* RCCN Descriptor IE */
+               /* XXX Not implemented */
+       case 0x29: /* Global Time IE */
+               /* XXX Not implemented */
+       case 0x2b: /* DA IE */
+               /* XXX Not implemented */
+       default:
+               ND_PRINT("IE Data = ");
+               for(i = 0; i < ie_len; i++) {
+                       ND_PRINT("%02x ", GET_U_1(p + i));
+               }
+               break;
        }
-       ND_PRINT((ndo, "]"));
-       ptr += len * 2;
-      }
-    }
-    break;
-  case 0x1d: /* Rendezvous Tome IE */
-    if (ie_len != 4) {
-      ND_PRINT((ndo, "[ERROR: Length != 2]"));
-    } else {
-      uint16_t r_time, w_u_interval;
-      r_time = EXTRACT_LE_16BITS(p);
-      w_u_interval = EXTRACT_LE_16BITS(p + 2);
-    
-      ND_PRINT((ndo, "Rendezvous time = %d, Wake-up Interval = %d",
-               r_time, w_u_interval));
-    }
-    break;
-  case 0x1e: /* Time correction IE */
-    if (ie_len != 2) {
-      ND_PRINT((ndo, "[ERROR: Length != 2]"));
-    } else {
-      uint16_t val;
-      int16_t timecorr;
-
-      val = EXTRACT_LE_16BITS(p);
-      if (val & 0x8000) { ND_PRINT((ndo, "Negative ")); }
-      val &= 0xfff;
-      val <<= 4;
-      timecorr = val;
-      timecorr >>= 4;
-    
-      ND_PRINT((ndo, "Ack time correction = %d, ", timecorr));
-    }
-    break;
-  case 0x22: /* Frament Sequence Content Description IE */
-    /* XXX Not implemented */
-  case 0x23: /* Simplified Superframe Specification IE */
-    /* XXX Not implemented */
-  case 0x24: /* Simplified GTS Specification IE */
-    /* XXX Not implemented */
-  case 0x25: /* LECIM Capabilities IE */
-    /* XXX Not implemented */
-  case 0x26: /* TRLE Descriptor IE */
-    /* XXX Not implemented */
-  case 0x27: /* RCC Capabilities IE */
-    /* XXX Not implemented */
-  case 0x28: /* RCCN Descriptor IE */
-    /* XXX Not implemented */
-  case 0x29: /* Global Time IE */
-    /* XXX Not implemented */
-  case 0x2b: /* DA IE */
-    /* XXX Not implemented */
-  default:
-    ND_PRINT((ndo, "IE Data = "));
-    for(i = 0; i < ie_len; i++) {
-      ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-    }
-    break;
-  }
 }
 
 /*
@@ -848,69 +927,70 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
 static int
 ieee802_15_4_print_header_ie_list(netdissect_options *ndo,
                                  const u_char *p,
-                                 uint16_t caplen,
+                                 u_int caplen,
                                  int *payload_ie_present)
 {
-  int len, ie, ie_len, element_id, i;
-
-  *payload_ie_present = 0;
-  len = 0;
-  do {
-    if (caplen < 2) {
-      ND_PRINT((ndo, "[ERROR: Truncated header IE]"));
-      return -1;
-    }
-    /* Extract IE Header */
-    ie = EXTRACT_LE_16BITS(p);
-    if (CHECK_BIT(ie, 15)) {
-      ND_PRINT((ndo, "[ERROR: Header IE with type 1] "));
-    }
-    /* Get length and Element ID */
-    ie_len = ie & 0x7f;
-    element_id = (ie >> 7) & 0xff;
-    if (element_id > 127) {
-      ND_PRINT((ndo, "Reserved Element ID %02x, length = %d ",
-               element_id, ie_len));
-    } else {
-      if (ie_len == 0) {
-       ND_PRINT((ndo, "\n\t%s [",
-                 h_ie_names[element_id]));
-      } else {
-       ND_PRINT((ndo, "\n\t%s [ length = %d, ",
-                 h_ie_names[element_id], ie_len));
-      }
-    }
-    if (caplen < ie_len) {
-      ND_PRINT((ndo, "[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, ie_len, element_id);
-    } else {
-      if (ie_len != 0) {
-       ND_PRINT((ndo, "IE Data = "));
-       for(i = 0; i < ie_len; i++) {
-         ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-       }
-      }
-    }
-    ND_PRINT((ndo, "] "));
-    len += 2 + ie_len;
-    p += ie_len;
-    caplen -= 2 + ie_len;
-    if (element_id == 0x7e) {
-      *payload_ie_present = 1;
-      break;
-    }
-    if (element_id == 0x7f) {
-      break;
-    }
-  } while (caplen > 0);
-  return len;
+       int len, ie, element_id, i;
+       uint16_t ie_len;
+
+       *payload_ie_present = 0;
+       len = 0;
+       do {
+               if (caplen < 2) {
+                       ND_PRINT("[ERROR: Truncated header IE]");
+                       return -1;
+               }
+               /* Extract IE Header */
+               ie = GET_LE_U_2(p);
+               if (CHECK_BIT(ie, 15)) {
+                       ND_PRINT("[ERROR: Header IE with type 1] ");
+               }
+               /* Get length and Element ID */
+               ie_len = ie & 0x7f;
+               element_id = (ie >> 7) & 0xff;
+               if (element_id > 127) {
+                       ND_PRINT("Reserved Element ID %02x, length = %d ",
+                                element_id, ie_len);
+               } else {
+                       if (ie_len == 0) {
+                               ND_PRINT("\n\t%s [", h_ie_names[element_id]);
+                       } else {
+                               ND_PRINT("\n\t%s [ length = %d, ",
+                                        h_ie_names[element_id], 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,
+                                                    ie_len, element_id);
+               } else {
+                       if (ie_len != 0) {
+                               ND_PRINT("IE Data = ");
+                               for(i = 0; i < ie_len; i++) {
+                                       ND_PRINT("%02x ", GET_U_1(p + i));
+                               }
+                       }
+               }
+               ND_PRINT("] ");
+               len += 2 + ie_len;
+               p += ie_len;
+               caplen -= 2 + ie_len;
+               if (element_id == 0x7e) {
+                       *payload_ie_present = 1;
+                       break;
+               }
+               if (element_id == 0x7f) {
+                       break;
+               }
+       } while (caplen != 0);
+       return len;
 }
 
 /*
@@ -922,241 +1002,244 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
                           uint16_t sub_ie_len,
                           int sub_id)
 {
-  int i, j, 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) {
-  case 0x08: /* Vendor Specific Nested IE */
-    if (sub_ie_len < 3) {
-      ND_PRINT((ndo, "[ERROR: Vendor OUI missing]"));
-    } else {
-      ND_PRINT((ndo, "OUI = 0x%02x%02x%02x, ",
-               EXTRACT_LE_8BITS(p),
-               EXTRACT_LE_8BITS(p + 1),
-               EXTRACT_LE_8BITS(p + 2)));
-      ND_PRINT((ndo, "Data = "));
-      for(i = 3; i < sub_ie_len; i++) {
-       ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-      }
-    }
-    break;
-  case 0x09: /* Channel Hopping IE */
-    if (sub_ie_len < 1) {
-      ND_PRINT((ndo, "[ERROR: Hopping sequence ID missing]"));
-    } else if (sub_ie_len == 1) {
-      ND_PRINT((ndo, "Hopping Sequence ID = %d", EXTRACT_LE_8BITS(p)));
-      p++;
-      sub_ie_len--;
-    } else {
-      int channel_page, number_of_channels;
-    
-      ND_PRINT((ndo, "Hopping Sequence ID = %d", EXTRACT_LE_8BITS(p)));
-      p++;
-      sub_ie_len--;
-      if (sub_ie_len < 7) {
-       ND_PRINT((ndo, "[ERROR: IE truncated]"));
-       break;
-      }
-      channel_page = EXTRACT_LE_8BITS(p);
-      number_of_channels = EXTRACT_LE_16BITS(p + 1);
-      ND_PRINT((ndo, "Channel Page = %d, Number of Channels = %d, ",
-               channel_page, number_of_channels));
-      ND_PRINT((ndo, "Phy Configuration = 0x%08x, ",
-               EXTRACT_LE_32BITS(p + 3)));
-      p += 7;
-      sub_ie_len -= 7;
-      if (channel_page == 9 || channel_page == 10) {
-       len = (number_of_channels + 7) / 8;
-       if (sub_ie_len < len) {
-         ND_PRINT((ndo, "[ERROR: IE truncated]"));
-         break;
-       }
-       ND_PRINT((ndo, "Extended bitmap = 0x"));
-       for(i = 0; i < len; i++) {
-         ND_PRINT((ndo, "%02x", EXTRACT_LE_8BITS(p + i)));
-       }
-       ND_PRINT((ndo, ", "));
-       p += len;
-       sub_ie_len -= len;
-      }
-      if (sub_ie_len < 2) {
-       ND_PRINT((ndo, "[ERROR: IE truncated]"));
-       break;
-      }
-      len = EXTRACT_LE_16BITS(p);
-      p += 2;
-      sub_ie_len -= 2;
-      ND_PRINT((ndo, "Hopping Seq length = %d [ ", len));
-    
-      if (sub_ie_len < len * 2) {
-       ND_PRINT((ndo, " [ERROR: IE truncated]"));
-       break;
-      }
-      for(i = 0; i < len; i++) {
-       ND_PRINT((ndo, "%02x ", EXTRACT_LE_16BITS(p + i * 2)));
-      }
-      ND_PRINT((ndo, "]"));
-      p += len * 2;
-      sub_ie_len -= len * 2;
-      if (sub_ie_len < 2) {
-       ND_PRINT((ndo, "[ERROR: IE truncated]"));
-       break;
-      }
-      ND_PRINT((ndo, "Current hop = %d", EXTRACT_LE_16BITS(p)));
-    }
-  
-    break;
-  case 0x1a: /* TSCH Syncronization IE. */
-    if (sub_ie_len < 6) {
-      ND_PRINT((ndo, "[ERROR: Length != 6]"));
-    }
-    ND_PRINT((ndo, "ASN = %02x%02x%02x%02x%02x, Join Metric = %d ",
-             EXTRACT_LE_8BITS(p + 4), EXTRACT_LE_8BITS(p + 3),
-             EXTRACT_LE_8BITS(p + 2), EXTRACT_LE_8BITS(p + 1),
-             EXTRACT_LE_8BITS(p + 0), EXTRACT_LE_8BITS(p + 5)));
-    break;
-  case 0x1b: /* TSCH Slotframe and Link IE. */
-    {
-      int sf_num, off, links, opts;
-    
-      if (sub_ie_len < 1) {
-       ND_PRINT((ndo, "[ERROR: Truncated IE]"));
-       break;
-      }
-      sf_num = EXTRACT_LE_8BITS(p);
-      ND_PRINT((ndo, "Slotframes = %d ", sf_num));
-      off = 1;
-      for(i = 0; i < sf_num; i++) {
-       if (sub_ie_len < off + 4) {
-         ND_PRINT((ndo, "[ERROR: Truncated IE before slotframes]"));
-         break;
-       }
-       links = EXTRACT_LE_8BITS(p + off + 3);
-       ND_PRINT((ndo, "\n\t\t\t[ Handle %d, size = %d, links = %d ",
-                 EXTRACT_LE_8BITS(p + off),
-                 EXTRACT_LE_16BITS(p + off + 1),
-                 links));
-       off += 4;
-       for(j = 0; j < links; j++) {
-         if (sub_ie_len < off + 5) {
-           ND_PRINT((ndo, "[ERROR: Truncated IE links]"));
-           break;
-         }
-         opts = EXTRACT_LE_8BITS(p + off + 4);
-         ND_PRINT((ndo, "\n\t\t\t\t[ Timeslot =  %d, Offset = %d, Options = ",
-                   EXTRACT_LE_16BITS(p + off),
-                   EXTRACT_LE_16BITS(p + off + 2)));
-         if (opts & 0x1) { ND_PRINT((ndo, "TX ")); }
-         if (opts & 0x2) { ND_PRINT((ndo, "RX ")); }
-         if (opts & 0x4) { ND_PRINT((ndo, "Shared ")); }
-         if (opts & 0x8) { ND_PRINT((ndo, "Timekeeping ")); }
-         if (opts & 0x10) { ND_PRINT((ndo, "Priority ")); }
-         off += 5;
-         ND_PRINT((ndo, "] "));
+       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) {
+       case 0x08: /* Vendor Specific Nested IE */
+               if (sub_ie_len < 3) {
+                       ND_PRINT("[ERROR: Vendor OUI missing]");
+               } else {
+                       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 < sub_ie_len; i++) {
+                               ND_PRINT("%02x ", GET_U_1(p + i));
+                       }
+               }
+               break;
+       case 0x09: /* Channel Hopping IE */
+               if (sub_ie_len < 1) {
+                       ND_PRINT("[ERROR: Hopping sequence ID missing]");
+               } else if (sub_ie_len == 1) {
+                       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", GET_U_1(p));
+                       p++;
+                       sub_ie_len--;
+                       if (sub_ie_len < 7) {
+                               ND_PRINT("[ERROR: IE truncated]");
+                               break;
+                       }
+                       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, ",
+                                GET_LE_U_4(p + 3));
+                       p += 7;
+                       sub_ie_len -= 7;
+                       if (channel_page == 9 || channel_page == 10) {
+                               len = (number_of_channels + 7) / 8;
+                               if (sub_ie_len < len) {
+                                       ND_PRINT("[ERROR: IE truncated]");
+                                       break;
+                               }
+                               ND_PRINT("Extended bitmap = 0x");
+                               for(i = 0; i < len; i++) {
+                                       ND_PRINT("%02x", GET_U_1(p + i));
+                               }
+                               ND_PRINT(", ");
+                               p += len;
+                               sub_ie_len -= len;
+                       }
+                       if (sub_ie_len < 2) {
+                               ND_PRINT("[ERROR: IE truncated]");
+                               break;
+                       }
+                       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 ", GET_LE_U_2(p + i * 2));
+                       }
+                       ND_PRINT("]");
+                       p += len * 2;
+                       sub_ie_len -= len * 2;
+                       if (sub_ie_len < 2) {
+                               ND_PRINT("[ERROR: IE truncated]");
+                               break;
+                       }
+                       ND_PRINT("Current hop = %d", GET_LE_U_2(p));
+               }
+
+               break;
+       case 0x1a: /* TSCH Synchronization IE. */
+               if (sub_ie_len < 6) {
+                       ND_PRINT("[ERROR: Length != 6]");
+               }
+               ND_PRINT("ASN = %010" PRIx64 ", Join Metric = %d ",
+                        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 = GET_U_1(p);
+                       ND_PRINT("Slotframes = %d ", sf_num);
+                       off = 1;
+                       for(i = 0; i < sf_num; i++) {
+                               if (sub_ie_len < off + 4) {
+                                       ND_PRINT("[ERROR: Truncated IE before slotframes]");
+                                       break;
+                               }
+                               links = GET_U_1(p + off + 3);
+                               ND_PRINT("\n\t\t\t[ Handle %d, size = %d, links = %d ",
+                                        GET_U_1(p + off),
+                                        GET_LE_U_2(p + off + 1),
+                                        links);
+                               off += 4;
+                               for(j = 0; j < links; j++) {
+                                       if (sub_ie_len < off + 5) {
+                                               ND_PRINT("[ERROR: Truncated IE links]");
+                                               break;
+                                       }
+                                       opts = GET_U_1(p + off + 4);
+                                       ND_PRINT("\n\t\t\t\t[ Timeslot =  %d, Offset = %d, Options = ",
+                                                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 "); }
+                                       if (opts & 0x8) {
+                                               ND_PRINT("Timekeeping ");
+                                       }
+                                       if (opts & 0x10) {
+                                               ND_PRINT("Priority ");
+                                       }
+                                       off += 5;
+                                       ND_PRINT("] ");
+                               }
+                               ND_PRINT("] ");
+                       }
+               }
+               break;
+       case 0x1c: /* TSCH Timeslot IE. */
+               if (sub_ie_len == 1) {
+                       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 ",
+                                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 ",
+                                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 ", GET_U_1(p + i));
+                       }
+               }
+               break;
+       case 0x1d: /* Hopping timing IE */
+               /* XXX Not implemented */
+       case 0x1e: /* Enhanced Beacon Filter IE */
+               /* XXX Not implemented */
+       case 0x1f: /* MAC Metrics IE */
+               /* XXX Not implemented */
+       case 0x20: /* All MAC Metrics IE */
+               /* XXX Not implemented */
+       case 0x21: /* Coexistence Specification IE */
+               /* XXX Not implemented */
+       case 0x22: /* SUN Device Capabilities IE */
+               /* XXX Not implemented */
+       case 0x23: /* SUN FSK Generic PHY IE */
+               /* XXX Not implemented */
+       case 0x24: /* Mode Switch Parameter IE */
+               /* XXX Not implemented */
+       case 0x25: /* PHY Parameter Change IE */
+               /* XXX Not implemented */
+       case 0x26: /* O-QPSK PHY Mode IE */
+               /* XXX Not implemented */
+       case 0x27: /* PCA Allocation IE */
+               /* XXX Not implemented */
+       case 0x28: /* LECIM DSSS Operating Mode IE */
+               /* XXX Not implemented */
+       case 0x29: /* LECIM FSK Operating Mode IE */
+               /* XXX Not implemented */
+       case 0x2b: /* TVWS PHY Operating Mode Description IE */
+               /* XXX Not implemented */
+       case 0x2c: /* TVWS Device Capabilities IE */
+               /* XXX Not implemented */
+       case 0x2d: /* TVWS Device Category IE */
+               /* XXX Not implemented */
+       case 0x2e: /* TVWS Device Identification IE */
+               /* XXX Not implemented */
+       case 0x2f: /* TVWS Device Location IE */
+               /* XXX Not implemented */
+       case 0x30: /* TVWS Channel Information Query IE */
+               /* XXX Not implemented */
+       case 0x31: /* TVWS Channel Information Source IE */
+               /* XXX Not implemented */
+       case 0x32: /* CTM IE */
+               /* XXX Not implemented */
+       case 0x33: /* Timestamp IE */
+               /* XXX Not implemented */
+       case 0x34: /* Timestamp Difference IE */
+               /* XXX Not implemented */
+       case 0x35: /* TMCTP Specification IE */
+               /* XXX Not implemented */
+       case 0x36: /* TCC PHY Operating Mode IE */
+               /* XXX Not implemented */
+       default:
+               ND_PRINT("IE Data = ");
+               for(i = 0; i < sub_ie_len; i++) {
+                       ND_PRINT("%02x ", GET_U_1(p + i));
+               }
+               break;
        }
-       ND_PRINT((ndo, "] "));
-      }
-    }
-    break;
-  case 0x1c: /* TSCH Timeslot IE. */
-    if (sub_ie_len == 1) {
-      ND_PRINT((ndo, "Time slot ID = %d ", EXTRACT_LE_8BITS(p)));
-    } else if (sub_ie_len == 25) {
-      ND_PRINT((ndo, "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_LE_8BITS(p),
-               EXTRACT_LE_16BITS(p + 1),
-               EXTRACT_LE_16BITS(p + 3),
-               EXTRACT_LE_16BITS(p + 5),
-               EXTRACT_LE_16BITS(p + 7),
-               EXTRACT_LE_16BITS(p + 9),
-               EXTRACT_LE_16BITS(p + 11),
-               EXTRACT_LE_16BITS(p + 13),
-               EXTRACT_LE_16BITS(p + 15),
-               EXTRACT_LE_16BITS(p + 17),
-               EXTRACT_LE_16BITS(p + 19),
-               EXTRACT_LE_16BITS(p + 21),
-               EXTRACT_LE_16BITS(p + 23)));
-    } else if (sub_ie_len == 27) {
-      ND_PRINT((ndo, "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_LE_8BITS(p),
-               EXTRACT_LE_16BITS(p + 1),
-               EXTRACT_LE_16BITS(p + 3),
-               EXTRACT_LE_16BITS(p + 5),
-               EXTRACT_LE_16BITS(p + 7),
-               EXTRACT_LE_16BITS(p + 9),
-               EXTRACT_LE_16BITS(p + 11),
-               EXTRACT_LE_16BITS(p + 13),
-               EXTRACT_LE_16BITS(p + 15),
-               EXTRACT_LE_16BITS(p + 17),
-               EXTRACT_LE_16BITS(p + 19),
-               EXTRACT_LE_24BITS(p + 21),
-               EXTRACT_LE_24BITS(p + 24)));
-    } else {
-      ND_PRINT((ndo, "[ERROR: Length not 1, 25, or 27]"));
-      ND_PRINT((ndo, "\n\t\t\tIE Data = "));
-      for(i = 0; i < sub_ie_len; i++) {
-       ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-      }
-    }
-    break;
-  case 0x1d: /* Hopping timing IE */
-    /* XXX Not implemented */
-  case 0x1e: /* Enhanced Beacon Filter IE */
-    /* XXX Not implemented */
-  case 0x1f: /* MAC Metrics IE */
-    /* XXX Not implemented */
-  case 0x20: /* All MAC Metrics IE */
-    /* XXX Not implemented */
-  case 0x21: /* Coexistence Specification IE */
-    /* XXX Not implemented */
-  case 0x22: /* SUN Device Capabilities IE */
-    /* XXX Not implemented */
-  case 0x23: /* SUN FSK Generic PHY IE */
-    /* XXX Not implemented */
-  case 0x24: /* Mode Switch Parameter IE */
-    /* XXX Not implemented */
-  case 0x25: /* PHY Parameter Change IE */
-    /* XXX Not implemented */
-  case 0x26: /* O-QPSK PHY Mode IE */
-    /* XXX Not implemented */
-  case 0x27: /* PCA Allocation IE */
-    /* XXX Not implemented */
-  case 0x28: /* LECIM DSSS Operating Mode IE */
-    /* XXX Not implemented */
-  case 0x29: /* LECIM FSK Operating Mode IE */
-    /* XXX Not implemented */
-  case 0x2b: /* TVWS PHY Operating Mode Description IE */
-    /* XXX Not implemented */
-  case 0x2c: /* TVWS Device Capabilities IE */
-    /* XXX Not implemented */
-  case 0x2d: /* TVWS Device Catagory IE */
-    /* XXX Not implemented */
-  case 0x2e: /* TVWS Device Identification IE */
-    /* XXX Not implemented */
-  case 0x2f: /* TVWS Device Location IE */
-    /* XXX Not implemented */
-  case 0x30: /* TVWS Channel Information Query IE */
-    /* XXX Not implemented */
-  case 0x31: /* TVWS Channel Information Source IE */
-    /* XXX Not implemented */
-  case 0x32: /* CTM IE */
-    /* XXX Not implemented */
-  case 0x33: /* Timestamp IE */
-    /* XXX Not implemented */
-  case 0x34: /* Timestamp Difference IE */
-    /* XXX Not implemented */
-  case 0x35: /* TMCTP Specification IE */
-    /* XXX Not implemented */
-  case 0x36: /* TCC PHY Operating Mode IE */
-    /* XXX Not implemented */
-  default:
-    ND_PRINT((ndo, "IE Data = "));
-    for(i = 0; i < sub_ie_len; i++) {
-      ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-    }
-    break;
-  }
 }
 
 /*
@@ -1168,55 +1251,158 @@ ieee802_15_4_print_mlme_ie_list(netdissect_options *ndo,
                                const u_char *p,
                                uint16_t ie_len)
 {
-  int ie, sub_ie_len, sub_id, i, type;
-
-  do {
-    if (ie_len < 2) {
-      ND_PRINT((ndo, "[ERROR: Truncated MLME IE]"));
-      return;
-    }
-    /* Extract IE header */
-    ie = EXTRACT_LE_16BITS(p);
-    type = CHECK_BIT(ie, 15);
-    if (type) {
-      /* Long type */
-      sub_ie_len = ie & 0x3ff;
-      sub_id = (ie >> 11) & 0x0f;
-    } else {
-      sub_ie_len = ie & 0xff;
-      sub_id = (ie >> 8) & 0x7f;
-    }
-  
-    /* Skip the IE header */
-    p += 2;
-  
-    if (type == 0) {
-      ND_PRINT((ndo, "\n\t\t%s [ length = %d, ",
-               p_mlme_short_names[sub_id], sub_ie_len));
-    } else {
-      ND_PRINT((ndo, "\n\t\t%s [ length = %d, ",
-               p_mlme_long_names[sub_id], sub_ie_len));
-    }
-  
-    if (ie_len < sub_ie_len) {
-      ND_PRINT((ndo, "[ERROR: Truncated IE data]"));
-      return;
-    }
-    if (sub_ie_len != 0) {
-      if (ndo->ndo_vflag > 3) {
-       ieee802_15_4_print_mlme_ie(ndo, p, sub_ie_len, sub_id);
-      } else if (ndo->ndo_vflag > 2) {
-       ND_PRINT((ndo, "IE Data = "));
-       for(i = 0; i < sub_ie_len; i++) {
-         ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
+       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 = GET_LE_U_2(p);
+               type = CHECK_BIT(ie, 15);
+               if (type) {
+                       /* Long type */
+                       sub_ie_len = ie & 0x3ff;
+                       sub_id = (ie >> 11) & 0x0f;
+               } else {
+                       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);
+               } else {
+                       ND_PRINT("\n\t\t%s [ length = %d, ",
+                                p_mlme_long_names[sub_id], sub_ie_len);
+               }
+
+               if (ie_len < 2 + sub_ie_len) {
+                       ND_PRINT("[ERROR: Truncated IE data]");
+                       return;
+               }
+               if (sub_ie_len != 0) {
+                       if (ndo->ndo_vflag > 3) {
+                               ieee802_15_4_print_mlme_ie(ndo, p, sub_ie_len, sub_id);
+                       } else if (ndo->ndo_vflag > 2) {
+                               ND_PRINT("IE Data = ");
+                               for(i = 0; i < sub_ie_len; i++) {
+                                       ND_PRINT("%02x ", GET_U_1(p + i));
+                               }
+                       }
+               }
+               ND_PRINT("] ");
+               p += sub_ie_len;
+               ie_len -= 2 + sub_ie_len;
+       } while (ie_len > 0);
+}
+
+/*
+ * Multiplexd IE (802.15.9) parsing and printing.
+ *
+ * Returns number of bytes consumed from packet or -1 in case of error.
+ */
+static void
+ieee802_15_4_print_mpx_ie(netdissect_options *ndo,
+                         const u_char *p,
+                         uint16_t ie_len)
+{
+       int transfer_type, tid;
+       int fragment_number, data_start;
+       int i;
+
+       data_start = 0;
+       if (ie_len < 1) {
+               ND_PRINT("[ERROR: Transaction control byte missing]");
+               return;
+       }
+
+       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. */
+               ND_PRINT("Type = Full upper layer fragment%s, ",
+                        (transfer_type == 0x01 ?
+                         " with small Multiplex ID" : ""));
+               if (transfer_type == 0x00) {
+                       if (ie_len < 3) {
+                               ND_PRINT("[ERROR: Multiplex ID missing]");
+                               return;
+                       }
+                       data_start = 3;
+                       ND_PRINT("tid = 0x%02x, Multiplex ID = 0x%04x, ",
+                                tid, GET_LE_U_2(p + 1));
+               } else {
+                       data_start = 1;
+                       ND_PRINT("Multiplex ID = 0x%04x, ", tid);
+               }
+               break;
+       case 0x02: /* First, or middle, Fragments */
+       case 0x04: /* Last fragment */
+               if (ie_len < 2) {
+                       ND_PRINT("[ERROR: fragment number missing]");
+                       return;
+               }
+
+               fragment_number = GET_U_1(p + 1);
+               ND_PRINT("Type = %s, tid = 0x%02x, fragment = 0x%02x, ",
+                        (transfer_type == 0x02 ?
+                         (fragment_number == 0 ?
+                          "First fragment" : "Middle fragment") :
+                         "Last fragment"), tid,
+                        fragment_number);
+               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 = 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;
+               }
+               break;
+       case 0x06: /* Abort code */
+               if (ie_len == 1) {
+                       ND_PRINT("Type = Abort, tid = 0x%02x, no max size given",
+                                tid);
+               } else if (ie_len == 3) {
+                       ND_PRINT("Type = Abort, tid = 0x%02x, max size = 0x%04x",
+                                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 ", GET_U_1(p + i));
+                       }
+               }
+               return;
+               /* NOTREACHED */
+               break;
+       case 0x03: /* Reserved */
+       case 0x05: /* Reserved */
+       case 0x07: /* Reserved */
+               ND_PRINT("Type = %d (Reserved), tid = 0x%02x, ",
+                        transfer_type, tid);
+               data_start = 1;
+               break;
+       }
+
+       ND_PRINT("Upper layer data = ");
+       for(i = data_start; i < ie_len; i++) {
+               ND_PRINT("%02x ", GET_U_1(p + i));
        }
-      }
-    }
-    ND_PRINT((ndo, "] "));
-    p += sub_ie_len;
-    ie_len -= 2 + sub_ie_len;
-  } while (ie_len > 0);
-  return;
 }
 
 /*
@@ -1228,180 +1414,96 @@ ieee802_15_4_print_mlme_ie_list(netdissect_options *ndo,
 static int
 ieee802_15_4_print_payload_ie_list(netdissect_options *ndo,
                                   const u_char *p,
-                                  uint16_t caplen)
+                                  u_int caplen)
 {
-  int len, ie, ie_len, group_id, i;
-
-  len = 0;
-  do {
-    if (caplen < 2) {
-      ND_PRINT((ndo, "[ERROR: Truncated header IE]"));
-      return -1;
-    }
-    /* Extract IE header */
-    ie = EXTRACT_LE_16BITS(p);
-    if ((CHECK_BIT(ie, 15)) == 0) {
-      ND_PRINT((ndo, "[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((ndo, "\n\t%s [", p_ie_names[group_id]));
-    } else {
-      ND_PRINT((ndo, "\n\t%s [ length = %d, ",
-               p_ie_names[group_id], ie_len));
-    }
-    if (caplen < ie_len) {
-      ND_PRINT((ndo, "[ERROR: Truncated IE data]"));
-      return -1;
-    }
-    if (ndo->ndo_vflag > 3 && ie_len != 0) {
-      switch (group_id) {
-      case 0x1: /* MLME IE */
-       ieee802_15_4_print_mlme_ie_list(ndo, p, ie_len);
-       break;
-      case 0x2: /* Vendor Specific Nested IE */
-       if (ie_len < 3) {
-         ND_PRINT((ndo, "[ERROR: Vendor OUI missing]"));
-       } else {
-         ND_PRINT((ndo, "OUI = 0x%02x%02x%02x, ",
-                   EXTRACT_LE_8BITS(p),
-                   EXTRACT_LE_8BITS(p + 1),
-                   EXTRACT_LE_8BITS(p + 2)));
-         ND_PRINT((ndo, "Data = "));
-         for(i = 3; i < ie_len; i++) {
-           ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-         }
-       }
-       break;
-      case 0x3: /* Multiplexed IE (802.15.9) */
-       if (ie_len < 1) {
-         ND_PRINT((ndo, "[ERROR: Transaction control byte missing]"));
-       } else {
-         int transfer_type, tid, fragment_number, data_start;
-         transfer_type = EXTRACT_LE_8BITS(p) & 0x7;
-         tid = EXTRACT_LE_8BITS(p) >> 3;
-         switch (transfer_type) {
-         case 0x00: /* Full upper layer frame. */
-         case 0x01: /* Full upper layer frame with small Multiplex ID. */
-           data_start = 1;
-           ND_PRINT((ndo, "Type = Full upper layer fragment%s, ",
-                     (transfer_type == 0x01 ?
-                      " with small Multiplex ID" : "")));
-           if (transfer_type == 0x00) {
-             if (ie_len < 3) {
-               ND_PRINT((ndo, "[ERROR: Multiplex ID missing]"));
-             } else {
-               data_start = 3;
-               ND_PRINT((ndo, "tid = 0x%02x, Multiplex ID = 0x%04x, ",
-                         tid, EXTRACT_LE_16BITS(p + 1)));
-             }
-           } else {
-             ND_PRINT((ndo, "Multiplex ID = 0x%04x, ", tid));
-           }
-           ND_PRINT((ndo, "Upper layer data = "));
-           for(i = data_start; i < ie_len; i++) {
-             ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-           }
-           break;
-         case 0x02: /* First, or middle, Fragments */
-         case 0x04: /* Last fragment */
-           if (ie_len < 2) {
-             ND_PRINT((ndo, "[ERROR: fragment number missing]"));
-           } else {
-             fragment_number = EXTRACT_LE_8BITS(p + 1);
-             ND_PRINT((ndo, "Type = %s, tid = 0x%02x, fragment = 0x%02x, ",
-                       (transfer_type == 0x02 ?
-                        (fragment_number == 0 ?
-                         "First fragment" : "Middle fragment") :
-                        "Last fragment"), tid,
-                       fragment_number));
-             data_start = 2;
-             if (fragment_number == 0) {
-               if (ie_len < 6) {
-                 ND_PRINT((ndo, "[ERROR: Total upper layer size or multiplex ID missing]"));
+       int len, ie, group_id, i;
+       uint16_t ie_len;
+
+       len = 0;
+       do {
+               if (caplen < 2) {
+                       ND_PRINT("[ERROR: Truncated header IE]");
+                       return -1;
+               }
+               /* Extract IE header */
+               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 [", p_ie_names[group_id]);
                } else {
-                 int total_size, multiplex_id;
-                 total_size = EXTRACT_LE_16BITS(p + 2);
-                 multiplex_id = EXTRACT_LE_16BITS(p + 4);
-                 ND_PRINT((ndo, "Total upper layer size = 0x%04x, Multiplex ID = 0x%04x, ",
-                           total_size, multiplex_id));
-               }
-               data_start = 6;
-             }
-             ND_PRINT((ndo, "Upper layer data = "));
-             for(i = data_start; i < ie_len; i++) {
-               ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-             }
-           }
-           break;
-         case 0x06: /* Abort code */
-           if (ie_len == 1) {
-             ND_PRINT((ndo, "Type = Abort, tid = 0x%02x, no max size given",
-                       tid));
-           } else if (ie_len == 3) {
-             ND_PRINT((ndo, "Type = Abort, tid = 0x%02x, max size = 0x%04x",
-                       tid, EXTRACT_LE_16BITS(p + 1)));
-           } else {
-             ND_PRINT((ndo, "Type = Abort, tid = 0x%02x, invalid length = %d (not 1 or 3)",
-                       tid, ie_len));
-             ND_PRINT((ndo, "Abort data = "));
-             for(i = 1; i < ie_len; i++) {
-               ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-             }
-           }
-           break;
-         case 0x03: /* Reserved */
-         case 0x05: /* Reserved */
-         case 0x07: /* Reserved */
-           ND_PRINT((ndo, "Type = %d (Reserved), tid = 0x%02x, ",
-                     transfer_type, tid));
-           ND_PRINT((ndo, "Upper layer data = "));
-           for(i = 1; i < ie_len; i++) {
-             ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-           }
-           break;
-         }
-       }
-       break;
-      case 0x5: /* IETF IE */
-       if (ie_len < 1) {
-         ND_PRINT((ndo, "[ERROR: Subtype ID missing]"));
-       } else {        
-         ND_PRINT((ndo, "Subtype ID = 0x%02x, Subtype content = ",
-                   EXTRACT_LE_8BITS(p)));
-         for(i = 1; i < ie_len; i++) {
-           ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-         }
-       }
-       break;
-      default:
-       ND_PRINT((ndo, "IE Data = "));
-       for(i = 0; i < ie_len; i++) {
-         ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-       }
-       break;
-      }
-    } else {
-      if (ie_len != 0) {
-       ND_PRINT((ndo, "IE Data = "));
-       for(i = 0; i < ie_len; i++) {
-         ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-       }
-      }
-    }
-    ND_PRINT((ndo, "]\n\t"));
-    len += 2 + ie_len;
-    p += ie_len;
-    caplen -= 2 + ie_len;
-    if (group_id == 0xf) {
-      break;
-    }
-  } while (caplen > 0);
-  return len;
+                       ND_PRINT("\n\t%s [ length = %d, ",
+                                p_ie_names[group_id], ie_len);
+               }
+               if (caplen < 2U + ie_len) {
+                       ND_PRINT("[ERROR: Truncated IE data]");
+                       return -1;
+               }
+               if (ndo->ndo_vflag > 3 && ie_len != 0) {
+                       switch (group_id) {
+                       case 0x1: /* MLME IE */
+                               ieee802_15_4_print_mlme_ie_list(ndo, p, ie_len);
+                               break;
+                       case 0x2: /* Vendor Specific Nested IE */
+                               if (ie_len < 3) {
+                                       ND_PRINT("[ERROR: Vendor OUI missing]");
+                               } else {
+                                       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 ",
+                                                        GET_U_1(p + i));
+                                       }
+                               }
+                               break;
+                       case 0x3: /* Multiplexed IE (802.15.9) */
+                               ieee802_15_4_print_mpx_ie(ndo, p, ie_len);
+                               break;
+                       case 0x5: /* IETF IE */
+                               if (ie_len < 1) {
+                                       ND_PRINT("[ERROR: Subtype ID missing]");
+                               } else {
+                                       ND_PRINT("Subtype ID = 0x%02x, Subtype content = ",
+                                                GET_U_1(p));
+                                       for(i = 1; i < ie_len; 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 ", GET_U_1(p + i));
+                               }
+                               break;
+                       }
+               } else {
+                       if (ie_len != 0) {
+                               ND_PRINT("IE Data = ");
+                               for(i = 0; i < ie_len; i++) {
+                                       ND_PRINT("%02x ", GET_U_1(p + i));
+                               }
+                       }
+               }
+               ND_PRINT("]\n\t");
+               len += 2 + ie_len;
+               p += ie_len;
+               caplen -= 2 + ie_len;
+               if (group_id == 0xf) {
+                       break;
+               }
+       } while (caplen > 0);
+       return len;
 }
 
 /*
@@ -1412,86 +1514,86 @@ ieee802_15_4_print_payload_ie_list(netdissect_options *ndo,
 static int
 ieee802_15_4_print_aux_sec_header(netdissect_options *ndo,
                                  const u_char *p,
-                                 uint16_t caplen,
+                                 u_int caplen,
                                  int *security_level)
 {
-  int sc, key_id_mode, len;
-
-  if (caplen < 1) {
-    ND_PRINT((ndo, "[ERROR: Truncated before Aux Security Header]"));
-    return -1;
-  }
-  sc = EXTRACT_LE_8BITS(p);
-  len = 1;
-  *security_level = sc & 0x7;
-  key_id_mode = (sc >> 3) & 0x3;
-
-  caplen -= 1;
-  p += 1;
-
-  if (ndo->ndo_vflag > 0) {
-    ND_PRINT((ndo, "\n\tSecurity Level %d, Key Id Mode %d, ",
-             *security_level, key_id_mode));
-  }
-  if ((CHECK_BIT(sc, 5)) == 0) {
-    if (caplen < 4) {
-      ND_PRINT((ndo, "[ERROR: Truncated before Frame Counter]"));
-      return -1;
-    }
-    len += 4;
-    caplen -= 4;
-    p += 4;
-    if (ndo->ndo_vflag > 1) {
-      ND_PRINT((ndo, "Frame Counter 0x%08x ",
-               EXTRACT_LE_32BITS(p + 1)));
-    }
-  }
-  switch (key_id_mode) {
-  case 0x00: /* Implicit. */
-    if (ndo->ndo_vflag > 1) {
-      ND_PRINT((ndo, "Implicit"));
-    }
-    return len;
-    break;
-  case 0x01: /* Key Index, nothing to print here. */
-    break;
-  case 0x02: /* PAN and Short address Key Source, and Key Index. */
-    if (caplen < 4) {
-      ND_PRINT((ndo, "[ERROR: Truncated before Key Source]"));
-      return -1;
-    }
-    if (ndo->ndo_vflag > 1) {
-      ND_PRINT((ndo, "KeySource 0x%04x:%0x4x, ",
-               EXTRACT_LE_16BITS(p), EXTRACT_LE_16BITS(p + 2)));
-    }
-    p += 4;
-    caplen -= 4;
-    len += 4;
-    break;
-  case 0x03: /* Extended address and Key Index. */
-    if (caplen < 8) {
-      ND_PRINT((ndo, "[ERROR: Truncated before Key Source]"));
-      return -1;
-    }
-    if (ndo->ndo_vflag > 1) {
-      ND_PRINT((ndo, "KeySource %s, ", le64addr_string(ndo, p)));
-    }
-    p += 4;
-    caplen -= 4;
-    len += 4;
-    break;
-  }
-  if (caplen < 1) {
-    ND_PRINT((ndo, "[ERROR: Truncated before Key Index]"));
-    return -1;
-  }
-  if (ndo->ndo_vflag > 1) {
-    ND_PRINT((ndo, "KeyIndex 0x%02x, ", EXTRACT_LE_8BITS(p)));
-  }
-  caplen -= 1;
-  p += 1;
-  len += 1;
-  return len;
+       int sc, key_id_mode, len;
+
+       if (caplen < 1) {
+               ND_PRINT("[ERROR: Truncated before Aux Security Header]");
+               return -1;
+       }
+       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);
+       }
+       if ((CHECK_BIT(sc, 5)) == 0) {
+               if (caplen < 4) {
+                       ND_PRINT("[ERROR: Truncated before Frame Counter]");
+                       return -1;
+               }
+               if (ndo->ndo_vflag > 1) {
+                       ND_PRINT("Frame Counter 0x%08x ",
+                                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("Implicit");
+               }
+               return len;
+               break;
+       case 0x01: /* Key Index, nothing to print here. */
+               break;
+       case 0x02: /* PAN and Short address Key Source, and Key Index. */
+               if (caplen < 4) {
+                       ND_PRINT("[ERROR: Truncated before Key Source]");
+                       return -1;
+               }
+               if (ndo->ndo_vflag > 1) {
+                       ND_PRINT("KeySource 0x%04x:%0x4x, ",
+                                GET_LE_U_2(p), GET_LE_U_2(p + 2));
+               }
+               p += 4;
+               caplen -= 4;
+               len += 4;
+               break;
+       case 0x03: /* Extended address and Key Index. */
+               if (caplen < 8) {
+                       ND_PRINT("[ERROR: Truncated before Key Source]");
+                       return -1;
+               }
+               if (ndo->ndo_vflag > 1) {
+                       ND_PRINT("KeySource %s, ", GET_LE64ADDR_STRING(p));
+               }
+               p += 4;
+               caplen -= 4;
+               len += 4;
+               break;
+       }
+       if (caplen < 1) {
+               ND_PRINT("[ERROR: Truncated before Key Index]");
+               return -1;
+       }
+       if (ndo->ndo_vflag > 1) {
+               ND_PRINT("KeyIndex 0x%02x, ", GET_U_1(p));
+       }
+       caplen -= 1;
+       p += 1;
+       len += 1;
+       return len;
 }
 
 /*
@@ -1505,177 +1607,186 @@ ieee802_15_4_print_command_data(netdissect_options *ndo,
                                const u_char *p,
                                u_int caplen)
 {
-  u_int i;
-
-  switch (command_id) {
-  case 0x01: /* Assocation Request */
-    if (caplen != 1) {
-      ND_PRINT((ndo, "Invalid Assocation request command length"));
-      return -1;
-    } else {
-      uint8_t cap_info;
-      cap_info = EXTRACT_LE_8BITS(p);
-      ND_PRINT((ndo, "%s%s%s%s%s%s",
-               ((cap_info & 0x02) ? "FFD, " : "RFD, "),
-               ((cap_info & 0x04) ? "AC powered, " : ""),
-               ((cap_info & 0x08) ? "Receiver on when idle, " : ""),
-               ((cap_info & 0x10) ? "Fast association, " : ""),
-               ((cap_info & 0x40) ? "Security supported, " : ""),
-               ((cap_info & 0x80) ? "Allocate address, " : "")));
-      return caplen;
-    }
-    break;
-  case 0x02: /* Assocation Response */
-    if (caplen != 3) {
-      ND_PRINT((ndo, "Invalid Assocation response command length"));
-      return -1;
-    } else {
-      ND_PRINT((ndo, "Short address = "));
-      ieee802_15_4_print_addr(ndo, p, 2);
-      switch (EXTRACT_LE_8BITS(p + 2)) {
-      case 0x00:
-       ND_PRINT((ndo, ", Association successful"));
-       break;
-      case 0x01:
-       ND_PRINT((ndo, ", PAN at capacity"));
-       break;
-      case 0x02:
-       ND_PRINT((ndo, ", PAN access denied"));
-       break;
-      case 0x03:
-       ND_PRINT((ndo, ", Hooping sequence offset duplication"));
-       break;
-      case 0x80:
-       ND_PRINT((ndo, ", Fast association successful"));
-       break;
-      default:
-       ND_PRINT((ndo, ", Status = 0x%02x", EXTRACT_LE_8BITS(p + 2)));
-       break;
-      }
-      return caplen;
-    }
-    break;
-  case 0x03: /* Diassociation Notification command */
-    if (caplen != 1) {
-      ND_PRINT((ndo, "Invalid Disassociation Notification command length"));
-      return -1;
-    } else {
-      switch (EXTRACT_LE_8BITS(p)) {
-      case 0x00:
-       ND_PRINT((ndo, "Reserved"));
-       break;
-      case 0x01:
-       ND_PRINT((ndo, "Reason = The coordinator wishes the device to leave PAN"));
-       break;
-      case 0x02:
-       ND_PRINT((ndo, "Reason = The device wishes to leave the PAN"));
-       break;
-      default:
-       ND_PRINT((ndo, "Reason = 0x%02x", EXTRACT_LE_8BITS(p + 2)));
-       break;
-      }
-      return caplen;
-    }
-       
-    /* Following ones do not have any data. */
-  case 0x04: /* Data Request command */
-  case 0x05: /* PAN ID Conflict Notification command */
-  case 0x06: /* Orphan Notification command */
-  case 0x07: /* Beacon Request command */
-    /* Should not have any data. */
-    return 0;
-  case 0x08: /* Coordinator Realignment command */
-    if (caplen < 7 || caplen > 8) {
-      ND_PRINT((ndo, "Invalid Coordinator Realignment command length"));
-      return -1;
-    } else {
-      uint16_t channel, page;
-
-      ND_PRINT((ndo, "Pan ID = 0x%04x, Coordinator short address = ",
-               EXTRACT_LE_16BITS(p)));
-      ieee802_15_4_print_addr(ndo, p + 2, 2);
-      channel = EXTRACT_LE_8BITS(p + 4);
-
-      if (caplen == 8) {
-       page = EXTRACT_LE_8BITS(p + 7);
-      } else {
-       page = 0x80;
-      }
-      if (CHECK_BIT(page, 7)) {
-       /* No page present, instead we have msb of
-          channel in the page. */
-       channel |= (page & 0x7f) << 8;
-       ND_PRINT((ndo, ", Channel Number = %d", channel));
-      } else {
-       ND_PRINT((ndo, ", Channel Number = %d, page = %d",
-                 channel, page));
-      }
-      ND_PRINT((ndo, ", Short address = "));
-      ieee802_15_4_print_addr(ndo, p + 5, 2);
-      return caplen;
-    }
-    break;
-  case 0x09: /* GTS Request command */
-    if (caplen != 1) {
-      ND_PRINT((ndo, "Invalid GTS Request command length"));
-      return -1;
-    } else {
-      uint8_t gts;
-
-      gts = EXTRACT_LE_8BITS(p);
-      ND_PRINT((ndo, "GTS Length = %d, %s, %s",
-               gts & 0xf,
-               (CHECK_BIT(gts, 4) ? "Receive-only GTS" : "Transmit-only GTS"),
-               (CHECK_BIT(gts, 5) ? "GTS allocation" : "GTS deallocations")));
-      return caplen;
-    }
-    break;
-  case 0x13: /* DSME Association Request command */
-    /* XXX Not implemented */
-  case 0x14: /* DSME Association Response command */
-    /* XXX Not implemented */
-  case 0x15: /* DSME GTS Request command */
-    /* XXX Not implemented */
-  case 0x16: /* DSME GTS Response command */
-    /* XXX Not implemented */
-  case 0x17: /* DSME GTS GTS Notify command */
-    /* XXX Not implemented */
-  case 0x18: /* DSME Information Request command */
-    /* XXX Not implemented */
-  case 0x19: /* DSME Information Response command */
-    /* XXX Not implemented */
-  case 0x1a: /* DSME Beacon Allocation Notification command */
-    /* XXX Not implemented */
-  case 0x1b: /* DSME Beacon Collision Notification command */
-    /* XXX Not implemented */
-  case 0x1c: /* DSME Link Report command */
-    /* XXX Not implemented */
-  case 0x20: /* RIT Data Request command */
-    /* XXX Not implemented */
-  case 0x21: /* DBS Request command */
-    /* XXX Not implemented */
-  case 0x22: /* DBS Response command */
-    /* XXX Not implemented */
-  case 0x23: /* RIT Data Response command */
-    /* XXX Not implemented */
-  case 0x24: /* Vendor Specific command */
-    /* XXX Not implemented */
-  case 0x0a: /* TRLE Management Request command */
-    /* XXX Not implemented */
-  case 0x0b: /* TRLE Management Response command */
-    /* XXX Not implemented */
-  default:
-    ND_PRINT((ndo, "Command Data = "));
-    for(i = 0; i < caplen; i++) {
-      ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
-    }
-    break;
-  }
-  return 0;
+       u_int i;
+
+       switch (command_id) {
+       case 0x01: /* Association Request */
+               if (caplen != 1) {
+                       ND_PRINT("Invalid Association request command length");
+                       return -1;
+               } else {
+                       uint8_t cap_info;
+                       cap_info = GET_U_1(p);
+                       ND_PRINT("%s%s%s%s%s%s",
+                                ((cap_info & 0x02) ?
+                                 "FFD, " : "RFD, "),
+                                ((cap_info & 0x04) ?
+                                 "AC powered, " : ""),
+                                ((cap_info & 0x08) ?
+                                 "Receiver on when idle, " : ""),
+                                ((cap_info & 0x10) ?
+                                 "Fast association, " : ""),
+                                ((cap_info & 0x40) ?
+                                 "Security supported, " : ""),
+                                ((cap_info & 0x80) ?
+                                 "Allocate address, " : ""));
+                       return caplen;
+               }
+               break;
+       case 0x02: /* Association Response */
+               if (caplen != 3) {
+                       ND_PRINT("Invalid Association response command length");
+                       return -1;
+               } else {
+                       ND_PRINT("Short address = ");
+                       ieee802_15_4_print_addr(ndo, p, 2);
+                       switch (GET_U_1(p + 2)) {
+                       case 0x00:
+                               ND_PRINT(", Association successful");
+                               break;
+                       case 0x01:
+                               ND_PRINT(", PAN at capacity");
+                               break;
+                       case 0x02:
+                               ND_PRINT(", PAN access denied");
+                               break;
+                       case 0x03:
+                               ND_PRINT(", Hooping sequence offset duplication");
+                               break;
+                       case 0x80:
+                               ND_PRINT(", Fast association successful");
+                               break;
+                       default:
+                               ND_PRINT(", Status = 0x%02x",
+                                        GET_U_1(p + 2));
+                               break;
+                       }
+                       return caplen;
+               }
+               break;
+       case 0x03: /* Diassociation Notification command */
+               if (caplen != 1) {
+                       ND_PRINT("Invalid Disassociation Notification command length");
+                       return -1;
+               } else {
+                       switch (GET_U_1(p)) {
+                       case 0x00:
+                               ND_PRINT("Reserved");
+                               break;
+                       case 0x01:
+                               ND_PRINT("Reason = The coordinator wishes the device to leave PAN");
+                               break;
+                       case 0x02:
+                               ND_PRINT("Reason = The device wishes to leave the PAN");
+                               break;
+                       default:
+                               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 */
+       case 0x06: /* Orphan Notification command */
+       case 0x07: /* Beacon Request command */
+               /* Should not have any data. */
+               return 0;
+       case 0x08: /* Coordinator Realignment command */
+               if (caplen < 7 || caplen > 8) {
+                       ND_PRINT("Invalid Coordinator Realignment command length");
+                       return -1;
+               } else {
+                       uint16_t channel, page;
+
+                       ND_PRINT("Pan ID = 0x%04x, Coordinator short address = ",
+                                GET_LE_U_2(p));
+                       ieee802_15_4_print_addr(ndo, p + 2, 2);
+                       channel = GET_U_1(p + 4);
+
+                       if (caplen == 8) {
+                               page = GET_U_1(p + 7);
+                       } else {
+                               page = 0x80;
+                       }
+                       if (CHECK_BIT(page, 7)) {
+                               /* No page present, instead we have msb of
+                                  channel in the page. */
+                               channel |= (page & 0x7f) << 8;
+                               ND_PRINT(", Channel Number = %d", channel);
+                       } else {
+                               ND_PRINT(", Channel Number = %d, page = %d",
+                                        channel, page);
+                       }
+                       ND_PRINT(", Short address = ");
+                       ieee802_15_4_print_addr(ndo, p + 5, 2);
+                       return caplen;
+               }
+               break;
+       case 0x09: /* GTS Request command */
+               if (caplen != 1) {
+                       ND_PRINT("Invalid GTS Request command length");
+                       return -1;
+               } else {
+                       uint8_t gts;
+
+                       gts = GET_U_1(p);
+                       ND_PRINT("GTS Length = %d, %s, %s",
+                                gts & 0xf,
+                                (CHECK_BIT(gts, 4) ?
+                                 "Receive-only GTS" : "Transmit-only GTS"),
+                                (CHECK_BIT(gts, 5) ?
+                                 "GTS allocation" : "GTS deallocations"));
+                       return caplen;
+               }
+               break;
+       case 0x13: /* DSME Association Request command */
+               /* XXX Not implemented */
+       case 0x14: /* DSME Association Response command */
+               /* XXX Not implemented */
+       case 0x15: /* DSME GTS Request command */
+               /* XXX Not implemented */
+       case 0x16: /* DSME GTS Response command */
+               /* XXX Not implemented */
+       case 0x17: /* DSME GTS Notify command */
+               /* XXX Not implemented */
+       case 0x18: /* DSME Information Request command */
+               /* XXX Not implemented */
+       case 0x19: /* DSME Information Response command */
+               /* XXX Not implemented */
+       case 0x1a: /* DSME Beacon Allocation Notification command */
+               /* XXX Not implemented */
+       case 0x1b: /* DSME Beacon Collision Notification command */
+               /* XXX Not implemented */
+       case 0x1c: /* DSME Link Report command */
+               /* XXX Not implemented */
+       case 0x20: /* RIT Data Request command */
+               /* XXX Not implemented */
+       case 0x21: /* DBS Request command */
+               /* XXX Not implemented */
+       case 0x22: /* DBS Response command */
+               /* XXX Not implemented */
+       case 0x23: /* RIT Data Response command */
+               /* XXX Not implemented */
+       case 0x24: /* Vendor Specific command */
+               /* XXX Not implemented */
+       case 0x0a: /* TRLE Management Request command */
+               /* XXX Not implemented */
+       case 0x0b: /* TRLE Management Response command */
+               /* XXX Not implemented */
+       default:
+               ND_PRINT("Command Data = ");
+               for(i = 0; i < caplen; i++) {
+                       ND_PRINT("%02x ", GET_U_1(p + i));
+               }
+               break;
+       }
+       return 0;
 }
 
 /*
- * Parse and print frames folloing standard format.
+ * Parse and print frames following standard format.
  *
  * Returns FALSE in case of error.
  */
@@ -1684,596 +1795,650 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                        const u_char *p, u_int caplen,
                        uint16_t fc)
 {
-  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 payload_ie_present;
-  uint8_t seq, fcs_len;
-  uint32_t fcs, crc_check;
-  const u_char *mic_start = NULL;
-
-  payload_ie_present = 0;
-
-  /* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not
-     know about that. */
-  if (caplen < 2) {
-    /* Cannot have FCS, assume fcs_len of 0. */
-    fcs_len = 0;
-    fcs = 0;
-  } else {
-    fcs_len = 2;
-
-    fcs = EXTRACT_LE_16BITS(p + caplen - 2);
-    crc_check = ieee802_15_4_crc16(p, caplen - 2);
-    if (crc_check != fcs) {
-      /* Wrong fcs, might not contain fcs, do not remove it. */
-    } else {
-      /* Remove FCS */
-      caplen -= fcs_len;
-    }
-  }
-
-  /* Frame version. */
-  frame_version = (fc >> 12) & 0x03;
-  frame_type = fc & 0x7;
-  ND_PRINT((ndo, "v%d ", frame_version));
-
-  if (ndo->ndo_vflag > 2) {
-    if (CHECK_BIT(fc, 3)) { ND_PRINT((ndo, "Security Enabled, ")); }
-    if (CHECK_BIT(fc, 4)) { ND_PRINT((ndo, "Frame Pending, ")); }
-    if (CHECK_BIT(fc, 5)) { ND_PRINT((ndo, "AR, ")); }
-    if (CHECK_BIT(fc, 6)) { ND_PRINT((ndo, "PAN ID Compression, ")); }
-    if (CHECK_BIT(fc, 8)) { ND_PRINT((ndo, "Sequence Number Suppression, ")); }
-    if (CHECK_BIT(fc, 9)) { ND_PRINT((ndo, "IE present, ")); }
-  }
-
-  /* Check for the sequence number supression. */
-  if (CHECK_BIT(fc, 8)) {
-    /* Sequence number is suppressed. */
-    if (frame_version < 2) {
-      /* Sequence number can only be supressed for frame
-        version 2 or higher, this is invalid frame. */
-      ND_PRINT((ndo, "[ERROR: Sequence number suppressed on frames where version < 2]"));
-    }
-    if (ndo->ndo_vflag)
-      ND_PRINT((ndo,"seq suppressed "));
-    p += 2;
-    caplen -= 2;
-  } else {
-    seq = EXTRACT_LE_8BITS(p + 2);
-    p += 3;
-    caplen -= 3;
-    if (ndo->ndo_vflag)
-      ND_PRINT((ndo,"seq %02x ", seq));
-  }
-
-  /* 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);
-  if (src_addr_len < 0) {
-    ND_PRINT((ndo,"[ERROR: Invalid src address mode]"));
-    return 0;
-  }
-  if (dst_addr_len < 0) {
-    ND_PRINT((ndo,"[ERROR: Invalid dst address mode]"));
-    return 0;
-  }
-  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) {
-      src_pan = 0;
-      dst_pan = 1;
-      if (dst_addr_len <= 0 || src_addr_len <= 0) {
-       /* Invalid frame, PAN ID Compression must be 0
-          if only one address in the frame. */
-       ND_PRINT((ndo,"[ERROR: PAN ID Compression != 0, and only one address with frame version < 2]"));
-      }
-    } else {
-      src_pan = 1;
-      dst_pan = 1;
-    }
-    if (dst_addr_len <= 0) {
-      dst_pan = 0;
-    }
-    if (src_addr_len <= 0) {
-      src_pan = 0;
-    }
-  } else {
-    /* Frame version 2 rules are more complicated, and they depend
-       on the address modes of the frame, generic rules are same,
-       but then there are some special cases. */
-    if (pan_id_comp) {
-      src_pan = 0;
-      dst_pan = 1;
-    } else {
-      src_pan = 1;
-      dst_pan = 1;
-    }
-    if (dst_addr_len <= 0) {
-      dst_pan = 0;
-    }
-    if (src_addr_len <= 0) {
-      src_pan = 0;
-    }
-    if (pan_id_comp) {
-      if (src_addr_len == 0 &&
-         dst_addr_len == 0) {
-       /* Both addresses are missing, but PAN ID
-          compression set, special case we have
-          destination PAN but no addresses. */
-       dst_pan = 1;
-      } else if ((src_addr_len == 0 &&
-                 dst_addr_len > 0) ||
-                (src_addr_len > 0 &&
-                 dst_addr_len == 0)) {
-       /* Only one address present, and PAN ID
-          compression is set, we do not have PAN id at
-          all. */
-       dst_pan = 0;
+       int len, frame_version, pan_id_comp;
+       int frame_type;
+       int src_pan, dst_pan, src_addr_len, dst_addr_len;
+       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;
+       /* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not
+          know about that. */
+       if (caplen < 4) {
+               /* Cannot have FCS, assume no FCS. */
+               fcs = 0;
+       } else {
+               /* Test for 4 octet FCS. */
+               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 = 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 {
+                               /* Wrong FCS, FCS might not be included in the
+                                  captured frame, do not remove it. */
+                       }
+               }
+       }
+
+       /* 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, 5)) { ND_PRINT("AR, "); }
+               if (CHECK_BIT(fc, 6)) { ND_PRINT("PAN ID Compression, "); }
+               if (CHECK_BIT(fc, 8)) { ND_PRINT("Sequence Number Suppression, "); }
+               if (CHECK_BIT(fc, 9)) { ND_PRINT("IE present, "); }
+       }
+
+       /* Check for the sequence number suppression. */
+       if (CHECK_BIT(fc, 8)) {
+               /* Sequence number is suppressed. */
+               if (frame_version < 2) {
+                       /* 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 = 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);
+       if (src_addr_len < 0) {
+               ND_PRINT("[ERROR: Invalid src address mode]");
+               return 0;
+       }
+       if (dst_addr_len < 0) {
+               ND_PRINT("[ERROR: Invalid dst address mode]");
+               return 0;
+       }
        src_pan = 0;
-      } else if (src_addr_len == 8 &&
-                dst_addr_len == 8) {
-       /* Both addresses are Extended, and PAN ID
-          compression set, we do not have PAN ID at
-          all. */
        dst_pan = 0;
-       src_pan = 0;
-      }
-    } else {
-      /* Special cases where PAN ID Compression is not set. */
-      if (src_addr_len == 8 &&
-         dst_addr_len == 8) {
-       /* Both addresses are Extended, and PAN ID
-          compression not set, we do have only one PAN
-          ID (destination). */
-       dst_pan = 1;
-       src_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) {
+                       src_pan = 0;
+                       dst_pan = 1;
+                       if (dst_addr_len <= 0 || src_addr_len <= 0) {
+                               /* Invalid frame, PAN ID Compression must be 0
+                                  if only one address in the frame. */
+                               ND_PRINT("[ERROR: PAN ID Compression != 0, and only one address with frame version < 2]");
+                       }
+               } else {
+                       src_pan = 1;
+                       dst_pan = 1;
+               }
+               if (dst_addr_len <= 0) {
+                       dst_pan = 0;
+               }
+               if (src_addr_len <= 0) {
+                       src_pan = 0;
+               }
+       } else {
+               /* Frame version 2 rules are more complicated, and they depend
+                  on the address modes of the frame, generic rules are same,
+                  but then there are some special cases. */
+               if (pan_id_comp) {
+                       src_pan = 0;
+                       dst_pan = 1;
+               } else {
+                       src_pan = 1;
+                       dst_pan = 1;
+               }
+               if (dst_addr_len <= 0) {
+                       dst_pan = 0;
+               }
+               if (src_addr_len <= 0) {
+                       src_pan = 0;
+               }
+               if (pan_id_comp) {
+                       if (src_addr_len == 0 &&
+                           dst_addr_len == 0) {
+                               /* Both addresses are missing, but PAN ID
+                                  compression set, special case we have
+                                  destination PAN but no addresses. */
+                               dst_pan = 1;
+                       } else if ((src_addr_len == 0 &&
+                                   dst_addr_len > 0) ||
+                                  (src_addr_len > 0 &&
+                                   dst_addr_len == 0)) {
+                               /* Only one address present, and PAN ID
+                                  compression is set, we do not have PAN id at
+                                  all. */
+                               dst_pan = 0;
+                               src_pan = 0;
+                       } else if (src_addr_len == 8 &&
+                                  dst_addr_len == 8) {
+                               /* Both addresses are Extended, and PAN ID
+                                  compression set, we do not have PAN ID at
+                                  all. */
+                               dst_pan = 0;
+                               src_pan = 0;
+                       }
+               } else {
+                       /* Special cases where PAN ID Compression is not set. */
+                       if (src_addr_len == 8 &&
+                           dst_addr_len == 8) {
+                               /* Both addresses are Extended, and PAN ID
+                                  compression not set, we do have only one PAN
+                                  ID (destination). */
+                               dst_pan = 1;
+                               src_pan = 0;
+                       }
 #ifdef BROKEN_6TISCH_PAN_ID_COMPRESSION
-      if (src_addr_len == 8 &&
-         dst_addr_len == 2) {
-       /* Special case for the broken 6tisch
-          implementations. */
-       src_pan = 0;
-      }
+                       if (src_addr_len == 8 &&
+                           dst_addr_len == 2) {
+                               /* Special case for the broken 6tisch
+                                  implementations. */
+                               src_pan = 0;
+                       }
 #endif /* BROKEN_6TISCH_PAN_ID_COMPRESSION */
-    }
-  }
-
-  /* Print dst PAN and address. */
-  if (dst_pan) {
-    if (caplen < 2) {
-      ND_PRINT((ndo, "[ERROR: Truncated before dst_pan]"));
-      return 0;
-    }
-    ND_PRINT((ndo, "%04x:", EXTRACT_LE_16BITS(p)));
-    p += 2;
-    caplen -= 2;
-  } else {
-    ND_PRINT((ndo, "-:"));
-  }
-  if (caplen < (u_int) dst_addr_len) {
-    ND_PRINT((ndo, "[ERROR: Truncated before dst_addr]"));
-    return 0;
-  }
-  ieee802_15_4_print_addr(ndo, p, dst_addr_len);
-  p += dst_addr_len;
-  caplen -= dst_addr_len;
-
-  ND_PRINT((ndo," < "));
-
-  /* Print src PAN and address. */
-  if (src_pan) {
-    if (caplen < 2) {
-      ND_PRINT((ndo, "[ERROR: Truncated before dst_pan]"));
-      return 0;
-    }
-    ND_PRINT((ndo, "%04x:", EXTRACT_LE_16BITS(p)));
-    p += 2;
-    caplen -= 2;
-  } else {
-    ND_PRINT((ndo, "-:"));
-  }
-  if (caplen < (u_int) src_addr_len) {
-    ND_PRINT((ndo, "[ERROR: Truncated before dst_addr]"));
-    return 0;
-  }
-  ieee802_15_4_print_addr(ndo, p, src_addr_len);
-  ND_PRINT((ndo, " "));
-  p += src_addr_len;
-  caplen -= src_addr_len;
-  if (CHECK_BIT(fc, 3)) {
-    len = ieee802_15_4_print_aux_sec_header(ndo, p, caplen, &security_level);
-    if (len < 0) {
-      return 0;
-    }
-    p += len;
-    caplen -= len;
-  } else {
-    security_level = 0;
-  }
-
-  switch (security_level) {
-  case 0: /*FALLTHOUGH */
-  case 4:
-    miclen = 0;
-    break;
-  case 1: /*FALLTHOUGH */
-  case 5:
-    miclen = 4;
-    break;
-  case 2: /*FALLTHOUGH */
-  case 6:
-    miclen = 8;
-    break;
-  case 3: /*FALLTHOUGH */
-  case 7:
-    miclen = 16;
-    break;
-  }
-
-  /* Remove MIC */
-  if (miclen > 0) {
-    if (caplen < (u_int) miclen) {
-      ND_PRINT((ndo, "[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. */
-    len = ieee802_15_4_print_header_ie_list(ndo, p, caplen,
-                                           &payload_ie_present);
-    if (len < 0) {
-      return 0;
-    }
-    p += len;
-    caplen -= len;
-  }
-
-  if (payload_ie_present) {
-    if (security_level >= 4) {
-      ND_PRINT((ndo, "Payload IEs present, but encrypted, cannot print "));
-    } else {
-      len = ieee802_15_4_print_payload_ie_list(ndo, p, caplen);
-      if (len < 0) {
-       return 0;
-      }
-      p += len;
-      caplen -= len;
-    }
-  }
-
-  /* Print MIC */
-  if (ndo->ndo_vflag > 2 && miclen != 0) {
-    ND_PRINT((ndo, "\n\tMIC "));
-       
-    for(len = 0; len < miclen; len += 4) {
-      ND_PRINT((ndo, "%08x", EXTRACT_32BITS(mic_start + len)));
-    }
-    ND_PRINT((ndo, " "));
-  }
-
-  /* Print FCS */
-  if (ndo->ndo_vflag > 2) {
-    if (crc_check == fcs) {
-      ND_PRINT((ndo, "FCS %04x ", fcs));
-    } else {
-      ND_PRINT((ndo, "wrong FCS %04x vs %04x (assume no FCS stored) ",
-               fcs, crc_check));
-    }
-  }
-
-  /* Payload print */
-  switch (frame_type) {
-  case 0x00: /* Beacon */
-    if (frame_version < 2) {
-      if (caplen < 2) {
-       ND_PRINT((ndo, "[ERROR: Truncated before beacon information]"));
-       break;
-      } else {
-       uint16_t ss;
-                       
-       ss = EXTRACT_LE_16BITS(p);
-       ieee802_15_4_print_superframe_specification(ndo, ss);
-       p += 2;
-       caplen -= 2;
-
-       /* GTS */
-       if (caplen < 1) {
-         ND_PRINT((ndo, "[ERROR: Truncated before GTS info]"));
-         break;
+               }
        }
-                               
-       len = ieee802_15_4_print_gts_info(ndo, p, caplen);
-       if (len < 0) {
-         break;
+
+       /* Print dst PAN and address. */
+       if (dst_pan) {
+               if (caplen < 2) {
+                       ND_PRINT("[ERROR: Truncated before dst_pan]");
+                       return 0;
+               }
+               ND_PRINT("%04x:", GET_LE_U_2(p));
+               p += 2;
+               caplen -= 2;
+       } else {
+               ND_PRINT("-:");
        }
+       if (caplen < (u_int) dst_addr_len) {
+               ND_PRINT("[ERROR: Truncated before dst_addr]");
+               return 0;
+       }
+       ieee802_15_4_print_addr(ndo, p, dst_addr_len);
+       p += dst_addr_len;
+       caplen -= dst_addr_len;
 
-       p += len;
-       caplen -= len;
-                       
-       /* Pending Addresses */
-       if (caplen < 1) {
-         ND_PRINT((ndo, "[ERROR: Truncated before pending addresses]"));
-         break;
+       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:", GET_LE_U_2(p));
+               p += 2;
+               caplen -= 2;
+       } else {
+               ND_PRINT("-:");
+       }
+       if (caplen < (u_int) src_addr_len) {
+               ND_PRINT("[ERROR: Truncated before dst_addr]");
+               return 0;
+       }
+       ieee802_15_4_print_addr(ndo, p, src_addr_len);
+       ND_PRINT(" ");
+       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 = 0;
+               break;
+       case 1: /*FALLTHOUGH */
+       case 5:
+               miclen = 4;
+               break;
+       case 2: /*FALLTHOUGH */
+       case 6:
+               miclen = 8;
+               break;
+       case 3: /*FALLTHOUGH */
+       case 7:
+               miclen = 16;
+               break;
+       }
+
+       /* Remove MIC */
+       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. */
+               len = ieee802_15_4_print_header_ie_list(ndo, p, caplen,
+                                                       &payload_ie_present);
+               if (len < 0) {
+                       return 0;
+               }
+               p += len;
+               caplen -= len;
+       }
+
+       if (payload_ie_present) {
+               if (security_level >= 4) {
+                       ND_PRINT("Payload IEs present, but encrypted, cannot print ");
+               } else {
+                       len = ieee802_15_4_print_payload_ie_list(ndo, p, caplen);
+                       if (len < 0) {
+                               return 0;
+                       }
+                       p += len;
+                       caplen -= len;
+               }
+       }
+
+       /* Print MIC */
+       if (ndo->ndo_vflag > 2 && miclen != 0) {
+               ND_PRINT("\n\tMIC ");
+
+               for (u_int micoffset = 0; micoffset < miclen; micoffset++) {
+                       ND_PRINT("%02x", GET_U_1(mic_start + micoffset));
+               }
+               ND_PRINT(" ");
        }
-       len = ieee802_15_4_print_pending_addresses(ndo, p, caplen);
-       if (len < 0) {
-         break;
+
+       /* Print FCS */
+       if (ndo->ndo_vflag > 2) {
+               if (crc_check == fcs) {
+                       ND_PRINT("FCS %x ", fcs);
+               } else {
+                       ND_PRINT("wrong FCS %x vs %x (assume no FCS stored) ",
+                                fcs, crc_check);
+               }
        }
-       p += len;
-       caplen -= len;
-      }
-    }
-    if (!ndo->ndo_suppress_default_print)
-      ND_DEFAULTPRINT(p, caplen);
-
-    break;
-  case 0x01: /* Data */
-  case 0x02: /* Acknowledgement */
-    if (!ndo->ndo_suppress_default_print)
-      ND_DEFAULTPRINT(p, caplen);
-    break;
-  case 0x03: /* MAC Command */
-    if (caplen < 1) {
-      ND_PRINT((ndo, "[ERROR: Truncated before Command ID]"));
-    } else {
-      uint8_t command_id;
-
-      command_id = EXTRACT_LE_8BITS(p);
-      if (command_id >= 0x30) {
-       ND_PRINT((ndo, "Command ID = Reserved 0x%02x ", command_id));
-      } else {
-       ND_PRINT((ndo, "Command ID = %s ", mac_c_names[command_id]));
-      }
-      p++;
-      caplen--;
-      if (caplen != 0) {
-       len = ieee802_15_4_print_command_data(ndo, command_id, p, caplen);
-       if (len >= 0) {
-         p += len;
-         caplen -= len;
+
+       /* Payload print */
+       switch (frame_type) {
+       case 0x00: /* Beacon */
+               if (frame_version < 2) {
+                       if (caplen < 2) {
+                               ND_PRINT("[ERROR: Truncated before beacon information]");
+                               break;
+                       } else {
+                               uint16_t ss;
+
+                               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]");
+                                       break;
+                               }
+                               len = ieee802_15_4_print_pending_addresses(ndo, p, caplen);
+                               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 */
+               if (!ndo->ndo_suppress_default_print)
+                       ND_DEFAULTPRINT(p, caplen);
+               break;
+       case 0x03: /* MAC Command */
+               if (caplen < 1) {
+                       ND_PRINT("[ERROR: Truncated before Command ID]");
+               } else {
+                       uint8_t command_id;
+
+                       command_id = GET_U_1(p);
+                       if (command_id >= 0x30) {
+                               ND_PRINT("Command ID = Reserved 0x%02x ",
+                                        command_id);
+                       } else {
+                               ND_PRINT("Command ID = %s ",
+                                        mac_c_names[command_id]);
+                       }
+                       p++;
+                       caplen--;
+                       if (caplen != 0) {
+                               len = ieee802_15_4_print_command_data(ndo, command_id, p, caplen);
+                               if (len >= 0) {
+                                       p += len;
+                                       caplen -= len;
+                               }
+                       }
+               }
+               if (!ndo->ndo_suppress_default_print)
+                       ND_DEFAULTPRINT(p, caplen);
+               break;
        }
-      }
-    }
-    if (!ndo->ndo_suppress_default_print)
-      ND_DEFAULTPRINT(p, caplen);
-    break;
-  }
-  return 1;
+       return 1;
 }
 
 /*
  * Print and parse Multipurpose frames.
  *
  * Returns FALSE in case of error.
-*/
+ */
 static u_int
 ieee802_15_4_mp_frame(netdissect_options *ndo,
                      const u_char *p, u_int caplen,
                      uint16_t fc)
 {
-  int len, frame_version, pan_id_present;
-  int src_addr_len, dst_addr_len;
-  int security_level, miclen = 0;
-  int ie_present, payload_ie_present, security_enabled;
-  uint8_t seq, fcs_len;
-  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;
-
-  /* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not
-     know about that. */
-  if (caplen < 2) {
-    /* Cannot have FCS, assume fcs_len of 0. */
-    fcs_len = 0;
-    fcs = 0;
-  } else {
-    fcs_len = 2;
-
-    fcs = EXTRACT_LE_16BITS(p + caplen - 2);
-    crc_check = ieee802_15_4_crc16(p, caplen - 2);
-    if (crc_check != fcs) {
-      /* Wrong fcs, might not contain fcs, do not remove it. */
-    } else {
-      /* Remove FCS */
-      caplen -= fcs_len;
-    }
-  }
-
-  if (CHECK_BIT(fc, 3)) {
-    /* Long Frame Control */
-
-    /* Frame version. */
-    frame_version = (fc >> 12) & 0x03;
-    ND_PRINT((ndo, "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((ndo, "Security Enabled, ")); }
-      if (CHECK_BIT(fc, 11)) { ND_PRINT((ndo, "Frame Pending, ")); }
-      if (CHECK_BIT(fc, 14)) { ND_PRINT((ndo, "AR, ")); }
-      if (pan_id_present) { ND_PRINT((ndo, "PAN ID Present, ")); }
-      if (CHECK_BIT(fc, 10)) {
-       ND_PRINT((ndo, "Sequence Number Suppression, "));
-      }
-      if (ie_present) { ND_PRINT((ndo, "IE present, ")); }
-    }
-
-    /* Check for the sequence number supression. */
-    if (CHECK_BIT(fc, 10)) {
-      /* Sequence number is suppressed, but long version. */
-      p += 2;
-      caplen -= 2;
-    } else {
-      seq = EXTRACT_LE_8BITS(p + 2);
-      p += 3;
-      caplen -= 3;
-      if (ndo->ndo_vflag)
-       ND_PRINT((ndo,"seq %02x ", seq));
-    }
-  } else {
-    /* Short format of header, but with seq no */
-    seq = EXTRACT_LE_8BITS(p + 1);
-    p += 2;
-    caplen -= 2;
-    if (ndo->ndo_vflag)
-      ND_PRINT((ndo,"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);
-  if (src_addr_len < 0) {
-    ND_PRINT((ndo,"[ERROR: Invalid src address mode]"));
-    return 0;
-  }
-  if (dst_addr_len < 0) {
-    ND_PRINT((ndo,"[ERROR: Invalid dst address mode]"));
-    return 0;
-  }
-
-  /* Print dst PAN and address. */
-  if (pan_id_present) {
-    if (caplen < 2) {
-      ND_PRINT((ndo, "[ERROR: Truncated before dst_pan]"));
-      return 0;
-    }
-    ND_PRINT((ndo, "%04x:", EXTRACT_LE_16BITS(p)));
-    p += 2;
-    caplen -= 2;
-  } else {
-    ND_PRINT((ndo, "-:"));
-  }
-  if (caplen < (u_int) dst_addr_len) {
-    ND_PRINT((ndo, "[ERROR: Truncated before dst_addr]"));
-    return 0;
-  }
-  ieee802_15_4_print_addr(ndo, p, dst_addr_len);
-  p += dst_addr_len;
-  caplen -= dst_addr_len;
-
-  ND_PRINT((ndo," < "));
-
-  /* Print src PAN and address. */
-  ND_PRINT((ndo, " -:"));
-  if (caplen < (u_int) src_addr_len) {
-    ND_PRINT((ndo, "[ERROR: Truncated before dst_addr]"));
-    return 0;
-  }
-  ieee802_15_4_print_addr(ndo, p, src_addr_len);
-  ND_PRINT((ndo, " "));
-  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;
-    }
-    p += len;
-    caplen -= len;
-  } else {
-    security_level = 0;
-  }
-
-  switch (security_level) {
-  case 0: /*FALLTHOUGH */
-  case 4:
-    miclen = 0;
-    break;
-  case 1: /*FALLTHOUGH */
-  case 5:
-    miclen = 4;
-    break;
-  case 2: /*FALLTHOUGH */
-  case 6:
-    miclen = 8;
-    break;
-  case 3: /*FALLTHOUGH */
-  case 7:
-    miclen = 16;
-    break;
-  }
-
-  /* Remove MIC */
-  if (miclen > 0) {
-    if (caplen < (u_int) miclen) {
-      ND_PRINT((ndo, "[ERROR: Truncated before MIC]"));
-      return 0;
-    }
-    caplen -= miclen;
-    mic_start = p + caplen;
-  }
-
-  /* Parse Information elements if present */
-  if (ie_present) {
-    /* Yes we have those. */
-    len = ieee802_15_4_print_header_ie_list(ndo, p, caplen,
-                                           &payload_ie_present);
-    if (len < 0) {
-      return 0;
-    }
-    p += len;
-    caplen -= len;
-  }
-
-  if (payload_ie_present) {
-    if (security_level >= 4) {
-      ND_PRINT((ndo, "Payload IEs present, but encrypted, cannot print "));
-    } else {
-      len = ieee802_15_4_print_payload_ie_list(ndo, p, caplen);
-      if (len < 0) {
-       return 0;
-      }
-      p += len;
-      caplen -= len;
-    }
-  }
-
-  /* Print MIC */
-  if (ndo->ndo_vflag > 2 && miclen != 0) {
-    ND_PRINT((ndo, "\n\tMIC "));
-       
-    for(len = 0; len < miclen; len += 4) {
-      ND_PRINT((ndo, "%08x", EXTRACT_32BITS(mic_start + len)));
-    }
-    ND_PRINT((ndo, " "));
-  }
-
-
-  /* Print FCS */
-  if (ndo->ndo_vflag > 2) {
-    if (crc_check == fcs) {
-      ND_PRINT((ndo, "FCS %04x ", fcs));
-    } else {
-      ND_PRINT((ndo, "wrong FCS %04x vs %04x (assume no FCS stored) ",
-               fcs, crc_check));
-    }
-  }
-
-  if (!ndo->ndo_suppress_default_print)
-    ND_DEFAULTPRINT(p, caplen);
-
-  return 1;
+       int len, frame_version, pan_id_present;
+       int src_addr_len, dst_addr_len;
+       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) {
+               /* Cannot have FCS, assume no FCS. */
+               fcs = 0;
+       } else {
+               if (caplen > 4) {
+                       /* Test for 4 octet FCS. */
+                       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 = 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 = 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 (CHECK_BIT(fc, 14)) { ND_PRINT("AR, "); }
+                       if (pan_id_present) { ND_PRINT("PAN ID Present, "); }
+                       if (CHECK_BIT(fc, 10)) {
+                               ND_PRINT("Sequence Number Suppression, ");
+                       }
+                       if (ie_present) { ND_PRINT("IE present, "); }
+               }
+
+               /* 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 = 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 = 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);
+       if (src_addr_len < 0) {
+               ND_PRINT("[ERROR: Invalid src address mode]");
+               return 0;
+       }
+       if (dst_addr_len < 0) {
+               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:", GET_LE_U_2(p));
+               p += 2;
+               caplen -= 2;
+       } else {
+               ND_PRINT("-:");
+       }
+       if (caplen < (u_int) dst_addr_len) {
+               ND_PRINT("[ERROR: Truncated before dst_addr]");
+               return 0;
+       }
+       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("[ERROR: Truncated before dst_addr]");
+               return 0;
+       }
+       ieee802_15_4_print_addr(ndo, p, 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 = 0;
+               break;
+       case 1: /*FALLTHOUGH */
+       case 5:
+               miclen = 4;
+               break;
+       case 2: /*FALLTHOUGH */
+       case 6:
+               miclen = 8;
+               break;
+       case 3: /*FALLTHOUGH */
+       case 7:
+               miclen = 16;
+               break;
+       }
+
+       /* Remove MIC */
+       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. */
+               len = ieee802_15_4_print_header_ie_list(ndo, p, caplen,
+                                                       &payload_ie_present);
+               if (len < 0) {
+                       return 0;
+               }
+               p += len;
+               caplen -= len;
+       }
+
+       if (payload_ie_present) {
+               if (security_level >= 4) {
+                       ND_PRINT("Payload IEs present, but encrypted, cannot print ");
+               } else {
+                       len = ieee802_15_4_print_payload_ie_list(ndo, p,
+                                                                caplen);
+                       if (len < 0) {
+                               return 0;
+                       }
+                       p += len;
+                       caplen -= len;
+               }
+       }
+
+       /* Print MIC */
+       if (ndo->ndo_vflag > 2 && miclen != 0) {
+               ND_PRINT("\n\tMIC ");
+
+               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) {
+                       ND_PRINT("FCS %x ", fcs);
+               } else {
+                       ND_PRINT("wrong FCS %x vs %x (assume no FCS stored) ",
+                                fcs, crc_check);
+               }
+       }
+
+       if (!ndo->ndo_suppress_default_print)
+               ND_DEFAULTPRINT(p, caplen);
+
+       return 1;
 }
 
 /*
@@ -2282,20 +2447,20 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
  * Returns FALSE in case of error.
  */
 static u_int
-ieee802_15_4_frag_frame(netdissect_options *ndo __attribute__ ((unused)),
-                       const u_char *p __attribute__ ((unused)),
-                       u_int caplen __attribute__ ((unused)),
-                       uint16_t fc __attribute__ ((unused)))
+ieee802_15_4_frag_frame(netdissect_options *ndo _U_,
+                       const u_char *p _U_,
+                       u_int caplen _U_,
+                       uint16_t fc _U_)
 {
-  /* Not implement yet, might be bit hard to implement, as the
-   * information to set up the fragment is coming in the previous frame
-   * in the Fragment Sequence Context Description IE, thus we need to
-   * store information from there, so we can use it here. */
-  return 0;
+       /* Not implement yet, might be bit hard to implement, as the
+        * information to set up the fragment is coming in the previous frame
+        * in the Fragment Sequence Context Description IE, thus we need to
+        * store information from there, so we can use it here. */
+       return 0;
 }
 
 /*
- * 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.
  */
@@ -2303,56 +2468,89 @@ u_int
 ieee802_15_4_print(netdissect_options *ndo,
                   const u_char *p, u_int caplen)
 {
-  int frame_type;
-  uint16_t fc;
-
-  if (caplen < 3) {
-    ND_PRINT((ndo, "[|802.15.4] %x", caplen));
-    return 0;
-  }
-
-  fc = EXTRACT_LE_16BITS(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 & 0x7;
-  ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[frame_type]));
-
-  switch (frame_type) {
-  case 0x00: /* Beacon */
-  case 0x01: /* Data */
-  case 0x02: /* Acknowledgement */
-  case 0x03: /* MAC Command */
-    return ieee802_15_4_std_frames(ndo, p, caplen, fc);
-    break;
-  case 0x04: /* Reserved */
-    return 0;
-    break;
-  case 0x05: /* Multipurpose */
-    return ieee802_15_4_mp_frame(ndo, p, caplen, fc);
-    break;
-  case 0x06: /* Fragment or Frak */
-    return ieee802_15_4_frag_frame(ndo, p, caplen, fc);
-    break;
-  case 0x07: /* Extended */
-    return 0;
-    break;
-  }
-  return 0;
+       int frame_type;
+       uint16_t fc;
+
+       ndo->ndo_protocol = "802.15.4";
+
+       if (caplen < 2) {
+               nd_print_trunc(ndo);
+               return caplen;
+       }
+
+       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 */
+       case 0x02: /* Acknowledgement */
+       case 0x03: /* MAC Command */
+               return ieee802_15_4_std_frames(ndo, p, caplen, fc);
+               break;
+       case 0x04: /* Reserved */
+               return 0;
+               break;
+       case 0x05: /* Multipurpose */
+               return ieee802_15_4_mp_frame(ndo, p, caplen, fc);
+               break;
+       case 0x06: /* Fragment or Frak */
+               return ieee802_15_4_frag_frame(ndo, p, caplen, fc);
+               break;
+       case 0x07: /* Extended */
+               return 0;
+               break;
+       }
+       return 0;
 }
 
 /*
  * 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;
-  return ieee802_15_4_print(ndo, p, caplen);
+       u_int caplen = h->caplen;
+       ndo->ndo_protocol = "802.15.4";
+       ndo->ndo_ll_hdr_len += ieee802_15_4_print(ndo, p, caplen);
 }
 
+/* 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;
+}