2 * Routines for Wireless LAN (IEEE 802.11) dissection
3 * Copyright 2000, Axis Communications AB
4 * Inquiries/bugreports should be sent to Johan.Jorgensen@axis.com
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
10 * Copyright 1998 Gerald Combs
12 * Copied from README.developer
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 * The following people helped me by pointing out bugs etc. Thank you!
34 * Magnus Hultman-Persson
38 * 09/12/2003 - Added dissection of country information tag
40 * Ritchie<at>tipsybottle.com
42 * 03/22/2004 - Added dissection of RSN IE
43 * Jouni Malinen <jkmaline@cc.hut.fi>
53 #ifdef NEED_SNPRINTF_H
54 # include "snprintf.h"
59 #include <epan/bitswap.h>
60 #include <epan/proto.h>
61 #include <epan/packet.h>
62 #include <epan/addr_resolv.h>
63 #include <epan/strutil.h>
64 #include <epan/prefs.h>
65 #include <epan/reassemble.h>
66 #include "packet-ipx.h"
67 #include "packet-llc.h"
68 #include "packet-ieee80211.h"
69 #include <epan/etypes.h>
70 #include <epan/crc32.h>
72 #include <epan/emem.h>
77 /* Defragment fragmented 802.11 datagrams */
78 static gboolean wlan_defragment = TRUE;
80 /* Check for the presence of the 802.11 FCS */
81 static gboolean wlan_check_fcs = FALSE;
83 /* Ignore the WEP bit; assume packet is decrypted */
84 static gboolean wlan_ignore_wep = FALSE;
86 /* Tables for reassembly of fragments. */
87 static GHashTable *wlan_fragment_table = NULL;
88 static GHashTable *wlan_reassembled_table = NULL;
90 /* Stuff for the WEP decoder */
91 static gint num_wepkeys = 0;
92 static guint8 **wep_keys = NULL;
93 static int *wep_keylens = NULL;
94 static void init_wepkeys(void);
95 static int wep_decrypt(guint8 *buf, guint32 len, int key_override);
96 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len);
97 static int weak_iv(guchar *iv);
98 #define SSWAP(a,b) {guint8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
100 /* #define USE_ENV */
101 /* When this is set, an unlimited number of WEP keys can be set in the
104 ETHEREAL_WEPKEYNUM=##
105 ETHEREAL_WEPKEY1=aa:bb:cc:dd:...
106 ETHEREAL_WEPKEY2=aa:bab:cc:dd:ee:...
108 ... you get the idea.
110 otherwise you're limited to specifying four keys in the preference system.
114 static const char *wep_keystr[] = {NULL, NULL, NULL, NULL};
117 /* ************************************************************************* */
118 /* Miscellaneous Constants */
119 /* ************************************************************************* */
120 #define SHORT_STR 256
122 /* ************************************************************************* */
123 /* Define some very useful macros that are used to analyze frame types etc. */
124 /* ************************************************************************* */
125 #define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+((x & 0xF0) >> 4)) /* Create key to (sub)type */
126 #define COOK_PROT_VERSION(x) ((x) & 0x3)
127 #define COOK_FRAME_TYPE(x) (((x) & 0xC) >> 2)
128 #define COOK_FRAME_SUBTYPE(x) (((x) & 0xF0) >> 4)
129 #define COOK_ADDR_SELECTOR(x) ((x) & 0x300)
130 #define COOK_ASSOC_ID(x) ((x) & 0x3FFF)
131 #define COOK_FRAGMENT_NUMBER(x) ((x) & 0x000F)
132 #define COOK_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
133 #define COOK_QOS_PRIORITY(x) ((x) & 0x0007)
134 #define COOK_QOS_ACK_POLICY(x) (((x) & 0x0060) >> 5)
135 #define COOK_FLAGS(x) (((x) & 0xFF00) >> 8)
136 #define COOK_DS_STATUS(x) ((x) & 0x3)
137 #define COOK_WEP_KEY(x) (((x) & 0xC0) >> 6)
138 #define COOK_QOS_TID(x) ((x) & 0x000F)
139 #define COOK_QOS_EOSP(x) (((x) & 0x0010) >> 4) /* end of service period */
140 #define COOK_QOS_FIELD_CONTENT(x) (((x) & 0xFF00) >> 8)
141 #define COOK_PS_BUF_STATE(x) (((x) & 0x02) >> 1)
142 #define COOK_PS_BUF_AC(x) (((x) & 0x0C) >> 2)
143 #define COOK_PS_BUF_LOAD(x) (((x) & 0xF0) >> 4)
145 #define KEY_EXTIV 0x20
148 #define FLAG_TO_DS 0x01
149 #define FLAG_FROM_DS 0x02
150 #define FLAG_MORE_FRAGMENTS 0x04
151 #define FLAG_RETRY 0x08
152 #define FLAG_POWER_MGT 0x10
153 #define FLAG_MORE_DATA 0x20
154 #define FLAG_PROTECTED 0x40
155 #define FLAG_ORDER 0x80
156 #define FLAG_DATA_NULL 0x24
157 #define FLAG_DATA_QOS 0x28
158 #define FLAG_EOSP 0x08
159 #define FLAG_DATA_CF_POLL 0x22
161 #define IS_TO_DS(x) ((x) & FLAG_TO_DS)
162 #define IS_FROM_DS(x) ((x) & FLAG_FROM_DS)
163 #define HAVE_FRAGMENTS(x) ((x) & FLAG_MORE_FRAGMENTS)
164 #define IS_RETRY(x) ((x) & FLAG_RETRY)
165 #define POWER_MGT_STATUS(x) ((x) & FLAG_POWER_MGT)
166 #define HAS_MORE_DATA(x) ((x) & FLAG_MORE_DATA)
167 #define IS_PROTECTED(x) (!wlan_ignore_wep && ((x) & FLAG_PROTECTED))
168 #define IS_STRICTLY_ORDERED(x) ((x) & FLAG_ORDER)
169 #define IS_DATA_NULL(x) (((x) & 0xf4) == FLAG_DATA_NULL)
170 #define IS_DATA_QOS(x) (((x) & 0xf8) == FLAG_DATA_QOS)
171 #define IS_DATA_CF_POLL(x) (((x) & 0xf2) == FLAG_DATA_CF_POLL)
173 #define MGT_RESERVED_RANGE(x) (((x>=0x06)&&(x<=0x07))||((x>=0x0E)&&(x<=0x0F)))
174 #define CTRL_RESERVED_RANGE(x) ((x>=0x10)&&(x<=0x17))
175 #define DATA_RESERVED_RANGE(x) (x==0x2D)
176 #define SPEC_RESERVED_RANGE(x) ((x>=0x30)&&(x<=0x3f))
179 /* ************************************************************************* */
180 /* Constants used to identify cooked frame types */
181 /* ************************************************************************* */
182 #define MGT_FRAME 0x00 /* Frame type is management */
183 #define CONTROL_FRAME 0x01 /* Frame type is control */
184 #define DATA_FRAME 0x02 /* Frame type is Data */
186 #define DATA_SHORT_HDR_LEN 24
187 #define DATA_LONG_HDR_LEN 30
188 #define MGT_FRAME_HDR_LEN 24 /* Length of Managment frame-headers */
190 #define MGT_ASSOC_REQ 0x00 /* Management - association request */
191 #define MGT_ASSOC_RESP 0x01 /* Management - association response */
192 #define MGT_REASSOC_REQ 0x02 /* Management - reassociation request */
193 #define MGT_REASSOC_RESP 0x03 /* Management - reassociation response */
194 #define MGT_PROBE_REQ 0x04 /* Management - Probe request */
195 #define MGT_PROBE_RESP 0x05 /* Management - Probe response */
196 #define MGT_BEACON 0x08 /* Management - Beacon frame */
197 #define MGT_ATIM 0x09 /* Management - ATIM */
198 #define MGT_DISASS 0x0A /* Management - Disassociation */
199 #define MGT_AUTHENTICATION 0x0B /* Management - Authentication */
200 #define MGT_DEAUTHENTICATION 0x0C /* Management - Deauthentication */
201 #define MGT_ACTION 0x0D /* Management - Action */
203 #define CTRL_BLOCK_ACK_REQ 0x18 /* Control - Block ack Request */
204 #define CTRL_BLOCK_ACK 0x19 /* Control - Block ack */
206 #define CTRL_PS_POLL 0x1A /* Control - power-save poll */
207 #define CTRL_RTS 0x1B /* Control - request to send */
208 #define CTRL_CTS 0x1C /* Control - clear to send */
209 #define CTRL_ACKNOWLEDGEMENT 0x1D /* Control - acknowledgement */
210 #define CTRL_CFP_END 0x1E /* Control - contention-free period end */
211 #define CTRL_CFP_ENDACK 0x1F /* Control - contention-free period end/ack */
213 #define DATA 0x20 /* Data - Data */
214 #define DATA_CF_ACK 0x21 /* Data - Data + CF acknowledge */
215 #define DATA_CF_POLL FLAG_DATA_CF_POLL /* Data - Data + CF poll */
216 #define DATA_CF_ACK_POLL 0x23 /* Data - Data + CF acknowledge + CF poll */
217 #define DATA_NULL_FUNCTION FLAG_DATA_NULL /* Data - Null function (no data) */
218 #define DATA_CF_ACK_NOD 0x25 /* Data - CF ack (no data) */
219 #define DATA_CF_POLL_NOD 0x26 /* Data - CF poll (No data) */
220 #define DATA_CF_ACK_POLL_NOD 0x27 /* Data - CF ack + CF poll (no data) */
221 #define DATA_QOS_DATA FLAG_DATA_QOS /* Data - QoS Data */
224 #define DATA_QOS_DATA_CF_ACK 0x29 /* Data - QoS Data + CF-Ack */
225 #define DATA_QOS_DATA_CF_POLL 0x2A /* Data - QoS Data + CF-Poll */
226 #define DATA_QOS_DATA_CF_ACK_POLL 0x2B /* Data - QoS Data + CF-Ack + CF-poll */
227 #define DATA_QOS_NULL 0x2C /* Data - QoS Null */
228 #define DATA_QOS_CF_POLL_NOD 0x2E /* Data - QoS CF-poll (No Data) */
229 #define DATA_QOS_CF_ACK_POLL_NOD 0x2F /* Data - QoS CF-Ack + CF-poll (No Data) */
231 #define DATA_ADDR_T1 0
232 #define DATA_ADDR_T2 (FLAG_FROM_DS << 8)
233 #define DATA_ADDR_T3 (FLAG_TO_DS << 8)
234 #define DATA_ADDR_T4 ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
237 /* ************************************************************************* */
238 /* Macros used to extract information about fixed fields */
239 /* ************************************************************************* */
240 #define ESS_SET(x) ((x) & 0x0001)
241 #define IBSS_SET(x) ((x) & 0x0002)
245 /* ************************************************************************* */
246 /* Logical field codes (dissector's encoding of fixed fields) */
247 /* ************************************************************************* */
248 #define FIELD_TIMESTAMP 0x01 /* 64-bit timestamp */
249 #define FIELD_BEACON_INTERVAL 0x02 /* 16-bit beacon interval */
250 #define FIELD_CAP_INFO 0x03 /* Add capability information tree */
251 #define FIELD_AUTH_ALG 0x04 /* Authentication algorithm used */
252 #define FIELD_AUTH_TRANS_SEQ 0x05 /* Authentication sequence number */
253 #define FIELD_CURRENT_AP_ADDR 0x06
254 #define FIELD_LISTEN_IVAL 0x07
255 #define FIELD_REASON_CODE 0x08
256 #define FIELD_ASSOC_ID 0x09
257 #define FIELD_STATUS_CODE 0x0A
258 #define FIELD_CATEGORY_CODE 0x0B /* Management action category */
259 #define FIELD_ACTION_CODE 0x0C /* Management action code */
260 #define FIELD_DIALOG_TOKEN 0x0D /* Management action dialog token */
261 #define FIELD_WME_ACTION_CODE 0x0E /* Management notification action code */
262 #define FIELD_WME_DIALOG_TOKEN 0x0F /* Management notification dialog token */
263 #define FIELD_WME_STATUS_CODE 0x10 /* Management notification setup response status code */
265 /* ************************************************************************* */
266 /* Logical field codes (IEEE 802.11 encoding of tags) */
267 /* ************************************************************************* */
268 #define TAG_SSID 0x00
269 #define TAG_SUPP_RATES 0x01
270 #define TAG_FH_PARAMETER 0x02
271 #define TAG_DS_PARAMETER 0x03
272 #define TAG_CF_PARAMETER 0x04
274 #define TAG_IBSS_PARAMETER 0x06
275 #define TAG_COUNTRY_INFO 0x07
276 #define TAG_FH_HOPPING_PARAMETER 0x08
277 #define TAG_FH_HOPPING_TABLE 0x09
278 #define TAG_REQUEST 0x0A
279 #define TAG_QBSS_LOAD 0x0B
280 #define TAG_EDCA_PARAM_SET 0x0C
281 #define TAG_TRAF_SPEC 0x0D
282 #define TAG_TRAF_CLASS 0x0E
283 #define TAG_SCHEDULE 0x0F
284 #define TAG_CHALLENGE_TEXT 0x10
285 #define TAG_POWER_CONSTRAINT 0x20
286 #define TAG_POWER_CAPABILITY 0x21
287 #define TAG_TPC_REQUEST 0x22
288 #define TAG_TPC_REPORT 0x23
289 #define TAG_SUPPORTED_CHANNELS 0x24
290 #define TAG_CHANNEL_SWITCH_ANN 0x25
291 #define TAG_MEASURE_REQ 0x26
292 #define TAG_MEASURE_REP 0x27
293 #define TAG_QUIET 0x28
294 #define TAG_IBSS_DFS 0x29
295 #define TAG_ERP_INFO 0x2A
296 #define TAG_TS_DELAY 0x2B
297 #define TAG_TCLAS_PROCESS 0x2C
298 #define TAG_QOS_CAPABILITY 0x2E
299 #define TAG_ERP_INFO_OLD 0x2F /* IEEE Std 802.11g/D4.0 */
300 #define TAG_RSN_IE 0x30
301 #define TAG_EXT_SUPP_RATES 0x32
302 #define TAG_AGERE_PROPRIETARY 0x80
303 #define TAG_CISCO_UNKNOWN_1 0x85 /* Cisco Compatible eXtensions? */
304 #define TAG_CISCO_UNKNOWN_2 0x88 /* Cisco Compatible eXtensions? */
305 #define TAG_VENDOR_SPECIFIC_IE 0xDD
306 #define TAG_SYMBOL_PROPRIETARY 0xAD
308 #define WPA_OUI "\x00\x50\xF2"
309 #define RSN_OUI "\x00\x0F\xAC"
310 #define WME_OUI "\x00\x50\xF2"
314 /* ************************************************************************* */
315 /* Frame types, and their names */
316 /* ************************************************************************* */
317 static const value_string frame_type_subtype_vals[] = {
318 {MGT_ASSOC_REQ, "Association Request"},
319 {MGT_ASSOC_RESP, "Association Response"},
320 {MGT_REASSOC_REQ, "Reassociation Request"},
321 {MGT_REASSOC_RESP, "Reassociation Response"},
322 {MGT_PROBE_REQ, "Probe Request"},
323 {MGT_PROBE_RESP, "Probe Response"},
324 {MGT_BEACON, "Beacon frame"},
326 {MGT_DISASS, "Dissassociate"},
327 {MGT_AUTHENTICATION, "Authentication"},
328 {MGT_DEAUTHENTICATION, "Deauthentication"},
329 {MGT_ACTION, "Action"},
330 {CTRL_PS_POLL, "Power-Save poll"},
331 {CTRL_RTS, "Request-to-send"},
332 {CTRL_CTS, "Clear-to-send"},
333 {CTRL_ACKNOWLEDGEMENT, "Acknowledgement"},
334 {CTRL_CFP_END, "CF-End (Control-frame)"},
335 {CTRL_CFP_ENDACK, "CF-End + CF-Ack (Control-frame)"},
337 {DATA_CF_ACK, "Data + CF-Acknowledgement"},
338 {DATA_CF_POLL, "Data + CF-Poll"},
339 {DATA_CF_ACK_POLL, "Data + CF-Acknowledgement/Poll"},
340 {DATA_NULL_FUNCTION, "Null function (No data)"},
341 {DATA_CF_ACK_NOD, "Data + Acknowledgement (No data)"},
342 {DATA_CF_POLL_NOD, "Data + CF-Poll (No data)"},
343 {DATA_CF_ACK_POLL_NOD, "Data + CF-Acknowledgement/Poll (No data)"},
344 {DATA_QOS_DATA, "QoS Data"},
345 {DATA_QOS_NULL, "QoS Null (No data)"},
346 {DATA_QOS_DATA_CF_ACK, "802.11 Q0S Data + CF-Ack"},
347 {DATA_QOS_DATA_CF_POLL, "802.11 QoS Data + CF-Poll"},
348 {DATA_QOS_DATA_CF_ACK_POLL, "802.11 Q0S Data + CF-Ack/Poll"},
349 {DATA_QOS_CF_POLL_NOD, "802.11 QoS CF-poll (No Data)"},
350 {DATA_QOS_CF_ACK_POLL_NOD, "802.11 QoS CF-Ack + CF-poll (No Data)"},
351 {CTRL_BLOCK_ACK_REQ, "802.11 Block Ack Req"},
352 {CTRL_BLOCK_ACK, "802.11 Block Ack"},
356 /* ************************************************************************* */
357 /* 802.1D Tag Names */
358 /* ************************************************************************* */
359 static const char *qos_tags[8] = {
370 /* ************************************************************************* */
371 /* WME Access Category Names (by 802.1D Tag) */
372 /* ************************************************************************* */
373 static const char *qos_acs[8] = {
384 /* ************************************************************************* */
385 /* WME Access Category Names (by WME ACI) */
386 /* ************************************************************************* */
387 static const char *wme_acs[4] = {
395 #define CAT_SPECTRUM_MGMT 0
398 #define CAT_BLOCK_ACK 3
399 #define CAT_MGMT_NOTIFICATION 17
401 #define SM_ACTION_MEASUREMENT_REQUEST 0
402 #define SM_ACTION_MEASUREMENT_REPORT 1
403 #define SM_ACTION_TPC_REQUEST 2
404 #define SM_ACTION_TPC_REPORT 3
405 #define SM_ACTION_CHAN_SWITCH_ANNC 4
407 static int proto_wlan = -1;
408 static packet_info * g_pinfo;
410 /* ************************************************************************* */
411 /* Header field info values for radio information */
412 /* ************************************************************************* */
413 static int hf_data_rate = -1;
414 static int hf_channel = -1;
415 static int hf_signal_strength = -1;
417 /* ************************************************************************* */
418 /* Header field info values for FC-field */
419 /* ************************************************************************* */
420 static int hf_fc_field = -1;
421 static int hf_fc_proto_version = -1;
422 static int hf_fc_frame_type = -1;
423 static int hf_fc_frame_subtype = -1;
424 static int hf_fc_frame_type_subtype = -1;
426 static int hf_fc_flags = -1;
427 static int hf_fc_to_ds = -1;
428 static int hf_fc_from_ds = -1;
429 static int hf_fc_data_ds = -1;
431 static int hf_fc_more_frag = -1;
432 static int hf_fc_retry = -1;
433 static int hf_fc_pwr_mgt = -1;
434 static int hf_fc_more_data = -1;
435 static int hf_fc_protected = -1;
436 static int hf_fc_order = -1;
439 /* ************************************************************************* */
440 /* Header values for Duration/ID field */
441 /* ************************************************************************* */
442 static int hf_did_duration = -1;
443 static int hf_assoc_id = -1;
446 /* ************************************************************************* */
447 /* Header values for different address-fields (all 4 of them) */
448 /* ************************************************************************* */
449 static int hf_addr_da = -1; /* Destination address subfield */
450 static int hf_addr_sa = -1; /* Source address subfield */
451 static int hf_addr_ra = -1; /* Receiver address subfield */
452 static int hf_addr_ta = -1; /* Transmitter address subfield */
453 static int hf_addr_bssid = -1; /* address is bssid */
455 static int hf_addr = -1; /* Source or destination address subfield */
458 /* ************************************************************************* */
459 /* Header values for QoS control field */
460 /* ************************************************************************* */
461 static int hf_qos_priority = -1;
462 static int hf_qos_ack_policy = -1;
463 static int hf_qos_eosp = -1;
464 static int hf_qos_field_content = -1;
465 /*static int hf_qos_txop_limit = -1;*/
466 static int hf_qos_buf_state = -1;
467 static int hf_qos_buf_ac = -1;
468 static int hf_qos_buf_load = -1;
469 /*static int hf_qos_txop_dur_req = -1;
470 static int hf_qos_queue_size = -1;*/
472 /* ************************************************************************* */
473 /* Header values for sequence number field */
474 /* ************************************************************************* */
475 static int hf_frag_number = -1;
476 static int hf_seq_number = -1;
478 /* ************************************************************************* */
479 /* Header values for Frame Check field */
480 /* ************************************************************************* */
481 static int hf_fcs = -1;
483 /* ************************************************************************* */
484 /* Header values for reassembly */
485 /* ************************************************************************* */
486 static int hf_fragments = -1;
487 static int hf_fragment = -1;
488 static int hf_fragment_overlap = -1;
489 static int hf_fragment_overlap_conflict = -1;
490 static int hf_fragment_multiple_tails = -1;
491 static int hf_fragment_too_long_fragment = -1;
492 static int hf_fragment_error = -1;
493 static int hf_reassembled_in = -1;
496 static int proto_wlan_mgt = -1;
497 /* ************************************************************************* */
498 /* Fixed fields found in mgt frames */
499 /* ************************************************************************* */
500 static int ff_auth_alg = -1; /* Authentication algorithm field */
501 static int ff_auth_seq = -1; /* Authentication transaction sequence */
502 static int ff_current_ap = -1; /* Current AP MAC address */
503 static int ff_listen_ival = -1; /* Listen interval fixed field */
504 static int ff_timestamp = -1; /* 64 bit timestamp */
505 static int ff_beacon_interval = -1; /* 16 bit Beacon interval */
506 static int ff_assoc_id = -1; /* 16 bit AID field */
507 static int ff_reason = -1; /* 16 bit reason code */
508 static int ff_status_code = -1; /* Status code */
509 static int ff_category_code = -1; /* 8 bit Category code */
510 static int ff_action_code = -1; /* 8 bit Action code */
511 static int ff_dialog_token = -1; /* 8 bit Dialog token */
512 static int ff_wme_action_code = -1; /* Management notification action code */
513 static int ff_wme_status_code = -1; /* Management notification setup response status code */
515 /* ************************************************************************* */
516 /* Flags found in the capability field (fixed field) */
517 /* ************************************************************************* */
518 static int ff_capture = -1;
519 static int ff_cf_ess = -1;
520 static int ff_cf_ibss = -1;
521 static int ff_cf_sta_poll = -1; /* CF pollable status for a STA */
522 static int ff_cf_ap_poll = -1; /* CF pollable status for an AP */
523 static int ff_cf_privacy = -1;
524 static int ff_cf_preamble = -1;
525 static int ff_cf_pbcc = -1;
526 static int ff_cf_agility = -1;
527 static int ff_short_slot_time = -1;
528 static int ff_dsss_ofdm = -1;
529 static int ff_cf_spec_man = -1;
530 static int ff_cf_apsd = -1;
531 static int ff_cf_del_blk_ack = -1;
532 static int ff_cf_imm_blk_ack = -1;
534 /* ************************************************************************* */
535 /* Tagged value format fields */
536 /* ************************************************************************* */
537 static int tag_number = -1;
538 static int tag_length = -1;
539 static int tag_interpretation = -1;
540 static int tag_oui = -1;
542 static int tim_length = -1;
543 static int tim_dtim_count = -1;
544 static int tim_dtim_period = -1;
545 static int tim_bmapctl = -1;
548 static int hf_fixed_parameters = -1; /* Protocol payload for management frames */
549 static int hf_tagged_parameters = -1; /* Fixed payload item */
550 static int hf_wep_iv = -1;
551 static int hf_wep_iv_weak = -1;
552 static int hf_tkip_extiv = -1;
553 static int hf_ccmp_extiv = -1;
554 static int hf_wep_key = -1;
555 static int hf_wep_icv = -1;
558 static int rsn_cap = -1;
559 static int rsn_cap_preauth = -1;
560 static int rsn_cap_no_pairwise = -1;
561 static int rsn_cap_ptksa_replay_counter = -1;
562 static int rsn_cap_gtksa_replay_counter = -1;
564 /* ************************************************************************* */
566 /* ************************************************************************* */
567 static gint ett_80211 = -1;
568 static gint ett_proto_flags = -1;
569 static gint ett_cap_tree = -1;
570 static gint ett_fc_tree = -1;
571 static gint ett_fragments = -1;
572 static gint ett_fragment = -1;
574 static gint ett_80211_mgt = -1;
575 static gint ett_fixed_parameters = -1;
576 static gint ett_tagged_parameters = -1;
577 static gint ett_qos_parameters = -1;
578 static gint ett_qos_ps_buf_state = -1;
579 static gint ett_wep_parameters = -1;
581 static gint ett_rsn_cap_tree = -1;
583 static gint ett_80211_mgt_ie = -1;
585 static const fragment_items frag_items = {
590 &hf_fragment_overlap,
591 &hf_fragment_overlap_conflict,
592 &hf_fragment_multiple_tails,
593 &hf_fragment_too_long_fragment,
599 static dissector_handle_t llc_handle;
600 static dissector_handle_t ipx_handle;
601 static dissector_handle_t eth_withoutfcs_handle;
602 static dissector_handle_t data_handle;
604 static int wlan_tap = -1;
606 /* ************************************************************************* */
607 /* Return the length of the current header (in bytes) */
608 /* ************************************************************************* */
610 find_header_length (guint16 fcf)
614 switch (COOK_FRAME_TYPE (fcf)) {
617 return MGT_FRAME_HDR_LEN;
620 switch (COMPOSE_FRAME_TYPE (fcf)) {
623 case CTRL_ACKNOWLEDGEMENT:
629 case CTRL_CFP_ENDACK:
630 case CTRL_BLOCK_ACK_REQ:
637 len = (COOK_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
639 if( IS_DATA_QOS(fcf))
650 /* ************************************************************************* */
651 /* This is the capture function used to update packet counts */
652 /* ************************************************************************* */
654 capture_ieee80211_common (const guchar * pd, int offset, int len,
655 packet_counts * ld, gboolean fixed_length_header)
657 guint16 fcf, hdr_length;
659 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
664 fcf = pletohs (&pd[0]);
666 if (IS_PROTECTED(COOK_FLAGS(fcf)))
672 switch (COMPOSE_FRAME_TYPE (fcf))
675 case DATA: /* We got a data frame */
676 case DATA_CF_ACK: /* Data with ACK */
678 case DATA_CF_ACK_POLL:
680 if (fixed_length_header)
681 hdr_length = DATA_LONG_HDR_LEN;
683 hdr_length = find_header_length (fcf);
684 /* I guess some bridges take Netware Ethernet_802_3 frames,
685 which are 802.3 frames (with a length field rather than
686 a type field, but with no 802.2 header in the payload),
687 and just stick the payload into an 802.11 frame. I've seen
688 captures that show frames of that sort.
690 This means we have to do the same check for Netware 802.3 -
691 or, if you will, "Netware 802.11" - that we do in the
692 Ethernet dissector, i.e. checking for 0xffff as the first
693 four bytes of the payload and, if we find it, treating it
695 if (!BYTES_ARE_IN_FRAME(offset+hdr_length, len, 2)) {
699 if (pd[offset+hdr_length] == 0xff && pd[offset+hdr_length+1] == 0xff) {
703 capture_llc (pd, offset + hdr_length, len, ld);
714 * Handle 802.11 with a variable-length link-layer header.
717 capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
719 capture_ieee80211_common (pd, offset, len, ld, FALSE);
723 * Handle 802.11 with a fixed-length link-layer header (padded to the
727 capture_ieee80211_fixed (const guchar * pd, int offset, int len, packet_counts * ld)
729 capture_ieee80211_common (pd, offset, len, ld, TRUE);
733 /* ************************************************************************* */
734 /* Add the subtree used to store the fixed parameters */
735 /* ************************************************************************* */
737 get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
739 proto_item *fixed_fields;
741 proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
742 size, size, "Fixed parameters (%d bytes)",
745 return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
749 /* ************************************************************************* */
750 /* Add the subtree used to store tagged parameters */
751 /* ************************************************************************* */
753 get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
755 proto_item *tagged_fields;
757 tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
762 "Tagged parameters (%d bytes)",
765 return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
769 /* ************************************************************************* */
770 /* Dissect and add fixed mgmt fields to protocol tree */
771 /* ************************************************************************* */
773 add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
775 const guint8 *dataptr;
776 char out_buff[SHORT_STR];
778 proto_item *cap_item;
779 static proto_tree *cap_tree;
784 case FIELD_TIMESTAMP:
785 dataptr = tvb_get_ptr (tvb, offset, 8);
786 memset (out_buff, 0, SHORT_STR);
787 g_snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
797 proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
800 case FIELD_BEACON_INTERVAL:
801 capability = tvb_get_letohs (tvb, offset);
802 temp_double = (double)capability;
803 temp_double = temp_double * 1024 / 1000000;
804 proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
805 temp_double,"Beacon Interval: %f [Seconds]",
807 if (check_col (g_pinfo->cinfo, COL_INFO)) {
808 col_append_fstr(g_pinfo->cinfo, COL_INFO, ",BI=%d", capability);
814 capability = tvb_get_letohs (tvb, offset);
816 cap_item = proto_tree_add_uint_format (tree, ff_capture,
819 "Capability Information: 0x%04X",
821 cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree);
822 proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 2,
824 proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 2,
826 if (ESS_SET (capability) != 0) /* This is an AP */
827 proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2,
830 else /* This is a STA */
831 proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
833 proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 2,
835 proto_tree_add_boolean (cap_tree, ff_cf_preamble, tvb, offset, 2,
837 proto_tree_add_boolean (cap_tree, ff_cf_pbcc, tvb, offset, 2,
839 proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 2,
841 proto_tree_add_boolean (cap_tree, ff_cf_spec_man, tvb, offset, 2,
843 proto_tree_add_boolean (cap_tree, ff_short_slot_time, tvb, offset, 2,
845 proto_tree_add_boolean (cap_tree, ff_cf_apsd, tvb, offset, 2,
847 proto_tree_add_boolean (cap_tree, ff_dsss_ofdm, tvb, offset, 2,
849 proto_tree_add_boolean (cap_tree, ff_cf_del_blk_ack, tvb, offset, 2,
851 proto_tree_add_boolean (cap_tree, ff_cf_imm_blk_ack, tvb, offset, 2,
856 proto_tree_add_item (tree, ff_auth_alg, tvb, offset, 2, TRUE);
859 case FIELD_AUTH_TRANS_SEQ:
860 proto_tree_add_item (tree, ff_auth_seq, tvb, offset, 2, TRUE);
863 case FIELD_CURRENT_AP_ADDR:
864 proto_tree_add_item (tree, ff_current_ap, tvb, offset, 6, FALSE);
867 case FIELD_LISTEN_IVAL:
868 proto_tree_add_item (tree, ff_listen_ival, tvb, offset, 2, TRUE);
871 case FIELD_REASON_CODE:
872 proto_tree_add_item (tree, ff_reason, tvb, offset, 2, TRUE);
876 proto_tree_add_uint(tree, ff_assoc_id, tvb, offset, 2,
877 COOK_ASSOC_ID(tvb_get_letohs(tvb,offset)));
878 /* proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE); */
881 case FIELD_STATUS_CODE:
882 proto_tree_add_item (tree, ff_status_code, tvb, offset, 2, TRUE);
885 case FIELD_CATEGORY_CODE:
886 proto_tree_add_item (tree, ff_category_code, tvb, offset, 1, TRUE);
889 case FIELD_ACTION_CODE:
890 proto_tree_add_item (tree, ff_action_code, tvb, offset, 1, TRUE);
893 case FIELD_DIALOG_TOKEN:
894 proto_tree_add_item (tree, ff_dialog_token, tvb, offset, 1, TRUE);
897 case FIELD_WME_ACTION_CODE:
898 proto_tree_add_item (tree, ff_wme_action_code, tvb, offset, 1, TRUE);
901 case FIELD_WME_STATUS_CODE:
902 proto_tree_add_item (tree, ff_wme_status_code, tvb, offset, 1, TRUE);
907 static const char *wpa_cipher_str[] =
918 wpa_cipher_idx2str(guint idx)
920 if (idx < sizeof(wpa_cipher_str)/sizeof(wpa_cipher_str[0]))
921 return wpa_cipher_str[idx];
925 static const char *wpa_keymgmt_str[] =
933 wpa_keymgmt_idx2str(guint idx)
935 if (idx < sizeof(wpa_keymgmt_str)/sizeof(wpa_keymgmt_str[0]))
936 return wpa_keymgmt_str[idx];
941 dissect_vendor_ie_wpawme(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
942 int offset, guint32 tag_len, const guint8 *tag_val)
944 guint32 tag_val_off = 0;
945 char out_buff[SHORT_STR], *pos;
948 /* Wi-Fi Protected Access (WPA) Information Element */
949 if (tag_val_off + 6 <= tag_len && !memcmp(tag_val, WPA_OUI"\x01", 4)) {
950 g_snprintf(out_buff, SHORT_STR, "WPA IE, type %u, version %u",
951 tag_val[tag_val_off + 3], pletohs(&tag_val[tag_val_off + 4]));
952 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
955 if (tag_val_off + 4 <= tag_len) {
956 /* multicast cipher suite */
957 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
958 g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
959 wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
960 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
963 /* unicast cipher suites */
964 if (tag_val_off + 2 <= tag_len) {
965 g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u",
966 pletohs(tag_val + tag_val_off));
967 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
971 while (tag_val_off + 4 <= tag_len) {
972 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
973 g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
974 i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
975 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
983 /* authenticated key management suites */
984 if (tag_val_off + 2 <= tag_len) {
985 g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u",
986 pletohs(tag_val + tag_val_off));
987 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
991 while (tag_val_off + 4 <= tag_len) {
992 if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
993 g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
994 i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
995 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1007 if (tag_val_off < tag_len)
1008 proto_tree_add_string(tree, tag_interpretation, tvb,
1009 offset, tag_len - tag_val_off, "Not interpreted");
1010 proto_item_append_text(ietree, ": WPA");
1011 } else if (tag_val_off + 7 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x00", 5)) {
1012 /* Wireless Multimedia Enhancements (WME) Information Element */
1013 g_snprintf(out_buff, SHORT_STR, "WME IE: type %u, subtype %u, version %u, parameter set %u",
1014 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
1015 tag_val[tag_val_off + 6]);
1016 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
1017 proto_item_append_text(ietree, ": WME");
1018 } else if (tag_val_off + 24 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x01", 5)) {
1019 /* Wireless Multimedia Enhancements (WME) Parameter Element */
1020 g_snprintf(out_buff, SHORT_STR, "WME PE: type %u, subtype %u, version %u, parameter set %u",
1021 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
1022 tag_val[tag_val_off + 6]);
1023 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
1026 for (i = 0; i < 4; i++) {
1027 g_snprintf(out_buff, SHORT_STR, "WME AC Parameters: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
1028 (tag_val[tag_val_off] & 0x60) >> 5,
1029 wme_acs[(tag_val[tag_val_off] & 0x60) >> 5],
1030 (tag_val[tag_val_off] & 0x10) ? "" : "not ",
1031 tag_val[tag_val_off] & 0x0f,
1032 tag_val[tag_val_off + 1] & 0x0f,
1033 (tag_val[tag_val_off + 1] & 0xf0) >> 4,
1034 tvb_get_letohs(tvb, offset + 2));
1035 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1039 proto_item_append_text(ietree, ": WME");
1040 } else if (tag_val_off + 56 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x02", 5)) {
1041 /* Wireless Multimedia Enhancements (WME) TSPEC Element */
1042 guint16 ts_info, msdu_size, surplus_bandwidth;
1043 const char *direction[] = { "Uplink", "Downlink", "Reserved", "Bi-directional" };
1044 const value_string fields[] = {
1045 {12, "Minimum Service Interval"},
1046 {16, "Maximum Service Interval"},
1047 {20, "Inactivity Interval"},
1048 {24, "Service Start Time"},
1049 {28, "Minimum Data Rate"},
1050 {32, "Mean Data Rate"},
1051 {36, "Maximum Burst Size"},
1052 {40, "Minimum PHY Rate"},
1053 {44, "Peak Data Rate"},
1054 {48, "Delay Bound"},
1059 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: type %u, subtype %u, version %u",
1060 tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5]);
1061 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
1065 ts_info = tvb_get_letohs(tvb, offset);
1066 g_snprintf(out_buff, SHORT_STR, "WME TS Info: Priority %u (%s) (%s), Contention-based access %sset, %s",
1067 (ts_info >> 11) & 0x7, qos_tags[(ts_info >> 11) & 0x7], qos_acs[(ts_info >> 11) & 0x7],
1068 (ts_info & 0x0080) ? "" : "not ",
1069 direction[(ts_info >> 5) & 0x3]);
1070 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1074 msdu_size = tvb_get_letohs(tvb, offset);
1075 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s MSDU Size %u",
1076 (msdu_size & 0x8000) ? "Fixed" : "Nominal", msdu_size & 0x7fff);
1077 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1081 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Maximum MSDU Size %u", tvb_get_letohs(tvb, offset));
1082 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1086 while ((field = val_to_str(tag_val_off, fields, "Unknown"))) {
1087 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s %u", field, tvb_get_letohl(tvb, offset));
1088 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1091 if (tag_val_off == 52)
1095 surplus_bandwidth = tvb_get_letohs(tvb, offset);
1096 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Surplus Bandwidth Allowance Factor %u.%u",
1097 (surplus_bandwidth >> 13) & 0x7, (surplus_bandwidth & 0x1fff));
1101 g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Medium Time %u", tvb_get_letohs(tvb, offset));
1102 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1105 proto_item_append_text(ietree, ": WME");
1110 dissect_vendor_ie_rsn(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
1111 int offset, guint32 tag_len, const guint8 *tag_val)
1113 guint32 tag_val_off = 0;
1114 char out_buff[SHORT_STR], *pos;
1117 if (tag_val_off + 4 <= tag_len && !memcmp(tag_val, RSN_OUI"\x04", 4)) {
1118 /* IEEE 802.11i / Key Data Encapsulation / Data Type=4 - PMKID.
1119 * This is only used within EAPOL-Key frame Key Data. */
1121 pos += snprintf(pos, out_buff + SHORT_STR - pos, "RSN PMKID: ");
1122 if (tag_len - 4 != PMKID_LEN) {
1123 pos += snprintf(pos, out_buff + SHORT_STR - pos,
1124 "(invalid PMKID len=%d, expected 16) ", tag_len - 4);
1126 for (i = 0; i < tag_len - 4; i++) {
1127 pos += snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
1128 tag_val[tag_val_off + 4 + i]);
1130 proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1133 proto_item_append_text(ietree, ": RSN");
1137 dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
1138 guint32 tag_len, const guint8 *tag_val)
1140 guint32 tag_val_off = 0;
1142 char out_buff[SHORT_STR];
1144 proto_item *cap_item;
1145 proto_tree *cap_tree;
1147 if (tag_val_off + 2 > tag_len) {
1148 proto_tree_add_string(tree, tag_interpretation, tvb, offset, tag_len,
1153 g_snprintf(out_buff, SHORT_STR, "RSN IE, version %u",
1154 pletohs(&tag_val[tag_val_off]));
1155 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1160 if (tag_val_off + 4 > tag_len)
1163 /* multicast cipher suite */
1164 if (!memcmp(&tag_val[tag_val_off], RSN_OUI, 3)) {
1165 g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
1166 wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1167 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1172 if (tag_val_off + 2 > tag_len)
1175 /* unicast cipher suites */
1176 count = pletohs(tag_val + tag_val_off);
1177 g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u", count);
1178 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1182 while (tag_val_off + 4 <= tag_len && i <= count) {
1183 if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
1185 g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
1186 i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
1187 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1193 if (i <= count || tag_val_off + 2 > tag_len)
1196 /* authenticated key management suites */
1197 count = pletohs(tag_val + tag_val_off);
1198 g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u", count);
1199 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1203 while (tag_val_off + 4 <= tag_len && i <= count) {
1204 if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
1206 g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
1207 i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
1208 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
1214 if (i <= count || tag_val_off + 2 > tag_len)
1217 rsn_capab = pletohs(&tag_val[tag_val_off]);
1218 g_snprintf(out_buff, SHORT_STR, "RSN Capabilities 0x%04x", rsn_capab);
1219 cap_item = proto_tree_add_uint_format(tree, rsn_cap, tvb,
1220 offset, 2, rsn_capab,
1221 "RSN Capabilities: 0x%04X", rsn_capab);
1222 cap_tree = proto_item_add_subtree(cap_item, ett_rsn_cap_tree);
1223 proto_tree_add_boolean(cap_tree, rsn_cap_preauth, tvb, offset, 2,
1225 proto_tree_add_boolean(cap_tree, rsn_cap_no_pairwise, tvb, offset, 2,
1227 proto_tree_add_uint(cap_tree, rsn_cap_ptksa_replay_counter, tvb, offset, 2,
1229 proto_tree_add_uint(cap_tree, rsn_cap_gtksa_replay_counter, tvb, offset, 2,
1234 if (tag_val_off + 2 > tag_len)
1237 count = pletohs(tag_val + tag_val_off);
1238 g_snprintf(out_buff, SHORT_STR, "# of PMKIDs: %u", count);
1239 proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
1243 /* PMKID List (16 * n octets) */
1244 for (i = 0; i < count; i++) {
1246 if (tag_val_off + PMKID_LEN > tag_len)
1249 pos += snprintf(pos, out_buff + SHORT_STR - pos, "PMKID %u: ", i);
1250 for (j = 0; j < PMKID_LEN; j++) {
1251 pos += snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
1252 tag_val[tag_val_off + j]);
1254 proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1255 PMKID_LEN, out_buff);
1256 offset += PMKID_LEN;
1257 tag_val_off += PMKID_LEN;
1261 if (tag_val_off < tag_len)
1262 proto_tree_add_string(tree, tag_interpretation, tvb, offset,
1263 tag_len - tag_val_off, "Not interpreted");
1266 /* ************************************************************************* */
1267 /* Dissect and add tagged (optional) fields to proto tree */
1268 /* ************************************************************************* */
1270 static const value_string tag_num_vals[] = {
1271 { TAG_SSID, "SSID parameter set" },
1272 { TAG_SUPP_RATES, "Supported Rates" },
1273 { TAG_FH_PARAMETER, "FH Parameter set" },
1274 { TAG_DS_PARAMETER, "DS Parameter set" },
1275 { TAG_CF_PARAMETER, "CF Parameter set" },
1276 { TAG_TIM, "(TIM) Traffic Indication Map" },
1277 { TAG_IBSS_PARAMETER, "IBSS Parameter set" },
1278 { TAG_COUNTRY_INFO, "Country Information" },
1279 { TAG_FH_HOPPING_PARAMETER, "Hopping Pattern Parameters" },
1280 { TAG_CHALLENGE_TEXT, "Challenge text" },
1281 { TAG_ERP_INFO, "ERP Information" },
1282 { TAG_ERP_INFO_OLD, "ERP Information" },
1283 { TAG_RSN_IE, "RSN Information" },
1284 { TAG_EXT_SUPP_RATES, "Extended Supported Rates" },
1285 { TAG_CISCO_UNKNOWN_1, "Cisco Unknown 1 + Device Name" },
1286 { TAG_CISCO_UNKNOWN_2, "Cisco Unknown 2" },
1287 { TAG_VENDOR_SPECIFIC_IE, "Vendor Specific" },
1288 { TAG_SYMBOL_PROPRIETARY, "Symbol Proprietary"},
1289 { TAG_AGERE_PROPRIETARY, "Agere Proprietary"},
1290 { TAG_REQUEST, "Request"},
1291 { TAG_QBSS_LOAD, "QBSS Load Element"},
1292 { TAG_EDCA_PARAM_SET, "EDCA Parameter Set"},
1293 { TAG_TRAF_SPEC, "Traffic Specification"},
1294 { TAG_TRAF_CLASS, "Traffic Classification"},
1295 { TAG_SCHEDULE, "Schedule"},
1296 { TAG_TS_DELAY, "TS Delay"},
1297 { TAG_TCLAS_PROCESS, "TCLAS Processing"},
1298 { TAG_QOS_CAPABILITY, "QoS Capability"},
1299 { TAG_POWER_CONSTRAINT, "Power Constraint"},
1300 { TAG_POWER_CAPABILITY, "Power Capability"},
1301 { TAG_TPC_REQUEST, "TPC Request"},
1302 { TAG_TPC_REPORT, "TPC Report"},
1303 { TAG_SUPPORTED_CHANNELS, "Supported Channels"},
1304 { TAG_CHANNEL_SWITCH_ANN, "Channel Switch Announcement"},
1305 { TAG_MEASURE_REQ, "Measurement Request"},
1306 { TAG_MEASURE_REP, "Measurement Report"},
1307 { TAG_QUIET, "Quiet"},
1308 { TAG_IBSS_DFS, "IBSS DFS"},
1312 static const value_string environment_vals[] = {
1314 { 0x4f, "Outdoor" },
1319 static int beacon_padding = 0; /* beacon padding bug */
1321 add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int offset)
1325 const guint8 *tag_data_ptr;
1326 guint32 tag_no, tag_len;
1329 char out_buff[SHORT_STR];
1330 char print_buff[SHORT_STR];
1331 proto_tree * orig_tree=tree;
1334 tag_no = tvb_get_guint8(tvb, offset);
1335 tag_len = tvb_get_guint8(tvb, offset + 1);
1337 ti=proto_tree_add_text(orig_tree,tvb,offset,tag_len+2,"%s",
1338 val_to_str(tag_no, tag_num_vals,
1339 (tag_no >= 17 && tag_no <= 31) ?
1340 "Reserved for challenge text" : "Reserved tag number" ));
1341 tree=proto_item_add_subtree(ti,ett_80211_mgt_ie);
1343 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
1344 "Tag Number: %u (%s)",
1346 val_to_str(tag_no, tag_num_vals,
1347 (tag_no >= 17 && tag_no <= 31) ?
1348 "Reserved for challenge text" :
1349 "Reserved tag number"));
1350 proto_tree_add_uint (tree, (tag_no==TAG_TIM ? tim_length : tag_length), tvb, offset + 1, 1, tag_len);
1356 if(beacon_padding == 0) /* padding bug */
1360 ssid = tvb_get_ephemeral_string(tvb, offset + 2, tag_len);
1361 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1363 if (check_col (pinfo->cinfo, COL_INFO)) {
1365 col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: \"%s\"",
1366 format_text(ssid, tag_len));
1368 col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: Broadcast");
1372 proto_item_append_text(ti, ": \"%s\"",
1373 format_text(ssid, tag_len));
1375 proto_item_append_text(ti, ": Broadcast");
1377 beacon_padding++; /* padding bug */
1381 case TAG_SUPP_RATES:
1382 case TAG_EXT_SUPP_RATES:
1383 tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
1384 for (i = 0, n = 0; i < tag_len && n < SHORT_STR; i++) {
1385 ret = snprintf (print_buff + n, SHORT_STR - n, "%2.1f%s ",
1386 (tag_data_ptr[i] & 0x7F) * 0.5,
1387 (tag_data_ptr[i] & 0x80) ? "(B)" : "");
1388 if (ret == -1 || ret >= SHORT_STR - n) {
1389 /* Some versions of snprintf return -1 if they'd truncate
1390 the output. Others return <buf_size> or greater. */
1395 g_snprintf (out_buff, SHORT_STR, "Supported rates: %s [Mbit/sec]", print_buff);
1396 out_buff[SHORT_STR-1] = '\0';
1397 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1399 proto_item_append_text(ti, ": %s", print_buff);
1402 case TAG_FH_PARAMETER:
1405 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 5",
1409 g_snprintf (out_buff, SHORT_STR,
1410 "Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, Hop Index %2d",
1411 tvb_get_letohs(tvb, offset + 2),
1412 tvb_get_guint8(tvb, offset + 4),
1413 tvb_get_guint8(tvb, offset + 5),
1414 tvb_get_guint8(tvb, offset + 6));
1415 out_buff[SHORT_STR-1] = '\0';
1416 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1420 case TAG_DS_PARAMETER:
1423 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
1427 g_snprintf (out_buff, SHORT_STR, "Current Channel: %u",
1428 tvb_get_guint8(tvb, offset + 2));
1429 out_buff[SHORT_STR-1] = '\0';
1430 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1432 proto_item_append_text(ti, ": %s", out_buff);
1435 case TAG_CF_PARAMETER:
1438 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 6",
1442 g_snprintf (out_buff, SHORT_STR, "CFP count: %u",
1443 tvb_get_guint8(tvb, offset + 2));
1444 out_buff[SHORT_STR-1] = '\0';
1445 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2,
1446 1, out_buff, "%s", out_buff);
1447 g_snprintf (out_buff, SHORT_STR, "CFP period: %u",
1448 tvb_get_guint8(tvb, offset + 3));
1449 out_buff[SHORT_STR-1] = '\0';
1450 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 3,
1451 1, out_buff, "%s", out_buff);
1452 g_snprintf (out_buff, SHORT_STR, "CFP max duration: %u",
1453 tvb_get_letohs(tvb, offset + 4));
1454 out_buff[SHORT_STR-1] = '\0';
1455 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 4,
1456 2, out_buff, "%s", out_buff);
1457 g_snprintf (out_buff, SHORT_STR, "CFP Remaining: %u",
1458 tvb_get_letohs(tvb, offset + 6));
1459 out_buff[SHORT_STR-1] = '\0';
1460 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 6,
1461 2, out_buff, "%s", out_buff);
1462 proto_item_append_text(ti, ": CFP count %u, CFP period %u, CFP max duration %u, "
1464 tvb_get_guint8(tvb, offset + 2),
1465 tvb_get_guint8(tvb, offset + 3),
1466 tvb_get_letohs(tvb, offset + 4),
1467 tvb_get_letohs(tvb, offset + 6));
1473 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 4",
1483 proto_tree_add_item(tree, tim_dtim_count, tvb,
1484 offset + 2, 1, TRUE);
1485 proto_tree_add_item(tree, tim_dtim_period, tvb,
1486 offset + 3, 1, TRUE);
1487 proto_item_append_text(ti, ": DTIM %u of %u bitmap",
1488 tvb_get_guint8(tvb, offset + 2),
1489 tvb_get_guint8(tvb, offset + 3));
1491 bmapctl = tvb_get_guint8(tvb, offset + 4);
1492 bmapoff = bmapctl>>1;
1493 proto_tree_add_uint_format(tree, tim_bmapctl, tvb,
1494 offset + 4, 1, bmapctl,
1495 "Bitmap Control: 0x%02X (mcast:%u, bitmap offset %u)",
1496 bmapctl, bmapctl&1, bmapoff);
1498 bmaplen = tag_len - 3;
1499 bmap = tvb_get_ptr(tvb, offset + 5, bmaplen);
1500 if (bmaplen==1 && 0==bmap[0] && !(bmapctl&1)) {
1501 proto_item_append_text(ti, " empty");
1504 proto_item_append_text(ti, " mcast");
1507 if (bmaplen>1 || bmap[0]) {
1508 int len=snprintf (out_buff, SHORT_STR,
1509 "Bitmap: traffic for AID's:");
1511 for (i=0;i<bmaplen*8;i++) {
1512 if (bmap[i/8] & (1<<(i%8))) {
1513 int aid=i+bmapoff*8;
1514 len+=snprintf (out_buff+len, SHORT_STR-len," %u", aid);
1515 proto_item_append_text(ti, " %u", aid);
1516 if (len>=SHORT_STR) {
1521 out_buff[SHORT_STR-1] = '\0';
1522 proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 5,
1523 bmaplen, out_buff, "%s", out_buff);
1528 case TAG_IBSS_PARAMETER:
1531 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
1535 g_snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
1536 tvb_get_letohs(tvb, offset + 2));
1537 out_buff[SHORT_STR-1] = '\0';
1538 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1540 proto_item_append_text(ti, ": %s", out_buff);
1543 case TAG_COUNTRY_INFO: /* IEEE 802.11d-2001 and IEEE 802.11j-2004 */
1549 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 3",
1553 tvb_memcpy(tvb, ccode, offset + 2, 2);
1555 g_snprintf (out_buff, SHORT_STR, "Country Code: %s, %s Environment",
1556 format_text(ccode, 2),
1557 val_to_str(tvb_get_guint8(tvb, offset + 4), environment_vals,"Unknown (0x%02x)"));
1558 out_buff[SHORT_STR-1] = '\0';
1559 proto_item_append_text(ti, ": %s", out_buff);
1560 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,3, out_buff);
1562 for (i = 3; (i + 3) <= tag_len; i += 3)
1564 guint8 val1, val2, val3;
1565 val1 = tvb_get_guint8(tvb, offset + 2 + i);
1566 val2 = tvb_get_guint8(tvb, offset + 3 + i);
1567 val3 = tvb_get_guint8(tvb, offset + 4 + i);
1569 if (val1 <= 200) { /* 802.11d */
1570 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
1571 " Start Channel: %u, Channels: %u, Max TX Power: %d dBm",
1572 val1, val2, (gint) val3);
1573 } else { /* 802.11j */
1574 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
1575 " Reg Extension Id: %u, Regulatory Class: %u, Coverage Class: %u",
1582 case TAG_FH_HOPPING_PARAMETER:
1585 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
1589 g_snprintf (out_buff, SHORT_STR, "Prime Radix: %u, Number of Channels: %u",
1590 tvb_get_guint8(tvb, offset + 2),
1591 tvb_get_guint8(tvb, offset + 3));
1592 out_buff[SHORT_STR-1] = '\0';
1593 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2, tag_len, out_buff);
1594 proto_item_append_text(ti, ": %s", out_buff);
1597 case TAG_CHALLENGE_TEXT:
1598 g_snprintf (out_buff, SHORT_STR, "Challenge text: %s",
1599 tvb_bytes_to_str(tvb, offset + 2, tag_len));
1600 out_buff[SHORT_STR-1] = '\0';
1601 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1606 case TAG_ERP_INFO_OLD:
1612 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
1616 erp_info = tvb_get_guint8 (tvb, offset + 2);
1617 g_snprintf (print_buff, SHORT_STR, "%sNon-ERP STAs, %suse protection, %s preambles",
1618 erp_info & 0x01 ? "" : "no ",
1619 erp_info & 0x02 ? "" : "do not ",
1620 erp_info & 0x04 ? "short or long": "long");
1621 print_buff[SHORT_STR-1] = '\0';
1622 g_snprintf (out_buff, SHORT_STR,
1623 "ERP info: 0x%x (%s)",erp_info,print_buff);
1624 out_buff[SHORT_STR-1] = '\0';
1625 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1627 proto_item_append_text(ti, ": %s", print_buff);
1631 case TAG_CISCO_UNKNOWN_1:
1632 /* The Name of the sending device starts at offset 10 and is up to
1633 15 or 16 bytes in length, \0 padded */
1636 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 26",
1640 g_snprintf (out_buff, SHORT_STR, "%.16s",
1641 tvb_format_stringzpad(tvb, offset + 12, 16));
1642 out_buff[SHORT_STR-1] = '\0';
1643 proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 2,
1644 tag_len, "", "Tag interpretation: Unknown + Name: %s",
1646 if (check_col (pinfo->cinfo, COL_INFO)) {
1647 col_append_fstr(pinfo->cinfo, COL_INFO, ", Name: \"%s\"", out_buff);
1651 case TAG_VENDOR_SPECIFIC_IE:
1652 tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
1654 oui = tvb_get_ntoh24(tvb, offset + 2);
1655 tag_val = tvb_get_ptr(tvb, offset + 2, tag_len);
1656 #define WPAWME_OUI 0x0050F2
1657 #define RSNOUI_VAL 0x000FAC
1660 dissect_vendor_ie_wpawme(ti, tree, tvb, offset + 2, tag_len, tag_val);
1663 dissect_vendor_ie_rsn(ti, tree, tvb, offset + 2, tag_len, tag_val);
1666 proto_tree_add_bytes_format (tree, tag_oui, tvb, offset + 2, 3,
1667 "", "Vendor: %s", get_manuf_name(tag_val));
1668 proto_item_append_text(ti, ": %s", get_manuf_name(tag_val));
1669 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 5,
1670 tag_len - 3, "Not interpreted");
1678 dissect_rsn_ie(tree, tvb, offset + 2, tag_len,
1679 tvb_get_ptr (tvb, offset + 2, tag_len));
1683 tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
1684 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1685 tag_len, "Not interpreted");
1686 proto_item_append_text(ti, ": Tag %u Len %u", tag_no, tag_len);
1694 ieee_80211_add_tagged_parameters (tvbuff_t * tvb, int offset, packet_info * pinfo,
1695 proto_tree * tree, int tagged_parameters_len)
1699 beacon_padding = 0; /* this is for the beacon padding confused with ssid fix */
1700 while (tagged_parameters_len > 0) {
1701 if ((next_len=add_tagged_field (pinfo, tree, tvb, offset))==0)
1703 if (next_len > tagged_parameters_len) {
1704 /* XXX - flag this as an error? */
1705 next_len = tagged_parameters_len;
1708 tagged_parameters_len -= next_len;
1712 /* ************************************************************************* */
1713 /* Dissect 802.11 management frame */
1714 /* ************************************************************************* */
1716 dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
1719 proto_item *ti = NULL;
1720 proto_tree *mgt_tree;
1721 proto_tree *fixed_tree;
1722 proto_tree *tagged_tree;
1724 int tagged_parameter_tree_len;
1728 CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
1730 ti = proto_tree_add_item (tree, proto_wlan_mgt, tvb, 0, -1, FALSE);
1731 mgt_tree = proto_item_add_subtree (ti, ett_80211_mgt);
1733 switch (COMPOSE_FRAME_TYPE(fcf))
1737 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
1738 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1739 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
1740 offset = 4; /* Size of fixed fields */
1742 tagged_parameter_tree_len =
1743 tvb_reported_length_remaining(tvb, offset);
1744 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1745 tagged_parameter_tree_len);
1746 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1747 tagged_parameter_tree_len);
1751 case MGT_ASSOC_RESP:
1752 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1753 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1754 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
1755 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
1756 offset = 6; /* Size of fixed fields */
1758 tagged_parameter_tree_len =
1759 tvb_reported_length_remaining(tvb, offset);
1760 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1761 tagged_parameter_tree_len);
1762 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1763 tagged_parameter_tree_len);
1767 case MGT_REASSOC_REQ:
1768 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
1769 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1770 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
1771 add_fixed_field (fixed_tree, tvb, 4, FIELD_CURRENT_AP_ADDR);
1772 offset = 10; /* Size of fixed fields */
1774 tagged_parameter_tree_len =
1775 tvb_reported_length_remaining(tvb, offset);
1776 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1777 tagged_parameter_tree_len);
1778 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1779 tagged_parameter_tree_len);
1782 case MGT_REASSOC_RESP:
1783 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1784 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
1785 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
1786 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
1787 offset = 6; /* Size of fixed fields */
1789 tagged_parameter_tree_len =
1790 tvb_reported_length_remaining(tvb, offset);
1791 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1792 tagged_parameter_tree_len);
1793 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1794 tagged_parameter_tree_len);
1800 tagged_parameter_tree_len =
1801 tvb_reported_length_remaining(tvb, offset);
1802 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1803 tagged_parameter_tree_len);
1804 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1805 tagged_parameter_tree_len);
1809 case MGT_PROBE_RESP:
1810 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
1811 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
1812 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
1813 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
1814 offset = 12; /* Size of fixed fields */
1816 tagged_parameter_tree_len =
1817 tvb_reported_length_remaining(tvb, offset);
1818 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1819 tagged_parameter_tree_len);
1820 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1821 tagged_parameter_tree_len);
1825 case MGT_BEACON: /* Dissect protocol payload fields */
1826 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
1827 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
1828 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
1829 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
1830 offset = 12; /* Size of fixed fields */
1832 tagged_parameter_tree_len =
1833 tvb_reported_length_remaining(tvb, offset);
1834 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1835 tagged_parameter_tree_len);
1836 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1837 tagged_parameter_tree_len);
1846 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1847 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
1851 case MGT_AUTHENTICATION:
1852 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1853 add_fixed_field (fixed_tree, tvb, 0, FIELD_AUTH_ALG);
1854 add_fixed_field (fixed_tree, tvb, 2, FIELD_AUTH_TRANS_SEQ);
1855 add_fixed_field (fixed_tree, tvb, 4, FIELD_STATUS_CODE);
1856 offset = 6; /* Size of fixed fields */
1858 tagged_parameter_tree_len =
1859 tvb_reported_length_remaining(tvb, offset);
1860 if (tagged_parameter_tree_len != 0)
1862 tagged_tree = get_tagged_parameter_tree (mgt_tree,
1865 tagged_parameter_tree_len);
1866 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1867 tagged_parameter_tree_len);
1872 case MGT_DEAUTHENTICATION:
1873 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1874 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
1879 switch (tvb_get_guint8(tvb, 0))
1882 case CAT_SPECTRUM_MGMT:
1883 switch (tvb_get_guint8(tvb, 1))
1885 case SM_ACTION_MEASUREMENT_REQUEST:
1886 case SM_ACTION_MEASUREMENT_REPORT:
1887 case SM_ACTION_TPC_REQUEST:
1888 case SM_ACTION_TPC_REPORT:
1889 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
1890 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
1891 add_fixed_field (fixed_tree, tvb, 1, FIELD_ACTION_CODE);
1892 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
1893 offset = 3; /* Size of fixed fields */
1896 case SM_ACTION_CHAN_SWITCH_ANNC:
1897 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1898 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
1899 offset = 2; /* Size of fixed fields */
1903 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1904 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
1905 offset = 2; /* Size of fixed fields */
1910 case CAT_MGMT_NOTIFICATION: /* Management notification frame */
1911 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
1912 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
1913 add_fixed_field (fixed_tree, tvb, 1, FIELD_WME_ACTION_CODE);
1914 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
1915 add_fixed_field (fixed_tree, tvb, 3, FIELD_WME_STATUS_CODE);
1916 offset = 4; /* Size of fixed fields */
1920 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 1);
1921 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
1922 offset = 1; /* Size of fixed fields */
1926 tagged_parameter_tree_len =
1927 tvb_reported_length_remaining(tvb, offset);
1928 if (tagged_parameter_tree_len != 0)
1930 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
1931 tagged_parameter_tree_len);
1932 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
1933 tagged_parameter_tree_len);
1940 set_src_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
1942 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1943 col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "%s (%s)",
1944 get_ether_name(addr), type);
1945 if (check_col(pinfo->cinfo, COL_UNRES_DL_SRC))
1946 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s",
1947 ether_to_str(addr));
1951 set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
1953 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1954 col_add_fstr(pinfo->cinfo, COL_RES_DL_DST, "%s (%s)",
1955 get_ether_name(addr), type);
1956 if (check_col(pinfo->cinfo, COL_UNRES_DL_DST))
1957 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s",
1958 ether_to_str(addr));
1967 /* ************************************************************************* */
1968 /* Dissect 802.11 frame */
1969 /* ************************************************************************* */
1971 dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
1972 proto_tree * tree, gboolean fixed_length_header,
1973 gboolean has_radio_information, gint fcs_len,
1974 gboolean wlan_broken_fc)
1976 guint16 fcf, flags, frame_type_subtype;
1977 guint16 seq_control;
1978 guint32 seq_number, frag_number;
1979 gboolean more_frags;
1980 const guint8 *src = NULL;
1981 const guint8 *dst = NULL;
1982 const guint8 *bssid = NULL;
1983 proto_item *ti = NULL;
1984 proto_item *flag_item;
1985 proto_item *fc_item;
1986 proto_tree *hdr_tree = NULL;
1987 proto_tree *flag_tree;
1988 proto_tree *fc_tree;
1991 gint len, reported_len, ivlen;
1992 gboolean save_fragmented;
1993 tvbuff_t *volatile next_tvb = NULL;
1995 volatile encap_t encap_type;
1996 guint8 octet1, octet2;
1997 char out_buff[SHORT_STR];
2000 wlan_hdr *volatile whdr;
2001 static wlan_hdr whdrs[4];
2005 if (check_col (pinfo->cinfo, COL_PROTOCOL))
2006 col_set_str (pinfo->cinfo, COL_PROTOCOL, "IEEE 802.11");
2007 if (check_col (pinfo->cinfo, COL_INFO))
2008 col_clear (pinfo->cinfo, COL_INFO);
2010 /* Add the radio information, if present, to the column information */
2011 if (has_radio_information) {
2012 if (check_col(pinfo->cinfo, COL_TX_RATE)) {
2013 col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u",
2014 pinfo->pseudo_header->ieee_802_11.data_rate / 2,
2015 pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
2017 if (check_col(pinfo->cinfo, COL_RSSI)) {
2018 /* XX - this is a percentage, not a dBm or normalized or raw RSSI */
2019 col_add_fstr(pinfo->cinfo, COL_RSSI, "%u",
2020 pinfo->pseudo_header->ieee_802_11.signal_level);
2024 fcf = tvb_get_letohs (tvb, 0);
2025 if (wlan_broken_fc) {
2027 fcf = ((fcf & 0xff) << 8) | (((fcf & 0xff00) >> 8) & 0xff);
2029 if (fixed_length_header)
2030 hdr_len = DATA_LONG_HDR_LEN;
2032 hdr_len = find_header_length (fcf);
2033 frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
2035 if (check_col (pinfo->cinfo, COL_PROTOCOL))
2036 col_set_str (pinfo->cinfo, COL_PROTOCOL,
2037 val_to_str(frame_type_subtype, frame_type_subtype_vals,
2038 "Unrecognized (Reserved frame)"));
2040 if (check_col (pinfo->cinfo, COL_INFO))
2041 col_set_str (pinfo->cinfo, COL_INFO,
2042 val_to_str(frame_type_subtype, frame_type_subtype_vals,
2043 "Unrecognized (Reserved frame)"));
2045 flags = COOK_FLAGS (fcf);
2046 more_frags = HAVE_FRAGMENTS (flags);
2049 /* Add the radio information, if present, and the FC to the current tree */
2052 ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
2054 hdr_tree = proto_item_add_subtree (ti, ett_80211);
2056 if (has_radio_information) {
2057 proto_tree_add_uint_format(hdr_tree, hf_data_rate,
2059 pinfo->pseudo_header->ieee_802_11.data_rate,
2060 "Data Rate: %u.%u Mb/s",
2061 pinfo->pseudo_header->ieee_802_11.data_rate / 2,
2062 pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
2064 proto_tree_add_uint(hdr_tree, hf_channel,
2066 pinfo->pseudo_header->ieee_802_11.channel);
2068 proto_tree_add_uint_format(hdr_tree, hf_signal_strength,
2070 pinfo->pseudo_header->ieee_802_11.signal_level,
2071 "Signal Strength: %u%%",
2072 pinfo->pseudo_header->ieee_802_11.signal_level);
2075 proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
2077 wlan_broken_fc?1:0, 1,
2078 frame_type_subtype);
2080 fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb,
2083 "Frame Control: 0x%04X (%s)",
2084 fcf, wlan_broken_fc?"Swapped":"Normal");
2086 fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
2089 proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb,
2090 wlan_broken_fc?1:0, 1,
2091 COOK_PROT_VERSION (fcf));
2093 proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb,
2094 wlan_broken_fc?1:0, 1,
2095 COOK_FRAME_TYPE (fcf));
2097 proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
2099 wlan_broken_fc?1:0, 1,
2100 COOK_FRAME_SUBTYPE (fcf));
2103 proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb,
2104 wlan_broken_fc?0:1, 1,
2105 flags, "Flags: 0x%X", flags);
2107 flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
2109 proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb,
2110 wlan_broken_fc?0:1, 1,
2111 COOK_DS_STATUS (flags));
2112 proto_tree_add_boolean_hidden (flag_tree, hf_fc_to_ds, tvb, 1, 1,
2114 proto_tree_add_boolean_hidden (flag_tree, hf_fc_from_ds, tvb, 1, 1,
2117 proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb,
2118 wlan_broken_fc?0:1, 1,
2121 proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb,
2122 wlan_broken_fc?0:1, 1, flags);
2124 proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb,
2125 wlan_broken_fc?0:1, 1, flags);
2127 proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb,
2128 wlan_broken_fc?0:1, 1,
2131 proto_tree_add_boolean (flag_tree, hf_fc_protected, tvb,
2132 wlan_broken_fc?0:1, 1, flags);
2134 proto_tree_add_boolean (flag_tree, hf_fc_order, tvb,
2135 wlan_broken_fc?0:1, 1, flags);
2137 if (frame_type_subtype == CTRL_PS_POLL)
2138 proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
2139 COOK_ASSOC_ID(tvb_get_letohs(tvb,2)));
2142 proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
2143 tvb_get_letohs (tvb, 2));
2147 * Decode the part of the frame header that isn't the same for all
2154 switch (COOK_FRAME_TYPE (fcf))
2159 * All management frame types have the same header.
2161 src = tvb_get_ptr (tvb, 10, 6);
2162 dst = tvb_get_ptr (tvb, 4, 6);
2164 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
2165 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
2166 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
2167 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
2170 SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, tvb_get_ptr(tvb, 16,6));
2171 SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
2172 SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
2173 whdr->type = frame_type_subtype;
2175 seq_control = tvb_get_letohs(tvb, 22);
2176 frag_number = COOK_FRAGMENT_NUMBER(seq_control);
2177 seq_number = COOK_SEQUENCE_NUMBER(seq_control);
2179 if (check_col (pinfo->cinfo, COL_INFO))
2181 col_append_fstr(pinfo->cinfo, COL_INFO,
2182 ",SN=%d", seq_number);
2184 col_append_fstr(pinfo->cinfo, COL_INFO,
2185 ",FN=%d",frag_number);
2190 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2192 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2194 /* add items for wlan.addr filter */
2195 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2196 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2198 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
2199 tvb_get_ptr (tvb, 16, 6));
2201 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2204 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2210 switch (frame_type_subtype)
2214 src = tvb_get_ptr (tvb, 10, 6);
2215 dst = tvb_get_ptr (tvb, 4, 6);
2217 set_src_addr_cols(pinfo, src, "BSSID");
2218 set_dst_addr_cols(pinfo, dst, "BSSID");
2222 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6, dst);
2224 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
2230 src = tvb_get_ptr (tvb, 10, 6);
2231 dst = tvb_get_ptr (tvb, 4, 6);
2233 set_src_addr_cols(pinfo, src, "TA");
2234 set_dst_addr_cols(pinfo, dst, "RA");
2238 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2240 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
2246 dst = tvb_get_ptr (tvb, 4, 6);
2248 set_dst_addr_cols(pinfo, dst, "RA");
2251 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2255 case CTRL_ACKNOWLEDGEMENT:
2256 dst = tvb_get_ptr (tvb, 4, 6);
2258 set_dst_addr_cols(pinfo, dst, "RA");
2261 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2266 src = tvb_get_ptr (tvb, 10, 6);
2267 dst = tvb_get_ptr (tvb, 4, 6);
2269 set_src_addr_cols(pinfo, src, "BSSID");
2270 set_dst_addr_cols(pinfo, dst, "RA");
2274 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2275 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
2280 case CTRL_CFP_ENDACK:
2281 src = tvb_get_ptr (tvb, 10, 6);
2282 dst = tvb_get_ptr (tvb, 4, 6);
2284 set_src_addr_cols(pinfo, src, "BSSID");
2285 set_dst_addr_cols(pinfo, dst, "RA");
2289 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2291 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
2295 case CTRL_BLOCK_ACK_REQ:
2297 src = tvb_get_ptr (tvb, 10, 6);
2298 dst = tvb_get_ptr (tvb, 4, 6);
2300 set_src_addr_cols(pinfo, src, "TA");
2301 set_dst_addr_cols(pinfo, dst, "RA");
2305 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
2307 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
2313 case CTRL_BLOCK_ACK:
2315 src = tvb_get_ptr (tvb, 10, 6);
2316 dst = tvb_get_ptr (tvb, 4, 6);
2318 set_src_addr_cols(pinfo, src, "TA");
2319 set_dst_addr_cols(pinfo, dst, "RA");
2323 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
2325 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
2327 /* TODO BAR Format */
2334 addr_type = COOK_ADDR_SELECTOR (fcf);
2336 /* In order to show src/dst address we must always do the following */
2341 src = tvb_get_ptr (tvb, 10, 6);
2342 dst = tvb_get_ptr (tvb, 4, 6);
2343 bssid = tvb_get_ptr (tvb, 16, 6);
2348 src = tvb_get_ptr (tvb, 16, 6);
2349 dst = tvb_get_ptr (tvb, 4, 6);
2350 bssid = tvb_get_ptr (tvb, 10, 6);
2355 src = tvb_get_ptr (tvb, 10, 6);
2356 dst = tvb_get_ptr (tvb, 16, 6);
2357 bssid = tvb_get_ptr (tvb, 4, 6);
2362 src = tvb_get_ptr (tvb, 24, 6);
2363 dst = tvb_get_ptr (tvb, 16, 6);
2364 bssid = tvb_get_ptr (tvb, 16, 6);
2368 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
2369 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
2370 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
2371 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
2375 SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, bssid);
2376 SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
2377 SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
2378 whdr->type = frame_type_subtype;
2380 seq_control = tvb_get_letohs(tvb, 22);
2381 frag_number = COOK_FRAGMENT_NUMBER(seq_control);
2382 seq_number = COOK_SEQUENCE_NUMBER(seq_control);
2384 if (check_col (pinfo->cinfo, COL_INFO))
2386 col_append_fstr(pinfo->cinfo, COL_INFO,
2387 ",SN=%d", seq_number);
2389 col_append_fstr(pinfo->cinfo, COL_INFO,
2390 ",FN=%d",frag_number);
2393 /* Now if we have a tree we start adding stuff */
2402 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2403 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2404 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
2405 tvb_get_ptr (tvb, 16, 6));
2406 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2408 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2411 /* add items for wlan.addr filter */
2412 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2413 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2418 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2419 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
2420 tvb_get_ptr (tvb, 10, 6));
2421 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6, src);
2422 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2424 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2427 /* add items for wlan.addr filter */
2428 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2429 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, src);
2434 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
2435 tvb_get_ptr (tvb, 4, 6));
2436 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2437 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
2439 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2441 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2444 /* add items for wlan.addr filter */
2445 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2446 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
2451 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
2452 tvb_get_ptr (tvb, 4, 6));
2453 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
2454 tvb_get_ptr (tvb, 10, 6));
2455 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
2456 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2458 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2460 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6, src);
2462 /* add items for wlan.addr filter */
2463 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
2464 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 24, 6, src);
2472 len = tvb_length_remaining(tvb, hdr_len);
2473 reported_len = tvb_reported_length_remaining(tvb, hdr_len);
2477 case 0: /* Definitely has no FCS */
2481 case 4: /* Definitely has an FCS */
2485 default: /* Don't know - use "wlan_check_fcs" */
2486 has_fcs = wlan_check_fcs;
2492 * Well, this packet should, in theory, have an FCS.
2493 * Do we have the entire packet, and does it have enough data for
2496 if (reported_len < 4)
2499 * The packet is claimed not to even have enough data for a 4-byte
2501 * Pretend it doesn't have an FCS.
2505 else if (len < reported_len)
2508 * The packet is claimed to have enough data for a 4-byte FCS, but
2509 * we didn't capture all of the packet.
2510 * Slice off the 4-byte FCS from the reported length, and trim the
2511 * captured length so it's no more than the reported length; that
2512 * will slice off what of the FCS, if any, is in the captured
2516 if (len > reported_len)
2522 * We have the entire packet, and it includes a 4-byte FCS.
2523 * Slice it off, and put it into the tree.
2529 guint32 fcs = crc32_802_tvb(tvb, hdr_len + len);
2530 guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len);
2532 if (fcs == sent_fcs)
2533 proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
2534 hdr_len + len, 4, sent_fcs,
2535 "Frame check sequence: 0x%08x [correct]", sent_fcs);
2537 proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
2538 hdr_len + len, 4, sent_fcs,
2539 "Frame check sequence: 0x%08x [incorrect, should be 0x%08x]",
2548 * Only management and data frames have a body, so we don't have
2549 * anything more to do for other types of frames.
2551 switch (COOK_FRAME_TYPE (fcf))
2559 if (tree && IS_DATA_QOS(frame_type_subtype)) {
2561 proto_item *qos_fields;
2562 proto_tree *qos_tree;
2564 guint16 qos_control;
2565 guint16 qos_priority;
2566 guint16 qos_ack_policy;
2568 guint16 qos_field_content;
2570 qos_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len - 2, 2,
2572 qos_tree = proto_item_add_subtree (qos_fields, ett_qos_parameters);
2574 qos_control = tvb_get_letohs(tvb, hdr_len - 2);
2575 qos_priority = COOK_QOS_PRIORITY(qos_control);
2576 qos_ack_policy = COOK_QOS_ACK_POLICY(qos_control);
2577 qos_eosp = COOK_QOS_EOSP(qos_control);
2578 qos_field_content = COOK_QOS_FIELD_CONTENT( qos_control);
2580 proto_tree_add_uint_format (qos_tree, hf_qos_priority, tvb,
2581 hdr_len - 2, 2, qos_priority,
2582 "Priority: %d (%s) (%s)",
2583 qos_priority, qos_tags[qos_priority], qos_acs[qos_priority]);
2585 if(flags & FLAG_FROM_DS) {
2586 proto_tree_add_boolean (qos_tree, hf_qos_eosp, tvb,
2587 hdr_len - 2, 1, qos_eosp);
2589 if(IS_DATA_CF_POLL(frame_type_subtype)) {
2591 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2592 hdr_len - 1, 1, qos_field_content, "TXOP Limit: %d ", qos_field_content);
2595 /* qap ps buffer state */
2596 proto_item *qos_ps_buf_state_fields;
2597 proto_tree *qos_ps_buf_state_tree;
2602 buf_state = COOK_PS_BUF_STATE(qos_field_content);
2603 buf_ac = COOK_PS_BUF_AC(qos_field_content); /*access category */
2604 buf_load = COOK_PS_BUF_LOAD(qos_field_content);
2606 qos_ps_buf_state_fields = proto_tree_add_text(qos_tree, tvb, hdr_len - 1, 1,
2607 "QAP PS Buffer State: 0x%x", qos_field_content);
2608 qos_ps_buf_state_tree = proto_item_add_subtree (qos_ps_buf_state_fields, ett_qos_ps_buf_state);
2610 /* FIXME: hf_ values not defined
2611 proto_tree_add_boolean (qos_ps_buf_state_tree, hf_qos_buf_state, tvb,
2614 proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_ac, tvb,
2615 hdr_len - 1, 1, buf_ac, "Priority: %d (%s)",
2616 buf_ac, wme_acs[buf_ac]);
2618 proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_load, tvb,
2619 hdr_len - 1, 1, buf_load, "Buffered load: %d ", (buf_load * 4096));
2623 } else if(qos_eosp) {
2624 /* txop limit requested */
2625 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2626 hdr_len - 1, 1, qos_field_content, "Queue Size: %d ", (qos_field_content * 254));
2629 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
2630 hdr_len - 1, 1, qos_field_content, "TXOP Limit Requested: %d ", qos_field_content);
2633 proto_tree_add_uint (qos_tree, hf_qos_ack_policy, tvb, hdr_len - 2, 1,
2636 } /* end of qos control field */
2639 * No-data frames don't have a body.
2641 if( IS_DATA_NULL(frame_type_subtype))
2654 if (IS_PROTECTED(COOK_FLAGS(fcf))) {
2656 * It's a WEP-encrypted frame; dissect the WEP parameters and decrypt
2657 * the data, if we have a matching key. Otherwise display it as data.
2659 gboolean can_decrypt = FALSE;
2660 proto_tree *wep_tree = NULL;
2662 guint8 key, keybyte;
2664 keybyte = tvb_get_guint8(tvb, hdr_len + 3);
2665 key = COOK_WEP_KEY(keybyte);
2666 if ((keybyte & KEY_EXTIV) && (len >= EXTIV_LEN)) {
2667 /* Extended IV; this frame is likely encrypted with TKIP or CCMP */
2669 proto_item *extiv_fields;
2671 extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
2672 "TKIP/CCMP parameters");
2673 wep_tree = proto_item_add_subtree (extiv_fields, ett_wep_parameters);
2674 /* It is unknown whether this is a TKIP or CCMP encrypted packet, so
2675 * display both packet number alternatives unless the ExtIV can be
2676 * determined to be possible only with one of the encryption protocols.
2678 if (tvb_get_guint8(tvb, hdr_len + 1) & 0x20) {
2679 g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
2680 tvb_get_letohl(tvb, hdr_len + 4),
2681 tvb_get_guint8(tvb, hdr_len),
2682 tvb_get_guint8(tvb, hdr_len + 2));
2683 proto_tree_add_string(wep_tree, hf_tkip_extiv, tvb, hdr_len,
2684 EXTIV_LEN, out_buff);
2686 if (tvb_get_guint8(tvb, hdr_len + 2) == 0) {
2687 g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
2688 tvb_get_letohl(tvb, hdr_len + 4),
2689 tvb_get_guint8(tvb, hdr_len + 1),
2690 tvb_get_guint8(tvb, hdr_len));
2691 proto_tree_add_string(wep_tree, hf_ccmp_extiv, tvb, hdr_len,
2692 EXTIV_LEN, out_buff);
2694 proto_tree_add_uint(wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
2697 /* Subtract out the length of the IV. */
2699 reported_len -= EXTIV_LEN;
2701 /* It is unknown whether this is TKIP or CCMP, so let's not even try to
2702 * parse TKIP Michael MIC+ICV or CCMP MIC. */
2704 /* No Ext. IV - WEP packet */
2706 * XXX - pass the IV and key to "try_decrypt_wep()", and have it pass
2707 * them to "wep_decrypt()", rather than having "wep_decrypt()" extract
2710 * Also, just pass the data *following* the WEP parameters as the
2711 * buffer to decrypt.
2713 iv = tvb_get_ntoh24(tvb, hdr_len);
2715 proto_item *wep_fields;
2717 wep_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 4,
2720 wep_tree = proto_item_add_subtree (wep_fields, ett_wep_parameters);
2721 proto_tree_add_uint (wep_tree, hf_wep_iv, tvb, hdr_len, 3, iv);
2722 tvb_memcpy(tvb, iv_buff, hdr_len, 3);
2723 is_iv_bad = weak_iv(iv_buff);
2724 if (is_iv_bad != -1) {
2725 proto_tree_add_boolean_format (wep_tree, hf_wep_iv_weak,
2727 "Weak IV for key byte %d",
2732 proto_tree_add_uint (wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
2734 /* Subtract out the length of the IV. */
2740 * Well, this packet should, in theory, have an ICV.
2741 * Do we have the entire packet, and does it have enough data for
2744 if (reported_len < 4) {
2746 * The packet is claimed not to even have enough data for a
2748 * Pretend it doesn't have an ICV.
2751 } else if (len < reported_len) {
2753 * The packet is claimed to have enough data for a 4-byte ICV,
2754 * but we didn't capture all of the packet.
2755 * Slice off the 4-byte ICV from the reported length, and trim
2756 * the captured length so it's no more than the reported length;
2757 * that will slice off what of the ICV, if any, is in the
2762 if (len > reported_len)
2766 * We have the entire packet, and it includes a 4-byte ICV.
2767 * Slice it off, and put it into the tree.
2769 * We only support decrypting if we have the the ICV.
2771 * XXX - the ICV is encrypted; we're putting the encrypted
2772 * value, not the decrypted value, into the tree.
2780 if (!can_decrypt || (next_tvb = try_decrypt_wep(tvb, hdr_len, reported_len + 8)) == NULL) {
2782 * WEP decode impossible or failed, treat payload as raw data
2783 * and don't attempt fragment reassembly or further dissection.
2785 next_tvb = tvb_new_subset(tvb, hdr_len + ivlen, len, reported_len);
2787 if (tree && can_decrypt)
2788 proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
2789 hdr_len + ivlen + len, 4,
2790 tvb_get_ntohl(tvb, hdr_len + ivlen + len),
2791 "WEP ICV: 0x%08x (not verified)",
2792 tvb_get_ntohl(tvb, hdr_len + ivlen + len));
2794 if (pinfo->ethertype != ETHERTYPE_CENTRINO_PROMISC)
2796 /* Some wireless drivers (such as Centrino) WEP payload already decrypted */
2797 call_dissector(data_handle, next_tvb, pinfo, tree);
2803 proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
2804 hdr_len + ivlen + len, 4,
2805 tvb_get_ntohl(tvb, hdr_len + ivlen + len),
2806 "WEP ICV: 0x%08x (correct)",
2807 tvb_get_ntohl(tvb, hdr_len + ivlen + len));
2809 add_new_data_source(pinfo, next_tvb, "Decrypted WEP data");
2813 * WEP decryption successful!
2815 * Use the tvbuff we got back from the decryption; the data starts at
2816 * the beginning. The lengths are already correct for the decoded WEP
2823 * Not a WEP-encrypted frame; just use the data from the tvbuff
2826 * The payload starts at "hdr_len" (i.e., just past the 802.11
2827 * MAC header), the length of data in the tvbuff following the
2828 * 802.11 header is "len", and the length of data in the packet
2829 * following the 802.11 header is "reported_len".
2835 * Do defragmentation if "wlan_defragment" is true, and we have more
2836 * fragments or this isn't the first fragment.
2838 * We have to do some special handling to catch frames that
2839 * have the "More Fragments" indicator not set but that
2840 * don't show up as reassembled and don't have any other
2841 * fragments present. Some networking interfaces appear
2842 * to do reassembly even when you're capturing raw packets
2843 * *and* show the reassembled packet without the "More
2844 * Fragments" indicator set *but* with a non-zero fragment
2847 * "fragment_add_seq_802_11()" handles that; we want to call it
2848 * even if we have a short frame, so that it does those checks - if
2849 * the frame is short, it doesn't do reassembly on it.
2851 * (This could get some false positives if we really *did* only
2852 * capture the last fragment of a fragmented packet, but that's
2855 save_fragmented = pinfo->fragmented;
2856 if (wlan_defragment && (more_frags || frag_number != 0)) {
2857 fragment_data *fd_head;
2860 * If we've already seen this frame, look it up in the
2861 * table of reassembled packets, otherwise add it to
2862 * whatever reassembly is in progress, if any, and see
2865 fd_head = fragment_add_seq_802_11(next_tvb, hdr_len, pinfo, seq_number,
2866 wlan_fragment_table,
2867 wlan_reassembled_table,
2871 next_tvb = process_reassembled_data(tvb, hdr_len, pinfo,
2872 "Reassembled 802.11", fd_head,
2873 &frag_items, NULL, hdr_tree);
2876 * If this is the first fragment, dissect its contents, otherwise
2877 * just show it as a fragment.
2879 if (frag_number != 0) {
2880 /* Not the first fragment - don't dissect it. */
2883 /* First fragment, or not fragmented. Dissect what we have here. */
2885 /* Get a tvbuff for the payload. */
2886 next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len);
2889 * If this is the first fragment, but not the only fragment,
2890 * tell the next protocol that.
2893 pinfo->fragmented = TRUE;
2895 pinfo->fragmented = FALSE;
2899 if (next_tvb == NULL) {
2900 /* Just show this as an incomplete fragment. */
2901 if (check_col(pinfo->cinfo, COL_INFO))
2902 col_set_str(pinfo->cinfo, COL_INFO, "Fragmented IEEE 802.11 frame");
2903 next_tvb = tvb_new_subset (tvb, hdr_len, len, reported_len);
2904 call_dissector(data_handle, next_tvb, pinfo, tree);
2905 pinfo->fragmented = save_fragmented;
2909 switch (COOK_FRAME_TYPE (fcf))
2913 dissect_ieee80211_mgt (fcf, next_tvb, pinfo, tree);
2918 /* I guess some bridges take Netware Ethernet_802_3 frames,
2919 which are 802.3 frames (with a length field rather than
2920 a type field, but with no 802.2 header in the payload),
2921 and just stick the payload into an 802.11 frame. I've seen
2922 captures that show frames of that sort.
2924 We also handle some odd form of encapsulation in which a
2925 complete Ethernet frame is encapsulated within an 802.11
2926 data frame, with no 802.2 header. This has been seen
2929 So, if the packet doesn't start with 0xaa 0xaa:
2931 we first use the same scheme that linux-wlan-ng does to detect
2932 those encapsulated Ethernet frames, namely looking to see whether
2933 the frame either starts with 6 octets that match the destination
2934 address from the 802.11 header or has 6 octets that match the
2935 source address from the 802.11 header following the first 6 octets,
2936 and, if so, treat it as an encapsulated Ethernet frame;
2938 otherwise, we use the same scheme that we use in the Ethernet
2939 dissector to recognize Netware 802.3 frames, namely checking
2940 whether the packet starts with 0xff 0xff and, if so, treat it
2941 as an encapsulated IPX frame. */
2942 encap_type = ENCAP_802_2;
2944 octet1 = tvb_get_guint8(next_tvb, 0);
2945 octet2 = tvb_get_guint8(next_tvb, 1);
2946 if (octet1 != 0xaa || octet2 != 0xaa) {
2947 src = tvb_get_ptr (next_tvb, 6, 6);
2948 dst = tvb_get_ptr (next_tvb, 0, 6);
2949 if (memcmp(src, pinfo->dl_src.data, 6) == 0 ||
2950 memcmp(dst, pinfo->dl_dst.data, 6) == 0)
2951 encap_type = ENCAP_ETHERNET;
2952 else if (octet1 == 0xff && octet2 == 0xff)
2953 encap_type = ENCAP_IPX;
2956 CATCH2(BoundsError, ReportedBoundsError) {
2962 switch (encap_type) {
2965 call_dissector(llc_handle, next_tvb, pinfo, tree);
2968 case ENCAP_ETHERNET:
2969 call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree);
2973 call_dissector(ipx_handle, next_tvb, pinfo, tree);
2978 pinfo->fragmented = save_fragmented;
2981 tap_queue_packet(wlan_tap, pinfo, whdr);
2985 * Dissect 802.11 with a variable-length link-layer header.
2988 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
2990 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
2991 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE);
2995 * Dissect 802.11 with a variable-length link-layer header and a pseudo-
2996 * header containing radio information.
2999 dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3001 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE,
3002 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE);
3006 * Dissect 802.11 with a variable-length link-layer header and a byte-swapped
3007 * control field (some hardware sends out LWAPP-encapsulated 802.11
3008 * packets with the control field byte swapped).
3011 dissect_ieee80211_bsfc (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3013 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE);
3017 * Dissect 802.11 with a fixed-length link-layer header (padded to the
3021 dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3023 dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE);
3027 wlan_defragment_init(void)
3029 fragment_table_init(&wlan_fragment_table);
3030 reassembled_table_init(&wlan_reassembled_table);
3034 proto_register_ieee80211 (void)
3036 static const value_string frame_type[] = {
3037 {MGT_FRAME, "Management frame"},
3038 {CONTROL_FRAME, "Control frame"},
3039 {DATA_FRAME, "Data frame"},
3043 static const value_string tofrom_ds[] = {
3044 {0, "Not leaving DS or network is operating "
3045 "in AD-HOC mode (To DS: 0 From DS: 0)"},
3046 {FLAG_TO_DS, "Frame from STA to DS via an AP (To DS: 1 "
3048 {FLAG_FROM_DS, "Frame from DS to a STA via AP(To DS: 0 "
3050 {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS from one AP to another "
3051 "AP (To DS: 1 From DS: 1)"},
3055 static const true_false_string tods_flag = {
3056 "Frame is entering DS",
3057 "Frame is not entering DS"
3060 static const true_false_string fromds_flag = {
3061 "Frame is exiting DS",
3062 "Frame is not exiting DS"
3065 static const true_false_string more_frags = {
3066 "More fragments follow",
3067 "This is the last fragment"
3070 static const true_false_string retry_flags = {
3071 "Frame is being retransmitted",
3072 "Frame is not being retransmitted"
3075 static const true_false_string pm_flags = {
3076 "STA will go to sleep",
3080 static const true_false_string md_flags = {
3081 "Data is buffered for STA at AP",
3085 static const true_false_string protected_flags = {
3086 "Data is protected",
3087 "Data is not protected"
3090 static const true_false_string order_flags = {
3092 "Not strictly ordered"
3095 static const true_false_string cf_ess_flags = {
3096 "Transmitter is an AP",
3097 "Transmitter is a STA"
3101 static const true_false_string cf_privacy_flags = {
3102 "AP/STA can support WEP",
3103 "AP/STA cannot support WEP"
3106 static const true_false_string cf_preamble_flags = {
3107 "Short preamble allowed",
3108 "Short preamble not allowed"
3111 static const true_false_string cf_pbcc_flags = {
3112 "PBCC modulation allowed",
3113 "PBCC modulation not allowed"
3116 static const true_false_string cf_agility_flags = {
3117 "Channel agility in use",
3118 "Channel agility not in use"
3121 static const true_false_string short_slot_time_flags = {
3122 "Short slot time in use",
3123 "Short slot time not in use"
3126 static const true_false_string dsss_ofdm_flags = {
3127 "DSSS-OFDM modulation allowed",
3128 "DSSS-OFDM modulation not allowed"
3131 static const true_false_string cf_spec_man_flags = {
3132 "dot11SpectrumManagementRequired TRUE",
3133 "dot11SpectrumManagementRequired FALSE",
3136 static const true_false_string cf_apsd_flags = {
3138 "apsd not implemented",
3141 static const true_false_string cf_del_blk_ack_flags = {
3142 "delayed block ack implemented",
3143 "delayed block ack not implented",
3146 static const true_false_string cf_imm_blk_ack_flags = {
3147 "immediate block ack implemented",
3148 "immediate block ack not implented",
3150 static const true_false_string cf_ibss_flags = {
3151 "Transmitter belongs to an IBSS",
3152 "Transmitter belongs to a BSS"
3155 static const true_false_string eosp_flag = {
3156 "End of service period",
3160 static const value_string sta_cf_pollable[] = {
3161 {0x00, "Station is not CF-Pollable"},
3162 {0x02, "Station is CF-Pollable, "
3163 "not requesting to be placed on the CF-polling list"},
3164 {0x01, "Station is CF-Pollable, "
3165 "requesting to be placed on the CF-polling list"},
3166 {0x03, "Station is CF-Pollable, requesting never to be polled"},
3167 {0x0200, "QSTA requesting association in QBSS"},
3171 static const value_string ap_cf_pollable[] = {
3172 {0x00, "No point coordinator at AP"},
3173 {0x02, "Point coordinator at AP for delivery only (no polling)"},
3174 {0x01, "Point coordinator at AP for delivery and polling"},
3176 {0x0200, "QAP (HC) does not use CFP for delivery of unicast data type frames"},
3177 {0x0202, "QAP (HC) uses CFP for delivery, but does not send CF-Polls to non-QoS STAs"},
3178 {0x0201, "QAP (HC) uses CFP for delivery, and sends CF-Polls to non-QoS STAs"},
3179 {0x0203, "Reserved"},
3184 static const value_string auth_alg[] = {
3185 {0x00, "Open System"},
3186 {0x01, "Shared key"},
3187 {0x80, "Network EAP"}, /* Cisco proprietary? */
3191 static const value_string reason_codes[] = {
3193 {0x01, "Unspecified reason"},
3194 {0x02, "Previous authentication no longer valid"},
3195 {0x03, "Deauthenticated because sending STA is leaving (has left) "
3197 {0x04, "Disassociated due to inactivity"},
3198 {0x05, "Disassociated because AP is unable to handle all currently "
3199 "associated stations"},
3200 {0x06, "Class 2 frame received from nonauthenticated station"},
3201 {0x07, "Class 3 frame received from nonassociated station"},
3202 {0x08, "Disassociated because sending STA is leaving (has left) BSS"},
3203 {0x09, "Station requesting (re)association is not authenticated with "
3204 "responding station"},
3205 {0x0A, "Disassociated because the information in the Power Capability "
3206 "element is unacceptable"},
3207 {0x0B, "Disassociated because the information in the Supported"
3208 "Channels element is unacceptable"},
3209 {0x0D, "Invalid Information Element"},
3210 {0x0E, "Michael MIC failure"},
3211 {0x0F, "4-Way Handshake timeout"},
3212 {0x10, "Group key update timeout"},
3213 {0x11, "Information element in 4-Way Handshake different from "
3214 "(Re)Association Request/Probe Response/Beacon"},
3215 {0x12, "Group Cipher is not valid"},
3216 {0x13, "Pairwise Cipher is not valid"},
3217 {0x14, "AKMP is not valid"},
3218 {0x15, "Unsupported RSN IE version"},
3219 {0x16, "Invalid RSN IE Capabilities"},
3220 {0x17, "IEEE 802.1X Authentication failed"},
3221 {0x18, "Cipher suite is rejected per security policy"},
3222 {0x20, "Disassociated for unspecified, QoS-related reason"},
3223 {0x21, "Disassociated because QAP lacks sufficient bandwidth for this QSTA"},
3224 {0x22, "Disassociated because of excessive number of frames that need to be "
3225 "acknowledged, but are not acknowledged for AP transmissions and/or poor "
3226 "channel conditions"},
3227 {0x23, "Disassociated because QSTA is transmitting outside the limits of its TXOPs"},
3228 {0x24, "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)"},
3229 {0x25, "Requested from peer QSTA as it does not want to use the mechanism"},
3230 {0x26, "Requested from peer QSTA as the QSTA received frames using the mechanism "
3231 "for which a set up is required"},
3232 {0x27, "Requested from peer QSTA due to time out"},
3233 {0x2D, "Peer QSTA does not support the requested cipher suite"},
3238 static const value_string status_codes[] = {
3239 {0x00, "Successful"},
3240 {0x01, "Unspecified failure"},
3241 {0x0A, "Cannot support all requested capabilities in the "
3242 "Capability information field"},
3243 {0x0B, "Reassociation denied due to inability to confirm that "
3244 "association exists"},
3245 {0x0C, "Association denied due to reason outside the scope of this "
3248 {0x0D, "Responding station does not support the specified authentication "
3250 {0x0E, "Received an Authentication frame with authentication sequence "
3251 "transaction sequence number out of expected sequence"},
3252 {0x0F, "Authentication rejected because of challenge failure"},
3253 {0x10, "Authentication rejected due to timeout waiting for next "
3254 "frame in sequence"},
3255 {0x11, "Association denied because AP is unable to handle additional "
3256 "associated stations"},
3257 {0x12, "Association denied due to requesting station not supporting all "
3258 "of the datarates in the BSSBasicServiceSet Parameter"},
3259 {0x13, "Association denied due to requesting station not supporting "
3260 "short preamble operation"},
3261 {0x14, "Association denied due to requesting station not supporting "
3263 {0x15, "Association denied due to requesting station not supporting "
3265 {0x16, "Association request rejected because Spectrum Management"
3266 "capability is required"},
3267 {0x17, "Association request rejected because the information in the"
3268 "Power Capability element is unacceptable"},
3269 {0x18, "Association request rejected because the information in the"
3270 "Supported Channels element is unacceptable"},
3271 {0x19, "Association denied due to requesting station not supporting "
3272 "short slot operation"},
3273 {0x1A, "Association denied due to requesting station not supporting "
3274 "DSSS-OFDM operation"},
3275 {0x20, "Unspecified, QoS-related failure"},
3276 {0x21, "Association denied due to QAP having insufficient bandwidth "
3277 "to handle another QSTA"},
3278 {0x22, "Association denied due to excessive frame loss rates and/or "
3279 "poor conditions on current operating channel"},
3280 {0x23, "Association (with QBSS) denied due to requesting station not "
3281 "supporting the QoS facility"},
3282 {0x24, "Association denied due to requesting station not supporting "
3284 {0x25, "The request has been declined."},
3285 {0x26, "The request has not been successful as one or more parameters "
3286 "have invalid values."},
3287 {0x27, "The TS has not been created because the request cannot be honored. "
3288 "However, a suggested TSPEC is provided so that the initiating QSTA may "
3289 "attempt to set another TS with the suggested changes to the TSPEC."},
3290 {0x28, "Invalid Information Element"},
3291 {0x29, "Group Cipher is not valid"},
3292 {0x2A, "Pairwise Cipher is not valid"},
3293 {0x2B, "AKMP is not valid"},
3294 {0x2C, "Unsupported RSN IE version"},
3295 {0x2D, "Invalid RSN IE Capabilities"},
3296 {0x2E, "Cipher suite is rejected per security policy"},
3297 {0x2F, "The TS has not been created. However, the HC may be capable of "
3298 "creating a TS, in response to a request, after the time indicated in the TS Delay element."},
3299 {0x30, "Direct Link is not allowed in the BSS by policy"},
3300 {0x31, "Destination STA is not present within this QBSS."},
3301 {0x32, "The Destination STA is not a QSTA."},
3305 static const value_string category_codes[] = {
3306 {CAT_SPECTRUM_MGMT, "Spectrum Management"},
3309 {CAT_BLOCK_ACK, "Block Ack"},
3310 {CAT_MGMT_NOTIFICATION, "Management notification frame"},
3314 static const value_string action_codes[] ={
3315 {SM_ACTION_MEASUREMENT_REQUEST, "Measurement Request"},
3316 {SM_ACTION_MEASUREMENT_REPORT, "Measurement Report"},
3317 {SM_ACTION_TPC_REQUEST, "TPC Request"},
3318 {SM_ACTION_TPC_REPORT, "TPC Report"},
3319 {SM_ACTION_CHAN_SWITCH_ANNC, "Channel Switch Announcement"},
3323 static const value_string wme_action_codes[] = {
3324 {0x00, "Setup request"},
3325 {0x01, "Setup response"},
3330 static const value_string wme_status_codes[] = {
3331 {0x00, "Admission accepted"},
3332 {0x01, "Invalid parameters"},
3337 static const value_string ack_policy[] = {
3338 {0x00, "Normal Ack"},
3340 {0x01, "No explicit Ack"},
3341 {0x03, "Block Ack"},
3345 static hf_register_info hf[] = {
3347 {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
3348 "Data rate (.5 Mb/s units)", HFILL }},
3351 {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
3352 "Radio channel", HFILL }},
3354 {&hf_signal_strength,
3355 {"Signal Strength", "wlan.signal_strength", FT_UINT8, BASE_DEC, NULL, 0,
3356 "Signal strength (percentage)", HFILL }},
3359 {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
3360 "MAC Frame control", HFILL }},
3362 {&hf_fc_proto_version,
3363 {"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
3364 "MAC Protocol version", HFILL }}, /* 0 */
3367 {"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, VALS(frame_type), 0,
3368 "Frame type", HFILL }},
3370 {&hf_fc_frame_subtype,
3371 {"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
3372 "Frame subtype", HFILL }}, /* 2 */
3374 {&hf_fc_frame_type_subtype,
3375 {"Type/Subtype", "wlan.fc.type_subtype", FT_UINT16, BASE_DEC, VALS(frame_type_subtype_vals), 0,
3376 "Type and subtype combined", HFILL }},
3379 {"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
3380 "Protocol flags", HFILL }},
3383 {"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, VALS (&tofrom_ds), 0,
3384 "Data-frame DS-traversal status", HFILL }}, /* 3 */
3387 {"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), FLAG_TO_DS,
3388 "To DS flag", HFILL }}, /* 4 */
3391 {"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), FLAG_FROM_DS,
3392 "From DS flag", HFILL }}, /* 5 */
3395 {"More Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), FLAG_MORE_FRAGMENTS,
3396 "More Fragments flag", HFILL }}, /* 6 */
3399 {"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), FLAG_RETRY,
3400 "Retransmission flag", HFILL }},
3403 {"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), FLAG_POWER_MGT,
3404 "Power management status", HFILL }},
3407 {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
3408 "More data flag", HFILL }},
3411 {"Protected flag", "wlan.fc.protected", FT_BOOLEAN, 8, TFS (&protected_flags), FLAG_PROTECTED,
3412 "Protected flag", HFILL }},
3415 {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
3416 "Strictly ordered flag", HFILL }},
3419 {"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
3420 "Association-ID field", HFILL }},
3423 {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
3424 "Duration field", HFILL }},
3427 {"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
3428 "Destination Hardware Address", HFILL }},
3431 {"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
3432 "Source Hardware Address", HFILL }},
3435 {"Source or Destination address", "wlan.addr", FT_ETHER, BASE_NONE, NULL, 0,
3436 "Source or Destination Hardware Address", HFILL }},
3439 {"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
3440 "Receiving Station Hardware Address", HFILL }},
3443 {"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
3444 "Transmitting Station Hardware Address", HFILL }},
3447 {"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
3448 "Basic Service Set ID", HFILL }},
3451 {"Fragment number", "wlan.frag", FT_UINT16, BASE_DEC, NULL, 0,
3452 "Fragment number", HFILL }},
3455 {"Sequence number", "wlan.seq", FT_UINT16, BASE_DEC, NULL, 0,
3456 "Sequence number", HFILL }},
3459 {"Priority", "wlan.qos.priority", FT_UINT16, BASE_DEC, NULL, 0,
3460 "802.1D Tag", HFILL }},
3463 {"EOSP", "wlan.qos.eosp", FT_BOOLEAN, 8, TFS (&eosp_flag), FLAG_EOSP,
3464 "EOSP Field", HFILL }},
3466 {&hf_qos_ack_policy,
3467 {"Ack Policy", "wlan.qos.ack", FT_UINT16, BASE_HEX, VALS (&ack_policy), 0,
3468 "Ack Policy", HFILL }},
3470 {&hf_qos_field_content,
3471 {"Content", "wlan.qos.fc_content", FT_UINT16, BASE_DEC, NULL, 0,
3472 "Content1", HFILL }},
3474 /* {&hf_qos_buffer_state,
3475 {"QAP PS buffer State", "wlan.qos.ps_buf_state", FT_UINT16, BASE_DEC, NULL, 0,
3476 "QAP PS buffer State", HFILL }},
3478 {&hf_qos_txop_dur_req,
3479 {"TXOP Duration Requested", "wlan.qos.txop_dur_req", FT_UINT16, BASE_DEC, NULL, 0,
3480 "TXOP Duration Requested", HFILL }},
3482 {&hf_qos_queue_size,
3483 {"Queue Size", "wlan.qos.queue_size", FT_UINT16, BASE_DEC, NULL, 0,
3484 "Queue Size", HFILL }},*/
3487 {"Frame check sequence", "wlan.fcs", FT_UINT32, BASE_HEX,
3488 NULL, 0, "FCS", HFILL }},
3490 {&hf_fragment_overlap,
3491 {"Fragment overlap", "wlan.fragment.overlap", FT_BOOLEAN, BASE_NONE,
3492 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
3494 {&hf_fragment_overlap_conflict,
3495 {"Conflicting data in fragment overlap", "wlan.fragment.overlap.conflict",
3496 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3497 "Overlapping fragments contained conflicting data", HFILL }},
3499 {&hf_fragment_multiple_tails,
3500 {"Multiple tail fragments found", "wlan.fragment.multipletails",
3501 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3502 "Several tails were found when defragmenting the packet", HFILL }},
3504 {&hf_fragment_too_long_fragment,
3505 {"Fragment too long", "wlan.fragment.toolongfragment",
3506 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3507 "Fragment contained data past end of packet", HFILL }},
3509 {&hf_fragment_error,
3510 {"Defragmentation error", "wlan.fragment.error",
3511 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3512 "Defragmentation error due to illegal fragments", HFILL }},
3515 {"802.11 Fragment", "wlan.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3516 "802.11 Fragment", HFILL }},
3519 {"802.11 Fragments", "wlan.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
3520 "802.11 Fragments", HFILL }},
3522 {&hf_reassembled_in,
3523 {"Reassembled 802.11 in frame", "wlan.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3524 "This 802.11 packet is reassembled in this frame", HFILL }},
3527 {"Initialization Vector", "wlan.wep.iv", FT_UINT24, BASE_HEX, NULL, 0,
3528 "Initialization Vector", HFILL }},
3531 {"Weak IV", "wlan.wep.weakiv", FT_BOOLEAN,BASE_NONE, NULL,0x0,
3535 {"TKIP Ext. Initialization Vector", "wlan.tkip.extiv", FT_STRING,
3536 BASE_HEX, NULL, 0, "TKIP Extended Initialization Vector", HFILL }},
3539 {"CCMP Ext. Initialization Vector", "wlan.ccmp.extiv", FT_STRING,
3540 BASE_HEX, NULL, 0, "CCMP Extended Initialization Vector", HFILL }},
3543 {"Key Index", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
3544 "Key Index", HFILL }},
3547 {"WEP ICV", "wlan.wep.icv", FT_UINT32, BASE_HEX, NULL, 0,
3548 "WEP ICV", HFILL }},
3551 static const true_false_string rsn_preauth_flags = {
3552 "Transmitter supports pre-authentication",
3553 "Transmitter does not support pre-authentication"
3556 static const true_false_string rsn_no_pairwise_flags = {
3557 "Transmitter cannot support WEP default key 0 simultaneously with "
3559 "Transmitter can support WEP default key 0 simultaneously with "
3563 static const value_string rsn_cap_replay_counter[] = {
3564 {0x00, "1 replay counter per PTKSA/GTKSA/STAKeySA"},
3565 {0x01, "2 replay counters per PTKSA/GTKSA/STAKeySA"},
3566 {0x02, "4 replay counters per PTKSA/GTKSA/STAKeySA"},
3567 {0x03, "16 replay counters per PTKSA/GTKSA/STAKeySA"},
3571 static hf_register_info ff[] = {
3573 {"Timestamp", "wlan_mgt.fixed.timestamp", FT_STRING, BASE_NONE,
3574 NULL, 0, "", HFILL }},
3577 {"Authentication Algorithm", "wlan_mgt.fixed.auth.alg",
3578 FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, "", HFILL }},
3580 {&ff_beacon_interval,
3581 {"Beacon Interval", "wlan_mgt.fixed.beacon", FT_DOUBLE, BASE_DEC, NULL, 0,
3584 {&hf_fixed_parameters,
3585 {"Fixed parameters", "wlan_mgt.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
3588 {&hf_tagged_parameters,
3589 {"Tagged parameters", "wlan_mgt.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
3593 {"Capabilities", "wlan_mgt.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
3594 "Capability information", HFILL }},
3597 {"ESS capabilities", "wlan_mgt.fixed.capabilities.ess",
3598 FT_BOOLEAN, 16, TFS (&cf_ess_flags), 0x0001, "ESS capabilities", HFILL }},
3601 {"IBSS status", "wlan_mgt.fixed.capabilities.ibss",
3602 FT_BOOLEAN, 16, TFS (&cf_ibss_flags), 0x0002, "IBSS participation", HFILL }},
3605 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.sta",
3606 FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0x020C,
3607 "CF-Poll capabilities for a STA", HFILL }},
3610 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.ap",
3611 FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0x020C,
3612 "CF-Poll capabilities for an AP", HFILL }},
3615 {"Privacy", "wlan_mgt.fixed.capabilities.privacy",
3616 FT_BOOLEAN, 16, TFS (&cf_privacy_flags), 0x0010, "WEP support", HFILL }},
3619 {"Short Preamble", "wlan_mgt.fixed.capabilities.preamble",
3620 FT_BOOLEAN, 16, TFS (&cf_preamble_flags), 0x0020, "Short Preamble", HFILL }},
3623 {"PBCC", "wlan_mgt.fixed.capabilities.pbcc",
3624 FT_BOOLEAN, 16, TFS (&cf_pbcc_flags), 0x0040, "PBCC Modulation", HFILL }},
3627 {"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
3628 FT_BOOLEAN, 16, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
3631 {"Spectrum Management", "wlan_mgt.fixed.capabilities.spec_man",
3632 FT_BOOLEAN, 16, TFS (&cf_spec_man_flags), 0x0100, "Spectrum Management", HFILL }},
3634 {&ff_short_slot_time,
3635 {"Short Slot Time", "wlan_mgt.fixed.capabilities.short_slot_time",
3636 FT_BOOLEAN, 16, TFS (&short_slot_time_flags), 0x0400, "Short Slot Time",
3640 {"Automatic Power Save Delivery", "wlan_mgt.fixed.capabilities.apsd",
3641 FT_BOOLEAN, 16, TFS (&cf_apsd_flags), 0x0800, "Automatic Power Save "
3642 "Delivery", HFILL }},
3645 {"DSSS-OFDM", "wlan_mgt.fixed.capabilities.dsss_ofdm",
3646 FT_BOOLEAN, 16, TFS (&dsss_ofdm_flags), 0x2000, "DSSS-OFDM Modulation",
3649 {&ff_cf_del_blk_ack,
3650 {"Delayed Block Ack", "wlan_mgt.fixed.capabilities.del_blk_ack",
3651 FT_BOOLEAN, 16, TFS (&cf_del_blk_ack_flags), 0x4000, "Delayed Block "
3654 {&ff_cf_imm_blk_ack,
3655 {"Immediate Block Ack", "wlan_mgt.fixed.capabilities.imm_blk_ack",
3656 FT_BOOLEAN, 16, TFS (&cf_imm_blk_ack_flags), 0x8000, "Immediate Block "
3660 {"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
3661 FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
3664 {"Association ID", "wlan_mgt.fixed.aid",
3665 FT_UINT16, BASE_HEX, NULL, 0, "Association ID", HFILL }},
3668 {"Listen Interval", "wlan_mgt.fixed.listen_ival",
3669 FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval", HFILL }},
3672 {"Current AP", "wlan_mgt.fixed.current_ap",
3673 FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP", HFILL }},
3676 {"Reason code", "wlan_mgt.fixed.reason_code",
3677 FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
3678 "Reason for unsolicited notification", HFILL }},
3681 {"Status code", "wlan_mgt.fixed.status_code",
3682 FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
3683 "Status of requested event", HFILL }},
3686 {"Category code", "wlan_mgt.fixed.category_code",
3687 FT_UINT16, BASE_DEC, VALS (&category_codes), 0,
3688 "Management action category", HFILL }},
3691 {"Action code", "wlan_mgt.fixed.action_code",
3692 FT_UINT16, BASE_DEC, VALS (&action_codes), 0,
3693 "Management action code", HFILL }},
3696 {"Dialog token", "wlan_mgt.fixed.dialog_token",
3697 FT_UINT16, BASE_HEX, NULL, 0, "Management action dialog token", HFILL }},
3699 {&ff_wme_action_code,
3700 {"Action code", "wlan_mgt.fixed.action_code",
3701 FT_UINT16, BASE_HEX, VALS (&wme_action_codes), 0,
3702 "Management notification action code", HFILL }},
3704 {&ff_wme_status_code,
3705 {"Status code", "wlan_mgt.fixed.status_code",
3706 FT_UINT16, BASE_HEX, VALS (&wme_status_codes), 0,
3707 "Management notification setup response status code", HFILL }},
3710 {"Tag", "wlan_mgt.tag.number",
3711 FT_UINT8, BASE_DEC, VALS(tag_num_vals), 0,
3712 "Element ID", HFILL }},
3715 {"Tag length", "wlan_mgt.tag.length",
3716 FT_UINT8, BASE_DEC, NULL, 0, "Length of tag", HFILL }},
3718 {&tag_interpretation,
3719 {"Tag interpretation", "wlan_mgt.tag.interpretation",
3720 FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }},
3723 {"OUI", "wlan_mgt.tag.oui",
3724 FT_BYTES, BASE_NONE, NULL, 0, "OUI of vendor specific IE", HFILL }},
3727 {"TIM length", "wlan_mgt.tim.length",
3728 FT_UINT8, BASE_DEC, NULL, 0,
3729 "Traffic Indication Map length", HFILL }},
3732 {"DTIM count", "wlan_mgt.tim.dtim_count",
3733 FT_UINT8, BASE_DEC, NULL, 0,
3734 "DTIM count", HFILL }},
3737 {"DTIM period", "wlan_mgt.tim.dtim_period",
3738 FT_UINT8, BASE_DEC, NULL, 0,
3739 "DTIM period", HFILL }},
3742 {"Bitmap control", "wlan_mgt.tim.bmapctl",
3743 FT_UINT8, BASE_HEX, NULL, 0,
3744 "Bitmap control", HFILL }},
3747 {"RSN Capabilities", "wlan_mgt.rsn.capabilities", FT_UINT16, BASE_HEX,
3748 NULL, 0, "RSN Capability information", HFILL }},
3751 {"RSN Pre-Auth capabilities", "wlan_mgt.rsn.capabilities.preauth",
3752 FT_BOOLEAN, 16, TFS (&rsn_preauth_flags), 0x0001,
3753 "RSN Pre-Auth capabilities", HFILL }},
3755 {&rsn_cap_no_pairwise,
3756 {"RSN No Pairwise capabilities", "wlan_mgt.rsn.capabilities.no_pairwise",
3757 FT_BOOLEAN, 16, TFS (&rsn_no_pairwise_flags), 0x0002,
3758 "RSN No Pairwise capabilities", HFILL }},
3760 {&rsn_cap_ptksa_replay_counter,
3761 {"RSN PTKSA Replay Counter capabilities",
3762 "wlan_mgt.rsn.capabilities.ptksa_replay_counter",
3763 FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x000C,
3764 "RSN PTKSA Replay Counter capabilities", HFILL }},
3766 {&rsn_cap_gtksa_replay_counter,
3767 {"RSN GTKSA Replay Counter capabilities",
3768 "wlan_mgt.rsn.capabilities.gtksa_replay_counter",
3769 FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x0030,
3770 "RSN GTKSA Replay Counter capabilities", HFILL }},
3773 static gint *tree_array[] = {
3780 &ett_fixed_parameters,
3781 &ett_tagged_parameters,
3782 &ett_qos_parameters,
3783 &ett_qos_ps_buf_state,
3784 &ett_wep_parameters,
3789 module_t *wlan_module;
3791 static const enum_val_t wep_keys_options[] = {
3801 proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
3802 "IEEE 802.11", "wlan");
3803 proto_register_field_array (proto_wlan, hf, array_length (hf));
3804 proto_wlan_mgt = proto_register_protocol ("IEEE 802.11 wireless LAN management frame",
3805 "802.11 MGT", "wlan_mgt");
3806 proto_register_field_array (proto_wlan_mgt, ff, array_length (ff));
3807 proto_register_subtree_array (tree_array, array_length (tree_array));
3809 register_dissector("wlan", dissect_ieee80211, proto_wlan);
3810 register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
3811 register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan);
3812 register_init_routine(wlan_defragment_init);
3814 wlan_tap = register_tap("wlan");
3816 /* Register configuration options */
3817 wlan_module = prefs_register_protocol(proto_wlan, init_wepkeys);
3818 prefs_register_bool_preference(wlan_module, "defragment",
3819 "Reassemble fragmented 802.11 datagrams",
3820 "Whether fragmented 802.11 datagrams should be reassembled",
3823 prefs_register_bool_preference(wlan_module, "check_fcs",
3824 "Assume packets have FCS",
3825 "Some 802.11 cards include the FCS at the end of a packet, others do not.",
3828 prefs_register_bool_preference(wlan_module, "ignore_wep",
3829 "Ignore the WEP bit",
3830 "Some 802.11 cards leave the WEP bit set even though the packet is decrypted.",
3834 prefs_register_enum_preference(wlan_module, "wep_keys",
3836 "How many WEP keys do we have to choose from? (0 to disable, up to 4)",
3837 &num_wepkeys, wep_keys_options, FALSE);
3839 prefs_register_string_preference(wlan_module, "wep_key1",
3841 "First WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
3843 prefs_register_string_preference(wlan_module, "wep_key2",
3845 "Second WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
3847 prefs_register_string_preference(wlan_module, "wep_key3",
3849 "Third WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
3851 prefs_register_string_preference(wlan_module, "wep_key4",
3853 "Fourth WEP key (A:B:C:D:E) [40bit] (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
3859 proto_reg_handoff_ieee80211(void)
3861 dissector_handle_t ieee80211_handle;
3862 dissector_handle_t ieee80211_radio_handle;
3865 * Get handles for the LLC, IPX and Ethernet dissectors.
3867 llc_handle = find_dissector("llc");
3868 ipx_handle = find_dissector("ipx");
3869 eth_withoutfcs_handle = find_dissector("eth_withoutfcs");
3870 data_handle = find_dissector("data");
3872 ieee80211_handle = find_dissector("wlan");
3873 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle);
3874 ieee80211_radio_handle = create_dissector_handle(dissect_ieee80211_radio,
3876 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
3877 ieee80211_radio_handle);
3878 dissector_add("ethertype", ETHERTYPE_CENTRINO_PROMISC, ieee80211_handle);
3881 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len) {
3882 const guint8 *enc_data;
3885 tvbuff_t *decr_tvb = NULL;
3887 if (num_wepkeys < 1)
3890 enc_data = tvb_get_ptr(tvb, offset, len);
3892 if ((tmp = g_malloc(len)) == NULL)
3893 return NULL; /* krap! */
3895 /* try once with the key index in the packet, then look through our list. */
3896 for (i = -1; i < num_wepkeys; i++) {
3897 /* copy the encrypted data over to the tmp buffer */
3899 printf("trying %d\n", i);
3901 memcpy(tmp, enc_data, len);
3902 if (wep_decrypt(tmp, len, i) == 0) {
3904 /* decrypt successful, let's set up a new data tvb. */
3905 decr_tvb = tvb_new_real_data(tmp, len-8, len-8);
3906 tvb_set_free_cb(decr_tvb, g_free);
3907 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
3914 if ((!decr_tvb) && (tmp)) g_free(tmp);
3917 printf("de-wep %p\n", decr_tvb);
3924 /* de-weps the block. if successful, buf* will point to the data start. */
3925 static int wep_decrypt(guint8 *buf, guint32 len, int key_override) {
3926 guint32 i, j, k, crc, keylen;
3927 guint8 s[256], key[128], c_crc[4];
3928 guint8 keyidx, *dpos, *cpos;
3930 /* Needs to be at least 8 bytes of payload */
3934 /* initialize the first bytes of the key from the IV */
3938 keyidx = COOK_WEP_KEY(buf[3]);
3940 if (key_override >= 0)
3941 keyidx = key_override;
3943 if (keyidx >= (guint)num_wepkeys)
3946 keylen = wep_keylens[keyidx];
3950 if (wep_keys[keyidx] == NULL)
3953 keylen+=3; /* add in ICV bytes */
3955 /* copy the rest of the key over from the designated key */
3956 memcpy(key+3, wep_keys[keyidx], wep_keylens[keyidx]);
3959 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]);
3962 /* set up the RC4 state */
3963 for (i = 0; i < 256; i++)
3966 for (i = 0; i < 256; i++) {
3967 j = (j + s[i] + key[i % keylen]) & 0xff;
3971 /* Apply the RC4 to the data, update the CRC32 */
3976 for (k = 0; k < (len -8); k++) {
3978 j = (j+s[i]) & 0xff;
3981 printf("%d -- %02x ", k, *dpos);
3983 *dpos = *cpos++ ^ s[(s[i] + s[j]) & 0xff];
3985 printf("%02x\n", *dpos);
3987 crc = crc32_ccitt_table[(crc ^ *dpos++) & 0xff] ^ (crc >> 8);
3991 /* now let's check the crc */
3993 c_crc[1] = crc >> 8;
3994 c_crc[2] = crc >> 16;
3995 c_crc[3] = crc >> 24;
3997 for (k = 0; k < 4; k++) {
3999 j = (j+s[i]) & 0xff;
4002 printf("-- %02x %02x\n", *dpos, c_crc[k]);
4004 if ((*cpos++ ^ s[(s[i] + s[j]) & 0xff]) != c_crc[k])
4005 return -1; /* ICV mismatch */
4011 static void init_wepkeys(void) {
4020 tmp = getenv("ETHEREAL_WEPKEYNUM");
4025 num_wepkeys = atoi(tmp);
4027 if (num_wepkeys > 4)
4031 if (num_wepkeys < 1)
4038 g_free(wep_keylens);
4040 wep_keys = g_malloc(num_wepkeys * sizeof(guint8*));
4041 wep_keylens = g_malloc(num_wepkeys * sizeof(int));
4042 bytes = g_byte_array_new();
4044 for (i = 0 ; i < num_wepkeys; i++) {
4050 g_snprintf(buf, 128, "ETHEREAL_WEPKEY%d", i+1);
4053 tmp = wep_keystr[i];
4059 printf("%s -- %s\n", buf, tmp);
4061 printf("%d -- %s\n", i+1, tmp);
4066 g_free(wep_keys[i]);
4069 res = hex_str_to_bytes(tmp, bytes, FALSE);
4070 if (res && bytes->len > 0) {
4071 if (bytes->len > 32) {
4074 wep_keys[i] = g_malloc(32 * sizeof(guint8));
4075 memset(wep_keys[i], 0, 32 * sizeof(guint8));
4076 memcpy(wep_keys[i], bytes->data, bytes->len * sizeof(guint8));
4077 wep_keylens[i] = bytes->len;
4079 printf("%d: %d bytes\n", i, bytes->len);
4080 printf("%d: %s\n", i, bytes_to_str(bytes->data, bytes->len));
4084 printf("res: %d bytes->len: %d\n", res, bytes->len);
4086 g_warning("Could not parse WEP key %d: %s", i + 1, tmp);
4090 g_byte_array_free(bytes, TRUE);
4093 * This code had been taken from AirSnort crack.c function classify()
4094 * Permission granted by snax <at> shmoo dot com
4095 * weak_iv - determine which key byte an iv is useful in resolving
4096 * parm - p, pointer to the first byte of an IV
4097 * return - n - this IV is weak for byte n of a WEP key
4098 * -1 - this IV is not weak for any key bytes
4100 * This function tests for IVs that are known to satisfy the criteria
4101 * for a weak IV as specified in FMS section 7.1
4109 if (iv[1] == 255 && iv[0] > 2 && iv[0] < 16) {
4113 sum = iv[0] + iv[1];
4115 if (iv[2] <= 0x0a) {
4118 else if (iv[2] == 0xff){
4123 if (sum == k && (iv[2] >= 0xf2 && iv[2] <= 0xfe && iv[2] != 0xfd)){