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 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
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 ETHEREAL_WEPKEYNUM=##
105 ETHEREAL_WEPKEY1=aa:bb:cc:dd:...
106 ETHEREAL_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)
744 guint16 fcf, hdr_length;
746 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
751 fcf = pletohs (&pd[0]);
753 if (IS_PROTECTED(FCF_FLAGS(fcf)))
759 switch (COMPOSE_FRAME_TYPE (fcf))
762 case DATA: /* We got a data frame */
763 case DATA_CF_ACK: /* Data with ACK */
765 case DATA_CF_ACK_POLL:
767 if (fixed_length_header)
768 hdr_length = DATA_LONG_HDR_LEN;
770 hdr_length = find_header_length (fcf);
771 /* I guess some bridges take Netware Ethernet_802_3 frames,
772 which are 802.3 frames (with a length field rather than
773 a type field, but with no 802.2 header in the payload),
774 and just stick the payload into an 802.11 frame. I've seen
775 captures that show frames of that sort.
777 This means we have to do the same check for Netware 802.3 -
778 or, if you will, "Netware 802.11" - that we do in the
779 Ethernet dissector, i.e. checking for 0xffff as the first
780 four bytes of the payload and, if we find it, treating it
782 if (!BYTES_ARE_IN_FRAME(offset+hdr_length, len, 2)) {
786 if (pd[offset+hdr_length] == 0xff && pd[offset+hdr_length+1] == 0xff) {
790 capture_llc (pd, offset + hdr_length, len, ld);
801 * Handle 802.11 with a variable-length link-layer header.
804 capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
806 capture_ieee80211_common (pd, offset, len, ld, FALSE);
810 * Handle 802.11 with a fixed-length link-layer header (padded to the
814 capture_ieee80211_fixed (const guchar * pd, int offset, int len, packet_counts * ld)
816 capture_ieee80211_common (pd, offset, len, ld, TRUE);
820 /* ************************************************************************* */
821 /* Add the subtree used to store the fixed parameters */
822 /* ************************************************************************* */
824 get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
826 proto_item *fixed_fields;
828 proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
829 size, size, "Fixed parameters (%d bytes)",
832 return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
836 /* ************************************************************************* */
837 /* Add the subtree used to store tagged parameters */
838 /* ************************************************************************* */
840 get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
842 proto_item *tagged_fields;
844 tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
849 "Tagged parameters (%d bytes)",
852 return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
856 /* ************************************************************************* */
857 /* Dissect and add fixed mgmt fields to protocol tree */
858 /* ************************************************************************* */
860 add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
862 const guint8 *dataptr;
863 char out_buff[SHORT_STR];
865 proto_item *cap_item;
866 static proto_tree *cap_tree;
871 case FIELD_TIMESTAMP:
872 dataptr = tvb_get_ptr (tvb, offset, 8);
873 memset (out_buff, 0, SHORT_STR);
874 g_snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
884 proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
887 case FIELD_BEACON_INTERVAL:
888 capability = tvb_get_letohs (tvb, offset);
889 temp_double = (double)capability;
890 temp_double = temp_double * 1024 / 1000000;
891 proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
892 temp_double,"Beacon Interval: %f [Seconds]",
894 if (check_col (g_pinfo->cinfo, COL_INFO)) {
895 col_append_fstr(g_pinfo->cinfo, COL_INFO, ",BI=%d", capability);
901 capability = tvb_get_letohs (tvb, offset);
903 cap_item = proto_tree_add_uint_format (tree, ff_capture,
906 "Capability Information: 0x%04X",
908 cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree);
909 proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 2,
911 proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 2,
913 if (ESS_SET (capability) != 0) /* This is an AP */
914 proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2,
917 else /* This is a STA */
918 proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
920 proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 2,
922 proto_tree_add_boolean (cap_tree, ff_cf_preamble, tvb, offset, 2,
924 proto_tree_add_boolean (cap_tree, ff_cf_pbcc, tvb, offset, 2,
926 proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 2,
928 proto_tree_add_boolean (cap_tree, ff_cf_spec_man, tvb, offset, 2,
930 proto_tree_add_boolean (cap_tree, ff_short_slot_time, tvb, offset, 2,
932 proto_tree_add_boolean (cap_tree, ff_cf_apsd, tvb, offset, 2,
934 proto_tree_add_boolean (cap_tree, ff_dsss_ofdm, tvb, offset, 2,
936 proto_tree_add_boolean (cap_tree, ff_cf_del_blk_ack, tvb, offset, 2,
938 proto_tree_add_boolean (cap_tree, ff_cf_imm_blk_ack, tvb, offset, 2,
943 proto_tree_add_item (tree, ff_auth_alg, tvb, offset, 2, TRUE);
946 case FIELD_AUTH_TRANS_SEQ:
947 proto_tree_add_item (tree, ff_auth_seq, tvb, offset, 2, TRUE);
950 case FIELD_CURRENT_AP_ADDR:
951 proto_tree_add_item (tree, ff_current_ap, tvb, offset, 6, FALSE);
954 case FIELD_LISTEN_IVAL:
955 proto_tree_add_item (tree, ff_listen_ival, tvb, offset, 2, TRUE);
958 case FIELD_REASON_CODE:
959 proto_tree_add_item (tree, ff_reason, tvb, offset, 2, TRUE);
963 proto_tree_add_uint(tree, ff_assoc_id, tvb, offset, 2,
964 ASSOC_ID(tvb_get_letohs(tvb,offset)));
965 /* proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE); */
968 case FIELD_STATUS_CODE:
969 proto_tree_add_item (tree, ff_status_code, tvb, offset, 2, TRUE);
972 case FIELD_CATEGORY_CODE:
973 proto_tree_add_item (tree, ff_category_code, tvb, offset, 1, TRUE);
976 case FIELD_ACTION_CODE:
977 proto_tree_add_item (tree, ff_action_code, tvb, offset, 1, TRUE);
980 case FIELD_DIALOG_TOKEN:
981 proto_tree_add_item (tree, ff_dialog_token, tvb, offset, 1, TRUE);
984 case FIELD_WME_ACTION_CODE:
985 proto_tree_add_item (tree, ff_wme_action_code, tvb, offset, 1, TRUE);
988 case FIELD_WME_STATUS_CODE:
989 proto_tree_add_item (tree, ff_wme_status_code, tvb, offset, 1, TRUE);
994 static const char *wpa_cipher_str[] =
1005 wpa_cipher_idx2str(guint idx)
1007 if (idx < sizeof(wpa_cipher_str)/sizeof(wpa_cipher_str[0]))
1008 return wpa_cipher_str[idx];
1012 static const char *wpa_keymgmt_str[] =
1020 wpa_keymgmt_idx2str(guint idx)
1022 if (idx < sizeof(wpa_keymgmt_str)/sizeof(wpa_keymgmt_str[0]))
1023 return wpa_keymgmt_str[idx];
1028 dissect_vendor_ie_wpawme(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
1029 int offset, guint32 tag_len, const guint8 *tag_val)
1031 guint32 tag_val_off = 0;
1032 char out_buff[SHORT_STR];
1035 /* Wi-Fi Protected Access (WPA) Information Element */
1036 if (tag_val_off + 6 <= tag_len && !memcmp(tag_val, WPA_OUI"\x01", 4)) {
1037 g_snprintf(out_buff, SHORT_STR, "WPA IE, type %u, version %u",
1038 tag_val[tag_val_off + 3], pletohs(&tag_val[tag_val_off + 4]));
1039 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
1042 if (tag_val_off + 4 <= tag_len) {
1043 /* multicast cipher suite */
1044 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
1045 g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
1046 wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1047 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1050 /* unicast cipher suites */
1051 if (tag_val_off + 2 <= tag_len) {
1052 g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u",
1053 pletohs(tag_val + tag_val_off));
1054 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1058 while (tag_val_off + 4 <= tag_len) {
1059 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
1060 g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
1061 i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1062 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1070 /* authenticated key management suites */
1071 if (tag_val_off + 2 <= tag_len) {
1072 g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u",
1073 pletohs(tag_val + tag_val_off));
1074 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1078 while (tag_val_off + 4 <= tag_len) {
1079 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
1080 g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
1081 i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
1082 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1094 if (tag_val_off < tag_len)
1095 proto_tree_add_string(tree, tag_interpretation, tvb,
1096 offset, tag_len - tag_val_off, "Not interpreted");
1097 proto_item_append_text(ietree, ": WPA");
1098 } else if (tag_val_off + 7 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x00", 5)) {
1099 /* Wireless Multimedia Enhancements (WME) Information Element */
1100 g_snprintf(out_buff, SHORT_STR, "WME IE: type %u, subtype %u, version %u, parameter set %u",
1101 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
1102 tag_val[tag_val_off + 6]);
1103 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
1104 proto_item_append_text(ietree, ": WME");
1105 } else if (tag_val_off + 24 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x01", 5)) {
1106 /* Wireless Multimedia Enhancements (WME) Parameter Element */
1107 g_snprintf(out_buff, SHORT_STR, "WME PE: type %u, subtype %u, version %u, parameter set %u",
1108 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
1109 tag_val[tag_val_off + 6]);
1110 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
1113 for (i = 0; i < 4; i++) {
1114 g_snprintf(out_buff, SHORT_STR, "WME AC Parameters: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
1115 (tag_val[tag_val_off] & 0x60) >> 5,
1116 wme_acs[(tag_val[tag_val_off] & 0x60) >> 5],
1117 (tag_val[tag_val_off] & 0x10) ? "" : "not ",
1118 tag_val[tag_val_off] & 0x0f,
1119 tag_val[tag_val_off + 1] & 0x0f,
1120 (tag_val[tag_val_off + 1] & 0xf0) >> 4,
1121 tvb_get_letohs(tvb, offset + 2));
1122 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1126 proto_item_append_text(ietree, ": WME");
1127 } else if (tag_val_off + 56 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x02", 5)) {
1128 /* Wireless Multimedia Enhancements (WME) TSPEC Element */
1129 guint16 ts_info, msdu_size, surplus_bandwidth;
1130 const char *direction[] = { "Uplink", "Downlink", "Reserved", "Bi-directional" };
1131 const value_string fields[] = {
1132 {12, "Minimum Service Interval"},
1133 {16, "Maximum Service Interval"},
1134 {20, "Inactivity Interval"},
1135 {24, "Service Start Time"},
1136 {28, "Minimum Data Rate"},
1137 {32, "Mean Data Rate"},
1138 {36, "Maximum Burst Size"},
1139 {40, "Minimum PHY Rate"},
1140 {44, "Peak Data Rate"},
1141 {48, "Delay Bound"},
1146 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: type %u, subtype %u, version %u",
1147 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5]);
1148 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
1152 ts_info = tvb_get_letohs(tvb, offset);
1153 g_snprintf(out_buff, SHORT_STR, "WME TS Info: Priority %u (%s) (%s), Contention-based access %sset, %s",
1154 (ts_info >> 11) & 0x7, qos_tags[(ts_info >> 11) & 0x7], qos_acs[(ts_info >> 11) & 0x7],
1155 (ts_info & 0x0080) ? "" : "not ",
1156 direction[(ts_info >> 5) & 0x3]);
1157 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1161 msdu_size = tvb_get_letohs(tvb, offset);
1162 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s MSDU Size %u",
1163 (msdu_size & 0x8000) ? "Fixed" : "Nominal", msdu_size & 0x7fff);
1164 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1168 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Maximum MSDU Size %u", tvb_get_letohs(tvb, offset));
1169 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1173 while ((field = val_to_str(tag_val_off, fields, "Unknown"))) {
1174 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s %u", field, tvb_get_letohl(tvb, offset));
1175 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1178 if (tag_val_off == 52)
1182 surplus_bandwidth = tvb_get_letohs(tvb, offset);
1183 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Surplus Bandwidth Allowance Factor %u.%u",
1184 (surplus_bandwidth >> 13) & 0x7, (surplus_bandwidth & 0x1fff));
1188 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Medium Time %u", tvb_get_letohs(tvb, offset));
1189 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1192 proto_item_append_text(ietree, ": WME");
1197 dissect_vendor_ie_rsn(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
1198 int offset, guint32 tag_len, const guint8 *tag_val)
1200 guint32 tag_val_off = 0;
1201 char out_buff[SHORT_STR], *pos;
1204 if (tag_val_off + 4 <= tag_len && !memcmp(tag_val, RSN_OUI"\x04", 4)) {
1205 /* IEEE 802.11i / Key Data Encapsulation / Data Type=4 - PMKID.
1206 * This is only used within EAPOL-Key frame Key Data. */
1208 pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "RSN PMKID: ");
1209 if (tag_len - 4 != PMKID_LEN) {
1210 pos += g_snprintf(pos, out_buff + SHORT_STR - pos,
1211 "(invalid PMKID len=%d, expected 16) ", tag_len - 4);
1213 for (i = 0; i < tag_len - 4; i++) {
1214 pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
1215 tag_val[tag_val_off + 4 + i]);
1217 proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1220 proto_item_append_text(ietree, ": RSN");
1224 AIRONET_IE_VERSION = 3,
1226 AIRONET_IE_QBSS_V2 = 14
1227 } aironet_ie_type_t;
1229 static const value_string aironet_ie_type_vals[] = {
1230 { AIRONET_IE_VERSION, "CCX version"},
1231 { AIRONET_IE_QOS, "Qos"},
1232 { AIRONET_IE_QBSS_V2, "QBSS V2 - CCA"},
1238 dissect_vendor_ie_aironet(proto_item * aironet_item, proto_tree * ietree,
1239 tvbuff_t * tvb, int offset, guint32 tag_len)
1243 gboolean dont_change = FALSE; /* Don't change the IE item text to default */
1245 type = tvb_get_guint8(tvb, offset);
1246 proto_tree_add_item (ietree, hf_aironet_ie_type, tvb, offset, 1, TRUE);
1250 case AIRONET_IE_VERSION:
1251 proto_tree_add_item (ietree, hf_aironet_ie_version, tvb, offset, 1, TRUE);
1252 proto_item_append_text(aironet_item, ": Aironet CCX version = %d",
1253 tvb_get_guint8(tvb, offset));
1256 case AIRONET_IE_QOS:
1257 proto_tree_add_item (ietree, hf_aironet_ie_qos_unk1, tvb, offset, 1, TRUE);
1259 proto_tree_add_item (ietree, hf_aironet_ie_qos_paramset, tvb, offset, 1, TRUE);
1262 /* XXX: just copied over from WME. Maybe "Best Effort" and "Background"
1263 * need to be swapped. Also, the "TXOP" may be TXOP - or not.
1265 for (i = 0; i < 4; i++) {
1266 guint8 byte1, byte2;
1268 byte1 = tvb_get_guint8(tvb, offset);
1269 byte2 = tvb_get_guint8(tvb, offset + 1);
1270 txop = tvb_get_letohs(tvb, offset + 2);
1271 proto_tree_add_bytes_format(ietree, hf_aironet_ie_qos_val, tvb, offset, 4,
1272 tvb_get_ptr(tvb, offset, 4),
1273 "CCX QoS Parameters??: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
1274 (byte1 & 0x60) >> 5, wme_acs[(byte1 & 0x60) >> 5],
1275 (byte1 & 0x10) ? "" : "not ", byte1 & 0x0f,
1276 byte2 & 0x0f, (byte2 & 0xf0) >> 4,
1281 case AIRONET_IE_QBSS_V2:
1282 /* Extract Values */
1283 proto_tree_add_item (ietree, hf_qbss2_scount, tvb, offset, 2, TRUE);
1284 proto_tree_add_item (ietree, hf_qbss2_cu, tvb, offset + 2, 1, FALSE);
1285 proto_tree_add_item (ietree, hf_qbss2_cal, tvb, offset + 3, 1, FALSE);
1286 proto_tree_add_item (ietree, hf_qbss2_gl, tvb, offset + 4, 1, FALSE);
1289 proto_tree_add_item(ietree, hf_aironet_ie_data, tvb, offset,
1290 tag_len - 1, FALSE);
1294 proto_item_append_text(aironet_item, ": Aironet %s",
1295 val_to_str(type, aironet_ie_type_vals, "Unknown"));
1300 dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
1301 guint32 tag_len, const guint8 *tag_val)
1303 guint32 tag_val_off = 0;
1305 char out_buff[SHORT_STR];
1307 proto_item *cap_item;
1308 proto_tree *cap_tree;
1310 if (tag_val_off + 2 > tag_len) {
1311 proto_tree_add_string(tree, tag_interpretation, tvb, offset, tag_len,
1316 g_snprintf(out_buff, SHORT_STR, "RSN IE, version %u",
1317 pletohs(&tag_val[tag_val_off]));
1318 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1323 if (tag_val_off + 4 > tag_len)
1326 /* multicast cipher suite */
1327 if (!memcmp(&tag_val[tag_val_off], RSN_OUI, 3)) {
1328 g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
1329 wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1330 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1335 if (tag_val_off + 2 > tag_len)
1338 /* unicast cipher suites */
1339 count = pletohs(tag_val + tag_val_off);
1340 g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u", count);
1341 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1345 while (tag_val_off + 4 <= tag_len && i <= count) {
1346 if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
1348 g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
1349 i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1350 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1356 if (i <= count || tag_val_off + 2 > tag_len)
1359 /* authenticated key management suites */
1360 count = pletohs(tag_val + tag_val_off);
1361 g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u", count);
1362 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1366 while (tag_val_off + 4 <= tag_len && i <= count) {
1367 if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
1369 g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
1370 i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
1371 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1377 if (i <= count || tag_val_off + 2 > tag_len)
1380 rsn_capab = pletohs(&tag_val[tag_val_off]);
1381 g_snprintf(out_buff, SHORT_STR, "RSN Capabilities 0x%04x", rsn_capab);
1382 cap_item = proto_tree_add_uint_format(tree, rsn_cap, tvb,
1383 offset, 2, rsn_capab,
1384 "RSN Capabilities: 0x%04X", rsn_capab);
1385 cap_tree = proto_item_add_subtree(cap_item, ett_rsn_cap_tree);
1386 proto_tree_add_boolean(cap_tree, rsn_cap_preauth, tvb, offset, 2,
1388 proto_tree_add_boolean(cap_tree, rsn_cap_no_pairwise, tvb, offset, 2,
1390 proto_tree_add_uint(cap_tree, rsn_cap_ptksa_replay_counter, tvb, offset, 2,
1392 proto_tree_add_uint(cap_tree, rsn_cap_gtksa_replay_counter, tvb, offset, 2,
1397 if (tag_val_off + 2 > tag_len)
1400 count = pletohs(tag_val + tag_val_off);
1401 g_snprintf(out_buff, SHORT_STR, "# of PMKIDs: %u", count);
1402 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1406 /* PMKID List (16 * n octets) */
1407 for (i = 0; i < count; i++) {
1409 if (tag_val_off + PMKID_LEN > tag_len)
1412 pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "PMKID %u: ", i);
1413 for (j = 0; j < PMKID_LEN; j++) {
1414 pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
1415 tag_val[tag_val_off + j]);
1417 proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1418 PMKID_LEN, out_buff);
1419 offset += PMKID_LEN;
1420 tag_val_off += PMKID_LEN;
1424 if (tag_val_off < tag_len)
1425 proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1426 tag_len - tag_val_off, "Not interpreted");
1429 /* ************************************************************************* */
1430 /* Dissect and add tagged (optional) fields to proto tree */
1431 /* ************************************************************************* */
1433 static const value_string tag_num_vals[] = {
1434 { TAG_SSID, "SSID parameter set" },
1435 { TAG_SUPP_RATES, "Supported Rates" },
1436 { TAG_FH_PARAMETER, "FH Parameter set" },
1437 { TAG_DS_PARAMETER, "DS Parameter set" },
1438 { TAG_CF_PARAMETER, "CF Parameter set" },
1439 { TAG_TIM, "(TIM) Traffic Indication Map" },
1440 { TAG_IBSS_PARAMETER, "IBSS Parameter set" },
1441 { TAG_COUNTRY_INFO, "Country Information" },
1442 { TAG_FH_HOPPING_PARAMETER, "Hopping Pattern Parameters" },
1443 { TAG_CHALLENGE_TEXT, "Challenge text" },
1444 { TAG_ERP_INFO, "ERP Information" },
1445 { TAG_ERP_INFO_OLD, "ERP Information" },
1446 { TAG_RSN_IE, "RSN Information" },
1447 { TAG_EXT_SUPP_RATES, "Extended Supported Rates" },
1448 { TAG_CISCO_UNKNOWN_1, "Cisco Unknown 1 + Device Name" },
1449 { TAG_CISCO_UNKNOWN_2, "Cisco Unknown 2" },
1450 { TAG_VENDOR_SPECIFIC_IE, "Vendor Specific" },
1451 { TAG_SYMBOL_PROPRIETARY, "Symbol Proprietary"},
1452 { TAG_AGERE_PROPRIETARY, "Agere Proprietary"},
1453 { TAG_REQUEST, "Request"},
1454 { TAG_QBSS_LOAD, "QBSS Load Element"},
1455 { TAG_EDCA_PARAM_SET, "EDCA Parameter Set"},
1456 { TAG_TRAF_SPEC, "Traffic Specification"},
1457 { TAG_TRAF_CLASS, "Traffic Classification"},
1458 { TAG_SCHEDULE, "Schedule"},
1459 { TAG_TS_DELAY, "TS Delay"},
1460 { TAG_TCLAS_PROCESS, "TCLAS Processing"},
1461 { TAG_QOS_CAPABILITY, "QoS Capability"},
1462 { TAG_POWER_CONSTRAINT, "Power Constraint"},
1463 { TAG_POWER_CAPABILITY, "Power Capability"},
1464 { TAG_TPC_REQUEST, "TPC Request"},
1465 { TAG_TPC_REPORT, "TPC Report"},
1466 { TAG_SUPPORTED_CHANNELS, "Supported Channels"},
1467 { TAG_CHANNEL_SWITCH_ANN, "Channel Switch Announcement"},
1468 { TAG_MEASURE_REQ, "Measurement Request"},
1469 { TAG_MEASURE_REP, "Measurement Report"},
1470 { TAG_QUIET, "Quiet"},
1471 { TAG_IBSS_DFS, "IBSS DFS"},
1475 static const value_string environment_vals[] = {
1477 { 0x4f, "Outdoor" },
1482 static int beacon_padding = 0; /* beacon padding bug */
1484 add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int offset)
1487 const guint8 *tag_val;
1488 const guint8 *tag_data_ptr;
1489 guint32 tag_no, tag_len;
1492 char out_buff[SHORT_STR];
1493 char print_buff[SHORT_STR];
1494 proto_tree * orig_tree=tree;
1497 tag_no = tvb_get_guint8(tvb, offset);
1498 tag_len = tvb_get_guint8(tvb, offset + 1);
1500 ti=proto_tree_add_text(orig_tree,tvb,offset,tag_len+2,"%s",
1501 val_to_str(tag_no, tag_num_vals,
1502 (tag_no >= 17 && tag_no <= 31) ?
1503 "Reserved for challenge text" : "Reserved tag number" ));
1504 tree=proto_item_add_subtree(ti,ett_80211_mgt_ie);
1506 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
1507 "Tag Number: %u (%s)",
1509 val_to_str(tag_no, tag_num_vals,
1510 (tag_no >= 17 && tag_no <= 31) ?
1511 "Reserved for challenge text" :
1512 "Reserved tag number"));
1513 proto_tree_add_uint (tree, (tag_no==TAG_TIM ? tim_length : tag_length), tvb, offset + 1, 1, tag_len);
1519 if(beacon_padding == 0) /* padding bug */
1523 ssid = tvb_get_ephemeral_string(tvb, offset + 2, tag_len);
1524 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1526 if (check_col (pinfo->cinfo, COL_INFO)) {
1528 col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: \"%s\"",
1529 format_text(ssid, tag_len));
1531 col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: Broadcast");
1535 proto_item_append_text(ti, ": \"%s\"",
1536 format_text(ssid, tag_len));
1538 proto_item_append_text(ti, ": Broadcast");
1540 beacon_padding++; /* padding bug */
1544 case TAG_SUPP_RATES:
1545 case TAG_EXT_SUPP_RATES:
1548 proto_tree_add_text (tree, tvb, offset + 2, tag_len,
1549 "Tag length %u too short, must be > 0", tag_len);
1552 tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
1554 tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
1555 for (i = 0, n = 0; i < tag_len && n < SHORT_STR; i++) {
1556 ret = g_snprintf (print_buff + n, SHORT_STR - n, "%2.1f%s ",
1557 (tag_data_ptr[i] & 0x7F) * 0.5,
1558 (tag_data_ptr[i] & 0x80) ? "(B)" : "");
1559 if (ret == -1 || ret >= SHORT_STR - n) {
1560 /* Some versions of snprintf return -1 if they'd truncate
1561 the output. Others return <buf_size> or greater. */
1566 g_snprintf (out_buff, SHORT_STR, "Supported rates: %s [Mbit/sec]", print_buff);
1567 out_buff[SHORT_STR-1] = '\0';
1568 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1570 proto_item_append_text(ti, ": %s", print_buff);
1573 case TAG_FH_PARAMETER:
1576 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 5",
1580 g_snprintf (out_buff, SHORT_STR,
1581 "Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, Hop Index %2d",
1582 tvb_get_letohs(tvb, offset + 2),
1583 tvb_get_guint8(tvb, offset + 4),
1584 tvb_get_guint8(tvb, offset + 5),
1585 tvb_get_guint8(tvb, offset + 6));
1586 out_buff[SHORT_STR-1] = '\0';
1587 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1591 case TAG_DS_PARAMETER:
1594 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
1598 g_snprintf (out_buff, SHORT_STR, "Current Channel: %u",
1599 tvb_get_guint8(tvb, offset + 2));
1600 out_buff[SHORT_STR-1] = '\0';
1601 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1603 proto_item_append_text(ti, ": %s", out_buff);
1606 case TAG_CF_PARAMETER:
1609 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 6",
1613 g_snprintf (out_buff, SHORT_STR, "CFP count: %u",
1614 tvb_get_guint8(tvb, offset + 2));
1615 out_buff[SHORT_STR-1] = '\0';
1616 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2,
1617 1, out_buff, "%s", out_buff);
1618 g_snprintf (out_buff, SHORT_STR, "CFP period: %u",
1619 tvb_get_guint8(tvb, offset + 3));
1620 out_buff[SHORT_STR-1] = '\0';
1621 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 3,
1622 1, out_buff, "%s", out_buff);
1623 g_snprintf (out_buff, SHORT_STR, "CFP max duration: %u",
1624 tvb_get_letohs(tvb, offset + 4));
1625 out_buff[SHORT_STR-1] = '\0';
1626 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 4,
1627 2, out_buff, "%s", out_buff);
1628 g_snprintf (out_buff, SHORT_STR, "CFP Remaining: %u",
1629 tvb_get_letohs(tvb, offset + 6));
1630 out_buff[SHORT_STR-1] = '\0';
1631 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 6,
1632 2, out_buff, "%s", out_buff);
1633 proto_item_append_text(ti, ": CFP count %u, CFP period %u, CFP max duration %u, "
1635 tvb_get_guint8(tvb, offset + 2),
1636 tvb_get_guint8(tvb, offset + 3),
1637 tvb_get_letohs(tvb, offset + 4),
1638 tvb_get_letohs(tvb, offset + 6));
1644 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 4",
1654 proto_tree_add_item(tree, tim_dtim_count, tvb,
1655 offset + 2, 1, TRUE);
1656 proto_tree_add_item(tree, tim_dtim_period, tvb,
1657 offset + 3, 1, TRUE);
1658 proto_item_append_text(ti, ": DTIM %u of %u bitmap",
1659 tvb_get_guint8(tvb, offset + 2),
1660 tvb_get_guint8(tvb, offset + 3));
1662 bmapctl = tvb_get_guint8(tvb, offset + 4);
1663 bmapoff = bmapctl>>1;
1664 proto_tree_add_uint_format(tree, tim_bmapctl, tvb,
1665 offset + 4, 1, bmapctl,
1666 "Bitmap Control: 0x%02X (mcast:%u, bitmap offset %u)",
1667 bmapctl, bmapctl&1, bmapoff);
1669 bmaplen = tag_len - 3;
1670 bmap = tvb_get_ptr(tvb, offset + 5, bmaplen);
1671 if (bmaplen==1 && 0==bmap[0] && !(bmapctl&1)) {
1672 proto_item_append_text(ti, " empty");
1675 proto_item_append_text(ti, " mcast");
1678 if (bmaplen>1 || bmap[0]) {
1679 int len=g_snprintf (out_buff, SHORT_STR,
1680 "Bitmap: traffic for AID's:");
1682 for (i=0;i<bmaplen*8;i++) {
1683 if (bmap[i/8] & (1<<(i%8))) {
1684 int aid=i+bmapoff*8;
1685 len+=g_snprintf (out_buff+len, SHORT_STR-len," %u", aid);
1686 proto_item_append_text(ti, " %u", aid);
1687 if (len>=SHORT_STR) {
1692 out_buff[SHORT_STR-1] = '\0';
1693 proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 5,
1694 bmaplen, out_buff, "%s", out_buff);
1699 case TAG_IBSS_PARAMETER:
1702 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
1706 g_snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
1707 tvb_get_letohs(tvb, offset + 2));
1708 out_buff[SHORT_STR-1] = '\0';
1709 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1711 proto_item_append_text(ti, ": %s", out_buff);
1714 case TAG_COUNTRY_INFO: /* IEEE 802.11d-2001 and IEEE 802.11j-2004 */
1720 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 3",
1724 tvb_memcpy(tvb, ccode, offset + 2, 2);
1726 g_snprintf (out_buff, SHORT_STR, "Country Code: %s, %s Environment",
1727 format_text(ccode, 2),
1728 val_to_str(tvb_get_guint8(tvb, offset + 4), environment_vals,"Unknown (0x%02x)"));
1729 out_buff[SHORT_STR-1] = '\0';
1730 proto_item_append_text(ti, ": %s", out_buff);
1731 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,3, out_buff);
1733 for (i = 3; (i + 3) <= tag_len; i += 3)
1735 guint8 val1, val2, val3;
1736 val1 = tvb_get_guint8(tvb, offset + 2 + i);
1737 val2 = tvb_get_guint8(tvb, offset + 3 + i);
1738 val3 = tvb_get_guint8(tvb, offset + 4 + i);
1740 if (val1 <= 200) { /* 802.11d */
1741 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
1742 " Start Channel: %u, Channels: %u, Max TX Power: %d dBm",
1743 val1, val2, (gint) val3);
1744 } else { /* 802.11j */
1745 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
1746 " Reg Extension Id: %u, Regulatory Class: %u, Coverage Class: %u",
1754 if (tag_len < 4 || tag_len >5)
1756 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Wrong QBSS Tag Length %u", tag_len);
1762 /* QBSS Version 1 */
1763 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 1,
1764 tag_len, "Cisco QBSS Version 1 - non CCA");
1766 /* Extract Values */
1767 proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 1);
1768 proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
1769 proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
1770 proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 1, FALSE);
1772 else if (tag_len == 5)
1774 /* QBSS Version 2 */
1775 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1776 tag_len, "802.11e CCA Version");
1778 /* Extract Values */
1779 proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 2);
1780 proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
1781 proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
1782 proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 2, FALSE);
1786 case TAG_FH_HOPPING_PARAMETER:
1789 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
1793 g_snprintf (out_buff, SHORT_STR, "Prime Radix: %u, Number of Channels: %u",
1794 tvb_get_guint8(tvb, offset + 2),
1795 tvb_get_guint8(tvb, offset + 3));
1796 out_buff[SHORT_STR-1] = '\0';
1797 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2, tag_len, out_buff);
1798 proto_item_append_text(ti, ": %s", out_buff);
1801 case TAG_CHALLENGE_TEXT:
1802 g_snprintf (out_buff, SHORT_STR, "Challenge text: %s",
1803 tvb_bytes_to_str(tvb, offset + 2, tag_len));
1804 out_buff[SHORT_STR-1] = '\0';
1805 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1810 case TAG_ERP_INFO_OLD:
1816 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
1820 erp_info = tvb_get_guint8 (tvb, offset + 2);
1821 g_snprintf (print_buff, SHORT_STR, "%sNon-ERP STAs, %suse protection, %s preambles",
1822 erp_info & 0x01 ? "" : "no ",
1823 erp_info & 0x02 ? "" : "do not ",
1824 erp_info & 0x04 ? "short or long": "long");
1825 print_buff[SHORT_STR-1] = '\0';
1826 g_snprintf (out_buff, SHORT_STR,
1827 "ERP info: 0x%x (%s)",erp_info,print_buff);
1828 out_buff[SHORT_STR-1] = '\0';
1829 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1831 proto_item_append_text(ti, ": %s", print_buff);
1835 case TAG_CISCO_UNKNOWN_1:
1836 /* The Name of the sending device starts at offset 10 and is up to
1837 15 or 16 bytes in length, \0 padded */
1840 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 26",
1844 g_snprintf (out_buff, SHORT_STR, "%.16s",
1845 tvb_format_stringzpad(tvb, offset + 12, 16));
1846 out_buff[SHORT_STR-1] = '\0';
1847 proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 2,
1848 tag_len, "", "Tag interpretation: Unknown + Name: %s",
1850 if (check_col (pinfo->cinfo, COL_INFO)) {
1851 col_append_fstr(pinfo->cinfo, COL_INFO, ", Name: \"%s\"", out_buff);
1855 case TAG_VENDOR_SPECIFIC_IE:
1856 tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
1858 oui = tvb_get_ntoh24(tvb, offset + 2);
1859 tag_val = tvb_get_ptr(tvb, offset + 2, tag_len);
1861 #define WPAWME_OUI 0x0050F2
1862 #define RSNOUI_VAL 0x000FAC
1863 #define AIRONET_VAL 0x004096
1867 dissect_vendor_ie_wpawme(ti, tree, tvb, offset + 2, tag_len, tag_val);
1870 dissect_vendor_ie_rsn(ti, tree, tvb, offset + 2, tag_len, tag_val);
1873 dissect_vendor_ie_aironet(ti, tree, tvb, offset + 5, tag_len - 3);
1876 proto_tree_add_bytes_format (tree, tag_oui, tvb, offset + 2, 3,
1877 "", "Vendor: %s", get_manuf_name(tag_val));
1878 proto_item_append_text(ti, ": %s", get_manuf_name(tag_val));
1879 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 5,
1880 tag_len - 3, "Not interpreted");
1888 dissect_rsn_ie(tree, tvb, offset + 2, tag_len,
1889 tvb_get_ptr (tvb, offset + 2, tag_len));
1893 tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
1894 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1895 tag_len, "Not interpreted");
1896 proto_item_append_text(ti, ": Tag %u Len %u", tag_no, tag_len);
1904 ieee_80211_add_tagged_parameters (tvbuff_t * tvb, int offset, packet_info * pinfo,
1905 proto_tree * tree, int tagged_parameters_len)
1909 beacon_padding = 0; /* this is for the beacon padding confused with ssid fix */
1910 while (tagged_parameters_len > 0) {
1911 if ((next_len=add_tagged_field (pinfo, tree, tvb, offset))==0)
1913 if (next_len > tagged_parameters_len) {
1914 /* XXX - flag this as an error? */
1915 next_len = tagged_parameters_len;
1918 tagged_parameters_len -= next_len;
1922 /* ************************************************************************* */
1923 /* Dissect 802.11 management frame */
1924 /* ************************************************************************* */
1926 dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
1929 proto_item *ti = NULL;
1930 proto_tree *mgt_tree;
1931 proto_tree *fixed_tree;
1932 proto_tree *tagged_tree;
1934 int tagged_parameter_tree_len;
1938 CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
1940 ti = proto_tree_add_item (tree, proto_wlan_mgt, tvb, 0, -1, FALSE);
1941 mgt_tree = proto_item_add_subtree (ti, ett_80211_mgt);
1943 switch (COMPOSE_FRAME_TYPE(fcf))
1947 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
1948 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1949 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
1950 offset = 4; /* Size of fixed fields */
1952 tagged_parameter_tree_len =
1953 tvb_reported_length_remaining(tvb, offset);
1954 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1955 tagged_parameter_tree_len);
1956 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1957 tagged_parameter_tree_len);
1961 case MGT_ASSOC_RESP:
1962 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1963 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1964 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
1965 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
1966 offset = 6; /* Size of fixed fields */
1968 tagged_parameter_tree_len =
1969 tvb_reported_length_remaining(tvb, offset);
1970 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1971 tagged_parameter_tree_len);
1972 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1973 tagged_parameter_tree_len);
1977 case MGT_REASSOC_REQ:
1978 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
1979 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1980 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
1981 add_fixed_field (fixed_tree, tvb, 4, FIELD_CURRENT_AP_ADDR);
1982 offset = 10; /* Size of fixed fields */
1984 tagged_parameter_tree_len =
1985 tvb_reported_length_remaining(tvb, offset);
1986 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1987 tagged_parameter_tree_len);
1988 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1989 tagged_parameter_tree_len);
1992 case MGT_REASSOC_RESP:
1993 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1994 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1995 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
1996 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
1997 offset = 6; /* Size of fixed fields */
1999 tagged_parameter_tree_len =
2000 tvb_reported_length_remaining(tvb, offset);
2001 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2002 tagged_parameter_tree_len);
2003 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2004 tagged_parameter_tree_len);
2010 tagged_parameter_tree_len =
2011 tvb_reported_length_remaining(tvb, offset);
2012 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2013 tagged_parameter_tree_len);
2014 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2015 tagged_parameter_tree_len);
2019 case MGT_PROBE_RESP:
2020 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
2021 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
2022 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
2023 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
2024 offset = 12; /* Size of fixed fields */
2026 tagged_parameter_tree_len =
2027 tvb_reported_length_remaining(tvb, offset);
2028 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2029 tagged_parameter_tree_len);
2030 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2031 tagged_parameter_tree_len);
2035 case MGT_BEACON: /* Dissect protocol payload fields */
2036 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
2037 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
2038 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
2039 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
2040 offset = 12; /* Size of fixed fields */
2042 tagged_parameter_tree_len =
2043 tvb_reported_length_remaining(tvb, offset);
2044 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2045 tagged_parameter_tree_len);
2046 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2047 tagged_parameter_tree_len);
2056 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2057 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
2061 case MGT_AUTHENTICATION:
2062 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
2063 add_fixed_field (fixed_tree, tvb, 0, FIELD_AUTH_ALG);
2064 add_fixed_field (fixed_tree, tvb, 2, FIELD_AUTH_TRANS_SEQ);
2065 add_fixed_field (fixed_tree, tvb, 4, FIELD_STATUS_CODE);
2066 offset = 6; /* Size of fixed fields */
2068 tagged_parameter_tree_len =
2069 tvb_reported_length_remaining(tvb, offset);
2070 if (tagged_parameter_tree_len != 0)
2072 tagged_tree = get_tagged_parameter_tree (mgt_tree,
2075 tagged_parameter_tree_len);
2076 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2077 tagged_parameter_tree_len);
2082 case MGT_DEAUTHENTICATION:
2083 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2084 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
2089 switch (tvb_get_guint8(tvb, 0))
2092 case CAT_SPECTRUM_MGMT:
2093 switch (tvb_get_guint8(tvb, 1))
2095 case SM_ACTION_MEASUREMENT_REQUEST:
2096 case SM_ACTION_MEASUREMENT_REPORT:
2097 case SM_ACTION_TPC_REQUEST:
2098 case SM_ACTION_TPC_REPORT:
2099 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
2100 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2101 add_fixed_field (fixed_tree, tvb, 1, FIELD_ACTION_CODE);
2102 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2103 offset = 3; /* Size of fixed fields */
2106 case SM_ACTION_CHAN_SWITCH_ANNC:
2107 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2108 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2109 offset = 2; /* Size of fixed fields */
2113 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2114 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2115 offset = 2; /* Size of fixed fields */
2120 case CAT_MGMT_NOTIFICATION: /* Management notification frame */
2121 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
2122 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2123 add_fixed_field (fixed_tree, tvb, 1, FIELD_WME_ACTION_CODE);
2124 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2125 add_fixed_field (fixed_tree, tvb, 3, FIELD_WME_STATUS_CODE);
2126 offset = 4; /* Size of fixed fields */
2130 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 1);
2131 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2132 offset = 1; /* Size of fixed fields */
2136 tagged_parameter_tree_len =
2137 tvb_reported_length_remaining(tvb, offset);
2138 if (tagged_parameter_tree_len != 0)
2140 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2141 tagged_parameter_tree_len);
2142 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2143 tagged_parameter_tree_len);
2150 set_src_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
2152 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
2153 col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "%s (%s)",
2154 get_ether_name(addr), type);
2155 if (check_col(pinfo->cinfo, COL_UNRES_DL_SRC))
2156 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s",
2157 ether_to_str(addr));
2161 set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
2163 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
2164 col_add_fstr(pinfo->cinfo, COL_RES_DL_DST, "%s (%s)",
2165 get_ether_name(addr), type);
2166 if (check_col(pinfo->cinfo, COL_UNRES_DL_DST))
2167 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s",
2168 ether_to_str(addr));
2172 crc32_802_tvb_padded(tvbuff_t *tvb, guint hdr_len, guint hdr_size, guint len)
2176 c_crc = crc32_ccitt_tvb(tvb, hdr_len);
2177 c_crc = crc32_ccitt_seed(tvb_get_ptr(tvb, hdr_size, len), len, ~c_crc);
2180 c_crc = ((unsigned char)(c_crc>>0)<<24) |
2181 ((unsigned char)(c_crc>>8)<<16) |
2182 ((unsigned char)(c_crc>>16)<<8) |
2183 ((unsigned char)(c_crc>>24)<<0);
2194 /* ************************************************************************* */
2195 /* Dissect 802.11 frame */
2196 /* ************************************************************************* */
2198 dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
2199 proto_tree * tree, gboolean fixed_length_header,
2200 gboolean has_radio_information, gint fcs_len,
2201 gboolean wlan_broken_fc, gboolean datapad)
2203 guint16 fcf, flags, frame_type_subtype;
2204 guint16 seq_control;
2205 guint32 seq_number, frag_number;
2206 gboolean more_frags;
2207 const guint8 *src = NULL;
2208 const guint8 *dst = NULL;
2209 const guint8 *bssid = NULL;
2210 proto_item *ti = NULL;
2211 proto_item *flag_item;
2212 proto_item *fc_item;
2213 proto_tree *hdr_tree = NULL;
2214 proto_tree *flag_tree;
2215 proto_tree *fc_tree;
2216 guint16 hdr_len, ohdr_len;
2218 gint len, reported_len, ivlen;
2219 gboolean save_fragmented;
2220 tvbuff_t *volatile next_tvb = NULL;
2222 volatile encap_t encap_type;
2223 guint8 octet1, octet2;
2224 char out_buff[SHORT_STR];
2227 wlan_hdr *volatile whdr;
2228 static wlan_hdr whdrs[4];
2232 if (check_col (pinfo->cinfo, COL_PROTOCOL))
2233 col_set_str (pinfo->cinfo, COL_PROTOCOL, "IEEE 802.11");
2234 if (check_col (pinfo->cinfo, COL_INFO))
2235 col_clear (pinfo->cinfo, COL_INFO);
2237 /* Add the radio information, if present, to the column information */
2238 if (has_radio_information) {
2239 if (check_col(pinfo->cinfo, COL_TX_RATE)) {
2240 col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u",
2241 pinfo->pseudo_header->ieee_802_11.data_rate / 2,
2242 pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
2244 if (check_col(pinfo->cinfo, COL_RSSI)) {
2245 /* XX - this is a percentage, not a dBm or normalized or raw RSSI */
2246 col_add_fstr(pinfo->cinfo, COL_RSSI, "%u",
2247 pinfo->pseudo_header->ieee_802_11.signal_level);
2251 fcf = tvb_get_letohs (tvb, 0);
2252 if (wlan_broken_fc) {
2254 fcf = ((fcf & 0xff) << 8) | (((fcf & 0xff00) >> 8) & 0xff);
2256 if (fixed_length_header)
2257 hdr_len = DATA_LONG_HDR_LEN;
2259 hdr_len = find_header_length (fcf);
2262 hdr_len = roundup2(hdr_len, 4);
2263 frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
2265 if (check_col (pinfo->cinfo, COL_INFO))
2266 col_set_str (pinfo->cinfo, COL_INFO,
2267 val_to_str(frame_type_subtype, frame_type_subtype_vals,
2268 "Unrecognized (Reserved frame)"));
2270 flags = FCF_FLAGS (fcf);
2271 more_frags = HAVE_FRAGMENTS (flags);
2274 /* Add the radio information, if present, and the FC to the current tree */
2277 ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
2279 hdr_tree = proto_item_add_subtree (ti, ett_80211);
2281 if (has_radio_information) {
2282 proto_tree_add_uint_format(hdr_tree, hf_data_rate,
2284 pinfo->pseudo_header->ieee_802_11.data_rate,
2285 "Data Rate: %u.%u Mb/s",
2286 pinfo->pseudo_header->ieee_802_11.data_rate / 2,
2287 pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
2289 proto_tree_add_uint(hdr_tree, hf_channel,
2291 pinfo->pseudo_header->ieee_802_11.channel);
2293 proto_tree_add_uint_format(hdr_tree, hf_signal_strength,
2295 pinfo->pseudo_header->ieee_802_11.signal_level,
2296 "Signal Strength: %u%%",
2297 pinfo->pseudo_header->ieee_802_11.signal_level);
2300 proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
2302 wlan_broken_fc?1:0, 1,
2303 frame_type_subtype);
2305 fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb,
2308 "Frame Control: 0x%04X (%s)",
2309 fcf, wlan_broken_fc?"Swapped":"Normal");
2311 fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
2314 proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb,
2315 wlan_broken_fc?1:0, 1,
2316 FCF_PROT_VERSION (fcf));
2318 proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb,
2319 wlan_broken_fc?1:0, 1,
2320 FCF_FRAME_TYPE (fcf));
2322 proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
2324 wlan_broken_fc?1:0, 1,
2325 FCF_FRAME_SUBTYPE (fcf));
2328 proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb,
2329 wlan_broken_fc?0:1, 1,
2330 flags, "Flags: 0x%X", flags);
2332 flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
2334 proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb,
2335 wlan_broken_fc?0:1, 1,
2336 FLAGS_DS_STATUS (flags));
2337 proto_tree_add_boolean_hidden (flag_tree, hf_fc_to_ds, tvb, 1, 1,
2339 proto_tree_add_boolean_hidden (flag_tree, hf_fc_from_ds, tvb, 1, 1,
2342 proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb,
2343 wlan_broken_fc?0:1, 1,
2346 proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb,
2347 wlan_broken_fc?0:1, 1, flags);
2349 proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb,
2350 wlan_broken_fc?0:1, 1, flags);
2352 proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb,
2353 wlan_broken_fc?0:1, 1,
2356 proto_tree_add_boolean (flag_tree, hf_fc_protected, tvb,
2357 wlan_broken_fc?0:1, 1, flags);
2359 proto_tree_add_boolean (flag_tree, hf_fc_order, tvb,
2360 wlan_broken_fc?0:1, 1, flags);
2362 if (frame_type_subtype == CTRL_PS_POLL)
2363 proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
2364 ASSOC_ID(tvb_get_letohs(tvb,2)));
2367 proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
2368 tvb_get_letohs (tvb, 2));
2372 * Decode the part of the frame header that isn't the same for all
2379 switch (FCF_FRAME_TYPE (fcf))
2384 * All management frame types have the same header.
2386 src = tvb_get_ptr (tvb, 10, 6);
2387 dst = tvb_get_ptr (tvb, 4, 6);
2389 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
2390 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
2391 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
2392 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
2395 SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, tvb_get_ptr(tvb, 16,6));
2396 SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
2397 SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
2398 whdr->type = frame_type_subtype;
2400 seq_control = tvb_get_letohs(tvb, 22);
2401 frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
2402 seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
2404 if (check_col (pinfo->cinfo, COL_INFO))
2406 col_append_fstr(pinfo->cinfo, COL_INFO,
2407 ",SN=%d", seq_number);
2409 col_append_fstr(pinfo->cinfo, COL_INFO,
2410 ",FN=%d",frag_number);
2415 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2417 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2419 /* add items for wlan.addr filter */
2420 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2421 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2423 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
2424 tvb_get_ptr (tvb, 16, 6));
2426 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2429 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2435 switch (frame_type_subtype)
2439 src = tvb_get_ptr (tvb, 10, 6);
2440 dst = tvb_get_ptr (tvb, 4, 6);
2442 set_src_addr_cols(pinfo, src, "BSSID");
2443 set_dst_addr_cols(pinfo, dst, "BSSID");
2447 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6, dst);
2449 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
2455 src = tvb_get_ptr (tvb, 10, 6);
2456 dst = tvb_get_ptr (tvb, 4, 6);
2458 set_src_addr_cols(pinfo, src, "TA");
2459 set_dst_addr_cols(pinfo, dst, "RA");
2463 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2465 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
2471 dst = tvb_get_ptr (tvb, 4, 6);
2473 set_dst_addr_cols(pinfo, dst, "RA");
2476 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2480 case CTRL_ACKNOWLEDGEMENT:
2481 dst = tvb_get_ptr (tvb, 4, 6);
2483 set_dst_addr_cols(pinfo, dst, "RA");
2486 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2491 src = tvb_get_ptr (tvb, 10, 6);
2492 dst = tvb_get_ptr (tvb, 4, 6);
2494 set_src_addr_cols(pinfo, src, "BSSID");
2495 set_dst_addr_cols(pinfo, dst, "RA");
2499 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2500 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
2505 case CTRL_CFP_ENDACK:
2506 src = tvb_get_ptr (tvb, 10, 6);
2507 dst = tvb_get_ptr (tvb, 4, 6);
2509 set_src_addr_cols(pinfo, src, "BSSID");
2510 set_dst_addr_cols(pinfo, dst, "RA");
2514 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2516 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
2520 case CTRL_BLOCK_ACK_REQ:
2522 src = tvb_get_ptr (tvb, 10, 6);
2523 dst = tvb_get_ptr (tvb, 4, 6);
2525 set_src_addr_cols(pinfo, src, "TA");
2526 set_dst_addr_cols(pinfo, dst, "RA");
2530 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
2532 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
2538 case CTRL_BLOCK_ACK:
2540 src = tvb_get_ptr (tvb, 10, 6);
2541 dst = tvb_get_ptr (tvb, 4, 6);
2543 set_src_addr_cols(pinfo, src, "TA");
2544 set_dst_addr_cols(pinfo, dst, "RA");
2548 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
2550 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
2552 /* TODO BAR Format */
2559 addr_type = FCF_ADDR_SELECTOR (fcf);
2561 /* In order to show src/dst address we must always do the following */
2566 src = tvb_get_ptr (tvb, 10, 6);
2567 dst = tvb_get_ptr (tvb, 4, 6);
2568 bssid = tvb_get_ptr (tvb, 16, 6);
2573 src = tvb_get_ptr (tvb, 16, 6);
2574 dst = tvb_get_ptr (tvb, 4, 6);
2575 bssid = tvb_get_ptr (tvb, 10, 6);
2580 src = tvb_get_ptr (tvb, 10, 6);
2581 dst = tvb_get_ptr (tvb, 16, 6);
2582 bssid = tvb_get_ptr (tvb, 4, 6);
2587 src = tvb_get_ptr (tvb, 24, 6);
2588 dst = tvb_get_ptr (tvb, 16, 6);
2589 bssid = tvb_get_ptr (tvb, 16, 6);
2593 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
2594 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
2595 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
2596 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
2600 SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, bssid);
2601 SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
2602 SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
2603 whdr->type = frame_type_subtype;
2605 seq_control = tvb_get_letohs(tvb, 22);
2606 frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
2607 seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
2609 if (check_col (pinfo->cinfo, COL_INFO))
2611 col_append_fstr(pinfo->cinfo, COL_INFO,
2612 ",SN=%d", seq_number);
2614 col_append_fstr(pinfo->cinfo, COL_INFO,
2615 ",FN=%d",frag_number);
2618 /* Now if we have a tree we start adding stuff */
2627 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2628 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2629 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
2630 tvb_get_ptr (tvb, 16, 6));
2631 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2633 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2636 /* add items for wlan.addr filter */
2637 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2638 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2643 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2644 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
2645 tvb_get_ptr (tvb, 10, 6));
2646 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6, src);
2647 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2649 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2652 /* add items for wlan.addr filter */
2653 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2654 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, src);
2659 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
2660 tvb_get_ptr (tvb, 4, 6));
2661 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2662 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
2664 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2666 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2669 /* add items for wlan.addr filter */
2670 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2671 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
2676 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
2677 tvb_get_ptr (tvb, 4, 6));
2678 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
2679 tvb_get_ptr (tvb, 10, 6));
2680 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
2681 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2683 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2685 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6, src);
2687 /* add items for wlan.addr filter */
2688 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
2689 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 24, 6, src);
2697 len = tvb_length_remaining(tvb, hdr_len);
2698 reported_len = tvb_reported_length_remaining(tvb, hdr_len);
2702 case 0: /* Definitely has no FCS */
2706 case 4: /* Definitely has an FCS */
2710 default: /* Don't know - use "wlan_check_fcs" */
2711 has_fcs = wlan_check_fcs;
2717 * Well, this packet should, in theory, have an FCS.
2718 * Do we have the entire packet, and does it have enough data for
2721 if (reported_len < 4)
2724 * The packet is claimed not to even have enough data for a 4-byte
2726 * Pretend it doesn't have an FCS.
2730 else if (len < reported_len)
2733 * The packet is claimed to have enough data for a 4-byte FCS, but
2734 * we didn't capture all of the packet.
2735 * Slice off the 4-byte FCS from the reported length, and trim the
2736 * captured length so it's no more than the reported length; that
2737 * will slice off what of the FCS, if any, is in the captured
2741 if (len > reported_len)
2747 * We have the entire packet, and it includes a 4-byte FCS.
2748 * Slice it off, and put it into the tree.
2754 guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len);
2758 fcs = crc32_802_tvb_padded(tvb, ohdr_len, hdr_len, len);
2760 fcs = crc32_802_tvb(tvb, hdr_len + len);
2761 if (fcs == sent_fcs)
2762 proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
2763 hdr_len + len, 4, sent_fcs,
2764 "Frame check sequence: 0x%08x [correct]", sent_fcs);
2766 proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
2767 hdr_len + len, 4, sent_fcs,
2768 "Frame check sequence: 0x%08x [incorrect, should be 0x%08x]",
2777 * Only management and data frames have a body, so we don't have
2778 * anything more to do for other types of frames.
2780 switch (FCF_FRAME_TYPE (fcf))
2787 if (tree && DATA_FRAME_IS_QOS(frame_type_subtype))
2790 proto_item *qos_fields;
2791 proto_tree *qos_tree;
2794 guint16 qos_control;
2795 guint16 qos_priority;
2796 guint16 qos_ack_policy;
2798 guint16 qos_field_content;
2801 * We calculate the offset to the QoS header data as
2802 * an offset relative to the end of the header. But
2803 * when the header has been padded to align the data
2804 * this must be done relative to true header size, not
2805 * the padded/aligned value. To simplify this work we
2806 * stash the original header size in ohdr_len instead
2807 * of recalculating it.
2809 qosoff = ohdr_len - 2;
2810 qos_fields = proto_tree_add_text(hdr_tree, tvb, qosoff, 2,
2812 qos_tree = proto_item_add_subtree (qos_fields, ett_qos_parameters);
2814 qos_control = tvb_get_letohs(tvb, qosoff + 0);
2815 qos_priority = QOS_PRIORITY(qos_control);
2816 qos_ack_policy = QOS_ACK_POLICY(qos_control);
2817 qos_eosp = QOS_EOSP(qos_control);
2818 qos_field_content = QOS_FIELD_CONTENT( qos_control);
2820 proto_tree_add_uint_format (qos_tree, hf_qos_priority, tvb,
2821 qosoff, 2, qos_priority,
2822 "Priority: %d (%s) (%s)",
2823 qos_priority, qos_tags[qos_priority], qos_acs[qos_priority]);
2825 if (flags & FLAG_FROM_DS) {
2826 proto_tree_add_boolean (qos_tree, hf_qos_eosp, tvb,
2827 qosoff, 1, qos_eosp);
2829 if (DATA_FRAME_IS_CF_POLL(frame_type_subtype)) {
2831 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2832 qosoff + 1, 1, qos_field_content, "TXOP Limit: %d ", qos_field_content);
2835 /* qap ps buffer state */
2836 proto_item *qos_ps_buf_state_fields;
2837 proto_tree *qos_ps_buf_state_tree;
2842 buf_state = QOS_PS_BUF_STATE(qos_field_content);
2843 buf_ac = QOS_PS_BUF_AC(qos_field_content); /*access category */
2844 buf_load = QOS_PS_BUF_LOAD(qos_field_content);
2846 qos_ps_buf_state_fields = proto_tree_add_text(qos_tree, tvb, qosoff + 1, 1,
2847 "QAP PS Buffer State: 0x%x", qos_field_content);
2848 qos_ps_buf_state_tree = proto_item_add_subtree (qos_ps_buf_state_fields, ett_qos_ps_buf_state);
2850 /* FIXME: hf_ values not defined
2851 proto_tree_add_boolean (qos_ps_buf_state_tree, hf_qos_buf_state, tvb,
2854 proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_ac, tvb,
2855 qosoff + 1, 1, buf_ac, "Priority: %d (%s)",
2856 buf_ac, wme_acs[buf_ac]);
2858 proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_load, tvb,
2859 qosoff + 1, 1, buf_load, "Buffered load: %d ", (buf_load * 4096));
2863 } else if (qos_eosp) {
2864 /* txop limit requested */
2865 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2866 qosoff + 1, 1, qos_field_content, "Queue Size: %d ", (qos_field_content * 254));
2869 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2870 qosoff + 1, 1, qos_field_content, "TXOP Limit Requested: %d ", qos_field_content);
2873 proto_tree_add_uint (qos_tree, hf_qos_ack_policy, tvb, qosoff, 1,
2876 } /* end of qos control field */
2879 * No-data frames don't have a body.
2881 if (DATA_FRAME_IS_NULL(frame_type_subtype))
2893 if (IS_PROTECTED(FCF_FLAGS(fcf))) {
2895 * It's a WEP-encrypted frame; dissect the WEP parameters and decrypt
2896 * the data, if we have a matching key. Otherwise display it as data.
2898 gboolean can_decrypt = FALSE;
2899 proto_tree *wep_tree = NULL;
2901 guint8 key, keybyte;
2903 keybyte = tvb_get_guint8(tvb, hdr_len + 3);
2904 key = KEY_OCTET_WEP_KEY(keybyte);
2905 if ((keybyte & KEY_EXTIV) && (len >= EXTIV_LEN)) {
2906 /* Extended IV; this frame is likely encrypted with TKIP or CCMP */
2908 proto_item *extiv_fields;
2910 extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
2911 "TKIP/CCMP parameters");
2912 wep_tree = proto_item_add_subtree (extiv_fields, ett_wep_parameters);
2913 /* It is unknown whether this is a TKIP or CCMP encrypted packet, so
2914 * display both packet number alternatives unless the ExtIV can be
2915 * determined to be possible only with one of the encryption protocols.
2917 if (tvb_get_guint8(tvb, hdr_len + 1) & 0x20) {
2918 g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
2919 tvb_get_letohl(tvb, hdr_len + 4),
2920 tvb_get_guint8(tvb, hdr_len),
2921 tvb_get_guint8(tvb, hdr_len + 2));
2922 proto_tree_add_string(wep_tree, hf_tkip_extiv, tvb, hdr_len,
2923 EXTIV_LEN, out_buff);
2925 if (tvb_get_guint8(tvb, hdr_len + 2) == 0) {
2926 g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
2927 tvb_get_letohl(tvb, hdr_len + 4),
2928 tvb_get_guint8(tvb, hdr_len + 1),
2929 tvb_get_guint8(tvb, hdr_len));
2930 proto_tree_add_string(wep_tree, hf_ccmp_extiv, tvb, hdr_len,
2931 EXTIV_LEN, out_buff);
2933 proto_tree_add_uint(wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
2936 /* Subtract out the length of the IV. */
2938 reported_len -= EXTIV_LEN;
2940 /* It is unknown whether this is TKIP or CCMP, so let's not even try to
2941 * parse TKIP Michael MIC+ICV or CCMP MIC. */
2943 /* No Ext. IV - WEP packet */
2945 * XXX - pass the IV and key to "try_decrypt_wep()", and have it pass
2946 * them to "wep_decrypt()", rather than having "wep_decrypt()" extract
2949 * Also, just pass the data *following* the WEP parameters as the
2950 * buffer to decrypt.
2952 iv = tvb_get_ntoh24(tvb, hdr_len);
2954 proto_item *wep_fields;
2956 wep_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 4,
2959 wep_tree = proto_item_add_subtree (wep_fields, ett_wep_parameters);
2960 proto_tree_add_uint (wep_tree, hf_wep_iv, tvb, hdr_len, 3, iv);
2961 tvb_memcpy(tvb, iv_buff, hdr_len, 3);
2962 is_iv_bad = weak_iv(iv_buff);
2963 if (is_iv_bad != -1) {
2964 proto_tree_add_boolean_format (wep_tree, hf_wep_iv_weak,
2966 "Weak IV for key byte %d",
2971 proto_tree_add_uint (wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
2973 /* Subtract out the length of the IV. */
2979 * Well, this packet should, in theory, have an ICV.
2980 * Do we have the entire packet, and does it have enough data for
2983 if (reported_len < 4) {
2985 * The packet is claimed not to even have enough data for a
2987 * Pretend it doesn't have an ICV.
2990 } else if (len < reported_len) {
2992 * The packet is claimed to have enough data for a 4-byte ICV,
2993 * but we didn't capture all of the packet.
2994 * Slice off the 4-byte ICV from the reported length, and trim
2995 * the captured length so it's no more than the reported length;
2996 * that will slice off what of the ICV, if any, is in the
3001 if (len > reported_len)
3005 * We have the entire packet, and it includes a 4-byte ICV.
3006 * Slice it off, and put it into the tree.
3008 * We only support decrypting if we have the the ICV.
3010 * XXX - the ICV is encrypted; we're putting the encrypted
3011 * value, not the decrypted value, into the tree.
3019 if (!can_decrypt || (next_tvb = try_decrypt_wep(tvb, hdr_len, reported_len + 8)) == NULL) {
3021 * WEP decode impossible or failed, treat payload as raw data
3022 * and don't attempt fragment reassembly or further dissection.
3024 next_tvb = tvb_new_subset(tvb, hdr_len + ivlen, len, reported_len);
3026 if (tree && can_decrypt)
3027 proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
3028 hdr_len + ivlen + len, 4,
3029 tvb_get_ntohl(tvb, hdr_len + ivlen + len),
3030 "WEP ICV: 0x%08x (not verified)",
3031 tvb_get_ntohl(tvb, hdr_len + ivlen + len));
3033 if (pinfo->ethertype != ETHERTYPE_CENTRINO_PROMISC)
3035 /* Some wireless drivers (such as Centrino) WEP payload already decrypted */
3036 call_dissector(data_handle, next_tvb, pinfo, tree);
3042 proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
3043 hdr_len + ivlen + len, 4,
3044 tvb_get_ntohl(tvb, hdr_len + ivlen + len),
3045 "WEP ICV: 0x%08x (correct)",
3046 tvb_get_ntohl(tvb, hdr_len + ivlen + len));
3048 add_new_data_source(pinfo, next_tvb, "Decrypted WEP data");
3052 * WEP decryption successful!
3054 * Use the tvbuff we got back from the decryption; the data starts at
3055 * the beginning. The lengths are already correct for the decoded WEP
3062 * Not a WEP-encrypted frame; just use the data from the tvbuff
3065 * The payload starts at "hdr_len" (i.e., just past the 802.11
3066 * MAC header), the length of data in the tvbuff following the
3067 * 802.11 header is "len", and the length of data in the packet
3068 * following the 802.11 header is "reported_len".
3074 * Do defragmentation if "wlan_defragment" is true, and we have more
3075 * fragments or this isn't the first fragment.
3077 * We have to do some special handling to catch frames that
3078 * have the "More Fragments" indicator not set but that
3079 * don't show up as reassembled and don't have any other
3080 * fragments present. Some networking interfaces appear
3081 * to do reassembly even when you're capturing raw packets
3082 * *and* show the reassembled packet without the "More
3083 * Fragments" indicator set *but* with a non-zero fragment
3086 * "fragment_add_seq_802_11()" handles that; we want to call it
3087 * even if we have a short frame, so that it does those checks - if
3088 * the frame is short, it doesn't do reassembly on it.
3090 * (This could get some false positives if we really *did* only
3091 * capture the last fragment of a fragmented packet, but that's
3094 save_fragmented = pinfo->fragmented;
3095 if (wlan_defragment && (more_frags || frag_number != 0)) {
3096 fragment_data *fd_head;
3099 * If we've already seen this frame, look it up in the
3100 * table of reassembled packets, otherwise add it to
3101 * whatever reassembly is in progress, if any, and see
3104 fd_head = fragment_add_seq_802_11(next_tvb, hdr_len, pinfo, seq_number,
3105 wlan_fragment_table,
3106 wlan_reassembled_table,
3110 next_tvb = process_reassembled_data(tvb, hdr_len, pinfo,
3111 "Reassembled 802.11", fd_head,
3112 &frag_items, NULL, hdr_tree);
3115 * If this is the first fragment, dissect its contents, otherwise
3116 * just show it as a fragment.
3118 if (frag_number != 0) {
3119 /* Not the first fragment - don't dissect it. */
3122 /* First fragment, or not fragmented. Dissect what we have here. */
3124 /* Get a tvbuff for the payload. */
3125 next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len);
3128 * If this is the first fragment, but not the only fragment,
3129 * tell the next protocol that.
3132 pinfo->fragmented = TRUE;
3134 pinfo->fragmented = FALSE;
3138 if (next_tvb == NULL) {
3139 /* Just show this as an incomplete fragment. */
3140 if (check_col(pinfo->cinfo, COL_INFO))
3141 col_set_str(pinfo->cinfo, COL_INFO, "Fragmented IEEE 802.11 frame");
3142 next_tvb = tvb_new_subset (tvb, hdr_len, len, reported_len);
3143 call_dissector(data_handle, next_tvb, pinfo, tree);
3144 pinfo->fragmented = save_fragmented;
3148 switch (FCF_FRAME_TYPE (fcf))
3152 dissect_ieee80211_mgt (fcf, next_tvb, pinfo, tree);
3157 /* I guess some bridges take Netware Ethernet_802_3 frames,
3158 which are 802.3 frames (with a length field rather than
3159 a type field, but with no 802.2 header in the payload),
3160 and just stick the payload into an 802.11 frame. I've seen
3161 captures that show frames of that sort.
3163 We also handle some odd form of encapsulation in which a
3164 complete Ethernet frame is encapsulated within an 802.11
3165 data frame, with no 802.2 header. This has been seen
3168 So, if the packet doesn't start with 0xaa 0xaa:
3170 we first use the same scheme that linux-wlan-ng does to detect
3171 those encapsulated Ethernet frames, namely looking to see whether
3172 the frame either starts with 6 octets that match the destination
3173 address from the 802.11 header or has 6 octets that match the
3174 source address from the 802.11 header following the first 6 octets,
3175 and, if so, treat it as an encapsulated Ethernet frame;
3177 otherwise, we use the same scheme that we use in the Ethernet
3178 dissector to recognize Netware 802.3 frames, namely checking
3179 whether the packet starts with 0xff 0xff and, if so, treat it
3180 as an encapsulated IPX frame. */
3181 encap_type = ENCAP_802_2;
3183 octet1 = tvb_get_guint8(next_tvb, 0);
3184 octet2 = tvb_get_guint8(next_tvb, 1);
3185 if (octet1 != 0xaa || octet2 != 0xaa) {
3186 src = tvb_get_ptr (next_tvb, 6, 6);
3187 dst = tvb_get_ptr (next_tvb, 0, 6);
3188 if (memcmp(src, pinfo->dl_src.data, 6) == 0 ||
3189 memcmp(dst, pinfo->dl_dst.data, 6) == 0)
3190 encap_type = ENCAP_ETHERNET;
3191 else if (octet1 == 0xff && octet2 == 0xff)
3192 encap_type = ENCAP_IPX;
3195 CATCH2(BoundsError, ReportedBoundsError) {
3201 switch (encap_type) {
3204 call_dissector(llc_handle, next_tvb, pinfo, tree);
3207 case ENCAP_ETHERNET:
3208 call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree);
3212 call_dissector(ipx_handle, next_tvb, pinfo, tree);
3217 pinfo->fragmented = save_fragmented;
3220 tap_queue_packet(wlan_tap, pinfo, whdr);
3224 * Dissect 802.11 with a variable-length link-layer header.
3227 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3229 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
3230 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
3234 * Dissect 802.11 with a variable-length link-layer header and data padding.
3237 dissect_ieee80211_datapad (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3239 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
3240 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, TRUE);
3244 * Dissect 802.11 with a variable-length link-layer header and a pseudo-
3245 * header containing radio information.
3248 dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3250 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE,
3251 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
3255 * Dissect 802.11 with a variable-length link-layer header and a byte-swapped
3256 * control field (some hardware sends out LWAPP-encapsulated 802.11
3257 * packets with the control field byte swapped).
3260 dissect_ieee80211_bsfc (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3262 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE, FALSE);
3266 * Dissect 802.11 with a fixed-length link-layer header (padded to the
3270 dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3272 dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE, FALSE);
3276 wlan_defragment_init(void)
3278 fragment_table_init(&wlan_fragment_table);
3279 reassembled_table_init(&wlan_reassembled_table);
3283 proto_register_ieee80211 (void)
3285 static const value_string frame_type[] = {
3286 {MGT_FRAME, "Management frame"},
3287 {CONTROL_FRAME, "Control frame"},
3288 {DATA_FRAME, "Data frame"},
3292 static const value_string tofrom_ds[] = {
3293 {0, "Not leaving DS or network is operating "
3294 "in AD-HOC mode (To DS: 0 From DS: 0)"},
3295 {FLAG_TO_DS, "Frame from STA to DS via an AP (To DS: 1 "
3297 {FLAG_FROM_DS, "Frame from DS to a STA via AP(To DS: 0 "
3299 {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS from one AP to another "
3300 "AP (To DS: 1 From DS: 1)"},
3304 static const true_false_string tods_flag = {
3305 "Frame is entering DS",
3306 "Frame is not entering DS"
3309 static const true_false_string fromds_flag = {
3310 "Frame is exiting DS",
3311 "Frame is not exiting DS"
3314 static const true_false_string more_frags = {
3315 "More fragments follow",
3316 "This is the last fragment"
3319 static const true_false_string retry_flags = {
3320 "Frame is being retransmitted",
3321 "Frame is not being retransmitted"
3324 static const true_false_string pm_flags = {
3325 "STA will go to sleep",
3329 static const true_false_string md_flags = {
3330 "Data is buffered for STA at AP",
3334 static const true_false_string protected_flags = {
3335 "Data is protected",
3336 "Data is not protected"
3339 static const true_false_string order_flags = {
3341 "Not strictly ordered"
3344 static const true_false_string cf_ess_flags = {
3345 "Transmitter is an AP",
3346 "Transmitter is a STA"
3350 static const true_false_string cf_privacy_flags = {
3351 "AP/STA can support WEP",
3352 "AP/STA cannot support WEP"
3355 static const true_false_string cf_preamble_flags = {
3356 "Short preamble allowed",
3357 "Short preamble not allowed"
3360 static const true_false_string cf_pbcc_flags = {
3361 "PBCC modulation allowed",
3362 "PBCC modulation not allowed"
3365 static const true_false_string cf_agility_flags = {
3366 "Channel agility in use",
3367 "Channel agility not in use"
3370 static const true_false_string short_slot_time_flags = {
3371 "Short slot time in use",
3372 "Short slot time not in use"
3375 static const true_false_string dsss_ofdm_flags = {
3376 "DSSS-OFDM modulation allowed",
3377 "DSSS-OFDM modulation not allowed"
3380 static const true_false_string cf_spec_man_flags = {
3381 "dot11SpectrumManagementRequired TRUE",
3382 "dot11SpectrumManagementRequired FALSE",
3385 static const true_false_string cf_apsd_flags = {
3387 "apsd not implemented",
3390 static const true_false_string cf_del_blk_ack_flags = {
3391 "delayed block ack implemented",
3392 "delayed block ack not implented",
3395 static const true_false_string cf_imm_blk_ack_flags = {
3396 "immediate block ack implemented",
3397 "immediate block ack not implented",
3399 static const true_false_string cf_ibss_flags = {
3400 "Transmitter belongs to an IBSS",
3401 "Transmitter belongs to a BSS"
3404 static const true_false_string eosp_flag = {
3405 "End of service period",
3409 static const value_string sta_cf_pollable[] = {
3410 {0x00, "Station is not CF-Pollable"},
3411 {0x02, "Station is CF-Pollable, "
3412 "not requesting to be placed on the CF-polling list"},
3413 {0x01, "Station is CF-Pollable, "
3414 "requesting to be placed on the CF-polling list"},
3415 {0x03, "Station is CF-Pollable, requesting never to be polled"},
3416 {0x0200, "QSTA requesting association in QBSS"},
3420 static const value_string ap_cf_pollable[] = {
3421 {0x00, "No point coordinator at AP"},
3422 {0x02, "Point coordinator at AP for delivery only (no polling)"},
3423 {0x01, "Point coordinator at AP for delivery and polling"},
3425 {0x0200, "QAP (HC) does not use CFP for delivery of unicast data type frames"},
3426 {0x0202, "QAP (HC) uses CFP for delivery, but does not send CF-Polls to non-QoS STAs"},
3427 {0x0201, "QAP (HC) uses CFP for delivery, and sends CF-Polls to non-QoS STAs"},
3428 {0x0203, "Reserved"},
3433 static const value_string auth_alg[] = {
3434 {0x00, "Open System"},
3435 {0x01, "Shared key"},
3436 {0x80, "Network EAP"}, /* Cisco proprietary? */
3440 static const value_string reason_codes[] = {
3442 {0x01, "Unspecified reason"},
3443 {0x02, "Previous authentication no longer valid"},
3444 {0x03, "Deauthenticated because sending STA is leaving (has left) "
3446 {0x04, "Disassociated due to inactivity"},
3447 {0x05, "Disassociated because AP is unable to handle all currently "
3448 "associated stations"},
3449 {0x06, "Class 2 frame received from nonauthenticated station"},
3450 {0x07, "Class 3 frame received from nonassociated station"},
3451 {0x08, "Disassociated because sending STA is leaving (has left) BSS"},
3452 {0x09, "Station requesting (re)association is not authenticated with "
3453 "responding station"},
3454 {0x0A, "Disassociated because the information in the Power Capability "
3455 "element is unacceptable"},
3456 {0x0B, "Disassociated because the information in the Supported"
3457 "Channels element is unacceptable"},
3458 {0x0D, "Invalid Information Element"},
3459 {0x0E, "Michael MIC failure"},
3460 {0x0F, "4-Way Handshake timeout"},
3461 {0x10, "Group key update timeout"},
3462 {0x11, "Information element in 4-Way Handshake different from "
3463 "(Re)Association Request/Probe Response/Beacon"},
3464 {0x12, "Group Cipher is not valid"},
3465 {0x13, "Pairwise Cipher is not valid"},
3466 {0x14, "AKMP is not valid"},
3467 {0x15, "Unsupported RSN IE version"},
3468 {0x16, "Invalid RSN IE Capabilities"},
3469 {0x17, "IEEE 802.1X Authentication failed"},
3470 {0x18, "Cipher suite is rejected per security policy"},
3471 {0x20, "Disassociated for unspecified, QoS-related reason"},
3472 {0x21, "Disassociated because QAP lacks sufficient bandwidth for this QSTA"},
3473 {0x22, "Disassociated because of excessive number of frames that need to be "
3474 "acknowledged, but are not acknowledged for AP transmissions and/or poor "
3475 "channel conditions"},
3476 {0x23, "Disassociated because QSTA is transmitting outside the limits of its TXOPs"},
3477 {0x24, "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)"},
3478 {0x25, "Requested from peer QSTA as it does not want to use the mechanism"},
3479 {0x26, "Requested from peer QSTA as the QSTA received frames using the mechanism "
3480 "for which a set up is required"},
3481 {0x27, "Requested from peer QSTA due to time out"},
3482 {0x2D, "Peer QSTA does not support the requested cipher suite"},
3487 static const value_string status_codes[] = {
3488 {0x00, "Successful"},
3489 {0x01, "Unspecified failure"},
3490 {0x0A, "Cannot support all requested capabilities in the "
3491 "Capability information field"},
3492 {0x0B, "Reassociation denied due to inability to confirm that "
3493 "association exists"},
3494 {0x0C, "Association denied due to reason outside the scope of this "
3497 {0x0D, "Responding station does not support the specified authentication "
3499 {0x0E, "Received an Authentication frame with authentication sequence "
3500 "transaction sequence number out of expected sequence"},
3501 {0x0F, "Authentication rejected because of challenge failure"},
3502 {0x10, "Authentication rejected due to timeout waiting for next "
3503 "frame in sequence"},
3504 {0x11, "Association denied because AP is unable to handle additional "
3505 "associated stations"},
3506 {0x12, "Association denied due to requesting station not supporting all "
3507 "of the datarates in the BSSBasicServiceSet Parameter"},
3508 {0x13, "Association denied due to requesting station not supporting "
3509 "short preamble operation"},
3510 {0x14, "Association denied due to requesting station not supporting "
3512 {0x15, "Association denied due to requesting station not supporting "
3514 {0x16, "Association request rejected because Spectrum Management"
3515 "capability is required"},
3516 {0x17, "Association request rejected because the information in the"
3517 "Power Capability element is unacceptable"},
3518 {0x18, "Association request rejected because the information in the"
3519 "Supported Channels element is unacceptable"},
3520 {0x19, "Association denied due to requesting station not supporting "
3521 "short slot operation"},
3522 {0x1A, "Association denied due to requesting station not supporting "
3523 "DSSS-OFDM operation"},
3524 {0x20, "Unspecified, QoS-related failure"},
3525 {0x21, "Association denied due to QAP having insufficient bandwidth "
3526 "to handle another QSTA"},
3527 {0x22, "Association denied due to excessive frame loss rates and/or "
3528 "poor conditions on current operating channel"},
3529 {0x23, "Association (with QBSS) denied due to requesting station not "
3530 "supporting the QoS facility"},
3531 {0x24, "Association denied due to requesting station not supporting "
3533 {0x25, "The request has been declined."},
3534 {0x26, "The request has not been successful as one or more parameters "
3535 "have invalid values."},
3536 {0x27, "The TS has not been created because the request cannot be honored. "
3537 "However, a suggested TSPEC is provided so that the initiating QSTA may "
3538 "attempt to set another TS with the suggested changes to the TSPEC."},
3539 {0x28, "Invalid Information Element"},
3540 {0x29, "Group Cipher is not valid"},
3541 {0x2A, "Pairwise Cipher is not valid"},
3542 {0x2B, "AKMP is not valid"},
3543 {0x2C, "Unsupported RSN IE version"},
3544 {0x2D, "Invalid RSN IE Capabilities"},
3545 {0x2E, "Cipher suite is rejected per security policy"},
3546 {0x2F, "The TS has not been created. However, the HC may be capable of "
3547 "creating a TS, in response to a request, after the time indicated in the TS Delay element."},
3548 {0x30, "Direct Link is not allowed in the BSS by policy"},
3549 {0x31, "Destination STA is not present within this QBSS."},
3550 {0x32, "The Destination STA is not a QSTA."},
3554 static const value_string category_codes[] = {
3555 {CAT_SPECTRUM_MGMT, "Spectrum Management"},
3558 {CAT_BLOCK_ACK, "Block Ack"},
3559 {CAT_MGMT_NOTIFICATION, "Management notification frame"},
3563 static const value_string action_codes[] ={
3564 {SM_ACTION_MEASUREMENT_REQUEST, "Measurement Request"},
3565 {SM_ACTION_MEASUREMENT_REPORT, "Measurement Report"},
3566 {SM_ACTION_TPC_REQUEST, "TPC Request"},
3567 {SM_ACTION_TPC_REPORT, "TPC Report"},
3568 {SM_ACTION_CHAN_SWITCH_ANNC, "Channel Switch Announcement"},
3572 static const value_string wme_action_codes[] = {
3573 {0x00, "Setup request"},
3574 {0x01, "Setup response"},
3579 static const value_string wme_status_codes[] = {
3580 {0x00, "Admission accepted"},
3581 {0x01, "Invalid parameters"},
3586 static const value_string ack_policy[] = {
3587 {0x00, "Normal Ack"},
3589 {0x01, "No explicit Ack"},
3590 {0x03, "Block Ack"},
3594 static hf_register_info hf[] = {
3596 {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
3597 "Data rate (.5 Mb/s units)", HFILL }},
3600 {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
3601 "Radio channel", HFILL }},
3603 {&hf_signal_strength,
3604 {"Signal Strength", "wlan.signal_strength", FT_UINT8, BASE_DEC, NULL, 0,
3605 "Signal strength (percentage)", HFILL }},
3608 {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
3609 "MAC Frame control", HFILL }},
3611 {&hf_fc_proto_version,
3612 {"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
3613 "MAC Protocol version", HFILL }}, /* 0 */
3616 {"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, VALS(frame_type), 0,
3617 "Frame type", HFILL }},
3619 {&hf_fc_frame_subtype,
3620 {"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
3621 "Frame subtype", HFILL }}, /* 2 */
3623 {&hf_fc_frame_type_subtype,
3624 {"Type/Subtype", "wlan.fc.type_subtype", FT_UINT16, BASE_DEC, VALS(frame_type_subtype_vals), 0,
3625 "Type and subtype combined", HFILL }},
3628 {"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
3629 "Protocol flags", HFILL }},
3632 {"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, VALS (&tofrom_ds), 0,
3633 "Data-frame DS-traversal status", HFILL }}, /* 3 */
3636 {"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), FLAG_TO_DS,
3637 "To DS flag", HFILL }}, /* 4 */
3640 {"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), FLAG_FROM_DS,
3641 "From DS flag", HFILL }}, /* 5 */
3644 {"More Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), FLAG_MORE_FRAGMENTS,
3645 "More Fragments flag", HFILL }}, /* 6 */
3648 {"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), FLAG_RETRY,
3649 "Retransmission flag", HFILL }},
3652 {"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), FLAG_POWER_MGT,
3653 "Power management status", HFILL }},
3656 {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
3657 "More data flag", HFILL }},
3660 {"Protected flag", "wlan.fc.protected", FT_BOOLEAN, 8, TFS (&protected_flags), FLAG_PROTECTED,
3661 "Protected flag", HFILL }},
3664 {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
3665 "Strictly ordered flag", HFILL }},
3668 {"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
3669 "Association-ID field", HFILL }},
3672 {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
3673 "Duration field", HFILL }},
3676 {"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
3677 "Destination Hardware Address", HFILL }},
3680 {"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
3681 "Source Hardware Address", HFILL }},
3684 {"Source or Destination address", "wlan.addr", FT_ETHER, BASE_NONE, NULL, 0,
3685 "Source or Destination Hardware Address", HFILL }},
3688 {"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
3689 "Receiving Station Hardware Address", HFILL }},
3692 {"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
3693 "Transmitting Station Hardware Address", HFILL }},
3696 {"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
3697 "Basic Service Set ID", HFILL }},
3700 {"Fragment number", "wlan.frag", FT_UINT16, BASE_DEC, NULL, 0,
3701 "Fragment number", HFILL }},
3704 {"Sequence number", "wlan.seq", FT_UINT16, BASE_DEC, NULL, 0,
3705 "Sequence number", HFILL }},
3708 {"Priority", "wlan.qos.priority", FT_UINT16, BASE_DEC, NULL, 0,
3709 "802.1D Tag", HFILL }},
3712 {"EOSP", "wlan.qos.eosp", FT_BOOLEAN, 8, TFS (&eosp_flag), QOS_FLAG_EOSP,
3713 "EOSP Field", HFILL }},
3715 {&hf_qos_ack_policy,
3716 {"Ack Policy", "wlan.qos.ack", FT_UINT16, BASE_HEX, VALS (&ack_policy), 0,
3717 "Ack Policy", HFILL }},
3719 {&hf_qos_field_content,
3720 {"Content", "wlan.qos.fc_content", FT_UINT16, BASE_DEC, NULL, 0,
3721 "Content1", HFILL }},
3723 /* {&hf_qos_buffer_state,
3724 {"QAP PS buffer State", "wlan.qos.ps_buf_state", FT_UINT16, BASE_DEC, NULL, 0,
3725 "QAP PS buffer State", HFILL }},
3727 {&hf_qos_txop_dur_req,
3728 {"TXOP Duration Requested", "wlan.qos.txop_dur_req", FT_UINT16, BASE_DEC, NULL, 0,
3729 "TXOP Duration Requested", HFILL }},
3731 {&hf_qos_queue_size,
3732 {"Queue Size", "wlan.qos.queue_size", FT_UINT16, BASE_DEC, NULL, 0,
3733 "Queue Size", HFILL }},*/
3736 {"Frame check sequence", "wlan.fcs", FT_UINT32, BASE_HEX,
3737 NULL, 0, "FCS", HFILL }},
3739 {&hf_fragment_overlap,
3740 {"Fragment overlap", "wlan.fragment.overlap", FT_BOOLEAN, BASE_NONE,
3741 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
3743 {&hf_fragment_overlap_conflict,
3744 {"Conflicting data in fragment overlap", "wlan.fragment.overlap.conflict",
3745 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3746 "Overlapping fragments contained conflicting data", HFILL }},
3748 {&hf_fragment_multiple_tails,
3749 {"Multiple tail fragments found", "wlan.fragment.multipletails",
3750 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3751 "Several tails were found when defragmenting the packet", HFILL }},
3753 {&hf_fragment_too_long_fragment,
3754 {"Fragment too long", "wlan.fragment.toolongfragment",
3755 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3756 "Fragment contained data past end of packet", HFILL }},
3758 {&hf_fragment_error,
3759 {"Defragmentation error", "wlan.fragment.error",
3760 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3761 "Defragmentation error due to illegal fragments", HFILL }},
3764 {"802.11 Fragment", "wlan.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3765 "802.11 Fragment", HFILL }},
3768 {"802.11 Fragments", "wlan.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
3769 "802.11 Fragments", HFILL }},
3771 {&hf_reassembled_in,
3772 {"Reassembled 802.11 in frame", "wlan.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3773 "This 802.11 packet is reassembled in this frame", HFILL }},
3776 {"Initialization Vector", "wlan.wep.iv", FT_UINT24, BASE_HEX, NULL, 0,
3777 "Initialization Vector", HFILL }},
3780 {"Weak IV", "wlan.wep.weakiv", FT_BOOLEAN,BASE_NONE, NULL,0x0,
3784 {"TKIP Ext. Initialization Vector", "wlan.tkip.extiv", FT_STRING,
3785 BASE_HEX, NULL, 0, "TKIP Extended Initialization Vector", HFILL }},
3788 {"CCMP Ext. Initialization Vector", "wlan.ccmp.extiv", FT_STRING,
3789 BASE_HEX, NULL, 0, "CCMP Extended Initialization Vector", HFILL }},
3792 {"Key Index", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
3793 "Key Index", HFILL }},
3796 {"WEP ICV", "wlan.wep.icv", FT_UINT32, BASE_HEX, NULL, 0,
3797 "WEP ICV", HFILL }},
3800 static const true_false_string rsn_preauth_flags = {
3801 "Transmitter supports pre-authentication",
3802 "Transmitter does not support pre-authentication"
3805 static const true_false_string rsn_no_pairwise_flags = {
3806 "Transmitter cannot support WEP default key 0 simultaneously with "
3808 "Transmitter can support WEP default key 0 simultaneously with "
3812 static const value_string rsn_cap_replay_counter[] = {
3813 {0x00, "1 replay counter per PTKSA/GTKSA/STAKeySA"},
3814 {0x01, "2 replay counters per PTKSA/GTKSA/STAKeySA"},
3815 {0x02, "4 replay counters per PTKSA/GTKSA/STAKeySA"},
3816 {0x03, "16 replay counters per PTKSA/GTKSA/STAKeySA"},
3820 static hf_register_info ff[] = {
3822 {"Timestamp", "wlan_mgt.fixed.timestamp", FT_STRING, BASE_NONE,
3823 NULL, 0, "", HFILL }},
3826 {"Authentication Algorithm", "wlan_mgt.fixed.auth.alg",
3827 FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, "", HFILL }},
3829 {&ff_beacon_interval,
3830 {"Beacon Interval", "wlan_mgt.fixed.beacon", FT_DOUBLE, BASE_DEC, NULL, 0,
3833 {&hf_fixed_parameters,
3834 {"Fixed parameters", "wlan_mgt.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
3837 {&hf_tagged_parameters,
3838 {"Tagged parameters", "wlan_mgt.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
3842 {"Capabilities", "wlan_mgt.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
3843 "Capability information", HFILL }},
3846 {"ESS capabilities", "wlan_mgt.fixed.capabilities.ess",
3847 FT_BOOLEAN, 16, TFS (&cf_ess_flags), 0x0001, "ESS capabilities", HFILL }},
3850 {"IBSS status", "wlan_mgt.fixed.capabilities.ibss",
3851 FT_BOOLEAN, 16, TFS (&cf_ibss_flags), 0x0002, "IBSS participation", HFILL }},
3854 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.sta",
3855 FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0x020C,
3856 "CF-Poll capabilities for a STA", HFILL }},
3859 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.ap",
3860 FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0x020C,
3861 "CF-Poll capabilities for an AP", HFILL }},
3864 {"Privacy", "wlan_mgt.fixed.capabilities.privacy",
3865 FT_BOOLEAN, 16, TFS (&cf_privacy_flags), 0x0010, "WEP support", HFILL }},
3868 {"Short Preamble", "wlan_mgt.fixed.capabilities.preamble",
3869 FT_BOOLEAN, 16, TFS (&cf_preamble_flags), 0x0020, "Short Preamble", HFILL }},
3872 {"PBCC", "wlan_mgt.fixed.capabilities.pbcc",
3873 FT_BOOLEAN, 16, TFS (&cf_pbcc_flags), 0x0040, "PBCC Modulation", HFILL }},
3876 {"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
3877 FT_BOOLEAN, 16, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
3880 {"Spectrum Management", "wlan_mgt.fixed.capabilities.spec_man",
3881 FT_BOOLEAN, 16, TFS (&cf_spec_man_flags), 0x0100, "Spectrum Management", HFILL }},
3883 {&ff_short_slot_time,
3884 {"Short Slot Time", "wlan_mgt.fixed.capabilities.short_slot_time",
3885 FT_BOOLEAN, 16, TFS (&short_slot_time_flags), 0x0400, "Short Slot Time",
3889 {"Automatic Power Save Delivery", "wlan_mgt.fixed.capabilities.apsd",
3890 FT_BOOLEAN, 16, TFS (&cf_apsd_flags), 0x0800, "Automatic Power Save "
3891 "Delivery", HFILL }},
3894 {"DSSS-OFDM", "wlan_mgt.fixed.capabilities.dsss_ofdm",
3895 FT_BOOLEAN, 16, TFS (&dsss_ofdm_flags), 0x2000, "DSSS-OFDM Modulation",
3898 {&ff_cf_del_blk_ack,
3899 {"Delayed Block Ack", "wlan_mgt.fixed.capabilities.del_blk_ack",
3900 FT_BOOLEAN, 16, TFS (&cf_del_blk_ack_flags), 0x4000, "Delayed Block "
3903 {&ff_cf_imm_blk_ack,
3904 {"Immediate Block Ack", "wlan_mgt.fixed.capabilities.imm_blk_ack",
3905 FT_BOOLEAN, 16, TFS (&cf_imm_blk_ack_flags), 0x8000, "Immediate Block "
3909 {"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
3910 FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
3913 {"Association ID", "wlan_mgt.fixed.aid",
3914 FT_UINT16, BASE_HEX, NULL, 0, "Association ID", HFILL }},
3917 {"Listen Interval", "wlan_mgt.fixed.listen_ival",
3918 FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval", HFILL }},
3921 {"Current AP", "wlan_mgt.fixed.current_ap",
3922 FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP", HFILL }},
3925 {"Reason code", "wlan_mgt.fixed.reason_code",
3926 FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
3927 "Reason for unsolicited notification", HFILL }},
3930 {"Status code", "wlan_mgt.fixed.status_code",
3931 FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
3932 "Status of requested event", HFILL }},
3935 {"Category code", "wlan_mgt.fixed.category_code",
3936 FT_UINT16, BASE_DEC, VALS (&category_codes), 0,
3937 "Management action category", HFILL }},
3940 {"Action code", "wlan_mgt.fixed.action_code",
3941 FT_UINT16, BASE_DEC, VALS (&action_codes), 0,
3942 "Management action code", HFILL }},
3945 {"Dialog token", "wlan_mgt.fixed.dialog_token",
3946 FT_UINT16, BASE_HEX, NULL, 0, "Management action dialog token", HFILL }},
3948 {&ff_wme_action_code,
3949 {"Action code", "wlan_mgt.fixed.action_code",
3950 FT_UINT16, BASE_HEX, VALS (&wme_action_codes), 0,
3951 "Management notification action code", HFILL }},
3953 {&ff_wme_status_code,
3954 {"Status code", "wlan_mgt.fixed.status_code",
3955 FT_UINT16, BASE_HEX, VALS (&wme_status_codes), 0,
3956 "Management notification setup response status code", HFILL }},
3959 {"Tag", "wlan_mgt.tag.number",
3960 FT_UINT8, BASE_DEC, VALS(tag_num_vals), 0,
3961 "Element ID", HFILL }},
3964 {"Tag length", "wlan_mgt.tag.length",
3965 FT_UINT8, BASE_DEC, NULL, 0, "Length of tag", HFILL }},
3967 {&tag_interpretation,
3968 {"Tag interpretation", "wlan_mgt.tag.interpretation",
3969 FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }},
3972 {"OUI", "wlan_mgt.tag.oui",
3973 FT_BYTES, BASE_NONE, NULL, 0, "OUI of vendor specific IE", HFILL }},
3976 {"TIM length", "wlan_mgt.tim.length",
3977 FT_UINT8, BASE_DEC, NULL, 0,
3978 "Traffic Indication Map length", HFILL }},
3981 {"DTIM count", "wlan_mgt.tim.dtim_count",
3982 FT_UINT8, BASE_DEC, NULL, 0,
3983 "DTIM count", HFILL }},
3986 {"DTIM period", "wlan_mgt.tim.dtim_period",
3987 FT_UINT8, BASE_DEC, NULL, 0,
3988 "DTIM period", HFILL }},
3991 {"Bitmap control", "wlan_mgt.tim.bmapctl",
3992 FT_UINT8, BASE_HEX, NULL, 0,
3993 "Bitmap control", HFILL }},
3996 {"RSN Capabilities", "wlan_mgt.rsn.capabilities", FT_UINT16, BASE_HEX,
3997 NULL, 0, "RSN Capability information", HFILL }},
4000 {"RSN Pre-Auth capabilities", "wlan_mgt.rsn.capabilities.preauth",
4001 FT_BOOLEAN, 16, TFS (&rsn_preauth_flags), 0x0001,
4002 "RSN Pre-Auth capabilities", HFILL }},
4004 {&rsn_cap_no_pairwise,
4005 {"RSN No Pairwise capabilities", "wlan_mgt.rsn.capabilities.no_pairwise",
4006 FT_BOOLEAN, 16, TFS (&rsn_no_pairwise_flags), 0x0002,
4007 "RSN No Pairwise capabilities", HFILL }},
4009 {&rsn_cap_ptksa_replay_counter,
4010 {"RSN PTKSA Replay Counter capabilities",
4011 "wlan_mgt.rsn.capabilities.ptksa_replay_counter",
4012 FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x000C,
4013 "RSN PTKSA Replay Counter capabilities", HFILL }},
4015 {&rsn_cap_gtksa_replay_counter,
4016 {"RSN GTKSA Replay Counter capabilities",
4017 "wlan_mgt.rsn.capabilities.gtksa_replay_counter",
4018 FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x0030,
4019 "RSN GTKSA Replay Counter capabilities", HFILL }},
4021 {&hf_aironet_ie_type,
4022 {"Aironet IE type", "wlan_mgt.aironet.type",
4023 FT_UINT8, BASE_DEC, VALS(aironet_ie_type_vals), 0, "", HFILL }},
4025 {&hf_aironet_ie_version,
4026 {"Aironet IE CCX version?", "wlan_mgt.aironet.version",
4027 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4029 { &hf_aironet_ie_data,
4030 { "Aironet IE data", "wlan_mgmt.aironet.data",
4031 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
4034 {"QBSS Version", "wlan_mgt.qbss.version",
4035 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4038 {"Station Count", "wlan_mgt.qbss.scount",
4039 FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
4042 {"Channel Utilization", "wlan_mgt.qbss.cu",
4043 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4046 {"Available Admission Capabilities", "wlan_mgt.qbss.adc",
4047 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4050 {"Channel Utilization", "wlan_mgt.qbss2.cu",
4051 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4054 {"G.711 CU Quantum", "wlan_mgt.qbss2.glimit",
4055 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4058 {"Call Admission Limit", "wlan_mgt.qbss2.cal",
4059 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4062 {"Station Count", "wlan_mgt.qbss2.scount",
4063 FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
4065 {&hf_aironet_ie_qos_unk1,
4066 {"Aironet IE QoS unknown1", "wlan_mgt.aironet.qos.unk1",
4067 FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
4069 {&hf_aironet_ie_qos_paramset,
4070 {"Aironet IE QoS paramset", "wlan_mgt.aironet.qos.paramset",
4071 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4073 {&hf_aironet_ie_qos_val,
4074 {"Aironet IE QoS valueset", "wlan_mgt.aironet.qos.val",
4075 FT_BYTES, BASE_NONE, NULL, 0, "", HFILL }},
4079 static gint *tree_array[] = {
4086 &ett_fixed_parameters,
4087 &ett_tagged_parameters,
4088 &ett_qos_parameters,
4089 &ett_qos_ps_buf_state,
4090 &ett_wep_parameters,
4095 module_t *wlan_module;
4097 static const enum_val_t wep_keys_options[] = {
4107 proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
4108 "IEEE 802.11", "wlan");
4109 proto_register_field_array (proto_wlan, hf, array_length (hf));
4110 proto_wlan_mgt = proto_register_protocol ("IEEE 802.11 wireless LAN management frame",
4111 "802.11 MGT", "wlan_mgt");
4112 proto_register_field_array (proto_wlan_mgt, ff, array_length (ff));
4113 proto_register_subtree_array (tree_array, array_length (tree_array));
4115 register_dissector("wlan", dissect_ieee80211, proto_wlan);
4116 register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
4117 register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan);
4118 register_dissector("wlan_datapad", dissect_ieee80211_datapad, proto_wlan);
4119 register_init_routine(wlan_defragment_init);
4121 wlan_tap = register_tap("wlan");
4123 /* Register configuration options */
4124 wlan_module = prefs_register_protocol(proto_wlan, init_wepkeys);
4125 prefs_register_bool_preference(wlan_module, "defragment",
4126 "Reassemble fragmented 802.11 datagrams",
4127 "Whether fragmented 802.11 datagrams should be reassembled",
4130 prefs_register_bool_preference(wlan_module, "check_fcs",
4131 "Assume packets have FCS",
4132 "Some 802.11 cards include the FCS at the end of a packet, others do not.",
4135 prefs_register_bool_preference(wlan_module, "ignore_wep",
4136 "Ignore the WEP bit",
4137 "Some 802.11 cards leave the WEP bit set even though the packet is decrypted.",
4141 prefs_register_enum_preference(wlan_module, "wep_keys",
4143 "How many WEP keys do we have to choose from? (0 to disable, up to 4)",
4144 &num_wepkeys, wep_keys_options, FALSE);
4146 prefs_register_string_preference(wlan_module, "wep_key1",
4148 "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",
4150 prefs_register_string_preference(wlan_module, "wep_key2",
4152 "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",
4154 prefs_register_string_preference(wlan_module, "wep_key3",
4156 "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",
4158 prefs_register_string_preference(wlan_module, "wep_key4",
4160 "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",
4166 proto_reg_handoff_ieee80211(void)
4168 dissector_handle_t ieee80211_handle;
4169 dissector_handle_t ieee80211_radio_handle;
4172 * Get handles for the LLC, IPX and Ethernet dissectors.
4174 llc_handle = find_dissector("llc");
4175 ipx_handle = find_dissector("ipx");
4176 eth_withoutfcs_handle = find_dissector("eth_withoutfcs");
4177 data_handle = find_dissector("data");
4179 ieee80211_handle = find_dissector("wlan");
4180 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle);
4181 ieee80211_radio_handle = create_dissector_handle(dissect_ieee80211_radio,
4183 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
4184 ieee80211_radio_handle);
4185 dissector_add("ethertype", ETHERTYPE_CENTRINO_PROMISC, ieee80211_handle);
4188 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len) {
4189 const guint8 *enc_data;
4192 tvbuff_t *decr_tvb = NULL;
4194 if (num_wepkeys < 1)
4197 enc_data = tvb_get_ptr(tvb, offset, len);
4199 if ((tmp = g_malloc(len)) == NULL)
4200 return NULL; /* krap! */
4202 /* try once with the key index in the packet, then look through our list. */
4203 for (i = -1; i < num_wepkeys; i++) {
4204 /* copy the encrypted data over to the tmp buffer */
4206 printf("trying %d\n", i);
4208 memcpy(tmp, enc_data, len);
4209 if (wep_decrypt(tmp, len, i) == 0) {
4211 /* decrypt successful, let's set up a new data tvb. */
4212 decr_tvb = tvb_new_real_data(tmp, len-8, len-8);
4213 tvb_set_free_cb(decr_tvb, g_free);
4214 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
4221 if ((!decr_tvb) && (tmp)) g_free(tmp);
4224 printf("de-wep %p\n", decr_tvb);
4231 /* de-weps the block. if successful, buf* will point to the data start. */
4232 static int wep_decrypt(guint8 *buf, guint32 len, int key_override) {
4233 guint32 i, j, k, crc, keylen;
4234 guint8 s[256], key[128], c_crc[4];
4235 guint8 keyidx, *dpos, *cpos;
4237 /* Needs to be at least 8 bytes of payload */
4241 /* initialize the first bytes of the key from the IV */
4245 keyidx = KEY_OCTET_WEP_KEY(buf[3]);
4247 if (key_override >= 0)
4248 keyidx = key_override;
4250 if (keyidx >= (guint)num_wepkeys)
4253 keylen = wep_keylens[keyidx];
4257 if (wep_keys[keyidx] == NULL)
4260 keylen+=3; /* add in ICV bytes */
4262 /* copy the rest of the key over from the designated key */
4263 memcpy(key+3, wep_keys[keyidx], wep_keylens[keyidx]);
4266 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]);
4269 /* set up the RC4 state */
4270 for (i = 0; i < 256; i++)
4273 for (i = 0; i < 256; i++) {
4274 j = (j + s[i] + key[i % keylen]) & 0xff;
4278 /* Apply the RC4 to the data, update the CRC32 */
4283 for (k = 0; k < (len -8); k++) {
4285 j = (j+s[i]) & 0xff;
4288 printf("%d -- %02x ", k, *dpos);
4290 *dpos = *cpos++ ^ s[(s[i] + s[j]) & 0xff];
4292 printf("%02x\n", *dpos);
4294 crc = crc32_ccitt_table[(crc ^ *dpos++) & 0xff] ^ (crc >> 8);
4298 /* now let's check the crc */
4300 c_crc[1] = crc >> 8;
4301 c_crc[2] = crc >> 16;
4302 c_crc[3] = crc >> 24;
4304 for (k = 0; k < 4; k++) {
4306 j = (j+s[i]) & 0xff;
4309 printf("-- %02x %02x\n", *dpos, c_crc[k]);
4311 if ((*cpos++ ^ s[(s[i] + s[j]) & 0xff]) != c_crc[k])
4312 return -1; /* ICV mismatch */
4318 static void init_wepkeys(void) {
4327 tmp = getenv("ETHEREAL_WEPKEYNUM");
4332 num_wepkeys = atoi(tmp);
4334 if (num_wepkeys > 4)
4338 if (num_wepkeys < 1)
4345 g_free(wep_keylens);
4347 wep_keys = g_malloc(num_wepkeys * sizeof(guint8*));
4348 wep_keylens = g_malloc(num_wepkeys * sizeof(int));
4349 bytes = g_byte_array_new();
4351 for (i = 0 ; i < num_wepkeys; i++) {
4357 g_snprintf(buf, 128, "ETHEREAL_WEPKEY%d", i+1);
4360 tmp = wep_keystr[i];
4366 printf("%s -- %s\n", buf, tmp);
4368 printf("%d -- %s\n", i+1, tmp);
4373 g_free(wep_keys[i]);
4376 res = hex_str_to_bytes(tmp, bytes, FALSE);
4377 if (res && bytes->len > 0) {
4378 if (bytes->len > 32) {
4381 wep_keys[i] = g_malloc(32 * sizeof(guint8));
4382 memset(wep_keys[i], 0, 32 * sizeof(guint8));
4383 memcpy(wep_keys[i], bytes->data, bytes->len * sizeof(guint8));
4384 wep_keylens[i] = bytes->len;
4386 printf("%d: %d bytes\n", i, bytes->len);
4387 printf("%d: %s\n", i, bytes_to_str(bytes->data, bytes->len));
4391 printf("res: %d bytes->len: %d\n", res, bytes->len);
4393 g_warning("Could not parse WEP key %d: %s", i + 1, tmp);
4397 g_byte_array_free(bytes, TRUE);
4400 * This code had been taken from AirSnort crack.c function classify()
4401 * Permission granted by snax <at> shmoo dot com
4402 * weak_iv - determine which key byte an iv is useful in resolving
4403 * parm - p, pointer to the first byte of an IV
4404 * return - n - this IV is weak for byte n of a WEP key
4405 * -1 - this IV is not weak for any key bytes
4407 * This function tests for IVs that are known to satisfy the criteria
4408 * for a weak IV as specified in FMS section 7.1
4416 if (iv[1] == 255 && iv[0] > 2 && iv[0] < 16) {
4420 sum = iv[0] + iv[1];
4422 if (iv[2] <= 0x0a) {
4425 else if (iv[2] == 0xff){
4430 if (sum == k && (iv[2] >= 0xf2 && iv[2] <= 0xfe && iv[2] != 0xfd)){