X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/24598ce6b7cfe72ada92aed48691fdf092d94fc7..bd00116d80c18b782f4cb15dfc90cd5bf993d4f5:/print-802_11.c diff --git a/print-802_11.c b/print-802_11.c index c94cc0dd..2b4463ec 100644 --- a/print-802_11.c +++ b/print-802_11.c @@ -20,7 +20,6 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -45,8 +44,11 @@ #define IEEE802_11_BSSID_LEN 6 #define IEEE802_11_RA_LEN 6 #define IEEE802_11_TA_LEN 6 +#define IEEE802_11_ADDR1_LEN 6 #define IEEE802_11_SEQ_LEN 2 #define IEEE802_11_CTL_LEN 2 +#define IEEE802_11_CARRIED_FC_LEN 2 +#define IEEE802_11_HT_CONTROL_LEN 4 #define IEEE802_11_IV_LEN 3 #define IEEE802_11_KID_LEN 1 @@ -166,16 +168,16 @@ static const struct tok ctrl_str[] = { #define FC_RETRY(fc) ((fc) & 0x0800) #define FC_POWER_MGMT(fc) ((fc) & 0x1000) #define FC_MORE_DATA(fc) ((fc) & 0x2000) -#define FC_WEP(fc) ((fc) & 0x4000) +#define FC_PROTECTED(fc) ((fc) & 0x4000) #define FC_ORDER(fc) ((fc) & 0x8000) struct mgmt_header_t { - u_int16_t fc; - u_int16_t duration; - u_int8_t da[6]; - u_int8_t sa[6]; - u_int8_t bssid[6]; - u_int16_t seq_ctrl; + uint16_t fc; + uint16_t duration; + uint8_t da[IEEE802_11_DA_LEN]; + uint8_t sa[IEEE802_11_SA_LEN]; + uint8_t bssid[IEEE802_11_BSSID_LEN]; + uint16_t seq_ctrl; }; #define MGMT_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ @@ -189,54 +191,54 @@ struct mgmt_header_t { #define CAPABILITY_PRIVACY(cap) ((cap) & 0x0010) struct ssid_t { - u_int8_t element_id; - u_int8_t length; + uint8_t element_id; + uint8_t length; u_char ssid[33]; /* 32 + 1 for null */ }; struct rates_t { - u_int8_t element_id; - u_int8_t length; - u_int8_t rate[16]; + uint8_t element_id; + uint8_t length; + uint8_t rate[16]; }; struct challenge_t { - u_int8_t element_id; - u_int8_t length; - u_int8_t text[254]; /* 1-253 + 1 for null */ + uint8_t element_id; + uint8_t length; + uint8_t text[254]; /* 1-253 + 1 for null */ }; struct fh_t { - u_int8_t element_id; - u_int8_t length; - u_int16_t dwell_time; - u_int8_t hop_set; - u_int8_t hop_pattern; - u_int8_t hop_index; + uint8_t element_id; + uint8_t length; + uint16_t dwell_time; + uint8_t hop_set; + uint8_t hop_pattern; + uint8_t hop_index; }; struct ds_t { - u_int8_t element_id; - u_int8_t length; - u_int8_t channel; + uint8_t element_id; + uint8_t length; + uint8_t channel; }; struct cf_t { - u_int8_t element_id; - u_int8_t length; - u_int8_t count; - u_int8_t period; - u_int16_t max_duration; - u_int16_t dur_remaing; + uint8_t element_id; + uint8_t length; + uint8_t count; + uint8_t period; + uint16_t max_duration; + uint16_t dur_remaing; }; struct tim_t { - u_int8_t element_id; - u_int8_t length; - u_int8_t count; - u_int8_t period; - u_int8_t bitmap_control; - u_int8_t bitmap[251]; + uint8_t element_id; + uint8_t length; + uint8_t count; + uint8_t period; + uint8_t bitmap_control; + uint8_t bitmap[251]; }; #define E_SSID 0 @@ -266,18 +268,18 @@ struct tim_t { struct mgmt_body_t { - u_int8_t timestamp[IEEE802_11_TSTAMP_LEN]; - u_int16_t beacon_interval; - u_int16_t listen_interval; - u_int16_t status_code; - u_int16_t aid; + uint8_t timestamp[IEEE802_11_TSTAMP_LEN]; + uint16_t beacon_interval; + uint16_t listen_interval; + uint16_t status_code; + uint16_t aid; u_char ap[IEEE802_11_AP_LEN]; - u_int16_t reason_code; - u_int16_t auth_alg; - u_int16_t auth_trans_seq_num; + uint16_t reason_code; + uint16_t auth_alg; + uint16_t auth_trans_seq_num; int challenge_present; struct challenge_t challenge; - u_int16_t capability_info; + uint16_t capability_info; int ssid_present; struct ssid_t ssid; int rates_present; @@ -292,85 +294,90 @@ struct mgmt_body_t { struct tim_t tim; }; -struct ctrl_rts_t { - u_int16_t fc; - u_int16_t duration; - u_int8_t ra[6]; - u_int8_t ta[6]; - u_int8_t fcs[4]; +struct ctrl_control_wrapper_hdr_t { + uint16_t fc; + uint16_t duration; + uint8_t addr1[IEEE802_11_ADDR1_LEN]; + uint16_t carried_fc[IEEE802_11_CARRIED_FC_LEN]; + uint16_t ht_control[IEEE802_11_HT_CONTROL_LEN]; +}; + +#define CTRL_CONTROL_WRAPPER_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ + IEEE802_11_ADDR1_LEN+\ + IEEE802_11_CARRIED_FC_LEN+\ + IEEE802_11_HT_CONTROL_LEN) + +struct ctrl_rts_hdr_t { + uint16_t fc; + uint16_t duration; + uint8_t ra[IEEE802_11_RA_LEN]; + uint8_t ta[IEEE802_11_TA_LEN]; }; #define CTRL_RTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_TA_LEN) -struct ctrl_cts_t { - u_int16_t fc; - u_int16_t duration; - u_int8_t ra[6]; - u_int8_t fcs[4]; +struct ctrl_cts_hdr_t { + uint16_t fc; + uint16_t duration; + uint8_t ra[IEEE802_11_RA_LEN]; }; #define CTRL_CTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) -struct ctrl_ack_t { - u_int16_t fc; - u_int16_t duration; - u_int8_t ra[6]; - u_int8_t fcs[4]; +struct ctrl_ack_hdr_t { + uint16_t fc; + uint16_t duration; + uint8_t ra[IEEE802_11_RA_LEN]; }; #define CTRL_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) -struct ctrl_ps_poll_t { - u_int16_t fc; - u_int16_t aid; - u_int8_t bssid[6]; - u_int8_t ta[6]; - u_int8_t fcs[4]; +struct ctrl_ps_poll_hdr_t { + uint16_t fc; + uint16_t aid; + uint8_t bssid[IEEE802_11_BSSID_LEN]; + uint8_t ta[IEEE802_11_TA_LEN]; }; #define CTRL_PS_POLL_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_AID_LEN+\ IEEE802_11_BSSID_LEN+IEEE802_11_TA_LEN) -struct ctrl_end_t { - u_int16_t fc; - u_int16_t duration; - u_int8_t ra[6]; - u_int8_t bssid[6]; - u_int8_t fcs[4]; +struct ctrl_end_hdr_t { + uint16_t fc; + uint16_t duration; + uint8_t ra[IEEE802_11_RA_LEN]; + uint8_t bssid[IEEE802_11_BSSID_LEN]; }; #define CTRL_END_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN) -struct ctrl_end_ack_t { - u_int16_t fc; - u_int16_t duration; - u_int8_t ra[6]; - u_int8_t bssid[6]; - u_int8_t fcs[4]; +struct ctrl_end_ack_hdr_t { + uint16_t fc; + uint16_t duration; + uint8_t ra[IEEE802_11_RA_LEN]; + uint8_t bssid[IEEE802_11_BSSID_LEN]; }; #define CTRL_END_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN) -struct ctrl_ba_t { - u_int16_t fc; - u_int16_t duration; - u_int8_t ra[6]; - u_int8_t fcs[4]; +struct ctrl_ba_hdr_t { + uint16_t fc; + uint16_t duration; + uint8_t ra[IEEE802_11_RA_LEN]; }; #define CTRL_BA_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) -struct ctrl_bar_t { - u_int16_t fc; - u_int16_t dur; - u_int8_t ra[6]; - u_int8_t ta[6]; - u_int16_t ctl; - u_int16_t seq; - u_int8_t fcs[4]; +struct ctrl_bar_hdr_t { + uint16_t fc; + uint16_t dur; + uint8_t ra[IEEE802_11_RA_LEN]; + uint8_t ta[IEEE802_11_TA_LEN]; + uint16_t ctl; + uint16_t seq; }; #define CTRL_BAR_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ @@ -378,12 +385,12 @@ struct ctrl_bar_t { IEEE802_11_CTL_LEN+IEEE802_11_SEQ_LEN) struct meshcntl_t { - u_int8_t flags; - u_int8_t ttl; - u_int8_t seq[4]; - u_int8_t addr4[6]; - u_int8_t addr5[6]; - u_int8_t addr6[6]; + uint8_t flags; + uint8_t ttl; + uint8_t seq[4]; + uint8_t addr4[6]; + uint8_t addr5[6]; + uint8_t addr6[6]; }; #define IV_IV(iv) ((iv) & 0xFFFFFF) @@ -443,18 +450,18 @@ struct meshcntl_t { * Note well: all radiotap fields are little-endian. */ struct ieee80211_radiotap_header { - u_int8_t it_version; /* Version 0. Only increases + uint8_t it_version; /* Version 0. Only increases * for drastic changes, * introduction of compatible * new fields does not count. */ - u_int8_t it_pad; - u_int16_t it_len; /* length of the whole + uint8_t it_pad; + uint16_t it_len; /* length of the whole * header in bytes, including * it_version, it_pad, * it_len, and data fields. */ - u_int32_t it_present; /* A bitmap telling which + uint32_t it_present; /* A bitmap telling which * fields are present. Set bit 31 * (0x80000000) to extend the * bitmap by another 32 bits. @@ -466,25 +473,25 @@ struct ieee80211_radiotap_header { /* Name Data type Units * ---- --------- ----- * - * IEEE80211_RADIOTAP_TSFT u_int64_t microseconds + * IEEE80211_RADIOTAP_TSFT uint64_t microseconds * * Value in microseconds of the MAC's 64-bit 802.11 Time * Synchronization Function timer when the first bit of the * MPDU arrived at the MAC. For received frames, only. * - * IEEE80211_RADIOTAP_CHANNEL 2 x u_int16_t MHz, bitmap + * IEEE80211_RADIOTAP_CHANNEL 2 x uint16_t MHz, bitmap * * Tx/Rx frequency in MHz, followed by flags (see below). * Note that IEEE80211_RADIOTAP_XCHANNEL must be used to * represent an HT channel as there is not enough room in * the flags word. * - * IEEE80211_RADIOTAP_FHSS u_int16_t see below + * IEEE80211_RADIOTAP_FHSS uint16_t see below * * For frequency-hopping radios, the hop set (first byte) * and pattern (second byte). * - * IEEE80211_RADIOTAP_RATE u_int8_t 500kb/s or index + * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s or index * * Tx/Rx data rate. If bit 0x80 is set then it represents an * an MCS index and not an IEEE rate. @@ -501,30 +508,30 @@ struct ieee80211_radiotap_header { * RF noise power at the antenna, decibel difference from one * milliwatt. * - * IEEE80211_RADIOTAP_DB_ANTSIGNAL u_int8_t decibel (dB) + * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB) * * RF signal power at the antenna, decibel difference from an * arbitrary, fixed reference. * - * IEEE80211_RADIOTAP_DB_ANTNOISE u_int8_t decibel (dB) + * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB) * * RF noise power at the antenna, decibel difference from an * arbitrary, fixed reference point. * - * IEEE80211_RADIOTAP_LOCK_QUALITY u_int16_t unitless + * IEEE80211_RADIOTAP_LOCK_QUALITY uint16_t unitless * * Quality of Barker code lock. Unitless. Monotonically * nondecreasing with "better" lock strength. Called "Signal * Quality" in datasheets. (Is there a standard way to measure * this?) * - * IEEE80211_RADIOTAP_TX_ATTENUATION u_int16_t unitless + * IEEE80211_RADIOTAP_TX_ATTENUATION uint16_t unitless * * Transmit power expressed as unitless distance from max * power set at factory calibration. 0 is max power. * Monotonically nondecreasing with lower power levels. * - * IEEE80211_RADIOTAP_DB_TX_ATTENUATION u_int16_t decibels (dB) + * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t decibels (dB) * * Transmit power expressed as decibel distance from max power * set at factory calibration. 0 is max power. Monotonically @@ -537,24 +544,24 @@ struct ieee80211_radiotap_header { * reference). This is the absolute power level measured at * the antenna port. * - * IEEE80211_RADIOTAP_FLAGS u_int8_t bitmap + * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap * * Properties of transmitted and received frames. See flags * defined below. * - * IEEE80211_RADIOTAP_ANTENNA u_int8_t antenna index + * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index * * Unitless indication of the Rx/Tx antenna for this packet. * The first antenna is antenna 0. * - * IEEE80211_RADIOTAP_RX_FLAGS u_int16_t bitmap + * IEEE80211_RADIOTAP_RX_FLAGS uint16_t bitmap * * Properties of received frames. See flags defined below. * - * IEEE80211_RADIOTAP_XCHANNEL u_int32_t bitmap - * u_int16_t MHz - * u_int8_t channel number - * u_int8_t .5 dBm + * IEEE80211_RADIOTAP_XCHANNEL uint32_t bitmap + * uint16_t MHz + * uint8_t channel number + * uint8_t .5 dBm * * Extended channel specification: flags (see below) followed by * frequency in MHz, the corresponding IEEE channel number, and @@ -562,18 +569,18 @@ struct ieee80211_radiotap_header { * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL * and only one of the two should be present. * - * IEEE80211_RADIOTAP_MCS u_int8_t known - * u_int8_t flags - * u_int8_t mcs + * IEEE80211_RADIOTAP_MCS uint8_t known + * uint8_t flags + * uint8_t mcs * * Bitset indicating which fields have known values, followed * by bitset of flag values, followed by the MCS rate index as * in IEEE 802.11n. * * IEEE80211_RADIOTAP_VENDOR_NAMESPACE - * u_int8_t OUI[3] - * u_int8_t subspace - * u_int16_t length + * uint8_t OUI[3] + * uint8_t subspace + * uint16_t length * * The Vendor Namespace Field contains three sub-fields. The first * sub-field is 3 bytes long. It contains the vendor's IEEE 802 @@ -689,9 +696,9 @@ static const char tstr[] = "[|802.11]"; /* This is used to save state when parsing/processing parameters */ struct radiotap_state { - u_int32_t present; + uint32_t present; - u_int8_t rate; + uint8_t rate; }; #define PRINT_SSID(p) \ @@ -1187,9 +1194,7 @@ static const char *status_text[] = { "The request has not been successful as one or more parameters " "have invalid values", /* 38 */ "The TS has not been created because the request cannot be honored. " - "However, a suggested TSPEC is provided so that the initiating QSTA" - "may attempt to set another TS with the suggested changes to the " - "TSPEC", /* 39 */ + "Try again with the suggested changes to the TSPEC", /* 39 */ "Invalid Information Element", /* 40 */ "Group Cipher is not valid", /* 41 */ "Pairwise Cipher is not valid", /* 42 */ @@ -1279,13 +1284,13 @@ static int wep_print(netdissect_options *ndo, const u_char *p) { - u_int32_t iv; + uint32_t iv; if (!ND_TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN)) return 0; iv = EXTRACT_LE_32BITS(p); - ND_PRINT((ndo, "Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv), + ND_PRINT((ndo, " IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv), IV_KEYID(iv))); return 1; @@ -1315,16 +1320,21 @@ parse_elements(netdissect_options *ndo, pbody->tim_present = 0; while (length != 0) { - if (!ND_TTEST2(*(p + offset), 1)) + /* Make sure we at least have the element ID and length. */ + if (!ND_TTEST2(*(p + offset), 2)) return 0; - if (length < 1) + if (length < 2) return 0; + elementlen = *(p + offset + 1); + + /* Make sure we have the entire element. */ + if (!ND_TTEST2(*(p + offset + 2), elementlen)) + return 0; + if (length < elementlen + 2) + return 0; + switch (*(p + offset)) { case E_SSID: - if (!ND_TTEST2(*(p + offset), 2)) - return 0; - if (length < 2) - return 0; memcpy(&ssid, p + offset, 2); offset += 2; length -= 2; @@ -1353,10 +1363,6 @@ parse_elements(netdissect_options *ndo, } break; case E_CHALLENGE: - if (!ND_TTEST2(*(p + offset), 2)) - return 0; - if (length < 2) - return 0; memcpy(&challenge, p + offset, 2); offset += 2; length -= 2; @@ -1387,10 +1393,6 @@ parse_elements(netdissect_options *ndo, } break; case E_RATES: - if (!ND_TTEST2(*(p + offset), 2)) - return 0; - if (length < 2) - return 0; memcpy(&rates, p + offset, 2); offset += 2; length -= 2; @@ -1427,13 +1429,17 @@ parse_elements(netdissect_options *ndo, } break; case E_DS: - if (!ND_TTEST2(*(p + offset), 3)) - return 0; - if (length < 3) - return 0; - memcpy(&ds, p + offset, 3); - offset += 3; - length -= 3; + memcpy(&ds, p + offset, 2); + offset += 2; + length -= 2; + if (ds.length != 1) { + offset += ds.length; + length -= ds.length; + break; + } + ds.channel = *(p + offset); + offset += 1; + length -= 1; /* * Present and not truncated. * @@ -1447,13 +1453,17 @@ parse_elements(netdissect_options *ndo, } break; case E_CF: - if (!ND_TTEST2(*(p + offset), 8)) - return 0; - if (length < 8) - return 0; - memcpy(&cf, p + offset, 8); - offset += 8; - length -= 8; + memcpy(&cf, p + offset, 2); + offset += 2; + length -= 2; + if (cf.length != 6) { + offset += cf.length; + length -= cf.length; + break; + } + memcpy(&cf.count, p + offset, 6); + offset += 6; + length -= 6; /* * Present and not truncated. * @@ -1467,29 +1477,20 @@ parse_elements(netdissect_options *ndo, } break; case E_TIM: - if (!ND_TTEST2(*(p + offset), 2)) - return 0; - if (length < 2) - return 0; memcpy(&tim, p + offset, 2); offset += 2; length -= 2; - if (!ND_TTEST2(*(p + offset), 3)) - return 0; - if (length < 3) + if (tim.length <= 3) { + offset += tim.length; + length -= tim.length; + break; + } + if (tim.length - 3 > (int)sizeof tim.bitmap) return 0; memcpy(&tim.count, p + offset, 3); offset += 3; length -= 3; - if (tim.length <= 3) - break; - if (tim.length - 3 > (int)sizeof tim.bitmap) - return 0; - if (!ND_TTEST2(*(p + offset), tim.length - 3)) - return 0; - if (length < (u_int)(tim.length - 3)) - return 0; memcpy(tim.bitmap, p + (tim.length - 3), (tim.length - 3)); offset += tim.length - 3; @@ -1511,17 +1512,8 @@ parse_elements(netdissect_options *ndo, ND_PRINT((ndo, "(1) unhandled element_id (%d) ", *(p + offset))); #endif - if (!ND_TTEST2(*(p + offset), 2)) - return 0; - if (length < 2) - return 0; - elementlen = *(p + offset + 1); - if (!ND_TTEST2(*(p + offset + 2), elementlen)) - return 0; - if (length < elementlen + 2) - return 0; - offset += elementlen + 2; - length -= elementlen + 2; + offset += 2 + elementlen; + length -= 2 + elementlen; break; } } @@ -1627,7 +1619,7 @@ handle_assoc_response(netdissect_options *ndo, ret = parse_elements(ndo, &pbody, p, offset, length); - ND_PRINT((ndo, " AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 , + ND_PRINT((ndo, " AID(%x) :%s: %s", ((uint16_t)(pbody.aid << 2 )) >> 2 , CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "", (pbody.status_code < NUM_STATUSES ? status_text[pbody.status_code] @@ -1816,7 +1808,7 @@ handle_auth(netdissect_options *ndo, static int handle_deauth(netdissect_options *ndo, - const struct mgmt_header_t *pmh, const u_char *p, u_int length) + const uint8_t *src, const u_char *p, u_int length) { struct mgmt_body_t pbody; const char *reason = NULL; @@ -1836,7 +1828,7 @@ handle_deauth(netdissect_options *ndo, if (ndo->ndo_eflag) { ND_PRINT((ndo, ": %s", reason)); } else { - ND_PRINT((ndo, " (%s): %s", etheraddr_string(ndo, pmh->sa), reason)); + ND_PRINT((ndo, " (%s): %s", etheraddr_string(ndo, src), reason)); } return 1; } @@ -1901,7 +1893,7 @@ handle_deauth(netdissect_options *ndo, static int handle_action(netdissect_options *ndo, - const struct mgmt_header_t *pmh, const u_char *p, u_int length) + const uint8_t *src, const u_char *p, u_int length) { if (!ND_TTEST2(*p, 2)) return 0; @@ -1910,7 +1902,7 @@ handle_action(netdissect_options *ndo, if (ndo->ndo_eflag) { ND_PRINT((ndo, ": ")); } else { - ND_PRINT((ndo, " (%s): ", etheraddr_string(ndo, pmh->sa))); + ND_PRINT((ndo, " (%s): ", etheraddr_string(ndo, src))); } switch (p[0]) { case 0: ND_PRINT((ndo, "Spectrum Management Act#%d", p[1])); break; @@ -1941,10 +1933,13 @@ handle_action(netdissect_options *ndo, static int mgmt_body_print(netdissect_options *ndo, - u_int16_t fc, const struct mgmt_header_t *pmh, - const u_char *p, u_int length) + uint16_t fc, const uint8_t *src, const u_char *p, u_int length) { ND_PRINT((ndo, "%s", tok2str(st_str, "Unhandled Management subtype(%x)", FC_SUBTYPE(fc)))); + + /* There may be a problem w/ AP not having this bit set */ + if (FC_PROTECTED(fc)) + return wep_print(ndo, p); switch (FC_SUBTYPE(fc)) { case ST_ASSOC_REQUEST: return handle_assoc_request(ndo, p, length); @@ -1965,17 +1960,11 @@ mgmt_body_print(netdissect_options *ndo, case ST_DISASSOC: return handle_disassoc(ndo, p, length); case ST_AUTH: - if (!ND_TTEST2(*p, 3)) - return 0; - if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) { - ND_PRINT((ndo, "Authentication (Shared-Key)-3 ")); - return wep_print(ndo, p); - } return handle_auth(ndo, p, length); case ST_DEAUTH: - return handle_deauth(ndo, pmh, p, length); + return handle_deauth(ndo, src, p, length); case ST_ACTION: - return handle_action(ndo, pmh, p, length); + return handle_action(ndo, src, p, length); default: return 1; } @@ -1988,7 +1977,7 @@ mgmt_body_print(netdissect_options *ndo, static int ctrl_body_print(netdissect_options *ndo, - u_int16_t fc, const u_char *p) + uint16_t fc, const u_char *p) { ND_PRINT((ndo, "%s", tok2str(ctrl_str, "Unknown Ctrl Subtype", FC_SUBTYPE(fc)))); switch (FC_SUBTYPE(fc)) { @@ -2000,67 +1989,63 @@ ctrl_body_print(netdissect_options *ndo, return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " RA:%s TA:%s CTL(%x) SEQ(%u) ", - etheraddr_string(ndo, ((const struct ctrl_bar_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_bar_t *)p)->ta), - EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)), - EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)))); + etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ra), + etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ta), + EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->ctl)), + EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->seq)))); break; case CTRL_BA: if (!ND_TTEST2(*p, CTRL_BA_HDRLEN)) return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ba_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_ba_hdr_t *)p)->ra))); break; case CTRL_PS_POLL: if (!ND_TTEST2(*p, CTRL_PS_POLL_HDRLEN)) return 0; ND_PRINT((ndo, " AID(%x)", - EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)))); + EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_hdr_t *)p)->aid)))); break; case CTRL_RTS: if (!ND_TTEST2(*p, CTRL_RTS_HDRLEN)) return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " TA:%s ", - etheraddr_string(ndo, ((const struct ctrl_rts_t *)p)->ta))); + etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ta))); break; case CTRL_CTS: if (!ND_TTEST2(*p, CTRL_CTS_HDRLEN)) return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_cts_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_cts_hdr_t *)p)->ra))); break; case CTRL_ACK: if (!ND_TTEST2(*p, CTRL_ACK_HDRLEN)) return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ack_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_ack_hdr_t *)p)->ra))); break; case CTRL_CF_END: if (!ND_TTEST2(*p, CTRL_END_HDRLEN)) return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_end_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->ra))); break; case CTRL_END_ACK: if (!ND_TTEST2(*p, CTRL_END_ACK_HDRLEN)) return 0; if (!ndo->ndo_eflag) ND_PRINT((ndo, " RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_end_ack_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->ra))); break; } return 1; } -/* - * Print Header funcs - */ - /* * Data Frame - Address field contents * @@ -2071,10 +2056,55 @@ ctrl_body_print(netdissect_options *ndo, * 1 | 1 | RA | TA | DA | SA */ +/* + * Function to get source and destination MAC addresses for a data frame. + */ static void -data_header_print(netdissect_options *ndo, - u_int16_t fc, const u_char *p, const u_int8_t **srcp, - const u_int8_t **dstp) +get_data_src_dst_mac(uint16_t fc, const u_char *p, const uint8_t **srcp, + const uint8_t **dstp) +{ +#define ADDR1 (p + 4) +#define ADDR2 (p + 10) +#define ADDR3 (p + 16) +#define ADDR4 (p + 24) + + if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { + *srcp = ADDR2; + *dstp = ADDR1; + } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { + *srcp = ADDR3; + *dstp = ADDR1; + } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { + *srcp = ADDR2; + *dstp = ADDR3; + } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { + *srcp = ADDR4; + *dstp = ADDR3; + } + +#undef ADDR1 +#undef ADDR2 +#undef ADDR3 +#undef ADDR4 +} + +static void +get_mgmt_src_dst_mac(const u_char *p, const uint8_t **srcp, const uint8_t **dstp) +{ + const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p; + + if (srcp != NULL) + *srcp = hp->sa; + if (dstp != NULL) + *dstp = hp->da; +} + +/* + * Print Header funcs + */ + +static void +data_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p) { u_int subtype = FC_SUBTYPE(fc); @@ -2101,42 +2131,18 @@ data_header_print(netdissect_options *ndo, #define ADDR4 (p + 24) if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { - if (srcp != NULL) - *srcp = ADDR2; - if (dstp != NULL) - *dstp = ADDR1; - if (!ndo->ndo_eflag) - return; ND_PRINT((ndo, "DA:%s SA:%s BSSID:%s ", etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2), etheraddr_string(ndo, ADDR3))); } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { - if (srcp != NULL) - *srcp = ADDR3; - if (dstp != NULL) - *dstp = ADDR1; - if (!ndo->ndo_eflag) - return; ND_PRINT((ndo, "DA:%s BSSID:%s SA:%s ", etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2), etheraddr_string(ndo, ADDR3))); } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { - if (srcp != NULL) - *srcp = ADDR2; - if (dstp != NULL) - *dstp = ADDR3; - if (!ndo->ndo_eflag) - return; ND_PRINT((ndo, "BSSID:%s SA:%s DA:%s ", etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2), etheraddr_string(ndo, ADDR3))); } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { - if (srcp != NULL) - *srcp = ADDR4; - if (dstp != NULL) - *dstp = ADDR3; - if (!ndo->ndo_eflag) - return; ND_PRINT((ndo, "RA:%s TA:%s DA:%s SA:%s ", etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2), etheraddr_string(ndo, ADDR3), etheraddr_string(ndo, ADDR4))); @@ -2149,84 +2155,67 @@ data_header_print(netdissect_options *ndo, } static void -mgmt_header_print(netdissect_options *ndo, - const u_char *p, const u_int8_t **srcp, const u_int8_t **dstp) +mgmt_header_print(netdissect_options *ndo, const u_char *p) { const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p; - if (srcp != NULL) - *srcp = hp->sa; - if (dstp != NULL) - *dstp = hp->da; - if (!ndo->ndo_eflag) - return; - ND_PRINT((ndo, "BSSID:%s DA:%s SA:%s ", etheraddr_string(ndo, (hp)->bssid), etheraddr_string(ndo, (hp)->da), etheraddr_string(ndo, (hp)->sa))); } static void -ctrl_header_print(netdissect_options *ndo, - u_int16_t fc, const u_char *p, const u_int8_t **srcp, - const u_int8_t **dstp) +ctrl_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p) { - if (srcp != NULL) - *srcp = NULL; - if (dstp != NULL) - *dstp = NULL; - if (!ndo->ndo_eflag) - return; - switch (FC_SUBTYPE(fc)) { case CTRL_BAR: ND_PRINT((ndo, " RA:%s TA:%s CTL(%x) SEQ(%u) ", - etheraddr_string(ndo, ((const struct ctrl_bar_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_bar_t *)p)->ta), - EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)), - EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)))); + etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ra), + etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ta), + EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->ctl)), + EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->seq)))); break; case CTRL_BA: ND_PRINT((ndo, "RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ba_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_ba_hdr_t *)p)->ra))); break; case CTRL_PS_POLL: ND_PRINT((ndo, "BSSID:%s TA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ps_poll_t *)p)->bssid), - etheraddr_string(ndo, ((const struct ctrl_ps_poll_t *)p)->ta))); + etheraddr_string(ndo, ((const struct ctrl_ps_poll_hdr_t *)p)->bssid), + etheraddr_string(ndo, ((const struct ctrl_ps_poll_hdr_t *)p)->ta))); break; case CTRL_RTS: ND_PRINT((ndo, "RA:%s TA:%s ", - etheraddr_string(ndo, ((const struct ctrl_rts_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_rts_t *)p)->ta))); + etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ra), + etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ta))); break; case CTRL_CTS: ND_PRINT((ndo, "RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_cts_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_cts_hdr_t *)p)->ra))); break; case CTRL_ACK: ND_PRINT((ndo, "RA:%s ", - etheraddr_string(ndo, ((const struct ctrl_ack_t *)p)->ra))); + etheraddr_string(ndo, ((const struct ctrl_ack_hdr_t *)p)->ra))); break; case CTRL_CF_END: ND_PRINT((ndo, "RA:%s BSSID:%s ", - etheraddr_string(ndo, ((const struct ctrl_end_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_end_t *)p)->bssid))); + etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->ra), + etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->bssid))); break; case CTRL_END_ACK: ND_PRINT((ndo, "RA:%s BSSID:%s ", - etheraddr_string(ndo, ((const struct ctrl_end_ack_t *)p)->ra), - etheraddr_string(ndo, ((const struct ctrl_end_ack_t *)p)->bssid))); + etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->ra), + etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->bssid))); break; default: - ND_PRINT((ndo, "(H) Unknown Ctrl Subtype")); + /* We shouldn't get here - we should already have quit */ break; } } static int extract_header_length(netdissect_options *ndo, - u_int16_t fc) + uint16_t fc) { int len; @@ -2235,8 +2224,12 @@ extract_header_length(netdissect_options *ndo, return MGMT_HDRLEN; case T_CTRL: switch (FC_SUBTYPE(fc)) { + case CTRL_CONTROL_WRAPPER: + return CTRL_CONTROL_WRAPPER_HDRLEN; case CTRL_BAR: return CTRL_BAR_HDRLEN; + case CTRL_BA: + return CTRL_BA_HDRLEN; case CTRL_PS_POLL: return CTRL_PS_POLL_HDRLEN; case CTRL_RTS: @@ -2250,6 +2243,7 @@ extract_header_length(netdissect_options *ndo, case CTRL_END_ACK: return CTRL_END_ACK_HDRLEN; default: + ND_PRINT((ndo, "unknown 802.11 ctrl frame subtype (%d)", FC_SUBTYPE(fc))); return 0; } case T_DATA: @@ -2258,7 +2252,7 @@ extract_header_length(netdissect_options *ndo, len += 2; return len; default: - ND_PRINT((ndo, "unknown IEEE802.11 frame type (%d)", FC_TYPE(fc))); + ND_PRINT((ndo, "unknown 802.11 frame type (%d)", FC_TYPE(fc))); return 0; } } @@ -2270,15 +2264,12 @@ extract_mesh_header_length(const u_char *p) } /* - * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp" - * to point to the source and destination MAC addresses in any case if - * "srcp" and "dstp" aren't null. + * Print the 802.11 MAC header. */ static void ieee_802_11_hdr_print(netdissect_options *ndo, - u_int16_t fc, const u_char *p, u_int hdrlen, - u_int meshdrlen, const u_int8_t **srcp, - const u_int8_t **dstp) + uint16_t fc, const u_char *p, u_int hdrlen, + u_int meshdrlen) { if (ndo->ndo_vflag) { if (FC_MORE_DATA(fc)) @@ -2291,8 +2282,8 @@ ieee_802_11_hdr_print(netdissect_options *ndo, ND_PRINT((ndo, "Retry ")); if (FC_ORDER(fc)) ND_PRINT((ndo, "Strictly Ordered ")); - if (FC_WEP(fc)) - ND_PRINT((ndo, "WEP Encrypted ")); + if (FC_PROTECTED(fc)) + ND_PRINT((ndo, "Protected ")); if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL) ND_PRINT((ndo, "%dus ", EXTRACT_LE_16BITS( @@ -2316,19 +2307,15 @@ ieee_802_11_hdr_print(netdissect_options *ndo, switch (FC_TYPE(fc)) { case T_MGMT: - mgmt_header_print(ndo, p, srcp, dstp); + mgmt_header_print(ndo, p); break; case T_CTRL: - ctrl_header_print(ndo, fc, p, srcp, dstp); + ctrl_header_print(ndo, fc, p); break; case T_DATA: - data_header_print(ndo, fc, p, srcp, dstp); + data_header_print(ndo, fc, p); break; default: - ND_PRINT((ndo, "(header) unknown IEEE802.11 frame type (%d)", - FC_TYPE(fc))); - *srcp = NULL; - *dstp = NULL; break; } } @@ -2342,10 +2329,10 @@ ieee802_11_print(netdissect_options *ndo, const u_char *p, u_int length, u_int orig_caplen, int pad, u_int fcslen) { - u_int16_t fc; + uint16_t fc; u_int caplen, hdrlen, meshdrlen; - const u_int8_t *src, *dst; - u_short extracted_ethertype; + const uint8_t *src, *dst; + int llc_hdrlen; caplen = orig_caplen; /* Remove FCS, if present */ @@ -2368,6 +2355,10 @@ ieee802_11_print(netdissect_options *ndo, fc = EXTRACT_LE_16BITS(p); hdrlen = extract_header_length(ndo, fc); + if (hdrlen == 0) { + /* Unknown frame type or control frame subtype; quit. */ + return (0); + } if (pad) hdrlen = roundup2(hdrlen, 4); if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA && @@ -2377,13 +2368,13 @@ ieee802_11_print(netdissect_options *ndo, } else meshdrlen = 0; - if (caplen < hdrlen) { ND_PRINT((ndo, "%s", tstr)); return hdrlen; } - ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen, &src, &dst); + if (ndo->ndo_eflag) + ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen); /* * Go past the 802.11 header. @@ -2394,8 +2385,8 @@ ieee802_11_print(netdissect_options *ndo, switch (FC_TYPE(fc)) { case T_MGMT: - if (!mgmt_body_print(ndo, fc, - (const struct mgmt_header_t *)(p - hdrlen), p, length)) { + get_mgmt_src_dst_mac(p - hdrlen, &src, &dst); + if (!mgmt_body_print(ndo, fc, src, p, length)) { ND_PRINT((ndo, "%s", tstr)); return hdrlen; } @@ -2410,30 +2401,29 @@ ieee802_11_print(netdissect_options *ndo, if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc))) return hdrlen; /* no-data frame */ /* There may be a problem w/ AP not having this bit set */ - if (FC_WEP(fc)) { + if (FC_PROTECTED(fc)) { + ND_PRINT((ndo, "Data")); if (!wep_print(ndo, p)) { ND_PRINT((ndo, "%s", tstr)); return hdrlen; } - } else if (llc_print(ndo, p, length, caplen, dst, src, - &extracted_ethertype) == 0) { - /* - * Some kinds of LLC packet we cannot - * handle intelligently - */ - if (!ndo->ndo_eflag) - ieee_802_11_hdr_print(ndo, fc, p - hdrlen, hdrlen, - meshdrlen, NULL, NULL); - if (extracted_ethertype) - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string( - htons(extracted_ethertype)))); - if (!ndo->ndo_suppress_default_print) - ND_DEFAULTPRINT(p, caplen); + } else { + get_data_src_dst_mac(fc, p - hdrlen, &src, &dst); + llc_hdrlen = llc_print(ndo, p, length, caplen, dst, src); + if (llc_hdrlen < 0) { + /* + * Some kinds of LLC packet we cannot + * handle intelligently + */ + if (!ndo->ndo_suppress_default_print) + ND_DEFAULTPRINT(p, caplen); + llc_hdrlen = -llc_hdrlen; + } + hdrlen += llc_hdrlen; } break; default: - ND_PRINT((ndo, "unknown 802.11 frame type (%d)", FC_TYPE(fc))); + /* We shouldn't get here - we should already have quit */ break; } @@ -2514,16 +2504,16 @@ print_chaninfo(netdissect_options *ndo, static int print_radiotap_field(netdissect_options *ndo, - struct cpack_state *s, u_int32_t bit, u_int8_t *flags, - struct radiotap_state *state, u_int32_t presentflags) + struct cpack_state *s, uint32_t bit, uint8_t *flags, + struct radiotap_state *state, uint32_t presentflags) { union { int8_t i8; - u_int8_t u8; + uint8_t u8; int16_t i16; - u_int16_t u16; - u_int32_t u32; - u_int64_t u64; + uint16_t u16; + uint32_t u32; + uint64_t u64; } u, u2, u3, u4; int rc; @@ -2594,9 +2584,9 @@ print_radiotap_field(netdissect_options *ndo, rc = cpack_uint8(s, &u3.u8); break; case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: { - u_int8_t vns[3]; - u_int16_t length; - u_int8_t subspace; + uint8_t vns[3]; + uint16_t length; + uint8_t subspace; if ((cpack_align_and_reserve(s, 2)) == NULL) { rc = -1; @@ -2845,13 +2835,13 @@ ieee802_11_radio_print(netdissect_options *ndo, struct cpack_state cpacker; struct ieee80211_radiotap_header *hdr; - u_int32_t present, next_present; - u_int32_t presentflags = 0; - u_int32_t *presentp, *last_presentp; + uint32_t present, next_present; + uint32_t presentflags = 0; + uint32_t *presentp, *last_presentp; enum ieee80211_radiotap_type bit; int bit0; u_int len; - u_int8_t flags; + uint8_t flags; int pad; u_int fcslen; struct radiotap_state state; @@ -2869,7 +2859,7 @@ ieee802_11_radio_print(netdissect_options *ndo, ND_PRINT((ndo, "%s", tstr)); return caplen; } - cpack_init(&cpacker, (u_int8_t *)hdr, len); /* align against header start */ + cpack_init(&cpacker, (uint8_t *)hdr, len); /* align against header start */ cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */ for (last_presentp = &hdr->it_present; IS_EXTENDED(last_presentp) && @@ -2929,7 +2919,7 @@ static u_int ieee802_11_avs_radio_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) { - u_int32_t caphdr_len; + uint32_t caphdr_len; if (caplen < 8) { ND_PRINT((ndo, "%s", tstr)); @@ -2981,7 +2971,7 @@ prism_if_print(netdissect_options *ndo, { u_int caplen = h->caplen; u_int length = h->len; - u_int32_t msgcode; + uint32_t msgcode; if (caplen < 4) { ND_PRINT((ndo, "%s", tstr));