]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-802_11.c
gre: add support for MikroTik Ethernet-over-IP hack.
[tcpdump] / print-802_11.c
index 0303e2869c92841e051d2caee0c37d28a77e2bd3..ca49e09edca5fda9296ad7061c2bbc9dc9d919a1 100644 (file)
@@ -193,22 +193,22 @@ struct mgmt_header_t {
 #define        CAPABILITY_PRIVACY(cap) ((cap) & 0x0010)
 
 struct ssid_t {
-       uint8_t         length;
+       u_int           length;
        u_char          ssid[33];  /* 32 + 1 for null */
 };
 
 struct rates_t {
-       uint8_t         length;
+       u_int           length;
        uint8_t         rate[16];
 };
 
 struct challenge_t {
-       uint8_t         length;
+       u_int           length;
        uint8_t         text[254]; /* 1-253 + 1 for null */
 };
 
 struct fh_t {
-       uint8_t         length;
+       u_int           length;
        uint16_t        dwell_time;
        uint8_t         hop_set;
        uint8_t hop_pattern;
@@ -216,12 +216,12 @@ struct fh_t {
 };
 
 struct ds_t {
-       uint8_t         length;
+       u_int           length;
        uint8_t         channel;
 };
 
 struct cf_t {
-       uint8_t         length;
+       u_int           length;
        uint8_t         count;
        uint8_t         period;
        uint16_t        max_duration;
@@ -229,13 +229,18 @@ struct cf_t {
 };
 
 struct tim_t {
-       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
@@ -260,6 +265,7 @@ struct tim_t {
 /* reserved            19 */
 /* reserved            16 */
 /* reserved            16 */
+#define E_MESHID       114
 
 
 struct mgmt_body_t {
@@ -287,6 +293,8 @@ 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 {
@@ -362,9 +370,11 @@ struct ctrl_ba_hdr_t {
        nd_uint16_t     fc;
        nd_uint16_t     duration;
        nd_mac_addr     ra;
+       nd_mac_addr     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;
@@ -403,15 +413,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) \
@@ -420,6 +430,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
 
 /*
@@ -942,8 +959,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 */
@@ -990,7 +1007,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 */
@@ -1138,6 +1155,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.
@@ -1148,6 +1166,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. */
@@ -1277,9 +1296,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.
                         *
@@ -1303,10 +1331,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;
@@ -1322,6 +1355,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)  ",
@@ -1375,6 +1432,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:
@@ -1539,6 +1597,7 @@ handle_probe_response(netdissect_options *ndo,
        PRINT_SSID(pbody);
        PRINT_RATES(pbody);
        PRINT_DS_CHANNEL(pbody);
+       PRINT_MESHID(pbody);
 
        return ret;
 trunc:
@@ -2005,8 +2064,9 @@ ctrl_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
                    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_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra),
+                   GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ta));
                break;
        case CTRL_PS_POLL:
                ND_PRINT("BSSID:%s TA:%s ",