]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-802_11.c
CI: Add warning exemptions for Sun C (suncc-5.15) on Solaris 10
[tcpdump] / print-802_11.c
index a34fc0719873ae8250ed7acb682ca27b6c386418..6f3bbee8cd5f8a696c8b7dbb055e8ff77609f5b9 100644 (file)
@@ -22,9 +22,7 @@
 
 /* \summary: IEEE 802.11 printer */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
 
 #include "netdissect-stdinc.h"
 
@@ -67,7 +65,7 @@
 #define        IEEE802_11_STATUS_LEN           2
 #define        IEEE802_11_REASON_LEN           2
 
-/* Length of previous AP in reassocation frame */
+/* Length of previous AP in reassociation frame */
 #define        IEEE802_11_AP_LEN               6
 
 #define        T_MGMT 0x0  /* management */
@@ -176,9 +174,9 @@ static const struct tok ctrl_str[] = {
 struct mgmt_header_t {
        nd_uint16_t     fc;
        nd_uint16_t     duration;
-       nd_mac_addr     da;
-       nd_mac_addr     sa;
-       nd_mac_addr     bssid;
+       nd_mac48        da;
+       nd_mac48        sa;
+       nd_mac48        bssid;
        nd_uint16_t     seq_ctrl;
 };
 
@@ -193,26 +191,22 @@ struct mgmt_header_t {
 #define        CAPABILITY_PRIVACY(cap) ((cap) & 0x0010)
 
 struct ssid_t {
-       uint8_t         element_id;
-       uint8_t         length;
+       u_int           length;
        u_char          ssid[33];  /* 32 + 1 for null */
 };
 
 struct rates_t {
-       uint8_t         element_id;
-       uint8_t         length;
+       u_int           length;
        uint8_t         rate[16];
 };
 
 struct challenge_t {
-       uint8_t         element_id;
-       uint8_t         length;
+       u_int           length;
        uint8_t         text[254]; /* 1-253 + 1 for null */
 };
 
 struct fh_t {
-       uint8_t         element_id;
-       uint8_t         length;
+       u_int           length;
        uint16_t        dwell_time;
        uint8_t         hop_set;
        uint8_t hop_pattern;
@@ -220,14 +214,12 @@ struct fh_t {
 };
 
 struct ds_t {
-       uint8_t         element_id;
-       uint8_t         length;
+       u_int           length;
        uint8_t         channel;
 };
 
 struct cf_t {
-       uint8_t         element_id;
-       uint8_t         length;
+       u_int           length;
        uint8_t         count;
        uint8_t         period;
        uint16_t        max_duration;
@@ -235,14 +227,18 @@ struct cf_t {
 };
 
 struct tim_t {
-       uint8_t         element_id;
-       uint8_t         length;
+       u_int           length;
        uint8_t         count;
        uint8_t         period;
        uint8_t         bitmap_control;
        uint8_t         bitmap[251];
 };
 
+struct meshid_t {
+       u_int           length;
+       u_char          meshid[33];  /* 32 + 1 for null */
+};
+
 #define        E_SSID          0
 #define        E_RATES 1
 #define        E_FH            2
@@ -267,6 +263,7 @@ struct tim_t {
 /* reserved            19 */
 /* reserved            16 */
 /* reserved            16 */
+#define E_MESHID       114
 
 
 struct mgmt_body_t {
@@ -294,12 +291,14 @@ struct mgmt_body_t {
        struct fh_t     fh;
        int             tim_present;
        struct tim_t    tim;
+       int             meshid_present;
+       struct meshid_t meshid;
 };
 
 struct ctrl_control_wrapper_hdr_t {
        nd_uint16_t     fc;
        nd_uint16_t     duration;
-       nd_mac_addr     addr1;
+       nd_mac48        addr1;
        nd_uint16_t     carried_fc[IEEE802_11_CARRIED_FC_LEN];
        nd_uint16_t     ht_control[IEEE802_11_HT_CONTROL_LEN];
 };
@@ -312,8 +311,8 @@ struct ctrl_control_wrapper_hdr_t {
 struct ctrl_rts_hdr_t {
        nd_uint16_t     fc;
        nd_uint16_t     duration;
-       nd_mac_addr     ra;
-       nd_mac_addr     ta;
+       nd_mac48        ra;
+       nd_mac48        ta;
 };
 
 #define        CTRL_RTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
@@ -322,7 +321,7 @@ struct ctrl_rts_hdr_t {
 struct ctrl_cts_hdr_t {
        nd_uint16_t     fc;
        nd_uint16_t     duration;
-       nd_mac_addr     ra;
+       nd_mac48        ra;
 };
 
 #define        CTRL_CTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
@@ -330,7 +329,7 @@ struct ctrl_cts_hdr_t {
 struct ctrl_ack_hdr_t {
        nd_uint16_t     fc;
        nd_uint16_t     duration;
-       nd_mac_addr     ra;
+       nd_mac48        ra;
 };
 
 #define        CTRL_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
@@ -338,8 +337,8 @@ struct ctrl_ack_hdr_t {
 struct ctrl_ps_poll_hdr_t {
        nd_uint16_t     fc;
        nd_uint16_t     aid;
-       nd_mac_addr     bssid;
-       nd_mac_addr     ta;
+       nd_mac48        bssid;
+       nd_mac48        ta;
 };
 
 #define        CTRL_PS_POLL_HDRLEN     (IEEE802_11_FC_LEN+IEEE802_11_AID_LEN+\
@@ -348,8 +347,8 @@ struct ctrl_ps_poll_hdr_t {
 struct ctrl_end_hdr_t {
        nd_uint16_t     fc;
        nd_uint16_t     duration;
-       nd_mac_addr     ra;
-       nd_mac_addr     bssid;
+       nd_mac48        ra;
+       nd_mac48        bssid;
 };
 
 #define        CTRL_END_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
@@ -358,8 +357,8 @@ struct ctrl_end_hdr_t {
 struct ctrl_end_ack_hdr_t {
        nd_uint16_t     fc;
        nd_uint16_t     duration;
-       nd_mac_addr     ra;
-       nd_mac_addr     bssid;
+       nd_mac48        ra;
+       nd_mac48        bssid;
 };
 
 #define        CTRL_END_ACK_HDRLEN     (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
@@ -368,16 +367,18 @@ struct ctrl_end_ack_hdr_t {
 struct ctrl_ba_hdr_t {
        nd_uint16_t     fc;
        nd_uint16_t     duration;
-       nd_mac_addr     ra;
+       nd_mac48        ra;
+       nd_mac48        ta;
 };
 
-#define        CTRL_BA_HDRLEN  (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
+#define        CTRL_BA_HDRLEN  (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
+                        IEEE802_11_RA_LEN+IEEE802_11_TA_LEN)
 
 struct ctrl_bar_hdr_t {
        nd_uint16_t     fc;
        nd_uint16_t     dur;
-       nd_mac_addr     ra;
-       nd_mac_addr     ta;
+       nd_mac48        ra;
+       nd_mac48        ta;
        nd_uint16_t     ctl;
        nd_uint16_t     seq;
 };
@@ -390,9 +391,9 @@ struct meshcntl_t {
        nd_uint8_t      flags;
        nd_uint8_t      ttl;
        nd_uint32_t     seq;
-       nd_mac_addr     addr4;
-       nd_mac_addr     addr5;
-       nd_mac_addr     addr6;
+       nd_mac48        addr4;
+       nd_mac48        addr5;
+       nd_mac48        addr6;
 };
 
 #define        IV_IV(iv)       ((iv) & 0xFFFFFF)
@@ -410,15 +411,15 @@ struct meshcntl_t {
        ND_PRINT("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
 #define PRINT_RATES(p) \
        if (p.rates_present) { \
-               int z; \
                const char *sep = " ["; \
-               for (z = 0; z < p.rates.length ; z++) { \
-                       PRINT_RATE(sep, p.rates.rate[z], \
-                               (p.rates.rate[z] & 0x80 ? "*" : "")); \
-                       sep = " "; \
-               } \
-               if (p.rates.length != 0) \
+               if (p.rates.length != 0) { \
+                       for (u_int z = 0; z < p.rates.length ; z++) { \
+                               PRINT_RATE(sep, p.rates.rate[z], \
+                                       (p.rates.rate[z] & 0x80 ? "*" : "")); \
+                               sep = " "; \
+                       } \
                        ND_PRINT(" Mbit]"); \
+               } \
        }
 
 #define PRINT_DS_CHANNEL(p) \
@@ -427,6 +428,13 @@ struct meshcntl_t {
        ND_PRINT("%s", \
            CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "");
 
+#define PRINT_MESHID(p) \
+       if (p.meshid_present) { \
+               ND_PRINT(" (MESHID: "); \
+               fn_print_str(ndo, p.meshid.meshid); \
+               ND_PRINT(")"); \
+       }
+
 #define MAX_MCS_INDEX  76
 
 /*
@@ -949,8 +957,8 @@ static const char *status_text[] = {
        "Reserved",                                                                     /* 69 */
        "Reserved",                                                                     /* 70 */
        "Reserved",                                                                     /* 71 */
-       "Invalid contents of RSNE",                             /* 72 */
-       "U-APSD coexistence is not supported",          /* 73 */
+       "Invalid contents of RSNE",                             /* 72 */
+       "U-APSD coexistence is not supported",          /* 73 */
        "Requested U-APSD coexistence mode is not supported", /* 74 */
        "Requested Interval/Duration value cannot be "
          "supported with U-APSD coexistence",          /* 75 */
@@ -997,7 +1005,7 @@ static const char *status_text[] = {
          "Spectrum Management field is unacceptable", /* 103 */
        "Association denied because the requesting STA "
          "does not support VHT features",                      /* 104 */
-       "Enablement denied",                                            /* 105 */
+       "Enablement denied",                                            /* 105 */
        "Enablement denied due to restriction from an "
          "authorized GDB",                                                     /* 106 */
        "Authorization deenabled",                                      /* 107 */
@@ -1091,7 +1099,7 @@ static const char *reason_text[] = {
          "requesting to close the mesh peering",                               /* 55 */
        "The mesh STA has resent dot11MeshMaxRetries Mesh "
          "Peering Open frames, without receiving a Mesh Peering "
-         "Confirm frame"                                                                               /* 56 */
+         "Confirm frame",                                                                              /* 56 */
        "The confirmTimer for the mesh peering instance times out",     /* 57 */
        "The mesh STA fails to unwrap the GTK or the values in the "
          "wrapped contents do not match",                                              /* 58 */
@@ -1145,6 +1153,7 @@ parse_elements(netdissect_options *ndo,
        struct ds_t ds;
        struct cf_t cf;
        struct tim_t tim;
+       struct meshid_t meshid;
 
        /*
         * We haven't seen any elements yet.
@@ -1155,6 +1164,7 @@ parse_elements(netdissect_options *ndo,
        pbody->ds_present = 0;
        pbody->cf_present = 0;
        pbody->tim_present = 0;
+       pbody->meshid_present = 0;
 
        while (length != 0) {
                /* Make sure we at least have the element ID and length. */
@@ -1170,7 +1180,7 @@ parse_elements(netdissect_options *ndo,
 
                switch (GET_U_1(p + offset)) {
                case E_SSID:
-                       memcpy(&ssid, p + offset, 2);
+                       ssid.length = elementlen;
                        offset += 2;
                        length -= 2;
                        if (ssid.length != 0) {
@@ -1194,7 +1204,7 @@ parse_elements(netdissect_options *ndo,
                        }
                        break;
                case E_CHALLENGE:
-                       memcpy(&challenge, p + offset, 2);
+                       challenge.length = elementlen;
                        offset += 2;
                        length -= 2;
                        if (challenge.length != 0) {
@@ -1220,7 +1230,7 @@ parse_elements(netdissect_options *ndo,
                        }
                        break;
                case E_RATES:
-                       memcpy(&rates, p + offset, 2);
+                       rates.length = elementlen;
                        offset += 2;
                        length -= 2;
                        if (rates.length != 0) {
@@ -1252,7 +1262,7 @@ parse_elements(netdissect_options *ndo,
                        }
                        break;
                case E_DS:
-                       memcpy(&ds, p + offset, 2);
+                       ds.length = elementlen;
                        offset += 2;
                        length -= 2;
                        if (ds.length != 1) {
@@ -1276,7 +1286,7 @@ parse_elements(netdissect_options *ndo,
                        }
                        break;
                case E_CF:
-                       memcpy(&cf, p + offset, 2);
+                       cf.length = elementlen;
                        offset += 2;
                        length -= 2;
                        if (cf.length != 6) {
@@ -1284,9 +1294,18 @@ parse_elements(netdissect_options *ndo,
                                length -= cf.length;
                                break;
                        }
-                       memcpy(&cf.count, p + offset, 6);
-                       offset += 6;
-                       length -= 6;
+                       cf.count = GET_U_1(p + offset);
+                       offset += 1;
+                       length -= 1;
+                       cf.period = GET_U_1(p + offset);
+                       offset += 1;
+                       length -= 1;
+                       cf.max_duration = GET_LE_U_2(p + offset);
+                       offset += 2;
+                       length -= 2;
+                       cf.dur_remaining = GET_LE_U_2(p + offset);
+                       offset += 2;
+                       length -= 2;
                        /*
                         * Present and not truncated.
                         *
@@ -1300,7 +1319,7 @@ parse_elements(netdissect_options *ndo,
                        }
                        break;
                case E_TIM:
-                       memcpy(&tim, p + offset, 2);
+                       tim.length = elementlen;
                        offset += 2;
                        length -= 2;
                        if (tim.length <= 3U) {
@@ -1310,10 +1329,15 @@ parse_elements(netdissect_options *ndo,
                        }
                        if (tim.length - 3U > sizeof(tim.bitmap))
                                return 0;
-                       memcpy(&tim.count, p + offset, 3);
-                       offset += 3;
-                       length -= 3;
-
+                       tim.count = GET_U_1(p + offset);
+                       offset += 1;
+                       length -= 1;
+                       tim.period = GET_U_1(p + offset);
+                       offset += 1;
+                       length -= 1;
+                       tim.bitmap_control = GET_U_1(p + offset);
+                       offset += 1;
+                       length -= 1;
                        memcpy(tim.bitmap, p + offset, tim.length - 3);
                        offset += tim.length - 3;
                        length -= tim.length - 3;
@@ -1329,6 +1353,30 @@ parse_elements(netdissect_options *ndo,
                                pbody->tim_present = 1;
                        }
                        break;
+               case E_MESHID:
+                       meshid.length = elementlen;
+                       offset += 2;
+                       length -= 2;
+                       if (meshid.length != 0) {
+                               if (meshid.length > sizeof(meshid.meshid) - 1)
+                                       return 0;
+                               memcpy(&meshid.meshid, p + offset, meshid.length);
+                               offset += meshid.length;
+                               length -= meshid.length;
+                       }
+                       meshid.meshid[meshid.length] = '\0';
+                       /*
+                        * Present and not truncated.
+                        *
+                        * If we haven't already seen a MESHID IE,
+                        * copy this one, otherwise ignore this one,
+                        * so we later report the first one we saw.
+                        */
+                       if (!pbody->meshid_present) {
+                               pbody->meshid = meshid;
+                               pbody->meshid_present = 1;
+                       }
+                       break;
                default:
 #if 0
                        ND_PRINT("(1) unhandled element_id (%u)  ",
@@ -1382,6 +1430,7 @@ handle_beacon(netdissect_options *ndo,
        ND_PRINT(" %s",
            CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
        PRINT_DS_CHANNEL(pbody);
+       PRINT_MESHID(pbody);
 
        return ret;
 trunc:
@@ -1483,7 +1532,7 @@ handle_reassoc_request(netdissect_options *ndo,
        ret = parse_elements(ndo, &pbody, p, offset, length);
 
        PRINT_SSID(pbody);
-       ND_PRINT(" AP : %s", etheraddr_string(ndo,  pbody.ap ));
+       ND_PRINT(" AP : %s", mac48_string(ndo,  pbody.ap ));
 
        return ret;
 trunc:
@@ -1546,6 +1595,7 @@ handle_probe_response(netdissect_options *ndo,
        PRINT_SSID(pbody);
        PRINT_RATES(pbody);
        PRINT_DS_CHANNEL(pbody);
+       PRINT_MESHID(pbody);
 
        return ret;
 trunc:
@@ -1658,93 +1708,102 @@ handle_deauth(netdissect_options *ndo,
        if (ndo->ndo_eflag) {
                ND_PRINT(": %s", reason);
        } else {
-               ND_PRINT(" (%s): %s", GET_ETHERADDR_STRING(src), reason);
+               ND_PRINT(" (%s): %s", GET_MAC48_STRING(src), reason);
        }
        return 1;
 trunc:
        return 0;
 }
 
-#define        PRINT_HT_ACTION(v) (\
-       (v) == 0 ? ND_PRINT("TxChWidth"): \
-       (v) == 1 ? ND_PRINT("MIMOPwrSave"): \
-                  ND_PRINT("Act#%u", (v)))
-#define        PRINT_BA_ACTION(v) (\
-       (v) == 0 ? ND_PRINT("ADDBA Request"): \
-       (v) == 1 ? ND_PRINT("ADDBA Response"): \
-       (v) == 2 ? ND_PRINT("DELBA"): \
-                  ND_PRINT("Act#%u", (v)))
-#define        PRINT_MESHLINK_ACTION(v) (\
-       (v) == 0 ? ND_PRINT("Request"): \
-       (v) == 1 ? ND_PRINT("Report"): \
-                  ND_PRINT("Act#%u", (v)))
-#define        PRINT_MESHPEERING_ACTION(v) (\
-       (v) == 0 ? ND_PRINT("Open"): \
-       (v) == 1 ? ND_PRINT("Confirm"): \
-       (v) == 2 ? ND_PRINT("Close"): \
-                  ND_PRINT("Act#%u", (v)))
-#define        PRINT_MESHPATH_ACTION(v) (\
-       (v) == 0 ? ND_PRINT("Request"): \
-       (v) == 1 ? ND_PRINT("Report"): \
-       (v) == 2 ? ND_PRINT("Error"): \
-       (v) == 3 ? ND_PRINT("RootAnnouncement"): \
-                  ND_PRINT("Act#%u", (v)))
-
-#define PRINT_MESH_ACTION(v) (\
-       (v) == 0 ? ND_PRINT("MeshLink"): \
-       (v) == 1 ? ND_PRINT("HWMP"): \
-       (v) == 2 ? ND_PRINT("Gate Announcement"): \
-       (v) == 3 ? ND_PRINT("Congestion Control"): \
-       (v) == 4 ? ND_PRINT("MCCA Setup Request"): \
-       (v) == 5 ? ND_PRINT("MCCA Setup Reply"): \
-       (v) == 6 ? ND_PRINT("MCCA Advertisement Request"): \
-       (v) == 7 ? ND_PRINT("MCCA Advertisement"): \
-       (v) == 8 ? ND_PRINT("MCCA Teardown"): \
-       (v) == 9 ? ND_PRINT("TBTT Adjustment Request"): \
-       (v) == 10 ? ND_PRINT("TBTT Adjustment Response"): \
-                  ND_PRINT("Act#%u", (v)))
-#define PRINT_MULTIHOP_ACTION(v) (\
-       (v) == 0 ? ND_PRINT("Proxy Update"): \
-       (v) == 1 ? ND_PRINT("Proxy Update Confirmation"): \
-                  ND_PRINT("Act#%u", (v)))
-#define PRINT_SELFPROT_ACTION(v) (\
-       (v) == 1 ? ND_PRINT("Peering Open"): \
-       (v) == 2 ? ND_PRINT("Peering Confirm"): \
-       (v) == 3 ? ND_PRINT("Peering Close"): \
-       (v) == 4 ? ND_PRINT("Group Key Inform"): \
-       (v) == 5 ? ND_PRINT("Group Key Acknowledge"): \
-                  ND_PRINT("Act#%u", (v)))
+static const struct tok category_str[] = {
+       { 0,   "Spectrum Management" },
+       { 1,   "QoS"                 },
+       { 2,   "DLS"                 },
+       { 3,   "BA"                  },
+       { 7,   "HT"                  },
+       { 13,  "MeshAction"          },
+       { 14,  "MultihopAction"      },
+       { 15,  "SelfprotectAction"   },
+       { 127, "Vendor"              },
+       { 0, NULL }
+};
+
+static const struct tok act_ba_str[] = {
+       { 0, "ADDBA Request"  },
+       { 1, "ADDBA Response" },
+       { 2, "DELBA"          },
+       { 0, NULL }
+};
+
+static const struct tok act_ht_str[] = {
+       { 0, "TxChWidth"   },
+       { 1, "MIMOPwrSave" },
+       { 0, NULL }
+};
+
+static const struct tok act_mesh_str[] = {
+       { 0,  "MeshLink"                   },
+       { 1,  "HWMP"                       },
+       { 2,  "Gate Announcement"          },
+       { 3,  "Congestion Control"         },
+       { 4,  "MCCA Setup Request"         },
+       { 5,  "MCCA Setup Reply"           },
+       { 6,  "MCCA Advertisement Request" },
+       { 7,  "MCCA Advertisement"         },
+       { 8,  "MCCA Teardown"              },
+       { 9,  "TBTT Adjustment Request"    },
+       { 10, "TBTT Adjustment Response"   },
+       { 0, NULL }
+};
+
+static const struct tok act_mhop_str[] = {
+       { 0, "Proxy Update" },
+       { 1, "Proxy Update Confirmation" },
+       { 0, NULL }
+};
+
+static const struct tok act_selfpr_str[] = {
+       { 1, "Peering Open"          },
+       { 2, "Peering Confirm"       },
+       { 3, "Peering Close"         },
+       { 4, "Group Key Inform"      },
+       { 5, "Group Key Acknowledge" },
+       { 0, NULL }
+};
+
+static const struct uint_tokary category2tokary[] = {
+       { 3,   act_ba_str     },
+       { 7,   act_ht_str     },
+       { 13,  act_mesh_str   },
+       { 14,  act_mhop_str   },
+       { 15,  act_selfpr_str },
+       /* uint2tokary() does not use array termination. */
+};
 
 static int
 handle_action(netdissect_options *ndo,
              const uint8_t *src, const u_char *p, u_int length)
 {
+       uint8_t category, action;
+       const struct tok *action_str;
+
        ND_TCHECK_2(p);
        if (length < 2)
                goto trunc;
        if (ndo->ndo_eflag) {
                ND_PRINT(": ");
        } else {
-               ND_PRINT(" (%s): ", GET_ETHERADDR_STRING(src));
-       }
-       switch (GET_U_1(p)) {
-       case 0: ND_PRINT("Spectrum Management Act#%u", GET_U_1(p + 1)); break;
-       case 1: ND_PRINT("QoS Act#%u", GET_U_1(p + 1)); break;
-       case 2: ND_PRINT("DLS Act#%u", GET_U_1(p + 1)); break;
-       case 3: ND_PRINT("BA "); PRINT_BA_ACTION(GET_U_1(p + 1)); break;
-       case 7: ND_PRINT("HT "); PRINT_HT_ACTION(GET_U_1(p + 1)); break;
-       case 13: ND_PRINT("MeshAction "); PRINT_MESH_ACTION(GET_U_1(p + 1)); break;
-       case 14:
-               ND_PRINT("MultiohopAction ");
-               PRINT_MULTIHOP_ACTION(GET_U_1(p + 1)); break;
-       case 15:
-               ND_PRINT("SelfprotectAction ");
-               PRINT_SELFPROT_ACTION(GET_U_1(p + 1)); break;
-       case 127: ND_PRINT("Vendor Act#%u", GET_U_1(p + 1)); break;
-       default:
-               ND_PRINT("Reserved(%u) Act#%u", GET_U_1(p), GET_U_1(p + 1));
-               break;
+               ND_PRINT(" (%s): ", GET_MAC48_STRING(src));
        }
+       category = GET_U_1(p);
+       ND_PRINT("%s ", tok2str(category_str, "Reserved(%u)", category));
+       action = GET_U_1(p + 1);
+       action_str = uint2tokary(category2tokary, category);
+       if (!action_str)
+               ND_PRINT("Act#%u", action);
+       else
+               ND_PRINT("%s", tok2str(action_str, "Act#%u", action));
+
        return 1;
 trunc:
        return 0;
@@ -1813,8 +1872,8 @@ ctrl_body_print(netdissect_options *ndo,
                ND_TCHECK_LEN(p, CTRL_BAR_HDRLEN);
                if (!ndo->ndo_eflag)
                        ND_PRINT(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
-                           GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ra),
-                           GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ta),
+                           GET_MAC48_STRING(((const struct ctrl_bar_hdr_t *)p)->ra),
+                           GET_MAC48_STRING(((const struct ctrl_bar_hdr_t *)p)->ta),
                            GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->ctl),
                            GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->seq));
                break;
@@ -1822,7 +1881,7 @@ ctrl_body_print(netdissect_options *ndo,
                ND_TCHECK_LEN(p, CTRL_BA_HDRLEN);
                if (!ndo->ndo_eflag)
                        ND_PRINT(" RA:%s ",
-                           GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra));
+                           GET_MAC48_STRING(((const struct ctrl_ba_hdr_t *)p)->ra));
                break;
        case CTRL_PS_POLL:
                ND_TCHECK_LEN(p, CTRL_PS_POLL_HDRLEN);
@@ -1833,31 +1892,31 @@ ctrl_body_print(netdissect_options *ndo,
                ND_TCHECK_LEN(p, CTRL_RTS_HDRLEN);
                if (!ndo->ndo_eflag)
                        ND_PRINT(" TA:%s ",
-                           GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ta));
+                           GET_MAC48_STRING(((const struct ctrl_rts_hdr_t *)p)->ta));
                break;
        case CTRL_CTS:
                ND_TCHECK_LEN(p, CTRL_CTS_HDRLEN);
                if (!ndo->ndo_eflag)
                        ND_PRINT(" RA:%s ",
-                           GET_ETHERADDR_STRING(((const struct ctrl_cts_hdr_t *)p)->ra));
+                           GET_MAC48_STRING(((const struct ctrl_cts_hdr_t *)p)->ra));
                break;
        case CTRL_ACK:
                ND_TCHECK_LEN(p, CTRL_ACK_HDRLEN);
                if (!ndo->ndo_eflag)
                        ND_PRINT(" RA:%s ",
-                           GET_ETHERADDR_STRING(((const struct ctrl_ack_hdr_t *)p)->ra));
+                           GET_MAC48_STRING(((const struct ctrl_ack_hdr_t *)p)->ra));
                break;
        case CTRL_CF_END:
                ND_TCHECK_LEN(p, CTRL_END_HDRLEN);
                if (!ndo->ndo_eflag)
                        ND_PRINT(" RA:%s ",
-                           GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->ra));
+                           GET_MAC48_STRING(((const struct ctrl_end_hdr_t *)p)->ra));
                break;
        case CTRL_END_ACK:
                ND_TCHECK_LEN(p, CTRL_END_ACK_HDRLEN);
                if (!ndo->ndo_eflag)
                        ND_PRINT(" RA:%s ",
-                           GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra));
+                           GET_MAC48_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra));
                break;
        }
        return 1;
@@ -1899,7 +1958,7 @@ get_data_src_dst_mac(uint16_t fc, const u_char *p, const uint8_t **srcp,
                }
        } else {
                if (!FC_FROM_DS(fc)) {
-                       /* From DS and not To DS */
+                       /* To DS and not From DS */
                        *srcp = ADDR2;
                        *dstp = ADDR3;
                } else {
@@ -1959,20 +2018,20 @@ data_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
 
        if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
                ND_PRINT("DA:%s SA:%s BSSID:%s ",
-                   GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
-                   GET_ETHERADDR_STRING(ADDR3));
+                   GET_MAC48_STRING(ADDR1), GET_MAC48_STRING(ADDR2),
+                   GET_MAC48_STRING(ADDR3));
        } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
                ND_PRINT("DA:%s BSSID:%s SA:%s ",
-                   GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
-                   GET_ETHERADDR_STRING(ADDR3));
+                   GET_MAC48_STRING(ADDR1), GET_MAC48_STRING(ADDR2),
+                   GET_MAC48_STRING(ADDR3));
        } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
                ND_PRINT("BSSID:%s SA:%s DA:%s ",
-                   GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
-                   GET_ETHERADDR_STRING(ADDR3));
+                   GET_MAC48_STRING(ADDR1), GET_MAC48_STRING(ADDR2),
+                   GET_MAC48_STRING(ADDR3));
        } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
                ND_PRINT("RA:%s TA:%s DA:%s SA:%s ",
-                   GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
-                   GET_ETHERADDR_STRING(ADDR3), GET_ETHERADDR_STRING(ADDR4));
+                   GET_MAC48_STRING(ADDR1), GET_MAC48_STRING(ADDR2),
+                   GET_MAC48_STRING(ADDR3), GET_MAC48_STRING(ADDR4));
        }
 
 #undef ADDR1
@@ -1987,8 +2046,8 @@ mgmt_header_print(netdissect_options *ndo, const u_char *p)
        const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
 
        ND_PRINT("BSSID:%s DA:%s SA:%s ",
-           GET_ETHERADDR_STRING((hp)->bssid), GET_ETHERADDR_STRING((hp)->da),
-           GET_ETHERADDR_STRING((hp)->sa));
+           GET_MAC48_STRING((hp)->bssid), GET_MAC48_STRING((hp)->da),
+           GET_MAC48_STRING((hp)->sa));
 }
 
 static void
@@ -1997,42 +2056,43 @@ ctrl_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
        switch (FC_SUBTYPE(fc)) {
        case CTRL_BAR:
                ND_PRINT(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
-                   GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ra),
-                   GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ta),
+                   GET_MAC48_STRING(((const struct ctrl_bar_hdr_t *)p)->ra),
+                   GET_MAC48_STRING(((const struct ctrl_bar_hdr_t *)p)->ta),
                    GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->ctl),
                    GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->seq));
                break;
        case CTRL_BA:
