2 * Routines for Wireless LAN (IEEE 802.11) dissection
3 * Copyright 2000, Axis Communications AB
4 * Inquiries/bugreports should be sent to Johan.Jorgensen@axis.com
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * Copied from README.developer
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 * The following people helped me by pointing out bugs etc. Thank you!
34 * Magnus Hultman-Persson
38 * 09/12/2003 - Added dissection of country information tag
40 * Ritchie<at>tipsybottle.com
42 * 03/22/2004 - Added dissection of RSN IE
43 * Jouni Malinen <jkmaline@cc.hut.fi>
55 #include <epan/bitswap.h>
56 #include <epan/proto.h>
57 #include <epan/packet.h>
58 #include <epan/addr_resolv.h>
59 #include <epan/strutil.h>
60 #include <epan/prefs.h>
61 #include <epan/reassemble.h>
62 #include "packet-ipx.h"
63 #include "packet-llc.h"
64 #include "packet-ieee80211.h"
65 #include <epan/etypes.h>
66 #include <epan/crc32.h>
68 #include <epan/emem.h>
74 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
77 /* Defragment fragmented 802.11 datagrams */
78 static gboolean wlan_defragment = TRUE;
80 /* Check for the presence of the 802.11 FCS */
81 static gboolean wlan_check_fcs = FALSE;
83 /* Ignore the WEP bit; assume packet is decrypted */
84 static gboolean wlan_ignore_wep = FALSE;
86 /* Tables for reassembly of fragments. */
87 static GHashTable *wlan_fragment_table = NULL;
88 static GHashTable *wlan_reassembled_table = NULL;
90 /* Stuff for the WEP decoder */
91 static gint num_wepkeys = 0;
92 static guint8 **wep_keys = NULL;
93 static int *wep_keylens = NULL;
94 static void init_wepkeys(void);
95 static int wep_decrypt(guint8 *buf, guint32 len, int key_override);
96 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len);
97 static int weak_iv(guchar *iv);
98 #define SSWAP(a,b) {guint8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
100 /* #define USE_ENV */
101 /* When this is set, an unlimited number of WEP keys can be set in the
104 WIRESHARK_WEPKEYNUM=##
105 WIRESHARK_WEPKEY1=aa:bb:cc:dd:...
106 WIRESHARK_WEPKEY2=aa:bab:cc:dd:ee:...
108 ... you get the idea.
110 otherwise you're limited to specifying four keys in the preference system.
114 static const char *wep_keystr[] = {NULL, NULL, NULL, NULL};
117 /* ************************************************************************* */
118 /* Miscellaneous Constants */
119 /* ************************************************************************* */
120 #define SHORT_STR 256
122 /* ************************************************************************* */
123 /* Define some very useful macros that are used to analyze frame types etc. */
124 /* ************************************************************************* */
127 * Extract the protocol version from the frame control field
129 #define FCF_PROT_VERSION(x) ((x) & 0x3)
132 * Extract the frame type from the frame control field.
134 #define FCF_FRAME_TYPE(x) (((x) & 0xC) >> 2)
137 * Extract the frame subtype from the frame control field.
139 #define FCF_FRAME_SUBTYPE(x) (((x) & 0xF0) >> 4)
142 * Convert the frame type and subtype from the frame control field into
143 * one of the MGT_, CTRL_, or DATA_ values.
145 #define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+FCF_FRAME_SUBTYPE(x)) /* Create key to (sub)type */
148 * The subtype field of a data frame is, in effect, composed of 4 flag
149 * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have
150 * any data), and QoS.
152 #define DATA_FRAME_IS_CF_ACK(x) ((x) & 0x01)
153 #define DATA_FRAME_IS_CF_POLL(x) ((x) & 0x02)
154 #define DATA_FRAME_IS_NULL(x) ((x) & 0x04)
155 #define DATA_FRAME_IS_QOS(x) ((x) & 0x08)
158 * Extract the flags from the frame control field.
160 #define FCF_FLAGS(x) (((x) & 0xFF00) >> 8)
163 * Bits from the flags field.
165 #define FLAG_TO_DS 0x01
166 #define FLAG_FROM_DS 0x02
167 #define FLAG_MORE_FRAGMENTS 0x04
168 #define FLAG_RETRY 0x08
169 #define FLAG_POWER_MGT 0x10
170 #define FLAG_MORE_DATA 0x20
171 #define FLAG_PROTECTED 0x40
172 #define FLAG_ORDER 0x80
175 * Test bits in the flags field.
177 #define IS_TO_DS(x) ((x) & FLAG_TO_DS)
178 #define IS_FROM_DS(x) ((x) & FLAG_FROM_DS)
179 #define HAVE_FRAGMENTS(x) ((x) & FLAG_MORE_FRAGMENTS)
180 #define IS_RETRY(x) ((x) & FLAG_RETRY)
181 #define POWER_MGT_STATUS(x) ((x) & FLAG_POWER_MGT)
182 #define HAS_MORE_DATA(x) ((x) & FLAG_MORE_DATA)
183 #define IS_PROTECTED(x) (!wlan_ignore_wep && ((x) & FLAG_PROTECTED))
184 #define IS_STRICTLY_ORDERED(x) ((x) & FLAG_ORDER)
187 * Extract subfields from the flags field.
189 #define FLAGS_DS_STATUS(x) ((x) & (FLAG_FROM_DS|FLAG_TO_DS))
192 * Extract an indication of the types of addresses in a data frame from
193 * the frame control field.
195 #define FCF_ADDR_SELECTOR(x) ((x) & ((FLAG_TO_DS|FLAG_FROM_DS) << 8))
197 #define DATA_ADDR_T1 0
198 #define DATA_ADDR_T2 (FLAG_FROM_DS << 8)
199 #define DATA_ADDR_T3 (FLAG_TO_DS << 8)
200 #define DATA_ADDR_T4 ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
203 * Extract the fragment number and sequence number from the sequence
206 #define SEQCTL_FRAGMENT_NUMBER(x) ((x) & 0x000F)
207 #define SEQCTL_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
210 * Extract subfields from the QoS control field.
212 #define QOS_TID(x) ((x) & 0x000F)
213 #define QOS_PRIORITY(x) ((x) & 0x0007)
214 #define QOS_EOSP(x) (((x) & 0x0010) >> 4) /* end of service period */
215 #define QOS_ACK_POLICY(x) (((x) & 0x0060) >> 5)
216 #define QOS_FIELD_CONTENT(x) (((x) & 0xFF00) >> 8)
218 #define QOS_FLAG_EOSP 0x08
221 * Extract subfields from the result of QOS_FIELD_CONTENT().
223 #define QOS_PS_BUF_STATE(x) (((x) & 0x02) >> 1)
224 #define QOS_PS_BUF_AC(x) (((x) & 0x0C) >> 2)
225 #define QOS_PS_BUF_LOAD(x) (((x) & 0xF0) >> 4)
228 * Extract the association ID from the value in an association ID field.
230 #define ASSOC_ID(x) ((x) & 0x3FFF)
233 * Extract subfields from the key octet in WEP-encrypted frames.
235 #define KEY_OCTET_WEP_KEY(x) (((x) & 0xC0) >> 6)
237 #define KEY_EXTIV 0x20
241 /* ************************************************************************* */
242 /* Constants used to identify cooked frame types */
243 /* ************************************************************************* */
244 #define MGT_FRAME 0x00 /* Frame type is management */
245 #define CONTROL_FRAME 0x01 /* Frame type is control */
246 #define DATA_FRAME 0x02 /* Frame type is Data */
248 #define DATA_SHORT_HDR_LEN 24
249 #define DATA_LONG_HDR_LEN 30
250 #define MGT_FRAME_HDR_LEN 24 /* Length of Managment frame-headers */
253 * COMPOSE_FRAME_TYPE() values for management frames.
255 #define MGT_ASSOC_REQ 0x00 /* association request */
256 #define MGT_ASSOC_RESP 0x01 /* association response */
257 #define MGT_REASSOC_REQ 0x02 /* reassociation request */
258 #define MGT_REASSOC_RESP 0x03 /* reassociation response */
259 #define MGT_PROBE_REQ 0x04 /* Probe request */
260 #define MGT_PROBE_RESP 0x05 /* Probe response */
261 #define MGT_BEACON 0x08 /* Beacon frame */
262 #define MGT_ATIM 0x09 /* ATIM */
263 #define MGT_DISASS 0x0A /* Disassociation */
264 #define MGT_AUTHENTICATION 0x0B /* Authentication */
265 #define MGT_DEAUTHENTICATION 0x0C /* Deauthentication */
266 #define MGT_ACTION 0x0D /* Action */
269 * COMPOSE_FRAME_TYPE() values for control frames.
271 #define CTRL_BLOCK_ACK_REQ 0x18 /* Block ack Request */
272 #define CTRL_BLOCK_ACK 0x19 /* Block ack */
273 #define CTRL_PS_POLL 0x1A /* power-save poll */
274 #define CTRL_RTS 0x1B /* request to send */
275 #define CTRL_CTS 0x1C /* clear to send */
276 #define CTRL_ACKNOWLEDGEMENT 0x1D /* acknowledgement */
277 #define CTRL_CFP_END 0x1E /* contention-free period end */
278 #define CTRL_CFP_ENDACK 0x1F /* contention-free period end/ack */
281 * COMPOSE_FRAME_TYPE() values for data frames.
283 #define DATA 0x20 /* Data */
284 #define DATA_CF_ACK 0x21 /* Data + CF-Ack */
285 #define DATA_CF_POLL 0x22 /* Data + CF-Poll */
286 #define DATA_CF_ACK_POLL 0x23 /* Data + CF-Ack + CF-Poll */
287 #define DATA_NULL_FUNCTION 0x24 /* Null function (no data) */
288 #define DATA_CF_ACK_NOD 0x25 /* CF-Ack (no data) */
289 #define DATA_CF_POLL_NOD 0x26 /* CF-Poll (No data) */
290 #define DATA_CF_ACK_POLL_NOD 0x27 /* CF-Ack + CF-Poll (no data) */
292 #define DATA_QOS_DATA 0x28 /* QoS Data */
293 #define DATA_QOS_DATA_CF_ACK 0x29 /* QoS Data + CF-Ack */
294 #define DATA_QOS_DATA_CF_POLL 0x2A /* QoS Data + CF-Poll */
295 #define DATA_QOS_DATA_CF_ACK_POLL 0x2B /* QoS Data + CF-Ack + CF-Poll */
296 #define DATA_QOS_NULL 0x2C /* QoS Null */
297 #define DATA_QOS_CF_POLL_NOD 0x2E /* QoS CF-Poll (No Data) */
298 #define DATA_QOS_CF_ACK_POLL_NOD 0x2F /* QoS CF-Ack + CF-Poll (No Data) */
301 /* ************************************************************************* */
302 /* Macros used to extract information about fixed fields */
303 /* ************************************************************************* */
304 #define ESS_SET(x) ((x) & 0x0001)
305 #define IBSS_SET(x) ((x) & 0x0002)
309 /* ************************************************************************* */
310 /* Logical field codes (dissector's encoding of fixed fields) */
311 /* ************************************************************************* */
312 #define FIELD_TIMESTAMP 0x01 /* 64-bit timestamp */
313 #define FIELD_BEACON_INTERVAL 0x02 /* 16-bit beacon interval */
314 #define FIELD_CAP_INFO 0x03 /* Add capability information tree */
315 #define FIELD_AUTH_ALG 0x04 /* Authentication algorithm used */
316 #define FIELD_AUTH_TRANS_SEQ 0x05 /* Authentication sequence number */
317 #define FIELD_CURRENT_AP_ADDR 0x06
318 #define FIELD_LISTEN_IVAL 0x07
319 #define FIELD_REASON_CODE 0x08
320 #define FIELD_ASSOC_ID 0x09
321 #define FIELD_STATUS_CODE 0x0A
322 #define FIELD_CATEGORY_CODE 0x0B /* Management action category */
323 #define FIELD_ACTION_CODE 0x0C /* Management action code */
324 #define FIELD_DIALOG_TOKEN 0x0D /* Management action dialog token */
325 #define FIELD_WME_ACTION_CODE 0x0E /* Management notification action code */
326 #define FIELD_WME_DIALOG_TOKEN 0x0F /* Management notification dialog token */
327 #define FIELD_WME_STATUS_CODE 0x10 /* Management notification setup response status code */
329 /* ************************************************************************* */
330 /* Logical field codes (IEEE 802.11 encoding of tags) */
331 /* ************************************************************************* */
332 #define TAG_SSID 0x00
333 #define TAG_SUPP_RATES 0x01
334 #define TAG_FH_PARAMETER 0x02
335 #define TAG_DS_PARAMETER 0x03
336 #define TAG_CF_PARAMETER 0x04
338 #define TAG_IBSS_PARAMETER 0x06
339 #define TAG_COUNTRY_INFO 0x07
340 #define TAG_FH_HOPPING_PARAMETER 0x08
341 #define TAG_FH_HOPPING_TABLE 0x09
342 #define TAG_REQUEST 0x0A
343 #define TAG_QBSS_LOAD 0x0B
344 #define TAG_EDCA_PARAM_SET 0x0C
345 #define TAG_TRAF_SPEC 0x0D
346 #define TAG_TRAF_CLASS 0x0E
347 #define TAG_SCHEDULE 0x0F
348 #define TAG_CHALLENGE_TEXT 0x10
349 #define TAG_POWER_CONSTRAINT 0x20
350 #define TAG_POWER_CAPABILITY 0x21
351 #define TAG_TPC_REQUEST 0x22
352 #define TAG_TPC_REPORT 0x23
353 #define TAG_SUPPORTED_CHANNELS 0x24
354 #define TAG_CHANNEL_SWITCH_ANN 0x25
355 #define TAG_MEASURE_REQ 0x26
356 #define TAG_MEASURE_REP 0x27
357 #define TAG_QUIET 0x28
358 #define TAG_IBSS_DFS 0x29
359 #define TAG_ERP_INFO 0x2A
360 #define TAG_TS_DELAY 0x2B
361 #define TAG_TCLAS_PROCESS 0x2C
362 #define TAG_QOS_CAPABILITY 0x2E
363 #define TAG_ERP_INFO_OLD 0x2F /* IEEE Std 802.11g/D4.0 */
364 #define TAG_RSN_IE 0x30
365 #define TAG_EXT_SUPP_RATES 0x32
366 #define TAG_AGERE_PROPRIETARY 0x80
367 #define TAG_CISCO_UNKNOWN_1 0x85 /* Cisco Compatible eXtensions? */
368 #define TAG_CISCO_UNKNOWN_2 0x88 /* Cisco Compatible eXtensions? */
369 #define TAG_VENDOR_SPECIFIC_IE 0xDD
370 #define TAG_SYMBOL_PROPRIETARY 0xAD
372 #define WPA_OUI "\x00\x50\xF2"
373 #define RSN_OUI "\x00\x0F\xAC"
374 #define WME_OUI "\x00\x50\xF2"
378 /* ************************************************************************* */
379 /* Frame types, and their names */
380 /* ************************************************************************* */
381 static const value_string frame_type_subtype_vals[] = {
382 {MGT_ASSOC_REQ, "Association Request"},
383 {MGT_ASSOC_RESP, "Association Response"},
384 {MGT_REASSOC_REQ, "Reassociation Request"},
385 {MGT_REASSOC_RESP, "Reassociation Response"},
386 {MGT_PROBE_REQ, "Probe Request"},
387 {MGT_PROBE_RESP, "Probe Response"},
388 {MGT_BEACON, "Beacon frame"},
390 {MGT_DISASS, "Dissassociate"},
391 {MGT_AUTHENTICATION, "Authentication"},
392 {MGT_DEAUTHENTICATION, "Deauthentication"},
393 {MGT_ACTION, "Action"},
395 {CTRL_BLOCK_ACK_REQ, "802.11 Block Ack Req"},
396 {CTRL_BLOCK_ACK, "802.11 Block Ack"},
397 {CTRL_PS_POLL, "Power-Save poll"},
398 {CTRL_RTS, "Request-to-send"},
399 {CTRL_CTS, "Clear-to-send"},
400 {CTRL_ACKNOWLEDGEMENT, "Acknowledgement"},
401 {CTRL_CFP_END, "CF-End (Control-frame)"},
402 {CTRL_CFP_ENDACK, "CF-End + CF-Ack (Control-frame)"},
405 {DATA_CF_ACK, "Data + CF-Ack"},
406 {DATA_CF_POLL, "Data + CF-Poll"},
407 {DATA_CF_ACK_POLL, "Data + CF-Ack + CF-Poll"},
408 {DATA_NULL_FUNCTION, "Null function (No data)"},
409 {DATA_CF_ACK_NOD, "Acknowledgement (No data)"},
410 {DATA_CF_POLL_NOD, "CF-Poll (No data)"},
411 {DATA_CF_ACK_POLL_NOD, "CF-Ack/Poll (No data)"},
412 {DATA_QOS_DATA, "QoS Data"},
413 {DATA_QOS_DATA_CF_ACK, "QoS Data + CF-Acknowledgment"},
414 {DATA_QOS_DATA_CF_POLL, "QoS Data + CF-Poll"},
415 {DATA_QOS_DATA_CF_ACK_POLL, "QoS Data + CF-Ack + CF-Poll"},
416 {DATA_QOS_NULL, "QoS Null function (No data)"},
417 {DATA_QOS_CF_POLL_NOD, "QoS CF-Poll (No Data)"},
418 {DATA_QOS_CF_ACK_POLL_NOD, "QoS CF-Ack + CF-Poll (No data)"},
422 /* ************************************************************************* */
423 /* 802.1D Tag Names */
424 /* ************************************************************************* */
425 static const char *qos_tags[8] = {
436 /* ************************************************************************* */
437 /* WME Access Category Names (by 802.1D Tag) */
438 /* ************************************************************************* */
439 static const char *qos_acs[8] = {
450 /* ************************************************************************* */
451 /* WME Access Category Names (by WME ACI) */
452 /* ************************************************************************* */
453 static const char *wme_acs[4] = {
461 #define CAT_SPECTRUM_MGMT 0
464 #define CAT_BLOCK_ACK 3
465 #define CAT_MGMT_NOTIFICATION 17
467 #define SM_ACTION_MEASUREMENT_REQUEST 0
468 #define SM_ACTION_MEASUREMENT_REPORT 1
469 #define SM_ACTION_TPC_REQUEST 2
470 #define SM_ACTION_TPC_REPORT 3
471 #define SM_ACTION_CHAN_SWITCH_ANNC 4
473 static int proto_wlan = -1;
474 static packet_info * g_pinfo;
476 /* ************************************************************************* */
477 /* Header field info values for radio information */
478 /* ************************************************************************* */
479 static int hf_data_rate = -1;
480 static int hf_channel = -1;
481 static int hf_signal_strength = -1;
483 /* ************************************************************************* */
484 /* Header field info values for FC-field */
485 /* ************************************************************************* */
486 static int hf_fc_field = -1;
487 static int hf_fc_proto_version = -1;
488 static int hf_fc_frame_type = -1;
489 static int hf_fc_frame_subtype = -1;
490 static int hf_fc_frame_type_subtype = -1;
492 static int hf_fc_flags = -1;
493 static int hf_fc_to_ds = -1;
494 static int hf_fc_from_ds = -1;
495 static int hf_fc_data_ds = -1;
497 static int hf_fc_more_frag = -1;
498 static int hf_fc_retry = -1;
499 static int hf_fc_pwr_mgt = -1;
500 static int hf_fc_more_data = -1;
501 static int hf_fc_protected = -1;
502 static int hf_fc_order = -1;
505 /* ************************************************************************* */
506 /* Header values for Duration/ID field */
507 /* ************************************************************************* */
508 static int hf_did_duration = -1;
509 static int hf_assoc_id = -1;
512 /* ************************************************************************* */
513 /* Header values for different address-fields (all 4 of them) */
514 /* ************************************************************************* */
515 static int hf_addr_da = -1; /* Destination address subfield */
516 static int hf_addr_sa = -1; /* Source address subfield */
517 static int hf_addr_ra = -1; /* Receiver address subfield */
518 static int hf_addr_ta = -1; /* Transmitter address subfield */
519 static int hf_addr_bssid = -1; /* address is bssid */
521 static int hf_addr = -1; /* Source or destination address subfield */
524 /* ************************************************************************* */
525 /* Header values for QoS control field */
526 /* ************************************************************************* */
527 static int hf_qos_priority = -1;
528 static int hf_qos_ack_policy = -1;
529 static int hf_qos_eosp = -1;
530 static int hf_qos_field_content = -1;
531 /*static int hf_qos_txop_limit = -1;*/
532 /* FIXME: hf_ values not defined
533 static int hf_qos_buf_state = -1;
534 static int hf_qos_buf_ac = -1;
535 static int hf_qos_buf_load = -1;
537 /*static int hf_qos_txop_dur_req = -1;
538 static int hf_qos_queue_size = -1;*/
540 /* ************************************************************************* */
541 /* Header values for sequence number field */
542 /* ************************************************************************* */
543 static int hf_frag_number = -1;
544 static int hf_seq_number = -1;
546 /* ************************************************************************* */
547 /* Header values for Frame Check field */
548 /* ************************************************************************* */
549 static int hf_fcs = -1;
551 /* ************************************************************************* */
552 /* Header values for reassembly */
553 /* ************************************************************************* */
554 static int hf_fragments = -1;
555 static int hf_fragment = -1;
556 static int hf_fragment_overlap = -1;
557 static int hf_fragment_overlap_conflict = -1;
558 static int hf_fragment_multiple_tails = -1;
559 static int hf_fragment_too_long_fragment = -1;
560 static int hf_fragment_error = -1;
561 static int hf_reassembled_in = -1;
564 static int proto_wlan_mgt = -1;
565 /* ************************************************************************* */
566 /* Fixed fields found in mgt frames */
567 /* ************************************************************************* */
568 static int ff_auth_alg = -1; /* Authentication algorithm field */
569 static int ff_auth_seq = -1; /* Authentication transaction sequence */
570 static int ff_current_ap = -1; /* Current AP MAC address */
571 static int ff_listen_ival = -1; /* Listen interval fixed field */
572 static int ff_timestamp = -1; /* 64 bit timestamp */
573 static int ff_beacon_interval = -1; /* 16 bit Beacon interval */
574 static int ff_assoc_id = -1; /* 16 bit AID field */
575 static int ff_reason = -1; /* 16 bit reason code */
576 static int ff_status_code = -1; /* Status code */
577 static int ff_category_code = -1; /* 8 bit Category code */
578 static int ff_action_code = -1; /* 8 bit Action code */
579 static int ff_dialog_token = -1; /* 8 bit Dialog token */
580 static int ff_wme_action_code = -1; /* Management notification action code */
581 static int ff_wme_status_code = -1; /* Management notification setup response status code */
583 /* ************************************************************************* */
584 /* Flags found in the capability field (fixed field) */
585 /* ************************************************************************* */
586 static int ff_capture = -1;
587 static int ff_cf_ess = -1;
588 static int ff_cf_ibss = -1;
589 static int ff_cf_sta_poll = -1; /* CF pollable status for a STA */
590 static int ff_cf_ap_poll = -1; /* CF pollable status for an AP */
591 static int ff_cf_privacy = -1;
592 static int ff_cf_preamble = -1;
593 static int ff_cf_pbcc = -1;
594 static int ff_cf_agility = -1;
595 static int ff_short_slot_time = -1;
596 static int ff_dsss_ofdm = -1;
597 static int ff_cf_spec_man = -1;
598 static int ff_cf_apsd = -1;
599 static int ff_cf_del_blk_ack = -1;
600 static int ff_cf_imm_blk_ack = -1;
602 /* ************************************************************************* */
603 /* Tagged value format fields */
604 /* ************************************************************************* */
605 static int tag_number = -1;
606 static int tag_length = -1;
607 static int tag_interpretation = -1;
608 static int tag_oui = -1;
611 static int tim_length = -1;
612 static int tim_dtim_count = -1;
613 static int tim_dtim_period = -1;
614 static int tim_bmapctl = -1;
617 static int hf_fixed_parameters = -1; /* Protocol payload for management frames */
618 static int hf_tagged_parameters = -1; /* Fixed payload item */
619 static int hf_wep_iv = -1;
620 static int hf_wep_iv_weak = -1;
621 static int hf_tkip_extiv = -1;
622 static int hf_ccmp_extiv = -1;
623 static int hf_wep_key = -1;
624 static int hf_wep_icv = -1;
627 static int rsn_cap = -1;
628 static int rsn_cap_preauth = -1;
629 static int rsn_cap_no_pairwise = -1;
630 static int rsn_cap_ptksa_replay_counter = -1;
631 static int rsn_cap_gtksa_replay_counter = -1;
633 static int hf_aironet_ie_type = -1;
634 static int hf_aironet_ie_version = -1;
635 static int hf_aironet_ie_data = -1;
636 static int hf_aironet_ie_qos_unk1 = -1;
637 static int hf_aironet_ie_qos_paramset = -1;
638 static int hf_aironet_ie_qos_val = -1;
640 /*QBSS - Version 1,2,802.11e*/
642 static int hf_qbss2_cal = -1;
643 static int hf_qbss2_gl = -1;
644 static int hf_qbss_cu = -1;
645 static int hf_qbss2_cu = -1;
646 static int hf_qbss_scount = -1;
647 static int hf_qbss2_scount = -1;
648 static int hf_qbss_version = -1;
649 static int hf_qbss_adc = -1;
651 /* ************************************************************************* */
653 /* ************************************************************************* */
654 static gint ett_80211 = -1;
655 static gint ett_proto_flags = -1;
656 static gint ett_cap_tree = -1;
657 static gint ett_fc_tree = -1;
658 static gint ett_fragments = -1;
659 static gint ett_fragment = -1;
661 static gint ett_80211_mgt = -1;
662 static gint ett_fixed_parameters = -1;
663 static gint ett_tagged_parameters = -1;
664 static gint ett_qos_parameters = -1;
665 static gint ett_qos_ps_buf_state = -1;
666 static gint ett_wep_parameters = -1;
668 static gint ett_rsn_cap_tree = -1;
670 static gint ett_80211_mgt_ie = -1;
672 static const fragment_items frag_items = {
677 &hf_fragment_overlap,
678 &hf_fragment_overlap_conflict,
679 &hf_fragment_multiple_tails,
680 &hf_fragment_too_long_fragment,
686 static dissector_handle_t llc_handle;
687 static dissector_handle_t ipx_handle;
688 static dissector_handle_t eth_withoutfcs_handle;
689 static dissector_handle_t data_handle;
691 static int wlan_tap = -1;
693 /* ************************************************************************* */
694 /* Return the length of the current header (in bytes) */
695 /* ************************************************************************* */
697 find_header_length (guint16 fcf)
701 switch (FCF_FRAME_TYPE (fcf)) {
704 return MGT_FRAME_HDR_LEN;
707 switch (COMPOSE_FRAME_TYPE (fcf)) {
710 case CTRL_ACKNOWLEDGEMENT:
716 case CTRL_CFP_ENDACK:
717 case CTRL_BLOCK_ACK_REQ:
724 len = (FCF_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
726 if (DATA_FRAME_IS_QOS(COMPOSE_FRAME_TYPE(fcf)))
737 /* ************************************************************************* */
738 /* This is the capture function used to update packet counts */
739 /* ************************************************************************* */
741 capture_ieee80211_common (const guchar * pd, int offset, int len,
742 packet_counts * ld, gboolean fixed_length_header,
745 guint16 fcf, hdr_length;
747 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
752 fcf = pletohs (&pd[offset]);
754 if (IS_PROTECTED(FCF_FLAGS(fcf)))
760 switch (COMPOSE_FRAME_TYPE (fcf))
763 case DATA: /* We got a data frame */
764 case DATA_CF_ACK: /* Data with ACK */
766 case DATA_CF_ACK_POLL:
768 if (fixed_length_header)
769 hdr_length = DATA_LONG_HDR_LEN;
771 hdr_length = find_header_length (fcf);
773 hdr_length = roundup2(hdr_length, 4);
774 /* I guess some bridges take Netware Ethernet_802_3 frames,
775 which are 802.3 frames (with a length field rather than
776 a type field, but with no 802.2 header in the payload),
777 and just stick the payload into an 802.11 frame. I've seen
778 captures that show frames of that sort.
780 This means we have to do the same check for Netware 802.3 -
781 or, if you will, "Netware 802.11" - that we do in the
782 Ethernet dissector, i.e. checking for 0xffff as the first
783 four bytes of the payload and, if we find it, treating it
785 if (!BYTES_ARE_IN_FRAME(offset+hdr_length, len, 2)) {
789 if (pd[offset+hdr_length] == 0xff && pd[offset+hdr_length+1] == 0xff) {
793 capture_llc (pd, offset + hdr_length, len, ld);
804 * Handle 802.11 with a variable-length link-layer header.
807 capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
809 capture_ieee80211_common (pd, offset, len, ld, FALSE, FALSE);
813 * Handle 802.11 with a variable-length link-layer header and data padding.
816 capture_ieee80211_datapad (const guchar * pd, int offset, int len,
819 capture_ieee80211_common (pd, offset, len, ld, FALSE, TRUE);
823 * Handle 802.11 with a fixed-length link-layer header (padded to the
827 capture_ieee80211_fixed (const guchar * pd, int offset, int len, packet_counts * ld)
829 capture_ieee80211_common (pd, offset, len, ld, TRUE, FALSE);
833 /* ************************************************************************* */
834 /* Add the subtree used to store the fixed parameters */
835 /* ************************************************************************* */
837 get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
839 proto_item *fixed_fields;
841 proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
842 size, size, "Fixed parameters (%d bytes)",
845 return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
849 /* ************************************************************************* */
850 /* Add the subtree used to store tagged parameters */
851 /* ************************************************************************* */
853 get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
855 proto_item *tagged_fields;
857 tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
862 "Tagged parameters (%d bytes)",
865 return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
869 /* ************************************************************************* */
870 /* Dissect and add fixed mgmt fields to protocol tree */
871 /* ************************************************************************* */
873 add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
875 const guint8 *dataptr;
876 char out_buff[SHORT_STR];
878 proto_item *cap_item;
879 static proto_tree *cap_tree;
884 case FIELD_TIMESTAMP:
885 dataptr = tvb_get_ptr (tvb, offset, 8);
886 memset (out_buff, 0, SHORT_STR);
887 g_snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
897 proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
900 case FIELD_BEACON_INTERVAL:
901 capability = tvb_get_letohs (tvb, offset);
902 temp_double = (double)capability;
903 temp_double = temp_double * 1024 / 1000000;
904 proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
905 temp_double,"Beacon Interval: %f [Seconds]",
907 if (check_col (g_pinfo->cinfo, COL_INFO)) {
908 col_append_fstr(g_pinfo->cinfo, COL_INFO, ",BI=%d", capability);
914 capability = tvb_get_letohs (tvb, offset);
916 cap_item = proto_tree_add_uint_format (tree, ff_capture,
919 "Capability Information: 0x%04X",
921 cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree);
922 proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 2,
924 proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 2,
926 if (ESS_SET (capability) != 0) /* This is an AP */
927 proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2,
930 else /* This is a STA */
931 proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
933 proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 2,
935 proto_tree_add_boolean (cap_tree, ff_cf_preamble, tvb, offset, 2,
937 proto_tree_add_boolean (cap_tree, ff_cf_pbcc, tvb, offset, 2,
939 proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 2,
941 proto_tree_add_boolean (cap_tree, ff_cf_spec_man, tvb, offset, 2,
943 proto_tree_add_boolean (cap_tree, ff_short_slot_time, tvb, offset, 2,
945 proto_tree_add_boolean (cap_tree, ff_cf_apsd, tvb, offset, 2,
947 proto_tree_add_boolean (cap_tree, ff_dsss_ofdm, tvb, offset, 2,
949 proto_tree_add_boolean (cap_tree, ff_cf_del_blk_ack, tvb, offset, 2,
951 proto_tree_add_boolean (cap_tree, ff_cf_imm_blk_ack, tvb, offset, 2,
956 proto_tree_add_item (tree, ff_auth_alg, tvb, offset, 2, TRUE);
959 case FIELD_AUTH_TRANS_SEQ:
960 proto_tree_add_item (tree, ff_auth_seq, tvb, offset, 2, TRUE);
963 case FIELD_CURRENT_AP_ADDR:
964 proto_tree_add_item (tree, ff_current_ap, tvb, offset, 6, FALSE);
967 case FIELD_LISTEN_IVAL:
968 proto_tree_add_item (tree, ff_listen_ival, tvb, offset, 2, TRUE);
971 case FIELD_REASON_CODE:
972 proto_tree_add_item (tree, ff_reason, tvb, offset, 2, TRUE);
976 proto_tree_add_uint(tree, ff_assoc_id, tvb, offset, 2,
977 ASSOC_ID(tvb_get_letohs(tvb,offset)));
978 /* proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE); */
981 case FIELD_STATUS_CODE:
982 proto_tree_add_item (tree, ff_status_code, tvb, offset, 2, TRUE);
985 case FIELD_CATEGORY_CODE:
986 proto_tree_add_item (tree, ff_category_code, tvb, offset, 1, TRUE);
989 case FIELD_ACTION_CODE:
990 proto_tree_add_item (tree, ff_action_code, tvb, offset, 1, TRUE);
993 case FIELD_DIALOG_TOKEN:
994 proto_tree_add_item (tree, ff_dialog_token, tvb, offset, 1, TRUE);
997 case FIELD_WME_ACTION_CODE:
998 proto_tree_add_item (tree, ff_wme_action_code, tvb, offset, 1, TRUE);
1001 case FIELD_WME_STATUS_CODE:
1002 proto_tree_add_item (tree, ff_wme_status_code, tvb, offset, 1, TRUE);
1007 static const char *wpa_cipher_str[] =
1018 wpa_cipher_idx2str(guint idx)
1020 if (idx < sizeof(wpa_cipher_str)/sizeof(wpa_cipher_str[0]))
1021 return wpa_cipher_str[idx];
1025 static const char *wpa_keymgmt_str[] =
1033 wpa_keymgmt_idx2str(guint idx)
1035 if (idx < sizeof(wpa_keymgmt_str)/sizeof(wpa_keymgmt_str[0]))
1036 return wpa_keymgmt_str[idx];
1041 dissect_vendor_ie_wpawme(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
1042 int offset, guint32 tag_len, const guint8 *tag_val)
1044 guint32 tag_val_off = 0;
1045 char out_buff[SHORT_STR];
1048 /* Wi-Fi Protected Access (WPA) Information Element */
1049 if (tag_val_off + 6 <= tag_len && !memcmp(tag_val, WPA_OUI"\x01", 4)) {
1050 g_snprintf(out_buff, SHORT_STR, "WPA IE, type %u, version %u",
1051 tag_val[tag_val_off + 3], pletohs(&tag_val[tag_val_off + 4]));
1052 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
1055 if (tag_val_off + 4 <= tag_len) {
1056 /* multicast cipher suite */
1057 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
1058 g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
1059 wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1060 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1063 /* unicast cipher suites */
1064 if (tag_val_off + 2 <= tag_len) {
1065 g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u",
1066 pletohs(tag_val + tag_val_off));
1067 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1071 while (tag_val_off + 4 <= tag_len) {
1072 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
1073 g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
1074 i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1075 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1083 /* authenticated key management suites */
1084 if (tag_val_off + 2 <= tag_len) {
1085 g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u",
1086 pletohs(tag_val + tag_val_off));
1087 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1091 while (tag_val_off + 4 <= tag_len) {
1092 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
1093 g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
1094 i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
1095 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1107 if (tag_val_off < tag_len)
1108 proto_tree_add_string(tree, tag_interpretation, tvb,
1109 offset, tag_len - tag_val_off, "Not interpreted");
1110 proto_item_append_text(ietree, ": WPA");
1111 } else if (tag_val_off + 7 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x00", 5)) {
1112 /* Wireless Multimedia Enhancements (WME) Information Element */
1113 g_snprintf(out_buff, SHORT_STR, "WME IE: type %u, subtype %u, version %u, parameter set %u",
1114 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
1115 tag_val[tag_val_off + 6]);
1116 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
1117 proto_item_append_text(ietree, ": WME");
1118 } else if (tag_val_off + 24 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x01", 5)) {
1119 /* Wireless Multimedia Enhancements (WME) Parameter Element */
1120 g_snprintf(out_buff, SHORT_STR, "WME PE: type %u, subtype %u, version %u, parameter set %u",
1121 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
1122 tag_val[tag_val_off + 6]);
1123 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
1126 for (i = 0; i < 4; i++) {
1127 g_snprintf(out_buff, SHORT_STR, "WME AC Parameters: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
1128 (tag_val[tag_val_off] & 0x60) >> 5,
1129 wme_acs[(tag_val[tag_val_off] & 0x60) >> 5],
1130 (tag_val[tag_val_off] & 0x10) ? "" : "not ",
1131 tag_val[tag_val_off] & 0x0f,
1132 tag_val[tag_val_off + 1] & 0x0f,
1133 (tag_val[tag_val_off + 1] & 0xf0) >> 4,
1134 tvb_get_letohs(tvb, offset + 2));
1135 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1139 proto_item_append_text(ietree, ": WME");
1140 } else if (tag_val_off + 56 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x02", 5)) {
1141 /* Wireless Multimedia Enhancements (WME) TSPEC Element */
1142 guint16 ts_info, msdu_size, surplus_bandwidth;
1143 const char *direction[] = { "Uplink", "Downlink", "Reserved", "Bi-directional" };
1144 const value_string fields[] = {
1145 {12, "Minimum Service Interval"},
1146 {16, "Maximum Service Interval"},
1147 {20, "Inactivity Interval"},
1148 {24, "Service Start Time"},
1149 {28, "Minimum Data Rate"},
1150 {32, "Mean Data Rate"},
1151 {36, "Maximum Burst Size"},
1152 {40, "Minimum PHY Rate"},
1153 {44, "Peak Data Rate"},
1154 {48, "Delay Bound"},
1159 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: type %u, subtype %u, version %u",
1160 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5]);
1161 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
1165 ts_info = tvb_get_letohs(tvb, offset);
1166 g_snprintf(out_buff, SHORT_STR, "WME TS Info: Priority %u (%s) (%s), Contention-based access %sset, %s",
1167 (ts_info >> 11) & 0x7, qos_tags[(ts_info >> 11) & 0x7], qos_acs[(ts_info >> 11) & 0x7],
1168 (ts_info & 0x0080) ? "" : "not ",
1169 direction[(ts_info >> 5) & 0x3]);
1170 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1174 msdu_size = tvb_get_letohs(tvb, offset);
1175 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s MSDU Size %u",
1176 (msdu_size & 0x8000) ? "Fixed" : "Nominal", msdu_size & 0x7fff);
1177 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1181 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Maximum MSDU Size %u", tvb_get_letohs(tvb, offset));
1182 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1186 while ((field = val_to_str(tag_val_off, fields, "Unknown"))) {
1187 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s %u", field, tvb_get_letohl(tvb, offset));
1188 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1191 if (tag_val_off == 52)
1195 surplus_bandwidth = tvb_get_letohs(tvb, offset);
1196 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Surplus Bandwidth Allowance Factor %u.%u",
1197 (surplus_bandwidth >> 13) & 0x7, (surplus_bandwidth & 0x1fff));
1201 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Medium Time %u", tvb_get_letohs(tvb, offset));
1202 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1205 proto_item_append_text(ietree, ": WME");
1210 dissect_vendor_ie_rsn(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
1211 int offset, guint32 tag_len, const guint8 *tag_val)
1213 guint32 tag_val_off = 0;
1214 char out_buff[SHORT_STR], *pos;
1217 if (tag_val_off + 4 <= tag_len && !memcmp(tag_val, RSN_OUI"\x04", 4)) {
1218 /* IEEE 802.11i / Key Data Encapsulation / Data Type=4 - PMKID.
1219 * This is only used within EAPOL-Key frame Key Data. */
1221 pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "RSN PMKID: ");
1222 if (tag_len - 4 != PMKID_LEN) {
1223 pos += g_snprintf(pos, out_buff + SHORT_STR - pos,
1224 "(invalid PMKID len=%d, expected 16) ", tag_len - 4);
1226 for (i = 0; i < tag_len - 4; i++) {
1227 pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
1228 tag_val[tag_val_off + 4 + i]);
1230 proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1233 proto_item_append_text(ietree, ": RSN");
1237 AIRONET_IE_VERSION = 3,
1239 AIRONET_IE_QBSS_V2 = 14
1240 } aironet_ie_type_t;
1242 static const value_string aironet_ie_type_vals[] = {
1243 { AIRONET_IE_VERSION, "CCX version"},
1244 { AIRONET_IE_QOS, "Qos"},
1245 { AIRONET_IE_QBSS_V2, "QBSS V2 - CCA"},
1251 dissect_vendor_ie_aironet(proto_item * aironet_item, proto_tree * ietree,
1252 tvbuff_t * tvb, int offset, guint32 tag_len)
1256 gboolean dont_change = FALSE; /* Don't change the IE item text to default */
1258 type = tvb_get_guint8(tvb, offset);
1259 proto_tree_add_item (ietree, hf_aironet_ie_type, tvb, offset, 1, TRUE);
1263 case AIRONET_IE_VERSION:
1264 proto_tree_add_item (ietree, hf_aironet_ie_version, tvb, offset, 1, TRUE);
1265 proto_item_append_text(aironet_item, ": Aironet CCX version = %d",
1266 tvb_get_guint8(tvb, offset));
1269 case AIRONET_IE_QOS:
1270 proto_tree_add_item (ietree, hf_aironet_ie_qos_unk1, tvb, offset, 1, TRUE);
1272 proto_tree_add_item (ietree, hf_aironet_ie_qos_paramset, tvb, offset, 1, TRUE);
1275 /* XXX: just copied over from WME. Maybe "Best Effort" and "Background"
1276 * need to be swapped. Also, the "TXOP" may be TXOP - or not.
1278 for (i = 0; i < 4; i++) {
1279 guint8 byte1, byte2;
1281 byte1 = tvb_get_guint8(tvb, offset);
1282 byte2 = tvb_get_guint8(tvb, offset + 1);
1283 txop = tvb_get_letohs(tvb, offset + 2);
1284 proto_tree_add_bytes_format(ietree, hf_aironet_ie_qos_val, tvb, offset, 4,
1285 tvb_get_ptr(tvb, offset, 4),
1286 "CCX QoS Parameters??: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
1287 (byte1 & 0x60) >> 5, wme_acs[(byte1 & 0x60) >> 5],
1288 (byte1 & 0x10) ? "" : "not ", byte1 & 0x0f,
1289 byte2 & 0x0f, (byte2 & 0xf0) >> 4,
1294 case AIRONET_IE_QBSS_V2:
1295 /* Extract Values */
1296 proto_tree_add_item (ietree, hf_qbss2_scount, tvb, offset, 2, TRUE);
1297 proto_tree_add_item (ietree, hf_qbss2_cu, tvb, offset + 2, 1, FALSE);
1298 proto_tree_add_item (ietree, hf_qbss2_cal, tvb, offset + 3, 1, FALSE);
1299 proto_tree_add_item (ietree, hf_qbss2_gl, tvb, offset + 4, 1, FALSE);
1302 proto_tree_add_item(ietree, hf_aironet_ie_data, tvb, offset,
1303 tag_len - 1, FALSE);
1307 proto_item_append_text(aironet_item, ": Aironet %s",
1308 val_to_str(type, aironet_ie_type_vals, "Unknown"));
1313 dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
1314 guint32 tag_len, const guint8 *tag_val)
1316 guint32 tag_val_off = 0;
1318 char out_buff[SHORT_STR];
1320 proto_item *cap_item;
1321 proto_tree *cap_tree;
1323 if (tag_val_off + 2 > tag_len) {
1324 proto_tree_add_string(tree, tag_interpretation, tvb, offset, tag_len,
1329 g_snprintf(out_buff, SHORT_STR, "RSN IE, version %u",
1330 pletohs(&tag_val[tag_val_off]));
1331 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1336 if (tag_val_off + 4 > tag_len)
1339 /* multicast cipher suite */
1340 if (!memcmp(&tag_val[tag_val_off], RSN_OUI, 3)) {
1341 g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
1342 wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1343 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1348 if (tag_val_off + 2 > tag_len)
1351 /* unicast cipher suites */
1352 count = pletohs(tag_val + tag_val_off);
1353 g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u", count);
1354 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1358 while (tag_val_off + 4 <= tag_len && i <= count) {
1359 if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
1361 g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
1362 i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1363 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1369 if (i <= count || tag_val_off + 2 > tag_len)
1372 /* authenticated key management suites */
1373 count = pletohs(tag_val + tag_val_off);
1374 g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u", count);
1375 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1379 while (tag_val_off + 4 <= tag_len && i <= count) {
1380 if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
1382 g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
1383 i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
1384 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1390 if (i <= count || tag_val_off + 2 > tag_len)
1393 rsn_capab = pletohs(&tag_val[tag_val_off]);
1394 g_snprintf(out_buff, SHORT_STR, "RSN Capabilities 0x%04x", rsn_capab);
1395 cap_item = proto_tree_add_uint_format(tree, rsn_cap, tvb,
1396 offset, 2, rsn_capab,
1397 "RSN Capabilities: 0x%04X", rsn_capab);
1398 cap_tree = proto_item_add_subtree(cap_item, ett_rsn_cap_tree);
1399 proto_tree_add_boolean(cap_tree, rsn_cap_preauth, tvb, offset, 2,
1401 proto_tree_add_boolean(cap_tree, rsn_cap_no_pairwise, tvb, offset, 2,
1403 proto_tree_add_uint(cap_tree, rsn_cap_ptksa_replay_counter, tvb, offset, 2,
1405 proto_tree_add_uint(cap_tree, rsn_cap_gtksa_replay_counter, tvb, offset, 2,
1410 if (tag_val_off + 2 > tag_len)
1413 count = pletohs(tag_val + tag_val_off);
1414 g_snprintf(out_buff, SHORT_STR, "# of PMKIDs: %u", count);
1415 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1419 /* PMKID List (16 * n octets) */
1420 for (i = 0; i < count; i++) {
1422 if (tag_val_off + PMKID_LEN > tag_len)
1425 pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "PMKID %u: ", i);
1426 for (j = 0; j < PMKID_LEN; j++) {
1427 pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
1428 tag_val[tag_val_off + j]);
1430 proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1431 PMKID_LEN, out_buff);
1432 offset += PMKID_LEN;
1433 tag_val_off += PMKID_LEN;
1437 if (tag_val_off < tag_len)
1438 proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1439 tag_len - tag_val_off, "Not interpreted");
1442 /* ************************************************************************* */
1443 /* Dissect and add tagged (optional) fields to proto tree */
1444 /* ************************************************************************* */
1446 static const value_string tag_num_vals[] = {
1447 { TAG_SSID, "SSID parameter set" },
1448 { TAG_SUPP_RATES, "Supported Rates" },
1449 { TAG_FH_PARAMETER, "FH Parameter set" },
1450 { TAG_DS_PARAMETER, "DS Parameter set" },
1451 { TAG_CF_PARAMETER, "CF Parameter set" },
1452 { TAG_TIM, "(TIM) Traffic Indication Map" },
1453 { TAG_IBSS_PARAMETER, "IBSS Parameter set" },
1454 { TAG_COUNTRY_INFO, "Country Information" },
1455 { TAG_FH_HOPPING_PARAMETER, "Hopping Pattern Parameters" },
1456 { TAG_CHALLENGE_TEXT, "Challenge text" },
1457 { TAG_ERP_INFO, "ERP Information" },
1458 { TAG_ERP_INFO_OLD, "ERP Information" },
1459 { TAG_RSN_IE, "RSN Information" },
1460 { TAG_EXT_SUPP_RATES, "Extended Supported Rates" },
1461 { TAG_CISCO_UNKNOWN_1, "Cisco Unknown 1 + Device Name" },
1462 { TAG_CISCO_UNKNOWN_2, "Cisco Unknown 2" },
1463 { TAG_VENDOR_SPECIFIC_IE, "Vendor Specific" },
1464 { TAG_SYMBOL_PROPRIETARY, "Symbol Proprietary"},
1465 { TAG_AGERE_PROPRIETARY, "Agere Proprietary"},
1466 { TAG_REQUEST, "Request"},
1467 { TAG_QBSS_LOAD, "QBSS Load Element"},
1468 { TAG_EDCA_PARAM_SET, "EDCA Parameter Set"},
1469 { TAG_TRAF_SPEC, "Traffic Specification"},
1470 { TAG_TRAF_CLASS, "Traffic Classification"},
1471 { TAG_SCHEDULE, "Schedule"},
1472 { TAG_TS_DELAY, "TS Delay"},
1473 { TAG_TCLAS_PROCESS, "TCLAS Processing"},
1474 { TAG_QOS_CAPABILITY, "QoS Capability"},
1475 { TAG_POWER_CONSTRAINT, "Power Constraint"},
1476 { TAG_POWER_CAPABILITY, "Power Capability"},
1477 { TAG_TPC_REQUEST, "TPC Request"},
1478 { TAG_TPC_REPORT, "TPC Report"},
1479 { TAG_SUPPORTED_CHANNELS, "Supported Channels"},
1480 { TAG_CHANNEL_SWITCH_ANN, "Channel Switch Announcement"},
1481 { TAG_MEASURE_REQ, "Measurement Request"},
1482 { TAG_MEASURE_REP, "Measurement Report"},
1483 { TAG_QUIET, "Quiet"},
1484 { TAG_IBSS_DFS, "IBSS DFS"},
1488 static const value_string environment_vals[] = {
1490 { 0x4f, "Outdoor" },
1495 static int beacon_padding = 0; /* beacon padding bug */
1497 add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int offset)
1500 const guint8 *tag_val;
1501 const guint8 *tag_data_ptr;
1502 guint32 tag_no, tag_len;
1505 char out_buff[SHORT_STR];
1506 char print_buff[SHORT_STR];
1507 proto_tree * orig_tree=tree;
1510 tag_no = tvb_get_guint8(tvb, offset);
1511 tag_len = tvb_get_guint8(tvb, offset + 1);
1513 ti=proto_tree_add_text(orig_tree,tvb,offset,tag_len+2,"%s",
1514 val_to_str(tag_no, tag_num_vals,
1515 (tag_no >= 17 && tag_no <= 31) ?
1516 "Reserved for challenge text" : "Reserved tag number" ));
1517 tree=proto_item_add_subtree(ti,ett_80211_mgt_ie);
1519 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
1520 "Tag Number: %u (%s)",
1522 val_to_str(tag_no, tag_num_vals,
1523 (tag_no >= 17 && tag_no <= 31) ?
1524 "Reserved for challenge text" :
1525 "Reserved tag number"));
1526 proto_tree_add_uint (tree, (tag_no==TAG_TIM ? tim_length : tag_length), tvb, offset + 1, 1, tag_len);
1532 if(beacon_padding == 0) /* padding bug */
1536 ssid = tvb_get_ephemeral_string(tvb, offset + 2, tag_len);
1537 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1539 if (check_col (pinfo->cinfo, COL_INFO)) {
1541 col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: \"%s\"",
1542 format_text(ssid, tag_len));
1544 col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: Broadcast");
1548 proto_item_append_text(ti, ": \"%s\"",
1549 format_text(ssid, tag_len));
1551 proto_item_append_text(ti, ": Broadcast");
1553 beacon_padding++; /* padding bug */
1557 case TAG_SUPP_RATES:
1558 case TAG_EXT_SUPP_RATES:
1561 proto_tree_add_text (tree, tvb, offset + 2, tag_len,
1562 "Tag length %u too short, must be > 0", tag_len);
1565 tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
1567 tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
1568 for (i = 0, n = 0; i < tag_len && n < SHORT_STR; i++) {
1569 ret = g_snprintf (print_buff + n, SHORT_STR - n, "%2.1f%s ",
1570 (tag_data_ptr[i] & 0x7F) * 0.5,
1571 (tag_data_ptr[i] & 0x80) ? "(B)" : "");
1572 if (ret == -1 || ret >= SHORT_STR - n) {
1573 /* Some versions of snprintf return -1 if they'd truncate
1574 the output. Others return <buf_size> or greater. */
1579 g_snprintf (out_buff, SHORT_STR, "Supported rates: %s [Mbit/sec]", print_buff);
1580 out_buff[SHORT_STR-1] = '\0';
1581 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1583 proto_item_append_text(ti, ": %s", print_buff);
1586 case TAG_FH_PARAMETER:
1589 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 5",
1593 g_snprintf (out_buff, SHORT_STR,
1594 "Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, Hop Index %2d",
1595 tvb_get_letohs(tvb, offset + 2),
1596 tvb_get_guint8(tvb, offset + 4),
1597 tvb_get_guint8(tvb, offset + 5),
1598 tvb_get_guint8(tvb, offset + 6));
1599 out_buff[SHORT_STR-1] = '\0';
1600 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1604 case TAG_DS_PARAMETER:
1607 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
1611 g_snprintf (out_buff, SHORT_STR, "Current Channel: %u",
1612 tvb_get_guint8(tvb, offset + 2));
1613 out_buff[SHORT_STR-1] = '\0';
1614 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1616 proto_item_append_text(ti, ": %s", out_buff);
1619 case TAG_CF_PARAMETER:
1622 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 6",
1626 g_snprintf (out_buff, SHORT_STR, "CFP count: %u",
1627 tvb_get_guint8(tvb, offset + 2));
1628 out_buff[SHORT_STR-1] = '\0';
1629 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2,
1630 1, out_buff, "%s", out_buff);
1631 g_snprintf (out_buff, SHORT_STR, "CFP period: %u",
1632 tvb_get_guint8(tvb, offset + 3));
1633 out_buff[SHORT_STR-1] = '\0';
1634 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 3,
1635 1, out_buff, "%s", out_buff);
1636 g_snprintf (out_buff, SHORT_STR, "CFP max duration: %u",
1637 tvb_get_letohs(tvb, offset + 4));
1638 out_buff[SHORT_STR-1] = '\0';
1639 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 4,
1640 2, out_buff, "%s", out_buff);
1641 g_snprintf (out_buff, SHORT_STR, "CFP Remaining: %u",
1642 tvb_get_letohs(tvb, offset + 6));
1643 out_buff[SHORT_STR-1] = '\0';
1644 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 6,
1645 2, out_buff, "%s", out_buff);
1646 proto_item_append_text(ti, ": CFP count %u, CFP period %u, CFP max duration %u, "
1648 tvb_get_guint8(tvb, offset + 2),
1649 tvb_get_guint8(tvb, offset + 3),
1650 tvb_get_letohs(tvb, offset + 4),
1651 tvb_get_letohs(tvb, offset + 6));
1657 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 4",
1667 proto_tree_add_item(tree, tim_dtim_count, tvb,
1668 offset + 2, 1, TRUE);
1669 proto_tree_add_item(tree, tim_dtim_period, tvb,
1670 offset + 3, 1, TRUE);
1671 proto_item_append_text(ti, ": DTIM %u of %u bitmap",
1672 tvb_get_guint8(tvb, offset + 2),
1673 tvb_get_guint8(tvb, offset + 3));
1675 bmapctl = tvb_get_guint8(tvb, offset + 4);
1676 bmapoff = bmapctl>>1;
1677 proto_tree_add_uint_format(tree, tim_bmapctl, tvb,
1678 offset + 4, 1, bmapctl,
1679 "Bitmap Control: 0x%02X (mcast:%u, bitmap offset %u)",
1680 bmapctl, bmapctl&1, bmapoff);
1682 bmaplen = tag_len - 3;
1683 bmap = tvb_get_ptr(tvb, offset + 5, bmaplen);
1684 if (bmaplen==1 && 0==bmap[0] && !(bmapctl&1)) {
1685 proto_item_append_text(ti, " empty");
1688 proto_item_append_text(ti, " mcast");
1691 if (bmaplen>1 || bmap[0]) {
1692 int len=g_snprintf (out_buff, SHORT_STR,
1693 "Bitmap: traffic for AID's:");
1695 for (i=0;i<bmaplen*8;i++) {
1696 if (bmap[i/8] & (1<<(i%8))) {
1697 int aid=i+bmapoff*8;
1698 len+=g_snprintf (out_buff+len, SHORT_STR-len," %u", aid);
1699 proto_item_append_text(ti, " %u", aid);
1700 if (len>=SHORT_STR) {
1705 out_buff[SHORT_STR-1] = '\0';
1706 proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 5,
1707 bmaplen, out_buff, "%s", out_buff);
1712 case TAG_IBSS_PARAMETER:
1715 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
1719 g_snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
1720 tvb_get_letohs(tvb, offset + 2));
1721 out_buff[SHORT_STR-1] = '\0';
1722 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1724 proto_item_append_text(ti, ": %s", out_buff);
1727 case TAG_COUNTRY_INFO: /* IEEE 802.11d-2001 and IEEE 802.11j-2004 */
1733 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 3",
1737 tvb_memcpy(tvb, ccode, offset + 2, 2);
1739 g_snprintf (out_buff, SHORT_STR, "Country Code: %s, %s Environment",
1740 format_text(ccode, 2),
1741 val_to_str(tvb_get_guint8(tvb, offset + 4), environment_vals,"Unknown (0x%02x)"));
1742 out_buff[SHORT_STR-1] = '\0';
1743 proto_item_append_text(ti, ": %s", out_buff);
1744 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,3, out_buff);
1746 for (i = 3; (i + 3) <= tag_len; i += 3)
1748 guint8 val1, val2, val3;
1749 val1 = tvb_get_guint8(tvb, offset + 2 + i);
1750 val2 = tvb_get_guint8(tvb, offset + 3 + i);
1751 val3 = tvb_get_guint8(tvb, offset + 4 + i);
1753 if (val1 <= 200) { /* 802.11d */
1754 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
1755 " Start Channel: %u, Channels: %u, Max TX Power: %d dBm",
1756 val1, val2, (gint) val3);
1757 } else { /* 802.11j */
1758 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
1759 " Reg Extension Id: %u, Regulatory Class: %u, Coverage Class: %u",
1767 if (tag_len < 4 || tag_len >5)
1769 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Wrong QBSS Tag Length %u", tag_len);
1775 /* QBSS Version 1 */
1776 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 1,
1777 tag_len, "Cisco QBSS Version 1 - non CCA");
1779 /* Extract Values */
1780 proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 1);
1781 proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
1782 proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
1783 proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 1, FALSE);
1785 else if (tag_len == 5)
1787 /* QBSS Version 2 */
1788 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1789 tag_len, "802.11e CCA Version");
1791 /* Extract Values */
1792 proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 2);
1793 proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
1794 proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
1795 proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 2, FALSE);
1799 case TAG_FH_HOPPING_PARAMETER:
1802 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
1806 g_snprintf (out_buff, SHORT_STR, "Prime Radix: %u, Number of Channels: %u",
1807 tvb_get_guint8(tvb, offset + 2),
1808 tvb_get_guint8(tvb, offset + 3));
1809 out_buff[SHORT_STR-1] = '\0';
1810 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2, tag_len, out_buff);
1811 proto_item_append_text(ti, ": %s", out_buff);
1814 case TAG_CHALLENGE_TEXT:
1815 g_snprintf (out_buff, SHORT_STR, "Challenge text: %s",
1816 tvb_bytes_to_str(tvb, offset + 2, tag_len));
1817 out_buff[SHORT_STR-1] = '\0';
1818 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1823 case TAG_ERP_INFO_OLD:
1829 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
1833 erp_info = tvb_get_guint8 (tvb, offset + 2);
1834 g_snprintf (print_buff, SHORT_STR, "%sNon-ERP STAs, %suse protection, %s preambles",
1835 erp_info & 0x01 ? "" : "no ",
1836 erp_info & 0x02 ? "" : "do not ",
1837 erp_info & 0x04 ? "short or long": "long");
1838 print_buff[SHORT_STR-1] = '\0';
1839 g_snprintf (out_buff, SHORT_STR,
1840 "ERP info: 0x%x (%s)",erp_info,print_buff);
1841 out_buff[SHORT_STR-1] = '\0';
1842 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1844 proto_item_append_text(ti, ": %s", print_buff);
1848 case TAG_CISCO_UNKNOWN_1:
1849 /* The Name of the sending device starts at offset 10 and is up to
1850 15 or 16 bytes in length, \0 padded */
1853 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 26",
1857 g_snprintf (out_buff, SHORT_STR, "%.16s",
1858 tvb_format_stringzpad(tvb, offset + 12, 16));
1859 out_buff[SHORT_STR-1] = '\0';
1860 proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 2,
1861 tag_len, "", "Tag interpretation: Unknown + Name: %s",
1863 if (check_col (pinfo->cinfo, COL_INFO)) {
1864 col_append_fstr(pinfo->cinfo, COL_INFO, ", Name: \"%s\"", out_buff);
1868 case TAG_VENDOR_SPECIFIC_IE:
1869 tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
1871 oui = tvb_get_ntoh24(tvb, offset + 2);
1872 tag_val = tvb_get_ptr(tvb, offset + 2, tag_len);
1874 #define WPAWME_OUI 0x0050F2
1875 #define RSNOUI_VAL 0x000FAC
1876 #define AIRONET_VAL 0x004096
1880 dissect_vendor_ie_wpawme(ti, tree, tvb, offset + 2, tag_len, tag_val);
1883 dissect_vendor_ie_rsn(ti, tree, tvb, offset + 2, tag_len, tag_val);
1886 dissect_vendor_ie_aironet(ti, tree, tvb, offset + 5, tag_len - 3);
1889 proto_tree_add_bytes_format (tree, tag_oui, tvb, offset + 2, 3,
1890 "", "Vendor: %s", get_manuf_name(tag_val));
1891 proto_item_append_text(ti, ": %s", get_manuf_name(tag_val));
1892 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 5,
1893 tag_len - 3, "Not interpreted");
1901 dissect_rsn_ie(tree, tvb, offset + 2, tag_len,
1902 tvb_get_ptr (tvb, offset + 2, tag_len));
1906 tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
1907 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1908 tag_len, "Not interpreted");
1909 proto_item_append_text(ti, ": Tag %u Len %u", tag_no, tag_len);
1917 ieee_80211_add_tagged_parameters (tvbuff_t * tvb, int offset, packet_info * pinfo,
1918 proto_tree * tree, int tagged_parameters_len)
1922 beacon_padding = 0; /* this is for the beacon padding confused with ssid fix */
1923 while (tagged_parameters_len > 0) {
1924 if ((next_len=add_tagged_field (pinfo, tree, tvb, offset))==0)
1926 if (next_len > tagged_parameters_len) {
1927 /* XXX - flag this as an error? */
1928 next_len = tagged_parameters_len;
1931 tagged_parameters_len -= next_len;
1935 /* ************************************************************************* */
1936 /* Dissect 802.11 management frame */
1937 /* ************************************************************************* */
1939 dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
1942 proto_item *ti = NULL;
1943 proto_tree *mgt_tree;
1944 proto_tree *fixed_tree;
1945 proto_tree *tagged_tree;
1947 int tagged_parameter_tree_len;
1951 CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
1953 ti = proto_tree_add_item (tree, proto_wlan_mgt, tvb, 0, -1, FALSE);
1954 mgt_tree = proto_item_add_subtree (ti, ett_80211_mgt);
1956 switch (COMPOSE_FRAME_TYPE(fcf))
1960 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
1961 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1962 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
1963 offset = 4; /* Size of fixed fields */
1965 tagged_parameter_tree_len =
1966 tvb_reported_length_remaining(tvb, offset);
1967 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1968 tagged_parameter_tree_len);
1969 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1970 tagged_parameter_tree_len);
1974 case MGT_ASSOC_RESP:
1975 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1976 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1977 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
1978 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
1979 offset = 6; /* Size of fixed fields */
1981 tagged_parameter_tree_len =
1982 tvb_reported_length_remaining(tvb, offset);
1983 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1984 tagged_parameter_tree_len);
1985 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1986 tagged_parameter_tree_len);
1990 case MGT_REASSOC_REQ:
1991 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
1992 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1993 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
1994 add_fixed_field (fixed_tree, tvb, 4, FIELD_CURRENT_AP_ADDR);
1995 offset = 10; /* Size of fixed fields */
1997 tagged_parameter_tree_len =
1998 tvb_reported_length_remaining(tvb, offset);
1999 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2000 tagged_parameter_tree_len);
2001 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2002 tagged_parameter_tree_len);
2005 case MGT_REASSOC_RESP:
2006 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
2007 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
2008 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
2009 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
2010 offset = 6; /* Size of fixed fields */
2012 tagged_parameter_tree_len =
2013 tvb_reported_length_remaining(tvb, offset);
2014 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2015 tagged_parameter_tree_len);
2016 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2017 tagged_parameter_tree_len);
2023 tagged_parameter_tree_len =
2024 tvb_reported_length_remaining(tvb, offset);
2025 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2026 tagged_parameter_tree_len);
2027 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2028 tagged_parameter_tree_len);
2032 case MGT_PROBE_RESP:
2033 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
2034 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
2035 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
2036 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
2037 offset = 12; /* Size of fixed fields */
2039 tagged_parameter_tree_len =
2040 tvb_reported_length_remaining(tvb, offset);
2041 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2042 tagged_parameter_tree_len);
2043 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2044 tagged_parameter_tree_len);
2048 case MGT_BEACON: /* Dissect protocol payload fields */
2049 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
2050 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
2051 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
2052 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
2053 offset = 12; /* Size of fixed fields */
2055 tagged_parameter_tree_len =
2056 tvb_reported_length_remaining(tvb, offset);
2057 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2058 tagged_parameter_tree_len);
2059 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2060 tagged_parameter_tree_len);
2069 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2070 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
2074 case MGT_AUTHENTICATION:
2075 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
2076 add_fixed_field (fixed_tree, tvb, 0, FIELD_AUTH_ALG);
2077 add_fixed_field (fixed_tree, tvb, 2, FIELD_AUTH_TRANS_SEQ);
2078 add_fixed_field (fixed_tree, tvb, 4, FIELD_STATUS_CODE);
2079 offset = 6; /* Size of fixed fields */
2081 tagged_parameter_tree_len =
2082 tvb_reported_length_remaining(tvb, offset);
2083 if (tagged_parameter_tree_len != 0)
2085 tagged_tree = get_tagged_parameter_tree (mgt_tree,
2088 tagged_parameter_tree_len);
2089 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2090 tagged_parameter_tree_len);
2095 case MGT_DEAUTHENTICATION:
2096 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2097 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
2102 switch (tvb_get_guint8(tvb, 0))
2105 case CAT_SPECTRUM_MGMT:
2106 switch (tvb_get_guint8(tvb, 1))
2108 case SM_ACTION_MEASUREMENT_REQUEST:
2109 case SM_ACTION_MEASUREMENT_REPORT:
2110 case SM_ACTION_TPC_REQUEST:
2111 case SM_ACTION_TPC_REPORT:
2112 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
2113 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2114 add_fixed_field (fixed_tree, tvb, 1, FIELD_ACTION_CODE);
2115 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2116 offset = 3; /* Size of fixed fields */
2119 case SM_ACTION_CHAN_SWITCH_ANNC:
2120 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2121 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2122 offset = 2; /* Size of fixed fields */
2126 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2127 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2128 offset = 2; /* Size of fixed fields */
2133 case CAT_MGMT_NOTIFICATION: /* Management notification frame */
2134 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
2135 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2136 add_fixed_field (fixed_tree, tvb, 1, FIELD_WME_ACTION_CODE);
2137 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2138 add_fixed_field (fixed_tree, tvb, 3, FIELD_WME_STATUS_CODE);
2139 offset = 4; /* Size of fixed fields */
2143 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 1);
2144 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2145 offset = 1; /* Size of fixed fields */
2149 tagged_parameter_tree_len =
2150 tvb_reported_length_remaining(tvb, offset);
2151 if (tagged_parameter_tree_len != 0)
2153 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2154 tagged_parameter_tree_len);
2155 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2156 tagged_parameter_tree_len);
2163 set_src_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
2165 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
2166 col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "%s (%s)",
2167 get_ether_name(addr), type);
2168 if (check_col(pinfo->cinfo, COL_UNRES_DL_SRC))
2169 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s",
2170 ether_to_str(addr));
2174 set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
2176 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
2177 col_add_fstr(pinfo->cinfo, COL_RES_DL_DST, "%s (%s)",
2178 get_ether_name(addr), type);
2179 if (check_col(pinfo->cinfo, COL_UNRES_DL_DST))
2180 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s",
2181 ether_to_str(addr));
2185 crc32_802_tvb_padded(tvbuff_t *tvb, guint hdr_len, guint hdr_size, guint len)
2189 c_crc = crc32_ccitt_tvb(tvb, hdr_len);
2190 c_crc = crc32_ccitt_seed(tvb_get_ptr(tvb, hdr_size, len), len, ~c_crc);
2193 c_crc = ((unsigned char)(c_crc>>0)<<24) |
2194 ((unsigned char)(c_crc>>8)<<16) |
2195 ((unsigned char)(c_crc>>16)<<8) |
2196 ((unsigned char)(c_crc>>24)<<0);
2207 /* ************************************************************************* */
2208 /* Dissect 802.11 frame */
2209 /* ************************************************************************* */
2211 dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
2212 proto_tree * tree, gboolean fixed_length_header,
2213 gboolean has_radio_information, gint fcs_len,
2214 gboolean wlan_broken_fc, gboolean datapad)
2216 guint16 fcf, flags, frame_type_subtype;
2217 guint16 seq_control;
2218 guint32 seq_number, frag_number;
2219 gboolean more_frags;
2220 const guint8 *src = NULL;
2221 const guint8 *dst = NULL;
2222 const guint8 *bssid = NULL;
2223 proto_item *ti = NULL;
2224 proto_item *flag_item;
2225 proto_item *fc_item;
2226 proto_tree *hdr_tree = NULL;
2227 proto_tree *flag_tree;
2228 proto_tree *fc_tree;
2229 guint16 hdr_len, ohdr_len;
2231 gint len, reported_len, ivlen;
2232 gboolean save_fragmented;
2233 tvbuff_t *volatile next_tvb = NULL;
2235 volatile encap_t encap_type;
2236 guint8 octet1, octet2;
2237 char out_buff[SHORT_STR];
2240 wlan_hdr *volatile whdr;
2241 static wlan_hdr whdrs[4];
2245 if (check_col (pinfo->cinfo, COL_PROTOCOL))
2246 col_set_str (pinfo->cinfo, COL_PROTOCOL, "IEEE 802.11");
2247 if (check_col (pinfo->cinfo, COL_INFO))
2248 col_clear (pinfo->cinfo, COL_INFO);
2250 /* Add the radio information, if present, to the column information */
2251 if (has_radio_information) {
2252 if (check_col(pinfo->cinfo, COL_TX_RATE)) {
2253 col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u",
2254 pinfo->pseudo_header->ieee_802_11.data_rate / 2,
2255 pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
2257 if (check_col(pinfo->cinfo, COL_RSSI)) {
2258 /* XX - this is a percentage, not a dBm or normalized or raw RSSI */
2259 col_add_fstr(pinfo->cinfo, COL_RSSI, "%u",
2260 pinfo->pseudo_header->ieee_802_11.signal_level);
2264 fcf = tvb_get_letohs (tvb, 0);
2265 if (wlan_broken_fc) {
2267 fcf = ((fcf & 0xff) << 8) | (((fcf & 0xff00) >> 8) & 0xff);
2269 if (fixed_length_header)
2270 hdr_len = DATA_LONG_HDR_LEN;
2272 hdr_len = find_header_length (fcf);
2275 hdr_len = roundup2(hdr_len, 4);
2276 frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
2278 if (check_col (pinfo->cinfo, COL_INFO))
2279 col_set_str (pinfo->cinfo, COL_INFO,
2280 val_to_str(frame_type_subtype, frame_type_subtype_vals,
2281 "Unrecognized (Reserved frame)"));
2283 flags = FCF_FLAGS (fcf);
2284 more_frags = HAVE_FRAGMENTS (flags);
2287 /* Add the radio information, if present, and the FC to the current tree */
2290 ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
2292 hdr_tree = proto_item_add_subtree (ti, ett_80211);
2294 if (has_radio_information) {
2295 proto_tree_add_uint_format(hdr_tree, hf_data_rate,
2297 pinfo->pseudo_header->ieee_802_11.data_rate,
2298 "Data Rate: %u.%u Mb/s",
2299 pinfo->pseudo_header->ieee_802_11.data_rate / 2,
2300 pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
2302 proto_tree_add_uint(hdr_tree, hf_channel,
2304 pinfo->pseudo_header->ieee_802_11.channel);
2306 proto_tree_add_uint_format(hdr_tree, hf_signal_strength,
2308 pinfo->pseudo_header->ieee_802_11.signal_level,
2309 "Signal Strength: %u%%",
2310 pinfo->pseudo_header->ieee_802_11.signal_level);
2313 proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
2315 wlan_broken_fc?1:0, 1,
2316 frame_type_subtype);
2318 fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb,
2321 "Frame Control: 0x%04X (%s)",
2322 fcf, wlan_broken_fc?"Swapped":"Normal");
2324 fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
2327 proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb,
2328 wlan_broken_fc?1:0, 1,
2329 FCF_PROT_VERSION (fcf));
2331 proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb,
2332 wlan_broken_fc?1:0, 1,
2333 FCF_FRAME_TYPE (fcf));
2335 proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
2337 wlan_broken_fc?1:0, 1,
2338 FCF_FRAME_SUBTYPE (fcf));
2341 proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb,
2342 wlan_broken_fc?0:1, 1,
2343 flags, "Flags: 0x%X", flags);
2345 flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
2347 proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb,
2348 wlan_broken_fc?0:1, 1,
2349 FLAGS_DS_STATUS (flags));
2350 proto_tree_add_boolean_hidden (flag_tree, hf_fc_to_ds, tvb, 1, 1,
2352 proto_tree_add_boolean_hidden (flag_tree, hf_fc_from_ds, tvb, 1, 1,
2355 proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb,
2356 wlan_broken_fc?0:1, 1,
2359 proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb,
2360 wlan_broken_fc?0:1, 1, flags);
2362 proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb,
2363 wlan_broken_fc?0:1, 1, flags);
2365 proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb,
2366 wlan_broken_fc?0:1, 1,
2369 proto_tree_add_boolean (flag_tree, hf_fc_protected, tvb,
2370 wlan_broken_fc?0:1, 1, flags);
2372 proto_tree_add_boolean (flag_tree, hf_fc_order, tvb,
2373 wlan_broken_fc?0:1, 1, flags);
2375 if (frame_type_subtype == CTRL_PS_POLL)
2376 proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
2377 ASSOC_ID(tvb_get_letohs(tvb,2)));
2380 proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
2381 tvb_get_letohs (tvb, 2));
2385 * Decode the part of the frame header that isn't the same for all
2392 switch (FCF_FRAME_TYPE (fcf))
2397 * All management frame types have the same header.
2399 src = tvb_get_ptr (tvb, 10, 6);
2400 dst = tvb_get_ptr (tvb, 4, 6);
2402 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
2403 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
2404 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
2405 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
2408 SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, tvb_get_ptr(tvb, 16,6));
2409 SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
2410 SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
2411 whdr->type = frame_type_subtype;
2413 seq_control = tvb_get_letohs(tvb, 22);
2414 frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
2415 seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
2417 if (check_col (pinfo->cinfo, COL_INFO))
2419 col_append_fstr(pinfo->cinfo, COL_INFO,
2420 ",SN=%d", seq_number);
2422 col_append_fstr(pinfo->cinfo, COL_INFO,
2423 ",FN=%d",frag_number);
2428 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2430 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2432 /* add items for wlan.addr filter */
2433 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2434 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2436 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
2437 tvb_get_ptr (tvb, 16, 6));
2439 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2442 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2448 switch (frame_type_subtype)
2452 src = tvb_get_ptr (tvb, 10, 6);
2453 dst = tvb_get_ptr (tvb, 4, 6);
2455 set_src_addr_cols(pinfo, src, "BSSID");
2456 set_dst_addr_cols(pinfo, dst, "BSSID");
2460 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6, dst);
2462 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
2468 src = tvb_get_ptr (tvb, 10, 6);
2469 dst = tvb_get_ptr (tvb, 4, 6);
2471 set_src_addr_cols(pinfo, src, "TA");
2472 set_dst_addr_cols(pinfo, dst, "RA");
2476 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2478 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
2484 dst = tvb_get_ptr (tvb, 4, 6);
2486 set_dst_addr_cols(pinfo, dst, "RA");
2489 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2493 case CTRL_ACKNOWLEDGEMENT:
2494 dst = tvb_get_ptr (tvb, 4, 6);
2496 set_dst_addr_cols(pinfo, dst, "RA");
2499 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2504 src = tvb_get_ptr (tvb, 10, 6);
2505 dst = tvb_get_ptr (tvb, 4, 6);
2507 set_src_addr_cols(pinfo, src, "BSSID");
2508 set_dst_addr_cols(pinfo, dst, "RA");
2512 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2513 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
2518 case CTRL_CFP_ENDACK:
2519 src = tvb_get_ptr (tvb, 10, 6);
2520 dst = tvb_get_ptr (tvb, 4, 6);
2522 set_src_addr_cols(pinfo, src, "BSSID");
2523 set_dst_addr_cols(pinfo, dst, "RA");
2527 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2529 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
2533 case CTRL_BLOCK_ACK_REQ:
2535 src = tvb_get_ptr (tvb, 10, 6);
2536 dst = tvb_get_ptr (tvb, 4, 6);
2538 set_src_addr_cols(pinfo, src, "TA");
2539 set_dst_addr_cols(pinfo, dst, "RA");
2543 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
2545 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
2551 case CTRL_BLOCK_ACK:
2553 src = tvb_get_ptr (tvb, 10, 6);
2554 dst = tvb_get_ptr (tvb, 4, 6);
2556 set_src_addr_cols(pinfo, src, "TA");
2557 set_dst_addr_cols(pinfo, dst, "RA");
2561 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
2563 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
2565 /* TODO BAR Format */
2572 addr_type = FCF_ADDR_SELECTOR (fcf);
2574 /* In order to show src/dst address we must always do the following */
2579 src = tvb_get_ptr (tvb, 10, 6);
2580 dst = tvb_get_ptr (tvb, 4, 6);
2581 bssid = tvb_get_ptr (tvb, 16, 6);
2586 src = tvb_get_ptr (tvb, 16, 6);
2587 dst = tvb_get_ptr (tvb, 4, 6);
2588 bssid = tvb_get_ptr (tvb, 10, 6);
2593 src = tvb_get_ptr (tvb, 10, 6);
2594 dst = tvb_get_ptr (tvb, 16, 6);
2595 bssid = tvb_get_ptr (tvb, 4, 6);
2600 src = tvb_get_ptr (tvb, 24, 6);
2601 dst = tvb_get_ptr (tvb, 16, 6);
2602 bssid = tvb_get_ptr (tvb, 16, 6);
2606 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
2607 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
2608 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
2609 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
2613 SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, bssid);
2614 SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
2615 SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
2616 whdr->type = frame_type_subtype;
2618 seq_control = tvb_get_letohs(tvb, 22);
2619 frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
2620 seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
2622 if (check_col (pinfo->cinfo, COL_INFO))
2624 col_append_fstr(pinfo->cinfo, COL_INFO,
2625 ",SN=%d", seq_number);
2627 col_append_fstr(pinfo->cinfo, COL_INFO,
2628 ",FN=%d",frag_number);
2631 /* Now if we have a tree we start adding stuff */
2640 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2641 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2642 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
2643 tvb_get_ptr (tvb, 16, 6));
2644 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2646 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2649 /* add items for wlan.addr filter */
2650 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2651 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2656 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2657 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
2658 tvb_get_ptr (tvb, 10, 6));
2659 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6, src);
2660 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2662 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2665 /* add items for wlan.addr filter */
2666 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2667 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, src);
2672 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
2673 tvb_get_ptr (tvb, 4, 6));
2674 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2675 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
2677 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2679 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2682 /* add items for wlan.addr filter */
2683 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2684 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
2689 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
2690 tvb_get_ptr (tvb, 4, 6));
2691 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
2692 tvb_get_ptr (tvb, 10, 6));
2693 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
2694 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2696 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2698 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6, src);
2700 /* add items for wlan.addr filter */
2701 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
2702 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 24, 6, src);
2710 len = tvb_length_remaining(tvb, hdr_len);
2711 reported_len = tvb_reported_length_remaining(tvb, hdr_len);
2715 case 0: /* Definitely has no FCS */
2719 case 4: /* Definitely has an FCS */
2723 default: /* Don't know - use "wlan_check_fcs" */
2724 has_fcs = wlan_check_fcs;
2730 * Well, this packet should, in theory, have an FCS.
2731 * Do we have the entire packet, and does it have enough data for
2734 if (reported_len < 4)
2737 * The packet is claimed not to even have enough data for a 4-byte
2739 * Pretend it doesn't have an FCS.
2743 else if (len < reported_len)
2746 * The packet is claimed to have enough data for a 4-byte FCS, but
2747 * we didn't capture all of the packet.
2748 * Slice off the 4-byte FCS from the reported length, and trim the
2749 * captured length so it's no more than the reported length; that
2750 * will slice off what of the FCS, if any, is in the captured
2754 if (len > reported_len)
2760 * We have the entire packet, and it includes a 4-byte FCS.
2761 * Slice it off, and put it into the tree.
2767 guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len);
2771 fcs = crc32_802_tvb_padded(tvb, ohdr_len, hdr_len, len);
2773 fcs = crc32_802_tvb(tvb, hdr_len + len);
2774 if (fcs == sent_fcs)
2775 proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
2776 hdr_len + len, 4, sent_fcs,
2777 "Frame check sequence: 0x%08x [correct]", sent_fcs);
2779 proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
2780 hdr_len + len, 4, sent_fcs,
2781 "Frame check sequence: 0x%08x [incorrect, should be 0x%08x]",
2790 * Only management and data frames have a body, so we don't have
2791 * anything more to do for other types of frames.
2793 switch (FCF_FRAME_TYPE (fcf))
2800 if (tree && DATA_FRAME_IS_QOS(frame_type_subtype))
2803 proto_item *qos_fields;
2804 proto_tree *qos_tree;
2807 guint16 qos_control;
2808 guint16 qos_priority;
2809 guint16 qos_ack_policy;
2811 guint16 qos_field_content;
2814 * We calculate the offset to the QoS header data as
2815 * an offset relative to the end of the header. But
2816 * when the header has been padded to align the data
2817 * this must be done relative to true header size, not
2818 * the padded/aligned value. To simplify this work we
2819 * stash the original header size in ohdr_len instead
2820 * of recalculating it.
2822 qosoff = ohdr_len - 2;
2823 qos_fields = proto_tree_add_text(hdr_tree, tvb, qosoff, 2,
2825 qos_tree = proto_item_add_subtree (qos_fields, ett_qos_parameters);
2827 qos_control = tvb_get_letohs(tvb, qosoff + 0);
2828 qos_priority = QOS_PRIORITY(qos_control);
2829 qos_ack_policy = QOS_ACK_POLICY(qos_control);
2830 qos_eosp = QOS_EOSP(qos_control);
2831 qos_field_content = QOS_FIELD_CONTENT( qos_control);
2833 proto_tree_add_uint_format (qos_tree, hf_qos_priority, tvb,
2834 qosoff, 2, qos_priority,
2835 "Priority: %d (%s) (%s)",
2836 qos_priority, qos_tags[qos_priority], qos_acs[qos_priority]);
2838 if (flags & FLAG_FROM_DS) {
2839 proto_tree_add_boolean (qos_tree, hf_qos_eosp, tvb,
2840 qosoff, 1, qos_eosp);
2842 if (DATA_FRAME_IS_CF_POLL(frame_type_subtype)) {
2844 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2845 qosoff + 1, 1, qos_field_content, "TXOP Limit: %d ", qos_field_content);
2848 /* qap ps buffer state */
2849 proto_item *qos_ps_buf_state_fields;
2850 proto_tree *qos_ps_buf_state_tree;
2855 buf_state = QOS_PS_BUF_STATE(qos_field_content);
2856 buf_ac = QOS_PS_BUF_AC(qos_field_content); /*access category */
2857 buf_load = QOS_PS_BUF_LOAD(qos_field_content);
2859 qos_ps_buf_state_fields = proto_tree_add_text(qos_tree, tvb, qosoff + 1, 1,
2860 "QAP PS Buffer State: 0x%x", qos_field_content);
2861 qos_ps_buf_state_tree = proto_item_add_subtree (qos_ps_buf_state_fields, ett_qos_ps_buf_state);
2863 /* FIXME: hf_ values not defined
2864 proto_tree_add_boolean (qos_ps_buf_state_tree, hf_qos_buf_state, tvb,
2867 proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_ac, tvb,
2868 qosoff + 1, 1, buf_ac, "Priority: %d (%s)",
2869 buf_ac, wme_acs[buf_ac]);
2871 proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_load, tvb,
2872 qosoff + 1, 1, buf_load, "Buffered load: %d ", (buf_load * 4096));
2876 } else if (qos_eosp) {
2877 /* txop limit requested */
2878 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2879 qosoff + 1, 1, qos_field_content, "Queue Size: %d ", (qos_field_content * 254));
2882 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2883 qosoff + 1, 1, qos_field_content, "TXOP Limit Requested: %d ", qos_field_content);
2886 proto_tree_add_uint (qos_tree, hf_qos_ack_policy, tvb, qosoff, 1,
2889 } /* end of qos control field */
2892 * No-data frames don't have a body.
2894 if (DATA_FRAME_IS_NULL(frame_type_subtype))
2906 if (IS_PROTECTED(FCF_FLAGS(fcf))) {
2908 * It's a WEP-encrypted frame; dissect the WEP parameters and decrypt
2909 * the data, if we have a matching key. Otherwise display it as data.
2911 gboolean can_decrypt = FALSE;
2912 proto_tree *wep_tree = NULL;
2914 guint8 key, keybyte;
2916 keybyte = tvb_get_guint8(tvb, hdr_len + 3);
2917 key = KEY_OCTET_WEP_KEY(keybyte);
2918 if ((keybyte & KEY_EXTIV) && (len >= EXTIV_LEN)) {
2919 /* Extended IV; this frame is likely encrypted with TKIP or CCMP */
2921 proto_item *extiv_fields;
2923 extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
2924 "TKIP/CCMP parameters");
2925 wep_tree = proto_item_add_subtree (extiv_fields, ett_wep_parameters);
2926 /* It is unknown whether this is a TKIP or CCMP encrypted packet, so
2927 * display both packet number alternatives unless the ExtIV can be
2928 * determined to be possible only with one of the encryption protocols.
2930 if (tvb_get_guint8(tvb, hdr_len + 1) & 0x20) {
2931 g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
2932 tvb_get_letohl(tvb, hdr_len + 4),
2933 tvb_get_guint8(tvb, hdr_len),
2934 tvb_get_guint8(tvb, hdr_len + 2));
2935 proto_tree_add_string(wep_tree, hf_tkip_extiv, tvb, hdr_len,
2936 EXTIV_LEN, out_buff);
2938 if (tvb_get_guint8(tvb, hdr_len + 2) == 0) {
2939 g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
2940 tvb_get_letohl(tvb, hdr_len + 4),
2941 tvb_get_guint8(tvb, hdr_len + 1),
2942 tvb_get_guint8(tvb, hdr_len));
2943 proto_tree_add_string(wep_tree, hf_ccmp_extiv, tvb, hdr_len,
2944 EXTIV_LEN, out_buff);
2946 proto_tree_add_uint(wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
2949 /* Subtract out the length of the IV. */
2951 reported_len -= EXTIV_LEN;
2953 /* It is unknown whether this is TKIP or CCMP, so let's not even try to
2954 * parse TKIP Michael MIC+ICV or CCMP MIC. */
2956 /* No Ext. IV - WEP packet */
2958 * XXX - pass the IV and key to "try_decrypt_wep()", and have it pass
2959 * them to "wep_decrypt()", rather than having "wep_decrypt()" extract
2962 * Also, just pass the data *following* the WEP parameters as the
2963 * buffer to decrypt.
2965 iv = tvb_get_ntoh24(tvb, hdr_len);
2967 proto_item *wep_fields;
2969 wep_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 4,
2972 wep_tree = proto_item_add_subtree (wep_fields, ett_wep_parameters);
2973 proto_tree_add_uint (wep_tree, hf_wep_iv, tvb, hdr_len, 3, iv);
2974 tvb_memcpy(tvb, iv_buff, hdr_len, 3);
2975 is_iv_bad = weak_iv(iv_buff);
2976 if (is_iv_bad != -1) {
2977 proto_tree_add_boolean_format (wep_tree, hf_wep_iv_weak,
2979 "Weak IV for key byte %d",
2984 proto_tree_add_uint (wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
2986 /* Subtract out the length of the IV. */
2992 * Well, this packet should, in theory, have an ICV.
2993 * Do we have the entire packet, and does it have enough data for
2996 if (reported_len < 4) {
2998 * The packet is claimed not to even have enough data for a
3000 * Pretend it doesn't have an ICV.
3003 } else if (len < reported_len) {
3005 * The packet is claimed to have enough data for a 4-byte ICV,
3006 * but we didn't capture all of the packet.
3007 * Slice off the 4-byte ICV from the reported length, and trim
3008 * the captured length so it's no more than the reported length;
3009 * that will slice off what of the ICV, if any, is in the
3014 if (len > reported_len)
3018 * We have the entire packet, and it includes a 4-byte ICV.
3019 * Slice it off, and put it into the tree.
3021 * We only support decrypting if we have the the ICV.
3023 * XXX - the ICV is encrypted; we're putting the encrypted
3024 * value, not the decrypted value, into the tree.
3032 if (!can_decrypt || (next_tvb = try_decrypt_wep(tvb, hdr_len, reported_len + 8)) == NULL) {
3034 * WEP decode impossible or failed, treat payload as raw data
3035 * and don't attempt fragment reassembly or further dissection.
3037 next_tvb = tvb_new_subset(tvb, hdr_len + ivlen, len, reported_len);
3039 if (tree && can_decrypt)
3040 proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
3041 hdr_len + ivlen + len, 4,
3042 tvb_get_ntohl(tvb, hdr_len + ivlen + len),
3043 "WEP ICV: 0x%08x (not verified)",
3044 tvb_get_ntohl(tvb, hdr_len + ivlen + len));
3046 if (pinfo->ethertype != ETHERTYPE_CENTRINO_PROMISC)
3048 /* Some wireless drivers (such as Centrino) WEP payload already decrypted */
3049 call_dissector(data_handle, next_tvb, pinfo, tree);
3055 proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
3056 hdr_len + ivlen + len, 4,
3057 tvb_get_ntohl(tvb, hdr_len + ivlen + len),
3058 "WEP ICV: 0x%08x (correct)",
3059 tvb_get_ntohl(tvb, hdr_len + ivlen + len));
3061 add_new_data_source(pinfo, next_tvb, "Decrypted WEP data");
3065 * WEP decryption successful!
3067 * Use the tvbuff we got back from the decryption; the data starts at
3068 * the beginning. The lengths are already correct for the decoded WEP
3075 * Not a WEP-encrypted frame; just use the data from the tvbuff
3078 * The payload starts at "hdr_len" (i.e., just past the 802.11
3079 * MAC header), the length of data in the tvbuff following the
3080 * 802.11 header is "len", and the length of data in the packet
3081 * following the 802.11 header is "reported_len".
3087 * Do defragmentation if "wlan_defragment" is true, and we have more
3088 * fragments or this isn't the first fragment.
3090 * We have to do some special handling to catch frames that
3091 * have the "More Fragments" indicator not set but that
3092 * don't show up as reassembled and don't have any other
3093 * fragments present. Some networking interfaces appear
3094 * to do reassembly even when you're capturing raw packets
3095 * *and* show the reassembled packet without the "More
3096 * Fragments" indicator set *but* with a non-zero fragment
3099 * "fragment_add_seq_802_11()" handles that; we want to call it
3100 * even if we have a short frame, so that it does those checks - if
3101 * the frame is short, it doesn't do reassembly on it.
3103 * (This could get some false positives if we really *did* only
3104 * capture the last fragment of a fragmented packet, but that's
3107 save_fragmented = pinfo->fragmented;
3108 if (wlan_defragment && (more_frags || frag_number != 0)) {
3109 fragment_data *fd_head;
3112 * If we've already seen this frame, look it up in the
3113 * table of reassembled packets, otherwise add it to
3114 * whatever reassembly is in progress, if any, and see
3117 fd_head = fragment_add_seq_802_11(next_tvb, hdr_len, pinfo, seq_number,
3118 wlan_fragment_table,
3119 wlan_reassembled_table,
3123 next_tvb = process_reassembled_data(tvb, hdr_len, pinfo,
3124 "Reassembled 802.11", fd_head,
3125 &frag_items, NULL, hdr_tree);
3128 * If this is the first fragment, dissect its contents, otherwise
3129 * just show it as a fragment.
3131 if (frag_number != 0) {
3132 /* Not the first fragment - don't dissect it. */
3135 /* First fragment, or not fragmented. Dissect what we have here. */
3137 /* Get a tvbuff for the payload. */
3138 next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len);
3141 * If this is the first fragment, but not the only fragment,
3142 * tell the next protocol that.
3145 pinfo->fragmented = TRUE;
3147 pinfo->fragmented = FALSE;
3151 if (next_tvb == NULL) {
3152 /* Just show this as an incomplete fragment. */
3153 if (check_col(pinfo->cinfo, COL_INFO))
3154 col_set_str(pinfo->cinfo, COL_INFO, "Fragmented IEEE 802.11 frame");
3155 next_tvb = tvb_new_subset (tvb, hdr_len, len, reported_len);
3156 call_dissector(data_handle, next_tvb, pinfo, tree);
3157 pinfo->fragmented = save_fragmented;
3161 switch (FCF_FRAME_TYPE (fcf))
3165 dissect_ieee80211_mgt (fcf, next_tvb, pinfo, tree);
3170 /* I guess some bridges take Netware Ethernet_802_3 frames,
3171 which are 802.3 frames (with a length field rather than
3172 a type field, but with no 802.2 header in the payload),
3173 and just stick the payload into an 802.11 frame. I've seen
3174 captures that show frames of that sort.
3176 We also handle some odd form of encapsulation in which a
3177 complete Ethernet frame is encapsulated within an 802.11
3178 data frame, with no 802.2 header. This has been seen
3181 So, if the packet doesn't start with 0xaa 0xaa:
3183 we first use the same scheme that linux-wlan-ng does to detect
3184 those encapsulated Ethernet frames, namely looking to see whether
3185 the frame either starts with 6 octets that match the destination
3186 address from the 802.11 header or has 6 octets that match the
3187 source address from the 802.11 header following the first 6 octets,
3188 and, if so, treat it as an encapsulated Ethernet frame;
3190 otherwise, we use the same scheme that we use in the Ethernet
3191 dissector to recognize Netware 802.3 frames, namely checking
3192 whether the packet starts with 0xff 0xff and, if so, treat it
3193 as an encapsulated IPX frame. */
3194 encap_type = ENCAP_802_2;
3196 octet1 = tvb_get_guint8(next_tvb, 0);
3197 octet2 = tvb_get_guint8(next_tvb, 1);
3198 if (octet1 != 0xaa || octet2 != 0xaa) {
3199 src = tvb_get_ptr (next_tvb, 6, 6);
3200 dst = tvb_get_ptr (next_tvb, 0, 6);
3201 if (memcmp(src, pinfo->dl_src.data, 6) == 0 ||
3202 memcmp(dst, pinfo->dl_dst.data, 6) == 0)
3203 encap_type = ENCAP_ETHERNET;
3204 else if (octet1 == 0xff && octet2 == 0xff)
3205 encap_type = ENCAP_IPX;
3208 CATCH2(BoundsError, ReportedBoundsError) {
3214 switch (encap_type) {
3217 call_dissector(llc_handle, next_tvb, pinfo, tree);
3220 case ENCAP_ETHERNET:
3221 call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree);
3225 call_dissector(ipx_handle, next_tvb, pinfo, tree);
3230 pinfo->fragmented = save_fragmented;
3233 tap_queue_packet(wlan_tap, pinfo, whdr);
3237 * Dissect 802.11 with a variable-length link-layer header.
3240 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3242 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
3243 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
3247 * Dissect 802.11 with a variable-length link-layer header and data padding.
3250 dissect_ieee80211_datapad (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3252 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
3253 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, TRUE);
3257 * Dissect 802.11 with a variable-length link-layer header and a pseudo-
3258 * header containing radio information.
3261 dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3263 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE,
3264 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
3268 * Dissect 802.11 with a variable-length link-layer header and a byte-swapped
3269 * control field (some hardware sends out LWAPP-encapsulated 802.11
3270 * packets with the control field byte swapped).
3273 dissect_ieee80211_bsfc (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3275 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE, FALSE);
3279 * Dissect 802.11 with a fixed-length link-layer header (padded to the
3283 dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3285 dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE, FALSE);
3289 wlan_defragment_init(void)
3291 fragment_table_init(&wlan_fragment_table);
3292 reassembled_table_init(&wlan_reassembled_table);
3296 proto_register_ieee80211 (void)
3298 static const value_string frame_type[] = {
3299 {MGT_FRAME, "Management frame"},
3300 {CONTROL_FRAME, "Control frame"},
3301 {DATA_FRAME, "Data frame"},
3305 static const value_string tofrom_ds[] = {
3306 {0, "Not leaving DS or network is operating "
3307 "in AD-HOC mode (To DS: 0 From DS: 0)"},
3308 {FLAG_TO_DS, "Frame from STA to DS via an AP (To DS: 1 "
3310 {FLAG_FROM_DS, "Frame from DS to a STA via AP(To DS: 0 "
3312 {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS from one AP to another "
3313 "AP (To DS: 1 From DS: 1)"},
3317 static const true_false_string tods_flag = {
3318 "Frame is entering DS",
3319 "Frame is not entering DS"
3322 static const true_false_string fromds_flag = {
3323 "Frame is exiting DS",
3324 "Frame is not exiting DS"
3327 static const true_false_string more_frags = {
3328 "More fragments follow",
3329 "This is the last fragment"
3332 static const true_false_string retry_flags = {
3333 "Frame is being retransmitted",
3334 "Frame is not being retransmitted"
3337 static const true_false_string pm_flags = {
3338 "STA will go to sleep",
3342 static const true_false_string md_flags = {
3343 "Data is buffered for STA at AP",
3347 static const true_false_string protected_flags = {
3348 "Data is protected",
3349 "Data is not protected"
3352 static const true_false_string order_flags = {
3354 "Not strictly ordered"
3357 static const true_false_string cf_ess_flags = {
3358 "Transmitter is an AP",
3359 "Transmitter is a STA"
3363 static const true_false_string cf_privacy_flags = {
3364 "AP/STA can support WEP",
3365 "AP/STA cannot support WEP"
3368 static const true_false_string cf_preamble_flags = {
3369 "Short preamble allowed",
3370 "Short preamble not allowed"
3373 static const true_false_string cf_pbcc_flags = {
3374 "PBCC modulation allowed",
3375 "PBCC modulation not allowed"
3378 static const true_false_string cf_agility_flags = {
3379 "Channel agility in use",
3380 "Channel agility not in use"
3383 static const true_false_string short_slot_time_flags = {
3384 "Short slot time in use",
3385 "Short slot time not in use"
3388 static const true_false_string dsss_ofdm_flags = {
3389 "DSSS-OFDM modulation allowed",
3390 "DSSS-OFDM modulation not allowed"
3393 static const true_false_string cf_spec_man_flags = {
3394 "dot11SpectrumManagementRequired TRUE",
3395 "dot11SpectrumManagementRequired FALSE",
3398 static const true_false_string cf_apsd_flags = {
3400 "apsd not implemented",
3403 static const true_false_string cf_del_blk_ack_flags = {
3404 "delayed block ack implemented",
3405 "delayed block ack not implented",
3408 static const true_false_string cf_imm_blk_ack_flags = {
3409 "immediate block ack implemented",
3410 "immediate block ack not implented",
3412 static const true_false_string cf_ibss_flags = {
3413 "Transmitter belongs to an IBSS",
3414 "Transmitter belongs to a BSS"
3417 static const true_false_string eosp_flag = {
3418 "End of service period",
3422 static const value_string sta_cf_pollable[] = {
3423 {0x00, "Station is not CF-Pollable"},
3424 {0x02, "Station is CF-Pollable, "
3425 "not requesting to be placed on the CF-polling list"},
3426 {0x01, "Station is CF-Pollable, "
3427 "requesting to be placed on the CF-polling list"},
3428 {0x03, "Station is CF-Pollable, requesting never to be polled"},
3429 {0x0200, "QSTA requesting association in QBSS"},
3433 static const value_string ap_cf_pollable[] = {
3434 {0x00, "No point coordinator at AP"},
3435 {0x02, "Point coordinator at AP for delivery only (no polling)"},
3436 {0x01, "Point coordinator at AP for delivery and polling"},
3438 {0x0200, "QAP (HC) does not use CFP for delivery of unicast data type frames"},
3439 {0x0202, "QAP (HC) uses CFP for delivery, but does not send CF-Polls to non-QoS STAs"},
3440 {0x0201, "QAP (HC) uses CFP for delivery, and sends CF-Polls to non-QoS STAs"},
3441 {0x0203, "Reserved"},
3446 static const value_string auth_alg[] = {
3447 {0x00, "Open System"},
3448 {0x01, "Shared key"},
3449 {0x80, "Network EAP"}, /* Cisco proprietary? */
3453 static const value_string reason_codes[] = {
3455 {0x01, "Unspecified reason"},
3456 {0x02, "Previous authentication no longer valid"},
3457 {0x03, "Deauthenticated because sending STA is leaving (has left) "
3459 {0x04, "Disassociated due to inactivity"},
3460 {0x05, "Disassociated because AP is unable to handle all currently "
3461 "associated stations"},
3462 {0x06, "Class 2 frame received from nonauthenticated station"},
3463 {0x07, "Class 3 frame received from nonassociated station"},
3464 {0x08, "Disassociated because sending STA is leaving (has left) BSS"},
3465 {0x09, "Station requesting (re)association is not authenticated with "
3466 "responding station"},
3467 {0x0A, "Disassociated because the information in the Power Capability "
3468 "element is unacceptable"},
3469 {0x0B, "Disassociated because the information in the Supported"
3470 "Channels element is unacceptable"},
3471 {0x0D, "Invalid Information Element"},
3472 {0x0E, "Michael MIC failure"},
3473 {0x0F, "4-Way Handshake timeout"},
3474 {0x10, "Group key update timeout"},
3475 {0x11, "Information element in 4-Way Handshake different from "
3476 "(Re)Association Request/Probe Response/Beacon"},
3477 {0x12, "Group Cipher is not valid"},
3478 {0x13, "Pairwise Cipher is not valid"},
3479 {0x14, "AKMP is not valid"},
3480 {0x15, "Unsupported RSN IE version"},
3481 {0x16, "Invalid RSN IE Capabilities"},
3482 {0x17, "IEEE 802.1X Authentication failed"},
3483 {0x18, "Cipher suite is rejected per security policy"},
3484 {0x20, "Disassociated for unspecified, QoS-related reason"},
3485 {0x21, "Disassociated because QAP lacks sufficient bandwidth for this QSTA"},
3486 {0x22, "Disassociated because of excessive number of frames that need to be "
3487 "acknowledged, but are not acknowledged for AP transmissions and/or poor "
3488 "channel conditions"},
3489 {0x23, "Disassociated because QSTA is transmitting outside the limits of its TXOPs"},
3490 {0x24, "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)"},
3491 {0x25, "Requested from peer QSTA as it does not want to use the mechanism"},
3492 {0x26, "Requested from peer QSTA as the QSTA received frames using the mechanism "
3493 "for which a set up is required"},
3494 {0x27, "Requested from peer QSTA due to time out"},
3495 {0x2D, "Peer QSTA does not support the requested cipher suite"},
3500 static const value_string status_codes[] = {
3501 {0x00, "Successful"},
3502 {0x01, "Unspecified failure"},
3503 {0x0A, "Cannot support all requested capabilities in the "
3504 "Capability information field"},
3505 {0x0B, "Reassociation denied due to inability to confirm that "
3506 "association exists"},
3507 {0x0C, "Association denied due to reason outside the scope of this "
3510 {0x0D, "Responding station does not support the specified authentication "
3512 {0x0E, "Received an Authentication frame with authentication sequence "
3513 "transaction sequence number out of expected sequence"},
3514 {0x0F, "Authentication rejected because of challenge failure"},
3515 {0x10, "Authentication rejected due to timeout waiting for next "
3516 "frame in sequence"},
3517 {0x11, "Association denied because AP is unable to handle additional "
3518 "associated stations"},
3519 {0x12, "Association denied due to requesting station not supporting all "
3520 "of the datarates in the BSSBasicServiceSet Parameter"},
3521 {0x13, "Association denied due to requesting station not supporting "
3522 "short preamble operation"},
3523 {0x14, "Association denied due to requesting station not supporting "
3525 {0x15, "Association denied due to requesting station not supporting "
3527 {0x16, "Association request rejected because Spectrum Management"
3528 "capability is required"},
3529 {0x17, "Association request rejected because the information in the"
3530 "Power Capability element is unacceptable"},
3531 {0x18, "Association request rejected because the information in the"
3532 "Supported Channels element is unacceptable"},
3533 {0x19, "Association denied due to requesting station not supporting "
3534 "short slot operation"},
3535 {0x1A, "Association denied due to requesting station not supporting "
3536 "DSSS-OFDM operation"},
3537 {0x20, "Unspecified, QoS-related failure"},
3538 {0x21, "Association denied due to QAP having insufficient bandwidth "
3539 "to handle another QSTA"},
3540 {0x22, "Association denied due to excessive frame loss rates and/or "
3541 "poor conditions on current operating channel"},
3542 {0x23, "Association (with QBSS) denied due to requesting station not "
3543 "supporting the QoS facility"},
3544 {0x24, "Association denied due to requesting station not supporting "
3546 {0x25, "The request has been declined."},
3547 {0x26, "The request has not been successful as one or more parameters "
3548 "have invalid values."},
3549 {0x27, "The TS has not been created because the request cannot be honored. "
3550 "However, a suggested TSPEC is provided so that the initiating QSTA may "
3551 "attempt to set another TS with the suggested changes to the TSPEC."},
3552 {0x28, "Invalid Information Element"},
3553 {0x29, "Group Cipher is not valid"},
3554 {0x2A, "Pairwise Cipher is not valid"},
3555 {0x2B, "AKMP is not valid"},
3556 {0x2C, "Unsupported RSN IE version"},
3557 {0x2D, "Invalid RSN IE Capabilities"},
3558 {0x2E, "Cipher suite is rejected per security policy"},
3559 {0x2F, "The TS has not been created. However, the HC may be capable of "
3560 "creating a TS, in response to a request, after the time indicated in the TS Delay element."},
3561 {0x30, "Direct Link is not allowed in the BSS by policy"},
3562 {0x31, "Destination STA is not present within this QBSS."},
3563 {0x32, "The Destination STA is not a QSTA."},
3567 static const value_string category_codes[] = {
3568 {CAT_SPECTRUM_MGMT, "Spectrum Management"},
3571 {CAT_BLOCK_ACK, "Block Ack"},
3572 {CAT_MGMT_NOTIFICATION, "Management notification frame"},
3576 static const value_string action_codes[] ={
3577 {SM_ACTION_MEASUREMENT_REQUEST, "Measurement Request"},
3578 {SM_ACTION_MEASUREMENT_REPORT, "Measurement Report"},
3579 {SM_ACTION_TPC_REQUEST, "TPC Request"},
3580 {SM_ACTION_TPC_REPORT, "TPC Report"},
3581 {SM_ACTION_CHAN_SWITCH_ANNC, "Channel Switch Announcement"},
3585 static const value_string wme_action_codes[] = {
3586 {0x00, "Setup request"},
3587 {0x01, "Setup response"},
3592 static const value_string wme_status_codes[] = {
3593 {0x00, "Admission accepted"},
3594 {0x01, "Invalid parameters"},
3599 static const value_string ack_policy[] = {
3600 {0x00, "Normal Ack"},
3602 {0x01, "No explicit Ack"},
3603 {0x03, "Block Ack"},
3607 static hf_register_info hf[] = {
3609 {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
3610 "Data rate (.5 Mb/s units)", HFILL }},
3613 {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
3614 "Radio channel", HFILL }},
3616 {&hf_signal_strength,
3617 {"Signal Strength", "wlan.signal_strength", FT_UINT8, BASE_DEC, NULL, 0,
3618 "Signal strength (percentage)", HFILL }},
3621 {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
3622 "MAC Frame control", HFILL }},
3624 {&hf_fc_proto_version,
3625 {"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
3626 "MAC Protocol version", HFILL }}, /* 0 */
3629 {"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, VALS(frame_type), 0,
3630 "Frame type", HFILL }},
3632 {&hf_fc_frame_subtype,
3633 {"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
3634 "Frame subtype", HFILL }}, /* 2 */
3636 {&hf_fc_frame_type_subtype,
3637 {"Type/Subtype", "wlan.fc.type_subtype", FT_UINT16, BASE_DEC, VALS(frame_type_subtype_vals), 0,
3638 "Type and subtype combined", HFILL }},
3641 {"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
3642 "Protocol flags", HFILL }},
3645 {"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, VALS (&tofrom_ds), 0,
3646 "Data-frame DS-traversal status", HFILL }}, /* 3 */
3649 {"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), FLAG_TO_DS,
3650 "To DS flag", HFILL }}, /* 4 */
3653 {"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), FLAG_FROM_DS,
3654 "From DS flag", HFILL }}, /* 5 */
3657 {"More Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), FLAG_MORE_FRAGMENTS,
3658 "More Fragments flag", HFILL }}, /* 6 */
3661 {"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), FLAG_RETRY,
3662 "Retransmission flag", HFILL }},
3665 {"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), FLAG_POWER_MGT,
3666 "Power management status", HFILL }},
3669 {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
3670 "More data flag", HFILL }},
3673 {"Protected flag", "wlan.fc.protected", FT_BOOLEAN, 8, TFS (&protected_flags), FLAG_PROTECTED,
3674 "Protected flag", HFILL }},
3677 {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
3678 "Strictly ordered flag", HFILL }},
3681 {"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
3682 "Association-ID field", HFILL }},
3685 {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
3686 "Duration field", HFILL }},
3689 {"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
3690 "Destination Hardware Address", HFILL }},
3693 {"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
3694 "Source Hardware Address", HFILL }},
3697 {"Source or Destination address", "wlan.addr", FT_ETHER, BASE_NONE, NULL, 0,
3698 "Source or Destination Hardware Address", HFILL }},
3701 {"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
3702 "Receiving Station Hardware Address", HFILL }},
3705 {"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
3706 "Transmitting Station Hardware Address", HFILL }},
3709 {"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
3710 "Basic Service Set ID", HFILL }},
3713 {"Fragment number", "wlan.frag", FT_UINT16, BASE_DEC, NULL, 0,
3714 "Fragment number", HFILL }},
3717 {"Sequence number", "wlan.seq", FT_UINT16, BASE_DEC, NULL, 0,
3718 "Sequence number", HFILL }},
3721 {"Priority", "wlan.qos.priority", FT_UINT16, BASE_DEC, NULL, 0,
3722 "802.1D Tag", HFILL }},
3725 {"EOSP", "wlan.qos.eosp", FT_BOOLEAN, 8, TFS (&eosp_flag), QOS_FLAG_EOSP,
3726 "EOSP Field", HFILL }},
3728 {&hf_qos_ack_policy,
3729 {"Ack Policy", "wlan.qos.ack", FT_UINT16, BASE_HEX, VALS (&ack_policy), 0,
3730 "Ack Policy", HFILL }},
3732 {&hf_qos_field_content,
3733 {"Content", "wlan.qos.fc_content", FT_UINT16, BASE_DEC, NULL, 0,
3734 "Content1", HFILL }},
3736 /* {&hf_qos_buffer_state,
3737 {"QAP PS buffer State", "wlan.qos.ps_buf_state", FT_UINT16, BASE_DEC, NULL, 0,
3738 "QAP PS buffer State", HFILL }},
3740 {&hf_qos_txop_dur_req,
3741 {"TXOP Duration Requested", "wlan.qos.txop_dur_req", FT_UINT16, BASE_DEC, NULL, 0,
3742 "TXOP Duration Requested", HFILL }},
3744 {&hf_qos_queue_size,
3745 {"Queue Size", "wlan.qos.queue_size", FT_UINT16, BASE_DEC, NULL, 0,
3746 "Queue Size", HFILL }},*/
3749 {"Frame check sequence", "wlan.fcs", FT_UINT32, BASE_HEX,
3750 NULL, 0, "FCS", HFILL }},
3752 {&hf_fragment_overlap,
3753 {"Fragment overlap", "wlan.fragment.overlap", FT_BOOLEAN, BASE_NONE,
3754 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
3756 {&hf_fragment_overlap_conflict,
3757 {"Conflicting data in fragment overlap", "wlan.fragment.overlap.conflict",
3758 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3759 "Overlapping fragments contained conflicting data", HFILL }},
3761 {&hf_fragment_multiple_tails,
3762 {"Multiple tail fragments found", "wlan.fragment.multipletails",
3763 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3764 "Several tails were found when defragmenting the packet", HFILL }},
3766 {&hf_fragment_too_long_fragment,
3767 {"Fragment too long", "wlan.fragment.toolongfragment",
3768 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3769 "Fragment contained data past end of packet", HFILL }},
3771 {&hf_fragment_error,
3772 {"Defragmentation error", "wlan.fragment.error",
3773 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3774 "Defragmentation error due to illegal fragments", HFILL }},
3777 {"802.11 Fragment", "wlan.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3778 "802.11 Fragment", HFILL }},
3781 {"802.11 Fragments", "wlan.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
3782 "802.11 Fragments", HFILL }},
3784 {&hf_reassembled_in,
3785 {"Reassembled 802.11 in frame", "wlan.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3786 "This 802.11 packet is reassembled in this frame", HFILL }},
3789 {"Initialization Vector", "wlan.wep.iv", FT_UINT24, BASE_HEX, NULL, 0,
3790 "Initialization Vector", HFILL }},
3793 {"Weak IV", "wlan.wep.weakiv", FT_BOOLEAN,BASE_NONE, NULL,0x0,
3797 {"TKIP Ext. Initialization Vector", "wlan.tkip.extiv", FT_STRING,
3798 BASE_HEX, NULL, 0, "TKIP Extended Initialization Vector", HFILL }},
3801 {"CCMP Ext. Initialization Vector", "wlan.ccmp.extiv", FT_STRING,
3802 BASE_HEX, NULL, 0, "CCMP Extended Initialization Vector", HFILL }},
3805 {"Key Index", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
3806 "Key Index", HFILL }},
3809 {"WEP ICV", "wlan.wep.icv", FT_UINT32, BASE_HEX, NULL, 0,
3810 "WEP ICV", HFILL }},
3813 static const true_false_string rsn_preauth_flags = {
3814 "Transmitter supports pre-authentication",
3815 "Transmitter does not support pre-authentication"
3818 static const true_false_string rsn_no_pairwise_flags = {
3819 "Transmitter cannot support WEP default key 0 simultaneously with "
3821 "Transmitter can support WEP default key 0 simultaneously with "
3825 static const value_string rsn_cap_replay_counter[] = {
3826 {0x00, "1 replay counter per PTKSA/GTKSA/STAKeySA"},
3827 {0x01, "2 replay counters per PTKSA/GTKSA/STAKeySA"},
3828 {0x02, "4 replay counters per PTKSA/GTKSA/STAKeySA"},
3829 {0x03, "16 replay counters per PTKSA/GTKSA/STAKeySA"},
3833 static hf_register_info ff[] = {
3835 {"Timestamp", "wlan_mgt.fixed.timestamp", FT_STRING, BASE_NONE,
3836 NULL, 0, "", HFILL }},
3839 {"Authentication Algorithm", "wlan_mgt.fixed.auth.alg",
3840 FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, "", HFILL }},
3842 {&ff_beacon_interval,
3843 {"Beacon Interval", "wlan_mgt.fixed.beacon", FT_DOUBLE, BASE_DEC, NULL, 0,
3846 {&hf_fixed_parameters,
3847 {"Fixed parameters", "wlan_mgt.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
3850 {&hf_tagged_parameters,
3851 {"Tagged parameters", "wlan_mgt.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
3855 {"Capabilities", "wlan_mgt.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
3856 "Capability information", HFILL }},
3859 {"ESS capabilities", "wlan_mgt.fixed.capabilities.ess",
3860 FT_BOOLEAN, 16, TFS (&cf_ess_flags), 0x0001, "ESS capabilities", HFILL }},
3863 {"IBSS status", "wlan_mgt.fixed.capabilities.ibss",
3864 FT_BOOLEAN, 16, TFS (&cf_ibss_flags), 0x0002, "IBSS participation", HFILL }},
3867 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.sta",
3868 FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0x020C,
3869 "CF-Poll capabilities for a STA", HFILL }},
3872 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.ap",
3873 FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0x020C,
3874 "CF-Poll capabilities for an AP", HFILL }},
3877 {"Privacy", "wlan_mgt.fixed.capabilities.privacy",
3878 FT_BOOLEAN, 16, TFS (&cf_privacy_flags), 0x0010, "WEP support", HFILL }},
3881 {"Short Preamble", "wlan_mgt.fixed.capabilities.preamble",
3882 FT_BOOLEAN, 16, TFS (&cf_preamble_flags), 0x0020, "Short Preamble", HFILL }},
3885 {"PBCC", "wlan_mgt.fixed.capabilities.pbcc",
3886 FT_BOOLEAN, 16, TFS (&cf_pbcc_flags), 0x0040, "PBCC Modulation", HFILL }},
3889 {"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
3890 FT_BOOLEAN, 16, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
3893 {"Spectrum Management", "wlan_mgt.fixed.capabilities.spec_man",
3894 FT_BOOLEAN, 16, TFS (&cf_spec_man_flags), 0x0100, "Spectrum Management", HFILL }},
3896 {&ff_short_slot_time,
3897 {"Short Slot Time", "wlan_mgt.fixed.capabilities.short_slot_time",
3898 FT_BOOLEAN, 16, TFS (&short_slot_time_flags), 0x0400, "Short Slot Time",
3902 {"Automatic Power Save Delivery", "wlan_mgt.fixed.capabilities.apsd",
3903 FT_BOOLEAN, 16, TFS (&cf_apsd_flags), 0x0800, "Automatic Power Save "
3904 "Delivery", HFILL }},
3907 {"DSSS-OFDM", "wlan_mgt.fixed.capabilities.dsss_ofdm",
3908 FT_BOOLEAN, 16, TFS (&dsss_ofdm_flags), 0x2000, "DSSS-OFDM Modulation",
3911 {&ff_cf_del_blk_ack,
3912 {"Delayed Block Ack", "wlan_mgt.fixed.capabilities.del_blk_ack",
3913 FT_BOOLEAN, 16, TFS (&cf_del_blk_ack_flags), 0x4000, "Delayed Block "
3916 {&ff_cf_imm_blk_ack,
3917 {"Immediate Block Ack", "wlan_mgt.fixed.capabilities.imm_blk_ack",
3918 FT_BOOLEAN, 16, TFS (&cf_imm_blk_ack_flags), 0x8000, "Immediate Block "
3922 {"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
3923 FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
3926 {"Association ID", "wlan_mgt.fixed.aid",
3927 FT_UINT16, BASE_HEX, NULL, 0, "Association ID", HFILL }},
3930 {"Listen Interval", "wlan_mgt.fixed.listen_ival",
3931 FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval", HFILL }},
3934 {"Current AP", "wlan_mgt.fixed.current_ap",
3935 FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP", HFILL }},
3938 {"Reason code", "wlan_mgt.fixed.reason_code",
3939 FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
3940 "Reason for unsolicited notification", HFILL }},
3943 {"Status code", "wlan_mgt.fixed.status_code",
3944 FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
3945 "Status of requested event", HFILL }},
3948 {"Category code", "wlan_mgt.fixed.category_code",
3949 FT_UINT16, BASE_DEC, VALS (&category_codes), 0,
3950 "Management action category", HFILL }},
3953 {"Action code", "wlan_mgt.fixed.action_code",
3954 FT_UINT16, BASE_DEC, VALS (&action_codes), 0,
3955 "Management action code", HFILL }},
3958 {"Dialog token", "wlan_mgt.fixed.dialog_token",
3959 FT_UINT16, BASE_HEX, NULL, 0, "Management action dialog token", HFILL }},
3961 {&ff_wme_action_code,
3962 {"Action code", "wlan_mgt.fixed.action_code",
3963 FT_UINT16, BASE_HEX, VALS (&wme_action_codes), 0,
3964 "Management notification action code", HFILL }},
3966 {&ff_wme_status_code,
3967 {"Status code", "wlan_mgt.fixed.status_code",
3968 FT_UINT16, BASE_HEX, VALS (&wme_status_codes), 0,
3969 "Management notification setup response status code", HFILL }},
3972 {"Tag", "wlan_mgt.tag.number",
3973 FT_UINT8, BASE_DEC, VALS(tag_num_vals), 0,
3974 "Element ID", HFILL }},
3977 {"Tag length", "wlan_mgt.tag.length",
3978 FT_UINT8, BASE_DEC, NULL, 0, "Length of tag", HFILL }},
3980 {&tag_interpretation,
3981 {"Tag interpretation", "wlan_mgt.tag.interpretation",
3982 FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }},
3985 {"OUI", "wlan_mgt.tag.oui",
3986 FT_BYTES, BASE_NONE, NULL, 0, "OUI of vendor specific IE", HFILL }},
3989 {"TIM length", "wlan_mgt.tim.length",
3990 FT_UINT8, BASE_DEC, NULL, 0,
3991 "Traffic Indication Map length", HFILL }},
3994 {"DTIM count", "wlan_mgt.tim.dtim_count",
3995 FT_UINT8, BASE_DEC, NULL, 0,
3996 "DTIM count", HFILL }},
3999 {"DTIM period", "wlan_mgt.tim.dtim_period",
4000 FT_UINT8, BASE_DEC, NULL, 0,
4001 "DTIM period", HFILL }},
4004 {"Bitmap control", "wlan_mgt.tim.bmapctl",
4005 FT_UINT8, BASE_HEX, NULL, 0,
4006 "Bitmap control", HFILL }},
4009 {"RSN Capabilities", "wlan_mgt.rsn.capabilities", FT_UINT16, BASE_HEX,
4010 NULL, 0, "RSN Capability information", HFILL }},
4013 {"RSN Pre-Auth capabilities", "wlan_mgt.rsn.capabilities.preauth",
4014 FT_BOOLEAN, 16, TFS (&rsn_preauth_flags), 0x0001,
4015 "RSN Pre-Auth capabilities", HFILL }},
4017 {&rsn_cap_no_pairwise,
4018 {"RSN No Pairwise capabilities", "wlan_mgt.rsn.capabilities.no_pairwise",
4019 FT_BOOLEAN, 16, TFS (&rsn_no_pairwise_flags), 0x0002,
4020 "RSN No Pairwise capabilities", HFILL }},
4022 {&rsn_cap_ptksa_replay_counter,
4023 {"RSN PTKSA Replay Counter capabilities",
4024 "wlan_mgt.rsn.capabilities.ptksa_replay_counter",
4025 FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x000C,
4026 "RSN PTKSA Replay Counter capabilities", HFILL }},
4028 {&rsn_cap_gtksa_replay_counter,
4029 {"RSN GTKSA Replay Counter capabilities",
4030 "wlan_mgt.rsn.capabilities.gtksa_replay_counter",
4031 FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x0030,
4032 "RSN GTKSA Replay Counter capabilities", HFILL }},
4034 {&hf_aironet_ie_type,
4035 {"Aironet IE type", "wlan_mgt.aironet.type",
4036 FT_UINT8, BASE_DEC, VALS(aironet_ie_type_vals), 0, "", HFILL }},
4038 {&hf_aironet_ie_version,
4039 {"Aironet IE CCX version?", "wlan_mgt.aironet.version",
4040 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4042 { &hf_aironet_ie_data,
4043 { "Aironet IE data", "wlan_mgmt.aironet.data",
4044 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
4047 {"QBSS Version", "wlan_mgt.qbss.version",
4048 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4051 {"Station Count", "wlan_mgt.qbss.scount",
4052 FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
4055 {"Channel Utilization", "wlan_mgt.qbss.cu",
4056 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4059 {"Available Admission Capabilities", "wlan_mgt.qbss.adc",
4060 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4063 {"Channel Utilization", "wlan_mgt.qbss2.cu",
4064 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4067 {"G.711 CU Quantum", "wlan_mgt.qbss2.glimit",
4068 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4071 {"Call Admission Limit", "wlan_mgt.qbss2.cal",
4072 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4075 {"Station Count", "wlan_mgt.qbss2.scount",
4076 FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
4078 {&hf_aironet_ie_qos_unk1,
4079 {"Aironet IE QoS unknown1", "wlan_mgt.aironet.qos.unk1",
4080 FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
4082 {&hf_aironet_ie_qos_paramset,
4083 {"Aironet IE QoS paramset", "wlan_mgt.aironet.qos.paramset",
4084 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4086 {&hf_aironet_ie_qos_val,
4087 {"Aironet IE QoS valueset", "wlan_mgt.aironet.qos.val",
4088 FT_BYTES, BASE_NONE, NULL, 0, "", HFILL }},
4092 static gint *tree_array[] = {
4099 &ett_fixed_parameters,
4100 &ett_tagged_parameters,
4101 &ett_qos_parameters,
4102 &ett_qos_ps_buf_state,
4103 &ett_wep_parameters,
4108 module_t *wlan_module;
4110 static const enum_val_t wep_keys_options[] = {
4120 proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
4121 "IEEE 802.11", "wlan");
4122 proto_register_field_array (proto_wlan, hf, array_length (hf));
4123 proto_wlan_mgt = proto_register_protocol ("IEEE 802.11 wireless LAN management frame",
4124 "802.11 MGT", "wlan_mgt");
4125 proto_register_field_array (proto_wlan_mgt, ff, array_length (ff));
4126 proto_register_subtree_array (tree_array, array_length (tree_array));
4128 register_dissector("wlan", dissect_ieee80211, proto_wlan);
4129 register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
4130 register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan);
4131 register_dissector("wlan_datapad", dissect_ieee80211_datapad, proto_wlan);
4132 register_init_routine(wlan_defragment_init);
4134 wlan_tap = register_tap("wlan");
4136 /* Register configuration options */
4137 wlan_module = prefs_register_protocol(proto_wlan, init_wepkeys);
4138 prefs_register_bool_preference(wlan_module, "defragment",
4139 "Reassemble fragmented 802.11 datagrams",
4140 "Whether fragmented 802.11 datagrams should be reassembled",
4143 prefs_register_bool_preference(wlan_module, "check_fcs",
4144 "Assume packets have FCS",
4145 "Some 802.11 cards include the FCS at the end of a packet, others do not.",
4148 prefs_register_bool_preference(wlan_module, "ignore_wep",
4149 "Ignore the WEP bit",
4150 "Some 802.11 cards leave the WEP bit set even though the packet is decrypted.",
4154 prefs_register_enum_preference(wlan_module, "wep_keys",
4156 "How many WEP keys do we have to choose from? (0 to disable, up to 4)",
4157 &num_wepkeys, wep_keys_options, FALSE);
4159 prefs_register_string_preference(wlan_module, "wep_key1",
4161 "First WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
4163 prefs_register_string_preference(wlan_module, "wep_key2",
4165 "Second WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
4167 prefs_register_string_preference(wlan_module, "wep_key3",
4169 "Third WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
4171 prefs_register_string_preference(wlan_module, "wep_key4",
4173 "Fourth WEP key (A:B:C:D:E) [40bit] (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
4179 proto_reg_handoff_ieee80211(void)
4181 dissector_handle_t ieee80211_handle;
4182 dissector_handle_t ieee80211_radio_handle;
4185 * Get handles for the LLC, IPX and Ethernet dissectors.
4187 llc_handle = find_dissector("llc");
4188 ipx_handle = find_dissector("ipx");
4189 eth_withoutfcs_handle = find_dissector("eth_withoutfcs");
4190 data_handle = find_dissector("data");
4192 ieee80211_handle = find_dissector("wlan");
4193 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle);
4194 ieee80211_radio_handle = create_dissector_handle(dissect_ieee80211_radio,
4196 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
4197 ieee80211_radio_handle);
4198 dissector_add("ethertype", ETHERTYPE_CENTRINO_PROMISC, ieee80211_handle);
4201 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len) {
4202 const guint8 *enc_data;
4205 tvbuff_t *decr_tvb = NULL;
4207 if (num_wepkeys < 1)
4210 enc_data = tvb_get_ptr(tvb, offset, len);
4212 if ((tmp = g_malloc(len)) == NULL)
4213 return NULL; /* krap! */
4215 /* try once with the key index in the packet, then look through our list. */
4216 for (i = -1; i < num_wepkeys; i++) {
4217 /* copy the encrypted data over to the tmp buffer */
4219 printf("trying %d\n", i);
4221 memcpy(tmp, enc_data, len);
4222 if (wep_decrypt(tmp, len, i) == 0) {
4224 /* decrypt successful, let's set up a new data tvb. */
4225 decr_tvb = tvb_new_real_data(tmp, len-8, len-8);
4226 tvb_set_free_cb(decr_tvb, g_free);
4227 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
4234 if ((!decr_tvb) && (tmp)) g_free(tmp);
4237 printf("de-wep %p\n", decr_tvb);
4244 /* de-weps the block. if successful, buf* will point to the data start. */
4245 static int wep_decrypt(guint8 *buf, guint32 len, int key_override) {
4246 guint32 i, j, k, crc, keylen;
4247 guint8 s[256], key[128], c_crc[4];
4248 guint8 keyidx, *dpos, *cpos;
4250 /* Needs to be at least 8 bytes of payload */
4254 /* initialize the first bytes of the key from the IV */
4258 keyidx = KEY_OCTET_WEP_KEY(buf[3]);
4260 if (key_override >= 0)
4261 keyidx = key_override;
4263 if (keyidx >= (guint)num_wepkeys)
4266 keylen = wep_keylens[keyidx];
4270 if (wep_keys[keyidx] == NULL)
4273 keylen+=3; /* add in ICV bytes */
4275 /* copy the rest of the key over from the designated key */
4276 memcpy(key+3, wep_keys[keyidx], wep_keylens[keyidx]);
4279 printf("%d: %02x %02x %02x (%d %d) %02x:%02x:%02x:%02x:%02x\n", len, key[0], key[1], key[2], keyidx, keylen, key[3], key[4], key[5], key[6], key[7]);
4282 /* set up the RC4 state */
4283 for (i = 0; i < 256; i++)
4286 for (i = 0; i < 256; i++) {
4287 j = (j + s[i] + key[i % keylen]) & 0xff;
4291 /* Apply the RC4 to the data, update the CRC32 */
4296 for (k = 0; k < (len -8); k++) {
4298 j = (j+s[i]) & 0xff;
4301 printf("%d -- %02x ", k, *dpos);
4303 *dpos = *cpos++ ^ s[(s[i] + s[j]) & 0xff];
4305 printf("%02x\n", *dpos);
4307 crc = crc32_ccitt_table[(crc ^ *dpos++) & 0xff] ^ (crc >> 8);
4311 /* now let's check the crc */
4313 c_crc[1] = crc >> 8;
4314 c_crc[2] = crc >> 16;
4315 c_crc[3] = crc >> 24;
4317 for (k = 0; k < 4; k++) {
4319 j = (j+s[i]) & 0xff;
4322 printf("-- %02x %02x\n", *dpos, c_crc[k]);
4324 if ((*cpos++ ^ s[(s[i] + s[j]) & 0xff]) != c_crc[k])
4325 return -1; /* ICV mismatch */
4331 static void init_wepkeys(void) {
4340 tmp = getenv("WIRESHARK_WEPKEYNUM");
4345 num_wepkeys = atoi(tmp);
4347 if (num_wepkeys > 4)
4351 if (num_wepkeys < 1)
4358 g_free(wep_keylens);
4360 wep_keys = g_malloc(num_wepkeys * sizeof(guint8*));
4361 wep_keylens = g_malloc(num_wepkeys * sizeof(int));
4362 bytes = g_byte_array_new();
4364 for (i = 0 ; i < num_wepkeys; i++) {
4370 g_snprintf(buf, 128, "WIRESHARK_WEPKEY%d", i+1);
4373 tmp = wep_keystr[i];
4379 printf("%s -- %s\n", buf, tmp);
4381 printf("%d -- %s\n", i+1, tmp);
4386 g_free(wep_keys[i]);
4389 res = hex_str_to_bytes(tmp, bytes, FALSE);
4390 if (res && bytes->len > 0) {
4391 if (bytes->len > 32) {
4394 wep_keys[i] = g_malloc(32 * sizeof(guint8));
4395 memset(wep_keys[i], 0, 32 * sizeof(guint8));
4396 memcpy(wep_keys[i], bytes->data, bytes->len * sizeof(guint8));
4397 wep_keylens[i] = bytes->len;
4399 printf("%d: %d bytes\n", i, bytes->len);
4400 printf("%d: %s\n", i, bytes_to_str(bytes->data, bytes->len));
4404 printf("res: %d bytes->len: %d\n", res, bytes->len);
4406 g_warning("Could not parse WEP key %d: %s", i + 1, tmp);
4410 g_byte_array_free(bytes, TRUE);
4413 * This code had been taken from AirSnort crack.c function classify()
4414 * Permission granted by snax <at> shmoo dot com
4415 * weak_iv - determine which key byte an iv is useful in resolving
4416 * parm - p, pointer to the first byte of an IV
4417 * return - n - this IV is weak for byte n of a WEP key
4418 * -1 - this IV is not weak for any key bytes
4420 * This function tests for IVs that are known to satisfy the criteria
4421 * for a weak IV as specified in FMS section 7.1
4429 if (iv[1] == 255 && iv[0] > 2 && iv[0] < 16) {
4433 sum = iv[0] + iv[1];
4435 if (iv[2] <= 0x0a) {
4438 else if (iv[2] == 0xff){
4443 if (sum == k && (iv[2] >= 0xf2 && iv[2] <= 0xfe && iv[2] != 0xfd)){