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
6 * $Id: packet-ieee80211.c,v 1.68 2002/06/19 17:57:23 guy Exp $
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
10 * Copyright 1998 Gerald Combs
12 * Copied from README.developer
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 * The following people helped me by pointing out bugs etc. Thank you!
34 * Magnus Hultman-Persson
44 #ifdef HAVE_SYS_TYPES_H
45 # include <sys/types.h>
48 #ifdef HAVE_NETINET_IN_H
49 # include <netinet/in.h>
52 #ifdef NEED_SNPRINTF_H
58 # include "snprintf.h"
63 #include <epan/bitswap.h>
64 #include <epan/proto.h>
65 #include <epan/packet.h>
66 #include <epan/resolv.h>
68 #include "reassemble.h"
69 #include "packet-ipx.h"
70 #include "packet-llc.h"
71 #include "packet-ieee80211.h"
74 /* Defragment fragmented 802.11 datagrams */
75 static gboolean wlan_defragment = TRUE;
77 /* Check for the presence of the 802.11 FCS */
78 static gboolean wlan_check_fcs = FALSE;
80 /* Ignore the WEP bit; assume packet is decrypted */
81 static gboolean wlan_ignore_wep = FALSE;
83 /* Tables for reassembly of fragments. */
84 static GHashTable *wlan_fragment_table = NULL;
85 static GHashTable *wlan_reassembled_table = NULL;
87 /* Stuff for the WEP decoder */
88 static guint num_wepkeys = 0;
89 static guint8 **wep_keys = NULL;
90 static int *wep_keylens = NULL;
91 static void init_wepkeys(void);
92 static int wep_decrypt(guint8 *buf, guint32 len, int key_override);
93 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len);
94 #define SSWAP(a,b) {guint8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
97 /* When this is set, an unlimited number of WEP keys can be set in the
100 ETHEREAL_WEPKEYNUM=##
101 ETHEREAL_WEPKEY1=aa:bb:cc:dd:...
102 ETHEREAL_WEPKEY2=aa:bab:cc:dd:ee:...
104 ... you get the idea.
106 otherwise you're limited to specifying four keys in the preference system.
110 static char *wep_keystr[] = {NULL, NULL, NULL, NULL};
113 /* ************************************************************************* */
114 /* Miscellaneous Constants */
115 /* ************************************************************************* */
116 #define SHORT_STR 256
118 /* ************************************************************************* */
119 /* Define some very useful macros that are used to analyze frame types etc. */
120 /* ************************************************************************* */
121 #define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+((x & 0xF0) >> 4)) /* Create key to (sub)type */
122 #define COOK_PROT_VERSION(x) ((x) & 0x3)
123 #define COOK_FRAME_TYPE(x) (((x) & 0xC) >> 2)
124 #define COOK_FRAME_SUBTYPE(x) (((x) & 0xF0) >> 4)
125 #define COOK_ADDR_SELECTOR(x) ((x) & 0x300)
126 #define COOK_ASSOC_ID(x) ((x) & 0x3FFF)
127 #define COOK_FRAGMENT_NUMBER(x) ((x) & 0x000F)
128 #define COOK_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
129 #define COOK_FLAGS(x) (((x) & 0xFF00) >> 8)
130 #define COOK_DS_STATUS(x) ((x) & 0x3)
131 #define COOK_WEP_KEY(x) (((x) & 0xC0) >> 6)
133 #define FLAG_TO_DS 0x01
134 #define FLAG_FROM_DS 0x02
135 #define FLAG_MORE_FRAGMENTS 0x04
136 #define FLAG_RETRY 0x08
137 #define FLAG_POWER_MGT 0x10
138 #define FLAG_MORE_DATA 0x20
139 #define FLAG_WEP 0x40
140 #define FLAG_ORDER 0x80
142 #define IS_TO_DS(x) ((x) & FLAG_TO_DS)
143 #define IS_FROM_DS(x) ((x) & FLAG_FROM_DS)
144 #define HAVE_FRAGMENTS(x) ((x) & FLAG_MORE_FRAGMENTS)
145 #define IS_RETRY(x) ((x) & FLAG_RETRY)
146 #define POWER_MGT_STATUS(x) ((x) & FLAG_POWER_MGT)
147 #define HAS_MORE_DATA(x) ((x) & FLAG_MORE_DATA)
148 #define IS_WEP(x) (!wlan_ignore_wep && ((x) & FLAG_WEP))
149 #define IS_STRICTLY_ORDERED(x) ((x) & FLAG_ORDER)
151 #define MGT_RESERVED_RANGE(x) (((x>=0x06)&&(x<=0x07))||((x>=0x0D)&&(x<=0x0F)))
152 #define CTRL_RESERVED_RANGE(x) ((x>=0x10)&&(x<=0x19))
153 #define DATA_RESERVED_RANGE(x) ((x>=0x28)&&(x<=0x2f))
154 #define SPEC_RESERVED_RANGE(x) ((x>=0x30)&&(x<=0x3f))
157 /* ************************************************************************* */
158 /* Constants used to identify cooked frame types */
159 /* ************************************************************************* */
160 #define MGT_FRAME 0x00 /* Frame type is management */
161 #define CONTROL_FRAME 0x01 /* Frame type is control */
162 #define DATA_FRAME 0x02 /* Frame type is Data */
164 #define DATA_SHORT_HDR_LEN 24
165 #define DATA_LONG_HDR_LEN 30
166 #define MGT_FRAME_HDR_LEN 24 /* Length of Managment frame-headers */
168 #define MGT_ASSOC_REQ 0x00 /* Management - association request */
169 #define MGT_ASSOC_RESP 0x01 /* Management - association response */
170 #define MGT_REASSOC_REQ 0x02 /* Management - reassociation request */
171 #define MGT_REASSOC_RESP 0x03 /* Management - reassociation response */
172 #define MGT_PROBE_REQ 0x04 /* Management - Probe request */
173 #define MGT_PROBE_RESP 0x05 /* Management - Probe response */
174 #define MGT_BEACON 0x08 /* Management - Beacon frame */
175 #define MGT_ATIM 0x09 /* Management - ATIM */
176 #define MGT_DISASS 0x0A /* Management - Disassociation */
177 #define MGT_AUTHENTICATION 0x0B /* Management - Authentication */
178 #define MGT_DEAUTHENTICATION 0x0C /* Management - Deauthentication */
180 #define CTRL_PS_POLL 0x1A /* Control - power-save poll */
181 #define CTRL_RTS 0x1B /* Control - request to send */
182 #define CTRL_CTS 0x1C /* Control - clear to send */
183 #define CTRL_ACKNOWLEDGEMENT 0x1D /* Control - acknowledgement */
184 #define CTRL_CFP_END 0x1E /* Control - contention-free period end */
185 #define CTRL_CFP_ENDACK 0x1F /* Control - contention-free period end/ack */
187 #define DATA 0x20 /* Data - Data */
188 #define DATA_CF_ACK 0x21 /* Data - Data + CF acknowledge */
189 #define DATA_CF_POLL 0x22 /* Data - Data + CF poll */
190 #define DATA_CF_ACK_POLL 0x23 /* Data - Data + CF acknowledge + CF poll */
191 #define DATA_NULL_FUNCTION 0x24 /* Data - Null function (no data) */
192 #define DATA_CF_ACK_NOD 0x25 /* Data - CF ack (no data) */
193 #define DATA_CF_POLL_NOD 0x26 /* Data - Data + CF poll (No data) */
194 #define DATA_CF_ACK_POLL_NOD 0x27 /* Data - CF ack + CF poll (no data) */
196 #define DATA_ADDR_T1 0
197 #define DATA_ADDR_T2 (FLAG_FROM_DS << 8)
198 #define DATA_ADDR_T3 (FLAG_TO_DS << 8)
199 #define DATA_ADDR_T4 ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
202 /* ************************************************************************* */
203 /* Macros used to extract information about fixed fields */
204 /* ************************************************************************* */
205 #define ESS_SET(x) ((x) & 0x0001)
206 #define IBSS_SET(x) ((x) & 0x0002)
210 /* ************************************************************************* */
211 /* Logical field codes (dissector's encoding of fixed fields) */
212 /* ************************************************************************* */
213 #define FIELD_TIMESTAMP 0x01 /* 64-bit timestamp */
214 #define FIELD_BEACON_INTERVAL 0x02 /* 16-bit beacon interval */
215 #define FIELD_CAP_INFO 0x03 /* Add capability information tree */
216 #define FIELD_AUTH_ALG 0x04 /* Authentication algorithm used */
217 #define FIELD_AUTH_TRANS_SEQ 0x05 /* Authentication sequence number */
218 #define FIELD_CURRENT_AP_ADDR 0x06
219 #define FIELD_LISTEN_IVAL 0x07
220 #define FIELD_REASON_CODE 0x08
221 #define FIELD_ASSOC_ID 0x09
222 #define FIELD_STATUS_CODE 0x0A
224 /* ************************************************************************* */
225 /* Logical field codes (IEEE 802.11 encoding of tags) */
226 /* ************************************************************************* */
227 #define TAG_SSID 0x00
228 #define TAG_SUPP_RATES 0x01
229 #define TAG_FH_PARAMETER 0x02
230 #define TAG_DS_PARAMETER 0x03
231 #define TAG_CF_PARAMETER 0x04
233 #define TAG_IBSS_PARAMETER 0x06
234 #define TAG_CHALLENGE_TEXT 0x10
236 /* ************************************************************************* */
237 /* Frame types, and their names */
238 /* ************************************************************************* */
239 static const value_string frame_type_subtype_vals[] = {
240 {MGT_ASSOC_REQ, "Association Request"},
241 {MGT_ASSOC_RESP, "Association Response"},
242 {MGT_REASSOC_REQ, "Reassociation Request"},
243 {MGT_REASSOC_RESP, "Reassociation Response"},
244 {MGT_PROBE_REQ, "Probe Request"},
245 {MGT_PROBE_RESP, "Probe Response"},
246 {MGT_BEACON, "Beacon frame"},
248 {MGT_DISASS, "Dissassociate"},
249 {MGT_AUTHENTICATION, "Authentication"},
250 {MGT_DEAUTHENTICATION, "Deauthentication"},
251 {CTRL_PS_POLL, "Power-Save poll"},
252 {CTRL_RTS, "Request-to-send"},
253 {CTRL_CTS, "Clear-to-send"},
254 {CTRL_ACKNOWLEDGEMENT, "Acknowledgement"},
255 {CTRL_CFP_END, "CF-End (Control-frame)"},
256 {CTRL_CFP_ENDACK, "CF-End + CF-Ack (Control-frame)"},
258 {DATA_CF_ACK, "Data + CF-Acknowledgement"},
259 {DATA_CF_POLL, "Data + CF-Poll"},
260 {DATA_CF_ACK_POLL, "Data + CF-Acknowledgement/Poll"},
261 {DATA_NULL_FUNCTION, "Null function (No data)"},
262 {DATA_CF_ACK_NOD, "Data + Acknowledgement (No data)"},
263 {DATA_CF_POLL_NOD, "Data + CF-Poll (No data)"},
264 {DATA_CF_ACK_POLL_NOD, "Data + CF-Acknowledgement/Poll (No data)"},
268 static int proto_wlan = -1;
270 /* ************************************************************************* */
271 /* Header field info values for radio information */
272 /* ************************************************************************* */
273 static int hf_data_rate = -1;
274 static int hf_channel = -1;
275 static int hf_signal_strength = -1;
277 /* ************************************************************************* */
278 /* Header field info values for FC-field */
279 /* ************************************************************************* */
280 static int hf_fc_field = -1;
281 static int hf_fc_proto_version = -1;
282 static int hf_fc_frame_type = -1;
283 static int hf_fc_frame_subtype = -1;
284 static int hf_fc_frame_type_subtype = -1;
286 static int hf_fc_flags = -1;
287 static int hf_fc_to_ds = -1;
288 static int hf_fc_from_ds = -1;
289 static int hf_fc_data_ds = -1;
291 static int hf_fc_more_frag = -1;
292 static int hf_fc_retry = -1;
293 static int hf_fc_pwr_mgt = -1;
294 static int hf_fc_more_data = -1;
295 static int hf_fc_wep = -1;
296 static int hf_fc_order = -1;
299 /* ************************************************************************* */
300 /* Header values for Duration/ID field */
301 /* ************************************************************************* */
302 static int hf_did_duration = -1;
303 static int hf_assoc_id = -1;
306 /* ************************************************************************* */
307 /* Header values for different address-fields (all 4 of them) */
308 /* ************************************************************************* */
309 static int hf_addr_da = -1; /* Destination address subfield */
310 static int hf_addr_sa = -1; /* Source address subfield */
311 static int hf_addr_ra = -1; /* Receiver address subfield */
312 static int hf_addr_ta = -1; /* Transmitter address subfield */
313 static int hf_addr_bssid = -1; /* address is bssid */
315 static int hf_addr = -1; /* Source or destination address subfield */
318 /* ************************************************************************* */
319 /* Header values for sequence number field */
320 /* ************************************************************************* */
321 static int hf_frag_number = -1;
322 static int hf_seq_number = -1;
324 /* ************************************************************************* */
325 /* Header values for Frame Check field */
326 /* ************************************************************************* */
327 static int hf_fcs = -1;
329 /* ************************************************************************* */
330 /* Header values for reassembly */
331 /* ************************************************************************* */
332 static int hf_fragments = -1;
333 static int hf_fragment = -1;
334 static int hf_fragment_overlap = -1;
335 static int hf_fragment_overlap_conflict = -1;
336 static int hf_fragment_multiple_tails = -1;
337 static int hf_fragment_too_long_fragment = -1;
338 static int hf_fragment_error = -1;
341 static int proto_wlan_mgt = -1;
342 /* ************************************************************************* */
343 /* Fixed fields found in mgt frames */
344 /* ************************************************************************* */
345 static int ff_auth_alg = -1; /* Authentication algorithm field */
346 static int ff_auth_seq = -1; /* Authentication transaction sequence */
347 static int ff_current_ap = -1; /* Current AP MAC address */
348 static int ff_listen_ival = -1; /* Listen interval fixed field */
349 static int ff_timestamp = -1; /* 64 bit timestamp */
350 static int ff_beacon_interval = -1; /* 16 bit Beacon interval */
351 static int ff_assoc_id = -1; /* 16 bit AID field */
352 static int ff_reason = -1; /* 16 bit reason code */
353 static int ff_status_code = -1; /* Status code */
355 /* ************************************************************************* */
356 /* Flags found in the capability field (fixed field) */
357 /* ************************************************************************* */
358 static int ff_capture = -1;
359 static int ff_cf_sta_poll = -1; /* CF pollable status for a STA */
360 static int ff_cf_ap_poll = -1; /* CF pollable status for an AP */
361 static int ff_cf_ess = -1;
362 static int ff_cf_ibss = -1;
363 static int ff_cf_privacy = -1;
364 static int ff_cf_preamble = -1;
365 static int ff_cf_pbcc = -1;
366 static int ff_cf_agility = -1;
368 /* ************************************************************************* */
369 /* Tagged value format fields */
370 /* ************************************************************************* */
371 static int tag_number = -1;
372 static int tag_length = -1;
373 static int tag_interpretation = -1;
377 static int hf_fixed_parameters = -1; /* Protocol payload for management frames */
378 static int hf_tagged_parameters = -1; /* Fixed payload item */
379 static int hf_wep_iv = -1;
380 static int hf_wep_key = -1;
381 static int hf_wep_icv = -1;
383 /* ************************************************************************* */
385 /* ************************************************************************* */
386 static gint ett_80211 = -1;
387 static gint ett_proto_flags = -1;
388 static gint ett_cap_tree = -1;
389 static gint ett_fc_tree = -1;
390 static gint ett_fragments = -1;
391 static gint ett_fragment = -1;
393 static gint ett_80211_mgt = -1;
394 static gint ett_fixed_parameters = -1;
395 static gint ett_tagged_parameters = -1;
396 static gint ett_wep_parameters = -1;
398 fragment_items frag_items = {
403 &hf_fragment_overlap,
404 &hf_fragment_overlap_conflict,
405 &hf_fragment_multiple_tails,
406 &hf_fragment_too_long_fragment,
411 static dissector_handle_t llc_handle;
412 static dissector_handle_t ipx_handle;
413 static dissector_handle_t data_handle;
415 /* ************************************************************************* */
416 /* Return the length of the current header (in bytes) */
417 /* ************************************************************************* */
419 find_header_length (guint16 fcf)
421 switch (COOK_FRAME_TYPE (fcf)) {
424 return MGT_FRAME_HDR_LEN;
427 switch (COMPOSE_FRAME_TYPE (fcf)) {
430 case CTRL_ACKNOWLEDGEMENT:
436 case CTRL_CFP_ENDACK:
442 return (COOK_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
450 /* ************************************************************************* */
451 /* This is the capture function used to update packet counts */
452 /* ************************************************************************* */
454 capture_ieee80211_common (const u_char * pd, int offset, int len,
455 packet_counts * ld, gboolean fixed_length_header)
457 guint16 fcf, hdr_length;
459 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
464 fcf = pletohs (&pd[0]);
466 if (IS_WEP(COOK_FLAGS(fcf)))
472 switch (COMPOSE_FRAME_TYPE (fcf))
475 case DATA: /* We got a data frame */
476 case DATA_CF_ACK: /* Data with ACK */
478 case DATA_CF_ACK_POLL:
479 if (fixed_length_header)
480 hdr_length = DATA_LONG_HDR_LEN;
482 hdr_length = find_header_length (fcf);
483 /* I guess some bridges take Netware Ethernet_802_3 frames,
484 which are 802.3 frames (with a length field rather than
485 a type field, but with no 802.2 header in the payload),
486 and just stick the payload into an 802.11 frame. I've seen
487 captures that show frames of that sort.
489 This means we have to do the same check for Netware 802.3 -
490 or, if you will, "Netware 802.11" - that we do in the
491 Ethernet dissector, i.e. checking for 0xffff as the first
492 four bytes of the payload and, if we find it, treating it
494 if (!BYTES_ARE_IN_FRAME(offset+hdr_length, len, 2)) {
498 if (pd[offset+hdr_length] == 0xff && pd[offset+hdr_length+1] == 0xff) {
502 capture_llc (pd, offset + hdr_length, len, ld);
513 * Handle 802.11 with a variable-length link-layer header.
516 capture_ieee80211 (const u_char * pd, int offset, int len, packet_counts * ld)
518 capture_ieee80211_common (pd, offset, len, ld, FALSE);
522 * Handle 802.11 with a fixed-length link-layer header (padded to the
526 capture_ieee80211_fixed (const u_char * pd, int offset, int len, packet_counts * ld)
528 capture_ieee80211_common (pd, offset, len, ld, TRUE);
532 /* ************************************************************************* */
533 /* Add the subtree used to store the fixed parameters */
534 /* ************************************************************************* */
536 get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
538 proto_item *fixed_fields;
540 proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
541 size, size, "Fixed parameters (%d bytes)",
544 return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
548 /* ************************************************************************* */
549 /* Add the subtree used to store tagged parameters */
550 /* ************************************************************************* */
552 get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
554 proto_item *tagged_fields;
556 tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
561 "Tagged parameters (%d bytes)",
564 return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
568 /* ************************************************************************* */
569 /* Dissect and add fixed mgmt fields to protocol tree */
570 /* ************************************************************************* */
572 add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
574 const guint8 *dataptr;
575 char out_buff[SHORT_STR];
577 proto_item *cap_item;
578 static proto_tree *cap_tree;
583 case FIELD_TIMESTAMP:
584 dataptr = tvb_get_ptr (tvb, offset, 8);
585 memset (out_buff, 0, SHORT_STR);
586 snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
596 proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
599 case FIELD_BEACON_INTERVAL:
600 temp_double = (double) tvb_get_letohs (tvb, offset);
601 temp_double = temp_double * 1024 / 1000000;
602 proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
603 temp_double,"Beacon Interval: %f [Seconds]",
609 capability = tvb_get_letohs (tvb, offset);
611 cap_item = proto_tree_add_uint_format (tree, ff_capture,
614 "Capability Information: 0x%04X",
616 cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree);
617 proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 1,
619 proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 1,
621 proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 1,
623 proto_tree_add_boolean (cap_tree, ff_cf_preamble, tvb, offset, 1,
625 proto_tree_add_boolean (cap_tree, ff_cf_pbcc, tvb, offset, 1,
627 proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 1,
629 if (ESS_SET (capability) != 0) /* This is an AP */
630 proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2,
631 ((capability & 0xC) >> 2));
633 else /* This is a STA */
634 proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
635 ((capability & 0xC) >> 2));
639 proto_tree_add_item (tree, ff_auth_alg, tvb, offset, 2, TRUE);
642 case FIELD_AUTH_TRANS_SEQ:
643 proto_tree_add_item (tree, ff_auth_seq, tvb, offset, 2, TRUE);
646 case FIELD_CURRENT_AP_ADDR:
647 proto_tree_add_item (tree, ff_current_ap, tvb, offset, 6, FALSE);
650 case FIELD_LISTEN_IVAL:
651 proto_tree_add_item (tree, ff_listen_ival, tvb, offset, 2, TRUE);
654 case FIELD_REASON_CODE:
655 proto_tree_add_item (tree, ff_reason, tvb, offset, 2, TRUE);
659 proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE);
662 case FIELD_STATUS_CODE:
663 proto_tree_add_item (tree, ff_status_code, tvb, offset, 2, TRUE);
669 /* ************************************************************************* */
670 /* Dissect and add tagged (optional) fields to proto tree */
671 /* ************************************************************************* */
673 add_tagged_field (proto_tree * tree, tvbuff_t * tvb, int offset)
675 const guint8 *tag_data_ptr;
676 guint32 tag_no, tag_len;
679 char out_buff[SHORT_STR];
682 tag_no = tvb_get_guint8(tvb, offset);
683 tag_len = tvb_get_guint8(tvb, offset + 1);
685 tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
688 if ((tag_no >= 17) && (tag_no <= 31))
689 { /* Reserved for challenge text */
690 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
691 "Tag Number: %u (Reserved for challenge text)",
694 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
695 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
696 tag_len, "Not interpreted");
697 return (int) tag_len + 2;
700 /* Next See if tag is reserved - if true, skip it! */
701 if (((tag_no >= 7) && (tag_no <= 15))
702 || ((tag_no >= 32) && (tag_no <= 255)))
704 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
705 "Tag Number: %u (Reserved tag number)",
708 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
710 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
711 tag_len, "Not interpreted");
712 return (int) tag_len + 2;
721 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
722 "Tag Number: %u (SSID parameter set)",
725 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
727 memset (out_buff, 0, SHORT_STR);
729 memcpy (out_buff, tag_data_ptr, (size_t) tag_len);
730 out_buff[tag_len + 1] = 0;
732 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
739 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
740 "Tag Number: %u (Supported Rates)", tag_no);
742 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
744 memset (out_buff, 0, SHORT_STR);
745 strcpy (out_buff, "Supported rates: ");
746 n = strlen (out_buff);
748 for (i = 0; i < tag_len && n < SHORT_STR; i++)
750 ret = snprintf (out_buff + n, SHORT_STR - n, "%2.1f%s ",
751 (tag_data_ptr[i] & 0x7F) * 0.5,
752 (tag_data_ptr[i] & 0x80) ? "(B)" : "");
754 /* Some versions of snprintf return -1 if they'd truncate
761 snprintf (out_buff + n, SHORT_STR - n, "[Mbit/sec]");
763 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
769 case TAG_FH_PARAMETER:
770 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
771 "Tag Number: %u (FH Parameter set)",
774 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
775 memset (out_buff, 0, SHORT_STR);
777 snprintf (out_buff, SHORT_STR,
778 "Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, "
779 "Hop Index %2d", pletohs (tag_data_ptr), tag_data_ptr[2],
780 tag_data_ptr[3], tag_data_ptr[4]);
782 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
788 case TAG_DS_PARAMETER:
789 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
790 "Tag Number: %u (DS Parameter set)",
793 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
794 memset (out_buff, 0, SHORT_STR);
796 snprintf (out_buff, SHORT_STR, "Current Channel: %u", tag_data_ptr[0]);
797 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
802 case TAG_CF_PARAMETER:
803 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
804 "Tag Number: %u (CF Parameter set)",
807 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
808 memset (out_buff, 0, SHORT_STR);
810 snprintf (out_buff, SHORT_STR,
811 "CFP count %u, CFP period %u, CFP max duration %u, "
812 "CFP Remaining %u", tag_data_ptr[0], tag_data_ptr[1],
813 pletohs (tag_data_ptr + 2), pletohs (tag_data_ptr + 4));
815 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
821 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
822 "Tag Number: %u ((TIM) Traffic Indication Map)",
825 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
826 memset (out_buff, 0, SHORT_STR);
827 snprintf (out_buff, SHORT_STR,
828 "DTIM count %u, DTIM period %u, Bitmap control 0x%X, "
829 "(Bitmap suppressed)", tag_data_ptr[0], tag_data_ptr[1],
831 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
837 case TAG_IBSS_PARAMETER:
838 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
839 "Tag Number: %u (IBSS Parameter set)",
842 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
843 memset (out_buff, 0, SHORT_STR);
844 snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
845 pletohs (tag_data_ptr));
847 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
853 case TAG_CHALLENGE_TEXT:
854 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
855 "Tag Number: %u (Challenge text)", tag_no);
857 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
858 memset (out_buff, 0, SHORT_STR);
859 snprintf (out_buff, SHORT_STR, "Challenge text: %.47s", tag_data_ptr);
860 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
872 /* ************************************************************************* */
873 /* Dissect 802.11 management frame */
874 /* ************************************************************************* */
876 dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
879 proto_item *ti = NULL;
880 proto_tree *mgt_tree;
881 proto_tree *fixed_tree;
882 proto_tree *tagged_tree;
885 int tagged_parameter_tree_len;
887 CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
891 ti = proto_tree_add_item (tree, proto_wlan_mgt, tvb, 0, -1, FALSE);
892 mgt_tree = proto_item_add_subtree (ti, ett_80211_mgt);
894 switch (COMPOSE_FRAME_TYPE(fcf))
898 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
899 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
900 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
902 next_idx = 4; /* Size of fixed fields */
903 tagged_parameter_tree_len =
904 tvb_reported_length_remaining(tvb, next_idx);
905 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
906 tagged_parameter_tree_len);
908 while (tagged_parameter_tree_len > 0) {
909 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
912 tagged_parameter_tree_len -= next_len;
918 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
919 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
920 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
921 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
923 next_idx = 6; /* Size of fixed fields */
925 tagged_parameter_tree_len =
926 tvb_reported_length_remaining(tvb, next_idx);
927 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
928 tagged_parameter_tree_len);
930 while (tagged_parameter_tree_len > 0) {
931 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
934 tagged_parameter_tree_len -= next_len;
939 case MGT_REASSOC_REQ:
940 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
941 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
942 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
943 add_fixed_field (fixed_tree, tvb, 4, FIELD_CURRENT_AP_ADDR);
945 next_idx = 10; /* Size of fixed fields */
946 tagged_parameter_tree_len =
947 tvb_reported_length_remaining(tvb, next_idx);
948 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
949 tagged_parameter_tree_len);
951 while (tagged_parameter_tree_len > 0) {
952 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
955 tagged_parameter_tree_len -= next_len;
959 case MGT_REASSOC_RESP:
960 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
961 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
962 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
963 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
965 next_idx = 6; /* Size of fixed fields */
966 tagged_parameter_tree_len =
967 tvb_reported_length_remaining(tvb, next_idx);
968 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
969 tagged_parameter_tree_len);
971 while (tagged_parameter_tree_len > 0) {
972 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
975 tagged_parameter_tree_len -= next_len;
982 tagged_parameter_tree_len =
983 tvb_reported_length_remaining(tvb, next_idx);
984 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
985 tagged_parameter_tree_len);
987 while (tagged_parameter_tree_len > 0) {
988 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
991 tagged_parameter_tree_len -= next_len;
997 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
998 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
999 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
1000 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
1002 next_idx = 12; /* Size of fixed fields */
1003 tagged_parameter_tree_len =
1004 tvb_reported_length_remaining(tvb, next_idx);
1005 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
1006 tagged_parameter_tree_len);
1008 while (tagged_parameter_tree_len > 0) {
1009 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
1011 next_idx +=next_len;
1012 tagged_parameter_tree_len -= next_len;
1017 case MGT_BEACON: /* Dissect protocol payload fields */
1018 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
1020 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
1021 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
1022 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
1024 next_idx = 12; /* Size of fixed fields */
1025 tagged_parameter_tree_len =
1026 tvb_reported_length_remaining(tvb, next_idx);
1027 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
1028 tagged_parameter_tree_len);
1030 while (tagged_parameter_tree_len > 0) {
1031 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
1033 next_idx +=next_len;
1034 tagged_parameter_tree_len -= next_len;
1044 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1045 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
1049 case MGT_AUTHENTICATION:
1050 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1051 add_fixed_field (fixed_tree, tvb, 0, FIELD_AUTH_ALG);
1052 add_fixed_field (fixed_tree, tvb, 2, FIELD_AUTH_TRANS_SEQ);
1053 add_fixed_field (fixed_tree, tvb, 4, FIELD_STATUS_CODE);
1055 next_idx = 6; /* Size of fixed fields */
1057 tagged_parameter_tree_len =
1058 tvb_reported_length_remaining(tvb, next_idx);
1059 if (tagged_parameter_tree_len != 0)
1061 tagged_tree = get_tagged_parameter_tree (mgt_tree,
1064 tagged_parameter_tree_len);
1066 while (tagged_parameter_tree_len > 0) {
1067 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
1069 next_idx +=next_len;
1070 tagged_parameter_tree_len -= next_len;
1076 case MGT_DEAUTHENTICATION:
1077 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1078 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
1085 set_src_addr_cols(packet_info *pinfo, const guint8 *addr, char *type)
1087 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1088 col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "%s (%s)",
1089 get_ether_name(addr), type);
1090 if (check_col(pinfo->cinfo, COL_UNRES_DL_SRC))
1091 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s (%s)",
1092 ether_to_str(addr), type);
1096 set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, char *type)
1098 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1099 col_add_fstr(pinfo->cinfo, COL_RES_DL_DST, "%s (%s)",
1100 get_ether_name(addr), type);
1101 if (check_col(pinfo->cinfo, COL_UNRES_DL_DST))
1102 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s (%s)",
1103 ether_to_str(addr), type);
1106 /* ************************************************************************* */
1107 /* Dissect 802.11 frame */
1108 /* ************************************************************************* */
1110 dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
1111 proto_tree * tree, gboolean fixed_length_header,
1112 gboolean has_radio_information, gboolean has_no_fcs)
1114 guint16 fcf, flags, frame_type_subtype;
1115 guint16 seq_control;
1116 guint32 seq_number, frag_number;
1117 gboolean more_frags;
1118 const guint8 *src = NULL, *dst = NULL;
1119 proto_item *ti = NULL;
1120 proto_item *flag_item;
1121 proto_item *fc_item;
1122 proto_tree *hdr_tree = NULL;
1123 proto_tree *flag_tree;
1124 proto_tree *fc_tree;
1126 gint len, reported_len;
1127 gboolean save_fragmented;
1128 tvbuff_t *volatile next_tvb = NULL;
1130 volatile gboolean is_802_2;
1132 if (check_col (pinfo->cinfo, COL_PROTOCOL))
1133 col_set_str (pinfo->cinfo, COL_PROTOCOL, "IEEE 802.11");
1134 if (check_col (pinfo->cinfo, COL_INFO))
1135 col_clear (pinfo->cinfo, COL_INFO);
1137 fcf = tvb_get_letohs (tvb, 0);
1138 if (fixed_length_header)
1139 hdr_len = DATA_LONG_HDR_LEN;
1141 hdr_len = find_header_length (fcf);
1142 frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
1144 if (check_col (pinfo->cinfo, COL_INFO))
1145 col_set_str (pinfo->cinfo, COL_INFO,
1146 val_to_str(frame_type_subtype, frame_type_subtype_vals,
1147 "Unrecognized (Reserved frame)"));
1149 flags = COOK_FLAGS (fcf);
1150 more_frags = HAVE_FRAGMENTS (flags);
1152 /* Add the radio information, if present, and the FC to the current tree */
1155 ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
1157 hdr_tree = proto_item_add_subtree (ti, ett_80211);
1159 if (has_radio_information) {
1160 proto_tree_add_uint_format(hdr_tree, hf_data_rate,
1162 pinfo->pseudo_header->ieee_802_11.data_rate,
1163 "Data Rate: %g mb/s",
1164 .5*pinfo->pseudo_header->ieee_802_11.data_rate);
1166 proto_tree_add_uint(hdr_tree, hf_channel,
1168 pinfo->pseudo_header->ieee_802_11.channel);
1170 proto_tree_add_uint_format(hdr_tree, hf_signal_strength,
1172 pinfo->pseudo_header->ieee_802_11.signal_level,
1173 "Signal Strength: %u%%",
1174 pinfo->pseudo_header->ieee_802_11.signal_level);
1177 proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
1179 frame_type_subtype);
1181 fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb, 0, 2,
1183 "Frame Control: 0x%04X",
1186 fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
1189 proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb, 0, 1,
1190 COOK_PROT_VERSION (fcf));
1192 proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb, 0, 1,
1193 COOK_FRAME_TYPE (fcf));
1195 proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
1197 COOK_FRAME_SUBTYPE (fcf));
1200 proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb, 1, 1,
1201 flags, "Flags: 0x%X", flags);
1203 flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
1205 proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb, 1, 1,
1206 COOK_DS_STATUS (flags));
1208 proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb, 1, 1,
1211 proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb, 1, 1, flags);
1213 proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb, 1, 1, flags);
1215 proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb, 1, 1,
1218 proto_tree_add_boolean (flag_tree, hf_fc_wep, tvb, 1, 1, flags);
1220 proto_tree_add_boolean (flag_tree, hf_fc_order, tvb, 1, 1, flags);
1222 if (frame_type_subtype == CTRL_PS_POLL)
1223 proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
1224 COOK_ASSOC_ID(tvb_get_letohs(tvb,2)));
1227 proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
1228 tvb_get_letohs (tvb, 2));
1232 * Decode the part of the frame header that isn't the same for all
1239 switch (COOK_FRAME_TYPE (fcf))
1244 * All management frame types have the same header.
1246 src = tvb_get_ptr (tvb, 10, 6);
1247 dst = tvb_get_ptr (tvb, 4, 6);
1249 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
1250 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
1251 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
1252 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
1254 seq_control = tvb_get_letohs(tvb, 22);
1255 frag_number = COOK_FRAGMENT_NUMBER(seq_control);
1256 seq_number = COOK_SEQUENCE_NUMBER(seq_control);
1260 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
1262 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
1264 /* add items for wlan.addr filter */
1265 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
1266 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
1268 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
1269 tvb_get_ptr (tvb, 16, 6));
1271 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1274 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1280 switch (frame_type_subtype)
1284 src = tvb_get_ptr (tvb, 10, 6);
1285 dst = tvb_get_ptr (tvb, 4, 6);
1287 set_src_addr_cols(pinfo, src, "BSSID");
1288 set_dst_addr_cols(pinfo, dst, "BSSID");
1292 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6, dst);
1294 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
1300 src = tvb_get_ptr (tvb, 10, 6);
1301 dst = tvb_get_ptr (tvb, 4, 6);
1303 set_src_addr_cols(pinfo, src, "TA");
1304 set_dst_addr_cols(pinfo, dst, "RA");
1308 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1310 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
1316 dst = tvb_get_ptr (tvb, 4, 6);
1318 set_dst_addr_cols(pinfo, dst, "RA");
1321 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1325 case CTRL_ACKNOWLEDGEMENT:
1326 dst = tvb_get_ptr (tvb, 4, 6);
1328 set_dst_addr_cols(pinfo, dst, "RA");
1331 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1336 src = tvb_get_ptr (tvb, 10, 6);
1337 dst = tvb_get_ptr (tvb, 4, 6);
1339 set_src_addr_cols(pinfo, src, "BSSID");
1340 set_dst_addr_cols(pinfo, dst, "RA");
1344 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1345 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
1350 case CTRL_CFP_ENDACK:
1351 src = tvb_get_ptr (tvb, 10, 6);
1352 dst = tvb_get_ptr (tvb, 4, 6);
1354 set_src_addr_cols(pinfo, src, "BSSID");
1355 set_dst_addr_cols(pinfo, dst, "RA");
1359 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1361 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
1368 addr_type = COOK_ADDR_SELECTOR (fcf);
1370 /* In order to show src/dst address we must always do the following */
1375 src = tvb_get_ptr (tvb, 10, 6);
1376 dst = tvb_get_ptr (tvb, 4, 6);
1381 src = tvb_get_ptr (tvb, 16, 6);
1382 dst = tvb_get_ptr (tvb, 4, 6);
1387 src = tvb_get_ptr (tvb, 10, 6);
1388 dst = tvb_get_ptr (tvb, 16, 6);
1393 src = tvb_get_ptr (tvb, 24, 6);
1394 dst = tvb_get_ptr (tvb, 16, 6);
1398 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
1399 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
1400 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
1401 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
1403 seq_control = tvb_get_letohs(tvb, 22);
1404 frag_number = COOK_FRAGMENT_NUMBER(seq_control);
1405 seq_number = COOK_SEQUENCE_NUMBER(seq_control);
1407 /* Now if we have a tree we start adding stuff */
1416 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
1417 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
1418 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
1419 tvb_get_ptr (tvb, 16, 6));
1420 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1422 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1425 /* add items for wlan.addr filter */
1426 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
1427 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
1432 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
1433 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
1434 tvb_get_ptr (tvb, 10, 6));
1435 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6, src);
1436 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1438 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1441 /* add items for wlan.addr filter */
1442 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
1443 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, src);
1448 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
1449 tvb_get_ptr (tvb, 4, 6));
1450 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
1451 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
1453 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1455 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1458 /* add items for wlan.addr filter */
1459 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
1460 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
1465 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
1466 tvb_get_ptr (tvb, 4, 6));
1467 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
1468 tvb_get_ptr (tvb, 10, 6));
1469 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
1470 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1472 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1474 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6, src);
1476 /* add items for wlan.addr filter */
1477 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
1478 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 24, 6, src);
1486 len = tvb_length_remaining(tvb, hdr_len);
1487 reported_len = tvb_reported_length_remaining(tvb, hdr_len);
1489 if (!has_no_fcs && (wlan_check_fcs))
1492 * Well, this packet should, in theory, have an FCS.
1493 * Do we have the entire packet, and does it have enough data for
1496 if (reported_len < 4)
1499 * The packet is claimed not to even have enough data for a 4-byte
1501 * Pretend it doesn't have an FCS.
1505 else if (len < reported_len)
1508 * The packet is claimed to have enough data for a 4-byte FCS, but
1509 * we didn't capture all of the packet.
1510 * Slice off the 4-byte FCS from the reported length, and trim the
1511 * captured length so it's no more than the reported length; that
1512 * will slice off what of the FCS, if any, is in the captured
1516 if (len > reported_len)
1522 * We have the entire packet, and it includes a 4-byte FCS.
1523 * Slice it off, and put it into the tree.
1528 proto_tree_add_item (hdr_tree, hf_fcs, tvb, hdr_len + len, 4, FALSE);
1533 * Only management and data frames have a body, so we don't have
1534 * anything more to do for other types of frames.
1536 switch (COOK_FRAME_TYPE (fcf))
1544 * No-data frames don't have a body.
1546 switch (frame_type_subtype)
1549 case DATA_NULL_FUNCTION:
1550 case DATA_CF_ACK_NOD:
1551 case DATA_CF_POLL_NOD:
1552 case DATA_CF_ACK_POLL_NOD:
1561 if (IS_WEP(COOK_FLAGS(fcf))) {
1563 * It's a WEP-encrypted frame; dissect the WEP parameters and decrypt
1564 * the data, if we have a matching key. Otherwise display it as data.
1566 gboolean can_decrypt = FALSE;
1567 proto_tree *wep_tree = NULL;
1570 proto_item *wep_fields;
1572 wep_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 4,
1575 wep_tree = proto_item_add_subtree (wep_fields, ett_wep_parameters);
1576 proto_tree_add_item (wep_tree, hf_wep_iv, tvb, hdr_len, 3, TRUE);
1578 proto_tree_add_uint (wep_tree, hf_wep_key, tvb, hdr_len + 3, 1,
1579 COOK_WEP_KEY (tvb_get_guint8 (tvb, hdr_len + 3)));
1582 /* Subtract out the length of the IV. */
1585 if (len < 0 || reported_len < 0) {
1586 /* We don't have anything beyond the IV. */
1591 * Well, this packet should, in theory, have an ICV.
1592 * Do we have the entire packet, and does it have enough data for
1595 if (reported_len < 4) {
1597 * The packet is claimed not to even have enough data for a
1599 * Pretend it doesn't have an ICV.
1602 } else if (len < reported_len) {
1604 * The packet is claimed to have enough data for a 4-byte ICV,
1605 * but we didn't capture all of the packet.
1606 * Slice off the 4-byte ICV from the reported length, and trim
1607 * the captured length so it's no more than the reported length;
1608 * that will slice off what of the ICV, if any, is in the
1613 if (len > reported_len)
1617 * We have the entire packet, and it includes a 4-byte ICV.
1618 * Slice it off, and put it into the tree.
1620 * We only support decrypting if we have the the ICV.
1622 * XXX - the ICV is encrypted; we're putting the encrypted
1623 * value, not the decrypted value, into the tree.
1628 proto_tree_add_item (wep_tree, hf_wep_icv, tvb, hdr_len + 4 + len, 4,
1633 if (!can_decrypt || (next_tvb = try_decrypt_wep(tvb, hdr_len, reported_len + 8)) == NULL) {
1635 * WEP decode impossible or failed, treat payload as raw data
1636 * and don't attempt fragment reassembly or further dissection.
1638 next_tvb = tvb_new_subset(tvb, hdr_len + 4, len, reported_len);
1640 call_dissector(data_handle, next_tvb, pinfo, tree);
1643 add_new_data_source(pinfo, next_tvb, "Decrypted WEP data");
1647 * WEP decryption successful!
1649 * Use the tvbuff we got back from the decryption; the data starts at
1650 * the beginning. The lengths are already correct for the decoded WEP
1657 * Not a WEP-encrypted frame; just use the data from the tvbuff
1660 * The payload starts at "hdr_len" (i.e., just past the 802.11
1661 * MAC header), the length of data in the tvbuff following the
1662 * 802.11 header is "len", and the length of data in the packet
1663 * following the 802.11 header is "reported_len".
1669 * Do defragmentation if "wlan_defragment" is true, and we have more
1670 * fragments or this isn't the first fragment.
1672 * We have to do some special handling to catch frames that
1673 * have the "More Fragments" indicator not set but that
1674 * don't show up as reassembled and don't have any other
1675 * fragments present. Some networking interfaces appear
1676 * to do reassembly even when you're capturing raw packets
1677 * *and* show the reassembled packet without the "More
1678 * Fragments" indicator set *but* with a non-zero fragment
1681 * "fragment_add_seq_check()" handles that; we want to call it
1682 * even if we have a short frame, so that it does those checks - if
1683 * the frame is short, it doesn't do reassembly on it.
1685 * (This could get some false positives if we really *did* only
1686 * capture the last fragment of a fragmented packet, but that's
1689 save_fragmented = pinfo->fragmented;
1690 if (wlan_defragment && (more_frags || frag_number != 0)) {
1691 fragment_data *fd_head;
1694 * If we've already seen this frame, look it up in the
1695 * table of reassembled packets, otherwise add it to
1696 * whatever reassembly is in progress, if any, and see
1699 fd_head = fragment_add_seq_check(next_tvb, hdr_len, pinfo, seq_number,
1700 wlan_fragment_table,
1701 wlan_reassembled_table,
1705 if (fd_head != NULL) {
1707 * Either this is reassembled or it wasn't fragmented
1708 * (see comment above about some networking interfaces).
1709 * In either case, it's now in the table of reassembled
1712 * If the "fragment_data" structure doesn't have a list of
1713 * fragments, we assume it's a placeholder to mark those
1714 * not-really-fragmented packets, and just treat this as
1715 * a non-fragmented frame.
1717 if (fd_head->next != NULL) {
1718 next_tvb = tvb_new_real_data(fd_head->data, fd_head->len, fd_head->len);
1719 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
1720 add_new_data_source(pinfo, next_tvb, "Reassembled 802.11");
1722 /* Show all fragments. */
1723 show_fragment_seq_tree(fd_head, &frag_items, hdr_tree, pinfo, next_tvb);
1726 * Not fragmented, really.
1727 * Show it as a regular frame.
1729 next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len);
1732 /* It's not fragmented. */
1733 pinfo->fragmented = FALSE;
1735 /* We don't have the complete reassembled payload. */
1740 * If this is the first fragment, dissect its contents, otherwise
1741 * just show it as a fragment.
1743 if (frag_number != 0) {
1744 /* Not the first fragment - don't dissect it. */
1747 /* First fragment, or not fragmented. Dissect what we have here. */
1749 /* Get a tvbuff for the payload. */
1750 next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len);
1753 * If this is the first fragment, but not the only fragment,
1754 * tell the next protocol that.
1757 pinfo->fragmented = TRUE;
1759 pinfo->fragmented = FALSE;
1763 if (next_tvb == NULL) {
1764 /* Just show this as an incomplete fragment. */
1765 if (check_col(pinfo->cinfo, COL_INFO))
1766 col_set_str(pinfo->cinfo, COL_INFO, "Fragmented IEEE 802.11 frame");
1767 next_tvb = tvb_new_subset (tvb, hdr_len, len, reported_len);
1768 call_dissector(data_handle, next_tvb, pinfo, tree);
1769 pinfo->fragmented = save_fragmented;
1773 switch (COOK_FRAME_TYPE (fcf))
1777 dissect_ieee80211_mgt (fcf, next_tvb, pinfo, tree);
1782 /* I guess some bridges take Netware Ethernet_802_3 frames,
1783 which are 802.3 frames (with a length field rather than
1784 a type field, but with no 802.2 header in the payload),
1785 and just stick the payload into an 802.11 frame. I've seen
1786 captures that show frames of that sort.
1788 This means we have to do the same check for Netware 802.3 -
1789 or, if you will, "Netware 802.11" - that we do in the
1790 Ethernet dissector, i.e. checking for 0xffff as the first
1791 four bytes of the payload and, if we find it, treating it
1795 if (tvb_get_ntohs(next_tvb, 0) == 0xffff)
1798 CATCH2(BoundsError, ReportedBoundsError) {
1805 call_dissector(llc_handle, next_tvb, pinfo, tree);
1807 call_dissector(ipx_handle, next_tvb, pinfo, tree);
1810 pinfo->fragmented = save_fragmented;
1814 * Dissect 802.11 with a variable-length link-layer header.
1817 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1819 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, FALSE);
1823 * Dissect 802.11 with a variable-length link-layer header and a pseudo-
1824 * header containing radio information.
1827 dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1829 /* These packets do NOT have a FCS present */
1830 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE, TRUE);
1834 * Dissect 802.11 with a fixed-length link-layer header (padded to the
1838 dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1840 dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, FALSE);
1844 wlan_defragment_init(void)
1846 fragment_table_init(&wlan_fragment_table);
1847 reassembled_table_init(&wlan_reassembled_table);
1851 proto_register_wlan (void)
1853 static const value_string frame_type[] = {
1854 {MGT_FRAME, "Management frame"},
1855 {CONTROL_FRAME, "Control frame"},
1856 {DATA_FRAME, "Data frame"},
1860 static const value_string tofrom_ds[] = {
1861 {0, "Not leaving DS or network is operating in AD-HOC mode (To DS: 0 From DS: 0)"},
1862 {FLAG_TO_DS, "Frame is entering DS (To DS: 1 From DS: 0)"},
1863 {FLAG_FROM_DS, "Frame is exiting DS (To DS: 0 From DS: 1)"},
1864 {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS (To DS: 1 From DS: 1)"},
1868 static const true_false_string tods_flag = {
1869 "TO DS: Should be false",
1873 static const true_false_string fromds_flag = {
1874 "FROM DS: Should be false",
1878 static const true_false_string more_frags = {
1879 "More fragments follow",
1880 "This is the last fragment"
1883 static const true_false_string retry_flags = {
1884 "Frame is being retransmitted",
1885 "Frame is not being retransmitted"
1888 static const true_false_string pm_flags = {
1889 "STA will go to sleep",
1893 static const true_false_string md_flags = {
1894 "Data is buffered for STA at AP",
1898 static const true_false_string wep_flags = {
1903 static const true_false_string order_flags = {
1905 "Not strictly ordered"
1908 static const true_false_string cf_ess_flags = {
1909 "Transmitter is an AP",
1910 "Transmitter is a STA"
1914 static const true_false_string cf_privacy_flags = {
1915 "AP/STA can support WEP",
1916 "AP/STA cannot support WEP"
1919 static const true_false_string cf_preamble_flags = {
1920 "Short preamble allowed",
1921 "Short preamble not allowed"
1924 static const true_false_string cf_pbcc_flags = {
1925 "PBCC modulation allowed",
1926 "PBCC modulation not allowed"
1929 static const true_false_string cf_agility_flags = {
1930 "Channel agility in use",
1931 "Channel agility not in use"
1935 static const true_false_string cf_ibss_flags = {
1936 "Transmitter belongs to an IBSS",
1937 "Transmitter belongs to a BSS"
1940 static const value_string sta_cf_pollable[] = {
1941 {0x00, "Station is not CF-Pollable"},
1942 {0x02, "Station is CF-Pollable, "
1943 "not requesting to be placed on the CF-polling list"},
1944 {0x01, "Station is CF-Pollable, "
1945 "requesting to be placed on the CF-polling list"},
1946 {0x03, "Station is CF-Pollable, requesting never to be polled"},
1950 static const value_string ap_cf_pollable[] = {
1951 {0x00, "No point coordinator at AP"},
1952 {0x02, "Point coordinator at AP for delivery only (no polling)"},
1953 {0x01, "Point coordinator at AP for delivery and polling"},
1959 static const value_string auth_alg[] = {
1960 {0x00, "Open System"},
1961 {0x01, "Shared key"},
1965 static const value_string reason_codes[] = {
1967 {0x01, "Unspecified reason"},
1968 {0x02, "Previous authentication no longer valid"},
1969 {0x03, "Deauthenticated because sending STA is leaving (has left) "
1971 {0x04, "Disassociated due to inactivity"},
1972 {0x05, "Disassociated because AP is unable to handle all currently "
1973 "associated stations"},
1974 {0x06, "Class 2 frame received from nonauthenticated station"},
1975 {0x07, "Class 3 frame received from nonassociated station"},
1976 {0x08, "Disassociated because sending STA is leaving (has left) BSS"},
1977 {0x09, "Station requesting (re)association is not authenticated with "
1978 "responding station"},
1983 static const value_string status_codes[] = {
1984 {0x00, "Successful"},
1985 {0x01, "Unspecified failure"},
1986 {0x0A, "Cannot support all requested capabilities in the "
1987 "Capability information field"},
1988 {0x0B, "Reassociation denied due to inability to confirm that "
1989 "association exists"},
1990 {0x0C, "Association denied due to reason outside the scope of this "
1993 {0x0D, "Responding station does not support the specified authentication "
1995 {0x0E, "Received an Authentication frame with authentication sequence "
1996 "transaction sequence number out of expected sequence"},
1997 {0x0F, "Authentication rejected because of challenge failure"},
1998 {0x10, "Authentication rejected due to timeout waiting for next "
1999 "frame in sequence"},
2000 {0x11, "Association denied because AP is unable to handle additional "
2001 "associated stations"},
2002 {0x12, "Association denied due to requesting station not supporting all "
2003 "of the datarates in the BSSBasicServiceSet Parameter"},
2007 static hf_register_info hf[] = {
2009 {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
2010 "Data rate (.5 Mb/s units)", HFILL }},
2013 {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
2014 "Radio channel", HFILL }},
2016 {&hf_signal_strength,
2017 {"Signal Strength", "wlan.signal_strength", FT_UINT8, BASE_DEC, NULL, 0,
2018 "Signal strength (percentage)", HFILL }},
2021 {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
2022 "MAC Frame control", HFILL }},
2024 {&hf_fc_proto_version,
2025 {"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
2026 "MAC Protocol version", HFILL }}, /* 0 */
2029 {"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, VALS(frame_type), 0,
2030 "Frame type", HFILL }},
2032 {&hf_fc_frame_subtype,
2033 {"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
2034 "Frame subtype", HFILL }}, /* 2 */
2036 {&hf_fc_frame_type_subtype,
2037 {"Type/Subtype", "wlan.fc.type_subtype", FT_UINT16, BASE_DEC, VALS(frame_type_subtype_vals), 0,
2038 "Type and subtype combined", HFILL }},
2041 {"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
2042 "Protocol flags", HFILL }},
2045 {"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, VALS (&tofrom_ds), 0,
2046 "Data-frame DS-traversal status", HFILL }}, /* 3 */
2049 {"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), FLAG_TO_DS,
2050 "To DS flag", HFILL }}, /* 4 */
2053 {"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), FLAG_FROM_DS,
2054 "From DS flag", HFILL }}, /* 5 */
2057 {"More Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), FLAG_MORE_FRAGMENTS,
2058 "More Fragments flag", HFILL }}, /* 6 */
2061 {"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), FLAG_RETRY,
2062 "Retransmission flag", HFILL }},
2065 {"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), FLAG_POWER_MGT,
2066 "Power management status", HFILL }},
2069 {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
2070 "More data flag", HFILL }},
2073 {"WEP flag", "wlan.fc.wep", FT_BOOLEAN, 8, TFS (&wep_flags), FLAG_WEP,
2074 "WEP flag", HFILL }},
2077 {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
2078 "Strictly ordered flag", HFILL }},
2081 {"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
2082 "Association-ID field", HFILL }},
2085 {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
2086 "Duration field", HFILL }},
2089 {"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
2090 "Destination Hardware Address", HFILL }},
2093 {"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
2094 "Source Hardware Address", HFILL }},
2097 {"Source or Destination address", "wlan.addr", FT_ETHER, BASE_NONE, NULL, 0,
2098 "Source or Destination Hardware Address", HFILL }},
2101 {"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
2102 "Receiving Station Hardware Address", HFILL }},
2105 {"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
2106 "Transmitting Station Hardware Address", HFILL }},
2109 {"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
2110 "Basic Service Set ID", HFILL }},
2113 {"Fragment number", "wlan.frag", FT_UINT16, BASE_DEC, NULL, 0,
2114 "Fragment number", HFILL }},
2117 {"Sequence number", "wlan.seq", FT_UINT16, BASE_DEC, NULL, 0,
2118 "Sequence number", HFILL }},
2121 {"Frame Check Sequence (not verified)", "wlan.fcs", FT_UINT32, BASE_HEX,
2122 NULL, 0, "FCS", HFILL }},
2124 {&hf_fragment_overlap,
2125 {"Fragment overlap", "wlan.fragment.overlap", FT_BOOLEAN, BASE_NONE,
2126 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
2128 {&hf_fragment_overlap_conflict,
2129 {"Conflicting data in fragment overlap", "wlan.fragment.overlap.conflict",
2130 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2131 "Overlapping fragments contained conflicting data", HFILL }},
2133 {&hf_fragment_multiple_tails,
2134 {"Multiple tail fragments found", "wlan.fragment.multipletails",
2135 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2136 "Several tails were found when defragmenting the packet", HFILL }},
2138 {&hf_fragment_too_long_fragment,
2139 {"Fragment too long", "wlan.fragment.toolongfragment",
2140 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2141 "Fragment contained data past end of packet", HFILL }},
2143 {&hf_fragment_error,
2144 {"Defragmentation error", "wlan.fragment.error",
2145 FT_NONE, BASE_NONE, NULL, 0x0,
2146 "Defragmentation error due to illegal fragments", HFILL }},
2149 {"802.11 Fragment", "wlan.fragment", FT_NONE, BASE_NONE, NULL, 0x0,
2150 "802.11 Fragment", HFILL }},
2153 {"802.11 Fragments", "wlan.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
2154 "802.11 Fragments", HFILL }},
2157 {"Initialization Vector", "wlan.wep.iv", FT_UINT24, BASE_HEX, NULL, 0,
2158 "Initialization Vector", HFILL }},
2161 {"Key", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
2165 {"WEP ICV (not verified)", "wlan.wep.icv", FT_UINT32, BASE_HEX, NULL, 0,
2166 "WEP ICV", HFILL }},
2169 static hf_register_info ff[] = {
2171 {"Timestamp", "wlan_mgt.fixed.timestamp", FT_STRING, BASE_NONE,
2172 NULL, 0, "", HFILL }},
2175 {"Authentication Algorithm", "wlan_mgt.fixed.auth.alg",
2176 FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, "", HFILL }},
2178 {&ff_beacon_interval,
2179 {"Beacon Interval", "wlan_mgt.fixed.beacon", FT_DOUBLE, BASE_DEC, NULL, 0,
2182 {&hf_fixed_parameters,
2183 {"Fixed parameters", "wlan_mgt.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
2186 {&hf_tagged_parameters,
2187 {"Tagged parameters", "wlan_mgt.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
2191 {"Capabilities", "wlan_mgt.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
2192 "Capability information", HFILL }},
2195 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.sta",
2196 FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0,
2197 "CF-Poll capabilities for a STA", HFILL }},
2200 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.ap",
2201 FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0,
2202 "CF-Poll capabilities for an AP", HFILL }},
2205 {"ESS capabilities", "wlan_mgt.fixed.capabilities.ess",
2206 FT_BOOLEAN, 8, TFS (&cf_ess_flags), 0x0001, "ESS capabilities", HFILL }},
2210 {"IBSS status", "wlan_mgt.fixed.capabilities.ibss",
2211 FT_BOOLEAN, 8, TFS (&cf_ibss_flags), 0x0002, "IBSS participation", HFILL }},
2213 {"Privacy", "wlan_mgt.fixed.capabilities.privacy",
2214 FT_BOOLEAN, 8, TFS (&cf_privacy_flags), 0x0010, "WEP support", HFILL }},
2217 {"Short Preamble", "wlan_mgt.fixed.capabilities.preamble",
2218 FT_BOOLEAN, 8, TFS (&cf_preamble_flags), 0x0020, "Short Preamble", HFILL }},
2221 {"PBCC", "wlan_mgt.fixed.capabilities.pbcc",
2222 FT_BOOLEAN, 8, TFS (&cf_pbcc_flags), 0x0040, "PBCC Modulation", HFILL }},
2225 {"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
2226 FT_BOOLEAN, 8, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
2229 {"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
2230 FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
2233 {"Association ID", "wlan_mgt.fixed.aid",
2234 FT_UINT16, BASE_HEX, NULL, 0, "Association ID", HFILL }},
2237 {"Listen Interval", "wlan_mgt.fixed.listen_ival",
2238 FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval", HFILL }},
2241 {"Current AP", "wlan_mgt.fixed.current_ap",
2242 FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP", HFILL }},
2245 {"Reason code", "wlan_mgt.fixed.reason_code",
2246 FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
2247 "Reason for unsolicited notification", HFILL }},
2250 {"Status code", "wlan_mgt.fixed.status_code",
2251 FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
2252 "Status of requested event", HFILL }},
2255 {"Tag", "wlan_mgt.tag.number",
2256 FT_UINT16, BASE_DEC, NULL, 0,
2257 "Element ID", HFILL }},
2260 {"Tag length", "wlan_mgt.tag.length",
2261 FT_UINT16, BASE_DEC, NULL, 0, "Length of tag", HFILL }},
2263 {&tag_interpretation,
2264 {"Tag interpretation", "wlan_mgt.tag.interpretation",
2265 FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }}
2269 static gint *tree_array[] = {
2276 &ett_fixed_parameters,
2277 &ett_tagged_parameters,
2278 &ett_wep_parameters,
2281 module_t *wlan_module;
2283 static const enum_val_t wep_keys_options[] = {
2293 proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
2294 "IEEE 802.11", "wlan");
2295 proto_register_field_array (proto_wlan, hf, array_length (hf));
2296 proto_wlan_mgt = proto_register_protocol ("IEEE 802.11 wireless LAN management frame",
2297 "802.11 MGT", "wlan_mgt");
2298 proto_register_field_array (proto_wlan_mgt, ff, array_length (ff));
2299 proto_register_subtree_array (tree_array, array_length (tree_array));
2301 register_dissector("wlan", dissect_ieee80211, proto_wlan);
2302 register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
2303 register_init_routine(wlan_defragment_init);
2305 /* Register configuration options */
2306 wlan_module = prefs_register_protocol(proto_wlan, NULL);
2307 prefs_register_bool_preference(wlan_module, "defragment",
2308 "Reassemble fragmented 802.11 datagrams",
2309 "Whether fragmented 802.11 datagrams should be reassembled",
2312 prefs_register_bool_preference(wlan_module, "check_fcs",
2313 "Assume packets have FCS",
2314 "Some 802.11 cards include the FCS at the end of a packet, others do not.",
2317 prefs_register_bool_preference(wlan_module, "ignore_wep",
2318 "Ignore the WEP bit",
2319 "Some 802.11 cards leave the WEP bit set even though the packet is decrypted.",
2323 prefs_register_enum_preference(wlan_module, "wep_keys",
2325 "How many WEP keys do we have to choose from? (0 to disable, up to 4)",
2326 &num_wepkeys, wep_keys_options, FALSE);
2328 prefs_register_string_preference(wlan_module, "wep_key1",
2330 "First WEP key (A:B:C:D:E:F)",
2332 prefs_register_string_preference(wlan_module, "wep_key2",
2334 "Second WEP key (A:B:C:D:E:F)",
2336 prefs_register_string_preference(wlan_module, "wep_key3",
2338 "Third WEP key (A:B:C:D:E:F)",
2340 prefs_register_string_preference(wlan_module, "wep_key4",
2342 "Fourth WEP key (A:B:C:D:E:F)",
2348 proto_reg_handoff_wlan(void)
2350 dissector_handle_t ieee80211_handle;
2351 dissector_handle_t ieee80211_radio_handle;
2354 * Get handles for the LLC and IPX dissectors.
2356 llc_handle = find_dissector("llc");
2357 ipx_handle = find_dissector("ipx");
2358 data_handle = find_dissector("data");
2360 ieee80211_handle = find_dissector("wlan");
2361 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle);
2362 ieee80211_radio_handle = create_dissector_handle(dissect_ieee80211_radio,
2364 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
2365 ieee80211_radio_handle);
2368 static const guint32 wep_crc32_table[256] = {
2369 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
2370 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
2371 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
2372 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
2373 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
2374 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
2375 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
2376 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
2377 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
2378 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
2379 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
2380 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
2381 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
2382 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
2383 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
2384 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
2385 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
2386 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
2387 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
2388 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
2389 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
2390 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
2391 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
2392 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
2393 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
2394 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
2395 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
2396 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
2397 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
2398 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
2399 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
2400 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
2401 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
2402 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
2403 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
2404 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
2405 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
2406 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
2407 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
2408 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
2409 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
2410 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
2411 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
2412 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
2413 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
2414 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
2415 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
2416 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
2417 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
2418 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
2419 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
2423 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len) {
2426 tvbuff_t *decr_tvb = NULL;
2428 if (num_wepkeys < 1)
2430 if (wep_keylens == NULL)
2433 if ((tmp = g_malloc(len)) == NULL)
2434 return NULL; /* krap! */
2436 /* try once with the key index in the packet, then look through our list. */
2437 for (i = -1; i < (int) num_wepkeys; i++) {
2438 /* copy the encrypted data over to the tmp buffer */
2440 printf("trying %d\n", i);
2442 tvb_memcpy(tvb, tmp, offset, len);
2443 if (wep_decrypt(tmp, len, i) == 0) {
2445 /* decrypt successful, let's set up a new data tvb. */
2446 decr_tvb = tvb_new_real_data(tmp, len-8, len-8);
2447 tvb_set_free_cb(decr_tvb, g_free);
2448 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
2455 if ((!decr_tvb) && (tmp)) free(tmp);
2458 printf("de-wep %p\n", decr_tvb);
2465 /* de-weps the block. if successful, buf* will point to the data start. */
2466 static int wep_decrypt(guint8 *buf, guint32 len, int key_override) {
2467 guint32 i, j, k, crc, keylen;
2468 guint8 s[256], key[128], c_crc[4];
2469 guint8 keyidx, *dpos, *cpos;
2471 /* Needs to be at least 8 bytes of payload */
2475 /* initialize the first bytes of the key from the IV */
2479 keyidx = COOK_WEP_KEY(buf[3]);
2481 if (key_override >= 0)
2482 keyidx = key_override;
2484 if (keyidx >= num_wepkeys)
2487 keylen = wep_keylens[keyidx];
2491 if (wep_keys[keyidx] == NULL)
2494 keylen+=3; /* add in ICV bytes */
2496 /* copy the rest of the key over from the designated key */
2497 memcpy(key+3, wep_keys[keyidx], wep_keylens[keyidx]);
2500 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]);
2503 /* set up the RC4 state */
2504 for (i = 0; i < 256; i++)
2507 for (i = 0; i < 256; i++) {
2508 j = (j + s[i] + key[i % keylen]) & 0xff;
2512 /* Apply the RC4 to the data, update the CRC32 */
2517 for (k = 0; k < (len -8); k++) {
2519 j = (j+s[i]) & 0xff;
2522 printf("%d -- %02x ", k, *dpos);
2524 *dpos = *cpos++ ^ s[(s[i] + s[j]) & 0xff];
2526 printf("%02x\n", *dpos);
2528 crc = wep_crc32_table[(crc ^ *dpos++) & 0xff] ^ (crc >> 8);
2532 /* now let's check the crc */
2534 c_crc[1] = crc >> 8;
2535 c_crc[2] = crc >> 16;
2536 c_crc[3] = crc >> 24;
2538 for (k = 0; k < 4; k++) {
2540 j = (j+s[i]) & 0xff;
2543 printf("-- %02x %02x\n", *dpos, c_crc[k]);
2545 if ((*cpos++ ^ s[(s[i] + s[j]) & 0xff]) != c_crc[k])
2546 return -1; /* ICV mismatch */
2552 /* XXX need to verify these malloc()s succeed */
2554 static void init_wepkeys(void) {
2562 tmp = getenv("ETHEREAL_WEPKEYNUM");
2567 num_wepkeys = atoi(tmp);
2569 if (num_wepkeys > 4)
2573 if (num_wepkeys < 1)
2576 if (wep_keylens != NULL)
2579 wep_keys = malloc(num_wepkeys * sizeof(guint8*));
2580 wep_keylens = malloc(num_wepkeys * sizeof(int));
2582 for (i = 0 ; i < num_wepkeys; i++) {
2587 sprintf(buf, "ETHEREAL_WEPKEY%d", i+1);
2590 tmp = wep_keystr[i];
2597 printf("%s -- %s\n", buf, tmp);
2599 printf("%d -- %s\n", i+1, tmp);
2603 wep_keys[i] = malloc(32 * sizeof(guint8));
2604 memset(wep_keys[i], 0, 32 * sizeof(guint8));
2606 while ((tmp != NULL) && (*tmp != 0)) {
2607 tmp3[j] = strtoul(tmp, &tmp2, 16) & 0xff;
2609 printf("%d %d -- %02x\n", i, j, tmp3[j]);
2614 if ((tmp != NULL) && (*tmp == ':'))