-               ND_PRINT("RA:%s ",
-                   GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra));
+               ND_PRINT("RA:%s TA:%s ",
+                   GET_MAC48_STRING(((const struct ctrl_ba_hdr_t *)p)->ra),
+                   GET_MAC48_STRING(((const struct ctrl_ba_hdr_t *)p)->ta));
                break;
        case CTRL_PS_POLL:
                ND_PRINT("BSSID:%s TA:%s ",
-                   GET_ETHERADDR_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->bssid),
-                   GET_ETHERADDR_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->ta));
+                   GET_MAC48_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->bssid),
+                   GET_MAC48_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->ta));
                break;
        case CTRL_RTS:
                ND_PRINT("RA:%s TA:%s ",
-                   GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ra),
-                   GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ta));
+                   GET_MAC48_STRING(((const struct ctrl_rts_hdr_t *)p)->ra),
+                   GET_MAC48_STRING(((const struct ctrl_rts_hdr_t *)p)->ta));
                break;
        case CTRL_CTS:
                ND_PRINT("RA:%s ",
-                   GET_ETHERADDR_STRING(((const struct ctrl_cts_hdr_t *)p)->ra));
+                   GET_MAC48_STRING(((const struct ctrl_cts_hdr_t *)p)->ra));
                break;
        case CTRL_ACK:
                ND_PRINT("RA:%s ",
-                   GET_ETHERADDR_STRING(((const struct ctrl_ack_hdr_t *)p)->ra));
+                   GET_MAC48_STRING(((const struct ctrl_ack_hdr_t *)p)->ra));
                break;
        case CTRL_CF_END:
                ND_PRINT("RA:%s BSSID:%s ",
-                   GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->ra),
-                   GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->bssid));
+                   GET_MAC48_STRING(((const struct ctrl_end_hdr_t *)p)->ra),
+                   GET_MAC48_STRING(((const struct ctrl_end_hdr_t *)p)->bssid));
                break;
        case CTRL_END_ACK:
                ND_PRINT("RA:%s BSSID:%s ",
-                   GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra),
-                   GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->bssid));
+                   GET_MAC48_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra),
+                   GET_MAC48_STRING(((const struct ctrl_end_ack_hdr_t *)p)->bssid));
                break;
        default:
                /* We shouldn't get here - we should already have quit */
