2 * Routines for Wireless LAN (IEEE 802.11) dissection
3 * Copyright 2000, Axis Communications AB
4 * Inquiries/bugreports should be sent to Johan.Jorgensen@axis.com
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * Copied from README.developer
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 * The following people helped me by pointing out bugs etc. Thank you!
34 * Magnus Hultman-Persson
38 * 09/12/2003 - Added dissection of country information tag
40 * Ritchie<at>tipsybottle.com
42 * 03/22/2004 - Added dissection of RSN IE
43 * Jouni Malinen <jkmaline@cc.hut.fi>
55 #include <epan/bitswap.h>
56 #include <epan/proto.h>
57 #include <epan/packet.h>
58 #include <epan/addr_resolv.h>
59 #include <epan/strutil.h>
60 #include <epan/prefs.h>
61 #include <epan/reassemble.h>
62 #include "packet-ipx.h"
63 #include "packet-llc.h"
64 #include "packet-ieee80211.h"
65 #include <epan/etypes.h>
67 #include <epan/crc32.h>
69 #include <epan/emem.h>
77 /* XXX - This is probably a bit much */
78 #define MAX_ENCRYPTION_KEYS 64
82 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
85 /* Defragment fragmented 802.11 datagrams */
86 static gboolean wlan_defragment = TRUE;
88 /* Check for the presence of the 802.11 FCS */
89 static gboolean wlan_check_fcs = FALSE;
91 /* Ignore the WEP bit; assume packet is decrypted */
92 static gboolean wlan_ignore_wep = FALSE;
94 /* Tables for reassembly of fragments. */
95 static GHashTable *wlan_fragment_table = NULL;
96 static GHashTable *wlan_reassembled_table = NULL;
98 /* Stuff for the WEP decoder */
99 /* XXX - Instead of making the user specify the number of WEP keys manually,
100 * we may want to change the "WEP key count" option to a toggle that
101 * enables/disables WEP decryption, and automatically figure out how
102 * many keys we have by parsing the key list.
104 static gint num_wepkeys = 0;
105 static guint8 **wep_keys = NULL;
106 static int *wep_keylens = NULL;
107 static void init_wepkeys(void);
108 static int wep_decrypt(guint8 *buf, guint32 len, int key_override);
109 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len);
110 static int weak_iv(guchar *iv);
111 #define SSWAP(a,b) {guint8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
113 /* #define USE_ENV */
114 /* When this is set, an unlimited number of WEP keys can be set in the
117 WIRESHARK_WEPKEYNUM=##
118 WIRESHARK_WEPKEY1=aa:bb:cc:dd:...
119 WIRESHARK_WEPKEY2=aa:bab:cc:dd:ee:...
121 ... you get the idea.
123 otherwise you're limited to specifying four keys in the preference system.
127 static char *wep_keystr[MAX_ENCRYPTION_KEYS];
130 /* ************************************************************************* */
131 /* Miscellaneous Constants */
132 /* ************************************************************************* */
133 #define SHORT_STR 256
135 /* ************************************************************************* */
136 /* Define some very useful macros that are used to analyze frame types etc. */
137 /* ************************************************************************* */
140 * Extract the protocol version from the frame control field
142 #define FCF_PROT_VERSION(x) ((x) & 0x3)
145 * Extract the frame type from the frame control field.
147 #define FCF_FRAME_TYPE(x) (((x) & 0xC) >> 2)
150 * Extract the frame subtype from the frame control field.
152 #define FCF_FRAME_SUBTYPE(x) (((x) & 0xF0) >> 4)
155 * Convert the frame type and subtype from the frame control field into
156 * one of the MGT_, CTRL_, or DATA_ values.
158 #define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+FCF_FRAME_SUBTYPE(x)) /* Create key to (sub)type */
161 * The subtype field of a data frame is, in effect, composed of 4 flag
162 * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have
163 * any data), and QoS.
165 #define DATA_FRAME_IS_CF_ACK(x) ((x) & 0x01)
166 #define DATA_FRAME_IS_CF_POLL(x) ((x) & 0x02)
167 #define DATA_FRAME_IS_NULL(x) ((x) & 0x04)
168 #define DATA_FRAME_IS_QOS(x) ((x) & 0x08)
171 * Extract the flags from the frame control field.
173 #define FCF_FLAGS(x) (((x) & 0xFF00) >> 8)
176 * Bits from the flags field.
178 #define FLAG_TO_DS 0x01
179 #define FLAG_FROM_DS 0x02
180 #define FLAG_MORE_FRAGMENTS 0x04
181 #define FLAG_RETRY 0x08
182 #define FLAG_POWER_MGT 0x10
183 #define FLAG_MORE_DATA 0x20
184 #define FLAG_PROTECTED 0x40
185 #define FLAG_ORDER 0x80
188 * Test bits in the flags field.
190 #define IS_TO_DS(x) ((x) & FLAG_TO_DS)
191 #define IS_FROM_DS(x) ((x) & FLAG_FROM_DS)
192 #define HAVE_FRAGMENTS(x) ((x) & FLAG_MORE_FRAGMENTS)
193 #define IS_RETRY(x) ((x) & FLAG_RETRY)
194 #define POWER_MGT_STATUS(x) ((x) & FLAG_POWER_MGT)
195 #define HAS_MORE_DATA(x) ((x) & FLAG_MORE_DATA)
196 #define IS_PROTECTED(x) (!wlan_ignore_wep && ((x) & FLAG_PROTECTED))
197 #define IS_STRICTLY_ORDERED(x) ((x) & FLAG_ORDER)
200 * Extract subfields from the flags field.
202 #define FLAGS_DS_STATUS(x) ((x) & (FLAG_FROM_DS|FLAG_TO_DS))
205 * Extract an indication of the types of addresses in a data frame from
206 * the frame control field.
208 #define FCF_ADDR_SELECTOR(x) ((x) & ((FLAG_TO_DS|FLAG_FROM_DS) << 8))
210 #define DATA_ADDR_T1 0
211 #define DATA_ADDR_T2 (FLAG_FROM_DS << 8)
212 #define DATA_ADDR_T3 (FLAG_TO_DS << 8)
213 #define DATA_ADDR_T4 ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
216 * Extract the fragment number and sequence number from the sequence
219 #define SEQCTL_FRAGMENT_NUMBER(x) ((x) & 0x000F)
220 #define SEQCTL_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
223 * Extract subfields from the QoS control field.
225 #define QOS_TID(x) ((x) & 0x000F)
226 #define QOS_PRIORITY(x) ((x) & 0x0007)
227 #define QOS_EOSP(x) (((x) & 0x0010) >> 4) /* end of service period */
228 #define QOS_ACK_POLICY(x) (((x) & 0x0060) >> 5)
229 #define QOS_FIELD_CONTENT(x) (((x) & 0xFF00) >> 8)
231 #define QOS_FLAG_EOSP 0x08
234 * Extract subfields from the result of QOS_FIELD_CONTENT().
236 #define QOS_PS_BUF_STATE(x) (((x) & 0x02) >> 1)
237 #define QOS_PS_BUF_AC(x) (((x) & 0x0C) >> 2)
238 #define QOS_PS_BUF_LOAD(x) (((x) & 0xF0) >> 4)
241 * Extract the association ID from the value in an association ID field.
243 #define ASSOC_ID(x) ((x) & 0x3FFF)
246 * Extract subfields from the key octet in WEP-encrypted frames.
248 #define KEY_OCTET_WEP_KEY(x) (((x) & 0xC0) >> 6)
250 #define KEY_EXTIV 0x20
254 /* ************************************************************************* */
255 /* Constants used to identify cooked frame types */
256 /* ************************************************************************* */
257 #define MGT_FRAME 0x00 /* Frame type is management */
258 #define CONTROL_FRAME 0x01 /* Frame type is control */
259 #define DATA_FRAME 0x02 /* Frame type is Data */
261 #define DATA_SHORT_HDR_LEN 24
262 #define DATA_LONG_HDR_LEN 30
263 #define MGT_FRAME_HDR_LEN 24 /* Length of Managment frame-headers */
266 * COMPOSE_FRAME_TYPE() values for management frames.
268 #define MGT_ASSOC_REQ 0x00 /* association request */
269 #define MGT_ASSOC_RESP 0x01 /* association response */
270 #define MGT_REASSOC_REQ 0x02 /* reassociation request */
271 #define MGT_REASSOC_RESP 0x03 /* reassociation response */
272 #define MGT_PROBE_REQ 0x04 /* Probe request */
273 #define MGT_PROBE_RESP 0x05 /* Probe response */
274 #define MGT_BEACON 0x08 /* Beacon frame */
275 #define MGT_ATIM 0x09 /* ATIM */
276 #define MGT_DISASS 0x0A /* Disassociation */
277 #define MGT_AUTHENTICATION 0x0B /* Authentication */
278 #define MGT_DEAUTHENTICATION 0x0C /* Deauthentication */
279 #define MGT_ACTION 0x0D /* Action */
282 * COMPOSE_FRAME_TYPE() values for control frames.
284 #define CTRL_BLOCK_ACK_REQ 0x18 /* Block ack Request */
285 #define CTRL_BLOCK_ACK 0x19 /* Block ack */
286 #define CTRL_PS_POLL 0x1A /* power-save poll */
287 #define CTRL_RTS 0x1B /* request to send */
288 #define CTRL_CTS 0x1C /* clear to send */
289 #define CTRL_ACKNOWLEDGEMENT 0x1D /* acknowledgement */
290 #define CTRL_CFP_END 0x1E /* contention-free period end */
291 #define CTRL_CFP_ENDACK 0x1F /* contention-free period end/ack */
294 * COMPOSE_FRAME_TYPE() values for data frames.
296 #define DATA 0x20 /* Data */
297 #define DATA_CF_ACK 0x21 /* Data + CF-Ack */
298 #define DATA_CF_POLL 0x22 /* Data + CF-Poll */
299 #define DATA_CF_ACK_POLL 0x23 /* Data + CF-Ack + CF-Poll */
300 #define DATA_NULL_FUNCTION 0x24 /* Null function (no data) */
301 #define DATA_CF_ACK_NOD 0x25 /* CF-Ack (no data) */
302 #define DATA_CF_POLL_NOD 0x26 /* CF-Poll (No data) */
303 #define DATA_CF_ACK_POLL_NOD 0x27 /* CF-Ack + CF-Poll (no data) */
305 #define DATA_QOS_DATA 0x28 /* QoS Data */
306 #define DATA_QOS_DATA_CF_ACK 0x29 /* QoS Data + CF-Ack */
307 #define DATA_QOS_DATA_CF_POLL 0x2A /* QoS Data + CF-Poll */
308 #define DATA_QOS_DATA_CF_ACK_POLL 0x2B /* QoS Data + CF-Ack + CF-Poll */
309 #define DATA_QOS_NULL 0x2C /* QoS Null */
310 #define DATA_QOS_CF_POLL_NOD 0x2E /* QoS CF-Poll (No Data) */
311 #define DATA_QOS_CF_ACK_POLL_NOD 0x2F /* QoS CF-Ack + CF-Poll (No Data) */
314 /* ************************************************************************* */
315 /* Macros used to extract information about fixed fields */
316 /* ************************************************************************* */
317 #define ESS_SET(x) ((x) & 0x0001)
318 #define IBSS_SET(x) ((x) & 0x0002)
322 /* ************************************************************************* */
323 /* Logical field codes (dissector's encoding of fixed fields) */
324 /* ************************************************************************* */
325 #define FIELD_TIMESTAMP 0x01 /* 64-bit timestamp */
326 #define FIELD_BEACON_INTERVAL 0x02 /* 16-bit beacon interval */
327 #define FIELD_CAP_INFO 0x03 /* Add capability information tree */
328 #define FIELD_AUTH_ALG 0x04 /* Authentication algorithm used */
329 #define FIELD_AUTH_TRANS_SEQ 0x05 /* Authentication sequence number */
330 #define FIELD_CURRENT_AP_ADDR 0x06
331 #define FIELD_LISTEN_IVAL 0x07
332 #define FIELD_REASON_CODE 0x08
333 #define FIELD_ASSOC_ID 0x09
334 #define FIELD_STATUS_CODE 0x0A
335 #define FIELD_CATEGORY_CODE 0x0B /* Management action category */
336 #define FIELD_ACTION_CODE 0x0C /* Management action code */
337 #define FIELD_DIALOG_TOKEN 0x0D /* Management action dialog token */
338 #define FIELD_WME_ACTION_CODE 0x0E /* Management notification action code */
339 #define FIELD_WME_DIALOG_TOKEN 0x0F /* Management notification dialog token */
340 #define FIELD_WME_STATUS_CODE 0x10 /* Management notification setup response status code */
342 /* ************************************************************************* */
343 /* Logical field codes (IEEE 802.11 encoding of tags) */
344 /* ************************************************************************* */
345 #define TAG_SSID 0x00
346 #define TAG_SUPP_RATES 0x01
347 #define TAG_FH_PARAMETER 0x02
348 #define TAG_DS_PARAMETER 0x03
349 #define TAG_CF_PARAMETER 0x04
351 #define TAG_IBSS_PARAMETER 0x06
352 #define TAG_COUNTRY_INFO 0x07
353 #define TAG_FH_HOPPING_PARAMETER 0x08
354 #define TAG_FH_HOPPING_TABLE 0x09
355 #define TAG_REQUEST 0x0A
356 #define TAG_QBSS_LOAD 0x0B
357 #define TAG_EDCA_PARAM_SET 0x0C
358 #define TAG_TRAF_SPEC 0x0D
359 #define TAG_TRAF_CLASS 0x0E
360 #define TAG_SCHEDULE 0x0F
361 #define TAG_CHALLENGE_TEXT 0x10
362 #define TAG_POWER_CONSTRAINT 0x20
363 #define TAG_POWER_CAPABILITY 0x21
364 #define TAG_TPC_REQUEST 0x22
365 #define TAG_TPC_REPORT 0x23
366 #define TAG_SUPPORTED_CHANNELS 0x24
367 #define TAG_CHANNEL_SWITCH_ANN 0x25
368 #define TAG_MEASURE_REQ 0x26
369 #define TAG_MEASURE_REP 0x27
370 #define TAG_QUIET 0x28
371 #define TAG_IBSS_DFS 0x29
372 #define TAG_ERP_INFO 0x2A
373 #define TAG_TS_DELAY 0x2B
374 #define TAG_TCLAS_PROCESS 0x2C
375 #define TAG_QOS_CAPABILITY 0x2E
376 #define TAG_ERP_INFO_OLD 0x2F /* IEEE Std 802.11g/D4.0 */
377 #define TAG_RSN_IE 0x30
378 #define TAG_EXT_SUPP_RATES 0x32
379 #define TAG_AGERE_PROPRIETARY 0x80
380 #define TAG_CISCO_UNKNOWN_1 0x85 /* Cisco Compatible eXtensions? */
381 #define TAG_CISCO_UNKNOWN_2 0x88 /* Cisco Compatible eXtensions? */
382 #define TAG_VENDOR_SPECIFIC_IE 0xDD
383 #define TAG_SYMBOL_PROPRIETARY 0xAD
385 #define WPA_OUI "\x00\x50\xF2"
386 #define RSN_OUI "\x00\x0F\xAC"
387 #define WME_OUI "\x00\x50\xF2"
391 /* ************************************************************************* */
392 /* Frame types, and their names */
393 /* ************************************************************************* */
394 static const value_string frame_type_subtype_vals[] = {
395 {MGT_ASSOC_REQ, "Association Request"},
396 {MGT_ASSOC_RESP, "Association Response"},
397 {MGT_REASSOC_REQ, "Reassociation Request"},
398 {MGT_REASSOC_RESP, "Reassociation Response"},
399 {MGT_PROBE_REQ, "Probe Request"},
400 {MGT_PROBE_RESP, "Probe Response"},
401 {MGT_BEACON, "Beacon frame"},
403 {MGT_DISASS, "Dissassociate"},
404 {MGT_AUTHENTICATION, "Authentication"},
405 {MGT_DEAUTHENTICATION, "Deauthentication"},
406 {MGT_ACTION, "Action"},
408 {CTRL_BLOCK_ACK_REQ, "802.11 Block Ack Req"},
409 {CTRL_BLOCK_ACK, "802.11 Block Ack"},
410 {CTRL_PS_POLL, "Power-Save poll"},
411 {CTRL_RTS, "Request-to-send"},
412 {CTRL_CTS, "Clear-to-send"},
413 {CTRL_ACKNOWLEDGEMENT, "Acknowledgement"},
414 {CTRL_CFP_END, "CF-End (Control-frame)"},
415 {CTRL_CFP_ENDACK, "CF-End + CF-Ack (Control-frame)"},
418 {DATA_CF_ACK, "Data + CF-Ack"},
419 {DATA_CF_POLL, "Data + CF-Poll"},
420 {DATA_CF_ACK_POLL, "Data + CF-Ack + CF-Poll"},
421 {DATA_NULL_FUNCTION, "Null function (No data)"},
422 {DATA_CF_ACK_NOD, "Acknowledgement (No data)"},
423 {DATA_CF_POLL_NOD, "CF-Poll (No data)"},
424 {DATA_CF_ACK_POLL_NOD, "CF-Ack/Poll (No data)"},
425 {DATA_QOS_DATA, "QoS Data"},
426 {DATA_QOS_DATA_CF_ACK, "QoS Data + CF-Acknowledgment"},
427 {DATA_QOS_DATA_CF_POLL, "QoS Data + CF-Poll"},
428 {DATA_QOS_DATA_CF_ACK_POLL, "QoS Data + CF-Ack + CF-Poll"},
429 {DATA_QOS_NULL, "QoS Null function (No data)"},
430 {DATA_QOS_CF_POLL_NOD, "QoS CF-Poll (No Data)"},
431 {DATA_QOS_CF_ACK_POLL_NOD, "QoS CF-Ack + CF-Poll (No data)"},
435 /* ************************************************************************* */
436 /* 802.1D Tag Names */
437 /* ************************************************************************* */
438 static const char *qos_tags[8] = {
449 /* ************************************************************************* */
450 /* WME Access Category Names (by 802.1D Tag) */
451 /* ************************************************************************* */
452 static const char *qos_acs[8] = {
463 /* ************************************************************************* */
464 /* WME Access Category Names (by WME ACI) */
465 /* ************************************************************************* */
466 static const char *wme_acs[4] = {
474 #define CAT_SPECTRUM_MGMT 0
477 #define CAT_BLOCK_ACK 3
478 #define CAT_MGMT_NOTIFICATION 17
480 #define SM_ACTION_MEASUREMENT_REQUEST 0
481 #define SM_ACTION_MEASUREMENT_REPORT 1
482 #define SM_ACTION_TPC_REQUEST 2
483 #define SM_ACTION_TPC_REPORT 3
484 #define SM_ACTION_CHAN_SWITCH_ANNC 4
486 static int proto_wlan = -1;
487 static packet_info * g_pinfo;
489 /* ************************************************************************* */
490 /* Header field info values for radio information */
491 /* ************************************************************************* */
492 static int hf_data_rate = -1;
493 static int hf_channel = -1;
494 static int hf_signal_strength = -1;
496 /* ************************************************************************* */
497 /* Header field info values for FC-field */
498 /* ************************************************************************* */
499 static int hf_fc_field = -1;
500 static int hf_fc_proto_version = -1;
501 static int hf_fc_frame_type = -1;
502 static int hf_fc_frame_subtype = -1;
503 static int hf_fc_frame_type_subtype = -1;
505 static int hf_fc_flags = -1;
506 static int hf_fc_to_ds = -1;
507 static int hf_fc_from_ds = -1;
508 static int hf_fc_data_ds = -1;
510 static int hf_fc_more_frag = -1;
511 static int hf_fc_retry = -1;
512 static int hf_fc_pwr_mgt = -1;
513 static int hf_fc_more_data = -1;
514 static int hf_fc_protected = -1;
515 static int hf_fc_order = -1;
518 /* ************************************************************************* */
519 /* Header values for Duration/ID field */
520 /* ************************************************************************* */
521 static int hf_did_duration = -1;
522 static int hf_assoc_id = -1;
525 /* ************************************************************************* */
526 /* Header values for different address-fields (all 4 of them) */
527 /* ************************************************************************* */
528 static int hf_addr_da = -1; /* Destination address subfield */
529 static int hf_addr_sa = -1; /* Source address subfield */
530 static int hf_addr_ra = -1; /* Receiver address subfield */
531 static int hf_addr_ta = -1; /* Transmitter address subfield */
532 static int hf_addr_bssid = -1; /* address is bssid */
534 static int hf_addr = -1; /* Source or destination address subfield */
537 /* ************************************************************************* */
538 /* Header values for QoS control field */
539 /* ************************************************************************* */
540 static int hf_qos_priority = -1;
541 static int hf_qos_ack_policy = -1;
542 static int hf_qos_eosp = -1;
543 static int hf_qos_field_content = -1;
544 /*static int hf_qos_txop_limit = -1;*/
545 /* FIXME: hf_ values not defined
546 static int hf_qos_buf_state = -1;
547 static int hf_qos_buf_ac = -1;
548 static int hf_qos_buf_load = -1;
550 /*static int hf_qos_txop_dur_req = -1;
551 static int hf_qos_queue_size = -1;*/
553 /* ************************************************************************* */
554 /* Header values for sequence number field */
555 /* ************************************************************************* */
556 static int hf_frag_number = -1;
557 static int hf_seq_number = -1;
559 /* ************************************************************************* */
560 /* Header values for Frame Check field */
561 /* ************************************************************************* */
562 static int hf_fcs = -1;
564 /* ************************************************************************* */
565 /* Header values for reassembly */
566 /* ************************************************************************* */
567 static int hf_fragments = -1;
568 static int hf_fragment = -1;
569 static int hf_fragment_overlap = -1;
570 static int hf_fragment_overlap_conflict = -1;
571 static int hf_fragment_multiple_tails = -1;
572 static int hf_fragment_too_long_fragment = -1;
573 static int hf_fragment_error = -1;
574 static int hf_reassembled_in = -1;
577 static int proto_wlan_mgt = -1;
578 /* ************************************************************************* */
579 /* Fixed fields found in mgt frames */
580 /* ************************************************************************* */
581 static int ff_auth_alg = -1; /* Authentication algorithm field */
582 static int ff_auth_seq = -1; /* Authentication transaction sequence */
583 static int ff_current_ap = -1; /* Current AP MAC address */
584 static int ff_listen_ival = -1; /* Listen interval fixed field */
585 static int ff_timestamp = -1; /* 64 bit timestamp */
586 static int ff_beacon_interval = -1; /* 16 bit Beacon interval */
587 static int ff_assoc_id = -1; /* 16 bit AID field */
588 static int ff_reason = -1; /* 16 bit reason code */
589 static int ff_status_code = -1; /* Status code */
590 static int ff_category_code = -1; /* 8 bit Category code */
591 static int ff_action_code = -1; /* 8 bit Action code */
592 static int ff_dialog_token = -1; /* 8 bit Dialog token */
593 static int ff_wme_action_code = -1; /* Management notification action code */
594 static int ff_wme_status_code = -1; /* Management notification setup response status code */
596 /* ************************************************************************* */
597 /* Flags found in the capability field (fixed field) */
598 /* ************************************************************************* */
599 static int ff_capture = -1;
600 static int ff_cf_ess = -1;
601 static int ff_cf_ibss = -1;
602 static int ff_cf_sta_poll = -1; /* CF pollable status for a STA */
603 static int ff_cf_ap_poll = -1; /* CF pollable status for an AP */
604 static int ff_cf_privacy = -1;
605 static int ff_cf_preamble = -1;
606 static int ff_cf_pbcc = -1;
607 static int ff_cf_agility = -1;
608 static int ff_short_slot_time = -1;
609 static int ff_dsss_ofdm = -1;
610 static int ff_cf_spec_man = -1;
611 static int ff_cf_apsd = -1;
612 static int ff_cf_del_blk_ack = -1;
613 static int ff_cf_imm_blk_ack = -1;
615 /* ************************************************************************* */
616 /* Tagged value format fields */
617 /* ************************************************************************* */
618 static int tag_number = -1;
619 static int tag_length = -1;
620 static int tag_interpretation = -1;
621 static int tag_oui = -1;
624 static int tim_length = -1;
625 static int tim_dtim_count = -1;
626 static int tim_dtim_period = -1;
627 static int tim_bmapctl = -1;
630 static int hf_fixed_parameters = -1; /* Protocol payload for management frames */
631 static int hf_tagged_parameters = -1; /* Fixed payload item */
632 static int hf_wep_iv = -1;
633 static int hf_wep_iv_weak = -1;
634 static int hf_tkip_extiv = -1;
635 static int hf_ccmp_extiv = -1;
636 static int hf_wep_key = -1;
637 static int hf_wep_icv = -1;
640 static int rsn_cap = -1;
641 static int rsn_cap_preauth = -1;
642 static int rsn_cap_no_pairwise = -1;
643 static int rsn_cap_ptksa_replay_counter = -1;
644 static int rsn_cap_gtksa_replay_counter = -1;
646 static int hf_aironet_ie_type = -1;
647 static int hf_aironet_ie_version = -1;
648 static int hf_aironet_ie_data = -1;
649 static int hf_aironet_ie_qos_unk1 = -1;
650 static int hf_aironet_ie_qos_paramset = -1;
651 static int hf_aironet_ie_qos_val = -1;
653 /*QBSS - Version 1,2,802.11e*/
655 static int hf_qbss2_cal = -1;
656 static int hf_qbss2_gl = -1;
657 static int hf_qbss_cu = -1;
658 static int hf_qbss2_cu = -1;
659 static int hf_qbss_scount = -1;
660 static int hf_qbss2_scount = -1;
661 static int hf_qbss_version = -1;
662 static int hf_qbss_adc = -1;
664 /* ************************************************************************* */
666 /* ************************************************************************* */
667 static gint ett_80211 = -1;
668 static gint ett_proto_flags = -1;
669 static gint ett_cap_tree = -1;
670 static gint ett_fc_tree = -1;
671 static gint ett_fragments = -1;
672 static gint ett_fragment = -1;
674 static gint ett_80211_mgt = -1;
675 static gint ett_fixed_parameters = -1;
676 static gint ett_tagged_parameters = -1;
677 static gint ett_qos_parameters = -1;
678 static gint ett_qos_ps_buf_state = -1;
679 static gint ett_wep_parameters = -1;
681 static gint ett_rsn_cap_tree = -1;
683 static gint ett_80211_mgt_ie = -1;
685 static const fragment_items frag_items = {
690 &hf_fragment_overlap,
691 &hf_fragment_overlap_conflict,
692 &hf_fragment_multiple_tails,
693 &hf_fragment_too_long_fragment,
699 static dissector_handle_t llc_handle;
700 static dissector_handle_t ipx_handle;
701 static dissector_handle_t eth_withoutfcs_handle;
702 static dissector_handle_t data_handle;
704 static int wlan_tap = -1;
706 /* ************************************************************************* */
707 /* Return the length of the current header (in bytes) */
708 /* ************************************************************************* */
710 find_header_length (guint16 fcf)
714 switch (FCF_FRAME_TYPE (fcf)) {
717 return MGT_FRAME_HDR_LEN;
720 switch (COMPOSE_FRAME_TYPE (fcf)) {
723 case CTRL_ACKNOWLEDGEMENT:
729 case CTRL_CFP_ENDACK:
730 case CTRL_BLOCK_ACK_REQ:
737 len = (FCF_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
739 if (DATA_FRAME_IS_QOS(COMPOSE_FRAME_TYPE(fcf)))
750 /* ************************************************************************* */
751 /* This is the capture function used to update packet counts */
752 /* ************************************************************************* */
754 capture_ieee80211_common (const guchar * pd, int offset, int len,
755 packet_counts * ld, gboolean fixed_length_header,
758 guint16 fcf, hdr_length;
760 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
765 fcf = pletohs (&pd[offset]);
767 if (IS_PROTECTED(FCF_FLAGS(fcf)))
773 switch (COMPOSE_FRAME_TYPE (fcf))
776 case DATA: /* We got a data frame */
777 case DATA_CF_ACK: /* Data with ACK */
779 case DATA_CF_ACK_POLL:
781 if (fixed_length_header)
782 hdr_length = DATA_LONG_HDR_LEN;
784 hdr_length = find_header_length (fcf);
786 hdr_length = roundup2(hdr_length, 4);
787 /* I guess some bridges take Netware Ethernet_802_3 frames,
788 which are 802.3 frames (with a length field rather than
789 a type field, but with no 802.2 header in the payload),
790 and just stick the payload into an 802.11 frame. I've seen
791 captures that show frames of that sort.
793 This means we have to do the same check for Netware 802.3 -
794 or, if you will, "Netware 802.11" - that we do in the
795 Ethernet dissector, i.e. checking for 0xffff as the first
796 four bytes of the payload and, if we find it, treating it
798 if (!BYTES_ARE_IN_FRAME(offset+hdr_length, len, 2)) {
802 if (pd[offset+hdr_length] == 0xff && pd[offset+hdr_length+1] == 0xff) {
806 capture_llc (pd, offset + hdr_length, len, ld);
817 * Handle 802.11 with a variable-length link-layer header.
820 capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
822 capture_ieee80211_common (pd, offset, len, ld, FALSE, FALSE);
826 * Handle 802.11 with a variable-length link-layer header and data padding.
829 capture_ieee80211_datapad (const guchar * pd, int offset, int len,
832 capture_ieee80211_common (pd, offset, len, ld, FALSE, TRUE);
836 * Handle 802.11 with a fixed-length link-layer header (padded to the
840 capture_ieee80211_fixed (const guchar * pd, int offset, int len, packet_counts * ld)
842 capture_ieee80211_common (pd, offset, len, ld, TRUE, FALSE);
846 /* ************************************************************************* */
847 /* Add the subtree used to store the fixed parameters */
848 /* ************************************************************************* */
850 get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
852 proto_item *fixed_fields;
854 proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
855 size, size, "Fixed parameters (%d bytes)",
858 return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
862 /* ************************************************************************* */
863 /* Add the subtree used to store tagged parameters */
864 /* ************************************************************************* */
866 get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
868 proto_item *tagged_fields;
870 tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
875 "Tagged parameters (%d bytes)",
878 return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
882 /* ************************************************************************* */
883 /* Dissect and add fixed mgmt fields to protocol tree */
884 /* ************************************************************************* */
886 add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
888 const guint8 *dataptr;
889 char out_buff[SHORT_STR];
891 proto_item *cap_item;
892 static proto_tree *cap_tree;
897 case FIELD_TIMESTAMP:
898 dataptr = tvb_get_ptr (tvb, offset, 8);
899 memset (out_buff, 0, SHORT_STR);
900 g_snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
910 proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
913 case FIELD_BEACON_INTERVAL:
914 capability = tvb_get_letohs (tvb, offset);
915 temp_double = (double)capability;
916 temp_double = temp_double * 1024 / 1000000;
917 proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
918 temp_double,"Beacon Interval: %f [Seconds]",
920 if (check_col (g_pinfo->cinfo, COL_INFO)) {
921 col_append_fstr(g_pinfo->cinfo, COL_INFO, ",BI=%d", capability);
927 capability = tvb_get_letohs (tvb, offset);
929 cap_item = proto_tree_add_uint_format (tree, ff_capture,
932 "Capability Information: 0x%04X",
934 cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree);
935 proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 2,
937 proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 2,
939 if (ESS_SET (capability) != 0) /* This is an AP */
940 proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2,
943 else /* This is a STA */
944 proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
946 proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 2,
948 proto_tree_add_boolean (cap_tree, ff_cf_preamble, tvb, offset, 2,
950 proto_tree_add_boolean (cap_tree, ff_cf_pbcc, tvb, offset, 2,
952 proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 2,
954 proto_tree_add_boolean (cap_tree, ff_cf_spec_man, tvb, offset, 2,
956 proto_tree_add_boolean (cap_tree, ff_short_slot_time, tvb, offset, 2,
958 proto_tree_add_boolean (cap_tree, ff_cf_apsd, tvb, offset, 2,
960 proto_tree_add_boolean (cap_tree, ff_dsss_ofdm, tvb, offset, 2,
962 proto_tree_add_boolean (cap_tree, ff_cf_del_blk_ack, tvb, offset, 2,
964 proto_tree_add_boolean (cap_tree, ff_cf_imm_blk_ack, tvb, offset, 2,
969 proto_tree_add_item (tree, ff_auth_alg, tvb, offset, 2, TRUE);
972 case FIELD_AUTH_TRANS_SEQ:
973 proto_tree_add_item (tree, ff_auth_seq, tvb, offset, 2, TRUE);
976 case FIELD_CURRENT_AP_ADDR:
977 proto_tree_add_item (tree, ff_current_ap, tvb, offset, 6, FALSE);
980 case FIELD_LISTEN_IVAL:
981 proto_tree_add_item (tree, ff_listen_ival, tvb, offset, 2, TRUE);
984 case FIELD_REASON_CODE:
985 proto_tree_add_item (tree, ff_reason, tvb, offset, 2, TRUE);
989 proto_tree_add_uint(tree, ff_assoc_id, tvb, offset, 2,
990 ASSOC_ID(tvb_get_letohs(tvb,offset)));
991 /* proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE); */
994 case FIELD_STATUS_CODE:
995 proto_tree_add_item (tree, ff_status_code, tvb, offset, 2, TRUE);
998 case FIELD_CATEGORY_CODE:
999 proto_tree_add_item (tree, ff_category_code, tvb, offset, 1, TRUE);
1002 case FIELD_ACTION_CODE:
1003 proto_tree_add_item (tree, ff_action_code, tvb, offset, 1, TRUE);
1006 case FIELD_DIALOG_TOKEN:
1007 proto_tree_add_item (tree, ff_dialog_token, tvb, offset, 1, TRUE);
1010 case FIELD_WME_ACTION_CODE:
1011 proto_tree_add_item (tree, ff_wme_action_code, tvb, offset, 1, TRUE);
1014 case FIELD_WME_STATUS_CODE:
1015 proto_tree_add_item (tree, ff_wme_status_code, tvb, offset, 1, TRUE);
1020 static const char *wpa_cipher_str[] =
1031 wpa_cipher_idx2str(guint idx)
1033 if (idx < sizeof(wpa_cipher_str)/sizeof(wpa_cipher_str[0]))
1034 return wpa_cipher_str[idx];
1038 static const char *wpa_keymgmt_str[] =
1046 wpa_keymgmt_idx2str(guint idx)
1048 if (idx < sizeof(wpa_keymgmt_str)/sizeof(wpa_keymgmt_str[0]))
1049 return wpa_keymgmt_str[idx];
1054 dissect_vendor_ie_wpawme(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
1055 int offset, guint32 tag_len, const guint8 *tag_val)
1057 guint32 tag_val_off = 0;
1058 char out_buff[SHORT_STR];
1061 /* Wi-Fi Protected Access (WPA) Information Element */
1062 if (tag_val_off + 6 <= tag_len && !memcmp(tag_val, WPA_OUI"\x01", 4)) {
1063 g_snprintf(out_buff, SHORT_STR, "WPA IE, type %u, version %u",
1064 tag_val[tag_val_off + 3], pletohs(&tag_val[tag_val_off + 4]));
1065 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
1068 if (tag_val_off + 4 <= tag_len) {
1069 /* multicast cipher suite */
1070 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
1071 g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
1072 wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1073 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1076 /* unicast cipher suites */
1077 if (tag_val_off + 2 <= tag_len) {
1078 g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u",
1079 pletohs(tag_val + tag_val_off));
1080 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1084 while (tag_val_off + 4 <= tag_len) {
1085 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
1086 g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
1087 i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1088 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1096 /* authenticated key management suites */
1097 if (tag_val_off + 2 <= tag_len) {
1098 g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u",
1099 pletohs(tag_val + tag_val_off));
1100 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1104 while (tag_val_off + 4 <= tag_len) {
1105 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
1106 g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
1107 i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
1108 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1120 if (tag_val_off < tag_len)
1121 proto_tree_add_string(tree, tag_interpretation, tvb,
1122 offset, tag_len - tag_val_off, "Not interpreted");
1123 proto_item_append_text(ietree, ": WPA");
1124 } else if (tag_val_off + 7 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x00", 5)) {
1125 /* Wireless Multimedia Enhancements (WME) Information Element */
1126 g_snprintf(out_buff, SHORT_STR, "WME IE: type %u, subtype %u, version %u, parameter set %u",
1127 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
1128 tag_val[tag_val_off + 6]);
1129 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
1130 proto_item_append_text(ietree, ": WME");
1131 } else if (tag_val_off + 24 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x01", 5)) {
1132 /* Wireless Multimedia Enhancements (WME) Parameter Element */
1133 g_snprintf(out_buff, SHORT_STR, "WME PE: type %u, subtype %u, version %u, parameter set %u",
1134 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
1135 tag_val[tag_val_off + 6]);
1136 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
1139 for (i = 0; i < 4; i++) {
1140 g_snprintf(out_buff, SHORT_STR, "WME AC Parameters: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
1141 (tag_val[tag_val_off] & 0x60) >> 5,
1142 wme_acs[(tag_val[tag_val_off] & 0x60) >> 5],
1143 (tag_val[tag_val_off] & 0x10) ? "" : "not ",
1144 tag_val[tag_val_off] & 0x0f,
1145 tag_val[tag_val_off + 1] & 0x0f,
1146 (tag_val[tag_val_off + 1] & 0xf0) >> 4,
1147 tvb_get_letohs(tvb, offset + 2));
1148 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1152 proto_item_append_text(ietree, ": WME");
1153 } else if (tag_val_off + 56 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x02", 5)) {
1154 /* Wireless Multimedia Enhancements (WME) TSPEC Element */
1155 guint16 ts_info, msdu_size, surplus_bandwidth;
1156 const char *direction[] = { "Uplink", "Downlink", "Reserved", "Bi-directional" };
1157 const value_string fields[] = {
1158 {12, "Minimum Service Interval"},
1159 {16, "Maximum Service Interval"},
1160 {20, "Inactivity Interval"},
1161 {24, "Service Start Time"},
1162 {28, "Minimum Data Rate"},
1163 {32, "Mean Data Rate"},
1164 {36, "Maximum Burst Size"},
1165 {40, "Minimum PHY Rate"},
1166 {44, "Peak Data Rate"},
1167 {48, "Delay Bound"},
1172 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: type %u, subtype %u, version %u",
1173 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5]);
1174 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
1178 ts_info = tvb_get_letohs(tvb, offset);
1179 g_snprintf(out_buff, SHORT_STR, "WME TS Info: Priority %u (%s) (%s), Contention-based access %sset, %s",
1180 (ts_info >> 11) & 0x7, qos_tags[(ts_info >> 11) & 0x7], qos_acs[(ts_info >> 11) & 0x7],
1181 (ts_info & 0x0080) ? "" : "not ",
1182 direction[(ts_info >> 5) & 0x3]);
1183 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1187 msdu_size = tvb_get_letohs(tvb, offset);
1188 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s MSDU Size %u",
1189 (msdu_size & 0x8000) ? "Fixed" : "Nominal", msdu_size & 0x7fff);
1190 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1194 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Maximum MSDU Size %u", tvb_get_letohs(tvb, offset));
1195 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1199 while ((field = val_to_str(tag_val_off, fields, "Unknown"))) {
1200 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s %u", field, tvb_get_letohl(tvb, offset));
1201 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1204 if (tag_val_off == 52)
1208 surplus_bandwidth = tvb_get_letohs(tvb, offset);
1209 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Surplus Bandwidth Allowance Factor %u.%u",
1210 (surplus_bandwidth >> 13) & 0x7, (surplus_bandwidth & 0x1fff));
1214 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Medium Time %u", tvb_get_letohs(tvb, offset));
1215 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1218 proto_item_append_text(ietree, ": WME");
1223 dissect_vendor_ie_rsn(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
1224 int offset, guint32 tag_len, const guint8 *tag_val)
1226 guint32 tag_val_off = 0;
1227 char out_buff[SHORT_STR], *pos;
1230 if (tag_val_off + 4 <= tag_len && !memcmp(tag_val, RSN_OUI"\x04", 4)) {
1231 /* IEEE 802.11i / Key Data Encapsulation / Data Type=4 - PMKID.
1232 * This is only used within EAPOL-Key frame Key Data. */
1234 pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "RSN PMKID: ");
1235 if (tag_len - 4 != PMKID_LEN) {
1236 pos += g_snprintf(pos, out_buff + SHORT_STR - pos,
1237 "(invalid PMKID len=%d, expected 16) ", tag_len - 4);
1239 for (i = 0; i < tag_len - 4; i++) {
1240 pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
1241 tag_val[tag_val_off + 4 + i]);
1243 proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1246 proto_item_append_text(ietree, ": RSN");
1250 AIRONET_IE_VERSION = 3,
1252 AIRONET_IE_QBSS_V2 = 14
1253 } aironet_ie_type_t;
1255 static const value_string aironet_ie_type_vals[] = {
1256 { AIRONET_IE_VERSION, "CCX version"},
1257 { AIRONET_IE_QOS, "Qos"},
1258 { AIRONET_IE_QBSS_V2, "QBSS V2 - CCA"},
1264 dissect_vendor_ie_aironet(proto_item * aironet_item, proto_tree * ietree,
1265 tvbuff_t * tvb, int offset, guint32 tag_len)
1269 gboolean dont_change = FALSE; /* Don't change the IE item text to default */
1271 type = tvb_get_guint8(tvb, offset);
1272 proto_tree_add_item (ietree, hf_aironet_ie_type, tvb, offset, 1, TRUE);
1276 case AIRONET_IE_VERSION:
1277 proto_tree_add_item (ietree, hf_aironet_ie_version, tvb, offset, 1, TRUE);
1278 proto_item_append_text(aironet_item, ": Aironet CCX version = %d",
1279 tvb_get_guint8(tvb, offset));
1282 case AIRONET_IE_QOS:
1283 proto_tree_add_item (ietree, hf_aironet_ie_qos_unk1, tvb, offset, 1, TRUE);
1285 proto_tree_add_item (ietree, hf_aironet_ie_qos_paramset, tvb, offset, 1, TRUE);
1288 /* XXX: just copied over from WME. Maybe "Best Effort" and "Background"
1289 * need to be swapped. Also, the "TXOP" may be TXOP - or not.
1291 for (i = 0; i < 4; i++) {
1292 guint8 byte1, byte2;
1294 byte1 = tvb_get_guint8(tvb, offset);
1295 byte2 = tvb_get_guint8(tvb, offset + 1);
1296 txop = tvb_get_letohs(tvb, offset + 2);
1297 proto_tree_add_bytes_format(ietree, hf_aironet_ie_qos_val, tvb, offset, 4,
1298 tvb_get_ptr(tvb, offset, 4),
1299 "CCX QoS Parameters??: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
1300 (byte1 & 0x60) >> 5, wme_acs[(byte1 & 0x60) >> 5],
1301 (byte1 & 0x10) ? "" : "not ", byte1 & 0x0f,
1302 byte2 & 0x0f, (byte2 & 0xf0) >> 4,
1307 case AIRONET_IE_QBSS_V2:
1308 /* Extract Values */
1309 proto_tree_add_item (ietree, hf_qbss2_scount, tvb, offset, 2, TRUE);
1310 proto_tree_add_item (ietree, hf_qbss2_cu, tvb, offset + 2, 1, FALSE);
1311 proto_tree_add_item (ietree, hf_qbss2_cal, tvb, offset + 3, 1, FALSE);
1312 proto_tree_add_item (ietree, hf_qbss2_gl, tvb, offset + 4, 1, FALSE);
1315 proto_tree_add_item(ietree, hf_aironet_ie_data, tvb, offset,
1316 tag_len - 1, FALSE);
1320 proto_item_append_text(aironet_item, ": Aironet %s",
1321 val_to_str(type, aironet_ie_type_vals, "Unknown"));
1326 dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
1327 guint32 tag_len, const guint8 *tag_val)
1329 guint32 tag_val_off = 0;
1331 char out_buff[SHORT_STR];
1333 proto_item *cap_item;
1334 proto_tree *cap_tree;
1336 if (tag_val_off + 2 > tag_len) {
1337 proto_tree_add_string(tree, tag_interpretation, tvb, offset, tag_len,
1342 g_snprintf(out_buff, SHORT_STR, "RSN IE, version %u",
1343 pletohs(&tag_val[tag_val_off]));
1344 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1349 if (tag_val_off + 4 > tag_len)
1352 /* multicast cipher suite */
1353 if (!memcmp(&tag_val[tag_val_off], RSN_OUI, 3)) {
1354 g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
1355 wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1356 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1361 if (tag_val_off + 2 > tag_len)
1364 /* unicast cipher suites */
1365 count = pletohs(tag_val + tag_val_off);
1366 g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u", count);
1367 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1371 while (tag_val_off + 4 <= tag_len && i <= count) {
1372 if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
1374 g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
1375 i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1376 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1382 if (i <= count || tag_val_off + 2 > tag_len)
1385 /* authenticated key management suites */
1386 count = pletohs(tag_val + tag_val_off);
1387 g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u", count);
1388 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1392 while (tag_val_off + 4 <= tag_len && i <= count) {
1393 if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
1395 g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
1396 i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
1397 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1403 if (i <= count || tag_val_off + 2 > tag_len)
1406 rsn_capab = pletohs(&tag_val[tag_val_off]);
1407 g_snprintf(out_buff, SHORT_STR, "RSN Capabilities 0x%04x", rsn_capab);
1408 cap_item = proto_tree_add_uint_format(tree, rsn_cap, tvb,
1409 offset, 2, rsn_capab,
1410 "RSN Capabilities: 0x%04X", rsn_capab);
1411 cap_tree = proto_item_add_subtree(cap_item, ett_rsn_cap_tree);
1412 proto_tree_add_boolean(cap_tree, rsn_cap_preauth, tvb, offset, 2,
1414 proto_tree_add_boolean(cap_tree, rsn_cap_no_pairwise, tvb, offset, 2,
1416 proto_tree_add_uint(cap_tree, rsn_cap_ptksa_replay_counter, tvb, offset, 2,
1418 proto_tree_add_uint(cap_tree, rsn_cap_gtksa_replay_counter, tvb, offset, 2,
1423 if (tag_val_off + 2 > tag_len)
1426 count = pletohs(tag_val + tag_val_off);
1427 g_snprintf(out_buff, SHORT_STR, "# of PMKIDs: %u", count);
1428 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1432 /* PMKID List (16 * n octets) */
1433 for (i = 0; i < count; i++) {
1435 if (tag_val_off + PMKID_LEN > tag_len)
1438 pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "PMKID %u: ", i);
1439 for (j = 0; j < PMKID_LEN; j++) {
1440 pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
1441 tag_val[tag_val_off + j]);
1443 proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1444 PMKID_LEN, out_buff);
1445 offset += PMKID_LEN;
1446 tag_val_off += PMKID_LEN;
1450 if (tag_val_off < tag_len)
1451 proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1452 tag_len - tag_val_off, "Not interpreted");
1455 /* ************************************************************************* */
1456 /* Dissect and add tagged (optional) fields to proto tree */
1457 /* ************************************************************************* */
1459 static const value_string tag_num_vals[] = {
1460 { TAG_SSID, "SSID parameter set" },
1461 { TAG_SUPP_RATES, "Supported Rates" },
1462 { TAG_FH_PARAMETER, "FH Parameter set" },
1463 { TAG_DS_PARAMETER, "DS Parameter set" },
1464 { TAG_CF_PARAMETER, "CF Parameter set" },
1465 { TAG_TIM, "(TIM) Traffic Indication Map" },
1466 { TAG_IBSS_PARAMETER, "IBSS Parameter set" },
1467 { TAG_COUNTRY_INFO, "Country Information" },
1468 { TAG_FH_HOPPING_PARAMETER, "Hopping Pattern Parameters" },
1469 { TAG_CHALLENGE_TEXT, "Challenge text" },
1470 { TAG_ERP_INFO, "ERP Information" },
1471 { TAG_ERP_INFO_OLD, "ERP Information" },
1472 { TAG_RSN_IE, "RSN Information" },
1473 { TAG_EXT_SUPP_RATES, "Extended Supported Rates" },
1474 { TAG_CISCO_UNKNOWN_1, "Cisco Unknown 1 + Device Name" },
1475 { TAG_CISCO_UNKNOWN_2, "Cisco Unknown 2" },
1476 { TAG_VENDOR_SPECIFIC_IE, "Vendor Specific" },
1477 { TAG_SYMBOL_PROPRIETARY, "Symbol Proprietary"},
1478 { TAG_AGERE_PROPRIETARY, "Agere Proprietary"},
1479 { TAG_REQUEST, "Request"},
1480 { TAG_QBSS_LOAD, "QBSS Load Element"},
1481 { TAG_EDCA_PARAM_SET, "EDCA Parameter Set"},
1482 { TAG_TRAF_SPEC, "Traffic Specification"},
1483 { TAG_TRAF_CLASS, "Traffic Classification"},
1484 { TAG_SCHEDULE, "Schedule"},
1485 { TAG_TS_DELAY, "TS Delay"},
1486 { TAG_TCLAS_PROCESS, "TCLAS Processing"},
1487 { TAG_QOS_CAPABILITY, "QoS Capability"},
1488 { TAG_POWER_CONSTRAINT, "Power Constraint"},
1489 { TAG_POWER_CAPABILITY, "Power Capability"},
1490 { TAG_TPC_REQUEST, "TPC Request"},
1491 { TAG_TPC_REPORT, "TPC Report"},
1492 { TAG_SUPPORTED_CHANNELS, "Supported Channels"},
1493 { TAG_CHANNEL_SWITCH_ANN, "Channel Switch Announcement"},
1494 { TAG_MEASURE_REQ, "Measurement Request"},
1495 { TAG_MEASURE_REP, "Measurement Report"},
1496 { TAG_QUIET, "Quiet"},
1497 { TAG_IBSS_DFS, "IBSS DFS"},
1501 static const value_string environment_vals[] = {
1503 { 0x4f, "Outdoor" },
1508 static int beacon_padding = 0; /* beacon padding bug */
1510 add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int offset)
1513 const guint8 *tag_val;
1514 const guint8 *tag_data_ptr;
1515 guint32 tag_no, tag_len;
1518 char out_buff[SHORT_STR];
1519 char print_buff[SHORT_STR];
1520 proto_tree * orig_tree=tree;
1523 tag_no = tvb_get_guint8(tvb, offset);
1524 tag_len = tvb_get_guint8(tvb, offset + 1);
1526 ti=proto_tree_add_text(orig_tree,tvb,offset,tag_len+2,"%s",
1527 val_to_str(tag_no, tag_num_vals,
1528 (tag_no >= 17 && tag_no <= 31) ?
1529 "Reserved for challenge text" : "Reserved tag number" ));
1530 tree=proto_item_add_subtree(ti,ett_80211_mgt_ie);
1532 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
1533 "Tag Number: %u (%s)",
1535 val_to_str(tag_no, tag_num_vals,
1536 (tag_no >= 17 && tag_no <= 31) ?
1537 "Reserved for challenge text" :
1538 "Reserved tag number"));
1539 proto_tree_add_uint (tree, (tag_no==TAG_TIM ? tim_length : tag_length), tvb, offset + 1, 1, tag_len);
1545 if(beacon_padding == 0) /* padding bug */
1549 ssid = tvb_get_ephemeral_string(tvb, offset + 2, tag_len);
1550 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1552 if (check_col (pinfo->cinfo, COL_INFO)) {
1554 col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: \"%s\"",
1555 format_text(ssid, tag_len));
1557 col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: Broadcast");
1561 proto_item_append_text(ti, ": \"%s\"",
1562 format_text(ssid, tag_len));
1564 proto_item_append_text(ti, ": Broadcast");
1566 beacon_padding++; /* padding bug */
1570 case TAG_SUPP_RATES:
1571 case TAG_EXT_SUPP_RATES:
1574 proto_tree_add_text (tree, tvb, offset + 2, tag_len,
1575 "Tag length %u too short, must be > 0", tag_len);
1578 tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
1580 tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
1581 for (i = 0, n = 0; i < tag_len && n < SHORT_STR; i++) {
1582 ret = g_snprintf (print_buff + n, SHORT_STR - n, "%2.1f%s ",
1583 (tag_data_ptr[i] & 0x7F) * 0.5,
1584 (tag_data_ptr[i] & 0x80) ? "(B)" : "");
1585 if (ret == -1 || ret >= SHORT_STR - n) {
1586 /* Some versions of snprintf return -1 if they'd truncate
1587 the output. Others return <buf_size> or greater. */
1592 g_snprintf (out_buff, SHORT_STR, "Supported rates: %s [Mbit/sec]", print_buff);
1593 out_buff[SHORT_STR-1] = '\0';
1594 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1596 proto_item_append_text(ti, ": %s", print_buff);
1599 case TAG_FH_PARAMETER:
1602 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 5",
1606 g_snprintf (out_buff, SHORT_STR,
1607 "Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, Hop Index %2d",
1608 tvb_get_letohs(tvb, offset + 2),
1609 tvb_get_guint8(tvb, offset + 4),
1610 tvb_get_guint8(tvb, offset + 5),
1611 tvb_get_guint8(tvb, offset + 6));
1612 out_buff[SHORT_STR-1] = '\0';
1613 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1617 case TAG_DS_PARAMETER:
1620 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
1624 g_snprintf (out_buff, SHORT_STR, "Current Channel: %u",
1625 tvb_get_guint8(tvb, offset + 2));
1626 out_buff[SHORT_STR-1] = '\0';
1627 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1629 proto_item_append_text(ti, ": %s", out_buff);
1632 case TAG_CF_PARAMETER:
1635 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 6",
1639 g_snprintf (out_buff, SHORT_STR, "CFP count: %u",
1640 tvb_get_guint8(tvb, offset + 2));
1641 out_buff[SHORT_STR-1] = '\0';
1642 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2,
1643 1, out_buff, "%s", out_buff);
1644 g_snprintf (out_buff, SHORT_STR, "CFP period: %u",
1645 tvb_get_guint8(tvb, offset + 3));
1646 out_buff[SHORT_STR-1] = '\0';
1647 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 3,
1648 1, out_buff, "%s", out_buff);
1649 g_snprintf (out_buff, SHORT_STR, "CFP max duration: %u",
1650 tvb_get_letohs(tvb, offset + 4));
1651 out_buff[SHORT_STR-1] = '\0';
1652 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 4,
1653 2, out_buff, "%s", out_buff);
1654 g_snprintf (out_buff, SHORT_STR, "CFP Remaining: %u",
1655 tvb_get_letohs(tvb, offset + 6));
1656 out_buff[SHORT_STR-1] = '\0';
1657 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 6,
1658 2, out_buff, "%s", out_buff);
1659 proto_item_append_text(ti, ": CFP count %u, CFP period %u, CFP max duration %u, "
1661 tvb_get_guint8(tvb, offset + 2),
1662 tvb_get_guint8(tvb, offset + 3),
1663 tvb_get_letohs(tvb, offset + 4),
1664 tvb_get_letohs(tvb, offset + 6));
1670 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 4",
1680 proto_tree_add_item(tree, tim_dtim_count, tvb,
1681 offset + 2, 1, TRUE);
1682 proto_tree_add_item(tree, tim_dtim_period, tvb,
1683 offset + 3, 1, TRUE);
1684 proto_item_append_text(ti, ": DTIM %u of %u bitmap",
1685 tvb_get_guint8(tvb, offset + 2),
1686 tvb_get_guint8(tvb, offset + 3));
1688 bmapctl = tvb_get_guint8(tvb, offset + 4);
1689 bmapoff = bmapctl>>1;
1690 proto_tree_add_uint_format(tree, tim_bmapctl, tvb,
1691 offset + 4, 1, bmapctl,
1692 "Bitmap Control: 0x%02X (mcast:%u, bitmap offset %u)",
1693 bmapctl, bmapctl&1, bmapoff);
1695 bmaplen = tag_len - 3;
1696 bmap = tvb_get_ptr(tvb, offset + 5, bmaplen);
1697 if (bmaplen==1 && 0==bmap[0] && !(bmapctl&1)) {
1698 proto_item_append_text(ti, " empty");
1701 proto_item_append_text(ti, " mcast");
1704 if (bmaplen>1 || bmap[0]) {
1705 int len=g_snprintf (out_buff, SHORT_STR,
1706 "Bitmap: traffic for AID's:");
1708 for (i=0;i<bmaplen*8;i++) {
1709 if (bmap[i/8] & (1<<(i%8))) {
1710 int aid=i+2*bmapoff*8;
1711 len+=g_snprintf (out_buff+len, SHORT_STR-len," %u", aid);
1712 proto_item_append_text(ti, " %u", aid);
1713 if (len>=SHORT_STR) {
1718 out_buff[SHORT_STR-1] = '\0';
1719 proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 5,
1720 bmaplen, out_buff, "%s", out_buff);
1725 case TAG_IBSS_PARAMETER:
1728 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
1732 g_snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
1733 tvb_get_letohs(tvb, offset + 2));
1734 out_buff[SHORT_STR-1] = '\0';
1735 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1737 proto_item_append_text(ti, ": %s", out_buff);
1740 case TAG_COUNTRY_INFO: /* IEEE 802.11d-2001 and IEEE 802.11j-2004 */
1746 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 3",
1750 tvb_memcpy(tvb, ccode, offset + 2, 2);
1752 g_snprintf (out_buff, SHORT_STR, "Country Code: %s, %s Environment",
1753 format_text(ccode, 2),
1754 val_to_str(tvb_get_guint8(tvb, offset + 4), environment_vals,"Unknown (0x%02x)"));
1755 out_buff[SHORT_STR-1] = '\0';
1756 proto_item_append_text(ti, ": %s", out_buff);
1757 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,3, out_buff);
1759 for (i = 3; (i + 3) <= tag_len; i += 3)
1761 guint8 val1, val2, val3;
1762 val1 = tvb_get_guint8(tvb, offset + 2 + i);
1763 val2 = tvb_get_guint8(tvb, offset + 3 + i);
1764 val3 = tvb_get_guint8(tvb, offset + 4 + i);
1766 if (val1 <= 200) { /* 802.11d */
1767 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
1768 " Start Channel: %u, Channels: %u, Max TX Power: %d dBm",
1769 val1, val2, (gint) val3);
1770 } else { /* 802.11j */
1771 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
1772 " Reg Extension Id: %u, Regulatory Class: %u, Coverage Class: %u",
1780 if (tag_len < 4 || tag_len >5)
1782 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Wrong QBSS Tag Length %u", tag_len);
1788 /* QBSS Version 1 */
1789 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 1,
1790 tag_len, "Cisco QBSS Version 1 - non CCA");
1792 /* Extract Values */
1793 proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 1);
1794 proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
1795 proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
1796 proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 1, FALSE);
1798 else if (tag_len == 5)
1800 /* QBSS Version 2 */
1801 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1802 tag_len, "802.11e CCA Version");
1804 /* Extract Values */
1805 proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 2);
1806 proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
1807 proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
1808 proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 2, FALSE);
1812 case TAG_FH_HOPPING_PARAMETER:
1815 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
1819 g_snprintf (out_buff, SHORT_STR, "Prime Radix: %u, Number of Channels: %u",
1820 tvb_get_guint8(tvb, offset + 2),
1821 tvb_get_guint8(tvb, offset + 3));
1822 out_buff[SHORT_STR-1] = '\0';
1823 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2, tag_len, out_buff);
1824 proto_item_append_text(ti, ": %s", out_buff);
1827 case TAG_CHALLENGE_TEXT:
1828 g_snprintf (out_buff, SHORT_STR, "Challenge text: %s",
1829 tvb_bytes_to_str(tvb, offset + 2, tag_len));
1830 out_buff[SHORT_STR-1] = '\0';
1831 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1836 case TAG_ERP_INFO_OLD:
1842 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
1846 erp_info = tvb_get_guint8 (tvb, offset + 2);
1847 g_snprintf (print_buff, SHORT_STR, "%sNon-ERP STAs, %suse protection, %s preambles",
1848 erp_info & 0x01 ? "" : "no ",
1849 erp_info & 0x02 ? "" : "do not ",
1850 /* 802.11g, 7.3.2.13: 1 means "one or more ... STAs
1851 * are not short preamble capable" */
1852 erp_info & 0x04 ? "long": "short or long");
1853 print_buff[SHORT_STR-1] = '\0';
1854 g_snprintf (out_buff, SHORT_STR,
1855 "ERP info: 0x%x (%s)",erp_info,print_buff);
1856 out_buff[SHORT_STR-1] = '\0';
1857 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1859 proto_item_append_text(ti, ": %s", print_buff);
1863 case TAG_CISCO_UNKNOWN_1:
1864 /* The Name of the sending device starts at offset 10 and is up to
1865 15 or 16 bytes in length, \0 padded */
1868 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 26",
1872 /* A cisco AP transmits the first 15 bytes of the AP name, probably
1873 followed by '\0' for ASCII termination */
1874 g_snprintf (out_buff, SHORT_STR, "%.16s",
1875 tvb_format_stringzpad(tvb, offset + 12, 16));
1876 out_buff[SHORT_STR-1] = '\0';
1877 proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 2,
1878 tag_len, "", "Tag interpretation: Unknown + Name: %s #Clients: %u",
1880 /* Total number off associated clients and
1881 repeater access points */
1882 tvb_get_guint8(tvb, offset + 28));
1883 if (check_col (pinfo->cinfo, COL_INFO)) {
1884 col_append_fstr(pinfo->cinfo, COL_INFO, ", Name: \"%s\"", out_buff);
1888 case TAG_VENDOR_SPECIFIC_IE:
1889 tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
1891 oui = tvb_get_ntoh24(tvb, offset + 2);
1892 tag_val = tvb_get_ptr(tvb, offset + 2, tag_len);
1894 #define WPAWME_OUI 0x0050F2
1895 #define RSNOUI_VAL 0x000FAC
1899 dissect_vendor_ie_wpawme(ti, tree, tvb, offset + 2, tag_len, tag_val);
1902 dissect_vendor_ie_rsn(ti, tree, tvb, offset + 2, tag_len, tag_val);
1904 case OUI_CISCOWL: /* Cisco Wireless (Aironet) */
1905 dissect_vendor_ie_aironet(ti, tree, tvb, offset + 5, tag_len - 3);
1908 proto_tree_add_bytes_format (tree, tag_oui, tvb, offset + 2, 3,
1909 "", "Vendor: %s", get_manuf_name(tag_val));
1910 proto_item_append_text(ti, ": %s", get_manuf_name(tag_val));
1911 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 5,
1912 tag_len - 3, "Not interpreted");
1920 dissect_rsn_ie(tree, tvb, offset + 2, tag_len,
1921 tvb_get_ptr (tvb, offset + 2, tag_len));
1925 tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
1926 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1927 tag_len, "Not interpreted");
1928 proto_item_append_text(ti, ": Tag %u Len %u", tag_no, tag_len);
1936 ieee_80211_add_tagged_parameters (tvbuff_t * tvb, int offset, packet_info * pinfo,
1937 proto_tree * tree, int tagged_parameters_len)
1941 beacon_padding = 0; /* this is for the beacon padding confused with ssid fix */
1942 while (tagged_parameters_len > 0) {
1943 if ((next_len=add_tagged_field (pinfo, tree, tvb, offset))==0)
1945 if (next_len > tagged_parameters_len) {
1946 /* XXX - flag this as an error? */
1947 next_len = tagged_parameters_len;
1950 tagged_parameters_len -= next_len;
1954 /* ************************************************************************* */
1955 /* Dissect 802.11 management frame */
1956 /* ************************************************************************* */
1958 dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
1961 proto_item *ti = NULL;
1962 proto_tree *mgt_tree;
1963 proto_tree *fixed_tree;
1964 proto_tree *tagged_tree;
1966 int tagged_parameter_tree_len;
1970 CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
1972 ti = proto_tree_add_item (tree, proto_wlan_mgt, tvb, 0, -1, FALSE);
1973 mgt_tree = proto_item_add_subtree (ti, ett_80211_mgt);
1975 switch (COMPOSE_FRAME_TYPE(fcf))
1979 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
1980 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1981 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
1982 offset = 4; /* 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);
1993 case MGT_ASSOC_RESP:
1994 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1995 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1996 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
1997 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
1998 offset = 6; /* Size of fixed fields */
2000 tagged_parameter_tree_len =
2001 tvb_reported_length_remaining(tvb, offset);
2002 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2003 tagged_parameter_tree_len);
2004 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2005 tagged_parameter_tree_len);
2009 case MGT_REASSOC_REQ:
2010 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
2011 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
2012 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
2013 add_fixed_field (fixed_tree, tvb, 4, FIELD_CURRENT_AP_ADDR);
2014 offset = 10; /* Size of fixed fields */
2016 tagged_parameter_tree_len =
2017 tvb_reported_length_remaining(tvb, offset);
2018 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2019 tagged_parameter_tree_len);
2020 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2021 tagged_parameter_tree_len);
2024 case MGT_REASSOC_RESP:
2025 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
2026 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
2027 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
2028 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
2029 offset = 6; /* Size of fixed fields */
2031 tagged_parameter_tree_len =
2032 tvb_reported_length_remaining(tvb, offset);
2033 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2034 tagged_parameter_tree_len);
2035 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2036 tagged_parameter_tree_len);
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);
2051 case MGT_PROBE_RESP:
2052 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
2053 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
2054 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
2055 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
2056 offset = 12; /* Size of fixed fields */
2058 tagged_parameter_tree_len =
2059 tvb_reported_length_remaining(tvb, offset);
2060 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2061 tagged_parameter_tree_len);
2062 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2063 tagged_parameter_tree_len);
2067 case MGT_BEACON: /* Dissect protocol payload fields */
2068 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
2069 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
2070 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
2071 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
2072 offset = 12; /* Size of fixed fields */
2074 tagged_parameter_tree_len =
2075 tvb_reported_length_remaining(tvb, offset);
2076 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2077 tagged_parameter_tree_len);
2078 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2079 tagged_parameter_tree_len);
2088 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2089 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
2093 case MGT_AUTHENTICATION:
2094 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
2095 add_fixed_field (fixed_tree, tvb, 0, FIELD_AUTH_ALG);
2096 add_fixed_field (fixed_tree, tvb, 2, FIELD_AUTH_TRANS_SEQ);
2097 add_fixed_field (fixed_tree, tvb, 4, FIELD_STATUS_CODE);
2098 offset = 6; /* Size of fixed fields */
2100 tagged_parameter_tree_len =
2101 tvb_reported_length_remaining(tvb, offset);
2102 if (tagged_parameter_tree_len != 0)
2104 tagged_tree = get_tagged_parameter_tree (mgt_tree,
2107 tagged_parameter_tree_len);
2108 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2109 tagged_parameter_tree_len);
2114 case MGT_DEAUTHENTICATION:
2115 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2116 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
2121 switch (tvb_get_guint8(tvb, 0))
2124 case CAT_SPECTRUM_MGMT:
2125 switch (tvb_get_guint8(tvb, 1))
2127 case SM_ACTION_MEASUREMENT_REQUEST:
2128 case SM_ACTION_MEASUREMENT_REPORT:
2129 case SM_ACTION_TPC_REQUEST:
2130 case SM_ACTION_TPC_REPORT:
2131 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
2132 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2133 add_fixed_field (fixed_tree, tvb, 1, FIELD_ACTION_CODE);
2134 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2135 offset = 3; /* Size of fixed fields */
2138 case SM_ACTION_CHAN_SWITCH_ANNC:
2139 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2140 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2141 offset = 2; /* Size of fixed fields */
2145 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2146 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2147 offset = 2; /* Size of fixed fields */
2152 case CAT_MGMT_NOTIFICATION: /* Management notification frame */
2153 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
2154 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2155 add_fixed_field (fixed_tree, tvb, 1, FIELD_WME_ACTION_CODE);
2156 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2157 add_fixed_field (fixed_tree, tvb, 3, FIELD_WME_STATUS_CODE);
2158 offset = 4; /* Size of fixed fields */
2162 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 1);
2163 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2164 offset = 1; /* Size of fixed fields */
2168 tagged_parameter_tree_len =
2169 tvb_reported_length_remaining(tvb, offset);
2170 if (tagged_parameter_tree_len != 0)
2172 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2173 tagged_parameter_tree_len);
2174 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2175 tagged_parameter_tree_len);
2182 set_src_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
2184 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
2185 col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "%s (%s)",
2186 get_ether_name(addr), type);
2187 if (check_col(pinfo->cinfo, COL_UNRES_DL_SRC))
2188 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s",
2189 ether_to_str(addr));
2193 set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
2195 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
2196 col_add_fstr(pinfo->cinfo, COL_RES_DL_DST, "%s (%s)",
2197 get_ether_name(addr), type);
2198 if (check_col(pinfo->cinfo, COL_UNRES_DL_DST))
2199 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s",
2200 ether_to_str(addr));
2204 crc32_802_tvb_padded(tvbuff_t *tvb, guint hdr_len, guint hdr_size, guint len)
2208 c_crc = crc32_ccitt_tvb(tvb, hdr_len);
2209 c_crc = crc32_ccitt_seed(tvb_get_ptr(tvb, hdr_size, len), len, ~c_crc);
2212 c_crc = ((unsigned char)(c_crc>>0)<<24) |
2213 ((unsigned char)(c_crc>>8)<<16) |
2214 ((unsigned char)(c_crc>>16)<<8) |
2215 ((unsigned char)(c_crc>>24)<<0);
2226 /* ************************************************************************* */
2227 /* Dissect 802.11 frame */
2228 /* ************************************************************************* */
2230 dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
2231 proto_tree * tree, gboolean fixed_length_header,
2232 gboolean has_radio_information, gint fcs_len,
2233 gboolean wlan_broken_fc, gboolean datapad)
2235 guint16 fcf, flags, frame_type_subtype;
2236 guint16 seq_control;
2237 guint32 seq_number, frag_number;
2238 gboolean more_frags;
2239 const guint8 *src = NULL;
2240 const guint8 *dst = NULL;
2241 const guint8 *bssid = NULL;
2242 proto_item *ti = NULL;
2243 proto_item *flag_item;
2244 proto_item *fc_item;
2245 proto_tree *hdr_tree = NULL;
2246 proto_tree *flag_tree;
2247 proto_tree *fc_tree;
2248 guint16 hdr_len, ohdr_len;
2250 gint len, reported_len, ivlen;
2251 gboolean save_fragmented;
2252 tvbuff_t *volatile next_tvb = NULL;
2254 volatile encap_t encap_type;
2255 guint8 octet1, octet2;
2256 char out_buff[SHORT_STR];
2259 wlan_hdr *volatile whdr;
2260 static wlan_hdr whdrs[4];
2264 if (check_col (pinfo->cinfo, COL_PROTOCOL))
2265 col_set_str (pinfo->cinfo, COL_PROTOCOL, "IEEE 802.11");
2266 if (check_col (pinfo->cinfo, COL_INFO))
2267 col_clear (pinfo->cinfo, COL_INFO);
2269 /* Add the radio information, if present, to the column information */
2270 if (has_radio_information) {
2271 if (check_col(pinfo->cinfo, COL_TX_RATE)) {
2272 col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u",
2273 pinfo->pseudo_header->ieee_802_11.data_rate / 2,
2274 pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
2276 if (check_col(pinfo->cinfo, COL_RSSI)) {
2277 /* XX - this is a percentage, not a dBm or normalized or raw RSSI */
2278 col_add_fstr(pinfo->cinfo, COL_RSSI, "%u",
2279 pinfo->pseudo_header->ieee_802_11.signal_level);
2283 fcf = tvb_get_letohs (tvb, 0);
2284 if (wlan_broken_fc) {
2286 fcf = ((fcf & 0xff) << 8) | (((fcf & 0xff00) >> 8) & 0xff);
2288 if (fixed_length_header)
2289 hdr_len = DATA_LONG_HDR_LEN;
2291 hdr_len = find_header_length (fcf);
2294 hdr_len = roundup2(hdr_len, 4);
2295 frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
2297 if (check_col (pinfo->cinfo, COL_INFO))
2298 col_set_str (pinfo->cinfo, COL_INFO,
2299 val_to_str(frame_type_subtype, frame_type_subtype_vals,
2300 "Unrecognized (Reserved frame)"));
2302 flags = FCF_FLAGS (fcf);
2303 more_frags = HAVE_FRAGMENTS (flags);
2306 /* Add the radio information, if present, and the FC to the current tree */
2309 ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
2311 hdr_tree = proto_item_add_subtree (ti, ett_80211);
2313 if (has_radio_information) {
2314 proto_tree_add_uint_format(hdr_tree, hf_data_rate,
2316 pinfo->pseudo_header->ieee_802_11.data_rate,
2317 "Data Rate: %u.%u Mb/s",
2318 pinfo->pseudo_header->ieee_802_11.data_rate / 2,
2319 pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
2321 proto_tree_add_uint(hdr_tree, hf_channel,
2323 pinfo->pseudo_header->ieee_802_11.channel);
2325 proto_tree_add_uint_format(hdr_tree, hf_signal_strength,
2327 pinfo->pseudo_header->ieee_802_11.signal_level,
2328 "Signal Strength: %u%%",
2329 pinfo->pseudo_header->ieee_802_11.signal_level);
2332 proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
2334 wlan_broken_fc?1:0, 1,
2335 frame_type_subtype);
2337 fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb,
2340 "Frame Control: 0x%04X (%s)",
2341 fcf, wlan_broken_fc?"Swapped":"Normal");
2343 fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
2346 proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb,
2347 wlan_broken_fc?1:0, 1,
2348 FCF_PROT_VERSION (fcf));
2350 proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb,
2351 wlan_broken_fc?1:0, 1,
2352 FCF_FRAME_TYPE (fcf));
2354 proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
2356 wlan_broken_fc?1:0, 1,
2357 FCF_FRAME_SUBTYPE (fcf));
2360 proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb,
2361 wlan_broken_fc?0:1, 1,
2362 flags, "Flags: 0x%X", flags);
2364 flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
2366 proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb,
2367 wlan_broken_fc?0:1, 1,
2368 FLAGS_DS_STATUS (flags));
2369 proto_tree_add_boolean_hidden (flag_tree, hf_fc_to_ds, tvb, 1, 1,
2371 proto_tree_add_boolean_hidden (flag_tree, hf_fc_from_ds, tvb, 1, 1,
2374 proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb,
2375 wlan_broken_fc?0:1, 1,
2378 proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb,
2379 wlan_broken_fc?0:1, 1, flags);
2381 proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb,
2382 wlan_broken_fc?0:1, 1, flags);
2384 proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb,
2385 wlan_broken_fc?0:1, 1,
2388 proto_tree_add_boolean (flag_tree, hf_fc_protected, tvb,
2389 wlan_broken_fc?0:1, 1, flags);
2391 proto_tree_add_boolean (flag_tree, hf_fc_order, tvb,
2392 wlan_broken_fc?0:1, 1, flags);
2394 if (frame_type_subtype == CTRL_PS_POLL)
2395 proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
2396 ASSOC_ID(tvb_get_letohs(tvb,2)));
2399 proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
2400 tvb_get_letohs (tvb, 2));
2404 * Decode the part of the frame header that isn't the same for all
2411 switch (FCF_FRAME_TYPE (fcf))
2416 * All management frame types have the same header.
2418 src = tvb_get_ptr (tvb, 10, 6);
2419 dst = tvb_get_ptr (tvb, 4, 6);
2421 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
2422 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
2423 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
2424 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
2427 SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, tvb_get_ptr(tvb, 16,6));
2428 SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
2429 SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
2430 whdr->type = frame_type_subtype;
2432 seq_control = tvb_get_letohs(tvb, 22);
2433 frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
2434 seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
2436 if (check_col (pinfo->cinfo, COL_INFO))
2438 col_append_fstr(pinfo->cinfo, COL_INFO,
2439 ",SN=%d", seq_number);
2441 col_append_fstr(pinfo->cinfo, COL_INFO,
2442 ",FN=%d",frag_number);
2447 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2449 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2451 /* add items for wlan.addr filter */
2452 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2453 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2455 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
2456 tvb_get_ptr (tvb, 16, 6));
2458 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2461 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2467 switch (frame_type_subtype)
2471 src = tvb_get_ptr (tvb, 10, 6);
2472 dst = tvb_get_ptr (tvb, 4, 6);
2474 set_src_addr_cols(pinfo, src, "BSSID");
2475 set_dst_addr_cols(pinfo, dst, "BSSID");
2479 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6, dst);
2481 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
2487 src = tvb_get_ptr (tvb, 10, 6);
2488 dst = tvb_get_ptr (tvb, 4, 6);
2490 set_src_addr_cols(pinfo, src, "TA");
2491 set_dst_addr_cols(pinfo, dst, "RA");
2495 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2497 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
2503 dst = tvb_get_ptr (tvb, 4, 6);
2505 set_dst_addr_cols(pinfo, dst, "RA");
2508 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2512 case CTRL_ACKNOWLEDGEMENT:
2513 dst = tvb_get_ptr (tvb, 4, 6);
2515 set_dst_addr_cols(pinfo, dst, "RA");
2518 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2523 src = tvb_get_ptr (tvb, 10, 6);
2524 dst = tvb_get_ptr (tvb, 4, 6);
2526 set_src_addr_cols(pinfo, src, "BSSID");
2527 set_dst_addr_cols(pinfo, dst, "RA");
2531 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2532 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
2537 case CTRL_CFP_ENDACK:
2538 src = tvb_get_ptr (tvb, 10, 6);
2539 dst = tvb_get_ptr (tvb, 4, 6);
2541 set_src_addr_cols(pinfo, src, "BSSID");
2542 set_dst_addr_cols(pinfo, dst, "RA");
2546 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2548 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
2552 case CTRL_BLOCK_ACK_REQ:
2554 src = tvb_get_ptr (tvb, 10, 6);
2555 dst = tvb_get_ptr (tvb, 4, 6);
2557 set_src_addr_cols(pinfo, src, "TA");
2558 set_dst_addr_cols(pinfo, dst, "RA");
2562 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
2564 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
2570 case CTRL_BLOCK_ACK:
2572 src = tvb_get_ptr (tvb, 10, 6);
2573 dst = tvb_get_ptr (tvb, 4, 6);
2575 set_src_addr_cols(pinfo, src, "TA");
2576 set_dst_addr_cols(pinfo, dst, "RA");
2580 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
2582 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
2584 /* TODO BAR Format */
2591 addr_type = FCF_ADDR_SELECTOR (fcf);
2593 /* In order to show src/dst address we must always do the following */
2598 src = tvb_get_ptr (tvb, 10, 6);
2599 dst = tvb_get_ptr (tvb, 4, 6);
2600 bssid = tvb_get_ptr (tvb, 16, 6);
2605 src = tvb_get_ptr (tvb, 16, 6);
2606 dst = tvb_get_ptr (tvb, 4, 6);
2607 bssid = tvb_get_ptr (tvb, 10, 6);
2612 src = tvb_get_ptr (tvb, 10, 6);
2613 dst = tvb_get_ptr (tvb, 16, 6);
2614 bssid = tvb_get_ptr (tvb, 4, 6);
2619 src = tvb_get_ptr (tvb, 24, 6);
2620 dst = tvb_get_ptr (tvb, 16, 6);
2621 bssid = tvb_get_ptr (tvb, 16, 6);
2625 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
2626 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
2627 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
2628 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
2632 SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, bssid);
2633 SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
2634 SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
2635 whdr->type = frame_type_subtype;
2637 seq_control = tvb_get_letohs(tvb, 22);
2638 frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
2639 seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
2641 if (check_col (pinfo->cinfo, COL_INFO))
2643 col_append_fstr(pinfo->cinfo, COL_INFO,
2644 ",SN=%d", seq_number);
2646 col_append_fstr(pinfo->cinfo, COL_INFO,
2647 ",FN=%d",frag_number);
2650 /* Now if we have a tree we start adding stuff */
2659 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2660 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2661 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
2662 tvb_get_ptr (tvb, 16, 6));
2663 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2665 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2668 /* add items for wlan.addr filter */
2669 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2670 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2675 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2676 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
2677 tvb_get_ptr (tvb, 10, 6));
2678 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6, src);
2679 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2681 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2684 /* add items for wlan.addr filter */
2685 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2686 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, src);
2691 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
2692 tvb_get_ptr (tvb, 4, 6));
2693 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2694 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
2696 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2698 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2701 /* add items for wlan.addr filter */
2702 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2703 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
2708 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
2709 tvb_get_ptr (tvb, 4, 6));
2710 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
2711 tvb_get_ptr (tvb, 10, 6));
2712 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
2713 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2715 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2717 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6, src);
2719 /* add items for wlan.addr filter */
2720 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
2721 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 24, 6, src);
2729 len = tvb_length_remaining(tvb, hdr_len);
2730 reported_len = tvb_reported_length_remaining(tvb, hdr_len);
2734 case 0: /* Definitely has no FCS */
2738 case 4: /* Definitely has an FCS */
2742 default: /* Don't know - use "wlan_check_fcs" */
2743 has_fcs = wlan_check_fcs;
2749 * Well, this packet should, in theory, have an FCS.
2750 * Do we have the entire packet, and does it have enough data for
2753 if (reported_len < 4)
2756 * The packet is claimed not to even have enough data for a 4-byte
2758 * Pretend it doesn't have an FCS.
2762 else if (len < reported_len)
2765 * The packet is claimed to have enough data for a 4-byte FCS, but
2766 * we didn't capture all of the packet.
2767 * Slice off the 4-byte FCS from the reported length, and trim the
2768 * captured length so it's no more than the reported length; that
2769 * will slice off what of the FCS, if any, is in the captured
2773 if (len > reported_len)
2779 * We have the entire packet, and it includes a 4-byte FCS.
2780 * Slice it off, and put it into the tree.
2786 guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len);
2790 fcs = crc32_802_tvb_padded(tvb, ohdr_len, hdr_len, len);
2792 fcs = crc32_802_tvb(tvb, hdr_len + len);
2793 if (fcs == sent_fcs)
2794 proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
2795 hdr_len + len, 4, sent_fcs,
2796 "Frame check sequence: 0x%08x [correct]", sent_fcs);
2798 proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
2799 hdr_len + len, 4, sent_fcs,
2800 "Frame check sequence: 0x%08x [incorrect, should be 0x%08x]",
2809 * Only management and data frames have a body, so we don't have
2810 * anything more to do for other types of frames.
2812 switch (FCF_FRAME_TYPE (fcf))
2819 if (tree && DATA_FRAME_IS_QOS(frame_type_subtype))
2822 proto_item *qos_fields;
2823 proto_tree *qos_tree;
2826 guint16 qos_control;
2827 guint16 qos_priority;
2828 guint16 qos_ack_policy;
2830 guint16 qos_field_content;
2833 * We calculate the offset to the QoS header data as
2834 * an offset relative to the end of the header. But
2835 * when the header has been padded to align the data
2836 * this must be done relative to true header size, not
2837 * the padded/aligned value. To simplify this work we
2838 * stash the original header size in ohdr_len instead
2839 * of recalculating it.
2841 qosoff = ohdr_len - 2;
2842 qos_fields = proto_tree_add_text(hdr_tree, tvb, qosoff, 2,
2844 qos_tree = proto_item_add_subtree (qos_fields, ett_qos_parameters);
2846 qos_control = tvb_get_letohs(tvb, qosoff + 0);
2847 qos_priority = QOS_PRIORITY(qos_control);
2848 qos_ack_policy = QOS_ACK_POLICY(qos_control);
2849 qos_eosp = QOS_EOSP(qos_control);
2850 qos_field_content = QOS_FIELD_CONTENT( qos_control);
2852 proto_tree_add_uint_format (qos_tree, hf_qos_priority, tvb,
2853 qosoff, 2, qos_priority,
2854 "Priority: %d (%s) (%s)",
2855 qos_priority, qos_tags[qos_priority], qos_acs[qos_priority]);
2857 if (flags & FLAG_FROM_DS) {
2858 proto_tree_add_boolean (qos_tree, hf_qos_eosp, tvb,
2859 qosoff, 1, qos_eosp);
2861 if (DATA_FRAME_IS_CF_POLL(frame_type_subtype)) {
2863 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2864 qosoff + 1, 1, qos_field_content, "TXOP Limit: %d ", qos_field_content);
2867 /* qap ps buffer state */
2868 proto_item *qos_ps_buf_state_fields;
2869 proto_tree *qos_ps_buf_state_tree;
2874 buf_state = QOS_PS_BUF_STATE(qos_field_content);
2875 buf_ac = QOS_PS_BUF_AC(qos_field_content); /*access category */
2876 buf_load = QOS_PS_BUF_LOAD(qos_field_content);
2878 qos_ps_buf_state_fields = proto_tree_add_text(qos_tree, tvb, qosoff + 1, 1,
2879 "QAP PS Buffer State: 0x%x", qos_field_content);
2880 qos_ps_buf_state_tree = proto_item_add_subtree (qos_ps_buf_state_fields, ett_qos_ps_buf_state);
2882 /* FIXME: hf_ values not defined
2883 proto_tree_add_boolean (qos_ps_buf_state_tree, hf_qos_buf_state, tvb,
2886 proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_ac, tvb,
2887 qosoff + 1, 1, buf_ac, "Priority: %d (%s)",
2888 buf_ac, wme_acs[buf_ac]);
2890 proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_load, tvb,
2891 qosoff + 1, 1, buf_load, "Buffered load: %d ", (buf_load * 4096));
2895 } else if (qos_eosp) {
2896 /* txop limit requested */
2897 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2898 qosoff + 1, 1, qos_field_content, "Queue Size: %d ", (qos_field_content * 254));
2901 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2902 qosoff + 1, 1, qos_field_content, "TXOP Limit Requested: %d ", qos_field_content);
2905 proto_tree_add_uint (qos_tree, hf_qos_ack_policy, tvb, qosoff, 1,
2908 } /* end of qos control field */
2911 * No-data frames don't have a body.
2913 if (DATA_FRAME_IS_NULL(frame_type_subtype))
2925 if (IS_PROTECTED(FCF_FLAGS(fcf))) {
2927 * It's a WEP-encrypted frame; dissect the WEP parameters and decrypt
2928 * the data, if we have a matching key. Otherwise display it as data.
2930 gboolean can_decrypt = FALSE;
2931 proto_tree *wep_tree = NULL;
2933 guint8 key, keybyte;
2935 keybyte = tvb_get_guint8(tvb, hdr_len + 3);
2936 key = KEY_OCTET_WEP_KEY(keybyte);
2937 if ((keybyte & KEY_EXTIV) && (len >= EXTIV_LEN)) {
2938 /* Extended IV; this frame is likely encrypted with TKIP or CCMP */
2940 proto_item *extiv_fields;
2942 extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
2943 "TKIP/CCMP parameters");
2944 wep_tree = proto_item_add_subtree (extiv_fields, ett_wep_parameters);
2945 /* It is unknown whether this is a TKIP or CCMP encrypted packet, so
2946 * display both packet number alternatives unless the ExtIV can be
2947 * determined to be possible only with one of the encryption protocols.
2949 if (tvb_get_guint8(tvb, hdr_len + 1) & 0x20) {
2950 g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
2951 tvb_get_letohl(tvb, hdr_len + 4),
2952 tvb_get_guint8(tvb, hdr_len),
2953 tvb_get_guint8(tvb, hdr_len + 2));
2954 proto_tree_add_string(wep_tree, hf_tkip_extiv, tvb, hdr_len,
2955 EXTIV_LEN, out_buff);
2957 if (tvb_get_guint8(tvb, hdr_len + 2) == 0) {
2958 g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
2959 tvb_get_letohl(tvb, hdr_len + 4),
2960 tvb_get_guint8(tvb, hdr_len + 1),
2961 tvb_get_guint8(tvb, hdr_len));
2962 proto_tree_add_string(wep_tree, hf_ccmp_extiv, tvb, hdr_len,
2963 EXTIV_LEN, out_buff);
2965 proto_tree_add_uint(wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
2968 /* Subtract out the length of the IV. */
2970 reported_len -= EXTIV_LEN;
2972 /* It is unknown whether this is TKIP or CCMP, so let's not even try to
2973 * parse TKIP Michael MIC+ICV or CCMP MIC. */
2975 /* No Ext. IV - WEP packet */
2977 * XXX - pass the IV and key to "try_decrypt_wep()", and have it pass
2978 * them to "wep_decrypt()", rather than having "wep_decrypt()" extract
2981 * Also, just pass the data *following* the WEP parameters as the
2982 * buffer to decrypt.
2984 iv = tvb_get_ntoh24(tvb, hdr_len);
2986 proto_item *wep_fields;
2988 wep_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 4,
2991 wep_tree = proto_item_add_subtree (wep_fields, ett_wep_parameters);
2992 proto_tree_add_uint (wep_tree, hf_wep_iv, tvb, hdr_len, 3, iv);
2993 tvb_memcpy(tvb, iv_buff, hdr_len, 3);
2994 is_iv_bad = weak_iv(iv_buff);
2995 if (is_iv_bad != -1) {
2996 proto_tree_add_boolean_format (wep_tree, hf_wep_iv_weak,
2998 "Weak IV for key byte %d",
3003 proto_tree_add_uint (wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
3005 /* Subtract out the length of the IV. */
3011 * Well, this packet should, in theory, have an ICV.
3012 * Do we have the entire packet, and does it have enough data for
3015 if (reported_len < 4) {
3017 * The packet is claimed not to even have enough data for a
3019 * Pretend it doesn't have an ICV.
3022 } else if (len < reported_len) {
3024 * The packet is claimed to have enough data for a 4-byte ICV,
3025 * but we didn't capture all of the packet.
3026 * Slice off the 4-byte ICV from the reported length, and trim
3027 * the captured length so it's no more than the reported length;
3028 * that will slice off what of the ICV, if any, is in the
3033 if (len > reported_len)
3037 * We have the entire packet, and it includes a 4-byte ICV.
3038 * Slice it off, and put it into the tree.
3040 * We only support decrypting if we have the the ICV.
3042 * XXX - the ICV is encrypted; we're putting the encrypted
3043 * value, not the decrypted value, into the tree.
3051 if (!can_decrypt || (next_tvb = try_decrypt_wep(tvb, hdr_len, reported_len + 8)) == NULL) {
3053 * WEP decode impossible or failed, treat payload as raw data
3054 * and don't attempt fragment reassembly or further dissection.
3056 next_tvb = tvb_new_subset(tvb, hdr_len + ivlen, len, reported_len);
3058 if (tree && can_decrypt)
3059 proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
3060 hdr_len + ivlen + len, 4,
3061 tvb_get_ntohl(tvb, hdr_len + ivlen + len),
3062 "WEP ICV: 0x%08x (not verified)",
3063 tvb_get_ntohl(tvb, hdr_len + ivlen + len));
3065 if (pinfo->ethertype != ETHERTYPE_CENTRINO_PROMISC)
3067 /* Some wireless drivers (such as Centrino) WEP payload already decrypted */
3068 call_dissector(data_handle, next_tvb, pinfo, tree);
3074 proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
3075 hdr_len + ivlen + len, 4,
3076 tvb_get_ntohl(tvb, hdr_len + ivlen + len),
3077 "WEP ICV: 0x%08x (correct)",
3078 tvb_get_ntohl(tvb, hdr_len + ivlen + len));
3080 add_new_data_source(pinfo, next_tvb, "Decrypted WEP data");
3084 * WEP decryption successful!
3086 * Use the tvbuff we got back from the decryption; the data starts at
3087 * the beginning. The lengths are already correct for the decoded WEP
3094 * Not a WEP-encrypted frame; just use the data from the tvbuff
3097 * The payload starts at "hdr_len" (i.e., just past the 802.11
3098 * MAC header), the length of data in the tvbuff following the
3099 * 802.11 header is "len", and the length of data in the packet
3100 * following the 802.11 header is "reported_len".
3106 * Do defragmentation if "wlan_defragment" is true, and we have more
3107 * fragments or this isn't the first fragment.
3109 * We have to do some special handling to catch frames that
3110 * have the "More Fragments" indicator not set but that
3111 * don't show up as reassembled and don't have any other
3112 * fragments present. Some networking interfaces appear
3113 * to do reassembly even when you're capturing raw packets
3114 * *and* show the reassembled packet without the "More
3115 * Fragments" indicator set *but* with a non-zero fragment
3118 * "fragment_add_seq_802_11()" handles that; we want to call it
3119 * even if we have a short frame, so that it does those checks - if
3120 * the frame is short, it doesn't do reassembly on it.
3122 * (This could get some false positives if we really *did* only
3123 * capture the last fragment of a fragmented packet, but that's
3126 save_fragmented = pinfo->fragmented;
3127 if (wlan_defragment && (more_frags || frag_number != 0)) {
3128 fragment_data *fd_head;
3131 * If we've already seen this frame, look it up in the
3132 * table of reassembled packets, otherwise add it to
3133 * whatever reassembly is in progress, if any, and see
3136 fd_head = fragment_add_seq_802_11(next_tvb, hdr_len, pinfo, seq_number,
3137 wlan_fragment_table,
3138 wlan_reassembled_table,
3142 next_tvb = process_reassembled_data(tvb, hdr_len, pinfo,
3143 "Reassembled 802.11", fd_head,
3144 &frag_items, NULL, hdr_tree);
3147 * If this is the first fragment, dissect its contents, otherwise
3148 * just show it as a fragment.
3150 if (frag_number != 0) {
3151 /* Not the first fragment - don't dissect it. */
3154 /* First fragment, or not fragmented. Dissect what we have here. */
3156 /* Get a tvbuff for the payload. */
3157 next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len);
3160 * If this is the first fragment, but not the only fragment,
3161 * tell the next protocol that.
3164 pinfo->fragmented = TRUE;
3166 pinfo->fragmented = FALSE;
3170 if (next_tvb == NULL) {
3171 /* Just show this as an incomplete fragment. */
3172 if (check_col(pinfo->cinfo, COL_INFO))
3173 col_set_str(pinfo->cinfo, COL_INFO, "Fragmented IEEE 802.11 frame");
3174 next_tvb = tvb_new_subset (tvb, hdr_len, len, reported_len);
3175 call_dissector(data_handle, next_tvb, pinfo, tree);
3176 pinfo->fragmented = save_fragmented;
3180 switch (FCF_FRAME_TYPE (fcf))
3184 dissect_ieee80211_mgt (fcf, next_tvb, pinfo, tree);
3189 /* I guess some bridges take Netware Ethernet_802_3 frames,
3190 which are 802.3 frames (with a length field rather than
3191 a type field, but with no 802.2 header in the payload),
3192 and just stick the payload into an 802.11 frame. I've seen
3193 captures that show frames of that sort.
3195 We also handle some odd form of encapsulation in which a
3196 complete Ethernet frame is encapsulated within an 802.11
3197 data frame, with no 802.2 header. This has been seen
3200 So, if the packet doesn't start with 0xaa 0xaa:
3202 we first use the same scheme that linux-wlan-ng does to detect
3203 those encapsulated Ethernet frames, namely looking to see whether
3204 the frame either starts with 6 octets that match the destination
3205 address from the 802.11 header or has 6 octets that match the
3206 source address from the 802.11 header following the first 6 octets,
3207 and, if so, treat it as an encapsulated Ethernet frame;
3209 otherwise, we use the same scheme that we use in the Ethernet
3210 dissector to recognize Netware 802.3 frames, namely checking
3211 whether the packet starts with 0xff 0xff and, if so, treat it
3212 as an encapsulated IPX frame. */
3213 encap_type = ENCAP_802_2;
3215 octet1 = tvb_get_guint8(next_tvb, 0);
3216 octet2 = tvb_get_guint8(next_tvb, 1);
3217 if (octet1 != 0xaa || octet2 != 0xaa) {
3218 src = tvb_get_ptr (next_tvb, 6, 6);
3219 dst = tvb_get_ptr (next_tvb, 0, 6);
3220 if (memcmp(src, pinfo->dl_src.data, 6) == 0 ||
3221 memcmp(dst, pinfo->dl_dst.data, 6) == 0)
3222 encap_type = ENCAP_ETHERNET;
3223 else if (octet1 == 0xff && octet2 == 0xff)
3224 encap_type = ENCAP_IPX;
3227 CATCH2(BoundsError, ReportedBoundsError) {
3233 switch (encap_type) {
3236 call_dissector(llc_handle, next_tvb, pinfo, tree);
3239 case ENCAP_ETHERNET:
3240 call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree);
3244 call_dissector(ipx_handle, next_tvb, pinfo, tree);
3249 pinfo->fragmented = save_fragmented;
3252 tap_queue_packet(wlan_tap, pinfo, whdr);
3256 * Dissect 802.11 with a variable-length link-layer header.
3259 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3261 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
3262 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
3266 * Dissect 802.11 with a variable-length link-layer header and data padding.
3269 dissect_ieee80211_datapad (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3271 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
3272 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, TRUE);
3276 * Dissect 802.11 with a variable-length link-layer header and a pseudo-
3277 * header containing radio information.
3280 dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3282 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE,
3283 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
3287 * Dissect 802.11 with a variable-length link-layer header and a byte-swapped
3288 * control field (some hardware sends out LWAPP-encapsulated 802.11
3289 * packets with the control field byte swapped).
3292 dissect_ieee80211_bsfc (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3294 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE, FALSE);
3298 * Dissect 802.11 with a fixed-length link-layer header (padded to the
3302 dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3304 dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE, FALSE);
3308 wlan_defragment_init(void)
3310 fragment_table_init(&wlan_fragment_table);
3311 reassembled_table_init(&wlan_reassembled_table);
3315 proto_register_ieee80211 (void)
3318 GString *key_name, *key_title, *key_desc;
3320 static const value_string frame_type[] = {
3321 {MGT_FRAME, "Management frame"},
3322 {CONTROL_FRAME, "Control frame"},
3323 {DATA_FRAME, "Data frame"},
3327 static const value_string tofrom_ds[] = {
3328 {0, "Not leaving DS or network is operating "
3329 "in AD-HOC mode (To DS: 0 From DS: 0)"},
3330 {FLAG_TO_DS, "Frame from STA to DS via an AP (To DS: 1 "
3332 {FLAG_FROM_DS, "Frame from DS to a STA via AP(To DS: 0 "
3334 {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS from one AP to another "
3335 "AP (To DS: 1 From DS: 1)"},
3339 static const true_false_string tods_flag = {
3340 "Frame is entering DS",
3341 "Frame is not entering DS"
3344 static const true_false_string fromds_flag = {
3345 "Frame is exiting DS",
3346 "Frame is not exiting DS"
3349 static const true_false_string more_frags = {
3350 "More fragments follow",
3351 "This is the last fragment"
3354 static const true_false_string retry_flags = {
3355 "Frame is being retransmitted",
3356 "Frame is not being retransmitted"
3359 static const true_false_string pm_flags = {
3360 "STA will go to sleep",
3364 static const true_false_string md_flags = {
3365 "Data is buffered for STA at AP",
3369 static const true_false_string protected_flags = {
3370 "Data is protected",
3371 "Data is not protected"
3374 static const true_false_string order_flags = {
3376 "Not strictly ordered"
3379 static const true_false_string cf_ess_flags = {
3380 "Transmitter is an AP",
3381 "Transmitter is a STA"
3385 static const true_false_string cf_privacy_flags = {
3386 "AP/STA can support WEP",
3387 "AP/STA cannot support WEP"
3390 static const true_false_string cf_preamble_flags = {
3391 "Short preamble allowed",
3392 "Short preamble not allowed"
3395 static const true_false_string cf_pbcc_flags = {
3396 "PBCC modulation allowed",
3397 "PBCC modulation not allowed"
3400 static const true_false_string cf_agility_flags = {
3401 "Channel agility in use",
3402 "Channel agility not in use"
3405 static const true_false_string short_slot_time_flags = {
3406 "Short slot time in use",
3407 "Short slot time not in use"
3410 static const true_false_string dsss_ofdm_flags = {
3411 "DSSS-OFDM modulation allowed",
3412 "DSSS-OFDM modulation not allowed"
3415 static const true_false_string cf_spec_man_flags = {
3416 "dot11SpectrumManagementRequired TRUE",
3417 "dot11SpectrumManagementRequired FALSE",
3420 static const true_false_string cf_apsd_flags = {
3422 "apsd not implemented",
3425 static const true_false_string cf_del_blk_ack_flags = {
3426 "delayed block ack implemented",
3427 "delayed block ack not implented",
3430 static const true_false_string cf_imm_blk_ack_flags = {
3431 "immediate block ack implemented",
3432 "immediate block ack not implented",
3434 static const true_false_string cf_ibss_flags = {
3435 "Transmitter belongs to an IBSS",
3436 "Transmitter belongs to a BSS"
3439 static const true_false_string eosp_flag = {
3440 "End of service period",
3444 static const value_string sta_cf_pollable[] = {
3445 {0x00, "Station is not CF-Pollable"},
3446 {0x02, "Station is CF-Pollable, "
3447 "not requesting to be placed on the CF-polling list"},
3448 {0x01, "Station is CF-Pollable, "
3449 "requesting to be placed on the CF-polling list"},
3450 {0x03, "Station is CF-Pollable, requesting never to be polled"},
3451 {0x0200, "QSTA requesting association in QBSS"},
3455 static const value_string ap_cf_pollable[] = {
3456 {0x00, "No point coordinator at AP"},
3457 {0x02, "Point coordinator at AP for delivery only (no polling)"},
3458 {0x01, "Point coordinator at AP for delivery and polling"},
3460 {0x0200, "QAP (HC) does not use CFP for delivery of unicast data type frames"},
3461 {0x0202, "QAP (HC) uses CFP for delivery, but does not send CF-Polls to non-QoS STAs"},
3462 {0x0201, "QAP (HC) uses CFP for delivery, and sends CF-Polls to non-QoS STAs"},
3463 {0x0203, "Reserved"},
3468 static const value_string auth_alg[] = {
3469 {0x00, "Open System"},
3470 {0x01, "Shared key"},
3471 {0x80, "Network EAP"}, /* Cisco proprietary? */
3475 static const value_string reason_codes[] = {
3477 {0x01, "Unspecified reason"},
3478 {0x02, "Previous authentication no longer valid"},
3479 {0x03, "Deauthenticated because sending STA is leaving (has left) "
3481 {0x04, "Disassociated due to inactivity"},
3482 {0x05, "Disassociated because AP is unable to handle all currently "
3483 "associated stations"},
3484 {0x06, "Class 2 frame received from nonauthenticated station"},
3485 {0x07, "Class 3 frame received from nonassociated station"},
3486 {0x08, "Disassociated because sending STA is leaving (has left) BSS"},
3487 {0x09, "Station requesting (re)association is not authenticated with "
3488 "responding station"},
3489 {0x0A, "Disassociated because the information in the Power Capability "
3490 "element is unacceptable"},
3491 {0x0B, "Disassociated because the information in the Supported"
3492 "Channels element is unacceptable"},
3493 {0x0D, "Invalid Information Element"},
3494 {0x0E, "Michael MIC failure"},
3495 {0x0F, "4-Way Handshake timeout"},
3496 {0x10, "Group key update timeout"},
3497 {0x11, "Information element in 4-Way Handshake different from "
3498 "(Re)Association Request/Probe Response/Beacon"},
3499 {0x12, "Group Cipher is not valid"},
3500 {0x13, "Pairwise Cipher is not valid"},
3501 {0x14, "AKMP is not valid"},
3502 {0x15, "Unsupported RSN IE version"},
3503 {0x16, "Invalid RSN IE Capabilities"},
3504 {0x17, "IEEE 802.1X Authentication failed"},
3505 {0x18, "Cipher suite is rejected per security policy"},
3506 {0x20, "Disassociated for unspecified, QoS-related reason"},
3507 {0x21, "Disassociated because QAP lacks sufficient bandwidth for this QSTA"},
3508 {0x22, "Disassociated because of excessive number of frames that need to be "
3509 "acknowledged, but are not acknowledged for AP transmissions and/or poor "
3510 "channel conditions"},
3511 {0x23, "Disassociated because QSTA is transmitting outside the limits of its TXOPs"},
3512 {0x24, "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)"},
3513 {0x25, "Requested from peer QSTA as it does not want to use the mechanism"},
3514 {0x26, "Requested from peer QSTA as the QSTA received frames using the mechanism "
3515 "for which a set up is required"},
3516 {0x27, "Requested from peer QSTA due to time out"},
3517 {0x2D, "Peer QSTA does not support the requested cipher suite"},
3522 static const value_string status_codes[] = {
3523 {0x00, "Successful"},
3524 {0x01, "Unspecified failure"},
3525 {0x0A, "Cannot support all requested capabilities in the "
3526 "Capability information field"},
3527 {0x0B, "Reassociation denied due to inability to confirm that "
3528 "association exists"},
3529 {0x0C, "Association denied due to reason outside the scope of this "
3532 {0x0D, "Responding station does not support the specified authentication "
3534 {0x0E, "Received an Authentication frame with authentication sequence "
3535 "transaction sequence number out of expected sequence"},
3536 {0x0F, "Authentication rejected because of challenge failure"},
3537 {0x10, "Authentication rejected due to timeout waiting for next "
3538 "frame in sequence"},
3539 {0x11, "Association denied because AP is unable to handle additional "
3540 "associated stations"},
3541 {0x12, "Association denied due to requesting station not supporting all "
3542 "of the datarates in the BSSBasicServiceSet Parameter"},
3543 {0x13, "Association denied due to requesting station not supporting "
3544 "short preamble operation"},
3545 {0x14, "Association denied due to requesting station not supporting "
3547 {0x15, "Association denied due to requesting station not supporting "
3549 {0x16, "Association request rejected because Spectrum Management"
3550 "capability is required"},
3551 {0x17, "Association request rejected because the information in the"
3552 "Power Capability element is unacceptable"},
3553 {0x18, "Association request rejected because the information in the"
3554 "Supported Channels element is unacceptable"},
3555 {0x19, "Association denied due to requesting station not supporting "
3556 "short slot operation"},
3557 {0x1A, "Association denied due to requesting station not supporting "
3558 "DSSS-OFDM operation"},
3559 {0x20, "Unspecified, QoS-related failure"},
3560 {0x21, "Association denied due to QAP having insufficient bandwidth "
3561 "to handle another QSTA"},
3562 {0x22, "Association denied due to excessive frame loss rates and/or "
3563 "poor conditions on current operating channel"},
3564 {0x23, "Association (with QBSS) denied due to requesting station not "
3565 "supporting the QoS facility"},
3566 {0x24, "Association denied due to requesting station not supporting "
3568 {0x25, "The request has been declined."},
3569 {0x26, "The request has not been successful as one or more parameters "
3570 "have invalid values."},
3571 {0x27, "The TS has not been created because the request cannot be honored. "
3572 "However, a suggested TSPEC is provided so that the initiating QSTA may "
3573 "attempt to set another TS with the suggested changes to the TSPEC."},
3574 {0x28, "Invalid Information Element"},
3575 {0x29, "Group Cipher is not valid"},
3576 {0x2A, "Pairwise Cipher is not valid"},
3577 {0x2B, "AKMP is not valid"},
3578 {0x2C, "Unsupported RSN IE version"},
3579 {0x2D, "Invalid RSN IE Capabilities"},
3580 {0x2E, "Cipher suite is rejected per security policy"},
3581 {0x2F, "The TS has not been created. However, the HC may be capable of "
3582 "creating a TS, in response to a request, after the time indicated in the TS Delay element."},
3583 {0x30, "Direct Link is not allowed in the BSS by policy"},
3584 {0x31, "Destination STA is not present within this QBSS."},
3585 {0x32, "The Destination STA is not a QSTA."},
3589 static const value_string category_codes[] = {
3590 {CAT_SPECTRUM_MGMT, "Spectrum Management"},
3593 {CAT_BLOCK_ACK, "Block Ack"},
3594 {CAT_MGMT_NOTIFICATION, "Management notification frame"},
3598 static const value_string action_codes[] ={
3599 {SM_ACTION_MEASUREMENT_REQUEST, "Measurement Request"},
3600 {SM_ACTION_MEASUREMENT_REPORT, "Measurement Report"},
3601 {SM_ACTION_TPC_REQUEST, "TPC Request"},
3602 {SM_ACTION_TPC_REPORT, "TPC Report"},
3603 {SM_ACTION_CHAN_SWITCH_ANNC, "Channel Switch Announcement"},
3607 static const value_string wme_action_codes[] = {
3608 {0x00, "Setup request"},
3609 {0x01, "Setup response"},
3614 static const value_string wme_status_codes[] = {
3615 {0x00, "Admission accepted"},
3616 {0x01, "Invalid parameters"},
3621 static const value_string ack_policy[] = {
3622 {0x00, "Normal Ack"},
3624 {0x01, "No explicit Ack"},
3625 {0x03, "Block Ack"},
3629 static hf_register_info hf[] = {
3631 {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
3632 "Data rate (.5 Mb/s units)", HFILL }},
3635 {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
3636 "Radio channel", HFILL }},
3638 {&hf_signal_strength,
3639 {"Signal Strength", "wlan.signal_strength", FT_UINT8, BASE_DEC, NULL, 0,
3640 "Signal strength (percentage)", HFILL }},
3643 {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
3644 "MAC Frame control", HFILL }},
3646 {&hf_fc_proto_version,
3647 {"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
3648 "MAC Protocol version", HFILL }}, /* 0 */
3651 {"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, VALS(frame_type), 0,
3652 "Frame type", HFILL }},
3654 {&hf_fc_frame_subtype,
3655 {"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
3656 "Frame subtype", HFILL }}, /* 2 */
3658 {&hf_fc_frame_type_subtype,
3659 {"Type/Subtype", "wlan.fc.type_subtype", FT_UINT16, BASE_DEC, VALS(frame_type_subtype_vals), 0,
3660 "Type and subtype combined", HFILL }},
3663 {"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
3664 "Protocol flags", HFILL }},
3667 {"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, VALS (&tofrom_ds), 0,
3668 "Data-frame DS-traversal status", HFILL }}, /* 3 */
3671 {"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), FLAG_TO_DS,
3672 "To DS flag", HFILL }}, /* 4 */
3675 {"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), FLAG_FROM_DS,
3676 "From DS flag", HFILL }}, /* 5 */
3679 {"More Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), FLAG_MORE_FRAGMENTS,
3680 "More Fragments flag", HFILL }}, /* 6 */
3683 {"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), FLAG_RETRY,
3684 "Retransmission flag", HFILL }},
3687 {"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), FLAG_POWER_MGT,
3688 "Power management status", HFILL }},
3691 {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
3692 "More data flag", HFILL }},
3695 {"Protected flag", "wlan.fc.protected", FT_BOOLEAN, 8, TFS (&protected_flags), FLAG_PROTECTED,
3696 "Protected flag", HFILL }},
3699 {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
3700 "Strictly ordered flag", HFILL }},
3703 {"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
3704 "Association-ID field", HFILL }},
3707 {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
3708 "Duration field", HFILL }},
3711 {"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
3712 "Destination Hardware Address", HFILL }},
3715 {"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
3716 "Source Hardware Address", HFILL }},
3719 {"Source or Destination address", "wlan.addr", FT_ETHER, BASE_NONE, NULL, 0,
3720 "Source or Destination Hardware Address", HFILL }},
3723 {"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
3724 "Receiving Station Hardware Address", HFILL }},
3727 {"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
3728 "Transmitting Station Hardware Address", HFILL }},
3731 {"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
3732 "Basic Service Set ID", HFILL }},
3735 {"Fragment number", "wlan.frag", FT_UINT16, BASE_DEC, NULL, 0,
3736 "Fragment number", HFILL }},
3739 {"Sequence number", "wlan.seq", FT_UINT16, BASE_DEC, NULL, 0,
3740 "Sequence number", HFILL }},
3743 {"Priority", "wlan.qos.priority", FT_UINT16, BASE_DEC, NULL, 0,
3744 "802.1D Tag", HFILL }},
3747 {"EOSP", "wlan.qos.eosp", FT_BOOLEAN, 8, TFS (&eosp_flag), QOS_FLAG_EOSP,
3748 "EOSP Field", HFILL }},
3750 {&hf_qos_ack_policy,
3751 {"Ack Policy", "wlan.qos.ack", FT_UINT16, BASE_HEX, VALS (&ack_policy), 0,
3752 "Ack Policy", HFILL }},
3754 {&hf_qos_field_content,
3755 {"Content", "wlan.qos.fc_content", FT_UINT16, BASE_DEC, NULL, 0,
3756 "Content1", HFILL }},
3758 /* {&hf_qos_buffer_state,
3759 {"QAP PS buffer State", "wlan.qos.ps_buf_state", FT_UINT16, BASE_DEC, NULL, 0,
3760 "QAP PS buffer State", HFILL }},
3762 {&hf_qos_txop_dur_req,
3763 {"TXOP Duration Requested", "wlan.qos.txop_dur_req", FT_UINT16, BASE_DEC, NULL, 0,
3764 "TXOP Duration Requested", HFILL }},
3766 {&hf_qos_queue_size,
3767 {"Queue Size", "wlan.qos.queue_size", FT_UINT16, BASE_DEC, NULL, 0,
3768 "Queue Size", HFILL }},*/
3771 {"Frame check sequence", "wlan.fcs", FT_UINT32, BASE_HEX,
3772 NULL, 0, "FCS", HFILL }},
3774 {&hf_fragment_overlap,
3775 {"Fragment overlap", "wlan.fragment.overlap", FT_BOOLEAN, BASE_NONE,
3776 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
3778 {&hf_fragment_overlap_conflict,
3779 {"Conflicting data in fragment overlap", "wlan.fragment.overlap.conflict",
3780 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3781 "Overlapping fragments contained conflicting data", HFILL }},
3783 {&hf_fragment_multiple_tails,
3784 {"Multiple tail fragments found", "wlan.fragment.multipletails",
3785 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3786 "Several tails were found when defragmenting the packet", HFILL }},
3788 {&hf_fragment_too_long_fragment,
3789 {"Fragment too long", "wlan.fragment.toolongfragment",
3790 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3791 "Fragment contained data past end of packet", HFILL }},
3793 {&hf_fragment_error,
3794 {"Defragmentation error", "wlan.fragment.error",
3795 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3796 "Defragmentation error due to illegal fragments", HFILL }},
3799 {"802.11 Fragment", "wlan.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3800 "802.11 Fragment", HFILL }},
3803 {"802.11 Fragments", "wlan.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
3804 "802.11 Fragments", HFILL }},
3806 {&hf_reassembled_in,
3807 {"Reassembled 802.11 in frame", "wlan.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3808 "This 802.11 packet is reassembled in this frame", HFILL }},
3811 {"Initialization Vector", "wlan.wep.iv", FT_UINT24, BASE_HEX, NULL, 0,
3812 "Initialization Vector", HFILL }},
3815 {"Weak IV", "wlan.wep.weakiv", FT_BOOLEAN,BASE_NONE, NULL,0x0,
3819 {"TKIP Ext. Initialization Vector", "wlan.tkip.extiv", FT_STRING,
3820 BASE_HEX, NULL, 0, "TKIP Extended Initialization Vector", HFILL }},
3823 {"CCMP Ext. Initialization Vector", "wlan.ccmp.extiv", FT_STRING,
3824 BASE_HEX, NULL, 0, "CCMP Extended Initialization Vector", HFILL }},
3827 {"Key Index", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
3828 "Key Index", HFILL }},
3831 {"WEP ICV", "wlan.wep.icv", FT_UINT32, BASE_HEX, NULL, 0,
3832 "WEP ICV", HFILL }},
3835 static const true_false_string rsn_preauth_flags = {
3836 "Transmitter supports pre-authentication",
3837 "Transmitter does not support pre-authentication"
3840 static const true_false_string rsn_no_pairwise_flags = {
3841 "Transmitter cannot support WEP default key 0 simultaneously with "
3843 "Transmitter can support WEP default key 0 simultaneously with "
3847 static const value_string rsn_cap_replay_counter[] = {
3848 {0x00, "1 replay counter per PTKSA/GTKSA/STAKeySA"},
3849 {0x01, "2 replay counters per PTKSA/GTKSA/STAKeySA"},
3850 {0x02, "4 replay counters per PTKSA/GTKSA/STAKeySA"},
3851 {0x03, "16 replay counters per PTKSA/GTKSA/STAKeySA"},
3855 static hf_register_info ff[] = {
3857 {"Timestamp", "wlan_mgt.fixed.timestamp", FT_STRING, BASE_NONE,
3858 NULL, 0, "", HFILL }},
3861 {"Authentication Algorithm", "wlan_mgt.fixed.auth.alg",
3862 FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, "", HFILL }},
3864 {&ff_beacon_interval,
3865 {"Beacon Interval", "wlan_mgt.fixed.beacon", FT_DOUBLE, BASE_DEC, NULL, 0,
3868 {&hf_fixed_parameters,
3869 {"Fixed parameters", "wlan_mgt.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
3872 {&hf_tagged_parameters,
3873 {"Tagged parameters", "wlan_mgt.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
3877 {"Capabilities", "wlan_mgt.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
3878 "Capability information", HFILL }},
3881 {"ESS capabilities", "wlan_mgt.fixed.capabilities.ess",
3882 FT_BOOLEAN, 16, TFS (&cf_ess_flags), 0x0001, "ESS capabilities", HFILL }},
3885 {"IBSS status", "wlan_mgt.fixed.capabilities.ibss",
3886 FT_BOOLEAN, 16, TFS (&cf_ibss_flags), 0x0002, "IBSS participation", HFILL }},
3889 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.sta",
3890 FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0x020C,
3891 "CF-Poll capabilities for a STA", HFILL }},
3894 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.ap",
3895 FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0x020C,
3896 "CF-Poll capabilities for an AP", HFILL }},
3899 {"Privacy", "wlan_mgt.fixed.capabilities.privacy",
3900 FT_BOOLEAN, 16, TFS (&cf_privacy_flags), 0x0010, "WEP support", HFILL }},
3903 {"Short Preamble", "wlan_mgt.fixed.capabilities.preamble",
3904 FT_BOOLEAN, 16, TFS (&cf_preamble_flags), 0x0020, "Short Preamble", HFILL }},
3907 {"PBCC", "wlan_mgt.fixed.capabilities.pbcc",
3908 FT_BOOLEAN, 16, TFS (&cf_pbcc_flags), 0x0040, "PBCC Modulation", HFILL }},
3911 {"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
3912 FT_BOOLEAN, 16, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
3915 {"Spectrum Management", "wlan_mgt.fixed.capabilities.spec_man",
3916 FT_BOOLEAN, 16, TFS (&cf_spec_man_flags), 0x0100, "Spectrum Management", HFILL }},
3918 {&ff_short_slot_time,
3919 {"Short Slot Time", "wlan_mgt.fixed.capabilities.short_slot_time",
3920 FT_BOOLEAN, 16, TFS (&short_slot_time_flags), 0x0400, "Short Slot Time",
3924 {"Automatic Power Save Delivery", "wlan_mgt.fixed.capabilities.apsd",
3925 FT_BOOLEAN, 16, TFS (&cf_apsd_flags), 0x0800, "Automatic Power Save "
3926 "Delivery", HFILL }},
3929 {"DSSS-OFDM", "wlan_mgt.fixed.capabilities.dsss_ofdm",
3930 FT_BOOLEAN, 16, TFS (&dsss_ofdm_flags), 0x2000, "DSSS-OFDM Modulation",
3933 {&ff_cf_del_blk_ack,
3934 {"Delayed Block Ack", "wlan_mgt.fixed.capabilities.del_blk_ack",
3935 FT_BOOLEAN, 16, TFS (&cf_del_blk_ack_flags), 0x4000, "Delayed Block "
3938 {&ff_cf_imm_blk_ack,
3939 {"Immediate Block Ack", "wlan_mgt.fixed.capabilities.imm_blk_ack",
3940 FT_BOOLEAN, 16, TFS (&cf_imm_blk_ack_flags), 0x8000, "Immediate Block "
3944 {"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
3945 FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
3948 {"Association ID", "wlan_mgt.fixed.aid",
3949 FT_UINT16, BASE_HEX, NULL, 0, "Association ID", HFILL }},
3952 {"Listen Interval", "wlan_mgt.fixed.listen_ival",
3953 FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval", HFILL }},
3956 {"Current AP", "wlan_mgt.fixed.current_ap",
3957 FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP", HFILL }},
3960 {"Reason code", "wlan_mgt.fixed.reason_code",
3961 FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
3962 "Reason for unsolicited notification", HFILL }},
3965 {"Status code", "wlan_mgt.fixed.status_code",
3966 FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
3967 "Status of requested event", HFILL }},
3970 {"Category code", "wlan_mgt.fixed.category_code",
3971 FT_UINT16, BASE_DEC, VALS (&category_codes), 0,
3972 "Management action category", HFILL }},
3975 {"Action code", "wlan_mgt.fixed.action_code",
3976 FT_UINT16, BASE_DEC, VALS (&action_codes), 0,
3977 "Management action code", HFILL }},
3980 {"Dialog token", "wlan_mgt.fixed.dialog_token",
3981 FT_UINT16, BASE_HEX, NULL, 0, "Management action dialog token", HFILL }},
3983 {&ff_wme_action_code,
3984 {"Action code", "wlan_mgt.fixed.action_code",
3985 FT_UINT16, BASE_HEX, VALS (&wme_action_codes), 0,
3986 "Management notification action code", HFILL }},
3988 {&ff_wme_status_code,
3989 {"Status code", "wlan_mgt.fixed.status_code",
3990 FT_UINT16, BASE_HEX, VALS (&wme_status_codes), 0,
3991 "Management notification setup response status code", HFILL }},
3994 {"Tag", "wlan_mgt.tag.number",
3995 FT_UINT8, BASE_DEC, VALS(tag_num_vals), 0,
3996 "Element ID", HFILL }},
3999 {"Tag length", "wlan_mgt.tag.length",
4000 FT_UINT8, BASE_DEC, NULL, 0, "Length of tag", HFILL }},
4002 {&tag_interpretation,
4003 {"Tag interpretation", "wlan_mgt.tag.interpretation",
4004 FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }},
4007 {"OUI", "wlan_mgt.tag.oui",
4008 FT_BYTES, BASE_NONE, NULL, 0, "OUI of vendor specific IE", HFILL }},
4011 {"TIM length", "wlan_mgt.tim.length",
4012 FT_UINT8, BASE_DEC, NULL, 0,
4013 "Traffic Indication Map length", HFILL }},
4016 {"DTIM count", "wlan_mgt.tim.dtim_count",
4017 FT_UINT8, BASE_DEC, NULL, 0,
4018 "DTIM count", HFILL }},
4021 {"DTIM period", "wlan_mgt.tim.dtim_period",
4022 FT_UINT8, BASE_DEC, NULL, 0,
4023 "DTIM period", HFILL }},
4026 {"Bitmap control", "wlan_mgt.tim.bmapctl",
4027 FT_UINT8, BASE_HEX, NULL, 0,
4028 "Bitmap control", HFILL }},
4031 {"RSN Capabilities", "wlan_mgt.rsn.capabilities", FT_UINT16, BASE_HEX,
4032 NULL, 0, "RSN Capability information", HFILL }},
4035 {"RSN Pre-Auth capabilities", "wlan_mgt.rsn.capabilities.preauth",
4036 FT_BOOLEAN, 16, TFS (&rsn_preauth_flags), 0x0001,
4037 "RSN Pre-Auth capabilities", HFILL }},
4039 {&rsn_cap_no_pairwise,
4040 {"RSN No Pairwise capabilities", "wlan_mgt.rsn.capabilities.no_pairwise",
4041 FT_BOOLEAN, 16, TFS (&rsn_no_pairwise_flags), 0x0002,
4042 "RSN No Pairwise capabilities", HFILL }},
4044 {&rsn_cap_ptksa_replay_counter,
4045 {"RSN PTKSA Replay Counter capabilities",
4046 "wlan_mgt.rsn.capabilities.ptksa_replay_counter",
4047 FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x000C,
4048 "RSN PTKSA Replay Counter capabilities", HFILL }},
4050 {&rsn_cap_gtksa_replay_counter,
4051 {"RSN GTKSA Replay Counter capabilities",
4052 "wlan_mgt.rsn.capabilities.gtksa_replay_counter",
4053 FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x0030,
4054 "RSN GTKSA Replay Counter capabilities", HFILL }},
4056 {&hf_aironet_ie_type,
4057 {"Aironet IE type", "wlan_mgt.aironet.type",
4058 FT_UINT8, BASE_DEC, VALS(aironet_ie_type_vals), 0, "", HFILL }},
4060 {&hf_aironet_ie_version,
4061 {"Aironet IE CCX version?", "wlan_mgt.aironet.version",
4062 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4064 { &hf_aironet_ie_data,
4065 { "Aironet IE data", "wlan_mgmt.aironet.data",
4066 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
4069 {"QBSS Version", "wlan_mgt.qbss.version",
4070 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4073 {"Station Count", "wlan_mgt.qbss.scount",
4074 FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
4077 {"Channel Utilization", "wlan_mgt.qbss.cu",
4078 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4081 {"Available Admission Capabilities", "wlan_mgt.qbss.adc",
4082 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4085 {"Channel Utilization", "wlan_mgt.qbss2.cu",
4086 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4089 {"G.711 CU Quantum", "wlan_mgt.qbss2.glimit",
4090 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4093 {"Call Admission Limit", "wlan_mgt.qbss2.cal",
4094 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4097 {"Station Count", "wlan_mgt.qbss2.scount",
4098 FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
4100 {&hf_aironet_ie_qos_unk1,
4101 {"Aironet IE QoS unknown1", "wlan_mgt.aironet.qos.unk1",
4102 FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
4104 {&hf_aironet_ie_qos_paramset,
4105 {"Aironet IE QoS paramset", "wlan_mgt.aironet.qos.paramset",
4106 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4108 {&hf_aironet_ie_qos_val,
4109 {"Aironet IE QoS valueset", "wlan_mgt.aironet.qos.val",
4110 FT_BYTES, BASE_NONE, NULL, 0, "", HFILL }},
4114 static gint *tree_array[] = {
4121 &ett_fixed_parameters,
4122 &ett_tagged_parameters,
4123 &ett_qos_parameters,
4124 &ett_qos_ps_buf_state,
4125 &ett_wep_parameters,
4130 module_t *wlan_module;
4132 enum_val_t *wep_keys_options = g_malloc(sizeof(enum_val_t) * (MAX_ENCRYPTION_KEYS + 2));
4135 proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
4136 "IEEE 802.11", "wlan");
4137 proto_register_field_array (proto_wlan, hf, array_length (hf));
4138 proto_wlan_mgt = proto_register_protocol ("IEEE 802.11 wireless LAN management frame",
4139 "802.11 MGT", "wlan_mgt");
4140 proto_register_field_array (proto_wlan_mgt, ff, array_length (ff));
4141 proto_register_subtree_array (tree_array, array_length (tree_array));
4143 register_dissector("wlan", dissect_ieee80211, proto_wlan);
4144 register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
4145 register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan);
4146 register_dissector("wlan_datapad", dissect_ieee80211_datapad, proto_wlan);
4147 register_init_routine(wlan_defragment_init);
4149 wlan_tap = register_tap("wlan");
4151 /* Register configuration options */
4152 wlan_module = prefs_register_protocol(proto_wlan, init_wepkeys);
4153 prefs_register_bool_preference(wlan_module, "defragment",
4154 "Reassemble fragmented 802.11 datagrams",
4155 "Whether fragmented 802.11 datagrams should be reassembled",
4158 prefs_register_bool_preference(wlan_module, "check_fcs",
4159 "Assume packets have FCS",
4160 "Some 802.11 cards include the FCS at the end of a packet, others do not.",
4163 prefs_register_bool_preference(wlan_module, "ignore_wep",
4164 "Ignore the WEP bit",
4165 "Some 802.11 cards leave the WEP bit set even though the packet is decrypted.",
4170 for (i = 0; i <= MAX_ENCRYPTION_KEYS; i++) {
4171 key_name = g_string_new("");
4172 g_string_sprintf(key_name, "%d", i);
4173 wep_keys_options[i].name = key_name->str;
4174 wep_keys_options[i].description = key_name->str;
4175 wep_keys_options[i].value = i;
4176 g_string_free(key_name, FALSE);
4178 wep_keys_options[i].name = NULL;
4179 wep_keys_options[i].description = NULL;
4180 wep_keys_options[i].value = -1;
4182 key_desc = g_string_new("");
4183 g_string_sprintf(key_desc, "How many WEP keys do we have to choose from? (0 to disable, up to %d)", MAX_ENCRYPTION_KEYS);
4184 prefs_register_enum_preference(wlan_module, "wep_keys",
4185 "WEP key count", key_desc->str,
4186 &num_wepkeys, wep_keys_options, FALSE);
4187 g_string_free(key_desc, FALSE);
4189 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
4190 key_name = g_string_new("");
4191 key_title = g_string_new("");
4192 key_desc = g_string_new("");
4193 wep_keystr[i] = NULL;
4194 /* prefs_register_*_preference() expects unique strings, so
4195 * we build them using g_string_sprintf and just leave them
4197 g_string_sprintf(key_name, "wep_key%d", i + 1);
4198 g_string_sprintf(key_title, "WEP key #%d", i + 1);
4199 g_string_sprintf(key_desc, "WEP key #%d bytes in hexadecimal (A:B:C:D:E) "
4200 "[40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key "
4201 "length you're using", i + 1);
4203 prefs_register_string_preference(wlan_module, key_name->str,
4204 key_title->str, key_desc->str, &wep_keystr[i]);
4206 g_string_free(key_name, FALSE);
4207 g_string_free(key_title, FALSE);
4208 g_string_free(key_desc, FALSE);
4214 proto_reg_handoff_ieee80211(void)
4216 dissector_handle_t ieee80211_handle;
4217 dissector_handle_t ieee80211_radio_handle;
4220 * Get handles for the LLC, IPX and Ethernet dissectors.
4222 llc_handle = find_dissector("llc");
4223 ipx_handle = find_dissector("ipx");
4224 eth_withoutfcs_handle = find_dissector("eth_withoutfcs");
4225 data_handle = find_dissector("data");
4227 ieee80211_handle = find_dissector("wlan");
4228 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle);
4229 ieee80211_radio_handle = create_dissector_handle(dissect_ieee80211_radio,
4231 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
4232 ieee80211_radio_handle);
4233 dissector_add("ethertype", ETHERTYPE_CENTRINO_PROMISC, ieee80211_handle);
4236 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len) {
4237 const guint8 *enc_data;
4240 tvbuff_t *decr_tvb = NULL;
4242 if (num_wepkeys < 1)
4245 enc_data = tvb_get_ptr(tvb, offset, len);
4247 if ((tmp = g_malloc(len)) == NULL)
4248 return NULL; /* krap! */
4250 /* try once with the key index in the packet, then look through our list. */
4251 for (i = -1; i < num_wepkeys; i++) {
4252 /* copy the encrypted data over to the tmp buffer */
4254 printf("trying %d\n", i);
4256 memcpy(tmp, enc_data, len);
4257 if (wep_decrypt(tmp, len, i) == 0) {
4259 /* decrypt successful, let's set up a new data tvb. */
4260 decr_tvb = tvb_new_real_data(tmp, len-8, len-8);
4261 tvb_set_free_cb(decr_tvb, g_free);
4262 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
4269 if ((!decr_tvb) && (tmp)) g_free(tmp);
4272 printf("de-wep %p\n", decr_tvb);
4279 /* de-weps the block. if successful, buf* will point to the data start. */
4280 static int wep_decrypt(guint8 *buf, guint32 len, int key_override) {
4281 guint32 i, j, k, crc, keylen;
4282 guint8 s[256], key[128], c_crc[4];
4283 guint8 keyidx, *dpos, *cpos;
4285 /* Needs to be at least 8 bytes of payload */
4289 /* initialize the first bytes of the key from the IV */
4293 keyidx = KEY_OCTET_WEP_KEY(buf[3]);
4295 if (key_override >= 0)
4296 keyidx = key_override;
4298 if (keyidx >= (guint)num_wepkeys)
4301 keylen = wep_keylens[keyidx];
4305 if (wep_keys[keyidx] == NULL)
4308 keylen+=3; /* add in ICV bytes */
4310 /* copy the rest of the key over from the designated key */
4311 memcpy(key+3, wep_keys[keyidx], wep_keylens[keyidx]);
4314 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]);
4317 /* set up the RC4 state */
4318 for (i = 0; i < 256; i++)
4321 for (i = 0; i < 256; i++) {
4322 j = (j + s[i] + key[i % keylen]) & 0xff;
4326 /* Apply the RC4 to the data, update the CRC32 */
4331 for (k = 0; k < (len -8); k++) {
4333 j = (j+s[i]) & 0xff;
4336 printf("%d -- %02x ", k, *dpos);
4338 *dpos = *cpos++ ^ s[(s[i] + s[j]) & 0xff];
4340 printf("%02x\n", *dpos);
4342 crc = crc32_ccitt_table[(crc ^ *dpos++) & 0xff] ^ (crc >> 8);
4346 /* now let's check the crc */
4348 c_crc[1] = crc >> 8;
4349 c_crc[2] = crc >> 16;
4350 c_crc[3] = crc >> 24;
4352 for (k = 0; k < 4; k++) {
4354 j = (j+s[i]) & 0xff;
4357 printf("-- %02x %02x\n", *dpos, c_crc[k]);
4359 if ((*cpos++ ^ s[(s[i] + s[j]) & 0xff]) != c_crc[k])
4360 return -1; /* ICV mismatch */
4366 static void init_wepkeys(void) {
4375 tmp = getenv("WIRESHARK_WEPKEYNUM");
4380 num_wepkeys = atoi(tmp);
4382 if (num_wepkeys > 4)
4386 if (num_wepkeys < 1)
4393 g_free(wep_keylens);
4395 wep_keys = g_malloc(num_wepkeys * sizeof(guint8*));
4396 wep_keylens = g_malloc(num_wepkeys * sizeof(int));
4397 bytes = g_byte_array_new();
4399 for (i = 0 ; i < num_wepkeys; i++) {
4405 g_snprintf(buf, 128, "WIRESHARK_WEPKEY%d", i+1);
4408 tmp = wep_keystr[i];
4414 printf("%s -- %s\n", buf, tmp);
4416 printf("%d -- %s\n", i+1, tmp);
4421 g_free(wep_keys[i]);
4424 res = hex_str_to_bytes(tmp, bytes, FALSE);
4425 if (res && bytes->len > 0) {
4426 if (bytes->len > 32) {
4429 wep_keys[i] = g_malloc(32 * sizeof(guint8));
4430 memset(wep_keys[i], 0, 32 * sizeof(guint8));
4431 memcpy(wep_keys[i], bytes->data, bytes->len * sizeof(guint8));
4432 wep_keylens[i] = bytes->len;
4434 printf("%d: %d bytes\n", i, bytes->len);
4435 printf("%d: %s\n", i, bytes_to_str(bytes->data, bytes->len));
4439 printf("res: %d bytes->len: %d\n", res, bytes->len);
4441 g_warning("Could not parse WEP key %d: %s", i + 1, tmp);
4445 g_byte_array_free(bytes, TRUE);
4448 * This code had been taken from AirSnort crack.c function classify()
4449 * Permission granted by snax <at> shmoo dot com
4450 * weak_iv - determine which key byte an iv is useful in resolving
4451 * parm - p, pointer to the first byte of an IV
4452 * return - n - this IV is weak for byte n of a WEP key
4453 * -1 - this IV is not weak for any key bytes
4455 * This function tests for IVs that are known to satisfy the criteria
4456 * for a weak IV as specified in FMS section 7.1
4464 if (iv[1] == 255 && iv[0] > 2 && iv[0] < 16) {
4468 sum = iv[0] + iv[1];
4470 if (iv[2] <= 0x0a) {
4473 else if (iv[2] == 0xff){
4478 if (sum == k && (iv[2] >= 0xf2 && iv[2] <= 0xfe && iv[2] != 0xfd)){