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.77 2002/10/31 20:46:00 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 NEED_SNPRINTF_H
45 # include "snprintf.h"
50 #include <epan/bitswap.h>
51 #include <epan/proto.h>
52 #include <epan/packet.h>
53 #include <epan/resolv.h>
55 #include "reassemble.h"
56 #include "packet-ipx.h"
57 #include "packet-llc.h"
58 #include "packet-ieee80211.h"
61 /* Defragment fragmented 802.11 datagrams */
62 static gboolean wlan_defragment = TRUE;
64 /* Check for the presence of the 802.11 FCS */
65 static gboolean wlan_check_fcs = FALSE;
67 /* Ignore the WEP bit; assume packet is decrypted */
68 static gboolean wlan_ignore_wep = FALSE;
70 /* Tables for reassembly of fragments. */
71 static GHashTable *wlan_fragment_table = NULL;
72 static GHashTable *wlan_reassembled_table = NULL;
74 /* Stuff for the WEP decoder */
75 static guint num_wepkeys = 0;
76 static guint8 **wep_keys = NULL;
77 static int *wep_keylens = NULL;
78 static void init_wepkeys(void);
79 static int wep_decrypt(guint8 *buf, guint32 len, int key_override);
80 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len);
81 #define SSWAP(a,b) {guint8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
83 /* FCS utility function. */
84 static guint32 crc32(const unsigned char* buf, unsigned int len);
87 /* When this is set, an unlimited number of WEP keys can be set in the
91 ETHEREAL_WEPKEY1=aa:bb:cc:dd:...
92 ETHEREAL_WEPKEY2=aa:bab:cc:dd:ee:...
96 otherwise you're limited to specifying four keys in the preference system.
100 static char *wep_keystr[] = {NULL, NULL, NULL, NULL};
103 /* ************************************************************************* */
104 /* Miscellaneous Constants */
105 /* ************************************************************************* */
106 #define SHORT_STR 256
108 /* ************************************************************************* */
109 /* Define some very useful macros that are used to analyze frame types etc. */
110 /* ************************************************************************* */
111 #define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+((x & 0xF0) >> 4)) /* Create key to (sub)type */
112 #define COOK_PROT_VERSION(x) ((x) & 0x3)
113 #define COOK_FRAME_TYPE(x) (((x) & 0xC) >> 2)
114 #define COOK_FRAME_SUBTYPE(x) (((x) & 0xF0) >> 4)
115 #define COOK_ADDR_SELECTOR(x) ((x) & 0x300)
116 #define COOK_ASSOC_ID(x) ((x) & 0x3FFF)
117 #define COOK_FRAGMENT_NUMBER(x) ((x) & 0x000F)
118 #define COOK_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
119 #define COOK_FLAGS(x) (((x) & 0xFF00) >> 8)
120 #define COOK_DS_STATUS(x) ((x) & 0x3)
121 #define COOK_WEP_KEY(x) (((x) & 0xC0) >> 6)
123 #define FLAG_TO_DS 0x01
124 #define FLAG_FROM_DS 0x02
125 #define FLAG_MORE_FRAGMENTS 0x04
126 #define FLAG_RETRY 0x08
127 #define FLAG_POWER_MGT 0x10
128 #define FLAG_MORE_DATA 0x20
129 #define FLAG_WEP 0x40
130 #define FLAG_ORDER 0x80
132 #define IS_TO_DS(x) ((x) & FLAG_TO_DS)
133 #define IS_FROM_DS(x) ((x) & FLAG_FROM_DS)
134 #define HAVE_FRAGMENTS(x) ((x) & FLAG_MORE_FRAGMENTS)
135 #define IS_RETRY(x) ((x) & FLAG_RETRY)
136 #define POWER_MGT_STATUS(x) ((x) & FLAG_POWER_MGT)
137 #define HAS_MORE_DATA(x) ((x) & FLAG_MORE_DATA)
138 #define IS_WEP(x) (!wlan_ignore_wep && ((x) & FLAG_WEP))
139 #define IS_STRICTLY_ORDERED(x) ((x) & FLAG_ORDER)
141 #define MGT_RESERVED_RANGE(x) (((x>=0x06)&&(x<=0x07))||((x>=0x0D)&&(x<=0x0F)))
142 #define CTRL_RESERVED_RANGE(x) ((x>=0x10)&&(x<=0x19))
143 #define DATA_RESERVED_RANGE(x) ((x>=0x28)&&(x<=0x2f))
144 #define SPEC_RESERVED_RANGE(x) ((x>=0x30)&&(x<=0x3f))
147 /* ************************************************************************* */
148 /* Constants used to identify cooked frame types */
149 /* ************************************************************************* */
150 #define MGT_FRAME 0x00 /* Frame type is management */
151 #define CONTROL_FRAME 0x01 /* Frame type is control */
152 #define DATA_FRAME 0x02 /* Frame type is Data */
154 #define DATA_SHORT_HDR_LEN 24
155 #define DATA_LONG_HDR_LEN 30
156 #define MGT_FRAME_HDR_LEN 24 /* Length of Managment frame-headers */
158 #define MGT_ASSOC_REQ 0x00 /* Management - association request */
159 #define MGT_ASSOC_RESP 0x01 /* Management - association response */
160 #define MGT_REASSOC_REQ 0x02 /* Management - reassociation request */
161 #define MGT_REASSOC_RESP 0x03 /* Management - reassociation response */
162 #define MGT_PROBE_REQ 0x04 /* Management - Probe request */
163 #define MGT_PROBE_RESP 0x05 /* Management - Probe response */
164 #define MGT_BEACON 0x08 /* Management - Beacon frame */
165 #define MGT_ATIM 0x09 /* Management - ATIM */
166 #define MGT_DISASS 0x0A /* Management - Disassociation */
167 #define MGT_AUTHENTICATION 0x0B /* Management - Authentication */
168 #define MGT_DEAUTHENTICATION 0x0C /* Management - Deauthentication */
170 #define CTRL_PS_POLL 0x1A /* Control - power-save poll */
171 #define CTRL_RTS 0x1B /* Control - request to send */
172 #define CTRL_CTS 0x1C /* Control - clear to send */
173 #define CTRL_ACKNOWLEDGEMENT 0x1D /* Control - acknowledgement */
174 #define CTRL_CFP_END 0x1E /* Control - contention-free period end */
175 #define CTRL_CFP_ENDACK 0x1F /* Control - contention-free period end/ack */
177 #define DATA 0x20 /* Data - Data */
178 #define DATA_CF_ACK 0x21 /* Data - Data + CF acknowledge */
179 #define DATA_CF_POLL 0x22 /* Data - Data + CF poll */
180 #define DATA_CF_ACK_POLL 0x23 /* Data - Data + CF acknowledge + CF poll */
181 #define DATA_NULL_FUNCTION 0x24 /* Data - Null function (no data) */
182 #define DATA_CF_ACK_NOD 0x25 /* Data - CF ack (no data) */
183 #define DATA_CF_POLL_NOD 0x26 /* Data - Data + CF poll (No data) */
184 #define DATA_CF_ACK_POLL_NOD 0x27 /* Data - CF ack + CF poll (no data) */
186 #define DATA_ADDR_T1 0
187 #define DATA_ADDR_T2 (FLAG_FROM_DS << 8)
188 #define DATA_ADDR_T3 (FLAG_TO_DS << 8)
189 #define DATA_ADDR_T4 ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
192 /* ************************************************************************* */
193 /* Macros used to extract information about fixed fields */
194 /* ************************************************************************* */
195 #define ESS_SET(x) ((x) & 0x0001)
196 #define IBSS_SET(x) ((x) & 0x0002)
200 /* ************************************************************************* */
201 /* Logical field codes (dissector's encoding of fixed fields) */
202 /* ************************************************************************* */
203 #define FIELD_TIMESTAMP 0x01 /* 64-bit timestamp */
204 #define FIELD_BEACON_INTERVAL 0x02 /* 16-bit beacon interval */
205 #define FIELD_CAP_INFO 0x03 /* Add capability information tree */
206 #define FIELD_AUTH_ALG 0x04 /* Authentication algorithm used */
207 #define FIELD_AUTH_TRANS_SEQ 0x05 /* Authentication sequence number */
208 #define FIELD_CURRENT_AP_ADDR 0x06
209 #define FIELD_LISTEN_IVAL 0x07
210 #define FIELD_REASON_CODE 0x08
211 #define FIELD_ASSOC_ID 0x09
212 #define FIELD_STATUS_CODE 0x0A
214 /* ************************************************************************* */
215 /* Logical field codes (IEEE 802.11 encoding of tags) */
216 /* ************************************************************************* */
217 #define TAG_SSID 0x00
218 #define TAG_SUPP_RATES 0x01
219 #define TAG_FH_PARAMETER 0x02
220 #define TAG_DS_PARAMETER 0x03
221 #define TAG_CF_PARAMETER 0x04
223 #define TAG_IBSS_PARAMETER 0x06
224 #define TAG_CHALLENGE_TEXT 0x10
226 /* ************************************************************************* */
227 /* Frame types, and their names */
228 /* ************************************************************************* */
229 static const value_string frame_type_subtype_vals[] = {
230 {MGT_ASSOC_REQ, "Association Request"},
231 {MGT_ASSOC_RESP, "Association Response"},
232 {MGT_REASSOC_REQ, "Reassociation Request"},
233 {MGT_REASSOC_RESP, "Reassociation Response"},
234 {MGT_PROBE_REQ, "Probe Request"},
235 {MGT_PROBE_RESP, "Probe Response"},
236 {MGT_BEACON, "Beacon frame"},
238 {MGT_DISASS, "Dissassociate"},
239 {MGT_AUTHENTICATION, "Authentication"},
240 {MGT_DEAUTHENTICATION, "Deauthentication"},
241 {CTRL_PS_POLL, "Power-Save poll"},
242 {CTRL_RTS, "Request-to-send"},
243 {CTRL_CTS, "Clear-to-send"},
244 {CTRL_ACKNOWLEDGEMENT, "Acknowledgement"},
245 {CTRL_CFP_END, "CF-End (Control-frame)"},
246 {CTRL_CFP_ENDACK, "CF-End + CF-Ack (Control-frame)"},
248 {DATA_CF_ACK, "Data + CF-Acknowledgement"},
249 {DATA_CF_POLL, "Data + CF-Poll"},
250 {DATA_CF_ACK_POLL, "Data + CF-Acknowledgement/Poll"},
251 {DATA_NULL_FUNCTION, "Null function (No data)"},
252 {DATA_CF_ACK_NOD, "Data + Acknowledgement (No data)"},
253 {DATA_CF_POLL_NOD, "Data + CF-Poll (No data)"},
254 {DATA_CF_ACK_POLL_NOD, "Data + CF-Acknowledgement/Poll (No data)"},
258 static int proto_wlan = -1;
260 /* ************************************************************************* */
261 /* Header field info values for radio information */
262 /* ************************************************************************* */
263 static int hf_data_rate = -1;
264 static int hf_channel = -1;
265 static int hf_signal_strength = -1;
267 /* ************************************************************************* */
268 /* Header field info values for FC-field */
269 /* ************************************************************************* */
270 static int hf_fc_field = -1;
271 static int hf_fc_proto_version = -1;
272 static int hf_fc_frame_type = -1;
273 static int hf_fc_frame_subtype = -1;
274 static int hf_fc_frame_type_subtype = -1;
276 static int hf_fc_flags = -1;
277 static int hf_fc_to_ds = -1;
278 static int hf_fc_from_ds = -1;
279 static int hf_fc_data_ds = -1;
281 static int hf_fc_more_frag = -1;
282 static int hf_fc_retry = -1;
283 static int hf_fc_pwr_mgt = -1;
284 static int hf_fc_more_data = -1;
285 static int hf_fc_wep = -1;
286 static int hf_fc_order = -1;
289 /* ************************************************************************* */
290 /* Header values for Duration/ID field */
291 /* ************************************************************************* */
292 static int hf_did_duration = -1;
293 static int hf_assoc_id = -1;
296 /* ************************************************************************* */
297 /* Header values for different address-fields (all 4 of them) */
298 /* ************************************************************************* */
299 static int hf_addr_da = -1; /* Destination address subfield */
300 static int hf_addr_sa = -1; /* Source address subfield */
301 static int hf_addr_ra = -1; /* Receiver address subfield */
302 static int hf_addr_ta = -1; /* Transmitter address subfield */
303 static int hf_addr_bssid = -1; /* address is bssid */
305 static int hf_addr = -1; /* Source or destination address subfield */
308 /* ************************************************************************* */
309 /* Header values for sequence number field */
310 /* ************************************************************************* */
311 static int hf_frag_number = -1;
312 static int hf_seq_number = -1;
314 /* ************************************************************************* */
315 /* Header values for Frame Check field */
316 /* ************************************************************************* */
317 static int hf_fcs = -1;
319 /* ************************************************************************* */
320 /* Header values for reassembly */
321 /* ************************************************************************* */
322 static int hf_fragments = -1;
323 static int hf_fragment = -1;
324 static int hf_fragment_overlap = -1;
325 static int hf_fragment_overlap_conflict = -1;
326 static int hf_fragment_multiple_tails = -1;
327 static int hf_fragment_too_long_fragment = -1;
328 static int hf_fragment_error = -1;
331 static int proto_wlan_mgt = -1;
332 /* ************************************************************************* */
333 /* Fixed fields found in mgt frames */
334 /* ************************************************************************* */
335 static int ff_auth_alg = -1; /* Authentication algorithm field */
336 static int ff_auth_seq = -1; /* Authentication transaction sequence */
337 static int ff_current_ap = -1; /* Current AP MAC address */
338 static int ff_listen_ival = -1; /* Listen interval fixed field */
339 static int ff_timestamp = -1; /* 64 bit timestamp */
340 static int ff_beacon_interval = -1; /* 16 bit Beacon interval */
341 static int ff_assoc_id = -1; /* 16 bit AID field */
342 static int ff_reason = -1; /* 16 bit reason code */
343 static int ff_status_code = -1; /* Status code */
345 /* ************************************************************************* */
346 /* Flags found in the capability field (fixed field) */
347 /* ************************************************************************* */
348 static int ff_capture = -1;
349 static int ff_cf_sta_poll = -1; /* CF pollable status for a STA */
350 static int ff_cf_ap_poll = -1; /* CF pollable status for an AP */
351 static int ff_cf_ess = -1;
352 static int ff_cf_ibss = -1;
353 static int ff_cf_privacy = -1;
354 static int ff_cf_preamble = -1;
355 static int ff_cf_pbcc = -1;
356 static int ff_cf_agility = -1;
358 /* ************************************************************************* */
359 /* Tagged value format fields */
360 /* ************************************************************************* */
361 static int tag_number = -1;
362 static int tag_length = -1;
363 static int tag_interpretation = -1;
367 static int hf_fixed_parameters = -1; /* Protocol payload for management frames */
368 static int hf_tagged_parameters = -1; /* Fixed payload item */
369 static int hf_wep_iv = -1;
370 static int hf_wep_key = -1;
371 static int hf_wep_icv = -1;
373 /* ************************************************************************* */
375 /* ************************************************************************* */
376 static gint ett_80211 = -1;
377 static gint ett_proto_flags = -1;
378 static gint ett_cap_tree = -1;
379 static gint ett_fc_tree = -1;
380 static gint ett_fragments = -1;
381 static gint ett_fragment = -1;
383 static gint ett_80211_mgt = -1;
384 static gint ett_fixed_parameters = -1;
385 static gint ett_tagged_parameters = -1;
386 static gint ett_wep_parameters = -1;
388 static const fragment_items frag_items = {
393 &hf_fragment_overlap,
394 &hf_fragment_overlap_conflict,
395 &hf_fragment_multiple_tails,
396 &hf_fragment_too_long_fragment,
401 static dissector_handle_t llc_handle;
402 static dissector_handle_t ipx_handle;
403 static dissector_handle_t data_handle;
405 /* ************************************************************************* */
406 /* Return the length of the current header (in bytes) */
407 /* ************************************************************************* */
409 find_header_length (guint16 fcf)
411 switch (COOK_FRAME_TYPE (fcf)) {
414 return MGT_FRAME_HDR_LEN;
417 switch (COMPOSE_FRAME_TYPE (fcf)) {
420 case CTRL_ACKNOWLEDGEMENT:
426 case CTRL_CFP_ENDACK:
432 return (COOK_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
440 /* ************************************************************************* */
441 /* This is the capture function used to update packet counts */
442 /* ************************************************************************* */
444 capture_ieee80211_common (const guchar * pd, int offset, int len,
445 packet_counts * ld, gboolean fixed_length_header)
447 guint16 fcf, hdr_length;
449 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
454 fcf = pletohs (&pd[0]);
456 if (IS_WEP(COOK_FLAGS(fcf)))
462 switch (COMPOSE_FRAME_TYPE (fcf))
465 case DATA: /* We got a data frame */
466 case DATA_CF_ACK: /* Data with ACK */
468 case DATA_CF_ACK_POLL:
469 if (fixed_length_header)
470 hdr_length = DATA_LONG_HDR_LEN;
472 hdr_length = find_header_length (fcf);
473 /* I guess some bridges take Netware Ethernet_802_3 frames,
474 which are 802.3 frames (with a length field rather than
475 a type field, but with no 802.2 header in the payload),
476 and just stick the payload into an 802.11 frame. I've seen
477 captures that show frames of that sort.
479 This means we have to do the same check for Netware 802.3 -
480 or, if you will, "Netware 802.11" - that we do in the
481 Ethernet dissector, i.e. checking for 0xffff as the first
482 four bytes of the payload and, if we find it, treating it
484 if (!BYTES_ARE_IN_FRAME(offset+hdr_length, len, 2)) {
488 if (pd[offset+hdr_length] == 0xff && pd[offset+hdr_length+1] == 0xff) {
492 capture_llc (pd, offset + hdr_length, len, ld);
503 * Handle 802.11 with a variable-length link-layer header.
506 capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
508 capture_ieee80211_common (pd, offset, len, ld, FALSE);
512 * Handle 802.11 with a fixed-length link-layer header (padded to the
516 capture_ieee80211_fixed (const guchar * pd, int offset, int len, packet_counts * ld)
518 capture_ieee80211_common (pd, offset, len, ld, TRUE);
522 /* ************************************************************************* */
523 /* Add the subtree used to store the fixed parameters */
524 /* ************************************************************************* */
526 get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
528 proto_item *fixed_fields;
530 proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
531 size, size, "Fixed parameters (%d bytes)",
534 return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
538 /* ************************************************************************* */
539 /* Add the subtree used to store tagged parameters */
540 /* ************************************************************************* */
542 get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
544 proto_item *tagged_fields;
546 tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
551 "Tagged parameters (%d bytes)",
554 return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
558 /* ************************************************************************* */
559 /* Dissect and add fixed mgmt fields to protocol tree */
560 /* ************************************************************************* */
562 add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
564 const guint8 *dataptr;
565 char out_buff[SHORT_STR];
567 proto_item *cap_item;
568 static proto_tree *cap_tree;
573 case FIELD_TIMESTAMP:
574 dataptr = tvb_get_ptr (tvb, offset, 8);
575 memset (out_buff, 0, SHORT_STR);
576 snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
586 proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
589 case FIELD_BEACON_INTERVAL:
590 temp_double = (double) tvb_get_letohs (tvb, offset);
591 temp_double = temp_double * 1024 / 1000000;
592 proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
593 temp_double,"Beacon Interval: %f [Seconds]",
599 capability = tvb_get_letohs (tvb, offset);
601 cap_item = proto_tree_add_uint_format (tree, ff_capture,
604 "Capability Information: 0x%04X",
606 cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree);
607 proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 1,
609 proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 1,
611 proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 1,
613 proto_tree_add_boolean (cap_tree, ff_cf_preamble, tvb, offset, 1,
615 proto_tree_add_boolean (cap_tree, ff_cf_pbcc, tvb, offset, 1,
617 proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 1,
619 if (ESS_SET (capability) != 0) /* This is an AP */
620 proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2,
621 ((capability & 0xC) >> 2));
623 else /* This is a STA */
624 proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
625 ((capability & 0xC) >> 2));
629 proto_tree_add_item (tree, ff_auth_alg, tvb, offset, 2, TRUE);
632 case FIELD_AUTH_TRANS_SEQ:
633 proto_tree_add_item (tree, ff_auth_seq, tvb, offset, 2, TRUE);
636 case FIELD_CURRENT_AP_ADDR:
637 proto_tree_add_item (tree, ff_current_ap, tvb, offset, 6, FALSE);
640 case FIELD_LISTEN_IVAL:
641 proto_tree_add_item (tree, ff_listen_ival, tvb, offset, 2, TRUE);
644 case FIELD_REASON_CODE:
645 proto_tree_add_item (tree, ff_reason, tvb, offset, 2, TRUE);
649 proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE);
652 case FIELD_STATUS_CODE:
653 proto_tree_add_item (tree, ff_status_code, tvb, offset, 2, TRUE);
659 /* ************************************************************************* */
660 /* Dissect and add tagged (optional) fields to proto tree */
661 /* ************************************************************************* */
663 add_tagged_field (proto_tree * tree, tvbuff_t * tvb, int offset)
665 const guint8 *tag_data_ptr;
666 guint32 tag_no, tag_len;
669 char out_buff[SHORT_STR];
672 tag_no = tvb_get_guint8(tvb, offset);
673 tag_len = tvb_get_guint8(tvb, offset + 1);
675 tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
678 if ((tag_no >= 17) && (tag_no <= 31))
679 { /* Reserved for challenge text */
680 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
681 "Tag Number: %u (Reserved for challenge text)",
684 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
685 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
686 tag_len, "Not interpreted");
687 return (int) tag_len + 2;
690 /* Next See if tag is reserved - if true, skip it! */
691 if (((tag_no >= 7) && (tag_no <= 15))
692 || ((tag_no >= 32) && (tag_no <= 255)))
694 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
695 "Tag Number: %u (Reserved tag number)",
698 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
700 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
701 tag_len, "Not interpreted");
702 return (int) tag_len + 2;
711 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
712 "Tag Number: %u (SSID parameter set)",
715 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
717 memset (out_buff, 0, SHORT_STR);
719 memcpy (out_buff, tag_data_ptr, (size_t) tag_len);
720 out_buff[tag_len + 1] = 0;
722 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
729 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
730 "Tag Number: %u (Supported Rates)", tag_no);
732 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
734 memset (out_buff, 0, SHORT_STR);
735 strcpy (out_buff, "Supported rates: ");
736 n = strlen (out_buff);
738 for (i = 0; i < tag_len && n < SHORT_STR; i++)
740 ret = snprintf (out_buff + n, SHORT_STR - n, "%2.1f%s ",
741 (tag_data_ptr[i] & 0x7F) * 0.5,
742 (tag_data_ptr[i] & 0x80) ? "(B)" : "");
744 /* Some versions of snprintf return -1 if they'd truncate
751 snprintf (out_buff + n, SHORT_STR - n, "[Mbit/sec]");
753 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
759 case TAG_FH_PARAMETER:
760 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
761 "Tag Number: %u (FH Parameter set)",
764 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
765 memset (out_buff, 0, SHORT_STR);
767 snprintf (out_buff, SHORT_STR,
768 "Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, "
769 "Hop Index %2d", pletohs (tag_data_ptr), tag_data_ptr[2],
770 tag_data_ptr[3], tag_data_ptr[4]);
772 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
778 case TAG_DS_PARAMETER:
779 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
780 "Tag Number: %u (DS Parameter set)",
783 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
784 memset (out_buff, 0, SHORT_STR);
786 snprintf (out_buff, SHORT_STR, "Current Channel: %u", tag_data_ptr[0]);
787 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
792 case TAG_CF_PARAMETER:
793 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
794 "Tag Number: %u (CF Parameter set)",
797 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
798 memset (out_buff, 0, SHORT_STR);
800 snprintf (out_buff, SHORT_STR,
801 "CFP count %u, CFP period %u, CFP max duration %u, "
802 "CFP Remaining %u", tag_data_ptr[0], tag_data_ptr[1],
803 pletohs (tag_data_ptr + 2), pletohs (tag_data_ptr + 4));
805 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
811 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
812 "Tag Number: %u ((TIM) Traffic Indication Map)",
815 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
816 memset (out_buff, 0, SHORT_STR);
817 snprintf (out_buff, SHORT_STR,
818 "DTIM count %u, DTIM period %u, Bitmap control 0x%X, "
819 "(Bitmap suppressed)", tag_data_ptr[0], tag_data_ptr[1],
821 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
827 case TAG_IBSS_PARAMETER:
828 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
829 "Tag Number: %u (IBSS Parameter set)",
832 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
833 memset (out_buff, 0, SHORT_STR);
834 snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
835 pletohs (tag_data_ptr));
837 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
843 case TAG_CHALLENGE_TEXT:
844 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
845 "Tag Number: %u (Challenge text)", tag_no);
847 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
848 memset (out_buff, 0, SHORT_STR);
849 snprintf (out_buff, SHORT_STR, "Challenge text: %.47s", tag_data_ptr);
850 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
862 /* ************************************************************************* */
863 /* Dissect 802.11 management frame */
864 /* ************************************************************************* */
866 dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
869 proto_item *ti = NULL;
870 proto_tree *mgt_tree;
871 proto_tree *fixed_tree;
872 proto_tree *tagged_tree;
875 int tagged_parameter_tree_len;
877 CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
881 ti = proto_tree_add_item (tree, proto_wlan_mgt, tvb, 0, -1, FALSE);
882 mgt_tree = proto_item_add_subtree (ti, ett_80211_mgt);
884 switch (COMPOSE_FRAME_TYPE(fcf))
888 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
889 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
890 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
892 next_idx = 4; /* Size of fixed fields */
893 tagged_parameter_tree_len =
894 tvb_reported_length_remaining(tvb, next_idx);
895 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
896 tagged_parameter_tree_len);
898 while (tagged_parameter_tree_len > 0) {
899 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
902 tagged_parameter_tree_len -= next_len;
908 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
909 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
910 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
911 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
913 next_idx = 6; /* Size of fixed fields */
915 tagged_parameter_tree_len =
916 tvb_reported_length_remaining(tvb, next_idx);
917 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
918 tagged_parameter_tree_len);
920 while (tagged_parameter_tree_len > 0) {
921 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
924 tagged_parameter_tree_len -= next_len;
929 case MGT_REASSOC_REQ:
930 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
931 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
932 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
933 add_fixed_field (fixed_tree, tvb, 4, FIELD_CURRENT_AP_ADDR);
935 next_idx = 10; /* Size of fixed fields */
936 tagged_parameter_tree_len =
937 tvb_reported_length_remaining(tvb, next_idx);
938 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
939 tagged_parameter_tree_len);
941 while (tagged_parameter_tree_len > 0) {
942 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
945 tagged_parameter_tree_len -= next_len;
949 case MGT_REASSOC_RESP:
950 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
951 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
952 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
953 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
955 next_idx = 6; /* Size of fixed fields */
956 tagged_parameter_tree_len =
957 tvb_reported_length_remaining(tvb, next_idx);
958 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
959 tagged_parameter_tree_len);
961 while (tagged_parameter_tree_len > 0) {
962 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
965 tagged_parameter_tree_len -= next_len;
972 tagged_parameter_tree_len =
973 tvb_reported_length_remaining(tvb, next_idx);
974 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
975 tagged_parameter_tree_len);
977 while (tagged_parameter_tree_len > 0) {
978 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
981 tagged_parameter_tree_len -= next_len;
987 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
988 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
989 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
990 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
992 next_idx = 12; /* Size of fixed fields */
993 tagged_parameter_tree_len =
994 tvb_reported_length_remaining(tvb, next_idx);
995 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
996 tagged_parameter_tree_len);
998 while (tagged_parameter_tree_len > 0) {
999 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
1001 next_idx +=next_len;
1002 tagged_parameter_tree_len -= next_len;
1007 case MGT_BEACON: /* Dissect protocol payload fields */
1008 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
1010 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
1011 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
1012 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
1014 next_idx = 12; /* Size of fixed fields */
1015 tagged_parameter_tree_len =
1016 tvb_reported_length_remaining(tvb, next_idx);
1017 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
1018 tagged_parameter_tree_len);
1020 while (tagged_parameter_tree_len > 0) {
1021 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
1023 next_idx +=next_len;
1024 tagged_parameter_tree_len -= next_len;
1034 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1035 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
1039 case MGT_AUTHENTICATION:
1040 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1041 add_fixed_field (fixed_tree, tvb, 0, FIELD_AUTH_ALG);
1042 add_fixed_field (fixed_tree, tvb, 2, FIELD_AUTH_TRANS_SEQ);
1043 add_fixed_field (fixed_tree, tvb, 4, FIELD_STATUS_CODE);
1045 next_idx = 6; /* Size of fixed fields */
1047 tagged_parameter_tree_len =
1048 tvb_reported_length_remaining(tvb, next_idx);
1049 if (tagged_parameter_tree_len != 0)
1051 tagged_tree = get_tagged_parameter_tree (mgt_tree,
1054 tagged_parameter_tree_len);
1056 while (tagged_parameter_tree_len > 0) {
1057 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
1059 next_idx +=next_len;
1060 tagged_parameter_tree_len -= next_len;
1066 case MGT_DEAUTHENTICATION:
1067 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1068 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
1075 set_src_addr_cols(packet_info *pinfo, const guint8 *addr, char *type)
1077 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1078 col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "%s (%s)",
1079 get_ether_name(addr), type);
1080 if (check_col(pinfo->cinfo, COL_UNRES_DL_SRC))
1081 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s (%s)",
1082 ether_to_str(addr), type);
1086 set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, char *type)
1088 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1089 col_add_fstr(pinfo->cinfo, COL_RES_DL_DST, "%s (%s)",
1090 get_ether_name(addr), type);
1091 if (check_col(pinfo->cinfo, COL_UNRES_DL_DST))
1092 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s (%s)",
1093 ether_to_str(addr), type);
1096 /* ************************************************************************* */
1097 /* Dissect 802.11 frame */
1098 /* ************************************************************************* */
1100 dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
1101 proto_tree * tree, gboolean fixed_length_header,
1102 gboolean has_radio_information, gboolean has_no_fcs)
1104 guint16 fcf, flags, frame_type_subtype;
1105 guint16 seq_control;
1106 guint32 seq_number, frag_number;
1107 gboolean more_frags;
1108 const guint8 *src = NULL, *dst = NULL;
1109 proto_item *ti = NULL;
1110 proto_item *flag_item;
1111 proto_item *fc_item;
1112 proto_tree *hdr_tree = NULL;
1113 proto_tree *flag_tree;
1114 proto_tree *fc_tree;
1116 gint len, reported_len;
1117 gboolean save_fragmented;
1118 tvbuff_t *volatile next_tvb = NULL;
1120 volatile gboolean is_802_2;
1122 if (check_col (pinfo->cinfo, COL_PROTOCOL))
1123 col_set_str (pinfo->cinfo, COL_PROTOCOL, "IEEE 802.11");
1124 if (check_col (pinfo->cinfo, COL_INFO))
1125 col_clear (pinfo->cinfo, COL_INFO);
1127 fcf = tvb_get_letohs (tvb, 0);
1128 if (fixed_length_header)
1129 hdr_len = DATA_LONG_HDR_LEN;
1131 hdr_len = find_header_length (fcf);
1132 frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
1134 if (check_col (pinfo->cinfo, COL_INFO))
1135 col_set_str (pinfo->cinfo, COL_INFO,
1136 val_to_str(frame_type_subtype, frame_type_subtype_vals,
1137 "Unrecognized (Reserved frame)"));
1139 flags = COOK_FLAGS (fcf);
1140 more_frags = HAVE_FRAGMENTS (flags);
1142 /* Add the radio information, if present, and the FC to the current tree */
1145 ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
1147 hdr_tree = proto_item_add_subtree (ti, ett_80211);
1149 if (has_radio_information) {
1150 proto_tree_add_uint_format(hdr_tree, hf_data_rate,
1152 pinfo->pseudo_header->ieee_802_11.data_rate,
1153 "Data Rate: %g mb/s",
1154 .5*pinfo->pseudo_header->ieee_802_11.data_rate);
1156 proto_tree_add_uint(hdr_tree, hf_channel,
1158 pinfo->pseudo_header->ieee_802_11.channel);
1160 proto_tree_add_uint_format(hdr_tree, hf_signal_strength,
1162 pinfo->pseudo_header->ieee_802_11.signal_level,
1163 "Signal Strength: %u%%",
1164 pinfo->pseudo_header->ieee_802_11.signal_level);
1167 proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
1169 frame_type_subtype);
1171 fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb, 0, 2,
1173 "Frame Control: 0x%04X",
1176 fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
1179 proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb, 0, 1,
1180 COOK_PROT_VERSION (fcf));
1182 proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb, 0, 1,
1183 COOK_FRAME_TYPE (fcf));
1185 proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
1187 COOK_FRAME_SUBTYPE (fcf));
1190 proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb, 1, 1,
1191 flags, "Flags: 0x%X", flags);
1193 flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
1195 proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb, 1, 1,
1196 COOK_DS_STATUS (flags));
1197 proto_tree_add_boolean_hidden (flag_tree, hf_fc_to_ds, tvb, 1, 1,
1199 proto_tree_add_boolean_hidden (flag_tree, hf_fc_from_ds, tvb, 1, 1,
1202 proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb, 1, 1,
1205 proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb, 1, 1, flags);
1207 proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb, 1, 1, flags);
1209 proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb, 1, 1,
1212 proto_tree_add_boolean (flag_tree, hf_fc_wep, tvb, 1, 1, flags);
1214 proto_tree_add_boolean (flag_tree, hf_fc_order, tvb, 1, 1, flags);
1216 if (frame_type_subtype == CTRL_PS_POLL)
1217 proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
1218 COOK_ASSOC_ID(tvb_get_letohs(tvb,2)));
1221 proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
1222 tvb_get_letohs (tvb, 2));
1226 * Decode the part of the frame header that isn't the same for all
1233 switch (COOK_FRAME_TYPE (fcf))
1238 * All management frame types have the same header.
1240 src = tvb_get_ptr (tvb, 10, 6);
1241 dst = tvb_get_ptr (tvb, 4, 6);
1243 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
1244 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
1245 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
1246 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
1248 seq_control = tvb_get_letohs(tvb, 22);
1249 frag_number = COOK_FRAGMENT_NUMBER(seq_control);
1250 seq_number = COOK_SEQUENCE_NUMBER(seq_control);
1254 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
1256 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
1258 /* add items for wlan.addr filter */
1259 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
1260 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
1262 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
1263 tvb_get_ptr (tvb, 16, 6));
1265 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1268 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1274 switch (frame_type_subtype)
1278 src = tvb_get_ptr (tvb, 10, 6);
1279 dst = tvb_get_ptr (tvb, 4, 6);
1281 set_src_addr_cols(pinfo, src, "BSSID");
1282 set_dst_addr_cols(pinfo, dst, "BSSID");
1286 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6, dst);
1288 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
1294 src = tvb_get_ptr (tvb, 10, 6);
1295 dst = tvb_get_ptr (tvb, 4, 6);
1297 set_src_addr_cols(pinfo, src, "TA");
1298 set_dst_addr_cols(pinfo, dst, "RA");
1302 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1304 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
1310 dst = tvb_get_ptr (tvb, 4, 6);
1312 set_dst_addr_cols(pinfo, dst, "RA");
1315 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1319 case CTRL_ACKNOWLEDGEMENT:
1320 dst = tvb_get_ptr (tvb, 4, 6);
1322 set_dst_addr_cols(pinfo, dst, "RA");
1325 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1330 src = tvb_get_ptr (tvb, 10, 6);
1331 dst = tvb_get_ptr (tvb, 4, 6);
1333 set_src_addr_cols(pinfo, src, "BSSID");
1334 set_dst_addr_cols(pinfo, dst, "RA");
1338 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1339 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
1344 case CTRL_CFP_ENDACK:
1345 src = tvb_get_ptr (tvb, 10, 6);
1346 dst = tvb_get_ptr (tvb, 4, 6);
1348 set_src_addr_cols(pinfo, src, "BSSID");
1349 set_dst_addr_cols(pinfo, dst, "RA");
1353 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1355 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
1362 addr_type = COOK_ADDR_SELECTOR (fcf);
1364 /* In order to show src/dst address we must always do the following */
1369 src = tvb_get_ptr (tvb, 10, 6);
1370 dst = tvb_get_ptr (tvb, 4, 6);
1375 src = tvb_get_ptr (tvb, 16, 6);
1376 dst = tvb_get_ptr (tvb, 4, 6);
1381 src = tvb_get_ptr (tvb, 10, 6);
1382 dst = tvb_get_ptr (tvb, 16, 6);
1387 src = tvb_get_ptr (tvb, 24, 6);
1388 dst = tvb_get_ptr (tvb, 16, 6);
1392 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
1393 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
1394 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
1395 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
1397 seq_control = tvb_get_letohs(tvb, 22);
1398 frag_number = COOK_FRAGMENT_NUMBER(seq_control);
1399 seq_number = COOK_SEQUENCE_NUMBER(seq_control);
1401 /* Now if we have a tree we start adding stuff */
1410 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
1411 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
1412 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
1413 tvb_get_ptr (tvb, 16, 6));
1414 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1416 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1419 /* add items for wlan.addr filter */
1420 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
1421 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
1426 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
1427 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
1428 tvb_get_ptr (tvb, 10, 6));
1429 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6, src);
1430 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1432 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1435 /* add items for wlan.addr filter */
1436 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
1437 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, src);
1442 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
1443 tvb_get_ptr (tvb, 4, 6));
1444 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
1445 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
1447 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1449 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1452 /* add items for wlan.addr filter */
1453 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
1454 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
1459 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
1460 tvb_get_ptr (tvb, 4, 6));
1461 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
1462 tvb_get_ptr (tvb, 10, 6));
1463 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
1464 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1466 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1468 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6, src);
1470 /* add items for wlan.addr filter */
1471 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
1472 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 24, 6, src);
1480 len = tvb_length_remaining(tvb, hdr_len);
1481 reported_len = tvb_reported_length_remaining(tvb, hdr_len);
1483 if (!has_no_fcs && (wlan_check_fcs))
1486 * Well, this packet should, in theory, have an FCS.
1487 * Do we have the entire packet, and does it have enough data for
1490 if (reported_len < 4)
1493 * The packet is claimed not to even have enough data for a 4-byte
1495 * Pretend it doesn't have an FCS.
1499 else if (len < reported_len)
1502 * The packet is claimed to have enough data for a 4-byte FCS, but
1503 * we didn't capture all of the packet.
1504 * Slice off the 4-byte FCS from the reported length, and trim the
1505 * captured length so it's no more than the reported length; that
1506 * will slice off what of the FCS, if any, is in the captured
1510 if (len > reported_len)
1516 * We have the entire packet, and it includes a 4-byte FCS.
1517 * Slice it off, and put it into the tree.
1523 guint32 fcs = crc32(tvb_get_ptr(tvb, 0, hdr_len + len), hdr_len + len);
1524 guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len);
1525 if (fcs == sent_fcs)
1526 proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
1527 hdr_len + len, 4, sent_fcs,
1528 "Frame check sequence: 0x%08x (correct)", sent_fcs);
1530 proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
1531 hdr_len + len, 4, sent_fcs,
1532 "Frame check sequence: 0x%08x (incorrect, should be 0x%08x)",
1539 * Only management and data frames have a body, so we don't have
1540 * anything more to do for other types of frames.
1542 switch (COOK_FRAME_TYPE (fcf))
1550 * No-data frames don't have a body.
1552 switch (frame_type_subtype)
1555 case DATA_NULL_FUNCTION:
1556 case DATA_CF_ACK_NOD:
1557 case DATA_CF_POLL_NOD:
1558 case DATA_CF_ACK_POLL_NOD:
1567 if (IS_WEP(COOK_FLAGS(fcf))) {
1569 * It's a WEP-encrypted frame; dissect the WEP parameters and decrypt
1570 * the data, if we have a matching key. Otherwise display it as data.
1572 gboolean can_decrypt = FALSE;
1573 proto_tree *wep_tree = NULL;
1578 * XXX - pass the IV and key to "try_decrypt_wep()", and have it pass
1579 * them to "wep_decrypt()", rather than having "wep_decrypt()" extract
1582 * Also, just pass the data *following* the WEP parameters as the
1583 * buffer to decrypt.
1585 iv = tvb_get_letoh24(tvb, hdr_len);
1587 proto_item *wep_fields;
1589 wep_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len, 4,
1592 wep_tree = proto_item_add_subtree (wep_fields, ett_wep_parameters);
1593 proto_tree_add_uint (wep_tree, hf_wep_iv, tvb, hdr_len, 3, iv);
1595 key = COOK_WEP_KEY (tvb_get_guint8 (tvb, hdr_len + 3));
1597 proto_tree_add_uint (wep_tree, hf_wep_key, tvb, hdr_len + 3, 1, key);
1599 /* Subtract out the length of the IV. */
1604 * Well, this packet should, in theory, have an ICV.
1605 * Do we have the entire packet, and does it have enough data for
1608 if (reported_len < 4) {
1610 * The packet is claimed not to even have enough data for a
1612 * Pretend it doesn't have an ICV.
1615 } else if (len < reported_len) {
1617 * The packet is claimed to have enough data for a 4-byte ICV,
1618 * but we didn't capture all of the packet.
1619 * Slice off the 4-byte ICV from the reported length, and trim
1620 * the captured length so it's no more than the reported length;
1621 * that will slice off what of the ICV, if any, is in the
1626 if (len > reported_len)
1630 * We have the entire packet, and it includes a 4-byte ICV.
1631 * Slice it off, and put it into the tree.
1633 * We only support decrypting if we have the the ICV.
1635 * XXX - the ICV is encrypted; we're putting the encrypted
1636 * value, not the decrypted value, into the tree.
1643 if (!can_decrypt || (next_tvb = try_decrypt_wep(tvb, hdr_len, reported_len + 8)) == NULL) {
1645 * WEP decode impossible or failed, treat payload as raw data
1646 * and don't attempt fragment reassembly or further dissection.
1648 next_tvb = tvb_new_subset(tvb, hdr_len + 4, len, reported_len);
1650 if (tree && can_decrypt)
1651 proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
1652 hdr_len + 4 + len, 4,
1653 tvb_get_ntohl(tvb, hdr_len + 4 + len),
1654 "WEP ICV: 0x%08x (not verified)",
1655 tvb_get_ntohl(tvb, hdr_len + 4 + len));
1657 call_dissector(data_handle, next_tvb, pinfo, tree);
1662 proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
1663 hdr_len + 4 + len, 4,
1664 tvb_get_ntohl(tvb, hdr_len + 4 + len),
1665 "WEP ICV: 0x%08x (correct)",
1666 tvb_get_ntohl(tvb, hdr_len + 4 + len));
1668 add_new_data_source(pinfo, next_tvb, "Decrypted WEP data");
1672 * WEP decryption successful!
1674 * Use the tvbuff we got back from the decryption; the data starts at
1675 * the beginning. The lengths are already correct for the decoded WEP
1682 * Not a WEP-encrypted frame; just use the data from the tvbuff
1685 * The payload starts at "hdr_len" (i.e., just past the 802.11
1686 * MAC header), the length of data in the tvbuff following the
1687 * 802.11 header is "len", and the length of data in the packet
1688 * following the 802.11 header is "reported_len".
1694 * Do defragmentation if "wlan_defragment" is true, and we have more
1695 * fragments or this isn't the first fragment.
1697 * We have to do some special handling to catch frames that
1698 * have the "More Fragments" indicator not set but that
1699 * don't show up as reassembled and don't have any other
1700 * fragments present. Some networking interfaces appear
1701 * to do reassembly even when you're capturing raw packets
1702 * *and* show the reassembled packet without the "More
1703 * Fragments" indicator set *but* with a non-zero fragment
1706 * "fragment_add_seq_check()" handles that; we want to call it
1707 * even if we have a short frame, so that it does those checks - if
1708 * the frame is short, it doesn't do reassembly on it.
1710 * (This could get some false positives if we really *did* only
1711 * capture the last fragment of a fragmented packet, but that's
1714 save_fragmented = pinfo->fragmented;
1715 if (wlan_defragment && (more_frags || frag_number != 0)) {
1716 fragment_data *fd_head;
1719 * If we've already seen this frame, look it up in the
1720 * table of reassembled packets, otherwise add it to
1721 * whatever reassembly is in progress, if any, and see
1724 fd_head = fragment_add_seq_check(next_tvb, hdr_len, pinfo, seq_number,
1725 wlan_fragment_table,
1726 wlan_reassembled_table,
1730 if (fd_head != NULL) {
1732 * Either this is reassembled or it wasn't fragmented
1733 * (see comment above about some networking interfaces).
1734 * In either case, it's now in the table of reassembled
1737 * If the "fragment_data" structure doesn't have a list of
1738 * fragments, we assume it's a placeholder to mark those
1739 * not-really-fragmented packets, and just treat this as
1740 * a non-fragmented frame.
1742 if (fd_head->next != NULL) {
1743 next_tvb = tvb_new_real_data(fd_head->data, fd_head->len, fd_head->len);
1744 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
1745 add_new_data_source(pinfo, next_tvb, "Reassembled 802.11");
1747 /* Show all fragments. */
1748 show_fragment_seq_tree(fd_head, &frag_items, hdr_tree, pinfo, next_tvb);
1751 * Not fragmented, really.
1752 * Show it as a regular frame.
1754 next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len);
1757 /* It's not fragmented. */
1758 pinfo->fragmented = FALSE;
1760 /* We don't have the complete reassembled payload. */
1765 * If this is the first fragment, dissect its contents, otherwise
1766 * just show it as a fragment.
1768 if (frag_number != 0) {
1769 /* Not the first fragment - don't dissect it. */
1772 /* First fragment, or not fragmented. Dissect what we have here. */
1774 /* Get a tvbuff for the payload. */
1775 next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len);
1778 * If this is the first fragment, but not the only fragment,
1779 * tell the next protocol that.
1782 pinfo->fragmented = TRUE;
1784 pinfo->fragmented = FALSE;
1788 if (next_tvb == NULL) {
1789 /* Just show this as an incomplete fragment. */
1790 if (check_col(pinfo->cinfo, COL_INFO))
1791 col_set_str(pinfo->cinfo, COL_INFO, "Fragmented IEEE 802.11 frame");
1792 next_tvb = tvb_new_subset (tvb, hdr_len, len, reported_len);
1793 call_dissector(data_handle, next_tvb, pinfo, tree);
1794 pinfo->fragmented = save_fragmented;
1798 switch (COOK_FRAME_TYPE (fcf))
1802 dissect_ieee80211_mgt (fcf, next_tvb, pinfo, tree);
1807 /* I guess some bridges take Netware Ethernet_802_3 frames,
1808 which are 802.3 frames (with a length field rather than
1809 a type field, but with no 802.2 header in the payload),
1810 and just stick the payload into an 802.11 frame. I've seen
1811 captures that show frames of that sort.
1813 This means we have to do the same check for Netware 802.3 -
1814 or, if you will, "Netware 802.11" - that we do in the
1815 Ethernet dissector, i.e. checking for 0xffff as the first
1816 four bytes of the payload and, if we find it, treating it
1820 if (tvb_get_ntohs(next_tvb, 0) == 0xffff)
1823 CATCH2(BoundsError, ReportedBoundsError) {
1830 call_dissector(llc_handle, next_tvb, pinfo, tree);
1832 call_dissector(ipx_handle, next_tvb, pinfo, tree);
1835 pinfo->fragmented = save_fragmented;
1839 * Dissect 802.11 with a variable-length link-layer header.
1842 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1844 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, FALSE);
1848 * Dissect 802.11 with a variable-length link-layer header and a pseudo-
1849 * header containing radio information.
1852 dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1854 /* These packets do NOT have a FCS present */
1855 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE, TRUE);
1859 * Dissect 802.11 with a fixed-length link-layer header (padded to the
1863 dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1865 dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, FALSE);
1869 wlan_defragment_init(void)
1871 fragment_table_init(&wlan_fragment_table);
1872 reassembled_table_init(&wlan_reassembled_table);
1876 proto_register_wlan (void)
1878 static const value_string frame_type[] = {
1879 {MGT_FRAME, "Management frame"},
1880 {CONTROL_FRAME, "Control frame"},
1881 {DATA_FRAME, "Data frame"},
1885 static const value_string tofrom_ds[] = {
1886 {0, "Not leaving DS or network is operating in AD-HOC mode (To DS: 0 From DS: 0)"},
1887 {FLAG_TO_DS, "Frame is entering DS (To DS: 1 From DS: 0)"},
1888 {FLAG_FROM_DS, "Frame is exiting DS (To DS: 0 From DS: 1)"},
1889 {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS (To DS: 1 From DS: 1)"},
1893 static const true_false_string tods_flag = {
1894 "Frame is entering DS",
1895 "Frame is not entering DS"
1898 static const true_false_string fromds_flag = {
1899 "Frame is exiting DS",
1900 "Frame is not exiting DS"
1903 static const true_false_string more_frags = {
1904 "More fragments follow",
1905 "This is the last fragment"
1908 static const true_false_string retry_flags = {
1909 "Frame is being retransmitted",
1910 "Frame is not being retransmitted"
1913 static const true_false_string pm_flags = {
1914 "STA will go to sleep",
1918 static const true_false_string md_flags = {
1919 "Data is buffered for STA at AP",
1923 static const true_false_string wep_flags = {
1928 static const true_false_string order_flags = {
1930 "Not strictly ordered"
1933 static const true_false_string cf_ess_flags = {
1934 "Transmitter is an AP",
1935 "Transmitter is a STA"
1939 static const true_false_string cf_privacy_flags = {
1940 "AP/STA can support WEP",
1941 "AP/STA cannot support WEP"
1944 static const true_false_string cf_preamble_flags = {
1945 "Short preamble allowed",
1946 "Short preamble not allowed"
1949 static const true_false_string cf_pbcc_flags = {
1950 "PBCC modulation allowed",
1951 "PBCC modulation not allowed"
1954 static const true_false_string cf_agility_flags = {
1955 "Channel agility in use",
1956 "Channel agility not in use"
1960 static const true_false_string cf_ibss_flags = {
1961 "Transmitter belongs to an IBSS",
1962 "Transmitter belongs to a BSS"
1965 static const value_string sta_cf_pollable[] = {
1966 {0x00, "Station is not CF-Pollable"},
1967 {0x02, "Station is CF-Pollable, "
1968 "not requesting to be placed on the CF-polling list"},
1969 {0x01, "Station is CF-Pollable, "
1970 "requesting to be placed on the CF-polling list"},
1971 {0x03, "Station is CF-Pollable, requesting never to be polled"},
1975 static const value_string ap_cf_pollable[] = {
1976 {0x00, "No point coordinator at AP"},
1977 {0x02, "Point coordinator at AP for delivery only (no polling)"},
1978 {0x01, "Point coordinator at AP for delivery and polling"},
1984 static const value_string auth_alg[] = {
1985 {0x00, "Open System"},
1986 {0x01, "Shared key"},
1990 static const value_string reason_codes[] = {
1992 {0x01, "Unspecified reason"},
1993 {0x02, "Previous authentication no longer valid"},
1994 {0x03, "Deauthenticated because sending STA is leaving (has left) "
1996 {0x04, "Disassociated due to inactivity"},
1997 {0x05, "Disassociated because AP is unable to handle all currently "
1998 "associated stations"},
1999 {0x06, "Class 2 frame received from nonauthenticated station"},
2000 {0x07, "Class 3 frame received from nonassociated station"},
2001 {0x08, "Disassociated because sending STA is leaving (has left) BSS"},
2002 {0x09, "Station requesting (re)association is not authenticated with "
2003 "responding station"},
2008 static const value_string status_codes[] = {
2009 {0x00, "Successful"},
2010 {0x01, "Unspecified failure"},
2011 {0x0A, "Cannot support all requested capabilities in the "
2012 "Capability information field"},
2013 {0x0B, "Reassociation denied due to inability to confirm that "
2014 "association exists"},
2015 {0x0C, "Association denied due to reason outside the scope of this "
2018 {0x0D, "Responding station does not support the specified authentication "
2020 {0x0E, "Received an Authentication frame with authentication sequence "
2021 "transaction sequence number out of expected sequence"},
2022 {0x0F, "Authentication rejected because of challenge failure"},
2023 {0x10, "Authentication rejected due to timeout waiting for next "
2024 "frame in sequence"},
2025 {0x11, "Association denied because AP is unable to handle additional "
2026 "associated stations"},
2027 {0x12, "Association denied due to requesting station not supporting all "
2028 "of the datarates in the BSSBasicServiceSet Parameter"},
2032 static hf_register_info hf[] = {
2034 {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
2035 "Data rate (.5 Mb/s units)", HFILL }},
2038 {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
2039 "Radio channel", HFILL }},
2041 {&hf_signal_strength,
2042 {"Signal Strength", "wlan.signal_strength", FT_UINT8, BASE_DEC, NULL, 0,
2043 "Signal strength (percentage)", HFILL }},
2046 {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
2047 "MAC Frame control", HFILL }},
2049 {&hf_fc_proto_version,
2050 {"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
2051 "MAC Protocol version", HFILL }}, /* 0 */
2054 {"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, VALS(frame_type), 0,
2055 "Frame type", HFILL }},
2057 {&hf_fc_frame_subtype,
2058 {"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
2059 "Frame subtype", HFILL }}, /* 2 */
2061 {&hf_fc_frame_type_subtype,
2062 {"Type/Subtype", "wlan.fc.type_subtype", FT_UINT16, BASE_DEC, VALS(frame_type_subtype_vals), 0,
2063 "Type and subtype combined", HFILL }},
2066 {"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
2067 "Protocol flags", HFILL }},
2070 {"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, VALS (&tofrom_ds), 0,
2071 "Data-frame DS-traversal status", HFILL }}, /* 3 */
2074 {"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), FLAG_TO_DS,
2075 "To DS flag", HFILL }}, /* 4 */
2078 {"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), FLAG_FROM_DS,
2079 "From DS flag", HFILL }}, /* 5 */
2082 {"More Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), FLAG_MORE_FRAGMENTS,
2083 "More Fragments flag", HFILL }}, /* 6 */
2086 {"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), FLAG_RETRY,
2087 "Retransmission flag", HFILL }},
2090 {"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), FLAG_POWER_MGT,
2091 "Power management status", HFILL }},
2094 {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
2095 "More data flag", HFILL }},
2098 {"WEP flag", "wlan.fc.wep", FT_BOOLEAN, 8, TFS (&wep_flags), FLAG_WEP,
2099 "WEP flag", HFILL }},
2102 {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
2103 "Strictly ordered flag", HFILL }},
2106 {"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
2107 "Association-ID field", HFILL }},
2110 {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
2111 "Duration field", HFILL }},
2114 {"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
2115 "Destination Hardware Address", HFILL }},
2118 {"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
2119 "Source Hardware Address", HFILL }},
2122 {"Source or Destination address", "wlan.addr", FT_ETHER, BASE_NONE, NULL, 0,
2123 "Source or Destination Hardware Address", HFILL }},
2126 {"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
2127 "Receiving Station Hardware Address", HFILL }},
2130 {"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
2131 "Transmitting Station Hardware Address", HFILL }},
2134 {"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
2135 "Basic Service Set ID", HFILL }},
2138 {"Fragment number", "wlan.frag", FT_UINT16, BASE_DEC, NULL, 0,
2139 "Fragment number", HFILL }},
2142 {"Sequence number", "wlan.seq", FT_UINT16, BASE_DEC, NULL, 0,
2143 "Sequence number", HFILL }},
2146 {"Frame check sequence", "wlan.fcs", FT_UINT32, BASE_HEX,
2147 NULL, 0, "FCS", HFILL }},
2149 {&hf_fragment_overlap,
2150 {"Fragment overlap", "wlan.fragment.overlap", FT_BOOLEAN, BASE_NONE,
2151 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
2153 {&hf_fragment_overlap_conflict,
2154 {"Conflicting data in fragment overlap", "wlan.fragment.overlap.conflict",
2155 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2156 "Overlapping fragments contained conflicting data", HFILL }},
2158 {&hf_fragment_multiple_tails,
2159 {"Multiple tail fragments found", "wlan.fragment.multipletails",
2160 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2161 "Several tails were found when defragmenting the packet", HFILL }},
2163 {&hf_fragment_too_long_fragment,
2164 {"Fragment too long", "wlan.fragment.toolongfragment",
2165 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2166 "Fragment contained data past end of packet", HFILL }},
2168 {&hf_fragment_error,
2169 {"Defragmentation error", "wlan.fragment.error",
2170 FT_NONE, BASE_NONE, NULL, 0x0,
2171 "Defragmentation error due to illegal fragments", HFILL }},
2174 {"802.11 Fragment", "wlan.fragment", FT_NONE, BASE_NONE, NULL, 0x0,
2175 "802.11 Fragment", HFILL }},
2178 {"802.11 Fragments", "wlan.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
2179 "802.11 Fragments", HFILL }},
2182 {"Initialization Vector", "wlan.wep.iv", FT_UINT24, BASE_HEX, NULL, 0,
2183 "Initialization Vector", HFILL }},
2186 {"Key", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
2190 {"WEP ICV", "wlan.wep.icv", FT_UINT32, BASE_HEX, NULL, 0,
2191 "WEP ICV", HFILL }},
2194 static hf_register_info ff[] = {
2196 {"Timestamp", "wlan_mgt.fixed.timestamp", FT_STRING, BASE_NONE,
2197 NULL, 0, "", HFILL }},
2200 {"Authentication Algorithm", "wlan_mgt.fixed.auth.alg",
2201 FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, "", HFILL }},
2203 {&ff_beacon_interval,
2204 {"Beacon Interval", "wlan_mgt.fixed.beacon", FT_DOUBLE, BASE_DEC, NULL, 0,
2207 {&hf_fixed_parameters,
2208 {"Fixed parameters", "wlan_mgt.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
2211 {&hf_tagged_parameters,
2212 {"Tagged parameters", "wlan_mgt.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
2216 {"Capabilities", "wlan_mgt.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
2217 "Capability information", HFILL }},
2220 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.sta",
2221 FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0,
2222 "CF-Poll capabilities for a STA", HFILL }},
2225 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.ap",
2226 FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0,
2227 "CF-Poll capabilities for an AP", HFILL }},
2230 {"ESS capabilities", "wlan_mgt.fixed.capabilities.ess",
2231 FT_BOOLEAN, 8, TFS (&cf_ess_flags), 0x0001, "ESS capabilities", HFILL }},
2235 {"IBSS status", "wlan_mgt.fixed.capabilities.ibss",
2236 FT_BOOLEAN, 8, TFS (&cf_ibss_flags), 0x0002, "IBSS participation", HFILL }},
2238 {"Privacy", "wlan_mgt.fixed.capabilities.privacy",
2239 FT_BOOLEAN, 8, TFS (&cf_privacy_flags), 0x0010, "WEP support", HFILL }},
2242 {"Short Preamble", "wlan_mgt.fixed.capabilities.preamble",
2243 FT_BOOLEAN, 8, TFS (&cf_preamble_flags), 0x0020, "Short Preamble", HFILL }},
2246 {"PBCC", "wlan_mgt.fixed.capabilities.pbcc",
2247 FT_BOOLEAN, 8, TFS (&cf_pbcc_flags), 0x0040, "PBCC Modulation", HFILL }},
2250 {"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
2251 FT_BOOLEAN, 8, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
2254 {"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
2255 FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
2258 {"Association ID", "wlan_mgt.fixed.aid",
2259 FT_UINT16, BASE_HEX, NULL, 0, "Association ID", HFILL }},
2262 {"Listen Interval", "wlan_mgt.fixed.listen_ival",
2263 FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval", HFILL }},
2266 {"Current AP", "wlan_mgt.fixed.current_ap",
2267 FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP", HFILL }},
2270 {"Reason code", "wlan_mgt.fixed.reason_code",
2271 FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
2272 "Reason for unsolicited notification", HFILL }},
2275 {"Status code", "wlan_mgt.fixed.status_code",
2276 FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
2277 "Status of requested event", HFILL }},
2280 {"Tag", "wlan_mgt.tag.number",
2281 FT_UINT16, BASE_DEC, NULL, 0,
2282 "Element ID", HFILL }},
2285 {"Tag length", "wlan_mgt.tag.length",
2286 FT_UINT16, BASE_DEC, NULL, 0, "Length of tag", HFILL }},
2288 {&tag_interpretation,
2289 {"Tag interpretation", "wlan_mgt.tag.interpretation",
2290 FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }}
2294 static gint *tree_array[] = {
2301 &ett_fixed_parameters,
2302 &ett_tagged_parameters,
2303 &ett_wep_parameters,
2306 module_t *wlan_module;
2308 static const enum_val_t wep_keys_options[] = {
2318 proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
2319 "IEEE 802.11", "wlan");
2320 proto_register_field_array (proto_wlan, hf, array_length (hf));
2321 proto_wlan_mgt = proto_register_protocol ("IEEE 802.11 wireless LAN management frame",
2322 "802.11 MGT", "wlan_mgt");
2323 proto_register_field_array (proto_wlan_mgt, ff, array_length (ff));
2324 proto_register_subtree_array (tree_array, array_length (tree_array));
2326 register_dissector("wlan", dissect_ieee80211, proto_wlan);
2327 register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
2328 register_init_routine(wlan_defragment_init);
2330 /* Register configuration options */
2331 wlan_module = prefs_register_protocol(proto_wlan, NULL);
2332 prefs_register_bool_preference(wlan_module, "defragment",
2333 "Reassemble fragmented 802.11 datagrams",
2334 "Whether fragmented 802.11 datagrams should be reassembled",
2337 prefs_register_bool_preference(wlan_module, "check_fcs",
2338 "Assume packets have FCS",
2339 "Some 802.11 cards include the FCS at the end of a packet, others do not.",
2342 prefs_register_bool_preference(wlan_module, "ignore_wep",
2343 "Ignore the WEP bit",
2344 "Some 802.11 cards leave the WEP bit set even though the packet is decrypted.",
2348 prefs_register_enum_preference(wlan_module, "wep_keys",
2350 "How many WEP keys do we have to choose from? (0 to disable, up to 4)",
2351 &num_wepkeys, wep_keys_options, FALSE);
2353 prefs_register_string_preference(wlan_module, "wep_key1",
2355 "First WEP key (A:B:C:D:E:F)",
2357 prefs_register_string_preference(wlan_module, "wep_key2",
2359 "Second WEP key (A:B:C:D:E:F)",
2361 prefs_register_string_preference(wlan_module, "wep_key3",
2363 "Third WEP key (A:B:C:D:E:F)",
2365 prefs_register_string_preference(wlan_module, "wep_key4",
2367 "Fourth WEP key (A:B:C:D:E:F)",
2373 proto_reg_handoff_wlan(void)
2375 dissector_handle_t ieee80211_handle;
2376 dissector_handle_t ieee80211_radio_handle;
2379 * Get handles for the LLC and IPX dissectors.
2381 llc_handle = find_dissector("llc");
2382 ipx_handle = find_dissector("ipx");
2383 data_handle = find_dissector("data");
2385 ieee80211_handle = find_dissector("wlan");
2386 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle);
2387 ieee80211_radio_handle = create_dissector_handle(dissect_ieee80211_radio,
2389 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
2390 ieee80211_radio_handle);
2393 static const guint32 wep_crc32_table[256] = {
2394 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
2395 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
2396 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
2397 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
2398 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
2399 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
2400 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
2401 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
2402 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
2403 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
2404 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
2405 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
2406 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
2407 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
2408 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
2409 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
2410 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
2411 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
2412 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
2413 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
2414 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
2415 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
2416 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
2417 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
2418 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
2419 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
2420 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
2421 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
2422 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
2423 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
2424 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
2425 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
2426 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
2427 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
2428 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
2429 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
2430 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
2431 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
2432 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
2433 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
2434 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
2435 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
2436 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
2437 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
2438 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
2439 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
2440 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
2441 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
2442 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
2443 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
2444 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
2448 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len) {
2451 tvbuff_t *decr_tvb = NULL;
2453 if (num_wepkeys < 1)
2455 if (wep_keylens == NULL)
2458 if ((tmp = g_malloc(len)) == NULL)
2459 return NULL; /* krap! */
2461 /* try once with the key index in the packet, then look through our list. */
2462 for (i = -1; i < (int) num_wepkeys; i++) {
2463 /* copy the encrypted data over to the tmp buffer */
2465 printf("trying %d\n", i);
2467 tvb_memcpy(tvb, tmp, offset, len);
2468 if (wep_decrypt(tmp, len, i) == 0) {
2470 /* decrypt successful, let's set up a new data tvb. */
2471 decr_tvb = tvb_new_real_data(tmp, len-8, len-8);
2472 tvb_set_free_cb(decr_tvb, g_free);
2473 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
2480 if ((!decr_tvb) && (tmp)) free(tmp);
2483 printf("de-wep %p\n", decr_tvb);
2490 /* de-weps the block. if successful, buf* will point to the data start. */
2491 static int wep_decrypt(guint8 *buf, guint32 len, int key_override) {
2492 guint32 i, j, k, crc, keylen;
2493 guint8 s[256], key[128], c_crc[4];
2494 guint8 keyidx, *dpos, *cpos;
2496 /* Needs to be at least 8 bytes of payload */
2500 /* initialize the first bytes of the key from the IV */
2504 keyidx = COOK_WEP_KEY(buf[3]);
2506 if (key_override >= 0)
2507 keyidx = key_override;
2509 if (keyidx >= num_wepkeys)
2512 keylen = wep_keylens[keyidx];
2516 if (wep_keys[keyidx] == NULL)
2519 keylen+=3; /* add in ICV bytes */
2521 /* copy the rest of the key over from the designated key */
2522 memcpy(key+3, wep_keys[keyidx], wep_keylens[keyidx]);
2525 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]);
2528 /* set up the RC4 state */
2529 for (i = 0; i < 256; i++)
2532 for (i = 0; i < 256; i++) {
2533 j = (j + s[i] + key[i % keylen]) & 0xff;
2537 /* Apply the RC4 to the data, update the CRC32 */
2542 for (k = 0; k < (len -8); k++) {
2544 j = (j+s[i]) & 0xff;
2547 printf("%d -- %02x ", k, *dpos);
2549 *dpos = *cpos++ ^ s[(s[i] + s[j]) & 0xff];
2551 printf("%02x\n", *dpos);
2553 crc = wep_crc32_table[(crc ^ *dpos++) & 0xff] ^ (crc >> 8);
2557 /* now let's check the crc */
2559 c_crc[1] = crc >> 8;
2560 c_crc[2] = crc >> 16;
2561 c_crc[3] = crc >> 24;
2563 for (k = 0; k < 4; k++) {
2565 j = (j+s[i]) & 0xff;
2568 printf("-- %02x %02x\n", *dpos, c_crc[k]);
2570 if ((*cpos++ ^ s[(s[i] + s[j]) & 0xff]) != c_crc[k])
2571 return -1; /* ICV mismatch */
2577 /* XXX need to verify these malloc()s succeed */
2579 static void init_wepkeys(void) {
2587 tmp = getenv("ETHEREAL_WEPKEYNUM");
2592 num_wepkeys = atoi(tmp);
2594 if (num_wepkeys > 4)
2598 if (num_wepkeys < 1)
2601 if (wep_keylens != NULL)
2604 wep_keys = malloc(num_wepkeys * sizeof(guint8*));
2605 wep_keylens = malloc(num_wepkeys * sizeof(int));
2607 for (i = 0 ; i < num_wepkeys; i++) {
2612 sprintf(buf, "ETHEREAL_WEPKEY%d", i+1);
2615 tmp = wep_keystr[i];
2622 printf("%s -- %s\n", buf, tmp);
2624 printf("%d -- %s\n", i+1, tmp);
2628 wep_keys[i] = malloc(32 * sizeof(guint8));
2629 memset(wep_keys[i], 0, 32 * sizeof(guint8));
2631 while ((tmp != NULL) && (*tmp != 0)) {
2632 tmp3[j] = strtoul(tmp, &tmp2, 16) & 0xff;
2634 printf("%d %d -- %02x\n", i, j, tmp3[j]);
2639 if ((tmp != NULL) && (*tmp == ':'))
2651 crc32(const unsigned char* buf, unsigned int len)
2654 guint32 crc32 = 0xFFFFFFFF, c_crc;
2656 for (i = 0; i < len; i++)
2657 crc32 = wep_crc32_table[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8);
2660 c_crc = ((unsigned char)(crc32>>0)<<24) |
2661 ((unsigned char)(crc32>>8)<<16) |
2662 ((unsigned char)(crc32>>16)<<8) |
2663 ((unsigned char)(crc32>>24)<<0);