@@ -2123,11 +2183,11 @@ ieee_802_11_hdr_print(netdissect_options *ndo,
                ND_PRINT("MeshData (AE %u TTL %u seq %u", ae,
                    GET_U_1(mc->ttl), GET_LE_U_4(mc->seq));
                if (ae > 0)
-                       ND_PRINT(" A4:%s", GET_ETHERADDR_STRING(mc->addr4));
+                       ND_PRINT(" A4:%s", GET_MAC48_STRING(mc->addr4));
                if (ae > 1)
-                       ND_PRINT(" A5:%s", GET_ETHERADDR_STRING(mc->addr5));
+                       ND_PRINT(" A5:%s", GET_MAC48_STRING(mc->addr5));
                if (ae > 2)
-                       ND_PRINT(" A6:%s", GET_ETHERADDR_STRING(mc->addr6));
+                       ND_PRINT(" A6:%s", GET_MAC48_STRING(mc->addr6));
                ND_PRINT(") ");
        }
 
@@ -2210,8 +2270,8 @@ ieee802_11_print(netdissect_options *ndo,
        caplen -= hdrlen;
        p += hdrlen;
 
-       src.addr_string = etheraddr_string;
-       dst.addr_string = etheraddr_string;
+       src.addr_string = mac48_string;
+       dst.addr_string = mac48_string;
        switch (FC_TYPE(fc)) {
        case T_MGMT:
                get_mgmt_src_dst_mac(p - hdrlen, &src.addr, &dst.addr);
@@ -2265,12 +2325,12 @@ ieee802_11_print(netdissect_options *ndo,
  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
  * is the number of bytes actually captured.
  */
-u_int
+void
 ieee802_11_if_print(netdissect_options *ndo,
                    const struct pcap_pkthdr *h, const u_char *p)
 {
-       ndo->ndo_protocol = "802.11_if";
-       return ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0);
+       ndo->ndo_protocol = "802.11";
+       ndo->ndo_ll_hdr_len += ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0);
 }
 
 
@@ -2642,7 +2702,7 @@ enum ieee80211_radiotap_type {
 
 static void
 print_chaninfo(netdissect_options *ndo,
-              uint16_t freq, int flags, int presentflags)
+              uint16_t freq, uint32_t flags, uint32_t presentflags)
 {
        ND_PRINT("%u MHz", freq);
        if (presentflags & (1 << IEEE80211_RADIOTAP_MCS)) {
@@ -2699,7 +2759,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_TSFT: {
                uint64_t tsft;
 
-               rc = cpack_uint64(ndo, s, &tsft);
+               rc = nd_cpack_uint64(ndo, s, &tsft);
                if (rc != 0)
                        goto trunc;
                ND_PRINT("%" PRIu64 "us tsft ", tsft);
@@ -2709,7 +2769,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_FLAGS: {
                uint8_t flagsval;
 
-               rc = cpack_uint8(ndo, s, &flagsval);
+               rc = nd_cpack_uint8(ndo, s, &flagsval);
                if (rc != 0)
                        goto trunc;
                *flagsp = flagsval;
@@ -2729,7 +2789,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_RATE: {
                uint8_t rate;
 
-               rc = cpack_uint8(ndo, s, &rate);
+               rc = nd_cpack_uint8(ndo, s, &rate);
                if (rc != 0)
                        goto trunc;
                /*
@@ -2780,10 +2840,10 @@ print_radiotap_field(netdissect_options *ndo,
                uint16_t frequency;
                uint16_t flags;
 
-               rc = cpack_uint16(ndo, s, &frequency);
+               rc = nd_cpack_uint16(ndo, s, &frequency);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint16(ndo, s, &flags);
+               rc = nd_cpack_uint16(ndo, s, &flags);
                if (rc != 0)
                        goto trunc;
                /*
@@ -2800,10 +2860,10 @@ print_radiotap_field(netdissect_options *ndo,
                uint8_t hopset;
                uint8_t hoppat;
 
-               rc = cpack_uint8(ndo, s, &hopset);
+               rc = nd_cpack_uint8(ndo, s, &hopset);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint8(ndo, s, &hoppat);
+               rc = nd_cpack_uint8(ndo, s, &hoppat);
                if (rc != 0)
                        goto trunc;
                ND_PRINT("fhset %u fhpat %u ", hopset, hoppat);
@@ -2813,7 +2873,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: {
                int8_t dbm_antsignal;
 
-               rc = cpack_int8(ndo, s, &dbm_antsignal);
+               rc = nd_cpack_int8(ndo, s, &dbm_antsignal);
                if (rc != 0)
                        goto trunc;
                ND_PRINT("%ddBm signal ", dbm_antsignal);
@@ -2823,7 +2883,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_DBM_ANTNOISE: {
                int8_t dbm_antnoise;
 
-               rc = cpack_int8(ndo, s, &dbm_antnoise);
+               rc = nd_cpack_int8(ndo, s, &dbm_antnoise);
                if (rc != 0)
                        goto trunc;
                ND_PRINT("%ddBm noise ", dbm_antnoise);
@@ -2833,7 +2893,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_LOCK_QUALITY: {
                uint16_t lock_quality;
 
-               rc = cpack_uint16(ndo, s, &lock_quality);
+               rc = nd_cpack_uint16(ndo, s, &lock_quality);
                if (rc != 0)
                        goto trunc;
                ND_PRINT("%u sq ", lock_quality);
@@ -2843,7 +2903,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_TX_ATTENUATION: {
                int16_t tx_attenuation;
 
-               rc = cpack_int16(ndo, s, &tx_attenuation);
+               rc = nd_cpack_int16(ndo, s, &tx_attenuation);
                if (rc != 0)
                        goto trunc;
                ND_PRINT("%d tx power ", -tx_attenuation);
@@ -2853,7 +2913,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: {
                int8_t db_tx_attenuation;
 
-               rc = cpack_int8(ndo, s, &db_tx_attenuation);
+               rc = nd_cpack_int8(ndo, s, &db_tx_attenuation);
                if (rc != 0)
                        goto trunc;
                ND_PRINT("%ddB tx attenuation ", -db_tx_attenuation);
@@ -2863,7 +2923,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_DBM_TX_POWER: {
                int8_t dbm_tx_power;
 
-               rc = cpack_int8(ndo, s, &dbm_tx_power);
+               rc = nd_cpack_int8(ndo, s, &dbm_tx_power);
                if (rc != 0)
                        goto trunc;
                ND_PRINT("%ddBm tx power ", dbm_tx_power);
@@ -2873,7 +2933,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_ANTENNA: {
                uint8_t antenna;
 
-               rc = cpack_uint8(ndo, s, &antenna);
+               rc = nd_cpack_uint8(ndo, s, &antenna);
                if (rc != 0)
                        goto trunc;
                ND_PRINT("antenna %u ", antenna);
@@ -2883,7 +2943,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_DB_ANTSIGNAL: {
                uint8_t db_antsignal;
 
-               rc = cpack_uint8(ndo, s, &db_antsignal);
+               rc = nd_cpack_uint8(ndo, s, &db_antsignal);
                if (rc != 0)
                        goto trunc;
                ND_PRINT("%udB signal ", db_antsignal);
@@ -2893,7 +2953,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_DB_ANTNOISE: {
                uint8_t db_antnoise;
 
-               rc = cpack_uint8(ndo, s, &db_antnoise);
+               rc = nd_cpack_uint8(ndo, s, &db_antnoise);
                if (rc != 0)
                        goto trunc;
                ND_PRINT("%udB noise ", db_antnoise);
@@ -2903,7 +2963,7 @@ print_radiotap_field(netdissect_options *ndo,
        case IEEE80211_RADIOTAP_RX_FLAGS: {
                uint16_t rx_flags;
 
-               rc = cpack_uint16(ndo, s, &rx_flags);
+               rc = nd_cpack_uint16(ndo, s, &rx_flags);
                if (rc != 0)
                        goto trunc;
                /* Do nothing for now */
@@ -2916,16 +2976,16 @@ print_radiotap_field(netdissect_options *ndo,
                uint8_t channel;
                uint8_t maxpower;
 
-               rc = cpack_uint32(ndo, s, &flags);
+               rc = nd_cpack_uint32(ndo, s, &flags);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint16(ndo, s, &frequency);
+               rc = nd_cpack_uint16(ndo, s, &frequency);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint8(ndo, s, &channel);
+               rc = nd_cpack_uint8(ndo, s, &channel);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint8(ndo, s, &maxpower);
+               rc = nd_cpack_uint8(ndo, s, &maxpower);
                if (rc != 0)
                        goto trunc;
                print_chaninfo(ndo, frequency, flags, presentflags);
@@ -2944,13 +3004,13 @@ print_radiotap_field(netdissect_options *ndo,
                };
                float htrate;
 
-               rc = cpack_uint8(ndo, s, &known);
+               rc = nd_cpack_uint8(ndo, s, &known);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint8(ndo, s, &flags);
+               rc = nd_cpack_uint8(ndo, s, &flags);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint8(ndo, s, &mcs_index);
+               rc = nd_cpack_uint8(ndo, s, &mcs_index);
                if (rc != 0)
                        goto trunc;
                if (known & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) {
@@ -3032,16 +3092,16 @@ print_radiotap_field(netdissect_options *ndo,
                uint8_t delim_crc;
                uint8_t reserved;
 
-               rc = cpack_uint32(ndo, s, &reference_num);
+               rc = nd_cpack_uint32(ndo, s, &reference_num);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint16(ndo, s, &flags);
+               rc = nd_cpack_uint16(ndo, s, &flags);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint8(ndo, s, &delim_crc);
+               rc = nd_cpack_uint8(ndo, s, &delim_crc);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint8(ndo, s, &reserved);
+               rc = nd_cpack_uint8(ndo, s, &reserved);
                if (rc != 0)
                        goto trunc;
                /* Do nothing for now */
@@ -3091,27 +3151,27 @@ print_radiotap_field(netdissect_options *ndo,
                        "unknown (31)"
                };
 
-               rc = cpack_uint16(ndo, s, &known);
+               rc = nd_cpack_uint16(ndo, s, &known);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint8(ndo, s, &flags);
+               rc = nd_cpack_uint8(ndo, s, &flags);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint8(ndo, s, &bandwidth);
+               rc = nd_cpack_uint8(ndo, s, &bandwidth);
                if (rc != 0)
                        goto trunc;
                for (i = 0; i < 4; i++) {
-                       rc = cpack_uint8(ndo, s, &mcs_nss[i]);
+                       rc = nd_cpack_uint8(ndo, s, &mcs_nss[i]);
                        if (rc != 0)
                                goto trunc;
                }
-               rc = cpack_uint8(ndo, s, &coding);
+               rc = nd_cpack_uint8(ndo, s, &coding);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint8(ndo, s, &group_id);
+               rc = nd_cpack_uint8(ndo, s, &group_id);
                if (rc != 0)
                        goto trunc;
-               rc = cpack_uint16(ndo, s, &partial_aid);
+               rc = nd_cpack_uint16(ndo, s, &partial_aid);
                if (rc != 0)
                        goto trunc;
                for (i = 0; i < 4; i++) {
@@ -3252,13 +3312,13 @@ ieee802_11_radio_print(netdissect_options *ndo,
                nd_print_trunc(ndo);
                return caplen;
        }
-       cpack_init(&cpacker, (const uint8_t *)hdr, len); /* align against header start */
-       cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */
+       nd_cpack_init(&cpacker, (const uint8_t *)hdr, len); /* align against header start */
+       nd_cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */
        for (last_presentp = &hdr->it_present;
             (const u_char*)(last_presentp + 1) <= p + len &&
             IS_EXTENDED(last_presentp);
             last_presentp++)
-         cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */
+         nd_cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */
 
        /* are there more bitmap extensions than bytes in header? */
        if ((const u_char*)(last_presentp + 1) > p + len) {
@@ -3294,7 +3354,7 @@ ieee802_11_radio_print(netdissect_options *ndo,
                         * it'd be added here; use vendor_oui and
                         * vendor_subnamespace to interpret the fields.
                         */
-                       if (cpack_advance(&cpacker, skip_length) != 0) {
+                       if (nd_cpack_advance(&cpacker, skip_length) != 0) {
                                /*
                                 * Ran out of space in the packet.
                                 */
@@ -3357,27 +3417,27 @@ ieee802_11_radio_print(netdissect_options *ndo,
                         */
                        bit0 = 0;
                        vendor_namespace = 1;
-                       if ((cpack_align_and_reserve(&cpacker, 2)) == NULL) {
+                       if ((nd_cpack_align_and_reserve(&cpacker, 2)) == NULL) {
                                nd_print_trunc(ndo);
                                break;
                        }
-                       if (cpack_uint8(ndo, &cpacker, &vendor_oui[0]) != 0) {
+                       if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[0]) != 0) {
                                nd_print_trunc(ndo);
                                break;
                        }
-                       if (cpack_uint8(ndo, &cpacker, &vendor_oui[1]) != 0) {
+                       if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[1]) != 0) {
                                nd_print_trunc(ndo);
                                break;
                        }
-                       if (cpack_uint8(ndo, &cpacker, &vendor_oui[2]) != 0) {
+                       if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[2]) != 0) {
                                nd_print_trunc(ndo);
                                break;
                        }
-                       if (cpack_uint8(ndo, &cpacker, &vendor_subnamespace) != 0) {
+                       if (nd_cpack_uint8(ndo, &cpacker, &vendor_subnamespace) != 0) {
                                nd_print_trunc(ndo);
                                break;
                        }
-                       if (cpack_uint16(ndo, &cpacker, &skip_length) != 0) {
+                       if (nd_cpack_uint16(ndo, &cpacker, &skip_length) != 0) {
                                nd_print_trunc(ndo);
                                break;
                        }
@@ -3458,7 +3518,7 @@ ieee802_11_radio_avs_print(netdissect_options *ndo,
  * the AVS header, and the first 4 bytes of the header are used to
  * indicate whether it's a Prism header or an AVS header).
  */
-u_int
+void
 prism_if_print(netdissect_options *ndo,
               const struct pcap_pkthdr *h, const u_char *p)
 {
@@ -3466,36 +3526,43 @@ prism_if_print(netdissect_options *ndo,
        u_int length = h->len;
        uint32_t msgcode;
 
-       ndo->ndo_protocol = "prism_if";
+       ndo->ndo_protocol = "prism";
        if (caplen < 4) {
                nd_print_trunc(ndo);
-               return caplen;
+               ndo->ndo_ll_hdr_len += caplen;
+               return;
        }
 
        msgcode = GET_BE_U_4(p);
        if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
-           msgcode == WLANCAP_MAGIC_COOKIE_V2)
-               return ieee802_11_radio_avs_print(ndo, p, length, caplen);
+           msgcode == WLANCAP_MAGIC_COOKIE_V2) {
+               ndo->ndo_ll_hdr_len += ieee802_11_radio_avs_print(ndo, p, length, caplen);
+               return;
+       }
 
        if (caplen < PRISM_HDR_LEN) {
                nd_print_trunc(ndo);
-               return caplen;
+               ndo->ndo_ll_hdr_len += caplen;
+               return;
        }
 
-       return PRISM_HDR_LEN + ieee802_11_print(ndo, p + PRISM_HDR_LEN,
-           length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
+       p += PRISM_HDR_LEN;
+       length -= PRISM_HDR_LEN;
+       caplen -= PRISM_HDR_LEN;
+       ndo->ndo_ll_hdr_len += PRISM_HDR_LEN;
+       ndo->ndo_ll_hdr_len += ieee802_11_print(ndo, p, length, caplen, 0, 0);
 }
 
 /*
  * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
  * header, containing information such as radio information.
  */
-u_int
+void
 ieee802_11_radio_if_print(netdissect_options *ndo,
                          const struct pcap_pkthdr *h, const u_char *p)
 {
-       ndo->ndo_protocol = "802.11_radio_if";
-       return ieee802_11_radio_print(ndo, p, h->len, h->caplen);
+       ndo->ndo_protocol = "802.11_radio";
+       ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, h->len, h->caplen);
 }
 
 /*
@@ -3503,10 +3570,10 @@ ieee802_11_radio_if_print(netdissect_options *ndo,
  * extra header, containing information such as radio information,
  * which we currently ignore.
  */
-u_int
+void
 ieee802_11_radio_avs_if_print(netdissect_options *ndo,
                              const struct pcap_pkthdr *h, const u_char *p)
 {
-       ndo->ndo_protocol = "802.11_radio_avs_if";
-       return ieee802_11_radio_avs_print(ndo, p, h->len, h->caplen);
+       ndo->ndo_protocol = "802.11_radio_avs";
+       ndo->ndo_ll_hdr_len += ieee802_11_radio_avs_print(ndo, p, h->len, h->caplen);
 }