2 * Routines for Wireless LAN (IEEE 802.11) dissection
3 * Copyright 2000, Axis Communications AB
4 * Inquiries/bugreports should be sent to Johan.Jorgensen@axis.com
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * Copied from README.developer
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 * The following people helped me by pointing out bugs etc. Thank you!
34 * Magnus Hultman-Persson
38 * 09/12/2003 - Added dissection of country information tag
40 * Ritchie<at>tipsybottle.com
42 * 03/22/2004 - Added dissection of RSN IE
43 * Jouni Malinen <jkmaline@cc.hut.fi>
45 * 10/24/2005 - Add dissection for 802.11e
46 * Zhu Yi <yi.zhu@intel.com>
58 #include <epan/bitswap.h>
59 #include <epan/proto.h>
60 #include <epan/packet.h>
61 #include <epan/addr_resolv.h>
62 #include <epan/strutil.h>
63 #include <epan/prefs.h>
64 #include <epan/reassemble.h>
65 #include "packet-ipx.h"
66 #include "packet-llc.h"
67 #include "packet-ieee80211.h"
68 #include <epan/etypes.h>
70 #include <epan/crc32.h>
72 #include <epan/emem.h>
73 #include <epan/crypt/wep-wpadefs.h>
80 #include <airpcap_loader.h>
82 /* XXX - This is probably a bit much */
83 #define MAX_ENCRYPTION_KEYS 64
87 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
90 /* Defragment fragmented 802.11 datagrams */
91 static gboolean wlan_defragment = TRUE;
93 /* Check for the presence of the 802.11 FCS */
94 static gboolean wlan_check_fcs = FALSE;
96 /* Ignore the WEP bit; assume packet is decrypted */
97 static gboolean wlan_ignore_wep = FALSE;
99 /* Tables for reassembly of fragments. */
100 static GHashTable *wlan_fragment_table = NULL;
101 static GHashTable *wlan_reassembled_table = NULL;
103 /* Stuff for the WEP decoder */
105 static gint num_wepkeys = 0;
106 static gboolean enable_decryption = FALSE;
107 static guint8 **wep_keys = NULL;
108 static int *wep_keylens = NULL;
109 static void init_wepkeys(void);
110 static int wep_decrypt(guint8 *buf, guint32 len, int key_override);
111 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len);
113 /* Davide Schiera (2006-11-26): created function to decrypt WEP and WPA/WPA2 */
114 static tvbuff_t *try_decrypt(tvbuff_t *tvb, guint32 offset, guint32 len, guint8 *algorithm, guint32 *sec_header, guint32 *sec_trailer);
116 static int weak_iv(guchar *iv);
117 #define SSWAP(a,b) {guint8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
119 /* #define USE_ENV */
120 /* When this is set, an unlimited number of WEP keys can be set in the
123 WIRESHARK_WEPKEYNUM=##
124 WIRESHARK_WEPKEY1=aa:bb:cc:dd:...
125 WIRESHARK_WEPKEY2=aa:bab:cc:dd:ee:...
127 ... you get the idea.
129 otherwise you're limited to specifying four keys in the preference system.
133 static char *wep_keystr[MAX_ENCRYPTION_KEYS];
136 /* ************************************************************************* */
137 /* Miscellaneous Constants */
138 /* ************************************************************************* */
139 #define SHORT_STR 256
141 /* ************************************************************************* */
142 /* Define some very useful macros that are used to analyze frame types etc. */
143 /* ************************************************************************* */
146 * Extract the protocol version from the frame control field
148 #define FCF_PROT_VERSION(x) ((x) & 0x3)
151 * Extract the frame type from the frame control field.
153 #define FCF_FRAME_TYPE(x) (((x) & 0xC) >> 2)
156 * Extract the frame subtype from the frame control field.
158 #define FCF_FRAME_SUBTYPE(x) (((x) & 0xF0) >> 4)
161 * Convert the frame type and subtype from the frame control field into
162 * one of the MGT_, CTRL_, or DATA_ values.
164 #define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+FCF_FRAME_SUBTYPE(x)) /* Create key to (sub)type */
167 * The subtype field of a data frame is, in effect, composed of 4 flag
168 * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have
169 * any data), and QoS.
171 #define DATA_FRAME_IS_CF_ACK(x) ((x) & 0x01)
172 #define DATA_FRAME_IS_CF_POLL(x) ((x) & 0x02)
173 #define DATA_FRAME_IS_NULL(x) ((x) & 0x04)
174 #define DATA_FRAME_IS_QOS(x) ((x) & 0x08)
177 * Extract the flags from the frame control field.
179 #define FCF_FLAGS(x) (((x) & 0xFF00) >> 8)
182 * Bits from the flags field.
184 #define FLAG_TO_DS 0x01
185 #define FLAG_FROM_DS 0x02
186 #define FLAG_MORE_FRAGMENTS 0x04
187 #define FLAG_RETRY 0x08
188 #define FLAG_POWER_MGT 0x10
189 #define FLAG_MORE_DATA 0x20
190 #define FLAG_PROTECTED 0x40
191 #define FLAG_ORDER 0x80
194 * Test bits in the flags field.
196 #define IS_TO_DS(x) ((x) & FLAG_TO_DS)
197 #define IS_FROM_DS(x) ((x) & FLAG_FROM_DS)
198 #define HAVE_FRAGMENTS(x) ((x) & FLAG_MORE_FRAGMENTS)
199 #define IS_RETRY(x) ((x) & FLAG_RETRY)
200 #define POWER_MGT_STATUS(x) ((x) & FLAG_POWER_MGT)
201 #define HAS_MORE_DATA(x) ((x) & FLAG_MORE_DATA)
202 #define IS_PROTECTED(x) (!wlan_ignore_wep && ((x) & FLAG_PROTECTED))
203 #define IS_STRICTLY_ORDERED(x) ((x) & FLAG_ORDER)
206 * Extract subfields from the flags field.
208 #define FLAGS_DS_STATUS(x) ((x) & (FLAG_FROM_DS|FLAG_TO_DS))
211 * Extract an indication of the types of addresses in a data frame from
212 * the frame control field.
214 #define FCF_ADDR_SELECTOR(x) ((x) & ((FLAG_TO_DS|FLAG_FROM_DS) << 8))
216 #define DATA_ADDR_T1 0
217 #define DATA_ADDR_T2 (FLAG_FROM_DS << 8)
218 #define DATA_ADDR_T3 (FLAG_TO_DS << 8)
219 #define DATA_ADDR_T4 ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
222 * Extract the fragment number and sequence number from the sequence
225 #define SEQCTL_FRAGMENT_NUMBER(x) ((x) & 0x000F)
226 #define SEQCTL_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
229 * Extract subfields from the QoS control field.
231 #define QOS_TID(x) ((x) & 0x000F)
232 #define QOS_PRIORITY(x) ((x) & 0x0007)
233 #define QOS_EOSP(x) (((x) & 0x0010) >> 4) /* end of service period */
234 #define QOS_ACK_POLICY(x) (((x) & 0x0060) >> 5)
235 #define QOS_FIELD_CONTENT(x) (((x) & 0xFF00) >> 8)
237 #define QOS_FLAG_EOSP 0x08
240 * Extract subfields from the result of QOS_FIELD_CONTENT().
242 #define QOS_PS_BUF_STATE(x) (((x) & 0x02) >> 1)
243 #define QOS_PS_BUF_AC(x) (((x) & 0x0C) >> 2)
244 #define QOS_PS_BUF_LOAD(x) (((x) & 0xF0) >> 4)
247 * Extract the association ID from the value in an association ID field.
249 #define ASSOC_ID(x) ((x) & 0x3FFF)
252 * Extract subfields from the key octet in WEP-encrypted frames.
254 #define KEY_OCTET_WEP_KEY(x) (((x) & 0xC0) >> 6)
257 * Extract subfields from TS Info field.
259 #define TSI_TYPE(x) (((x) & 0x000001) >> 0)
260 #define TSI_TSID(x) (((x) & 0x00001E) >> 1)
261 #define TSI_DIR(x) (((x) & 0x000060) >> 5)
262 #define TSI_ACCESS(x) (((x) & 0x000180) >> 7)
263 #define TSI_AGG(x) (((x) & 0x000200) >> 9)
264 #define TSI_APSD(x) (((x) & 0x000400) >> 10)
265 #define TSI_UP(x) (((x) & 0x003800) >> 11)
266 #define TSI_ACK(x) (((x) & 0x00C000) >> 14)
267 #define TSI_SCHED(x) (((x) & 0x010000) >> 16)
268 #define TSI_RESERVED(x) (((x) & 0xFE0000) >> 17)
270 #define KEY_EXTIV 0x20
274 /* ************************************************************************* */
275 /* Constants used to identify cooked frame types */
276 /* ************************************************************************* */
277 #define MGT_FRAME 0x00 /* Frame type is management */
278 #define CONTROL_FRAME 0x01 /* Frame type is control */
279 #define DATA_FRAME 0x02 /* Frame type is Data */
281 #define DATA_SHORT_HDR_LEN 24
282 #define DATA_LONG_HDR_LEN 30
283 #define MGT_FRAME_HDR_LEN 24 /* Length of Managment frame-headers */
286 * COMPOSE_FRAME_TYPE() values for management frames.
288 #define MGT_ASSOC_REQ 0x00 /* association request */
289 #define MGT_ASSOC_RESP 0x01 /* association response */
290 #define MGT_REASSOC_REQ 0x02 /* reassociation request */
291 #define MGT_REASSOC_RESP 0x03 /* reassociation response */
292 #define MGT_PROBE_REQ 0x04 /* Probe request */
293 #define MGT_PROBE_RESP 0x05 /* Probe response */
294 #define MGT_BEACON 0x08 /* Beacon frame */
295 #define MGT_ATIM 0x09 /* ATIM */
296 #define MGT_DISASS 0x0A /* Disassociation */
297 #define MGT_AUTHENTICATION 0x0B /* Authentication */
298 #define MGT_DEAUTHENTICATION 0x0C /* Deauthentication */
299 #define MGT_ACTION 0x0D /* Action */
302 * COMPOSE_FRAME_TYPE() values for control frames.
304 #define CTRL_BLOCK_ACK_REQ 0x18 /* Block ack Request */
305 #define CTRL_BLOCK_ACK 0x19 /* Block ack */
306 #define CTRL_PS_POLL 0x1A /* power-save poll */
307 #define CTRL_RTS 0x1B /* request to send */
308 #define CTRL_CTS 0x1C /* clear to send */
309 #define CTRL_ACKNOWLEDGEMENT 0x1D /* acknowledgement */
310 #define CTRL_CFP_END 0x1E /* contention-free period end */
311 #define CTRL_CFP_ENDACK 0x1F /* contention-free period end/ack */
314 * COMPOSE_FRAME_TYPE() values for data frames.
316 #define DATA 0x20 /* Data */
317 #define DATA_CF_ACK 0x21 /* Data + CF-Ack */
318 #define DATA_CF_POLL 0x22 /* Data + CF-Poll */
319 #define DATA_CF_ACK_POLL 0x23 /* Data + CF-Ack + CF-Poll */
320 #define DATA_NULL_FUNCTION 0x24 /* Null function (no data) */
321 #define DATA_CF_ACK_NOD 0x25 /* CF-Ack (no data) */
322 #define DATA_CF_POLL_NOD 0x26 /* CF-Poll (No data) */
323 #define DATA_CF_ACK_POLL_NOD 0x27 /* CF-Ack + CF-Poll (no data) */
325 #define DATA_QOS_DATA 0x28 /* QoS Data */
326 #define DATA_QOS_DATA_CF_ACK 0x29 /* QoS Data + CF-Ack */
327 #define DATA_QOS_DATA_CF_POLL 0x2A /* QoS Data + CF-Poll */
328 #define DATA_QOS_DATA_CF_ACK_POLL 0x2B /* QoS Data + CF-Ack + CF-Poll */
329 #define DATA_QOS_NULL 0x2C /* QoS Null */
330 #define DATA_QOS_CF_POLL_NOD 0x2E /* QoS CF-Poll (No Data) */
331 #define DATA_QOS_CF_ACK_POLL_NOD 0x2F /* QoS CF-Ack + CF-Poll (No Data) */
334 /* ************************************************************************* */
335 /* Macros used to extract information about fixed fields */
336 /* ************************************************************************* */
337 #define ESS_SET(x) ((x) & 0x0001)
338 #define IBSS_SET(x) ((x) & 0x0002)
342 /* ************************************************************************* */
343 /* Logical field codes (dissector's encoding of fixed fields) */
344 /* ************************************************************************* */
345 #define FIELD_TIMESTAMP 0x01 /* 64-bit timestamp */
346 #define FIELD_BEACON_INTERVAL 0x02 /* 16-bit beacon interval */
347 #define FIELD_CAP_INFO 0x03 /* Add capability information tree */
348 #define FIELD_AUTH_ALG 0x04 /* Authentication algorithm used */
349 #define FIELD_AUTH_TRANS_SEQ 0x05 /* Authentication sequence number */
350 #define FIELD_CURRENT_AP_ADDR 0x06
351 #define FIELD_LISTEN_IVAL 0x07
352 #define FIELD_REASON_CODE 0x08
353 #define FIELD_ASSOC_ID 0x09
354 #define FIELD_STATUS_CODE 0x0A
355 #define FIELD_CATEGORY_CODE 0x0B /* Management action category */
356 #define FIELD_ACTION_CODE 0x0C /* Management action code */
357 #define FIELD_DIALOG_TOKEN 0x0D /* Management action dialog token */
358 #define FIELD_WME_ACTION_CODE 0x0E /* Management notification action code */
359 #define FIELD_WME_DIALOG_TOKEN 0x0F /* Management notification dialog token */
360 #define FIELD_WME_STATUS_CODE 0x10 /* Management notification setup response status code */
361 #define FIELD_QOS_ACTION_CODE 0x11
362 #define FIELD_QOS_TS_INFO 0x12
363 #define FIELD_DLS_ACTION_CODE 0x13
364 #define FIELD_DST_MAC_ADDR 0X14 /* DLS destination MAC address */
365 #define FIELD_SRC_MAC_ADDR 0X15 /* DLS source MAC address */
366 #define FIELD_DLS_TIMEOUT 0X16 /* DLS timeout value */
367 #define FIELD_SCHEDULE_INFO 0X17 /* Schedule Info field */
369 /* ************************************************************************* */
370 /* Logical field codes (IEEE 802.11 encoding of tags) */
371 /* ************************************************************************* */
372 #define TAG_SSID 0x00
373 #define TAG_SUPP_RATES 0x01
374 #define TAG_FH_PARAMETER 0x02
375 #define TAG_DS_PARAMETER 0x03
376 #define TAG_CF_PARAMETER 0x04
378 #define TAG_IBSS_PARAMETER 0x06
379 #define TAG_COUNTRY_INFO 0x07
380 #define TAG_FH_HOPPING_PARAMETER 0x08
381 #define TAG_FH_HOPPING_TABLE 0x09
382 #define TAG_REQUEST 0x0A
383 #define TAG_QBSS_LOAD 0x0B
384 #define TAG_EDCA_PARAM_SET 0x0C
385 #define TAG_TSPEC 0x0D
386 #define TAG_TCLAS 0x0E
387 #define TAG_SCHEDULE 0x0F
388 #define TAG_CHALLENGE_TEXT 0x10
389 #define TAG_POWER_CONSTRAINT 0x20
390 #define TAG_POWER_CAPABILITY 0x21
391 #define TAG_TPC_REQUEST 0x22
392 #define TAG_TPC_REPORT 0x23
393 #define TAG_SUPPORTED_CHANNELS 0x24
394 #define TAG_CHANNEL_SWITCH_ANN 0x25
395 #define TAG_MEASURE_REQ 0x26
396 #define TAG_MEASURE_REP 0x27
397 #define TAG_QUIET 0x28
398 #define TAG_IBSS_DFS 0x29
399 #define TAG_ERP_INFO 0x2A
400 #define TAG_TS_DELAY 0x2B
401 #define TAG_TCLAS_PROCESS 0x2C
402 #define TAG_QOS_CAPABILITY 0x2E
403 #define TAG_ERP_INFO_OLD 0x2F /* IEEE Std 802.11g/D4.0 */
404 #define TAG_RSN_IE 0x30
405 #define TAG_EXT_SUPP_RATES 0x32
406 #define TAG_AGERE_PROPRIETARY 0x80
407 #define TAG_CISCO_UNKNOWN_1 0x85 /* Cisco Compatible eXtensions? */
408 #define TAG_CISCO_UNKNOWN_2 0x88 /* Cisco Compatible eXtensions? */
409 #define TAG_VENDOR_SPECIFIC_IE 0xDD
410 #define TAG_SYMBOL_PROPRIETARY 0xAD
412 #define WPA_OUI (const guint8 *) "\x00\x50\xF2"
413 #define RSN_OUI (const guint8 *) "\x00\x0F\xAC"
414 #define WME_OUI (const guint8 *) "\x00\x50\xF2"
418 /* ************************************************************************* */
419 /* Frame types, and their names */
420 /* ************************************************************************* */
421 static const value_string frame_type_subtype_vals[] = {
422 {MGT_ASSOC_REQ, "Association Request"},
423 {MGT_ASSOC_RESP, "Association Response"},
424 {MGT_REASSOC_REQ, "Reassociation Request"},
425 {MGT_REASSOC_RESP, "Reassociation Response"},
426 {MGT_PROBE_REQ, "Probe Request"},
427 {MGT_PROBE_RESP, "Probe Response"},
428 {MGT_BEACON, "Beacon frame"},
430 {MGT_DISASS, "Dissassociate"},
431 {MGT_AUTHENTICATION, "Authentication"},
432 {MGT_DEAUTHENTICATION, "Deauthentication"},
433 {MGT_ACTION, "Action"},
435 {CTRL_BLOCK_ACK_REQ, "802.11 Block Ack Req"},
436 {CTRL_BLOCK_ACK, "802.11 Block Ack"},
437 {CTRL_PS_POLL, "Power-Save poll"},
438 {CTRL_RTS, "Request-to-send"},
439 {CTRL_CTS, "Clear-to-send"},
440 {CTRL_ACKNOWLEDGEMENT, "Acknowledgement"},
441 {CTRL_CFP_END, "CF-End (Control-frame)"},
442 {CTRL_CFP_ENDACK, "CF-End + CF-Ack (Control-frame)"},
445 {DATA_CF_ACK, "Data + CF-Ack"},
446 {DATA_CF_POLL, "Data + CF-Poll"},
447 {DATA_CF_ACK_POLL, "Data + CF-Ack + CF-Poll"},
448 {DATA_NULL_FUNCTION, "Null function (No data)"},
449 {DATA_CF_ACK_NOD, "Acknowledgement (No data)"},
450 {DATA_CF_POLL_NOD, "CF-Poll (No data)"},
451 {DATA_CF_ACK_POLL_NOD, "CF-Ack/Poll (No data)"},
452 {DATA_QOS_DATA, "QoS Data"},
453 {DATA_QOS_DATA_CF_ACK, "QoS Data + CF-Acknowledgment"},
454 {DATA_QOS_DATA_CF_POLL, "QoS Data + CF-Poll"},
455 {DATA_QOS_DATA_CF_ACK_POLL, "QoS Data + CF-Ack + CF-Poll"},
456 {DATA_QOS_NULL, "QoS Null function (No data)"},
457 {DATA_QOS_CF_POLL_NOD, "QoS CF-Poll (No Data)"},
458 {DATA_QOS_CF_ACK_POLL_NOD, "QoS CF-Ack + CF-Poll (No data)"},
462 /* ************************************************************************* */
463 /* 802.1D Tag Names */
464 /* ************************************************************************* */
465 static const char *qos_tags[8] = {
476 /* ************************************************************************* */
477 /* WME Access Category Names (by 802.1D Tag) */
478 /* ************************************************************************* */
479 static const char *qos_acs[8] = {
490 /* ************************************************************************* */
491 /* WME Access Category Names (by WME ACI) */
492 /* ************************************************************************* */
493 static const char *wme_acs[4] = {
501 #define CAT_SPECTRUM_MGMT 0
504 #define CAT_BLOCK_ACK 3
505 #define CAT_MGMT_NOTIFICATION 17
507 #define SM_ACTION_MEASUREMENT_REQUEST 0
508 #define SM_ACTION_MEASUREMENT_REPORT 1
509 #define SM_ACTION_TPC_REQUEST 2
510 #define SM_ACTION_TPC_REPORT 3
511 #define SM_ACTION_CHAN_SWITCH_ANNC 4
513 #define SM_ACTION_ADDTS_REQUEST 0
514 #define SM_ACTION_ADDTS_RESPONSE 1
515 #define SM_ACTION_DELTS 2
516 #define SM_ACTION_QOS_SCHEDULE 3
518 #define SM_ACTION_DLS_REQUEST 0
519 #define SM_ACTION_DLS_RESPONSE 1
520 #define SM_ACTION_DLS_TEARDOWN 2
522 static int proto_wlan = -1;
523 static packet_info * g_pinfo;
525 /* ************************************************************************* */
526 /* Header field info values for radio information */
527 /* ************************************************************************* */
528 static int hf_data_rate = -1;
529 static int hf_channel = -1;
530 static int hf_signal_strength = -1;
532 /* ************************************************************************* */
533 /* Header field info values for FC-field */
534 /* ************************************************************************* */
535 static int hf_fc_field = -1;
536 static int hf_fc_proto_version = -1;
537 static int hf_fc_frame_type = -1;
538 static int hf_fc_frame_subtype = -1;
539 static int hf_fc_frame_type_subtype = -1;
541 static int hf_fc_flags = -1;
542 static int hf_fc_to_ds = -1;
543 static int hf_fc_from_ds = -1;
544 static int hf_fc_data_ds = -1;
546 static int hf_fc_more_frag = -1;
547 static int hf_fc_retry = -1;
548 static int hf_fc_pwr_mgt = -1;
549 static int hf_fc_more_data = -1;
550 static int hf_fc_protected = -1;
551 static int hf_fc_order = -1;
554 /* ************************************************************************* */
555 /* Header values for Duration/ID field */
556 /* ************************************************************************* */
557 static int hf_did_duration = -1;
558 static int hf_assoc_id = -1;
561 /* ************************************************************************* */
562 /* Header values for different address-fields (all 4 of them) */
563 /* ************************************************************************* */
564 static int hf_addr_da = -1; /* Destination address subfield */
565 static int hf_addr_sa = -1; /* Source address subfield */
566 static int hf_addr_ra = -1; /* Receiver address subfield */
567 static int hf_addr_ta = -1; /* Transmitter address subfield */
568 static int hf_addr_bssid = -1; /* address is bssid */
570 static int hf_addr = -1; /* Source or destination address subfield */
573 /* ************************************************************************* */
574 /* Header values for QoS control field */
575 /* ************************************************************************* */
576 static int hf_qos_priority = -1;
577 static int hf_qos_ack_policy = -1;
578 static int hf_qos_eosp = -1;
579 static int hf_qos_field_content = -1;
580 /*static int hf_qos_txop_limit = -1;*/
581 /* FIXME: hf_ values not defined
582 static int hf_qos_buf_state = -1;
583 static int hf_qos_buf_ac = -1;
584 static int hf_qos_buf_load = -1;
586 /*static int hf_qos_txop_dur_req = -1;
587 static int hf_qos_queue_size = -1;*/
589 /* ************************************************************************* */
590 /* Header values for sequence number field */
591 /* ************************************************************************* */
592 static int hf_frag_number = -1;
593 static int hf_seq_number = -1;
595 /* ************************************************************************* */
596 /* Header values for Frame Check field */
597 /* ************************************************************************* */
598 static int hf_fcs = -1;
599 static int hf_fcs_good = -1;
600 static int hf_fcs_bad = -1;
602 /* ************************************************************************* */
603 /* Header values for reassembly */
604 /* ************************************************************************* */
605 static int hf_fragments = -1;
606 static int hf_fragment = -1;
607 static int hf_fragment_overlap = -1;
608 static int hf_fragment_overlap_conflict = -1;
609 static int hf_fragment_multiple_tails = -1;
610 static int hf_fragment_too_long_fragment = -1;
611 static int hf_fragment_error = -1;
612 static int hf_reassembled_in = -1;
615 static int proto_wlan_mgt = -1;
616 /* ************************************************************************* */
617 /* Fixed fields found in mgt frames */
618 /* ************************************************************************* */
619 static int ff_auth_alg = -1; /* Authentication algorithm field */
620 static int ff_auth_seq = -1; /* Authentication transaction sequence */
621 static int ff_current_ap = -1; /* Current AP MAC address */
622 static int ff_listen_ival = -1; /* Listen interval fixed field */
623 static int ff_timestamp = -1; /* 64 bit timestamp */
624 static int ff_beacon_interval = -1; /* 16 bit Beacon interval */
625 static int ff_assoc_id = -1; /* 16 bit AID field */
626 static int ff_reason = -1; /* 16 bit reason code */
627 static int ff_status_code = -1; /* Status code */
628 static int ff_category_code = -1; /* 8 bit Category code */
629 static int ff_action_code = -1; /* 8 bit Action code */
630 static int ff_dialog_token = -1; /* 8 bit Dialog token */
631 static int ff_wme_action_code = -1; /* Management notification action code */
632 static int ff_wme_status_code = -1; /* Management notification setup response status code */
633 static int ff_qos_action_code = -1;
634 static int ff_dls_action_code = -1;
635 static int ff_dst_mac_addr = -1; /* DLS destination MAC addressi */
636 static int ff_src_mac_addr = -1; /* DLS source MAC addressi */
637 static int ff_dls_timeout = -1; /* DLS timeout value */
639 /* ************************************************************************* */
640 /* Flags found in the capability field (fixed field) */
641 /* ************************************************************************* */
642 static int ff_capture = -1;
643 static int ff_cf_ess = -1;
644 static int ff_cf_ibss = -1;
645 static int ff_cf_sta_poll = -1; /* CF pollable status for a STA */
646 static int ff_cf_ap_poll = -1; /* CF pollable status for an AP */
647 static int ff_cf_privacy = -1;
648 static int ff_cf_preamble = -1;
649 static int ff_cf_pbcc = -1;
650 static int ff_cf_agility = -1;
651 static int ff_short_slot_time = -1;
652 static int ff_dsss_ofdm = -1;
653 static int ff_cf_spec_man = -1;
654 static int ff_cf_apsd = -1;
655 static int ff_cf_del_blk_ack = -1;
656 static int ff_cf_imm_blk_ack = -1;
658 /* ************************************************************************* */
659 /* Tagged value format fields */
660 /* ************************************************************************* */
661 static int tag_number = -1;
662 static int tag_length = -1;
663 static int tag_interpretation = -1;
664 static int tag_oui = -1;
667 static int tim_length = -1;
668 static int tim_dtim_count = -1;
669 static int tim_dtim_period = -1;
670 static int tim_bmapctl = -1;
673 static int hf_fixed_parameters = -1; /* Protocol payload for management frames */
674 static int hf_tagged_parameters = -1; /* Fixed payload item */
675 static int hf_wep_iv = -1;
676 static int hf_wep_iv_weak = -1;
677 static int hf_tkip_extiv = -1;
678 static int hf_ccmp_extiv = -1;
679 static int hf_wep_key = -1;
680 static int hf_wep_icv = -1;
683 static int rsn_cap = -1;
684 static int rsn_cap_preauth = -1;
685 static int rsn_cap_no_pairwise = -1;
686 static int rsn_cap_ptksa_replay_counter = -1;
687 static int rsn_cap_gtksa_replay_counter = -1;
689 static int hf_aironet_ie_type = -1;
690 static int hf_aironet_ie_version = -1;
691 static int hf_aironet_ie_data = -1;
692 static int hf_aironet_ie_qos_unk1 = -1;
693 static int hf_aironet_ie_qos_paramset = -1;
694 static int hf_aironet_ie_qos_val = -1;
696 /*QBSS - Version 1,2,802.11e*/
698 static int hf_qbss2_cal = -1;
699 static int hf_qbss2_gl = -1;
700 static int hf_qbss_cu = -1;
701 static int hf_qbss2_cu = -1;
702 static int hf_qbss_scount = -1;
703 static int hf_qbss2_scount = -1;
704 static int hf_qbss_version = -1;
705 static int hf_qbss_adc = -1;
707 static int hf_ts_info = -1;
708 static int hf_tsinfo_type = -1;
709 static int hf_tsinfo_tsid = -1;
710 static int hf_tsinfo_dir = -1;
711 static int hf_tsinfo_access = -1;
712 static int hf_tsinfo_agg = -1;
713 static int hf_tsinfo_apsd = -1;
714 static int hf_tsinfo_up = -1;
715 static int hf_tsinfo_ack = -1;
716 static int hf_tsinfo_sched = -1;
717 static int tspec_nor_msdu = -1;
718 static int tspec_max_msdu = -1;
719 static int tspec_min_srv = -1;
720 static int tspec_max_srv = -1;
721 static int tspec_inact_int = -1;
722 static int tspec_susp_int = -1;
723 static int tspec_srv_start = -1;
724 static int tspec_min_data = -1;
725 static int tspec_mean_data = -1;
726 static int tspec_peak_data = -1;
727 static int tspec_burst_size = -1;
728 static int tspec_delay_bound = -1;
729 static int tspec_min_phy = -1;
730 static int tspec_surplus = -1;
731 static int tspec_medium = -1;
732 static int ts_delay = -1;
733 static int hf_class_type = -1;
734 static int hf_class_mask = -1;
735 static int hf_ether_type = -1;
736 static int hf_tclas_process = -1;
737 static int hf_sched_info = -1;
738 static int hf_sched_srv_start = -1;
739 static int hf_sched_srv_int = -1;
740 static int hf_sched_spec_int = -1;
741 static int cf_version = -1;
742 static int cf_ipv4_src = -1;
743 static int cf_ipv4_dst = -1;
744 static int cf_src_port = -1;
745 static int cf_dst_port = -1;
746 static int cf_dscp = -1;
747 static int cf_protocol = -1;
748 static int cf_ipv6_src = -1;
749 static int cf_ipv6_dst = -1;
750 static int cf_flow = -1;
751 static int cf_tag_type = -1;
753 /* ************************************************************************* */
755 /* ************************************************************************* */
756 static gint ett_80211 = -1;
757 static gint ett_proto_flags = -1;
758 static gint ett_cap_tree = -1;
759 static gint ett_fc_tree = -1;
760 static gint ett_fragments = -1;
761 static gint ett_fragment = -1;
763 static gint ett_80211_mgt = -1;
764 static gint ett_fixed_parameters = -1;
765 static gint ett_tagged_parameters = -1;
766 static gint ett_qos_parameters = -1;
767 static gint ett_qos_ps_buf_state = -1;
768 static gint ett_wep_parameters = -1;
770 static gint ett_rsn_cap_tree = -1;
772 static gint ett_80211_mgt_ie = -1;
773 static gint ett_tsinfo_tree = -1;
774 static gint ett_sched_tree = -1;
776 static gint ett_fcs = -1;
778 static const fragment_items frag_items = {
783 &hf_fragment_overlap,
784 &hf_fragment_overlap_conflict,
785 &hf_fragment_multiple_tails,
786 &hf_fragment_too_long_fragment,
792 static dissector_handle_t llc_handle;
793 static dissector_handle_t ipx_handle;
794 static dissector_handle_t eth_withoutfcs_handle;
795 static dissector_handle_t data_handle;
797 static int wlan_tap = -1;
799 /* Davide Schiera (2006-11-22): including AirPDcap project */
801 #include <epan/crypt/airpdcap_ws.h>
802 AIRPDCAP_CONTEXT airpdcap_ctx;
806 /* Davide Schiera (2006-11-22) ---------------------------------------------- */
809 /* ************************************************************************* */
810 /* Return the length of the current header (in bytes) */
811 /* ************************************************************************* */
813 find_header_length (guint16 fcf)
817 switch (FCF_FRAME_TYPE (fcf)) {
820 return MGT_FRAME_HDR_LEN;
823 switch (COMPOSE_FRAME_TYPE (fcf)) {
826 case CTRL_ACKNOWLEDGEMENT:
832 case CTRL_CFP_ENDACK:
833 case CTRL_BLOCK_ACK_REQ:
840 len = (FCF_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
842 if (DATA_FRAME_IS_QOS(COMPOSE_FRAME_TYPE(fcf)))
853 /* ************************************************************************* */
854 /* This is the capture function used to update packet counts */
855 /* ************************************************************************* */
857 capture_ieee80211_common (const guchar * pd, int offset, int len,
858 packet_counts * ld, gboolean fixed_length_header,
861 guint16 fcf, hdr_length;
863 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
868 fcf = pletohs (&pd[offset]);
870 if (IS_PROTECTED(FCF_FLAGS(fcf)))
876 switch (COMPOSE_FRAME_TYPE (fcf))
879 case DATA: /* We got a data frame */
880 case DATA_CF_ACK: /* Data with ACK */
882 case DATA_CF_ACK_POLL:
884 if (fixed_length_header)
885 hdr_length = DATA_LONG_HDR_LEN;
887 hdr_length = find_header_length (fcf);
889 hdr_length = roundup2(hdr_length, 4);
890 /* I guess some bridges take Netware Ethernet_802_3 frames,
891 which are 802.3 frames (with a length field rather than
892 a type field, but with no 802.2 header in the payload),
893 and just stick the payload into an 802.11 frame. I've seen
894 captures that show frames of that sort.
896 This means we have to do the same check for Netware 802.3 -
897 or, if you will, "Netware 802.11" - that we do in the
898 Ethernet dissector, i.e. checking for 0xffff as the first
899 four bytes of the payload and, if we find it, treating it
901 if (!BYTES_ARE_IN_FRAME(offset+hdr_length, len, 2)) {
905 if (pd[offset+hdr_length] == 0xff && pd[offset+hdr_length+1] == 0xff) {
909 capture_llc (pd, offset + hdr_length, len, ld);
920 * Handle 802.11 with a variable-length link-layer header.
923 capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
925 capture_ieee80211_common (pd, offset, len, ld, FALSE, FALSE);
929 * Handle 802.11 with a variable-length link-layer header and data padding.
932 capture_ieee80211_datapad (const guchar * pd, int offset, int len,
935 capture_ieee80211_common (pd, offset, len, ld, FALSE, TRUE);
939 * Handle 802.11 with a fixed-length link-layer header (padded to the
943 capture_ieee80211_fixed (const guchar * pd, int offset, int len, packet_counts * ld)
945 capture_ieee80211_common (pd, offset, len, ld, TRUE, FALSE);
949 /* ************************************************************************* */
950 /* Add the subtree used to store the fixed parameters */
951 /* ************************************************************************* */
953 get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
955 proto_item *fixed_fields;
957 proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
958 size, size, "Fixed parameters (%d bytes)",
961 return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
965 /* ************************************************************************* */
966 /* Add the subtree used to store tagged parameters */
967 /* ************************************************************************* */
969 get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
971 proto_item *tagged_fields;
973 tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
978 "Tagged parameters (%d bytes)",
981 return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
985 /* ************************************************************************* */
986 /* Dissect and add fixed mgmt fields to protocol tree */
987 /* ************************************************************************* */
989 add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
991 const guint8 *dataptr;
992 char out_buff[SHORT_STR];
994 proto_item *cap_item;
995 static proto_tree *cap_tree;
1000 case FIELD_TIMESTAMP:
1001 dataptr = tvb_get_ptr (tvb, offset, 8);
1002 memset (out_buff, 0, SHORT_STR);
1003 g_snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
1013 proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
1016 case FIELD_BEACON_INTERVAL:
1017 capability = tvb_get_letohs (tvb, offset);
1018 temp_double = (double)capability;
1019 temp_double = temp_double * 1024 / 1000000;
1020 proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
1021 temp_double,"Beacon Interval: %f [Seconds]",
1023 if (check_col (g_pinfo->cinfo, COL_INFO)) {
1024 col_append_fstr(g_pinfo->cinfo, COL_INFO, ",BI=%d", capability);
1029 case FIELD_CAP_INFO:
1030 capability = tvb_get_letohs (tvb, offset);
1032 cap_item = proto_tree_add_uint_format (tree, ff_capture,
1035 "Capability Information: 0x%04X",
1037 cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree);
1038 proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 2,
1040 proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 2,
1042 if (ESS_SET (capability) != 0) /* This is an AP */
1043 proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2,
1046 else /* This is a STA */
1047 proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
1049 proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 2,
1051 proto_tree_add_boolean (cap_tree, ff_cf_preamble, tvb, offset, 2,
1053 proto_tree_add_boolean (cap_tree, ff_cf_pbcc, tvb, offset, 2,
1055 proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 2,
1057 proto_tree_add_boolean (cap_tree, ff_cf_spec_man, tvb, offset, 2,
1059 proto_tree_add_boolean (cap_tree, ff_short_slot_time, tvb, offset, 2,
1061 proto_tree_add_boolean (cap_tree, ff_cf_apsd, tvb, offset, 2,
1063 proto_tree_add_boolean (cap_tree, ff_dsss_ofdm, tvb, offset, 2,
1065 proto_tree_add_boolean (cap_tree, ff_cf_del_blk_ack, tvb, offset, 2,
1067 proto_tree_add_boolean (cap_tree, ff_cf_imm_blk_ack, tvb, offset, 2,
1071 case FIELD_AUTH_ALG:
1072 proto_tree_add_item (tree, ff_auth_alg, tvb, offset, 2, TRUE);
1075 case FIELD_AUTH_TRANS_SEQ:
1076 proto_tree_add_item (tree, ff_auth_seq, tvb, offset, 2, TRUE);
1079 case FIELD_CURRENT_AP_ADDR:
1080 proto_tree_add_item (tree, ff_current_ap, tvb, offset, 6, FALSE);
1083 case FIELD_LISTEN_IVAL:
1084 proto_tree_add_item (tree, ff_listen_ival, tvb, offset, 2, TRUE);
1087 case FIELD_REASON_CODE:
1088 proto_tree_add_item (tree, ff_reason, tvb, offset, 2, TRUE);
1091 case FIELD_ASSOC_ID:
1092 proto_tree_add_uint(tree, ff_assoc_id, tvb, offset, 2,
1093 ASSOC_ID(tvb_get_letohs(tvb,offset)));
1094 /* proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE); */
1097 case FIELD_STATUS_CODE:
1098 proto_tree_add_item (tree, ff_status_code, tvb, offset, 2, TRUE);
1101 case FIELD_CATEGORY_CODE:
1102 proto_tree_add_item (tree, ff_category_code, tvb, offset, 1, TRUE);
1105 case FIELD_ACTION_CODE:
1106 proto_tree_add_item (tree, ff_action_code, tvb, offset, 1, TRUE);
1109 case FIELD_DIALOG_TOKEN:
1110 proto_tree_add_item (tree, ff_dialog_token, tvb, offset, 1, TRUE);
1113 case FIELD_WME_ACTION_CODE:
1114 proto_tree_add_item (tree, ff_wme_action_code, tvb, offset, 1, TRUE);
1117 case FIELD_WME_STATUS_CODE:
1118 proto_tree_add_item (tree, ff_wme_status_code, tvb, offset, 1, TRUE);
1121 case FIELD_QOS_ACTION_CODE:
1122 proto_tree_add_item (tree, ff_qos_action_code, tvb, offset, 1, TRUE);
1125 case FIELD_QOS_TS_INFO:
1127 proto_item *tsinfo_item;
1128 proto_tree *tsinfo_tree;
1131 tsinfo_item = proto_tree_add_item(tree, hf_ts_info, tvb,
1133 tsinfo_tree = proto_item_add_subtree(tsinfo_item, ett_tsinfo_tree);
1134 tsi = tvb_get_letoh24(tvb, offset);
1135 proto_tree_add_uint(tsinfo_tree, hf_tsinfo_type, tvb,
1136 offset, 3, TSI_TYPE (tsi));
1137 if (TSI_TSID (tsi) < 8)
1139 proto_tree_add_text(tsinfo_tree, tvb, offset, 3,
1140 "TSID: %u (< 8 is invalid)", TSI_TSID (tsi));
1144 proto_tree_add_uint(tsinfo_tree, hf_tsinfo_tsid, tvb,
1145 offset, 3, TSI_TSID (tsi));
1147 proto_tree_add_uint(tsinfo_tree, hf_tsinfo_dir, tvb,
1148 offset, 3, TSI_DIR (tsi));
1149 proto_tree_add_uint(tsinfo_tree, hf_tsinfo_access, tvb,
1150 offset, 3, TSI_ACCESS (tsi));
1151 proto_tree_add_uint(tsinfo_tree, hf_tsinfo_agg, tvb,
1152 offset, 3, TSI_AGG (tsi));
1153 proto_tree_add_uint(tsinfo_tree, hf_tsinfo_apsd, tvb,
1154 offset, 3, TSI_APSD (tsi));
1155 proto_tree_add_uint(tsinfo_tree, hf_tsinfo_up, tvb,
1156 offset, 3, TSI_UP (tsi));
1157 proto_tree_add_uint(tsinfo_tree, hf_tsinfo_ack, tvb,
1158 offset, 3, TSI_ACK (tsi));
1159 proto_tree_add_uint(tsinfo_tree, hf_tsinfo_sched, tvb,
1160 offset, 3, TSI_SCHED (tsi));
1164 case FIELD_DLS_ACTION_CODE:
1165 proto_tree_add_item (tree, ff_dls_action_code, tvb, offset, 1, TRUE);
1168 case FIELD_DST_MAC_ADDR:
1169 proto_tree_add_item (tree, ff_dst_mac_addr, tvb, offset, 6, TRUE);
1172 case FIELD_SRC_MAC_ADDR:
1173 proto_tree_add_item (tree, ff_src_mac_addr, tvb, offset, 6, TRUE);
1176 case FIELD_DLS_TIMEOUT:
1177 proto_tree_add_item (tree, ff_dls_timeout, tvb, offset, 2, TRUE);
1180 case FIELD_SCHEDULE_INFO:
1182 proto_item *sched_item;
1183 proto_tree *sched_tree;
1186 sched_item = proto_tree_add_item(tree, hf_sched_info,
1187 tvb, offset, 2, TRUE);
1188 sched_tree = proto_item_add_subtree(sched_item, ett_sched_tree);
1189 sched = tvb_get_letohs(tvb, offset);
1190 proto_tree_add_uint(sched_tree, hf_tsinfo_agg, tvb, offset,
1194 proto_tree_add_uint(sched_tree, hf_tsinfo_tsid, tvb, offset,
1195 2, (sched & 0x001E) >> 1);
1196 proto_tree_add_uint(sched_tree, hf_tsinfo_dir, tvb, offset,
1197 2, (sched & 0x0060) >> 5);
1204 static const value_string wpa_cipher_vals[] =
1207 {1, "WEP (40-bit)"},
1211 {5, "WEP (104-bit)"},
1215 static const value_string wpa_keymgmt_vals[] =
1224 dissect_vendor_ie_wpawme(proto_tree * ietree, proto_tree * tree, tvbuff_t * tag_tvb)
1227 guint tag_len = tvb_length_remaining(tag_tvb, 0);
1228 gchar out_buff[SHORT_STR];
1229 guint i, byte1, byte2;
1231 /* Wi-Fi Protected Access (WPA) Information Element */
1232 if (tag_off + 6 <= tag_len && !tvb_memeql(tag_tvb, tag_off, WPA_OUI"\x01", 4)) {
1233 g_snprintf(out_buff, SHORT_STR, "WPA IE, type %u, version %u",
1234 tvb_get_guint8(tag_tvb, tag_off + 3), tvb_get_letohs(tag_tvb, tag_off + 4));
1235 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 6, out_buff);
1237 if (tag_off + 4 <= tag_len) {
1238 /* multicast cipher suite */
1239 if (!tvb_memeql(tag_tvb, tag_off, WPA_OUI, 3)) {
1240 g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
1241 val_to_str(tvb_get_guint8(tag_tvb, tag_off + 3), wpa_cipher_vals,
1243 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4,
1246 /* unicast cipher suites */
1247 if (tag_off + 2 <= tag_len) {
1248 g_snprintf(out_buff, SHORT_STR,
1249 "# of unicast cipher suites: %u", tvb_get_letohs(tag_tvb, tag_off));
1250 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1254 while (tag_off + 4 <= tag_len) {
1255 if (!tvb_memeql(tag_tvb, tag_off, WPA_OUI, 3)) {
1256 g_snprintf(out_buff, SHORT_STR,
1257 "Unicast cipher suite %u: %s", i,
1258 val_to_str(tvb_get_guint8(tag_tvb, tag_off + 3),
1259 wpa_cipher_vals, "UNKNOWN"));
1260 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4,
1268 /* authenticated key management suites */
1269 if (tag_off + 2 <= tag_len) {
1270 g_snprintf(out_buff, SHORT_STR,
1271 "# of auth key management suites: %u", tvb_get_letohs(tag_tvb, tag_off));
1272 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1276 while (tag_off + 4 <= tag_len) {
1277 if (!tvb_memeql(tag_tvb, tag_off, WPA_OUI, 3)) {
1278 g_snprintf(out_buff, SHORT_STR,
1279 "auth key management suite %u: %s", i,
1280 val_to_str(tvb_get_guint8(tag_tvb, tag_off + 3),
1281 wpa_keymgmt_vals, "UNKNOWN"));
1282 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4,
1294 if (tag_off < tag_len)
1295 proto_tree_add_string(tree, tag_interpretation, tag_tvb,
1296 tag_off, tag_len - tag_off, "Not interpreted");
1297 proto_item_append_text(ietree, ": WPA");
1298 } else if (tag_off + 7 <= tag_len && !tvb_memeql(tag_tvb, tag_off, WME_OUI"\x02\x00", 5)) {
1299 /* Wireless Multimedia Enhancements (WME) Information Element */
1300 g_snprintf(out_buff, SHORT_STR,
1301 "WME IE: type %u, subtype %u, version %u, parameter set %u",
1302 tvb_get_guint8(tag_tvb, tag_off+3), tvb_get_guint8(tag_tvb, tag_off+4),
1303 tvb_get_guint8(tag_tvb, tag_off+5), tvb_get_guint8(tag_tvb, tag_off+6));
1304 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 7,
1306 proto_item_append_text(ietree, ": WME");
1307 } else if (tag_off + 24 <= tag_len && !tvb_memeql(tag_tvb, tag_off, WME_OUI"\x02\x01", 5)) {
1308 /* Wireless Multimedia Enhancements (WME) Parameter Element */
1309 g_snprintf(out_buff, SHORT_STR,
1310 "WME PE: type %u, subtype %u, version %u, parameter set %u",
1311 tvb_get_guint8(tag_tvb, tag_off+3), tvb_get_guint8(tag_tvb, tag_off+4),
1312 tvb_get_guint8(tag_tvb, tag_off+5), tvb_get_guint8(tag_tvb, tag_off+6));
1313 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 7,
1316 for (i = 0; i < 4; i++) {
1317 byte1 = tvb_get_guint8(tag_tvb, tag_off);
1318 byte2 = tvb_get_guint8(tag_tvb, tag_off + 1);
1319 g_snprintf(out_buff, SHORT_STR,
1320 "WME AC Parameters: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
1321 (byte1 & 0x60) >> 5, wme_acs[(byte1 & 0x60) >> 5],
1322 (byte1 & 0x10) ? "" : "not ", byte1 & 0x0f,
1323 byte2 & 0x0f, byte2 & 0xf0 >> 4,
1324 tvb_get_letohs(tag_tvb, tag_off + 2));
1325 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4,
1329 proto_item_append_text(ietree, ": WME");
1330 } else if (tag_off + 56 <= tag_len && !tvb_memeql(tag_tvb, tag_off, WME_OUI"\x02\x02", 5)) {
1331 /* Wireless Multimedia Enhancements (WME) TSPEC Element */
1332 guint16 ts_info, msdu_size, surplus_bandwidth;
1333 const char *direction[] = { "Uplink", "Downlink", "Reserved", "Bi-directional" };
1334 const value_string fields[] = {
1335 {12, "Minimum Service Interval"},
1336 {16, "Maximum Service Interval"},
1337 {20, "Inactivity Interval"},
1338 {24, "Service Start Time"},
1339 {28, "Minimum Data Rate"},
1340 {32, "Mean Data Rate"},
1341 {36, "Maximum Burst Size"},
1342 {40, "Minimum PHY Rate"},
1343 {44, "Peak Data Rate"},
1344 {48, "Delay Bound"},
1349 g_snprintf(out_buff, SHORT_STR,
1350 "WME TSPEC: type %u, subtype %u, version %u",
1351 tvb_get_guint8(tag_tvb, tag_off+3), tvb_get_guint8(tag_tvb, tag_off+4),
1352 tvb_get_guint8(tag_tvb, tag_off+5));
1353 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 6,
1357 ts_info = tvb_get_letohs(tag_tvb, tag_off);
1358 byte1 = (ts_info >> 11) & 0x7;
1359 g_snprintf(out_buff, SHORT_STR,
1360 "WME TS Info: Priority %u (%s) (%s), Contention-based access %sset, %s",
1361 byte1, qos_tags[byte1], qos_acs[byte1],
1362 (ts_info & 0x0080) ? "" : "not ",
1363 direction[(ts_info >> 5) & 0x3]);
1364 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1368 msdu_size = tvb_get_letohs(tag_tvb, tag_off);
1369 g_snprintf(out_buff, SHORT_STR,
1370 "WME TSPEC: %s MSDU Size %u",
1371 (msdu_size & 0x8000) ? "Fixed" : "Nominal", msdu_size & 0x7fff);
1372 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1376 g_snprintf(out_buff, SHORT_STR,
1377 "WME TSPEC: Maximum MSDU Size %u", tvb_get_letohs(tag_tvb, tag_off));
1378 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1382 while ((field = val_to_str(tag_off, fields, "Unknown"))) {
1383 g_snprintf(out_buff, SHORT_STR,
1384 "WME TSPEC: %s %u", field, tvb_get_letohl(tag_tvb, tag_off));
1385 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4,
1392 surplus_bandwidth = tvb_get_letohs(tag_tvb, tag_off);
1393 g_snprintf(out_buff, SHORT_STR,
1394 "WME TSPEC: Surplus Bandwidth Allowance Factor %u.%u",
1395 (surplus_bandwidth >> 13) & 0x7, (surplus_bandwidth & 0x1fff));
1396 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1400 g_snprintf(out_buff, SHORT_STR,
1401 "WME TSPEC: Medium Time %u", tvb_get_letohs(tag_tvb, tag_off));
1402 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2,
1405 proto_item_append_text(ietree, ": WME");
1410 dissect_vendor_ie_rsn(proto_tree * ietree, proto_tree * tree, tvbuff_t * tag_tvb)
1413 guint tag_len = tvb_length_remaining(tag_tvb, 0);
1414 guint pmkid_len = tag_len - 4;
1415 char out_buff[SHORT_STR], valid_str[SHORT_STR] = "";
1417 if (tag_len >= 4 && !tvb_memeql(tag_tvb, tag_off, RSN_OUI"\x04", 4)) {
1418 /* IEEE 802.11i / Key Data Encapsulation / Data Type=4 - PMKID.
1419 * This is only used within EAPOL-Key frame Key Data. */
1420 if (pmkid_len != PMKID_LEN) {
1421 g_snprintf(valid_str, SHORT_STR,
1422 "(invalid PMKID len=%d, expected 16) ", pmkid_len);
1424 g_snprintf(out_buff, SHORT_STR, "RSN PMKID: %s%s", valid_str,
1425 tvb_bytes_to_str(tag_tvb, 4, pmkid_len));
1426 proto_tree_add_string(tree, tag_interpretation, tag_tvb, 0,
1429 proto_item_append_text(ietree, ": RSN");
1433 AIRONET_IE_VERSION = 3,
1435 AIRONET_IE_QBSS_V2 = 14
1436 } aironet_ie_type_t;
1438 static const value_string aironet_ie_type_vals[] = {
1439 { AIRONET_IE_VERSION, "CCX version"},
1440 { AIRONET_IE_QOS, "Qos"},
1441 { AIRONET_IE_QBSS_V2, "QBSS V2 - CCA"},
1447 dissect_vendor_ie_aironet(proto_item * aironet_item, proto_tree * ietree,
1448 tvbuff_t * tvb, int offset, guint32 tag_len)
1452 gboolean dont_change = FALSE; /* Don't change the IE item text to default */
1454 type = tvb_get_guint8(tvb, offset);
1455 proto_tree_add_item (ietree, hf_aironet_ie_type, tvb, offset, 1, TRUE);
1459 case AIRONET_IE_VERSION:
1460 proto_tree_add_item (ietree, hf_aironet_ie_version, tvb, offset, 1, TRUE);
1461 proto_item_append_text(aironet_item, ": Aironet CCX version = %d",
1462 tvb_get_guint8(tvb, offset));
1465 case AIRONET_IE_QOS:
1466 proto_tree_add_item (ietree, hf_aironet_ie_qos_unk1, tvb, offset, 1, TRUE);
1468 proto_tree_add_item (ietree, hf_aironet_ie_qos_paramset, tvb, offset, 1, TRUE);
1471 /* XXX: just copied over from WME. Maybe "Best Effort" and "Background"
1472 * need to be swapped. Also, the "TXOP" may be TXOP - or not.
1474 for (i = 0; i < 4; i++) {
1475 guint8 byte1, byte2;
1477 byte1 = tvb_get_guint8(tvb, offset);
1478 byte2 = tvb_get_guint8(tvb, offset + 1);
1479 txop = tvb_get_letohs(tvb, offset + 2);
1480 proto_tree_add_bytes_format(ietree, hf_aironet_ie_qos_val, tvb, offset, 4,
1481 tvb_get_ptr(tvb, offset, 4),
1482 "CCX QoS Parameters??: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
1483 (byte1 & 0x60) >> 5, wme_acs[(byte1 & 0x60) >> 5],
1484 (byte1 & 0x10) ? "" : "not ", byte1 & 0x0f,
1485 byte2 & 0x0f, (byte2 & 0xf0) >> 4,
1490 case AIRONET_IE_QBSS_V2:
1491 /* Extract Values */
1492 proto_tree_add_item (ietree, hf_qbss2_scount, tvb, offset, 2, TRUE);
1493 proto_tree_add_item (ietree, hf_qbss2_cu, tvb, offset + 2, 1, FALSE);
1494 proto_tree_add_item (ietree, hf_qbss2_cal, tvb, offset + 3, 1, FALSE);
1495 proto_tree_add_item (ietree, hf_qbss2_gl, tvb, offset + 4, 1, FALSE);
1498 proto_tree_add_item(ietree, hf_aironet_ie_data, tvb, offset,
1499 tag_len - 1, FALSE);
1503 proto_item_append_text(aironet_item, ": Aironet %s",
1504 val_to_str(type, aironet_ie_type_vals, "Unknown"));
1509 dissect_rsn_ie(proto_tree * tree, tvbuff_t * tag_tvb)
1512 guint tag_len = tvb_length_remaining(tag_tvb, 0);
1514 char out_buff[SHORT_STR];
1516 proto_item *cap_item;
1517 proto_tree *cap_tree;
1519 if (tag_off + 2 > tag_len) {
1520 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, tag_len,
1525 g_snprintf(out_buff, SHORT_STR, "RSN IE, version %u",
1526 tvb_get_letohs(tag_tvb, tag_off));
1527 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2, out_buff);
1531 if (tag_off + 4 > tag_len)
1534 /* multicast cipher suite */
1535 if (!tvb_memeql(tag_tvb, tag_off, RSN_OUI, 3)) {
1536 g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
1537 val_to_str(tvb_get_guint8(tag_tvb, tag_off + 3),
1538 wpa_cipher_vals, "UNKNOWN"));
1539 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4, out_buff);
1543 if (tag_off + 2 > tag_len)
1546 /* unicast cipher suites */
1547 count = tvb_get_letohs(tag_tvb, tag_off);
1548 g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u", count);
1549 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2, out_buff);
1552 while (tag_off + 4 <= tag_len && i <= count) {
1553 if (tvb_memeql(tag_tvb, tag_off, RSN_OUI, 3) != 0)
1555 g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
1556 i, val_to_str(tvb_get_guint8(tag_tvb, tag_off + 3),
1557 wpa_cipher_vals, "UNKNOWN"));
1558 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4, out_buff);
1563 if (i <= count || tag_off + 2 > tag_len)
1566 /* authenticated key management suites */
1567 count = tvb_get_letohs(tag_tvb, tag_off);
1568 g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u", count);
1569 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2, out_buff);
1572 while (tag_off + 4 <= tag_len && i <= count) {
1573 if (tvb_memeql(tag_tvb, tag_off, RSN_OUI, 3) != 0)
1575 g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
1576 i, val_to_str(tvb_get_guint8(tag_tvb, tag_off + 3),
1577 wpa_keymgmt_vals, "UNKNOWN"));
1578 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 4, out_buff);
1583 if (i <= count || tag_off + 2 > tag_len)
1586 rsn_capab = tvb_get_letohs(tag_tvb, tag_off);
1587 g_snprintf(out_buff, SHORT_STR, "RSN Capabilities 0x%04x", rsn_capab);
1588 cap_item = proto_tree_add_uint_format(tree, rsn_cap, tag_tvb,
1589 tag_off, 2, rsn_capab,
1590 "RSN Capabilities: 0x%04X", rsn_capab);
1591 cap_tree = proto_item_add_subtree(cap_item, ett_rsn_cap_tree);
1592 proto_tree_add_boolean(cap_tree, rsn_cap_preauth, tag_tvb, tag_off, 2,
1594 proto_tree_add_boolean(cap_tree, rsn_cap_no_pairwise, tag_tvb, tag_off, 2,
1596 proto_tree_add_uint(cap_tree, rsn_cap_ptksa_replay_counter, tag_tvb, tag_off, 2,
1598 proto_tree_add_uint(cap_tree, rsn_cap_gtksa_replay_counter, tag_tvb, tag_off, 2,
1602 if (tag_off + 2 > tag_len)
1605 count = tvb_get_letohs(tag_tvb, tag_off);
1606 g_snprintf(out_buff, SHORT_STR, "# of PMKIDs: %u", count);
1607 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off, 2, out_buff);
1610 /* PMKID List (16 * n octets) */
1611 for (i = 0; i < count; i++) {
1612 if (tag_off + PMKID_LEN > tag_len)
1614 g_snprintf(out_buff, SHORT_STR, "PMKID %u: %s", i,
1615 tvb_bytes_to_str(tag_tvb, tag_off, PMKID_LEN));
1616 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off,
1617 PMKID_LEN, out_buff);
1618 tag_off += PMKID_LEN;
1622 if (tag_off < tag_len)
1623 proto_tree_add_string(tree, tag_interpretation, tag_tvb, tag_off,
1624 tag_len - tag_off, "Not interpreted");
1627 /* ************************************************************************* */
1628 /* Dissect and add tagged (optional) fields to proto tree */
1629 /* ************************************************************************* */
1631 static const value_string tag_num_vals[] = {
1632 { TAG_SSID, "SSID parameter set" },
1633 { TAG_SUPP_RATES, "Supported Rates" },
1634 { TAG_FH_PARAMETER, "FH Parameter set" },
1635 { TAG_DS_PARAMETER, "DS Parameter set" },
1636 { TAG_CF_PARAMETER, "CF Parameter set" },
1637 { TAG_TIM, "(TIM) Traffic Indication Map" },
1638 { TAG_IBSS_PARAMETER, "IBSS Parameter set" },
1639 { TAG_COUNTRY_INFO, "Country Information" },
1640 { TAG_FH_HOPPING_PARAMETER, "Hopping Pattern Parameters" },
1641 { TAG_CHALLENGE_TEXT, "Challenge text" },
1642 { TAG_ERP_INFO, "ERP Information" },
1643 { TAG_ERP_INFO_OLD, "ERP Information" },
1644 { TAG_RSN_IE, "RSN Information" },
1645 { TAG_EXT_SUPP_RATES, "Extended Supported Rates" },
1646 { TAG_CISCO_UNKNOWN_1, "Cisco Unknown 1 + Device Name" },
1647 { TAG_CISCO_UNKNOWN_2, "Cisco Unknown 2" },
1648 { TAG_VENDOR_SPECIFIC_IE, "Vendor Specific" },
1649 { TAG_SYMBOL_PROPRIETARY, "Symbol Proprietary"},
1650 { TAG_AGERE_PROPRIETARY, "Agere Proprietary"},
1651 { TAG_REQUEST, "Request"},
1652 { TAG_QBSS_LOAD, "QBSS Load Element"},
1653 { TAG_EDCA_PARAM_SET, "EDCA Parameter Set"},
1654 { TAG_TSPEC, "Traffic Specification"},
1655 { TAG_TCLAS, "Traffic Classification"},
1656 { TAG_SCHEDULE, "Schedule"},
1657 { TAG_TS_DELAY, "TS Delay"},
1658 { TAG_TCLAS_PROCESS, "TCLAS Processing"},
1659 { TAG_QOS_CAPABILITY, "QoS Capability"},
1660 { TAG_POWER_CONSTRAINT, "Power Constraint"},
1661 { TAG_POWER_CAPABILITY, "Power Capability"},
1662 { TAG_TPC_REQUEST, "TPC Request"},
1663 { TAG_TPC_REPORT, "TPC Report"},
1664 { TAG_SUPPORTED_CHANNELS, "Supported Channels"},
1665 { TAG_CHANNEL_SWITCH_ANN, "Channel Switch Announcement"},
1666 { TAG_MEASURE_REQ, "Measurement Request"},
1667 { TAG_MEASURE_REP, "Measurement Report"},
1668 { TAG_QUIET, "Quiet"},
1669 { TAG_IBSS_DFS, "IBSS DFS"},
1673 static const value_string environment_vals[] = {
1675 { 0x4f, "Outdoor" },
1680 static int beacon_padding = 0; /* beacon padding bug */
1682 add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int offset)
1686 const guint8 *tag_data_ptr;
1687 guint32 tag_no, tag_len;
1690 char out_buff[SHORT_STR];
1691 char print_buff[SHORT_STR];
1692 proto_tree * orig_tree=tree;
1695 tag_no = tvb_get_guint8(tvb, offset);
1696 tag_len = tvb_get_guint8(tvb, offset + 1);
1698 ti=proto_tree_add_text(orig_tree,tvb,offset,tag_len+2,"%s",
1699 val_to_str(tag_no, tag_num_vals,
1700 (tag_no >= 17 && tag_no <= 31) ?
1701 "Reserved for challenge text" : "Reserved tag number" ));
1702 tree=proto_item_add_subtree(ti,ett_80211_mgt_ie);
1704 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
1705 "Tag Number: %u (%s)",
1707 val_to_str(tag_no, tag_num_vals,
1708 (tag_no >= 17 && tag_no <= 31) ?
1709 "Reserved for challenge text" :
1710 "Reserved tag number"));
1711 proto_tree_add_uint (tree, (tag_no==TAG_TIM ? tim_length : tag_length), tvb, offset + 1, 1, tag_len);
1717 if(beacon_padding == 0) /* padding bug */
1719 guint8 *ssid; /* The SSID may consist of arbitrary bytes */
1721 ssid = tvb_get_ephemeral_string(tvb, offset + 2, tag_len);
1722 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1723 tag_len, (char *) ssid);
1724 if (check_col (pinfo->cinfo, COL_INFO)) {
1726 col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: \"%s\"",
1727 format_text(ssid, tag_len));
1729 col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: Broadcast");
1733 proto_item_append_text(ti, ": \"%s\"",
1734 format_text(ssid, tag_len));
1736 proto_item_append_text(ti, ": Broadcast");
1738 beacon_padding++; /* padding bug */
1742 case TAG_SUPP_RATES:
1743 case TAG_EXT_SUPP_RATES:
1746 proto_tree_add_text (tree, tvb, offset + 2, tag_len,
1747 "Tag length %u too short, must be > 0", tag_len);
1751 tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
1752 for (i = 0, n = 0; i < tag_len && n < SHORT_STR; i++) {
1753 ret = g_snprintf (print_buff + n, SHORT_STR - n, "%2.1f%s ",
1754 (tag_data_ptr[i] & 0x7F) * 0.5,
1755 (tag_data_ptr[i] & 0x80) ? "(B)" : "");
1756 if (ret == -1 || ret >= SHORT_STR - n) {
1757 /* Some versions of snprintf return -1 if they'd truncate
1758 the output. Others return <buf_size> or greater. */
1763 g_snprintf (out_buff, SHORT_STR, "Supported rates: %s [Mbit/sec]", print_buff);
1764 out_buff[SHORT_STR-1] = '\0';
1765 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1767 proto_item_append_text(ti, ": %s", print_buff);
1770 case TAG_FH_PARAMETER:
1773 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 5",
1777 g_snprintf (out_buff, SHORT_STR,
1778 "Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, Hop Index %2d",
1779 tvb_get_letohs(tvb, offset + 2),
1780 tvb_get_guint8(tvb, offset + 4),
1781 tvb_get_guint8(tvb, offset + 5),
1782 tvb_get_guint8(tvb, offset + 6));
1783 out_buff[SHORT_STR-1] = '\0';
1784 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1788 case TAG_DS_PARAMETER:
1791 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
1795 g_snprintf (out_buff, SHORT_STR, "Current Channel: %u",
1796 tvb_get_guint8(tvb, offset + 2));
1797 out_buff[SHORT_STR-1] = '\0';
1798 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1800 proto_item_append_text(ti, ": %s", out_buff);
1803 case TAG_CF_PARAMETER:
1806 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 6",
1810 g_snprintf (out_buff, SHORT_STR, "CFP count: %u",
1811 tvb_get_guint8(tvb, offset + 2));
1812 out_buff[SHORT_STR-1] = '\0';
1813 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2,
1814 1, out_buff, "%s", out_buff);
1815 g_snprintf (out_buff, SHORT_STR, "CFP period: %u",
1816 tvb_get_guint8(tvb, offset + 3));
1817 out_buff[SHORT_STR-1] = '\0';
1818 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 3,
1819 1, out_buff, "%s", out_buff);
1820 g_snprintf (out_buff, SHORT_STR, "CFP max duration: %u",
1821 tvb_get_letohs(tvb, offset + 4));
1822 out_buff[SHORT_STR-1] = '\0';
1823 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 4,
1824 2, out_buff, "%s", out_buff);
1825 g_snprintf (out_buff, SHORT_STR, "CFP Remaining: %u",
1826 tvb_get_letohs(tvb, offset + 6));
1827 out_buff[SHORT_STR-1] = '\0';
1828 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 6,
1829 2, out_buff, "%s", out_buff);
1830 proto_item_append_text(ti, ": CFP count %u, CFP period %u, CFP max duration %u, "
1832 tvb_get_guint8(tvb, offset + 2),
1833 tvb_get_guint8(tvb, offset + 3),
1834 tvb_get_letohs(tvb, offset + 4),
1835 tvb_get_letohs(tvb, offset + 6));
1841 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 4",
1851 proto_tree_add_item(tree, tim_dtim_count, tvb,
1852 offset + 2, 1, TRUE);
1853 proto_tree_add_item(tree, tim_dtim_period, tvb,
1854 offset + 3, 1, TRUE);
1855 proto_item_append_text(ti, ": DTIM %u of %u bitmap",
1856 tvb_get_guint8(tvb, offset + 2),
1857 tvb_get_guint8(tvb, offset + 3));
1859 bmapctl = tvb_get_guint8(tvb, offset + 4);
1860 bmapoff = bmapctl>>1;
1861 proto_tree_add_uint_format(tree, tim_bmapctl, tvb,
1862 offset + 4, 1, bmapctl,
1863 "Bitmap Control: 0x%02X (mcast:%u, bitmap offset %u)",
1864 bmapctl, bmapctl&1, bmapoff);
1866 bmaplen = tag_len - 3;
1867 bmap = tvb_get_ptr(tvb, offset + 5, bmaplen);
1868 if (bmaplen==1 && 0==bmap[0] && !(bmapctl&1)) {
1869 proto_item_append_text(ti, " empty");
1872 proto_item_append_text(ti, " mcast");
1875 if (bmaplen>1 || bmap[0]) {
1876 int len=g_snprintf (out_buff, SHORT_STR,
1877 "Bitmap: traffic for AID's:");
1879 for (i=0;i<bmaplen*8;i++) {
1880 if (bmap[i/8] & (1<<(i%8))) {
1881 int aid=i+2*bmapoff*8;
1882 len+=g_snprintf (out_buff+len, SHORT_STR-len," %u", aid);
1883 proto_item_append_text(ti, " %u", aid);
1884 if (len>=SHORT_STR) {
1889 out_buff[SHORT_STR-1] = '\0';
1890 proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 5,
1891 bmaplen, out_buff, "%s", out_buff);
1896 case TAG_IBSS_PARAMETER:
1899 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
1903 g_snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
1904 tvb_get_letohs(tvb, offset + 2));
1905 out_buff[SHORT_STR-1] = '\0';
1906 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1908 proto_item_append_text(ti, ": %s", out_buff);
1911 case TAG_COUNTRY_INFO: /* IEEE 802.11d-2001 and IEEE 802.11j-2004 */
1917 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 3",
1921 tvb_memcpy(tvb, ccode, offset + 2, 2);
1923 g_snprintf (out_buff, SHORT_STR, "Country Code: %s, %s Environment",
1924 format_text(ccode, 2),
1925 val_to_str(tvb_get_guint8(tvb, offset + 4), environment_vals,"Unknown (0x%02x)"));
1926 out_buff[SHORT_STR-1] = '\0';
1927 proto_item_append_text(ti, ": %s", out_buff);
1928 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,3, out_buff);
1930 for (i = 3; (i + 3) <= tag_len; i += 3)
1932 guint8 val1, val2, val3;
1933 val1 = tvb_get_guint8(tvb, offset + 2 + i);
1934 val2 = tvb_get_guint8(tvb, offset + 3 + i);
1935 val3 = tvb_get_guint8(tvb, offset + 4 + i);
1937 if (val1 <= 200) { /* 802.11d */
1938 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
1939 " Start Channel: %u, Channels: %u, Max TX Power: %d dBm",
1940 val1, val2, (gint) val3);
1941 } else { /* 802.11j */
1942 proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2+i,3, out_buff,
1943 " Reg Extension Id: %u, Regulatory Class: %u, Coverage Class: %u",
1951 if (tag_len < 4 || tag_len >5)
1953 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Wrong QBSS Tag Length %u", tag_len);
1959 /* QBSS Version 1 */
1960 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 1,
1961 tag_len, "Cisco QBSS Version 1 - non CCA");
1963 /* Extract Values */
1964 proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 1);
1965 proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
1966 proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
1967 proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 1, FALSE);
1969 else if (tag_len == 5)
1971 /* QBSS Version 2 */
1972 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
1973 tag_len, "802.11e CCA Version");
1975 /* Extract Values */
1976 proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 2);
1977 proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
1978 proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
1979 proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 2, FALSE);
1983 case TAG_FH_HOPPING_PARAMETER:
1986 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 2",
1990 g_snprintf (out_buff, SHORT_STR, "Prime Radix: %u, Number of Channels: %u",
1991 tvb_get_guint8(tvb, offset + 2),
1992 tvb_get_guint8(tvb, offset + 3));
1993 out_buff[SHORT_STR-1] = '\0';
1994 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2, tag_len, out_buff);
1995 proto_item_append_text(ti, ": %s", out_buff);
2001 proto_tree_add_text (tree, tvb, offset + 2, tag_len,
2002 "TSPEC tag length %u != 55", tag_len);
2005 add_fixed_field (tree, tvb, offset + 2, FIELD_QOS_TS_INFO);
2006 proto_tree_add_item(tree, tspec_nor_msdu, tvb, offset + 5, 2, TRUE);
2007 proto_tree_add_item(tree, tspec_max_msdu, tvb, offset + 7, 2, TRUE);
2008 proto_tree_add_item(tree, tspec_min_srv, tvb, offset + 9, 4, TRUE);
2009 proto_tree_add_item(tree, tspec_max_srv, tvb, offset + 13, 4, TRUE);
2010 proto_tree_add_item(tree, tspec_inact_int, tvb, offset + 17, 4, TRUE);
2011 proto_tree_add_item(tree, tspec_susp_int, tvb, offset + 21, 4, TRUE);
2012 proto_tree_add_item(tree, tspec_srv_start, tvb, offset + 25, 4, TRUE);
2013 proto_tree_add_item(tree, tspec_min_data, tvb, offset + 29, 4, TRUE);
2014 proto_tree_add_item(tree, tspec_mean_data, tvb, offset + 33, 4, TRUE);
2015 proto_tree_add_item(tree, tspec_peak_data, tvb, offset + 37, 4, TRUE);
2016 proto_tree_add_item(tree, tspec_burst_size, tvb, offset + 41, 4, TRUE);
2017 proto_tree_add_item(tree, tspec_delay_bound, tvb, offset + 45, 4, TRUE);
2018 proto_tree_add_item(tree, tspec_min_phy, tvb, offset + 49, 4, TRUE);
2019 proto_tree_add_item(tree, tspec_surplus, tvb, offset + 53, 2, TRUE);
2020 proto_tree_add_item(tree, tspec_medium, tvb, offset + 55, 2, TRUE);
2026 proto_tree_add_text (tree, tvb, offset + 2, tag_len,
2027 "TS_DELAY tag length %u != 4", tag_len);
2030 proto_tree_add_item(tree, ts_delay, tvb, offset + 2, 4, TRUE);
2036 proto_tree_add_text (tree, tvb, offset + 2, tag_len,
2037 "TCLAS element is too small %u", tag_len);
2044 type = tvb_get_guint8(tvb, offset + 2);
2045 proto_tree_add_item(tree, hf_tsinfo_up, tvb, offset + 2, 1, TRUE);
2046 proto_tree_add_item(tree, hf_class_type, tvb, offset + 3, 1, TRUE);
2047 proto_tree_add_item(tree, hf_class_mask, tvb, offset + 4, 1, TRUE);
2051 proto_tree_add_item(tree, ff_src_mac_addr, tvb, offset + 5,
2053 proto_tree_add_item(tree, ff_dst_mac_addr, tvb, offset + 11,
2055 proto_tree_add_item(tree, hf_ether_type, tvb, offset + 17,
2060 version = tvb_get_guint8(tvb, offset + 5);
2061 proto_tree_add_item(tree, cf_version, tvb, offset + 5, 1, TRUE);
2064 proto_tree_add_item(tree, cf_ipv4_src, tvb, offset + 6,
2066 proto_tree_add_item(tree, cf_ipv4_dst, tvb, offset + 10,
2068 proto_tree_add_item(tree, cf_src_port, tvb, offset + 14,
2070 proto_tree_add_item(tree, cf_dst_port, tvb, offset + 16,
2072 proto_tree_add_item(tree, cf_dscp, tvb, offset + 18,
2074 proto_tree_add_item(tree, cf_protocol, tvb, offset + 19,
2077 else if (version == 6)
2079 proto_tree_add_item(tree, cf_ipv6_src, tvb, offset + 6,
2081 proto_tree_add_item(tree, cf_ipv6_dst, tvb, offset + 22,
2083 proto_tree_add_item(tree, cf_src_port, tvb, offset + 38,
2085 proto_tree_add_item(tree, cf_dst_port, tvb, offset + 40,
2087 proto_tree_add_item(tree, cf_flow, tvb, offset + 42,
2093 proto_tree_add_item(tree, cf_tag_type, tvb, offset + 5,
2103 case TAG_TCLAS_PROCESS:
2106 proto_tree_add_text (tree, tvb, offset + 2, tag_len,
2107 "TCLAS_PROCESS element length %u != 1", tag_len);
2110 proto_tree_add_item(tree, hf_tclas_process, tvb, offset + 2, 1, TRUE);
2116 proto_tree_add_text (tree, tvb, offset + 2, tag_len,
2117 "TCLAS_PROCESS element length %u != 14", tag_len);
2120 add_fixed_field (tree, tvb, offset + 2, FIELD_SCHEDULE_INFO);
2121 proto_tree_add_item(tree, hf_sched_srv_start, tvb, offset + 4, 4, TRUE);
2122 proto_tree_add_item(tree, hf_sched_srv_int, tvb, offset + 8, 4, TRUE);
2123 proto_tree_add_item(tree, hf_sched_spec_int, tvb, offset + 12, 2, TRUE);
2126 case TAG_CHALLENGE_TEXT:
2127 g_snprintf (out_buff, SHORT_STR, "Challenge text: %s",
2128 tvb_bytes_to_str(tvb, offset + 2, tag_len));
2129 out_buff[SHORT_STR-1] = '\0';
2130 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
2135 case TAG_ERP_INFO_OLD:
2141 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 1",
2145 erp_info = tvb_get_guint8 (tvb, offset + 2);
2146 g_snprintf (print_buff, SHORT_STR, "%sNon-ERP STAs, %suse protection, %s preambles",
2147 erp_info & 0x01 ? "" : "no ",
2148 erp_info & 0x02 ? "" : "do not ",
2149 /* 802.11g, 7.3.2.13: 1 means "one or more ... STAs
2150 * are not short preamble capable" */
2151 erp_info & 0x04 ? "long": "short or long");
2152 print_buff[SHORT_STR-1] = '\0';
2153 g_snprintf (out_buff, SHORT_STR,
2154 "ERP info: 0x%x (%s)",erp_info,print_buff);
2155 out_buff[SHORT_STR-1] = '\0';
2156 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
2158 proto_item_append_text(ti, ": %s", print_buff);
2162 case TAG_CISCO_UNKNOWN_1:
2163 /* The Name of the sending device starts at offset 10 and is up to
2164 15 or 16 bytes in length, \0 padded */
2167 proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Tag length %u too short, must be >= 26",
2171 /* A cisco AP transmits the first 15 bytes of the AP name, probably
2172 followed by '\0' for ASCII termination */
2173 g_snprintf (out_buff, SHORT_STR, "%.16s",
2174 tvb_format_stringzpad(tvb, offset + 12, 16));
2175 out_buff[SHORT_STR-1] = '\0';
2176 proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 2,
2177 tag_len, "", "Tag interpretation: Unknown + Name: %s #Clients: %u",
2179 /* Total number off associated clients and
2180 repeater access points */
2181 tvb_get_guint8(tvb, offset + 28));
2182 if (check_col (pinfo->cinfo, COL_INFO)) {
2183 col_append_fstr(pinfo->cinfo, COL_INFO, ", Name: \"%s\"", out_buff);
2187 case TAG_VENDOR_SPECIFIC_IE:
2188 tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
2190 oui = tvb_get_ntoh24(tvb, offset + 2);
2191 tag_tvb = tvb_new_subset(tvb, offset + 2, tag_len, tag_len);
2193 #define WPAWME_OUI 0x0050F2
2194 #define RSNOUI_VAL 0x000FAC
2198 dissect_vendor_ie_wpawme(ti, tree, tag_tvb);
2201 dissect_vendor_ie_rsn(ti, tree, tag_tvb);
2203 case OUI_CISCOWL: /* Cisco Wireless (Aironet) */
2204 dissect_vendor_ie_aironet(ti, tree, tvb, offset + 5, tag_len - 3);
2207 tag_data_ptr = tvb_get_ptr(tag_tvb, 0, 3);
2208 proto_tree_add_bytes_format (tree, tag_oui, tvb, offset + 2, 3,
2209 tag_data_ptr, "Vendor: %s", get_manuf_name(tag_data_ptr));
2210 proto_item_append_text(ti, ": %s", get_manuf_name(tag_data_ptr));
2211 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 5,
2212 tag_len - 3, "Not interpreted");
2220 tag_tvb = tvb_new_subset(tvb, offset + 2, tag_len, tag_len);
2221 dissect_rsn_ie(tree, tag_tvb);
2225 tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
2226 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
2227 tag_len, "Not interpreted");
2228 proto_item_append_text(ti, ": Tag %u Len %u", tag_no, tag_len);
2236 ieee_80211_add_tagged_parameters (tvbuff_t * tvb, int offset, packet_info * pinfo,
2237 proto_tree * tree, int tagged_parameters_len)
2241 beacon_padding = 0; /* this is for the beacon padding confused with ssid fix */
2242 while (tagged_parameters_len > 0) {
2243 if ((next_len=add_tagged_field (pinfo, tree, tvb, offset))==0)
2245 if (next_len > tagged_parameters_len) {
2246 /* XXX - flag this as an error? */
2247 next_len = tagged_parameters_len;
2250 tagged_parameters_len -= next_len;
2254 /* ************************************************************************* */
2255 /* Dissect 802.11 management frame */
2256 /* ************************************************************************* */
2258 dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
2261 proto_item *ti = NULL;
2262 proto_tree *mgt_tree;
2263 proto_tree *fixed_tree;
2264 proto_tree *tagged_tree;
2266 int tagged_parameter_tree_len;
2270 CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
2272 ti = proto_tree_add_item (tree, proto_wlan_mgt, tvb, 0, -1, FALSE);
2273 mgt_tree = proto_item_add_subtree (ti, ett_80211_mgt);
2275 switch (COMPOSE_FRAME_TYPE(fcf))
2279 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
2280 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
2281 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
2282 offset = 4; /* Size of fixed fields */
2284 tagged_parameter_tree_len =
2285 tvb_reported_length_remaining(tvb, offset);
2286 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2287 tagged_parameter_tree_len);
2288 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2289 tagged_parameter_tree_len);
2293 case MGT_ASSOC_RESP:
2294 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
2295 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
2296 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
2297 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
2298 offset = 6; /* Size of fixed fields */
2300 tagged_parameter_tree_len =
2301 tvb_reported_length_remaining(tvb, offset);
2302 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2303 tagged_parameter_tree_len);
2304 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2305 tagged_parameter_tree_len);
2309 case MGT_REASSOC_REQ:
2310 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
2311 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
2312 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
2313 add_fixed_field (fixed_tree, tvb, 4, FIELD_CURRENT_AP_ADDR);
2314 offset = 10; /* Size of fixed fields */
2316 tagged_parameter_tree_len =
2317 tvb_reported_length_remaining(tvb, offset);
2318 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2319 tagged_parameter_tree_len);
2320 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2321 tagged_parameter_tree_len);
2324 case MGT_REASSOC_RESP:
2325 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
2326 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
2327 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
2328 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
2329 offset = 6; /* Size of fixed fields */
2331 tagged_parameter_tree_len =
2332 tvb_reported_length_remaining(tvb, offset);
2333 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2334 tagged_parameter_tree_len);
2335 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2336 tagged_parameter_tree_len);
2342 tagged_parameter_tree_len =
2343 tvb_reported_length_remaining(tvb, offset);
2344 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2345 tagged_parameter_tree_len);
2346 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2347 tagged_parameter_tree_len);
2351 case MGT_PROBE_RESP:
2352 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
2353 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
2354 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
2355 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
2356 offset = 12; /* Size of fixed fields */
2358 tagged_parameter_tree_len =
2359 tvb_reported_length_remaining(tvb, offset);
2360 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2361 tagged_parameter_tree_len);
2362 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2363 tagged_parameter_tree_len);
2367 case MGT_BEACON: /* Dissect protocol payload fields */
2368 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
2369 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
2370 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
2371 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
2372 offset = 12; /* Size of fixed fields */
2374 tagged_parameter_tree_len =
2375 tvb_reported_length_remaining(tvb, offset);
2376 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2377 tagged_parameter_tree_len);
2378 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2379 tagged_parameter_tree_len);
2388 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2389 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
2393 case MGT_AUTHENTICATION:
2394 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
2395 add_fixed_field (fixed_tree, tvb, 0, FIELD_AUTH_ALG);
2396 add_fixed_field (fixed_tree, tvb, 2, FIELD_AUTH_TRANS_SEQ);
2397 add_fixed_field (fixed_tree, tvb, 4, FIELD_STATUS_CODE);
2398 offset = 6; /* Size of fixed fields */
2400 tagged_parameter_tree_len =
2401 tvb_reported_length_remaining(tvb, offset);
2402 if (tagged_parameter_tree_len != 0)
2404 tagged_tree = get_tagged_parameter_tree (mgt_tree,
2407 tagged_parameter_tree_len);
2408 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2409 tagged_parameter_tree_len);
2414 case MGT_DEAUTHENTICATION:
2415 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2416 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
2421 switch (tvb_get_guint8(tvb, 0))
2424 case CAT_SPECTRUM_MGMT:
2425 switch (tvb_get_guint8(tvb, 1))
2427 case SM_ACTION_MEASUREMENT_REQUEST:
2428 case SM_ACTION_MEASUREMENT_REPORT:
2429 case SM_ACTION_TPC_REQUEST:
2430 case SM_ACTION_TPC_REPORT:
2431 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
2432 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2433 add_fixed_field (fixed_tree, tvb, 1, FIELD_ACTION_CODE);
2434 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2435 offset = 3; /* Size of fixed fields */
2438 case SM_ACTION_CHAN_SWITCH_ANNC:
2439 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2440 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2441 offset = 2; /* Size of fixed fields */
2445 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2446 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2447 offset = 2; /* Size of fixed fields */
2453 switch (tvb_get_guint8(tvb, 1))
2455 case SM_ACTION_ADDTS_REQUEST:
2456 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
2457 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2458 add_fixed_field (fixed_tree, tvb, 1, FIELD_QOS_ACTION_CODE);
2459 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2463 case SM_ACTION_ADDTS_RESPONSE:
2464 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 5);
2465 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2466 add_fixed_field (fixed_tree, tvb, 1, FIELD_QOS_ACTION_CODE);
2467 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2468 add_fixed_field (fixed_tree, tvb, 3, FIELD_STATUS_CODE);
2472 case SM_ACTION_DELTS:
2473 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 7);
2474 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2475 add_fixed_field (fixed_tree, tvb, 1, FIELD_QOS_ACTION_CODE);
2476 add_fixed_field (fixed_tree, tvb, 2, FIELD_QOS_TS_INFO);
2477 add_fixed_field (fixed_tree, tvb, 5, FIELD_REASON_CODE);
2481 case SM_ACTION_QOS_SCHEDULE:
2482 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2483 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2484 add_fixed_field (fixed_tree, tvb, 1, FIELD_QOS_ACTION_CODE);
2489 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2490 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2491 offset = 2; /* Size of fixed fields */
2497 switch (tvb_get_guint8(tvb, 1))
2499 case SM_ACTION_DLS_REQUEST:
2500 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 18);
2501 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2502 add_fixed_field (fixed_tree, tvb, 1, FIELD_DLS_ACTION_CODE);
2503 add_fixed_field (fixed_tree, tvb, 2, FIELD_DST_MAC_ADDR);
2504 add_fixed_field (fixed_tree, tvb, 8, FIELD_SRC_MAC_ADDR);
2505 add_fixed_field (fixed_tree, tvb, 14, FIELD_CAP_INFO);
2506 add_fixed_field (fixed_tree, tvb, 16, FIELD_DLS_TIMEOUT);
2510 case SM_ACTION_DLS_RESPONSE:
2511 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 16);
2512 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2513 add_fixed_field (fixed_tree, tvb, 1, FIELD_DLS_ACTION_CODE);
2514 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
2515 add_fixed_field (fixed_tree, tvb, 4, FIELD_DST_MAC_ADDR);
2516 add_fixed_field (fixed_tree, tvb, 10, FIELD_SRC_MAC_ADDR);
2518 if (!ff_status_code)
2519 add_fixed_field (fixed_tree, tvb, 16, FIELD_CAP_INFO);
2522 case SM_ACTION_DLS_TEARDOWN:
2523 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 18);
2524 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2525 add_fixed_field (fixed_tree, tvb, 1, FIELD_DLS_ACTION_CODE);
2526 add_fixed_field (fixed_tree, tvb, 2, FIELD_DST_MAC_ADDR);
2527 add_fixed_field (fixed_tree, tvb, 8, FIELD_SRC_MAC_ADDR);
2528 add_fixed_field (fixed_tree, tvb, 14, FIELD_REASON_CODE);
2533 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
2534 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2535 offset = 2; /* Size of fixed fields */
2540 case CAT_MGMT_NOTIFICATION: /* Management notification frame */
2541 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
2542 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2543 add_fixed_field (fixed_tree, tvb, 1, FIELD_WME_ACTION_CODE);
2544 add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
2545 add_fixed_field (fixed_tree, tvb, 3, FIELD_WME_STATUS_CODE);
2546 offset = 4; /* Size of fixed fields */
2550 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 1);
2551 add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
2552 offset = 1; /* Size of fixed fields */
2556 tagged_parameter_tree_len =
2557 tvb_reported_length_remaining(tvb, offset);
2558 if (tagged_parameter_tree_len != 0)
2560 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
2561 tagged_parameter_tree_len);
2562 ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
2563 tagged_parameter_tree_len);
2570 set_src_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
2572 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
2573 col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "%s (%s)",
2574 get_ether_name(addr), type);
2575 if (check_col(pinfo->cinfo, COL_UNRES_DL_SRC))
2576 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s",
2577 ether_to_str(addr));
2581 set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
2583 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
2584 col_add_fstr(pinfo->cinfo, COL_RES_DL_DST, "%s (%s)",
2585 get_ether_name(addr), type);
2586 if (check_col(pinfo->cinfo, COL_UNRES_DL_DST))
2587 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s",
2588 ether_to_str(addr));
2592 crc32_802_tvb_padded(tvbuff_t *tvb, guint hdr_len, guint hdr_size, guint len)
2596 c_crc = crc32_ccitt_tvb(tvb, hdr_len);
2597 c_crc = crc32_ccitt_seed(tvb_get_ptr(tvb, hdr_size, len), len, ~c_crc);
2600 c_crc = ((unsigned char)(c_crc>>0)<<24) |
2601 ((unsigned char)(c_crc>>8)<<16) |
2602 ((unsigned char)(c_crc>>16)<<8) |
2603 ((unsigned char)(c_crc>>24)<<0);
2614 /* ************************************************************************* */
2615 /* Dissect 802.11 frame */
2616 /* ************************************************************************* */
2618 dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
2619 proto_tree * tree, gboolean fixed_length_header,
2620 gboolean has_radio_information, gint fcs_len,
2621 gboolean wlan_broken_fc, gboolean datapad)
2623 guint16 fcf, flags, frame_type_subtype;
2624 guint16 seq_control;
2625 guint32 seq_number, frag_number;
2626 gboolean more_frags;
2627 const guint8 *src = NULL;
2628 const guint8 *dst = NULL;
2629 const guint8 *bssid = NULL;
2630 proto_item *ti = NULL;
2631 proto_item *flag_item;
2632 proto_item *fc_item;
2633 proto_item *fcs_item;
2634 proto_tree *hdr_tree = NULL;
2635 proto_tree *flag_tree;
2636 proto_tree *fc_tree;
2637 proto_tree *fcs_tree;
2638 guint16 hdr_len, ohdr_len;
2639 gboolean has_fcs, fcs_good, fcs_bad;
2640 gint len, reported_len, ivlen;
2641 gboolean save_fragmented;
2642 tvbuff_t *volatile next_tvb = NULL;
2644 volatile encap_t encap_type;
2645 guint8 octet1, octet2;
2646 char out_buff[SHORT_STR];
2649 wlan_hdr *volatile whdr;
2650 static wlan_hdr whdrs[4];
2654 if (check_col (pinfo->cinfo, COL_PROTOCOL))
2655 col_set_str (pinfo->cinfo, COL_PROTOCOL, "IEEE 802.11");
2656 if (check_col (pinfo->cinfo, COL_INFO))
2657 col_clear (pinfo->cinfo, COL_INFO);
2659 /* Add the radio information, if present, to the column information */
2660 if (has_radio_information) {
2661 if (check_col(pinfo->cinfo, COL_TX_RATE)) {
2662 col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u",
2663 pinfo->pseudo_header->ieee_802_11.data_rate / 2,
2664 pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
2666 if (check_col(pinfo->cinfo, COL_RSSI)) {
2667 /* XX - this is a percentage, not a dBm or normalized or raw RSSI */
2668 col_add_fstr(pinfo->cinfo, COL_RSSI, "%u",
2669 pinfo->pseudo_header->ieee_802_11.signal_level);
2673 fcf = tvb_get_letohs (tvb, 0);
2674 if (wlan_broken_fc) {
2676 fcf = ((fcf & 0xff) << 8) | (((fcf & 0xff00) >> 8) & 0xff);
2678 if (fixed_length_header)
2679 hdr_len = DATA_LONG_HDR_LEN;
2681 hdr_len = find_header_length (fcf);
2684 hdr_len = roundup2(hdr_len, 4);
2685 frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
2687 if (check_col (pinfo->cinfo, COL_INFO))
2688 col_set_str (pinfo->cinfo, COL_INFO,
2689 val_to_str(frame_type_subtype, frame_type_subtype_vals,
2690 "Unrecognized (Reserved frame)"));
2692 flags = FCF_FLAGS (fcf);
2693 more_frags = HAVE_FRAGMENTS (flags);
2696 /* Add the radio information, if present, and the FC to the current tree */
2699 ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
2701 hdr_tree = proto_item_add_subtree (ti, ett_80211);
2703 if (has_radio_information) {
2704 proto_tree_add_uint_format(hdr_tree, hf_data_rate,
2706 pinfo->pseudo_header->ieee_802_11.data_rate,
2707 "Data Rate: %u.%u Mb/s",
2708 pinfo->pseudo_header->ieee_802_11.data_rate / 2,
2709 pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0);
2711 proto_tree_add_uint(hdr_tree, hf_channel,
2713 pinfo->pseudo_header->ieee_802_11.channel);
2715 proto_tree_add_uint_format(hdr_tree, hf_signal_strength,
2717 pinfo->pseudo_header->ieee_802_11.signal_level,
2718 "Signal Strength: %u%%",
2719 pinfo->pseudo_header->ieee_802_11.signal_level);
2722 proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
2724 wlan_broken_fc?1:0, 1,
2725 frame_type_subtype);
2727 fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb,
2730 "Frame Control: 0x%04X (%s)",
2731 fcf, wlan_broken_fc?"Swapped":"Normal");
2733 fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
2736 proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb,
2737 wlan_broken_fc?1:0, 1,
2738 FCF_PROT_VERSION (fcf));
2740 proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb,
2741 wlan_broken_fc?1:0, 1,
2742 FCF_FRAME_TYPE (fcf));
2744 proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
2746 wlan_broken_fc?1:0, 1,
2747 FCF_FRAME_SUBTYPE (fcf));
2750 proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb,
2751 wlan_broken_fc?0:1, 1,
2752 flags, "Flags: 0x%X", flags);
2754 flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
2756 proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb,
2757 wlan_broken_fc?0:1, 1,
2758 FLAGS_DS_STATUS (flags));
2759 proto_tree_add_boolean_hidden (flag_tree, hf_fc_to_ds, tvb, 1, 1,
2761 proto_tree_add_boolean_hidden (flag_tree, hf_fc_from_ds, tvb, 1, 1,
2764 proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb,
2765 wlan_broken_fc?0:1, 1,
2768 proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb,
2769 wlan_broken_fc?0:1, 1, flags);
2771 proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb,
2772 wlan_broken_fc?0:1, 1, flags);
2774 proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb,
2775 wlan_broken_fc?0:1, 1,
2778 proto_tree_add_boolean (flag_tree, hf_fc_protected, tvb,
2779 wlan_broken_fc?0:1, 1, flags);
2781 proto_tree_add_boolean (flag_tree, hf_fc_order, tvb,
2782 wlan_broken_fc?0:1, 1, flags);
2784 if (frame_type_subtype == CTRL_PS_POLL)
2785 proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
2786 ASSOC_ID(tvb_get_letohs(tvb,2)));
2789 proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
2790 tvb_get_letohs (tvb, 2));
2794 * Decode the part of the frame header that isn't the same for all
2801 switch (FCF_FRAME_TYPE (fcf))
2806 * All management frame types have the same header.
2808 src = tvb_get_ptr (tvb, 10, 6);
2809 dst = tvb_get_ptr (tvb, 4, 6);
2811 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
2812 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
2813 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
2814 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
2817 SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, tvb_get_ptr(tvb, 16,6));
2818 SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
2819 SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
2820 whdr->type = frame_type_subtype;
2822 seq_control = tvb_get_letohs(tvb, 22);
2823 frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
2824 seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
2826 if (check_col (pinfo->cinfo, COL_INFO))
2828 col_append_fstr(pinfo->cinfo, COL_INFO,
2829 ",SN=%d", seq_number);
2831 col_append_fstr(pinfo->cinfo, COL_INFO,
2832 ",FN=%d",frag_number);
2837 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
2839 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
2841 /* add items for wlan.addr filter */
2842 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
2843 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
2845 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
2846 tvb_get_ptr (tvb, 16, 6));
2848 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
2851 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
2857 switch (frame_type_subtype)
2861 src = tvb_get_ptr (tvb, 10, 6);
2862 dst = tvb_get_ptr (tvb, 4, 6);
2864 set_src_addr_cols(pinfo, src, "BSSID");
2865 set_dst_addr_cols(pinfo, dst, "BSSID");
2869 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6, dst);
2871 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
2877 src = tvb_get_ptr (tvb, 10, 6);
2878 dst = tvb_get_ptr (tvb, 4, 6);
2880 set_src_addr_cols(pinfo, src, "TA");
2881 set_dst_addr_cols(pinfo, dst, "RA");
2885 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2887 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
2893 dst = tvb_get_ptr (tvb, 4, 6);
2895 set_dst_addr_cols(pinfo, dst, "RA");
2898 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2902 case CTRL_ACKNOWLEDGEMENT:
2903 dst = tvb_get_ptr (tvb, 4, 6);
2905 set_dst_addr_cols(pinfo, dst, "RA");
2908 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2913 src = tvb_get_ptr (tvb, 10, 6);
2914 dst = tvb_get_ptr (tvb, 4, 6);
2916 set_src_addr_cols(pinfo, src, "BSSID");
2917 set_dst_addr_cols(pinfo, dst, "RA");
2921 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2922 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
2927 case CTRL_CFP_ENDACK:
2928 src = tvb_get_ptr (tvb, 10, 6);
2929 dst = tvb_get_ptr (tvb, 4, 6);
2931 set_src_addr_cols(pinfo, src, "BSSID");
2932 set_dst_addr_cols(pinfo, dst, "RA");
2936 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
2938 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
2942 case CTRL_BLOCK_ACK_REQ:
2944 src = tvb_get_ptr (tvb, 10, 6);
2945 dst = tvb_get_ptr (tvb, 4, 6);
2947 set_src_addr_cols(pinfo, src, "TA");
2948 set_dst_addr_cols(pinfo, dst, "RA");
2952 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
2954 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
2960 case CTRL_BLOCK_ACK:
2962 src = tvb_get_ptr (tvb, 10, 6);
2963 dst = tvb_get_ptr (tvb, 4, 6);
2965 set_src_addr_cols(pinfo, src, "TA");
2966 set_dst_addr_cols(pinfo, dst, "RA");
2970 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
2972 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
2974 /* TODO BAR Format */
2981 addr_type = FCF_ADDR_SELECTOR (fcf);
2983 /* In order to show src/dst address we must always do the following */
2988 src = tvb_get_ptr (tvb, 10, 6);
2989 dst = tvb_get_ptr (tvb, 4, 6);
2990 bssid = tvb_get_ptr (tvb, 16, 6);
2995 src = tvb_get_ptr (tvb, 16, 6);
2996 dst = tvb_get_ptr (tvb, 4, 6);
2997 bssid = tvb_get_ptr (tvb, 10, 6);
3002 src = tvb_get_ptr (tvb, 10, 6);
3003 dst = tvb_get_ptr (tvb, 16, 6);
3004 bssid = tvb_get_ptr (tvb, 4, 6);
3009 src = tvb_get_ptr (tvb, 24, 6);
3010 dst = tvb_get_ptr (tvb, 16, 6);
3011 bssid = tvb_get_ptr (tvb, 16, 6);
3015 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
3016 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
3017 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
3018 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
3022 SET_ADDRESS(&whdr->bssid, AT_ETHER, 6, bssid);
3023 SET_ADDRESS(&whdr->src, AT_ETHER, 6, src);
3024 SET_ADDRESS(&whdr->dst, AT_ETHER, 6, dst);
3025 whdr->type = frame_type_subtype;
3027 seq_control = tvb_get_letohs(tvb, 22);
3028 frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
3029 seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
3031 if (check_col (pinfo->cinfo, COL_INFO))
3033 col_append_fstr(pinfo->cinfo, COL_INFO,
3034 ",SN=%d", seq_number);
3036 col_append_fstr(pinfo->cinfo, COL_INFO,
3037 ",FN=%d",frag_number);
3040 /* Now if we have a tree we start adding stuff */
3049 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
3050 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
3051 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
3052 tvb_get_ptr (tvb, 16, 6));
3053 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
3055 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
3058 /* add items for wlan.addr filter */
3059 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
3060 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
3065 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
3066 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
3067 tvb_get_ptr (tvb, 10, 6));
3068 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6, src);
3069 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
3071 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
3074 /* add items for wlan.addr filter */
3075 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
3076 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, src);
3081 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
3082 tvb_get_ptr (tvb, 4, 6));
3083 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
3084 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
3086 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
3088 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
3091 /* add items for wlan.addr filter */
3092 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
3093 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
3098 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
3099 tvb_get_ptr (tvb, 4, 6));
3100 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
3101 tvb_get_ptr (tvb, 10, 6));
3102 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
3103 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
3105 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
3107 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6, src);
3109 /* add items for wlan.addr filter */
3110 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
3111 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 24, 6, src);
3119 len = tvb_length_remaining(tvb, hdr_len);
3120 reported_len = tvb_reported_length_remaining(tvb, hdr_len);
3124 case 0: /* Definitely has no FCS */
3128 case 4: /* Definitely has an FCS */
3132 default: /* Don't know - use "wlan_check_fcs" */
3133 has_fcs = wlan_check_fcs;
3139 * Well, this packet should, in theory, have an FCS.
3140 * Do we have the entire packet, and does it have enough data for
3143 if (reported_len < 4)
3146 * The packet is claimed not to even have enough data for a 4-byte
3148 * Pretend it doesn't have an FCS.
3152 else if (len < reported_len)
3155 * The packet is claimed to have enough data for a 4-byte FCS, but
3156 * we didn't capture all of the packet.
3157 * Slice off the 4-byte FCS from the reported length, and trim the
3158 * captured length so it's no more than the reported length; that
3159 * will slice off what of the FCS, if any, is in the captured
3163 if (len > reported_len)
3169 * We have the entire packet, and it includes a 4-byte FCS.
3170 * Slice it off, and put it into the tree.
3176 guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len);
3180 fcs = crc32_802_tvb_padded(tvb, ohdr_len, hdr_len, len);
3182 fcs = crc32_802_tvb(tvb, hdr_len + len);
3183 if (fcs == sent_fcs) {
3192 fcs_item = proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
3193 hdr_len + len, 4, sent_fcs,
3194 "Frame check sequence: 0x%08x [correct]", sent_fcs);
3196 fcs_item = proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
3197 hdr_len + len, 4, sent_fcs,
3198 "Frame check sequence: 0x%08x [incorrect, should be 0x%08x]",
3201 fcs_tree = proto_item_add_subtree(fcs_item, ett_fcs);
3203 fcs_item = proto_tree_add_boolean(fcs_tree,
3207 PROTO_ITEM_SET_GENERATED(fcs_item);
3209 fcs_item = proto_tree_add_boolean(fcs_tree,
3213 PROTO_ITEM_SET_GENERATED(fcs_item);
3221 * Only management and data frames have a body, so we don't have
3222 * anything more to do for other types of frames.
3224 switch (FCF_FRAME_TYPE (fcf))
3231 if (tree && DATA_FRAME_IS_QOS(frame_type_subtype))
3234 proto_item *qos_fields;
3235 proto_tree *qos_tree;
3238 guint16 qos_control;
3239 guint16 qos_priority;
3240 guint16 qos_ack_policy;
3242 guint16 qos_field_content;
3245 * We calculate the offset to the QoS header data as
3246 * an offset relative to the end of the header. But
3247 * when the header has been padded to align the data
3248 * this must be done relative to true header size, not
3249 * the padded/aligned value. To simplify this work we
3250 * stash the original header size in ohdr_len instead
3251 * of recalculating it.
3253 qosoff = ohdr_len - 2;
3254 qos_fields = proto_tree_add_text(hdr_tree, tvb, qosoff, 2,
3256 qos_tree = proto_item_add_subtree (qos_fields, ett_qos_parameters);
3258 qos_control = tvb_get_letohs(tvb, qosoff + 0);
3259 qos_priority = QOS_PRIORITY(qos_control);
3260 qos_ack_policy = QOS_ACK_POLICY(qos_control);
3261 qos_eosp = QOS_EOSP(qos_control);
3262 qos_field_content = QOS_FIELD_CONTENT( qos_control);
3264 proto_tree_add_uint_format (qos_tree, hf_qos_priority, tvb,
3265 qosoff, 2, qos_priority,
3266 "Priority: %d (%s) (%s)",
3267 qos_priority, qos_tags[qos_priority], qos_acs[qos_priority]);
3269 if (flags & FLAG_FROM_DS) {
3270 proto_tree_add_boolean (qos_tree, hf_qos_eosp, tvb,
3271 qosoff, 1, qos_eosp);
3273 if (DATA_FRAME_IS_CF_POLL(frame_type_subtype)) {
3275 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
3276 qosoff + 1, 1, qos_field_content, "TXOP Limit: %d ", qos_field_content);
3279 /* qap ps buffer state */
3280 proto_item *qos_ps_buf_state_fields;
3281 proto_tree *qos_ps_buf_state_tree;
3286 buf_state = QOS_PS_BUF_STATE(qos_field_content);
3287 buf_ac = QOS_PS_BUF_AC(qos_field_content); /*access category */
3288 buf_load = QOS_PS_BUF_LOAD(qos_field_content);
3290 qos_ps_buf_state_fields = proto_tree_add_text(qos_tree, tvb, qosoff + 1, 1,
3291 "QAP PS Buffer State: 0x%x", qos_field_content);
3292 qos_ps_buf_state_tree = proto_item_add_subtree (qos_ps_buf_state_fields, ett_qos_ps_buf_state);
3294 /* FIXME: hf_ values not defined
3295 proto_tree_add_boolean (qos_ps_buf_state_tree, hf_qos_buf_state, tvb,
3298 proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_ac, tvb,
3299 qosoff + 1, 1, buf_ac, "Priority: %d (%s)",
3300 buf_ac, wme_acs[buf_ac]);
3302 proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_load, tvb,
3303 qosoff + 1, 1, buf_load, "Buffered load: %d ", (buf_load * 4096));
3307 } else if (qos_eosp) {
3308 /* txop limit requested */
3309 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
3310 qosoff + 1, 1, qos_field_content, "Queue Size: %d ", (qos_field_content * 254));
3313 proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
3314 qosoff + 1, 1, qos_field_content, "TXOP Limit Requested: %d ", qos_field_content);
3317 proto_tree_add_uint (qos_tree, hf_qos_ack_policy, tvb, qosoff, 1,
3320 } /* end of qos control field */
3322 #ifdef HAVE_AIRPDCAP
3323 /* Davide Schiera (2006-11-21): process handshake packet with AirPDcap */
3324 /* the processing will take care of 4-way handshake sessions for WPA */
3325 /* and WPA2 decryption */
3326 if (enable_decryption && !pinfo->fd->flags.visited) {
3327 const guint8 *enc_data = tvb_get_ptr(tvb, 0, hdr_len+reported_len);
3328 AirPDcapPacketProcess(&airpdcap_ctx, enc_data, hdr_len+reported_len, NULL, 0, NULL, FALSE, FALSE, TRUE, FALSE);
3330 /* Davide Schiera -------------------------------------------------------- */
3334 * No-data frames don't have a body.
3336 if (DATA_FRAME_IS_NULL(frame_type_subtype))
3348 if (IS_PROTECTED(FCF_FLAGS(fcf))) {
3350 * It's a WEP or WPA encrypted frame; dissect the protections parameters
3351 * and decrypt the data, if we have a matching key. Otherwise display it as data.
3354 gboolean can_decrypt = FALSE;
3355 proto_tree *wep_tree = NULL;
3357 guint8 key, keybyte;
3359 /* Davide Schiera (2006-11-27): define algorithms constants and macros */
3360 #ifdef HAVE_AIRPDCAP
3361 #define PROTECTION_ALG_TKIP AIRPDCAP_KEY_TYPE_TKIP
3362 #define PROTECTION_ALG_CCMP AIRPDCAP_KEY_TYPE_CCMP
3363 #define PROTECTION_ALG_WEP AIRPDCAP_KEY_TYPE_WEP
3364 #define PROTECTION_ALG_RSNA PROTECTION_ALG_CCMP | PROTECTION_ALG_TKIP
3366 #define PROTECTION_ALG_WEP 0
3367 #define PROTECTION_ALG_TKIP 1
3368 #define PROTECTION_ALG_CCMP 2
3369 #define PROTECTION_ALG_RSNA PROTECTION_ALG_CCMP | PROTECTION_ALG_TKIP
3371 guint8 algorithm=-1;
3372 /* Davide Schiera (2006-11-27): added macros to check the algorithm */
3373 /* used could be TKIP or CCMP */
3374 #define IS_TKIP(tvb, hdr_len) (tvb_get_guint8(tvb, hdr_len + 1) & 0x20)
3375 #define IS_CCMP(tvb, hdr_len) (tvb_get_guint8(tvb, hdr_len + 2) == 0)
3376 /* Davide Schiera ----------------------------------------------------- */
3378 #ifdef HAVE_AIRPDCAP
3379 /* Davide Schiera (2006-11-21): recorded original lengths to pass them */
3380 /* to the packets process function */
3381 guint32 sec_header=0;
3382 guint32 sec_trailer=0;
3384 next_tvb = try_decrypt(tvb, hdr_len, reported_len, &algorithm, &sec_header, &sec_trailer);
3386 /* Davide Schiera ----------------------------------------------------- */
3388 keybyte = tvb_get_guint8(tvb, hdr_len + 3);
3389 key = KEY_OCTET_WEP_KEY(keybyte);
3390 if ((keybyte & KEY_EXTIV) && (len >= EXTIV_LEN)) {
3391 /* Extended IV; this frame is likely encrypted with TKIP or CCMP */
3395 proto_item *extiv_fields;
3397 #ifdef HAVE_AIRPDCAP
3398 /* Davide Schiera (2006-11-27): differentiated CCMP and TKIP if */
3400 if (algorithm==PROTECTION_ALG_TKIP)
3401 extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
3403 else if (algorithm==PROTECTION_ALG_CCMP)
3404 extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
3407 /* Davide Schiera -------------------------------------------- */
3409 /* Davide Schiera (2006-11-27): differentiated CCMP and TKIP if*/
3411 if (IS_TKIP(tvb, hdr_len)) {
3412 algorithm=PROTECTION_ALG_TKIP;
3413 extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
3415 } else if (IS_CCMP(tvb, hdr_len)) {
3416 algorithm=PROTECTION_ALG_CCMP;
3417 extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
3420 extiv_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 8,
3421 "TKIP/CCMP parameters");
3422 #ifdef HAVE_AIRPDCAP
3426 wep_tree = proto_item_add_subtree (extiv_fields, ett_wep_parameters);
3428 if (algorithm==PROTECTION_ALG_TKIP) {
3429 g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
3430 tvb_get_letohl(tvb, hdr_len + 4),
3431 tvb_get_guint8(tvb, hdr_len),
3432 tvb_get_guint8(tvb, hdr_len + 2));
3433 proto_tree_add_string(wep_tree, hf_tkip_extiv, tvb, hdr_len,
3434 EXTIV_LEN, out_buff);
3435 } else if (algorithm==PROTECTION_ALG_CCMP) {
3436 g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
3437 tvb_get_letohl(tvb, hdr_len + 4),
3438 tvb_get_guint8(tvb, hdr_len + 1),
3439 tvb_get_guint8(tvb, hdr_len));
3440 proto_tree_add_string(wep_tree, hf_ccmp_extiv, tvb, hdr_len,
3441 EXTIV_LEN, out_buff);
3444 proto_tree_add_uint(wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
3447 /* Subtract out the length of the IV. */
3449 reported_len -= EXTIV_LEN;
3451 /* It is unknown whether this is TKIP or CCMP, so let's not even try to
3452 * parse TKIP Michael MIC+ICV or CCMP MIC. */
3454 #ifdef HAVE_AIRPDCAP
3455 /* Davide Schiera (2006-11-21): enable TKIP and CCMP decryption */
3456 /* checking for the trailer */
3457 if (next_tvb!=NULL) {
3458 if (reported_len < sec_trailer) {
3459 /* There is no space for a trailer, ignore it and don't decrypt */
3461 } else if (len < reported_len) {
3462 /* There is space for a trailer, but we haven't capture all the */
3463 /* packet. Slice off the trailer, but don't try to decrypt */
3464 reported_len -= sec_trailer;
3465 if (len > reported_len)
3468 /* Ok, we have a trailer and the whole packet. Decrypt it! */
3469 /* TODO: At the moment we won't add the trailer to the tree, */
3470 /* so don't remove the trailer from the packet */
3472 reported_len -= sec_trailer;
3476 /* Davide Schiera -------------------------------------------------- */
3479 /* No Ext. IV - WEP packet */
3481 * XXX - pass the IV and key to "try_decrypt_wep()", and have it pass
3482 * them to "wep_decrypt()", rather than having "wep_decrypt()" extract
3485 * Also, just pass the data *following* the WEP parameters as the
3486 * buffer to decrypt.
3488 iv = tvb_get_ntoh24(tvb, hdr_len);
3490 proto_item *wep_fields;
3492 wep_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 4,
3495 wep_tree = proto_item_add_subtree (wep_fields, ett_wep_parameters);
3496 proto_tree_add_uint (wep_tree, hf_wep_iv, tvb, hdr_len, 3, iv);
3497 tvb_memcpy(tvb, iv_buff, hdr_len, 3);
3498 is_iv_bad = weak_iv(iv_buff);
3499 if (is_iv_bad != -1) {
3500 proto_tree_add_boolean_format (wep_tree, hf_wep_iv_weak,
3502 "Weak IV for key byte %d",
3507 proto_tree_add_uint (wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
3509 /* Subtract out the length of the IV. */
3514 /* Davide Schiera (2006-11-27): Even if the decryption was not */
3515 /* successful, set the algorithm */
3516 algorithm=PROTECTION_ALG_WEP;
3519 * Well, this packet should, in theory, have an ICV.
3520 * Do we have the entire packet, and does it have enough data for
3523 if (reported_len < 4) {
3525 * The packet is claimed not to even have enough data for a
3527 * Pretend it doesn't have an ICV.
3530 } else if (len < reported_len) {
3532 * The packet is claimed to have enough data for a 4-byte ICV,
3533 * but we didn't capture all of the packet.
3534 * Slice off the 4-byte ICV from the reported length, and trim
3535 * the captured length so it's no more than the reported length;
3536 * that will slice off what of the ICV, if any, is in the
3541 if (len > reported_len)
3545 * We have the entire packet, and it includes a 4-byte ICV.
3546 * Slice it off, and put it into the tree.
3548 * We only support decrypting if we have the the ICV.
3550 * XXX - the ICV is encrypted; we're putting the encrypted
3551 * value, not the decrypted value, into the tree.
3559 #ifndef HAVE_AIRPDCAP
3561 next_tvb = try_decrypt_wep(tvb, hdr_len, reported_len + 8);
3563 /* Davide Schiera (2006-11-26): decrypted before parsing header and */
3564 /* protection header */
3566 if (!can_decrypt || next_tvb == NULL) {
3568 * WEP decode impossible or failed, treat payload as raw data
3569 * and don't attempt fragment reassembly or further dissection.
3571 next_tvb = tvb_new_subset(tvb, hdr_len + ivlen, len, reported_len);
3574 /* Davide Schiera (2006-11-21): added WEP or WPA separation */
3575 if (algorithm==PROTECTION_ALG_WEP) {
3577 proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
3578 hdr_len + ivlen + len, 4,
3579 tvb_get_ntohl(tvb, hdr_len + ivlen + len),
3580 "WEP ICV: 0x%08x (not verified)",
3581 tvb_get_ntohl(tvb, hdr_len + ivlen + len));
3582 } else if (algorithm==PROTECTION_ALG_CCMP) {
3583 } else if (algorithm==PROTECTION_ALG_TKIP) {
3585 /* Davide Schiera (2006-11-21) ---------------------------------- */
3587 if (pinfo->ethertype != ETHERTYPE_CENTRINO_PROMISC)
3589 /* Some wireless drivers (such as Centrino) WEP payload already decrypted */
3590 call_dissector(data_handle, next_tvb, pinfo, tree);
3595 /* Davide Schiera (2006-11-21): added WEP or WPA separation */
3596 if (algorithm==PROTECTION_ALG_WEP) {
3598 proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
3599 hdr_len + ivlen + len, 4,
3600 tvb_get_ntohl(tvb, hdr_len + ivlen + len),
3601 "WEP ICV: 0x%08x (correct)",
3602 tvb_get_ntohl(tvb, hdr_len + ivlen + len));
3604 add_new_data_source(pinfo, next_tvb, "Decrypted WEP data");
3605 } else if (algorithm==PROTECTION_ALG_CCMP) {
3606 add_new_data_source(pinfo, next_tvb, "Decrypted CCMP data");
3607 } else if (algorithm==PROTECTION_ALG_TKIP) {
3608 add_new_data_source(pinfo, next_tvb, "Decrypted TKIP data");
3610 /* Davide Schiera (2006-11-21) ------------------------------------- */
3611 /* Davide Schiera (2006-11-27): undefine macros and definitions */
3614 #undef PROTECTION_ALG_CCMP
3615 #undef PROTECTION_ALG_TKIP
3616 #undef PROTECTION_ALG_WEP
3617 /* Davide Schiera -------------------------------------------------- */
3621 * WEP decryption successful!
3623 * Use the tvbuff we got back from the decryption; the data starts at
3624 * the beginning. The lengths are already correct for the decoded WEP
3631 * Not a WEP-encrypted frame; just use the data from the tvbuff
3634 * The payload starts at "hdr_len" (i.e., just past the 802.11
3635 * MAC header), the length of data in the tvbuff following the
3636 * 802.11 header is "len", and the length of data in the packet
3637 * following the 802.11 header is "reported_len".
3643 * Do defragmentation if "wlan_defragment" is true, and we have more
3644 * fragments or this isn't the first fragment.
3646 * We have to do some special handling to catch frames that
3647 * have the "More Fragments" indicator not set but that
3648 * don't show up as reassembled and don't have any other
3649 * fragments present. Some networking interfaces appear
3650 * to do reassembly even when you're capturing raw packets
3651 * *and* show the reassembled packet without the "More
3652 * Fragments" indicator set *but* with a non-zero fragment
3655 * "fragment_add_seq_802_11()" handles that; we want to call it
3656 * even if we have a short frame, so that it does those checks - if
3657 * the frame is short, it doesn't do reassembly on it.
3659 * (This could get some false positives if we really *did* only
3660 * capture the last fragment of a fragmented packet, but that's
3663 save_fragmented = pinfo->fragmented;
3664 if (wlan_defragment && (more_frags || frag_number != 0)) {
3665 fragment_data *fd_head;
3668 * If we've already seen this frame, look it up in the
3669 * table of reassembled packets, otherwise add it to
3670 * whatever reassembly is in progress, if any, and see
3673 fd_head = fragment_add_seq_802_11(next_tvb, hdr_len, pinfo, seq_number,
3674 wlan_fragment_table,
3675 wlan_reassembled_table,
3679 next_tvb = process_reassembled_data(tvb, hdr_len, pinfo,
3680 "Reassembled 802.11", fd_head,
3681 &frag_items, NULL, hdr_tree);
3684 * If this is the first fragment, dissect its contents, otherwise
3685 * just show it as a fragment.
3687 if (frag_number != 0) {
3688 /* Not the first fragment - don't dissect it. */
3691 /* First fragment, or not fragmented. Dissect what we have here. */
3693 /* Get a tvbuff for the payload. */
3694 next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len);
3697 * If this is the first fragment, but not the only fragment,
3698 * tell the next protocol that.
3701 pinfo->fragmented = TRUE;
3703 pinfo->fragmented = FALSE;
3707 if (next_tvb == NULL) {
3708 /* Just show this as an incomplete fragment. */
3709 if (check_col(pinfo->cinfo, COL_INFO))
3710 col_set_str(pinfo->cinfo, COL_INFO, "Fragmented IEEE 802.11 frame");
3711 next_tvb = tvb_new_subset (tvb, hdr_len, len, reported_len);
3712 call_dissector(data_handle, next_tvb, pinfo, tree);
3713 pinfo->fragmented = save_fragmented;
3717 switch (FCF_FRAME_TYPE (fcf))
3721 dissect_ieee80211_mgt (fcf, next_tvb, pinfo, tree);
3726 /* I guess some bridges take Netware Ethernet_802_3 frames,
3727 which are 802.3 frames (with a length field rather than
3728 a type field, but with no 802.2 header in the payload),
3729 and just stick the payload into an 802.11 frame. I've seen
3730 captures that show frames of that sort.
3732 We also handle some odd form of encapsulation in which a
3733 complete Ethernet frame is encapsulated within an 802.11
3734 data frame, with no 802.2 header. This has been seen
3737 So, if the packet doesn't start with 0xaa 0xaa:
3739 we first use the same scheme that linux-wlan-ng does to detect
3740 those encapsulated Ethernet frames, namely looking to see whether
3741 the frame either starts with 6 octets that match the destination
3742 address from the 802.11 header or has 6 octets that match the
3743 source address from the 802.11 header following the first 6 octets,
3744 and, if so, treat it as an encapsulated Ethernet frame;
3746 otherwise, we use the same scheme that we use in the Ethernet
3747 dissector to recognize Netware 802.3 frames, namely checking
3748 whether the packet starts with 0xff 0xff and, if so, treat it
3749 as an encapsulated IPX frame. */
3750 encap_type = ENCAP_802_2;
3752 octet1 = tvb_get_guint8(next_tvb, 0);
3753 octet2 = tvb_get_guint8(next_tvb, 1);
3754 if (octet1 != 0xaa || octet2 != 0xaa) {
3755 src = tvb_get_ptr (next_tvb, 6, 6);
3756 dst = tvb_get_ptr (next_tvb, 0, 6);
3757 if (memcmp(src, pinfo->dl_src.data, 6) == 0 ||
3758 memcmp(dst, pinfo->dl_dst.data, 6) == 0)
3759 encap_type = ENCAP_ETHERNET;
3760 else if (octet1 == 0xff && octet2 == 0xff)
3761 encap_type = ENCAP_IPX;
3764 CATCH2(BoundsError, ReportedBoundsError) {
3770 switch (encap_type) {
3773 call_dissector(llc_handle, next_tvb, pinfo, tree);
3776 case ENCAP_ETHERNET:
3777 call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree);
3781 call_dissector(ipx_handle, next_tvb, pinfo, tree);
3786 pinfo->fragmented = save_fragmented;
3789 tap_queue_packet(wlan_tap, pinfo, whdr);
3793 * Dissect 802.11 with a variable-length link-layer header.
3796 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3798 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
3799 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
3803 * Dissect 802.11 with a variable-length link-layer header and data padding.
3806 dissect_ieee80211_datapad (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3808 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
3809 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, TRUE);
3813 * Dissect 802.11 with a variable-length link-layer header and a pseudo-
3814 * header containing radio information.
3817 dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3819 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE,
3820 pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
3824 * Dissect 802.11 with a variable-length link-layer header and a byte-swapped
3825 * control field (some hardware sends out LWAPP-encapsulated 802.11
3826 * packets with the control field byte swapped).
3829 dissect_ieee80211_bsfc (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3831 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE, FALSE);
3835 * Dissect 802.11 with a fixed-length link-layer header (padded to the
3839 dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
3841 dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE, FALSE);
3845 wlan_defragment_init(void)
3847 fragment_table_init(&wlan_fragment_table);
3848 reassembled_table_init(&wlan_reassembled_table);
3852 proto_register_ieee80211 (void)
3855 GString *key_name, *key_title, *key_desc;
3857 static const value_string frame_type[] = {
3858 {MGT_FRAME, "Management frame"},
3859 {CONTROL_FRAME, "Control frame"},
3860 {DATA_FRAME, "Data frame"},
3864 static const value_string tofrom_ds[] = {
3865 {0, "Not leaving DS or network is operating "
3866 "in AD-HOC mode (To DS: 0 From DS: 0)"},
3867 {FLAG_TO_DS, "Frame from STA to DS via an AP (To DS: 1 "
3869 {FLAG_FROM_DS, "Frame from DS to a STA via AP(To DS: 0 "
3871 {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS from one AP to another "
3872 "AP (To DS: 1 From DS: 1)"},
3876 static const true_false_string tods_flag = {
3877 "Frame is entering DS",
3878 "Frame is not entering DS"
3881 static const true_false_string fromds_flag = {
3882 "Frame is exiting DS",
3883 "Frame is not exiting DS"
3886 static const true_false_string more_frags = {
3887 "More fragments follow",
3888 "This is the last fragment"
3891 static const true_false_string retry_flags = {
3892 "Frame is being retransmitted",
3893 "Frame is not being retransmitted"
3896 static const true_false_string pm_flags = {
3897 "STA will go to sleep",
3901 static const true_false_string md_flags = {
3902 "Data is buffered for STA at AP",
3906 static const true_false_string protected_flags = {
3907 "Data is protected",
3908 "Data is not protected"
3911 static const true_false_string order_flags = {
3913 "Not strictly ordered"
3916 static const true_false_string cf_ess_flags = {
3917 "Transmitter is an AP",
3918 "Transmitter is a STA"
3922 static const true_false_string cf_privacy_flags = {
3923 "AP/STA can support WEP",
3924 "AP/STA cannot support WEP"
3927 static const true_false_string cf_preamble_flags = {
3928 "Short preamble allowed",
3929 "Short preamble not allowed"
3932 static const true_false_string cf_pbcc_flags = {
3933 "PBCC modulation allowed",
3934 "PBCC modulation not allowed"
3937 static const true_false_string cf_agility_flags = {
3938 "Channel agility in use",
3939 "Channel agility not in use"
3942 static const true_false_string short_slot_time_flags = {
3943 "Short slot time in use",
3944 "Short slot time not in use"
3947 static const true_false_string dsss_ofdm_flags = {
3948 "DSSS-OFDM modulation allowed",
3949 "DSSS-OFDM modulation not allowed"
3952 static const true_false_string cf_spec_man_flags = {
3953 "dot11SpectrumManagementRequired TRUE",
3954 "dot11SpectrumManagementRequired FALSE",
3957 static const true_false_string cf_apsd_flags = {
3959 "apsd not implemented",
3962 static const true_false_string cf_del_blk_ack_flags = {
3963 "delayed block ack implemented",
3964 "delayed block ack not implented",
3967 static const true_false_string cf_imm_blk_ack_flags = {
3968 "immediate block ack implemented",
3969 "immediate block ack not implented",
3971 static const true_false_string cf_ibss_flags = {
3972 "Transmitter belongs to an IBSS",
3973 "Transmitter belongs to a BSS"
3976 static const true_false_string eosp_flag = {
3977 "End of service period",
3981 static const value_string sta_cf_pollable[] = {
3982 {0x00, "Station is not CF-Pollable"},
3983 {0x02, "Station is CF-Pollable, "
3984 "not requesting to be placed on the CF-polling list"},
3985 {0x01, "Station is CF-Pollable, "
3986 "requesting to be placed on the CF-polling list"},
3987 {0x03, "Station is CF-Pollable, requesting never to be polled"},
3988 {0x0200, "QSTA requesting association in QBSS"},
3992 static const value_string ap_cf_pollable[] = {
3993 {0x00, "No point coordinator at AP"},
3994 {0x02, "Point coordinator at AP for delivery only (no polling)"},
3995 {0x01, "Point coordinator at AP for delivery and polling"},
3997 {0x0200, "QAP (HC) does not use CFP for delivery of unicast data type frames"},
3998 {0x0202, "QAP (HC) uses CFP for delivery, but does not send CF-Polls to non-QoS STAs"},
3999 {0x0201, "QAP (HC) uses CFP for delivery, and sends CF-Polls to non-QoS STAs"},
4000 {0x0203, "Reserved"},
4005 static const value_string auth_alg[] = {
4006 {0x00, "Open System"},
4007 {0x01, "Shared key"},
4008 {0x80, "Network EAP"}, /* Cisco proprietary? */
4012 static const value_string reason_codes[] = {
4014 {0x01, "Unspecified reason"},
4015 {0x02, "Previous authentication no longer valid"},
4016 {0x03, "Deauthenticated because sending STA is leaving (has left) "
4018 {0x04, "Disassociated due to inactivity"},
4019 {0x05, "Disassociated because AP is unable to handle all currently "
4020 "associated stations"},
4021 {0x06, "Class 2 frame received from nonauthenticated station"},
4022 {0x07, "Class 3 frame received from nonassociated station"},
4023 {0x08, "Disassociated because sending STA is leaving (has left) BSS"},
4024 {0x09, "Station requesting (re)association is not authenticated with "
4025 "responding station"},
4026 {0x0A, "Disassociated because the information in the Power Capability "
4027 "element is unacceptable"},
4028 {0x0B, "Disassociated because the information in the Supported"
4029 "Channels element is unacceptable"},
4030 {0x0D, "Invalid Information Element"},
4031 {0x0E, "Michael MIC failure"},
4032 {0x0F, "4-Way Handshake timeout"},
4033 {0x10, "Group key update timeout"},
4034 {0x11, "Information element in 4-Way Handshake different from "
4035 "(Re)Association Request/Probe Response/Beacon"},
4036 {0x12, "Group Cipher is not valid"},
4037 {0x13, "Pairwise Cipher is not valid"},
4038 {0x14, "AKMP is not valid"},
4039 {0x15, "Unsupported RSN IE version"},
4040 {0x16, "Invalid RSN IE Capabilities"},
4041 {0x17, "IEEE 802.1X Authentication failed"},
4042 {0x18, "Cipher suite is rejected per security policy"},
4043 {0x20, "Disassociated for unspecified, QoS-related reason"},
4044 {0x21, "Disassociated because QAP lacks sufficient bandwidth for this QSTA"},
4045 {0x22, "Disassociated because of excessive number of frames that need to be "
4046 "acknowledged, but are not acknowledged for AP transmissions and/or poor "
4047 "channel conditions"},
4048 {0x23, "Disassociated because QSTA is transmitting outside the limits of its TXOPs"},
4049 {0x24, "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)"},
4050 {0x25, "Requested from peer QSTA as it does not want to use the mechanism"},
4051 {0x26, "Requested from peer QSTA as the QSTA received frames using the mechanism "
4052 "for which a set up is required"},
4053 {0x27, "Requested from peer QSTA due to time out"},
4054 {0x2D, "Peer QSTA does not support the requested cipher suite"},
4059 static const value_string status_codes[] = {
4060 {0x00, "Successful"},
4061 {0x01, "Unspecified failure"},
4062 {0x0A, "Cannot support all requested capabilities in the "
4063 "Capability information field"},
4064 {0x0B, "Reassociation denied due to inability to confirm that "
4065 "association exists"},
4066 {0x0C, "Association denied due to reason outside the scope of this "
4069 {0x0D, "Responding station does not support the specified authentication "
4071 {0x0E, "Received an Authentication frame with authentication sequence "
4072 "transaction sequence number out of expected sequence"},
4073 {0x0F, "Authentication rejected because of challenge failure"},
4074 {0x10, "Authentication rejected due to timeout waiting for next "
4075 "frame in sequence"},
4076 {0x11, "Association denied because AP is unable to handle additional "
4077 "associated stations"},
4078 {0x12, "Association denied due to requesting station not supporting all "
4079 "of the datarates in the BSSBasicServiceSet Parameter"},
4080 {0x13, "Association denied due to requesting station not supporting "
4081 "short preamble operation"},
4082 {0x14, "Association denied due to requesting station not supporting "
4084 {0x15, "Association denied due to requesting station not supporting "
4086 {0x16, "Association request rejected because Spectrum Management"
4087 "capability is required"},
4088 {0x17, "Association request rejected because the information in the"
4089 "Power Capability element is unacceptable"},
4090 {0x18, "Association request rejected because the information in the"
4091 "Supported Channels element is unacceptable"},
4092 {0x19, "Association denied due to requesting station not supporting "
4093 "short slot operation"},
4094 {0x1A, "Association denied due to requesting station not supporting "
4095 "DSSS-OFDM operation"},
4096 {0x20, "Unspecified, QoS-related failure"},
4097 {0x21, "Association denied due to QAP having insufficient bandwidth "
4098 "to handle another QSTA"},
4099 {0x22, "Association denied due to excessive frame loss rates and/or "
4100 "poor conditions on current operating channel"},
4101 {0x23, "Association (with QBSS) denied due to requesting station not "
4102 "supporting the QoS facility"},
4103 {0x24, "Association denied due to requesting station not supporting "
4105 {0x25, "The request has been declined."},
4106 {0x26, "The request has not been successful as one or more parameters "
4107 "have invalid values."},
4108 {0x27, "The TS has not been created because the request cannot be honored. "
4109 "However, a suggested TSPEC is provided so that the initiating QSTA may "
4110 "attempt to set another TS with the suggested changes to the TSPEC."},
4111 {0x28, "Invalid Information Element"},
4112 {0x29, "Group Cipher is not valid"},
4113 {0x2A, "Pairwise Cipher is not valid"},
4114 {0x2B, "AKMP is not valid"},
4115 {0x2C, "Unsupported RSN IE version"},
4116 {0x2D, "Invalid RSN IE Capabilities"},
4117 {0x2E, "Cipher suite is rejected per security policy"},
4118 {0x2F, "The TS has not been created. However, the HC may be capable of "
4119 "creating a TS, in response to a request, after the time indicated in the TS Delay element."},
4120 {0x30, "Direct Link is not allowed in the BSS by policy"},
4121 {0x31, "Destination STA is not present within this QBSS."},
4122 {0x32, "The Destination STA is not a QSTA."},
4126 static const value_string category_codes[] = {
4127 {CAT_SPECTRUM_MGMT, "Spectrum Management"},
4130 {CAT_BLOCK_ACK, "Block Ack"},
4131 {CAT_MGMT_NOTIFICATION, "Management notification frame"},
4135 static const value_string action_codes[] ={
4136 {SM_ACTION_MEASUREMENT_REQUEST, "Measurement Request"},
4137 {SM_ACTION_MEASUREMENT_REPORT, "Measurement Report"},
4138 {SM_ACTION_TPC_REQUEST, "TPC Request"},
4139 {SM_ACTION_TPC_REPORT, "TPC Report"},
4140 {SM_ACTION_CHAN_SWITCH_ANNC, "Channel Switch Announcement"},
4144 static const value_string wme_action_codes[] = {
4145 {0x00, "Setup request"},
4146 {0x01, "Setup response"},
4151 static const value_string wme_status_codes[] = {
4152 {0x00, "Admission accepted"},
4153 {0x01, "Invalid parameters"},
4158 static const value_string ack_policy[] = {
4159 {0x00, "Normal Ack"},
4161 {0x02, "No explicit Ack"},
4162 {0x03, "Block Ack"},
4166 static const value_string qos_action_codes[] = {
4167 {SM_ACTION_ADDTS_REQUEST, "ADDTS Request"},
4168 {SM_ACTION_ADDTS_RESPONSE, "ADDTS Response"},
4169 {SM_ACTION_DELTS, "DELTS"},
4170 {SM_ACTION_QOS_SCHEDULE, "Schedule"},
4174 static const value_string dls_action_codes[] = {
4175 {SM_ACTION_DLS_REQUEST, "DLS Request"},
4176 {SM_ACTION_DLS_RESPONSE, "DLS Response"},
4177 {SM_ACTION_DLS_TEARDOWN, "DLS Teardown"},
4181 static const value_string tsinfo_type[] = {
4182 {0x0, "Aperiodic or unspecified Traffic"},
4183 {0x1, "Periodic Traffic"},
4187 static const value_string tsinfo_direction[] = {
4190 {0x02, "Direct link"},
4191 {0x03, "Bidirectional link"},
4195 static const value_string tsinfo_access[] = {
4203 static const value_string qos_up[] = {
4204 {0x00, "Best Effort"},
4205 {0x01, "Background"},
4207 {0x03, "Excellent Effort"},
4208 {0x04, "Controlled Load"},
4211 {0x07, "Network Control"},
4215 static const value_string classifier_type[] = {
4216 {0x00, "Ethernet parameters"},
4217 {0x01, "TCP/UDP IP parameters"},
4218 {0x02, "IEEE 802.1D/Q parameters"},
4222 static const value_string tclas_process[] = {
4223 {0x00, "Incoming MSDU's higher layer parameters have to match to the parameters in all associated TCLAS elements."},
4224 {0x01, "Incoming MSDU's higher layer parameters have to match to at least one of the associated TCLAS elements."},
4225 {0x02, "Incoming MSDU's that do not belong to any other TS are classified to the TS for which this TCLAS Processing element is used. In this case, there will not be any associated TCLAS elements."},
4229 static hf_register_info hf[] = {
4231 {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
4232 "Data rate (.5 Mb/s units)", HFILL }},
4235 {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
4236 "Radio channel", HFILL }},
4238 {&hf_signal_strength,
4239 {"Signal Strength", "wlan.signal_strength", FT_UINT8, BASE_DEC, NULL, 0,
4240 "Signal strength (percentage)", HFILL }},
4243 {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
4244 "MAC Frame control", HFILL }},
4246 {&hf_fc_proto_version,
4247 {"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
4248 "MAC Protocol version", HFILL }}, /* 0 */
4251 {"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, VALS(frame_type), 0,
4252 "Frame type", HFILL }},
4254 {&hf_fc_frame_subtype,
4255 {"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
4256 "Frame subtype", HFILL }}, /* 2 */
4258 {&hf_fc_frame_type_subtype,
4259 {"Type/Subtype", "wlan.fc.type_subtype", FT_UINT16, BASE_DEC, VALS(frame_type_subtype_vals), 0,
4260 "Type and subtype combined", HFILL }},
4263 {"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
4264 "Protocol flags", HFILL }},
4267 {"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, VALS (&tofrom_ds), 0,
4268 "Data-frame DS-traversal status", HFILL }}, /* 3 */
4271 {"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), FLAG_TO_DS,
4272 "To DS flag", HFILL }}, /* 4 */
4275 {"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), FLAG_FROM_DS,
4276 "From DS flag", HFILL }}, /* 5 */
4279 {"More Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), FLAG_MORE_FRAGMENTS,
4280 "More Fragments flag", HFILL }}, /* 6 */
4283 {"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), FLAG_RETRY,
4284 "Retransmission flag", HFILL }},
4287 {"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), FLAG_POWER_MGT,
4288 "Power management status", HFILL }},
4291 {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
4292 "More data flag", HFILL }},
4295 {"Protected flag", "wlan.fc.protected", FT_BOOLEAN, 8, TFS (&protected_flags), FLAG_PROTECTED,
4296 "Protected flag", HFILL }},
4299 {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
4300 "Strictly ordered flag", HFILL }},
4303 {"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
4304 "Association-ID field", HFILL }},
4307 {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
4308 "Duration field", HFILL }},
4311 {"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
4312 "Destination Hardware Address", HFILL }},
4315 {"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
4316 "Source Hardware Address", HFILL }},
4319 {"Source or Destination address", "wlan.addr", FT_ETHER, BASE_NONE, NULL, 0,
4320 "Source or Destination Hardware Address", HFILL }},
4323 {"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
4324 "Receiving Station Hardware Address", HFILL }},
4327 {"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
4328 "Transmitting Station Hardware Address", HFILL }},
4331 {"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
4332 "Basic Service Set ID", HFILL }},
4335 {"Fragment number", "wlan.frag", FT_UINT16, BASE_DEC, NULL, 0,
4336 "Fragment number", HFILL }},
4339 {"Sequence number", "wlan.seq", FT_UINT16, BASE_DEC, NULL, 0,
4340 "Sequence number", HFILL }},
4343 {"Priority", "wlan.qos.priority", FT_UINT16, BASE_DEC, NULL, 0,
4344 "802.1D Tag", HFILL }},
4347 {"EOSP", "wlan.qos.eosp", FT_BOOLEAN, 8, TFS (&eosp_flag), QOS_FLAG_EOSP,
4348 "EOSP Field", HFILL }},
4350 {&hf_qos_ack_policy,
4351 {"Ack Policy", "wlan.qos.ack", FT_UINT16, BASE_HEX, VALS (&ack_policy), 0,
4352 "Ack Policy", HFILL }},
4354 {&hf_qos_field_content,
4355 {"Content", "wlan.qos.fc_content", FT_UINT16, BASE_DEC, NULL, 0,
4356 "Content1", HFILL }},
4358 /* {&hf_qos_buffer_state,
4359 {"QAP PS buffer State", "wlan.qos.ps_buf_state", FT_UINT16, BASE_DEC, NULL, 0,
4360 "QAP PS buffer State", HFILL }},
4362 {&hf_qos_txop_dur_req,
4363 {"TXOP Duration Requested", "wlan.qos.txop_dur_req", FT_UINT16, BASE_DEC, NULL, 0,
4364 "TXOP Duration Requested", HFILL }},
4366 {&hf_qos_queue_size,
4367 {"Queue Size", "wlan.qos.queue_size", FT_UINT16, BASE_DEC, NULL, 0,
4368 "Queue Size", HFILL }},*/
4371 {"Frame check sequence", "wlan.fcs", FT_UINT32, BASE_HEX,
4372 NULL, 0, "FCS", HFILL }},
4375 {"Good", "wlan.fcs_good", FT_BOOLEAN, BASE_NONE,
4376 NULL, 0, "True if the FCS is correct", HFILL }},
4379 {"Bad", "wlan.fcs_bad", FT_BOOLEAN, BASE_NONE,
4380 NULL, 0, "True if the FCS is incorrect", HFILL }},
4382 {&hf_fragment_overlap,
4383 {"Fragment overlap", "wlan.fragment.overlap", FT_BOOLEAN, BASE_NONE,
4384 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
4386 {&hf_fragment_overlap_conflict,
4387 {"Conflicting data in fragment overlap", "wlan.fragment.overlap.conflict",
4388 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4389 "Overlapping fragments contained conflicting data", HFILL }},
4391 {&hf_fragment_multiple_tails,
4392 {"Multiple tail fragments found", "wlan.fragment.multipletails",
4393 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4394 "Several tails were found when defragmenting the packet", HFILL }},
4396 {&hf_fragment_too_long_fragment,
4397 {"Fragment too long", "wlan.fragment.toolongfragment",
4398 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4399 "Fragment contained data past end of packet", HFILL }},
4401 {&hf_fragment_error,
4402 {"Defragmentation error", "wlan.fragment.error",
4403 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4404 "Defragmentation error due to illegal fragments", HFILL }},
4407 {"802.11 Fragment", "wlan.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4408 "802.11 Fragment", HFILL }},
4411 {"802.11 Fragments", "wlan.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
4412 "802.11 Fragments", HFILL }},
4414 {&hf_reassembled_in,
4415 {"Reassembled 802.11 in frame", "wlan.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4416 "This 802.11 packet is reassembled in this frame", HFILL }},
4419 {"Initialization Vector", "wlan.wep.iv", FT_UINT24, BASE_HEX, NULL, 0,
4420 "Initialization Vector", HFILL }},
4423 {"Weak IV", "wlan.wep.weakiv", FT_BOOLEAN,BASE_NONE, NULL,0x0,
4427 {"TKIP Ext. Initialization Vector", "wlan.tkip.extiv", FT_STRING,
4428 BASE_HEX, NULL, 0, "TKIP Extended Initialization Vector", HFILL }},
4431 {"CCMP Ext. Initialization Vector", "wlan.ccmp.extiv", FT_STRING,
4432 BASE_HEX, NULL, 0, "CCMP Extended Initialization Vector", HFILL }},
4435 {"Key Index", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
4436 "Key Index", HFILL }},
4439 {"WEP ICV", "wlan.wep.icv", FT_UINT32, BASE_HEX, NULL, 0,
4440 "WEP ICV", HFILL }},
4443 static const true_false_string rsn_preauth_flags = {
4444 "Transmitter supports pre-authentication",
4445 "Transmitter does not support pre-authentication"
4448 static const true_false_string rsn_no_pairwise_flags = {
4449 "Transmitter cannot support WEP default key 0 simultaneously with "
4451 "Transmitter can support WEP default key 0 simultaneously with "
4455 static const value_string rsn_cap_replay_counter[] = {
4456 {0x00, "1 replay counter per PTKSA/GTKSA/STAKeySA"},
4457 {0x01, "2 replay counters per PTKSA/GTKSA/STAKeySA"},
4458 {0x02, "4 replay counters per PTKSA/GTKSA/STAKeySA"},
4459 {0x03, "16 replay counters per PTKSA/GTKSA/STAKeySA"},
4463 static hf_register_info ff[] = {
4465 {"Timestamp", "wlan_mgt.fixed.timestamp", FT_STRING, BASE_NONE,
4466 NULL, 0, "", HFILL }},
4469 {"Authentication Algorithm", "wlan_mgt.fixed.auth.alg",
4470 FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, "", HFILL }},
4472 {&ff_beacon_interval,
4473 {"Beacon Interval", "wlan_mgt.fixed.beacon", FT_DOUBLE, BASE_DEC, NULL, 0,
4476 {&hf_fixed_parameters,
4477 {"Fixed parameters", "wlan_mgt.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
4480 {&hf_tagged_parameters,
4481 {"Tagged parameters", "wlan_mgt.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
4485 {"Capabilities", "wlan_mgt.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
4486 "Capability information", HFILL }},
4489 {"ESS capabilities", "wlan_mgt.fixed.capabilities.ess",
4490 FT_BOOLEAN, 16, TFS (&cf_ess_flags), 0x0001, "ESS capabilities", HFILL }},
4493 {"IBSS status", "wlan_mgt.fixed.capabilities.ibss",
4494 FT_BOOLEAN, 16, TFS (&cf_ibss_flags), 0x0002, "IBSS participation", HFILL }},
4497 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.sta",
4498 FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0x020C,
4499 "CF-Poll capabilities for a STA", HFILL }},
4502 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.ap",
4503 FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0x020C,
4504 "CF-Poll capabilities for an AP", HFILL }},
4507 {"Privacy", "wlan_mgt.fixed.capabilities.privacy",
4508 FT_BOOLEAN, 16, TFS (&cf_privacy_flags), 0x0010, "WEP support", HFILL }},
4511 {"Short Preamble", "wlan_mgt.fixed.capabilities.preamble",
4512 FT_BOOLEAN, 16, TFS (&cf_preamble_flags), 0x0020, "Short Preamble", HFILL }},
4515 {"PBCC", "wlan_mgt.fixed.capabilities.pbcc",
4516 FT_BOOLEAN, 16, TFS (&cf_pbcc_flags), 0x0040, "PBCC Modulation", HFILL }},
4519 {"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
4520 FT_BOOLEAN, 16, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
4523 {"Spectrum Management", "wlan_mgt.fixed.capabilities.spec_man",
4524 FT_BOOLEAN, 16, TFS (&cf_spec_man_flags), 0x0100, "Spectrum Management", HFILL }},
4526 {&ff_short_slot_time,
4527 {"Short Slot Time", "wlan_mgt.fixed.capabilities.short_slot_time",
4528 FT_BOOLEAN, 16, TFS (&short_slot_time_flags), 0x0400, "Short Slot Time",
4532 {"Automatic Power Save Delivery", "wlan_mgt.fixed.capabilities.apsd",
4533 FT_BOOLEAN, 16, TFS (&cf_apsd_flags), 0x0800, "Automatic Power Save "
4534 "Delivery", HFILL }},
4537 {"DSSS-OFDM", "wlan_mgt.fixed.capabilities.dsss_ofdm",
4538 FT_BOOLEAN, 16, TFS (&dsss_ofdm_flags), 0x2000, "DSSS-OFDM Modulation",
4541 {&ff_cf_del_blk_ack,
4542 {"Delayed Block Ack", "wlan_mgt.fixed.capabilities.del_blk_ack",
4543 FT_BOOLEAN, 16, TFS (&cf_del_blk_ack_flags), 0x4000, "Delayed Block "
4546 {&ff_cf_imm_blk_ack,
4547 {"Immediate Block Ack", "wlan_mgt.fixed.capabilities.imm_blk_ack",
4548 FT_BOOLEAN, 16, TFS (&cf_imm_blk_ack_flags), 0x8000, "Immediate Block "
4552 {"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
4553 FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
4556 {"Association ID", "wlan_mgt.fixed.aid",
4557 FT_UINT16, BASE_HEX, NULL, 0, "Association ID", HFILL }},
4560 {"Listen Interval", "wlan_mgt.fixed.listen_ival",
4561 FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval", HFILL }},
4564 {"Current AP", "wlan_mgt.fixed.current_ap",
4565 FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP", HFILL }},
4568 {"Reason code", "wlan_mgt.fixed.reason_code",
4569 FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
4570 "Reason for unsolicited notification", HFILL }},
4573 {"Status code", "wlan_mgt.fixed.status_code",
4574 FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
4575 "Status of requested event", HFILL }},
4578 {"Category code", "wlan_mgt.fixed.category_code",
4579 FT_UINT16, BASE_DEC, VALS (&category_codes), 0,
4580 "Management action category", HFILL }},
4583 {"Action code", "wlan_mgt.fixed.action_code",
4584 FT_UINT16, BASE_DEC, VALS (&action_codes), 0,
4585 "Management action code", HFILL }},
4588 {"Dialog token", "wlan_mgt.fixed.dialog_token",
4589 FT_UINT16, BASE_HEX, NULL, 0, "Management action dialog token", HFILL }},
4591 {&ff_wme_action_code,
4592 {"Action code", "wlan_mgt.fixed.action_code",
4593 FT_UINT16, BASE_HEX, VALS (&wme_action_codes), 0,
4594 "Management notification action code", HFILL }},
4596 {&ff_wme_status_code,
4597 {"Status code", "wlan_mgt.fixed.status_code",
4598 FT_UINT16, BASE_HEX, VALS (&wme_status_codes), 0,
4599 "Management notification setup response status code", HFILL }},
4601 {&ff_qos_action_code,
4602 {"Action code", "wlan_mgt.fixed.action_code",
4603 FT_UINT16, BASE_HEX, VALS (&qos_action_codes), 0,
4604 "QoS management action code", HFILL }},
4606 {&ff_dls_action_code,
4607 {"Action code", "wlan_mgt.fixed.action_code",
4608 FT_UINT16, BASE_HEX, VALS (&dls_action_codes), 0,
4609 "DLS management action code", HFILL }},
4612 {"Destination address", "wlan_mgt.fixed.dst_mac_addr",
4613 FT_ETHER, BASE_NONE, NULL, 0, "Destination MAC address", HFILL }},
4616 {"Source address", "wlan_mgt.fixed.src_mac_addr",
4617 FT_ETHER, BASE_NONE, NULL, 0, "Source MAC address", HFILL }},
4620 {"DLS timeout", "wlan_mgt.fixed.dls_timeout",
4621 FT_UINT16, BASE_HEX, NULL, 0, "DLS timeout value", HFILL }},
4624 {"Tag", "wlan_mgt.tag.number",
4625 FT_UINT8, BASE_DEC, VALS(tag_num_vals), 0,
4626 "Element ID", HFILL }},
4629 {"Tag length", "wlan_mgt.tag.length",
4630 FT_UINT8, BASE_DEC, NULL, 0, "Length of tag", HFILL }},
4632 {&tag_interpretation,
4633 {"Tag interpretation", "wlan_mgt.tag.interpretation",
4634 FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }},
4637 {"OUI", "wlan_mgt.tag.oui",
4638 FT_BYTES, BASE_NONE, NULL, 0, "OUI of vendor specific IE", HFILL }},
4641 {"TIM length", "wlan_mgt.tim.length",
4642 FT_UINT8, BASE_DEC, NULL, 0,
4643 "Traffic Indication Map length", HFILL }},
4646 {"DTIM count", "wlan_mgt.tim.dtim_count",
4647 FT_UINT8, BASE_DEC, NULL, 0,
4648 "DTIM count", HFILL }},
4651 {"DTIM period", "wlan_mgt.tim.dtim_period",
4652 FT_UINT8, BASE_DEC, NULL, 0,
4653 "DTIM period", HFILL }},
4656 {"Bitmap control", "wlan_mgt.tim.bmapctl",
4657 FT_UINT8, BASE_HEX, NULL, 0,
4658 "Bitmap control", HFILL }},
4661 {"RSN Capabilities", "wlan_mgt.rsn.capabilities", FT_UINT16, BASE_HEX,
4662 NULL, 0, "RSN Capability information", HFILL }},
4665 {"RSN Pre-Auth capabilities", "wlan_mgt.rsn.capabilities.preauth",
4666 FT_BOOLEAN, 16, TFS (&rsn_preauth_flags), 0x0001,
4667 "RSN Pre-Auth capabilities", HFILL }},
4669 {&rsn_cap_no_pairwise,
4670 {"RSN No Pairwise capabilities", "wlan_mgt.rsn.capabilities.no_pairwise",
4671 FT_BOOLEAN, 16, TFS (&rsn_no_pairwise_flags), 0x0002,
4672 "RSN No Pairwise capabilities", HFILL }},
4674 {&rsn_cap_ptksa_replay_counter,
4675 {"RSN PTKSA Replay Counter capabilities",
4676 "wlan_mgt.rsn.capabilities.ptksa_replay_counter",
4677 FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x000C,
4678 "RSN PTKSA Replay Counter capabilities", HFILL }},
4680 {&rsn_cap_gtksa_replay_counter,
4681 {"RSN GTKSA Replay Counter capabilities",
4682 "wlan_mgt.rsn.capabilities.gtksa_replay_counter",
4683 FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x0030,
4684 "RSN GTKSA Replay Counter capabilities", HFILL }},
4686 {&hf_aironet_ie_type,
4687 {"Aironet IE type", "wlan_mgt.aironet.type",
4688 FT_UINT8, BASE_DEC, VALS(aironet_ie_type_vals), 0, "", HFILL }},
4690 {&hf_aironet_ie_version,
4691 {"Aironet IE CCX version?", "wlan_mgt.aironet.version",
4692 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4694 { &hf_aironet_ie_data,
4695 { "Aironet IE data", "wlan_mgmt.aironet.data",
4696 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
4699 {"QBSS Version", "wlan_mgt.qbss.version",
4700 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4703 {"Station Count", "wlan_mgt.qbss.scount",
4704 FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
4707 {"Channel Utilization", "wlan_mgt.qbss.cu",
4708 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4711 {"Available Admission Capabilities", "wlan_mgt.qbss.adc",
4712 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4715 {"Channel Utilization", "wlan_mgt.qbss2.cu",
4716 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4719 {"G.711 CU Quantum", "wlan_mgt.qbss2.glimit",
4720 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4723 {"Call Admission Limit", "wlan_mgt.qbss2.cal",
4724 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4727 {"Station Count", "wlan_mgt.qbss2.scount",
4728 FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
4730 {&hf_aironet_ie_qos_unk1,
4731 {"Aironet IE QoS unknown1", "wlan_mgt.aironet.qos.unk1",
4732 FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
4734 {&hf_aironet_ie_qos_paramset,
4735 {"Aironet IE QoS paramset", "wlan_mgt.aironet.qos.paramset",
4736 FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
4738 {&hf_aironet_ie_qos_val,
4739 {"Aironet IE QoS valueset", "wlan_mgt.aironet.qos.val",
4740 FT_BYTES, BASE_NONE, NULL, 0, "", HFILL }},
4743 {"TS Info", "wlan_mgt.ts_info",
4744 FT_UINT24, BASE_HEX, NULL, 0, "TS Info field", HFILL }},
4747 {"Traffic Type", "wlan_mgt.ts_info.type", FT_UINT8, BASE_DEC,
4748 VALS (&tsinfo_type), 0, "TS Info Traffic Type", HFILL }},
4751 {"TSID", "wlan_mgt.ts_info.tsid",
4752 FT_UINT8, BASE_DEC, NULL, 0, "TS Info TSID", HFILL }},
4755 {"Direction", "wlan_mgt.ts_info.dir", FT_UINT8, BASE_DEC,
4756 VALS (&tsinfo_direction), 0, "TS Info Direction", HFILL }},
4759 {"Access Policy", "wlan_mgt.ts_info.dir", FT_UINT8, BASE_DEC,
4760 VALS (&tsinfo_access), 0, "TS Info Access Policy", HFILL }},
4763 {"Aggregation", "wlan_mgt.ts_info.agg", FT_UINT8, BASE_DEC,
4764 NULL, 0, "TS Info Access Policy", HFILL }},
4767 {"APSD", "wlan_mgt.ts_info.apsd", FT_UINT8, BASE_DEC,
4768 NULL, 0, "TS Info APSD", HFILL }},
4771 {"UP", "wlan_mgt.ts_info.up", FT_UINT8, BASE_DEC,
4772 VALS (&qos_up), 0, "TS Info User Priority", HFILL }},
4775 {"Ack Policy", "wlan_mgt.ts_info.ack", FT_UINT8, BASE_DEC,
4776 VALS (&ack_policy), 0, "TS Info Ack Policy", HFILL }},
4779 {"Schedule", "wlan_mgt.ts_info.sched", FT_UINT8, BASE_DEC,
4780 NULL, 0, "TS Info Schedule", HFILL }},
4783 {"Normal MSDU Size", "wlan_mgt.tspec.nor_msdu",
4784 FT_UINT16, BASE_DEC, NULL, 0, "Normal MSDU Size", HFILL }},
4787 {"Maximum MSDU Size", "wlan_mgt.tspec.max_msdu",
4788 FT_UINT16, BASE_DEC, NULL, 0, "Maximum MSDU Size", HFILL }},
4791 {"Minimum Service Interval", "wlan_mgt.tspec.min_srv",
4792 FT_UINT32, BASE_DEC, NULL, 0, "Minimum Service Interval", HFILL }},
4795 {"Maximum Service Interval", "wlan_mgt.tspec.max_srv",
4796 FT_UINT32, BASE_DEC, NULL, 0, "Maximum Service Interval", HFILL }},
4799 {"Inactivity Interval", "wlan_mgt.tspec.inact_int",
4800 FT_UINT32, BASE_DEC, NULL, 0, "Inactivity Interval", HFILL }},
4803 {"Suspension Interval", "wlan_mgt.tspec.susp_int",
4804 FT_UINT32, BASE_DEC, NULL, 0, "Suspension Interval", HFILL }},
4807 {"Service Start Time", "wlan_mgt.tspec.srv_start",
4808 FT_UINT32, BASE_DEC, NULL, 0, "Service Start Time", HFILL }},
4811 {"Minimum Data Rate", "wlan_mgt.tspec.min_data",
4812 FT_UINT32, BASE_DEC, NULL, 0, "Minimum Data Rate", HFILL }},
4815 {"Mean Data Rate", "wlan_mgt.tspec.mean_data",
4816 FT_UINT32, BASE_DEC, NULL, 0, "Mean Data Rate", HFILL }},
4819 {"Peak Data Rate", "wlan_mgt.tspec.peak_data",
4820 FT_UINT32, BASE_DEC, NULL, 0, "Peak Data Rate", HFILL }},
4823 {"Burst Size", "wlan_mgt.tspec.burst_size",
4824 FT_UINT32, BASE_DEC, NULL, 0, "Burst Size", HFILL }},
4826 {&tspec_delay_bound,
4827 {"Delay Bound", "wlan_mgt.tspec.delay_bound",
4828 FT_UINT32, BASE_DEC, NULL, 0, "Delay Bound", HFILL }},
4831 {"Minimum PHY Rate", "wlan_mgt.tspec.min_phy",
4832 FT_UINT32, BASE_DEC, NULL, 0, "Minimum PHY Rate", HFILL }},
4835 {"Surplus Bandwidth Allowance", "wlan_mgt.tspec.surplus",
4836 FT_UINT16, BASE_DEC, NULL, 0, "Surplus Bandwidth Allowance", HFILL }},
4839 {"Medium Time", "wlan_mgt.tspec.medium",
4840 FT_UINT16, BASE_DEC, NULL, 0, "Medium Time", HFILL }},
4843 {"TS Delay", "wlan_mgt.ts_delay",
4844 FT_UINT32, BASE_DEC, NULL, 0, "TS Delay", HFILL }},
4847 {"Classifier Type", "wlan_mgt.tclas.class_type", FT_UINT8, BASE_DEC,
4848 VALS (classifier_type), 0, "Classifier Type", HFILL }},
4851 {"Classifier Mask", "wlan_mgt.tclas.class_mask", FT_UINT8, BASE_HEX,
4852 NULL, 0, "Classifier Mask", HFILL }},
4855 {"Type", "wlan_mgt.tclas.params.type", FT_UINT8, BASE_DEC,
4856 NULL, 0, "Classifier Parameters Ethernet Type", HFILL }},
4859 {"Processing", "wlan_mgt.tclas_proc.processing", FT_UINT8, BASE_DEC,
4860 VALS (tclas_process), 0, "TCLAS Porcessing", HFILL }},
4863 {"Schedule Info", "wlan_mgt.sched.sched_info",
4864 FT_UINT16, BASE_HEX, NULL, 0, "Schedule Info field", HFILL }},
4866 {&hf_sched_srv_start,
4867 {"Service Start Time", "wlan_mgt.sched.srv_start",
4868 FT_UINT32, BASE_HEX, NULL, 0, "Service Start Time", HFILL }},
4871 {"Service Interval", "wlan_mgt.sched.srv_int",
4872 FT_UINT32, BASE_HEX, NULL, 0, "Service Interval", HFILL }},
4874 {&hf_sched_spec_int,
4875 {"Specification Interval", "wlan_mgt.sched.spec_int",
4876 FT_UINT16, BASE_HEX, NULL, 0, "Specification Interval", HFILL }},
4879 {"IP Version", "wlan_mgt.tclas.params.version",
4880 FT_UINT8, BASE_DEC, NULL, 0, "IP Version", HFILL }},
4883 {"IPv4 Src Addr", "wlan_mgt.tclas.params.ipv4_src",
4884 FT_IPv4, BASE_NONE, NULL, 0, "IPv4 Src Addr", HFILL }},
4887 {"IPv4 Dst Addr", "wlan_mgt.tclas.params.ipv4_dst",
4888 FT_IPv4, BASE_NONE, NULL, 0, "IPv4 Dst Addr", HFILL }},
4891 {"Source Port", "wlan_mgt.tclas.params.src_port",
4892 FT_UINT16, BASE_DEC, NULL, 0, "Source Port", HFILL }},
4895 {"Destination Port", "wlan_mgt.tclas.params.dst_port",
4896 FT_UINT16, BASE_DEC, NULL, 0, "Destination Port", HFILL }},
4899 {"DSCP", "wlan_mgt.tclas.params.dscp",
4900 FT_UINT8, BASE_HEX, NULL, 0, "IPv4 DSCP Field", HFILL }},
4903 {"Protocol", "wlan_mgt.tclas.params.protocol",
4904 FT_UINT8, BASE_HEX, NULL, 0, "IPv4 Protocol", HFILL }},
4907 {"IPv6 Src Addr", "wlan_mgt.tclas.params.ipv6_src",
4908 FT_IPv6, BASE_NONE, NULL, 0, "IPv6 Src Addr", HFILL }},
4911 {"IPv6 Dst Addr", "wlan_mgt.tclas.params.ipv6_dst",
4912 FT_IPv6, BASE_NONE, NULL, 0, "IPv6 Dst Addr", HFILL }},
4915 {"Flow Label", "wlan_mgt.tclas.params.flow",
4916 FT_UINT24, BASE_HEX, NULL, 0, "IPv6 Flow Label", HFILL }},
4919 {"802.1Q Tag Type", "wlan_mgt.tclas.params.tag_type",
4920 FT_UINT16, BASE_HEX, NULL, 0, "802.1Q Tag Type", HFILL }},
4924 static gint *tree_array[] = {
4931 &ett_fixed_parameters,
4932 &ett_tagged_parameters,
4933 &ett_qos_parameters,
4934 &ett_qos_ps_buf_state,
4935 &ett_wep_parameters,
4943 module_t *wlan_module;
4946 proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
4947 "IEEE 802.11", "wlan");
4948 proto_register_field_array (proto_wlan, hf, array_length (hf));
4949 proto_wlan_mgt = proto_register_protocol ("IEEE 802.11 wireless LAN management frame",
4950 "802.11 MGT", "wlan_mgt");
4951 proto_register_field_array (proto_wlan_mgt, ff, array_length (ff));
4952 proto_register_subtree_array (tree_array, array_length (tree_array));
4954 register_dissector("wlan", dissect_ieee80211, proto_wlan);
4955 register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
4956 register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan);
4957 register_dissector("wlan_datapad", dissect_ieee80211_datapad, proto_wlan);
4958 register_dissector("wlan_radio", dissect_ieee80211_radio, proto_wlan);
4959 register_init_routine(wlan_defragment_init);
4961 wlan_tap = register_tap("wlan");
4963 /* Register configuration options */
4964 wlan_module = prefs_register_protocol(proto_wlan, init_wepkeys);
4965 prefs_register_bool_preference(wlan_module, "defragment",
4966 "Reassemble fragmented 802.11 datagrams",
4967 "Whether fragmented 802.11 datagrams should be reassembled",
4970 prefs_register_bool_preference(wlan_module, "check_fcs",
4971 "Assume packets have FCS",
4972 "Some 802.11 cards include the FCS at the end of a packet, others do not.",
4975 /* Davide Schiera (2006-11-26): changed "WEP bit" in "Protection bit" */
4976 /* (according to the document IEEE Std 802.11i-2004) */
4977 prefs_register_bool_preference(wlan_module, "ignore_wep",
4978 "Ignore the Protection bit",
4979 "Some 802.11 cards leave the Protection bit set even though the packet is decrypted.",
4984 prefs_register_obsolete_preference(wlan_module, "wep_keys");
4986 #ifdef HAVE_AIRPDCAP
4987 /* Davide Schiera (2006-11-26): added reference to WPA/WPA2 decryption */
4988 prefs_register_bool_preference(wlan_module, "enable_decryption",
4989 "Enable decryption", "Enable WEP and WPA/WPA2 decryption",
4990 &enable_decryption);
4992 prefs_register_bool_preference(wlan_module, "enable_decryption",
4993 "Enable decryption", "Enable WEP decryption",
4994 &enable_decryption);
4997 #ifdef HAVE_AIRPDCAP
4998 prefs_register_static_text_preference(wlan_module, "info_decryption_key",
4999 "Key examples: 01:02:03:04:05 (40/64-bit WEP),\n"
5000 "010203040506070809101111213 (104/128-bit WEP),\n"
5001 "wpa-pwd:MyPassword[:MyAP] (WPA + plaintext password [+ SSID]),\n"
5002 "wpa-psk:0102030405...6061626364 (WPA + 256-bit key). "
5003 "Invalid keys will be ignored.",
5004 "This is just a static text");
5006 prefs_register_static_text_preference(wlan_module, "info_decryption_key",
5007 "Key examples: 01:02:03:04:05 (40/64-bit WEP),\n"
5008 "010203040506070809101111213 (104/128-bit WEP)",
5009 "This is just a static text");
5012 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
5013 key_name = g_string_new("");
5014 key_title = g_string_new("");
5015 key_desc = g_string_new("");
5016 wep_keystr[i] = NULL;
5017 /* prefs_register_*_preference() expects unique strings, so
5018 * we build them using g_string_sprintf and just leave them
5020 #ifdef HAVE_AIRPDCAP
5021 g_string_sprintf(key_name, "wep_key%d", i + 1);
5022 g_string_sprintf(key_title, "Key #%d", i + 1);
5023 /* Davide Schiera (2006-11-26): modified keys input tooltip */
5024 g_string_sprintf(key_desc,
5025 "Key #%d string can be:"
5026 " <wep hexadecimal key>;"
5027 " wep:<wep hexadecimal key>;"
5028 " wpa-pwd:<passphrase>[:<ssid>];"
5029 " wpa-psk:<wpa hexadecimal key>", i + 1);
5031 g_string_sprintf(key_name, "wep_key%d", i + 1);
5032 g_string_sprintf(key_title, "WEP key #%d", i + 1);
5033 g_string_sprintf(key_desc, "WEP key #%d bytes in hexadecimal (A:B:C:D:E) "
5034 "[40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key "
5035 "length you're using", i + 1);
5038 prefs_register_string_preference(wlan_module, key_name->str,
5039 key_title->str, key_desc->str, (const char **) &wep_keystr[i]);
5041 g_string_free(key_name, FALSE);
5042 g_string_free(key_title, FALSE);
5043 g_string_free(key_desc, FALSE);
5049 proto_reg_handoff_ieee80211(void)
5051 dissector_handle_t ieee80211_handle;
5052 dissector_handle_t ieee80211_radio_handle;
5055 * Get handles for the LLC, IPX and Ethernet dissectors.
5057 llc_handle = find_dissector("llc");
5058 ipx_handle = find_dissector("ipx");
5059 eth_withoutfcs_handle = find_dissector("eth_withoutfcs");
5060 data_handle = find_dissector("data");
5062 ieee80211_handle = find_dissector("wlan");
5063 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle);
5064 ieee80211_radio_handle = create_dissector_handle(dissect_ieee80211_radio,
5066 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
5067 ieee80211_radio_handle);
5068 dissector_add("ethertype", ETHERTYPE_CENTRINO_PROMISC, ieee80211_handle);
5071 #ifdef HAVE_AIRPDCAP
5072 /* Davide Schiera (2006-11-26): this function will try to decrypt with WEP or */
5073 /* WPA and return a tvb to the caller to add a new tab. It returns the */
5074 /* algorithm used for decryption (WEP, TKIP, CCMP) and the header and */
5075 /* trailer lengths. */
5076 static tvbuff_t *try_decrypt(tvbuff_t *tvb, guint32 offset, guint32 len, guint8 *algorithm, guint32 *sec_header, guint32 *sec_trailer) {
5077 const guint8 *enc_data;
5079 tvbuff_t *decr_tvb = NULL;
5081 guchar dec_data[AIRPDCAP_MAX_CAPLEN];
5082 AIRPDCAP_KEY_ITEM used_key;
5084 if (!enable_decryption)
5087 /* get the entire packet */
5088 enc_data = tvb_get_ptr(tvb, 0, len+offset);
5090 /* process packet with AirPDcap */
5091 if (AirPDcapPacketProcess(&airpdcap_ctx, enc_data, len+offset, dec_data, &dec_caplen, &used_key, FALSE, FALSE, FALSE, TRUE)==AIRPDCAP_RET_SUCCESS)
5093 *algorithm=used_key.KeyType;
5094 switch (*algorithm) {
5095 case AIRPDCAP_KEY_TYPE_WEP:
5096 *sec_header=AIRPDCAP_WEP_HEADER;
5097 *sec_trailer=AIRPDCAP_WEP_TRAILER;
5099 case AIRPDCAP_KEY_TYPE_CCMP:
5100 *sec_header=AIRPDCAP_RSNA_HEADER;
5101 *sec_trailer=AIRPDCAP_CCMP_TRAILER;
5103 case AIRPDCAP_KEY_TYPE_TKIP:
5104 *sec_header=AIRPDCAP_RSNA_HEADER;
5105 *sec_trailer=AIRPDCAP_TKIP_TRAILER;
5111 /* allocate buffer for decrypted payload */
5112 if ((tmp = g_malloc(dec_caplen-offset)) == NULL)
5113 return NULL; /* krap! */
5114 memcpy(tmp, dec_data+offset, dec_caplen-offset);
5116 len=dec_caplen-offset;
5118 /* decrypt successful, let's set up a new data tvb. */
5119 decr_tvb = tvb_new_real_data(tmp, len, len);
5120 tvb_set_free_cb(decr_tvb, g_free);
5121 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
5127 /* Davide Schiera ----------------------------------------------------------- */
5130 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len) {
5131 const guint8 *enc_data;
5134 tvbuff_t *decr_tvb = NULL;
5136 if (! enable_decryption)
5139 enc_data = tvb_get_ptr(tvb, offset, len);
5141 if ((tmp = g_malloc(len)) == NULL)
5142 return NULL; /* krap! */
5144 /* try once with the key index in the packet, then look through our list. */
5145 for (i = 0; i < num_wepkeys; i++) {
5146 /* copy the encrypted data over to the tmp buffer */
5148 printf("trying %d\n", i);
5150 memcpy(tmp, enc_data, len);
5151 if (wep_decrypt(tmp, len, i) == 0) {
5153 /* decrypt successful, let's set up a new data tvb. */
5154 decr_tvb = tvb_new_real_data(tmp, len-8, len-8);
5155 tvb_set_free_cb(decr_tvb, g_free);
5156 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
5163 if ((!decr_tvb) && (tmp)) g_free(tmp);
5166 printf("de-wep %p\n", decr_tvb);
5172 #ifdef HAVE_AIRPDCAP
5174 void set_airpdcap_keys()
5177 AIRPDCAP_KEY_ITEM key;
5178 PAIRPDCAP_KEYS_COLLECTION keys;
5179 decryption_key_t* dk = NULL;
5184 keys=(PAIRPDCAP_KEYS_COLLECTION)g_malloc(sizeof(AIRPDCAP_KEYS_COLLECTION));
5187 for(i = 0; i < MAX_ENCRYPTION_KEYS; i++)
5189 tmpk = g_strdup(wep_keystr[i]);
5191 dk = parse_key_string(tmpk);
5195 if(dk->type == AIRPDCAP_KEY_TYPE_WEP)
5197 key.KeyType = AIRPDCAP_KEY_TYPE_WEP;
5199 bytes = g_byte_array_new();
5200 res = hex_str_to_bytes(dk->key->str, bytes, FALSE);
5202 if (dk->key->str && res && bytes->len > 0)
5205 * WEP key is correct (well, the can be even or odd, so it is not
5206 * a real check, I think... is a check performed somewhere in the
5207 * AirPDcap function??? )
5209 memcpy(key.KeyData.Wep.WepKey,bytes->data,bytes->len);
5210 key.KeyData.Wep.WepKeyLen = bytes->len;
5211 keys->Keys[keys->nKeys] = key;
5215 else if(dk->type == AIRPDCAP_KEY_TYPE_WPA_PWD)
5217 key.KeyType = AIRPDCAP_KEY_TYPE_WPA_PWD;
5219 /* XXX - Maybe check the lenght passed... */
5220 memcpy(key.KeyData.Wpa.UserPwd.Passphrase,dk->key->str,dk->key->len+1);
5222 if(dk->ssid != NULL)
5224 if(dk->ssid->len > 0)
5226 memcpy(key.KeyData.Wpa.UserPwd.Ssid,dk->ssid->data,dk->ssid->len);
5227 key.KeyData.Wpa.UserPwd.SsidLen = dk->ssid->len;
5229 else /* The GString is not NULL, but the 'ssid' name is just "\0" */
5231 key.KeyData.Wpa.UserPwd.SsidLen = 0;
5236 key.KeyData.Wpa.UserPwd.SsidLen = 0;
5239 keys->Keys[keys->nKeys] = key;
5242 else if(dk->type == AIRPDCAP_KEY_TYPE_WPA_PMK)
5244 key.KeyType = AIRPDCAP_KEY_TYPE_WPA_PMK;
5246 bytes = g_byte_array_new();
5247 res = hex_str_to_bytes(dk->key->str, bytes, FALSE);
5249 /* XXX - PAss the correct array of bytes... */
5250 memcpy(key.KeyData.Wpa.Pmk,bytes->data,bytes->len);
5252 keys->Keys[keys->nKeys] = key;
5256 if(tmpk != NULL) g_free(tmpk);
5259 /* Now set the keys */
5260 AirPDcapSetKeys(&airpdcap_ctx,keys->Keys,keys->nKeys);
5266 /* de-weps the block. if successful, buf* will point to the data start. */
5267 static int wep_decrypt(guint8 *buf, guint32 len, int keyidx) {
5268 guint32 i, j, k, crc, keylen;
5269 guint8 s[256], key[128], c_crc[4];
5270 guint8 *dpos, *cpos;
5272 /* Needs to be at least 8 bytes of payload */
5276 /* initialize the first bytes of the key from the IV */
5281 if (keyidx < 0 || keyidx >= num_wepkeys)
5284 keylen = wep_keylens[keyidx];
5288 if (wep_keys[keyidx] == NULL)
5291 keylen+=3; /* add in ICV bytes */
5293 /* copy the rest of the key over from the designated key */
5294 memcpy(key+3, wep_keys[keyidx], wep_keylens[keyidx]);
5297 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]);
5300 /* set up the RC4 state */
5301 for (i = 0; i < 256; i++)
5304 for (i = 0; i < 256; i++) {
5305 j = (j + s[i] + key[i % keylen]) & 0xff;
5309 /* Apply the RC4 to the data, update the CRC32 */
5314 for (k = 0; k < (len -8); k++) {
5316 j = (j+s[i]) & 0xff;
5319 printf("%d -- %02x ", k, *dpos);
5321 *dpos = *cpos++ ^ s[(s[i] + s[j]) & 0xff];
5323 printf("%02x\n", *dpos);
5325 crc = crc32_ccitt_table[(crc ^ *dpos++) & 0xff] ^ (crc >> 8);
5329 /* now let's check the crc */
5331 c_crc[1] = crc >> 8;
5332 c_crc[2] = crc >> 16;
5333 c_crc[3] = crc >> 24;
5335 for (k = 0; k < 4; k++) {
5337 j = (j+s[i]) & 0xff;
5340 printf("-- %02x %02x\n", *dpos, c_crc[k]);
5342 if ((*cpos++ ^ s[(s[i] + s[j]) & 0xff]) != c_crc[k])
5343 return -1; /* ICV mismatch */
5349 static void init_wepkeys(void) {
5356 for (i = 0; i < num_wepkeys; i++)
5357 g_free(wep_keys[i]);
5362 g_free(wep_keylens);
5367 tmp = getenv("WIRESHARK_WEPKEYNUM");
5372 num_wepkeys = atoi(tmp);
5374 if (num_wepkeys < 1)
5378 /* Figure out how many valid keys we have */
5379 bytes = g_byte_array_new();
5381 for ( i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
5382 res = hex_str_to_bytes(wep_keystr[i], bytes, FALSE);
5383 if (wep_keystr[i] && res && bytes-> len > 0) {
5388 #ifdef HAVE_AIRPDCAP
5390 * XXX - AirPDcap - That God sends it to us beautiful (che dio ce la mandi bona)
5391 * The next lines will add a key to the AirPDcap context. The keystring will be added
5392 * to the old WEP array too, but we don't care, because the packets will come here
5393 * already decrypted... One of these days we will fix this too
5395 set_airpdcap_keys();
5400 wep_keys = g_malloc0(num_wepkeys * sizeof(guint8*));
5401 wep_keylens = g_malloc(num_wepkeys * sizeof(int));
5403 for (i = 0, keyidx = 0; i < MAX_ENCRYPTION_KEYS && keyidx < num_wepkeys; i++) {
5404 wep_keys[keyidx] = NULL;
5405 wep_keylens[keyidx] = 0;
5409 g_snprintf(buf, 128, "WIRESHARK_WEPKEY%d", i+1);
5412 tmp = wep_keystr[i];
5418 printf("%s -- %s\n", buf, tmp);
5420 printf("%d -- %s\n", i+1, tmp);
5424 if (wep_keys[keyidx]) {
5425 g_free(wep_keys[keyidx]);
5428 res = hex_str_to_bytes(tmp, bytes, FALSE);
5429 if (tmp && res && bytes->len > 0) {
5430 if (bytes->len > 32) {
5433 wep_keys[keyidx] = g_malloc0(32 * sizeof(guint8));
5434 memcpy(wep_keys[keyidx], bytes->data, bytes->len * sizeof(guint8));
5435 wep_keylens[keyidx] = bytes->len;
5438 printf("%d: %d bytes\n", i, bytes->len);
5439 printf("%d: %s\n", i, bytes_to_str(bytes->data, bytes->len));
5443 printf("res: %d bytes->len: %d\n", res, bytes->len);
5445 g_warning("Could not parse WEP key %d: %s", i + 1, tmp);
5449 g_byte_array_free(bytes, TRUE);
5452 * This code had been taken from AirSnort crack.c function classify()
5453 * Permission granted by snax <at> shmoo dot com
5454 * weak_iv - determine which key byte an iv is useful in resolving
5455 * parm - p, pointer to the first byte of an IV
5456 * return - n - this IV is weak for byte n of a WEP key
5457 * -1 - this IV is not weak for any key bytes
5459 * This function tests for IVs that are known to satisfy the criteria
5460 * for a weak IV as specified in FMS section 7.1
5468 if (iv[1] == 255 && iv[0] > 2 && iv[0] < 16) {
5472 sum = iv[0] + iv[1];
5474 if (iv[2] <= 0x0a) {
5477 else if (iv[2] == 0xff){
5482 if (sum == k && (iv[2] >= 0xf2 && iv[2] <= 0xfe && iv[2] != 0xfd)){