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.60 2002/04/24 06:03:33 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 /* Tables for reassembly of fragments. */
78 static GHashTable *wlan_fragment_table = NULL;
79 static GHashTable *wlan_reassembled_table = NULL;
81 /* ************************************************************************* */
82 /* Miscellaneous Constants */
83 /* ************************************************************************* */
86 /* ************************************************************************* */
87 /* Define some very useful macros that are used to analyze frame types etc. */
88 /* ************************************************************************* */
89 #define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+((x & 0xF0) >> 4)) /* Create key to (sub)type */
90 #define COOK_PROT_VERSION(x) ((x) & 0x3)
91 #define COOK_FRAME_TYPE(x) (((x) & 0xC) >> 2)
92 #define COOK_FRAME_SUBTYPE(x) (((x) & 0xF0) >> 4)
93 #define COOK_ADDR_SELECTOR(x) ((x) & 0x300)
94 #define COOK_ASSOC_ID(x) ((x) & 0x3FFF)
95 #define COOK_FRAGMENT_NUMBER(x) ((x) & 0x000F)
96 #define COOK_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
97 #define COOK_FLAGS(x) (((x) & 0xFF00) >> 8)
98 #define COOK_DS_STATUS(x) ((x) & 0x3)
99 #define COOK_WEP_KEY(x) (((x) & 0xC0) >> 6)
101 #define FLAG_TO_DS 0x01
102 #define FLAG_FROM_DS 0x02
103 #define FLAG_MORE_FRAGMENTS 0x04
104 #define FLAG_RETRY 0x08
105 #define FLAG_POWER_MGT 0x10
106 #define FLAG_MORE_DATA 0x20
107 #define FLAG_WEP 0x40
108 #define FLAG_ORDER 0x80
110 #define IS_TO_DS(x) ((x) & FLAG_TO_DS)
111 #define IS_FROM_DS(x) ((x) & FLAG_FROM_DS)
112 #define HAVE_FRAGMENTS(x) ((x) & FLAG_MORE_FRAGMENTS)
113 #define IS_RETRY(x) ((x) & FLAG_RETRY)
114 #define POWER_MGT_STATUS(x) ((x) & FLAG_POWER_MGT)
115 #define HAS_MORE_DATA(x) ((x) & FLAG_MORE_DATA)
116 #define IS_WEP(x) ((x) & FLAG_WEP)
117 #define IS_STRICTLY_ORDERED(x) ((x) & FLAG_ORDER)
119 #define MGT_RESERVED_RANGE(x) (((x>=0x06)&&(x<=0x07))||((x>=0x0D)&&(x<=0x0F)))
120 #define CTRL_RESERVED_RANGE(x) ((x>=0x10)&&(x<=0x19))
121 #define DATA_RESERVED_RANGE(x) ((x>=0x28)&&(x<=0x2f))
122 #define SPEC_RESERVED_RANGE(x) ((x>=0x30)&&(x<=0x3f))
125 /* ************************************************************************* */
126 /* Constants used to identify cooked frame types */
127 /* ************************************************************************* */
128 #define MGT_FRAME 0x00 /* Frame type is management */
129 #define CONTROL_FRAME 0x01 /* Frame type is control */
130 #define DATA_FRAME 0x02 /* Frame type is Data */
132 #define DATA_SHORT_HDR_LEN 24
133 #define DATA_LONG_HDR_LEN 30
134 #define MGT_FRAME_HDR_LEN 24 /* Length of Managment frame-headers */
136 #define MGT_ASSOC_REQ 0x00 /* Management - association request */
137 #define MGT_ASSOC_RESP 0x01 /* Management - association response */
138 #define MGT_REASSOC_REQ 0x02 /* Management - reassociation request */
139 #define MGT_REASSOC_RESP 0x03 /* Management - reassociation response */
140 #define MGT_PROBE_REQ 0x04 /* Management - Probe request */
141 #define MGT_PROBE_RESP 0x05 /* Management - Probe response */
142 #define MGT_BEACON 0x08 /* Management - Beacon frame */
143 #define MGT_ATIM 0x09 /* Management - ATIM */
144 #define MGT_DISASS 0x0A /* Management - Disassociation */
145 #define MGT_AUTHENTICATION 0x0B /* Management - Authentication */
146 #define MGT_DEAUTHENTICATION 0x0C /* Management - Deauthentication */
148 #define CTRL_PS_POLL 0x1A /* Control - power-save poll */
149 #define CTRL_RTS 0x1B /* Control - request to send */
150 #define CTRL_CTS 0x1C /* Control - clear to send */
151 #define CTRL_ACKNOWLEDGEMENT 0x1D /* Control - acknowledgement */
152 #define CTRL_CFP_END 0x1E /* Control - contention-free period end */
153 #define CTRL_CFP_ENDACK 0x1F /* Control - contention-free period end/ack */
155 #define DATA 0x20 /* Data - Data */
156 #define DATA_CF_ACK 0x21 /* Data - Data + CF acknowledge */
157 #define DATA_CF_POLL 0x22 /* Data - Data + CF poll */
158 #define DATA_CF_ACK_POLL 0x23 /* Data - Data + CF acknowledge + CF poll */
159 #define DATA_NULL_FUNCTION 0x24 /* Data - Null function (no data) */
160 #define DATA_CF_ACK_NOD 0x25 /* Data - CF ack (no data) */
161 #define DATA_CF_POLL_NOD 0x26 /* Data - Data + CF poll (No data) */
162 #define DATA_CF_ACK_POLL_NOD 0x27 /* Data - CF ack + CF poll (no data) */
164 #define DATA_ADDR_T1 0
165 #define DATA_ADDR_T2 (FLAG_FROM_DS << 8)
166 #define DATA_ADDR_T3 (FLAG_TO_DS << 8)
167 #define DATA_ADDR_T4 ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
170 /* ************************************************************************* */
171 /* Macros used to extract information about fixed fields */
172 /* ************************************************************************* */
173 #define ESS_SET(x) ((x) & 0x0001)
174 #define IBSS_SET(x) ((x) & 0x0002)
178 /* ************************************************************************* */
179 /* Logical field codes (dissector's encoding of fixed fields) */
180 /* ************************************************************************* */
181 #define FIELD_TIMESTAMP 0x01 /* 64-bit timestamp */
182 #define FIELD_BEACON_INTERVAL 0x02 /* 16-bit beacon interval */
183 #define FIELD_CAP_INFO 0x03 /* Add capability information tree */
184 #define FIELD_AUTH_ALG 0x04 /* Authentication algorithm used */
185 #define FIELD_AUTH_TRANS_SEQ 0x05 /* Authentication sequence number */
186 #define FIELD_CURRENT_AP_ADDR 0x06
187 #define FIELD_LISTEN_IVAL 0x07
188 #define FIELD_REASON_CODE 0x08
189 #define FIELD_ASSOC_ID 0x09
190 #define FIELD_STATUS_CODE 0x0A
192 /* ************************************************************************* */
193 /* Logical field codes (IEEE 802.11 encoding of tags) */
194 /* ************************************************************************* */
195 #define TAG_SSID 0x00
196 #define TAG_SUPP_RATES 0x01
197 #define TAG_FH_PARAMETER 0x02
198 #define TAG_DS_PARAMETER 0x03
199 #define TAG_CF_PARAMETER 0x04
201 #define TAG_IBSS_PARAMETER 0x06
202 #define TAG_CHALLENGE_TEXT 0x10
204 /* ************************************************************************* */
205 /* Frame types, and their names */
206 /* ************************************************************************* */
207 static const value_string frame_type_subtype_vals[] = {
208 {MGT_ASSOC_REQ, "Association Request"},
209 {MGT_ASSOC_RESP, "Association Response"},
210 {MGT_REASSOC_REQ, "Reassociation Request"},
211 {MGT_REASSOC_RESP, "Reassociation Response"},
212 {MGT_PROBE_REQ, "Probe Request"},
213 {MGT_PROBE_RESP, "Probe Response"},
214 {MGT_BEACON, "Beacon frame"},
216 {MGT_DISASS, "Dissassociate"},
217 {MGT_AUTHENTICATION, "Authentication"},
218 {MGT_DEAUTHENTICATION, "Deauthentication"},
219 {CTRL_PS_POLL, "Power-Save poll"},
220 {CTRL_RTS, "Request-to-send"},
221 {CTRL_CTS, "Clear-to-send"},
222 {CTRL_ACKNOWLEDGEMENT, "Acknowledgement"},
223 {CTRL_CFP_END, "CF-End (Control-frame)"},
224 {CTRL_CFP_ENDACK, "CF-End + CF-Ack (Control-frame)"},
226 {DATA_CF_ACK, "Data + CF-Acknowledgement"},
227 {DATA_CF_POLL, "Data + CF-Poll"},
228 {DATA_CF_ACK_POLL, "Data + CF-Acknowledgement/Poll"},
229 {DATA_NULL_FUNCTION, "Null function (No data)"},
230 {DATA_CF_ACK_NOD, "Data + Acknowledgement (No data)"},
231 {DATA_CF_POLL_NOD, "Data + CF-Poll (No data)"},
232 {DATA_CF_ACK_POLL_NOD, "Data + CF-Acknowledgement/Poll (No data)"},
236 static int proto_wlan = -1;
238 /* ************************************************************************* */
239 /* Header field info values for radio information */
240 /* ************************************************************************* */
241 static int hf_data_rate = -1;
242 static int hf_channel = -1;
243 static int hf_signal_strength = -1;
245 /* ************************************************************************* */
246 /* Header field info values for FC-field */
247 /* ************************************************************************* */
248 static int hf_fc_field = -1;
249 static int hf_fc_proto_version = -1;
250 static int hf_fc_frame_type = -1;
251 static int hf_fc_frame_subtype = -1;
252 static int hf_fc_frame_type_subtype = -1;
254 static int hf_fc_flags = -1;
255 static int hf_fc_to_ds = -1;
256 static int hf_fc_from_ds = -1;
257 static int hf_fc_data_ds = -1;
259 static int hf_fc_more_frag = -1;
260 static int hf_fc_retry = -1;
261 static int hf_fc_pwr_mgt = -1;
262 static int hf_fc_more_data = -1;
263 static int hf_fc_wep = -1;
264 static int hf_fc_order = -1;
267 /* ************************************************************************* */
268 /* Header values for Duration/ID field */
269 /* ************************************************************************* */
270 static int hf_did_duration = -1;
271 static int hf_assoc_id = -1;
274 /* ************************************************************************* */
275 /* Header values for different address-fields (all 4 of them) */
276 /* ************************************************************************* */
277 static int hf_addr_da = -1; /* Destination address subfield */
278 static int hf_addr_sa = -1; /* Source address subfield */
279 static int hf_addr_ra = -1; /* Receiver address subfield */
280 static int hf_addr_ta = -1; /* Transmitter address subfield */
281 static int hf_addr_bssid = -1; /* address is bssid */
283 static int hf_addr = -1; /* Source or destination address subfield */
286 /* ************************************************************************* */
287 /* Header values for sequence number field */
288 /* ************************************************************************* */
289 static int hf_frag_number = -1;
290 static int hf_seq_number = -1;
292 /* ************************************************************************* */
293 /* Header values for Frame Check field */
294 /* ************************************************************************* */
295 static int hf_fcs = -1;
297 /* ************************************************************************* */
298 /* Header values for reassembly */
299 /* ************************************************************************* */
300 static int hf_fragments = -1;
301 static int hf_fragment = -1;
302 static int hf_fragment_overlap = -1;
303 static int hf_fragment_overlap_conflict = -1;
304 static int hf_fragment_multiple_tails = -1;
305 static int hf_fragment_too_long_fragment = -1;
306 static int hf_fragment_error = -1;
309 static int proto_wlan_mgt = -1;
310 /* ************************************************************************* */
311 /* Fixed fields found in mgt frames */
312 /* ************************************************************************* */
313 static int ff_auth_alg = -1; /* Authentication algorithm field */
314 static int ff_auth_seq = -1; /* Authentication transaction sequence */
315 static int ff_current_ap = -1; /* Current AP MAC address */
316 static int ff_listen_ival = -1; /* Listen interval fixed field */
317 static int ff_timestamp = -1; /* 64 bit timestamp */
318 static int ff_beacon_interval = -1; /* 16 bit Beacon interval */
319 static int ff_assoc_id = -1; /* 16 bit AID field */
320 static int ff_reason = -1; /* 16 bit reason code */
321 static int ff_status_code = -1; /* Status code */
323 /* ************************************************************************* */
324 /* Flags found in the capability field (fixed field) */
325 /* ************************************************************************* */
326 static int ff_capture = -1;
327 static int ff_cf_sta_poll = -1; /* CF pollable status for a STA */
328 static int ff_cf_ap_poll = -1; /* CF pollable status for an AP */
329 static int ff_cf_ess = -1;
330 static int ff_cf_ibss = -1;
331 static int ff_cf_privacy = -1;
332 static int ff_cf_preamble = -1;
333 static int ff_cf_pbcc = -1;
334 static int ff_cf_agility = -1;
336 /* ************************************************************************* */
337 /* Tagged value format fields */
338 /* ************************************************************************* */
339 static int tag_number = -1;
340 static int tag_length = -1;
341 static int tag_interpretation = -1;
345 static int hf_fixed_parameters = -1; /* Protocol payload for management frames */
346 static int hf_tagged_parameters = -1; /* Fixed payload item */
347 static int hf_wep_iv = -1;
348 static int hf_wep_key = -1;
349 static int hf_wep_crc = -1;
351 /* ************************************************************************* */
353 /* ************************************************************************* */
354 static gint ett_80211 = -1;
355 static gint ett_proto_flags = -1;
356 static gint ett_cap_tree = -1;
357 static gint ett_fc_tree = -1;
358 static gint ett_fragments = -1;
359 static gint ett_fragment = -1;
361 static gint ett_80211_mgt = -1;
362 static gint ett_fixed_parameters = -1;
363 static gint ett_tagged_parameters = -1;
364 static gint ett_wep_parameters = -1;
366 static dissector_handle_t llc_handle;
367 static dissector_handle_t ipx_handle;
368 static dissector_handle_t data_handle;
370 /* ************************************************************************* */
371 /* Return the length of the current header (in bytes) */
372 /* ************************************************************************* */
374 find_header_length (guint16 fcf)
376 switch (COOK_FRAME_TYPE (fcf)) {
379 return MGT_FRAME_HDR_LEN;
382 switch (COMPOSE_FRAME_TYPE (fcf)) {
385 case CTRL_ACKNOWLEDGEMENT:
391 case CTRL_CFP_ENDACK:
397 return (COOK_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
405 /* ************************************************************************* */
406 /* This is the capture function used to update packet counts */
407 /* ************************************************************************* */
409 capture_ieee80211_common (const u_char * pd, int offset, int len,
410 packet_counts * ld, gboolean fixed_length_header)
412 guint16 fcf, hdr_length;
414 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
419 fcf = pletohs (&pd[0]);
421 if (IS_WEP(COOK_FLAGS(fcf)))
427 switch (COMPOSE_FRAME_TYPE (fcf))
430 case DATA: /* We got a data frame */
431 case DATA_CF_ACK: /* Data with ACK */
433 case DATA_CF_ACK_POLL:
434 if (fixed_length_header)
435 hdr_length = DATA_LONG_HDR_LEN;
437 hdr_length = find_header_length (fcf);
438 /* I guess some bridges take Netware Ethernet_802_3 frames,
439 which are 802.3 frames (with a length field rather than
440 a type field, but with no 802.2 header in the payload),
441 and just stick the payload into an 802.11 frame. I've seen
442 captures that show frames of that sort.
444 This means we have to do the same check for Netware 802.3 -
445 or, if you will, "Netware 802.11" - that we do in the
446 Ethernet dissector, i.e. checking for 0xffff as the first
447 four bytes of the payload and, if we find it, treating it
449 if (!BYTES_ARE_IN_FRAME(offset+hdr_length, len, 2)) {
453 if (pd[offset+hdr_length] == 0xff && pd[offset+hdr_length+1] == 0xff) {
457 capture_llc (pd, offset + hdr_length, len, ld);
468 * Handle 802.11 with a variable-length link-layer header.
471 capture_ieee80211 (const u_char * pd, int offset, int len, packet_counts * ld)
473 capture_ieee80211_common (pd, offset, len, ld, FALSE);
477 * Handle 802.11 with a fixed-length link-layer header (padded to the
481 capture_ieee80211_fixed (const u_char * pd, int offset, int len, packet_counts * ld)
483 capture_ieee80211_common (pd, offset, len, ld, TRUE);
487 /* ************************************************************************* */
488 /* Add the subtree used to store the fixed parameters */
489 /* ************************************************************************* */
491 get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
493 proto_item *fixed_fields;
495 proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
496 size, size, "Fixed parameters (%d bytes)",
499 return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
503 /* ************************************************************************* */
504 /* Add the subtree used to store tagged parameters */
505 /* ************************************************************************* */
507 get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
509 proto_item *tagged_fields;
511 tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
516 "Tagged parameters (%d bytes)",
519 return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
523 /* ************************************************************************* */
524 /* Add the subtree used to store WEP parameters */
525 /* ************************************************************************* */
527 get_wep_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
529 proto_item *wep_fields;
530 proto_tree *wep_tree;
531 int crc_offset = size - 4;
533 wep_fields = proto_tree_add_text(tree, tvb, start, 4, "WEP parameters");
535 wep_tree = proto_item_add_subtree (wep_fields, ett_wep_parameters);
536 proto_tree_add_item (wep_tree, hf_wep_iv, tvb, start, 3, TRUE);
538 proto_tree_add_uint (wep_tree, hf_wep_key, tvb, start + 3, 1,
539 COOK_WEP_KEY (tvb_get_guint8 (tvb, start + 3)));
541 if (tvb_bytes_exist(tvb, start + crc_offset, 4))
542 proto_tree_add_uint (wep_tree, hf_wep_crc, tvb, start + crc_offset, 4,
543 tvb_get_ntohl (tvb, start + crc_offset));
546 /* ************************************************************************* */
547 /* Dissect and add fixed mgmt fields to protocol tree */
548 /* ************************************************************************* */
550 add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
552 const guint8 *dataptr;
553 char out_buff[SHORT_STR];
555 proto_item *cap_item;
556 static proto_tree *cap_tree;
561 case FIELD_TIMESTAMP:
562 dataptr = tvb_get_ptr (tvb, offset, 8);
563 memset (out_buff, 0, SHORT_STR);
564 snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
574 proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
577 case FIELD_BEACON_INTERVAL:
578 temp_double = (double) tvb_get_letohs (tvb, offset);
579 temp_double = temp_double * 1024 / 1000000;
580 proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
581 temp_double,"Beacon Interval: %f [Seconds]",
587 capability = tvb_get_letohs (tvb, offset);
589 cap_item = proto_tree_add_uint_format (tree, ff_capture,
592 "Capability Information: 0x%04X",
594 cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree);
595 proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 1,
597 proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 1,
599 proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 1,
601 proto_tree_add_boolean (cap_tree, ff_cf_preamble, tvb, offset, 1,
603 proto_tree_add_boolean (cap_tree, ff_cf_pbcc, tvb, offset, 1,
605 proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 1,
607 if (ESS_SET (capability) != 0) /* This is an AP */
608 proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2,
609 ((capability & 0xC) >> 2));
611 else /* This is a STA */
612 proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
613 ((capability & 0xC) >> 2));
617 proto_tree_add_item (tree, ff_auth_alg, tvb, offset, 2, TRUE);
620 case FIELD_AUTH_TRANS_SEQ:
621 proto_tree_add_item (tree, ff_auth_seq, tvb, offset, 2, TRUE);
624 case FIELD_CURRENT_AP_ADDR:
625 proto_tree_add_item (tree, ff_current_ap, tvb, offset, 6, FALSE);
628 case FIELD_LISTEN_IVAL:
629 proto_tree_add_item (tree, ff_listen_ival, tvb, offset, 2, TRUE);
632 case FIELD_REASON_CODE:
633 proto_tree_add_item (tree, ff_reason, tvb, offset, 2, TRUE);
637 proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE);
640 case FIELD_STATUS_CODE:
641 proto_tree_add_item (tree, ff_status_code, tvb, offset, 2, TRUE);
647 /* ************************************************************************* */
648 /* Dissect and add tagged (optional) fields to proto tree */
649 /* ************************************************************************* */
651 add_tagged_field (proto_tree * tree, tvbuff_t * tvb, int offset)
653 const guint8 *tag_data_ptr;
654 guint32 tag_no, tag_len;
657 char out_buff[SHORT_STR];
660 tag_no = tvb_get_guint8(tvb, offset);
661 tag_len = tvb_get_guint8(tvb, offset + 1);
663 tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
666 if ((tag_no >= 17) && (tag_no <= 31))
667 { /* Reserved for challenge text */
668 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
669 "Tag Number: %u (Reserved for challenge text)",
672 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
673 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
674 tag_len, "Not interpreted");
675 return (int) tag_len + 2;
678 /* Next See if tag is reserved - if true, skip it! */
679 if (((tag_no >= 7) && (tag_no <= 15))
680 || ((tag_no >= 32) && (tag_no <= 255)))
682 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
683 "Tag Number: %u (Reserved tag number)",
686 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
688 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
689 tag_len, "Not interpreted");
690 return (int) tag_len + 2;
699 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
700 "Tag Number: %u (SSID parameter set)",
703 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
705 memset (out_buff, 0, SHORT_STR);
707 memcpy (out_buff, tag_data_ptr, (size_t) tag_len);
708 out_buff[tag_len + 1] = 0;
710 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
717 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
718 "Tag Number: %u (Supported Rates)", tag_no);
720 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
722 memset (out_buff, 0, SHORT_STR);
723 strcpy (out_buff, "Supported rates: ");
724 n = strlen (out_buff);
726 for (i = 0; i < tag_len && n < SHORT_STR; i++)
728 ret = snprintf (out_buff + n, SHORT_STR - n, "%2.1f%s ",
729 (tag_data_ptr[i] & 0x7F) * 0.5,
730 (tag_data_ptr[i] & 0x80) ? "(B)" : "");
732 /* Some versions of snprintf return -1 if they'd truncate
739 snprintf (out_buff + n, SHORT_STR - n, "[Mbit/sec]");
741 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
747 case TAG_FH_PARAMETER:
748 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
749 "Tag Number: %u (FH Parameter set)",
752 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
753 memset (out_buff, 0, SHORT_STR);
755 snprintf (out_buff, SHORT_STR,
756 "Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, "
757 "Hop Index %2d", pletohs (tag_data_ptr), tag_data_ptr[2],
758 tag_data_ptr[3], tag_data_ptr[4]);
760 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
766 case TAG_DS_PARAMETER:
767 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
768 "Tag Number: %u (DS Parameter set)",
771 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
772 memset (out_buff, 0, SHORT_STR);
774 snprintf (out_buff, SHORT_STR, "Current Channel: %u", tag_data_ptr[0]);
775 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
780 case TAG_CF_PARAMETER:
781 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
782 "Tag Number: %u (CF Parameter set)",
785 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
786 memset (out_buff, 0, SHORT_STR);
788 snprintf (out_buff, SHORT_STR,
789 "CFP count %u, CFP period %u, CFP max duration %u, "
790 "CFP Remaining %u", tag_data_ptr[0], tag_data_ptr[1],
791 pletohs (tag_data_ptr + 2), pletohs (tag_data_ptr + 4));
793 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
799 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
800 "Tag Number: %u ((TIM) Traffic Indication Map)",
803 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
804 memset (out_buff, 0, SHORT_STR);
805 snprintf (out_buff, SHORT_STR,
806 "DTIM count %u, DTIM period %u, Bitmap control 0x%X, "
807 "(Bitmap suppressed)", tag_data_ptr[0], tag_data_ptr[1],
809 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
815 case TAG_IBSS_PARAMETER:
816 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
817 "Tag Number: %u (IBSS Parameter set)",
820 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
821 memset (out_buff, 0, SHORT_STR);
822 snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
823 pletohs (tag_data_ptr));
825 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
831 case TAG_CHALLENGE_TEXT:
832 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
833 "Tag Number: %u (Challenge text)", tag_no);
835 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
836 memset (out_buff, 0, SHORT_STR);
837 snprintf (out_buff, SHORT_STR, "Challenge text: %.47s", tag_data_ptr);
838 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
850 /* ************************************************************************* */
851 /* Dissect 802.11 management frame */
852 /* ************************************************************************* */
854 dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
857 proto_item *ti = NULL;
858 proto_tree *mgt_tree;
859 proto_tree *fixed_tree;
860 proto_tree *tagged_tree;
863 int tagged_parameter_tree_len;
865 CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
869 ti = proto_tree_add_item (tree, proto_wlan_mgt, tvb, 0, -1, FALSE);
870 mgt_tree = proto_item_add_subtree (ti, ett_80211_mgt);
872 switch (COMPOSE_FRAME_TYPE(fcf))
876 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
877 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
878 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
880 next_idx = 4; /* Size of fixed fields */
881 tagged_parameter_tree_len =
882 tvb_reported_length_remaining(tvb, next_idx);
883 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
884 tagged_parameter_tree_len);
886 while (tagged_parameter_tree_len > 0) {
887 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
890 tagged_parameter_tree_len -= next_len;
896 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
897 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
898 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
899 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
901 next_idx = 6; /* 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;
917 case MGT_REASSOC_REQ:
918 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
919 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
920 add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
921 add_fixed_field (fixed_tree, tvb, 4, FIELD_CURRENT_AP_ADDR);
923 next_idx = 10; /* Size of fixed fields */
924 tagged_parameter_tree_len =
925 tvb_reported_length_remaining(tvb, next_idx);
926 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
927 tagged_parameter_tree_len);
929 while (tagged_parameter_tree_len > 0) {
930 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
933 tagged_parameter_tree_len -= next_len;
937 case MGT_REASSOC_RESP:
938 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
939 add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
940 add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
941 add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
943 next_idx = 6; /* Size of fixed fields */
944 tagged_parameter_tree_len =
945 tvb_reported_length_remaining(tvb, next_idx);
946 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
947 tagged_parameter_tree_len);
949 while (tagged_parameter_tree_len > 0) {
950 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
953 tagged_parameter_tree_len -= next_len;
960 tagged_parameter_tree_len =
961 tvb_reported_length_remaining(tvb, next_idx);
962 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
963 tagged_parameter_tree_len);
965 while (tagged_parameter_tree_len > 0) {
966 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
969 tagged_parameter_tree_len -= next_len;
975 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
976 add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
977 add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
978 add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
980 next_idx = 12; /* Size of fixed fields */
981 tagged_parameter_tree_len =
982 tvb_reported_length_remaining(tvb, next_idx);
983 tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, next_idx,
984 tagged_parameter_tree_len);
986 while (tagged_parameter_tree_len > 0) {
987 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
990 tagged_parameter_tree_len -= next_len;
995 case MGT_BEACON: /* Dissect protocol payload fields */
996 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;
1022 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1023 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
1027 case MGT_AUTHENTICATION:
1028 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
1029 add_fixed_field (fixed_tree, tvb, 0, FIELD_AUTH_ALG);
1030 add_fixed_field (fixed_tree, tvb, 2, FIELD_AUTH_TRANS_SEQ);
1031 add_fixed_field (fixed_tree, tvb, 4, FIELD_STATUS_CODE);
1033 next_idx = 6; /* Size of fixed fields */
1035 tagged_parameter_tree_len =
1036 tvb_reported_length_remaining(tvb, next_idx);
1037 if (tagged_parameter_tree_len != 0)
1039 tagged_tree = get_tagged_parameter_tree (mgt_tree,
1042 tagged_parameter_tree_len);
1044 while (tagged_parameter_tree_len > 0) {
1045 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
1047 next_idx +=next_len;
1048 tagged_parameter_tree_len -= next_len;
1054 case MGT_DEAUTHENTICATION:
1055 fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1056 add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
1063 set_src_addr_cols(packet_info *pinfo, const guint8 *addr, char *type)
1065 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1066 col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "%s (%s)",
1067 get_ether_name(addr), type);
1068 if (check_col(pinfo->cinfo, COL_UNRES_DL_SRC))
1069 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s (%s)",
1070 ether_to_str(addr), type);
1074 set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, char *type)
1076 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1077 col_add_fstr(pinfo->cinfo, COL_RES_DL_DST, "%s (%s)",
1078 get_ether_name(addr), type);
1079 if (check_col(pinfo->cinfo, COL_UNRES_DL_DST))
1080 col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s (%s)",
1081 ether_to_str(addr), type);
1085 show_fragments(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1086 fragment_data *fd_head)
1093 fi = proto_tree_add_item(tree, hf_fragments, tvb, 0, -1, FALSE);
1094 ft = proto_item_add_subtree(fi, ett_fragments);
1096 for (fd = fd_head->next; fd != NULL; fd = fd->next){
1097 if (fd->flags & (FD_OVERLAP|FD_OVERLAPCONFLICT|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
1099 * This fragment has some flags set; create a subtree for it and
1100 * display the flags.
1102 proto_tree *fet = NULL;
1103 proto_item *fei = NULL;
1106 if (fd->flags & (FD_OVERLAPCONFLICT|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
1107 hf = hf_fragment_error;
1111 fei = proto_tree_add_none_format(ft, hf, tvb, offset, fd->len,
1112 "Frame:%u payload:%u-%u",
1113 fd->frame, offset, offset+fd->len-1);
1114 fet = proto_item_add_subtree(fei, ett_fragment);
1115 if (fd->flags&FD_OVERLAP)
1116 proto_tree_add_boolean(fet, hf_fragment_overlap, tvb, 0, 0, TRUE);
1117 if (fd->flags&FD_OVERLAPCONFLICT) {
1118 proto_tree_add_boolean(fet, hf_fragment_overlap_conflict, tvb, 0, 0,
1121 if (fd->flags&FD_MULTIPLETAILS) {
1122 proto_tree_add_boolean(fet, hf_fragment_multiple_tails, tvb, 0, 0,
1125 if (fd->flags&FD_TOOLONGFRAGMENT) {
1126 proto_tree_add_boolean(fet, hf_fragment_too_long_fragment, tvb, 0, 0,
1131 * Nothing of interest for this fragment.
1133 proto_tree_add_none_format(ft, hf_fragment, tvb, offset, fd->len,
1134 "Frame:%u payload:%u-%u",
1135 fd->frame, offset, offset+fd->len-1);
1139 if (fd_head->flags & (FD_OVERLAPCONFLICT|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
1140 if (check_col(pinfo->cinfo, COL_INFO))
1141 col_set_str(pinfo->cinfo, COL_INFO, "[Illegal fragments]");
1145 /* ************************************************************************* */
1146 /* Dissect 802.11 frame */
1147 /* ************************************************************************* */
1149 dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
1150 proto_tree * tree, gboolean fixed_length_header,
1151 gboolean has_radio_information)
1153 guint16 fcf, flags, frame_type_subtype;
1154 guint16 seq_control;
1155 guint32 seq_number, frag_number;
1156 gboolean more_frags;
1157 const guint8 *src = NULL, *dst = NULL;
1158 proto_item *ti = NULL;
1159 proto_item *flag_item;
1160 proto_item *fc_item;
1161 proto_tree *hdr_tree = NULL;
1162 proto_tree *flag_tree;
1163 proto_tree *fc_tree;
1165 gboolean save_fragmented;
1166 tvbuff_t *volatile next_tvb;
1168 volatile gboolean is_802_2;
1170 if (check_col (pinfo->cinfo, COL_PROTOCOL))
1171 col_set_str (pinfo->cinfo, COL_PROTOCOL, "IEEE 802.11");
1172 if (check_col (pinfo->cinfo, COL_INFO))
1173 col_clear (pinfo->cinfo, COL_INFO);
1175 fcf = tvb_get_letohs (tvb, 0);
1176 if (fixed_length_header)
1177 hdr_len = DATA_LONG_HDR_LEN;
1179 hdr_len = find_header_length (fcf);
1180 frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
1182 if (check_col (pinfo->cinfo, COL_INFO))
1183 col_set_str (pinfo->cinfo, COL_INFO,
1184 val_to_str(frame_type_subtype, frame_type_subtype_vals,
1185 "Unrecognized (Reserved frame)"));
1187 flags = COOK_FLAGS (fcf);
1188 more_frags = HAVE_FRAGMENTS (flags);
1190 /* Add the radio information, if present, and the FC to the current tree */
1193 ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
1195 hdr_tree = proto_item_add_subtree (ti, ett_80211);
1197 if (has_radio_information) {
1198 proto_tree_add_uint_format(hdr_tree, hf_data_rate,
1200 pinfo->pseudo_header->ieee_802_11.data_rate,
1201 "Data Rate: %g mb/s",
1202 .5*pinfo->pseudo_header->ieee_802_11.data_rate);
1204 proto_tree_add_uint(hdr_tree, hf_channel,
1206 pinfo->pseudo_header->ieee_802_11.channel);
1208 proto_tree_add_uint_format(hdr_tree, hf_signal_strength,
1210 pinfo->pseudo_header->ieee_802_11.signal_level,
1211 "Signal Strength: %u%%",
1212 pinfo->pseudo_header->ieee_802_11.signal_level);
1215 proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
1217 frame_type_subtype);
1219 fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb, 0, 2,
1221 "Frame Control: 0x%04X",
1224 fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
1227 proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb, 0, 1,
1228 COOK_PROT_VERSION (fcf));
1230 proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb, 0, 1,
1231 COOK_FRAME_TYPE (fcf));
1233 proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
1235 COOK_FRAME_SUBTYPE (fcf));
1238 proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb, 1, 1,
1239 flags, "Flags: 0x%X", flags);
1241 flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
1243 proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb, 1, 1,
1244 COOK_DS_STATUS (flags));
1246 proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb, 1, 1,
1249 proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb, 1, 1, flags);
1251 proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb, 1, 1, flags);
1253 proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb, 1, 1,
1256 proto_tree_add_boolean (flag_tree, hf_fc_wep, tvb, 1, 1, flags);
1258 proto_tree_add_boolean (flag_tree, hf_fc_order, tvb, 1, 1, flags);
1260 if (frame_type_subtype == CTRL_PS_POLL)
1261 proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
1262 COOK_ASSOC_ID(tvb_get_letohs(tvb,2)));
1265 proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
1266 tvb_get_letohs (tvb, 2));
1270 * Decode the part of the frame header that isn't the same for all
1277 switch (frame_type_subtype)
1281 case MGT_ASSOC_RESP:
1282 case MGT_REASSOC_REQ:
1283 case MGT_REASSOC_RESP:
1285 case MGT_PROBE_RESP:
1289 case MGT_AUTHENTICATION:
1290 case MGT_DEAUTHENTICATION:
1292 * All management frame types have the same header.
1294 src = tvb_get_ptr (tvb, 10, 6);
1295 dst = tvb_get_ptr (tvb, 4, 6);
1297 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
1298 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
1299 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
1300 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
1302 seq_control = tvb_get_letohs(tvb, 22);
1303 frag_number = COOK_FRAGMENT_NUMBER(seq_control);
1304 seq_number = COOK_SEQUENCE_NUMBER(seq_control);
1308 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
1310 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
1312 /* add items for wlan.addr filter */
1313 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
1314 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
1316 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
1317 tvb_get_ptr (tvb, 16, 6));
1319 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1322 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1329 src = tvb_get_ptr (tvb, 10, 6);
1330 dst = tvb_get_ptr (tvb, 4, 6);
1332 set_src_addr_cols(pinfo, src, "BSSID");
1333 set_dst_addr_cols(pinfo, dst, "BSSID");
1337 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6, dst);
1339 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
1345 src = tvb_get_ptr (tvb, 10, 6);
1346 dst = tvb_get_ptr (tvb, 4, 6);
1348 set_src_addr_cols(pinfo, src, "TA");
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_ta, tvb, 10, 6, src);
1361 dst = tvb_get_ptr (tvb, 4, 6);
1363 set_dst_addr_cols(pinfo, dst, "RA");
1366 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1370 case CTRL_ACKNOWLEDGEMENT:
1371 dst = tvb_get_ptr (tvb, 4, 6);
1373 set_dst_addr_cols(pinfo, dst, "RA");
1376 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1381 src = tvb_get_ptr (tvb, 10, 6);
1382 dst = tvb_get_ptr (tvb, 4, 6);
1384 set_src_addr_cols(pinfo, src, "BSSID");
1385 set_dst_addr_cols(pinfo, dst, "RA");
1389 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1390 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
1395 case CTRL_CFP_ENDACK:
1396 src = tvb_get_ptr (tvb, 10, 6);
1397 dst = tvb_get_ptr (tvb, 4, 6);
1399 set_src_addr_cols(pinfo, src, "BSSID");
1400 set_dst_addr_cols(pinfo, dst, "RA");
1404 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1406 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
1412 case DATA_NULL_FUNCTION:
1414 case DATA_CF_ACK_NOD:
1416 case DATA_CF_POLL_NOD:
1417 case DATA_CF_ACK_POLL:
1418 case DATA_CF_ACK_POLL_NOD:
1419 addr_type = COOK_ADDR_SELECTOR (fcf);
1421 /* In order to show src/dst address we must always do the following */
1426 src = tvb_get_ptr (tvb, 10, 6);
1427 dst = tvb_get_ptr (tvb, 4, 6);
1432 src = tvb_get_ptr (tvb, 16, 6);
1433 dst = tvb_get_ptr (tvb, 4, 6);
1438 src = tvb_get_ptr (tvb, 10, 6);
1439 dst = tvb_get_ptr (tvb, 16, 6);
1444 src = tvb_get_ptr (tvb, 24, 6);
1445 dst = tvb_get_ptr (tvb, 16, 6);
1449 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
1450 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
1451 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
1452 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
1454 seq_control = tvb_get_letohs(tvb, 22);
1455 frag_number = COOK_FRAGMENT_NUMBER(seq_control);
1456 seq_number = COOK_SEQUENCE_NUMBER(seq_control);
1458 /* Now if we have a tree we start adding stuff */
1467 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
1468 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
1469 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
1470 tvb_get_ptr (tvb, 16, 6));
1471 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1473 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1476 /* add items for wlan.addr filter */
1477 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
1478 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
1483 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
1484 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
1485 tvb_get_ptr (tvb, 10, 6));
1486 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6, src);
1487 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1489 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1492 /* add items for wlan.addr filter */
1493 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 4, 6, dst);
1494 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, src);
1499 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
1500 tvb_get_ptr (tvb, 4, 6));
1501 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
1502 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
1504 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1506 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1509 /* add items for wlan.addr filter */
1510 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 10, 6, src);
1511 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
1516 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
1517 tvb_get_ptr (tvb, 4, 6));
1518 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
1519 tvb_get_ptr (tvb, 10, 6));
1520 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6, dst);
1521 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1523 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1525 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6, src);
1527 /* add items for wlan.addr filter */
1528 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 16, 6, dst);
1529 proto_tree_add_ether_hidden(hdr_tree, hf_addr, tvb, 24, 6, src);
1538 * Only management and data frames have a body, so we don't have
1539 * anything more to do for other types of frames.
1541 switch (COOK_FRAME_TYPE (fcf))
1549 * No-data frames don't have a body.
1551 switch (frame_type_subtype)
1554 case DATA_NULL_FUNCTION:
1555 case DATA_CF_ACK_NOD:
1556 case DATA_CF_POLL_NOD:
1557 case DATA_CF_ACK_POLL_NOD:
1567 * For WEP-encrypted frames, dissect the WEP parameters and
1568 * display the payload as data.
1570 * XXX - allow the key to be specified, and, if it is, decrypt
1571 * the payload and dissect it?
1573 if (IS_WEP(COOK_FLAGS(fcf)))
1575 int pkt_len = tvb_reported_length (tvb);
1576 int cap_len = tvb_length (tvb);
1580 get_wep_parameter_tree (tree, tvb, hdr_len, pkt_len);
1581 pkt_len -= hdr_len + 4;
1582 cap_len -= hdr_len + 4;
1585 * OK, pkt_len and cap_len have had the length of the 802.11
1586 * header and WEP parameters subtracted.
1588 * If there's anything left:
1590 * if cap_len is greater than or equal to pkt_len (i.e., we
1591 * captured the entire packet), subtract the length of the
1592 * WEP CRC from cap_len;
1594 * if cap_len is from 1 to 3 bytes less than pkt_len (i.e.,
1595 * we captured some but not all of the WEP CRC), subtract
1596 * the length of the part of the WEP CRC we captured from
1599 * otherwise, (i.e., we captured none of the WEP CRC),
1600 * leave cap_len alone;
1602 * and subtract the length of the WEP CRC from pkt_len.
1604 if (cap_len >= pkt_len)
1606 else if ((pkt_len - cap_len) >= 1 && (pkt_len - cap_len) <= 3)
1607 cap_len -= 4 - (pkt_len - cap_len);
1609 if (cap_len > 0 && pkt_len > 0)
1610 call_dissector(data_handle,tvb_new_subset(tvb, hdr_len + 4, -1,tvb_reported_length_remaining(tvb,hdr_len + 4)),pinfo, tree);
1616 * Now dissect the body of a non-WEP-encrypted frame.
1620 * Do defragmentation if "wlan_defragment" is true.
1622 * We have to do some special handling to catch frames that
1623 * have the "More Fragments" indicator not set but that
1624 * don't show up as reassembled and don't have any other
1625 * fragments present. Some networking interfaces appear
1626 * to do reassembly even when you're capturing raw packets
1627 * *and* show the reassembled packet without the "More
1628 * Fragments" indicator set *but* with a non-zero fragment
1631 * (This could get some false positives if we really *did* only
1632 * capture the last fragment of a fragmented packet, but that's
1635 save_fragmented = pinfo->fragmented;
1636 if (wlan_defragment && (more_frags || frag_number != 0)) {
1637 fragment_data *fd_head;
1640 * If we've already seen this frame, look it up in the
1641 * table of reassembled packets, otherwise add it to
1642 * whatever reassembly is in progress, if any, and see
1645 fd_head = fragment_add_seq_check(tvb, hdr_len, pinfo, seq_number,
1646 wlan_fragment_table,
1647 wlan_reassembled_table,
1649 tvb_length_remaining(tvb, hdr_len),
1651 if (fd_head != NULL) {
1653 * Either this is reassembled or it wasn't fragmented
1654 * (see comment above about some networking interfaces).
1655 * In either case, it's now in the table of reassembled
1658 * If the "fragment_data" structure doesn't have a list of
1659 * fragments, we assume it's a placeholder to mark those
1660 * not-really-fragmented packets, and just treat this as
1661 * a non-fragmented frame.
1663 if (fd_head->next != NULL) {
1664 next_tvb = tvb_new_real_data(fd_head->data, fd_head->len, fd_head->len);
1665 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
1666 add_new_data_source(pinfo->fd, next_tvb, "Reassembled 802.11");
1668 /* Show all fragments. */
1669 show_fragments(next_tvb, pinfo, hdr_tree, fd_head);
1672 * Not fragmented, really.
1673 * Show it as a regular frame.
1675 next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
1678 /* It's not fragmented. */
1679 pinfo->fragmented = FALSE;
1681 /* We don't have the complete reassembled payload. */
1686 * If this is the first fragment, dissect its contents, otherwise
1687 * just show it as a fragment.
1689 if (frag_number != 0) {
1690 /* Not the first fragment - don't dissect it. */
1693 /* First fragment, or not fragmented. Dissect what we have here. */
1695 /* Get a tvbuff for the payload. */
1696 next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
1699 * If this is the first fragment, but not the only fragment,
1700 * tell the next protocol that.
1703 pinfo->fragmented = TRUE;
1705 pinfo->fragmented = FALSE;
1709 if (next_tvb == NULL) {
1710 /* Just show this as a fragment. */
1711 if (check_col(pinfo->cinfo, COL_INFO))
1712 col_set_str(pinfo->cinfo, COL_INFO, "Fragmented IEEE 802.11 frame");
1713 next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
1714 call_dissector(data_handle, next_tvb, pinfo, tree);
1715 pinfo->fragmented = save_fragmented;
1719 switch (COOK_FRAME_TYPE (fcf))
1723 dissect_ieee80211_mgt (fcf, next_tvb, pinfo, tree);
1728 /* I guess some bridges take Netware Ethernet_802_3 frames,
1729 which are 802.3 frames (with a length field rather than
1730 a type field, but with no 802.2 header in the payload),
1731 and just stick the payload into an 802.11 frame. I've seen
1732 captures that show frames of that sort.
1734 This means we have to do the same check for Netware 802.3 -
1735 or, if you will, "Netware 802.11" - that we do in the
1736 Ethernet dissector, i.e. checking for 0xffff as the first
1737 four bytes of the payload and, if we find it, treating it
1741 if (tvb_get_ntohs(next_tvb, 0) == 0xffff)
1744 CATCH2(BoundsError, ReportedBoundsError) {
1751 call_dissector(llc_handle, next_tvb, pinfo, tree);
1753 call_dissector(ipx_handle, next_tvb, pinfo, tree);
1756 pinfo->fragmented = save_fragmented;
1760 * Dissect 802.11 with a variable-length link-layer header.
1763 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1765 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE);
1769 * Dissect 802.11 with a variable-length link-layer header and a pseudo-
1770 * header containing radio information.
1773 dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1775 dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE);
1779 * Dissect 802.11 with a fixed-length link-layer header (padded to the
1783 dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1785 dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE);
1789 wlan_defragment_init(void)
1791 fragment_table_init(&wlan_fragment_table);
1792 reassembled_table_init(&wlan_reassembled_table);
1796 proto_register_wlan (void)
1798 static const value_string frame_type[] = {
1799 {MGT_FRAME, "Management frame"},
1800 {CONTROL_FRAME, "Control frame"},
1801 {DATA_FRAME, "Data frame"},
1805 static const value_string tofrom_ds[] = {
1806 {0, "Not leaving DS or network is operating in AD-HOC mode (To DS: 0 From DS: 0)"},
1807 {FLAG_TO_DS, "Frame is entering DS (To DS: 1 From DS: 0)"},
1808 {FLAG_FROM_DS, "Frame is exiting DS (To DS: 0 From DS: 1)"},
1809 {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS (To DS: 1 From DS: 1)"},
1813 static const true_false_string tods_flag = {
1814 "TO DS: Should be false",
1818 static const true_false_string fromds_flag = {
1819 "FROM DS: Should be false",
1823 static const true_false_string more_frags = {
1824 "More fragments follow",
1825 "This is the last fragment"
1828 static const true_false_string retry_flags = {
1829 "Frame is being retransmitted",
1830 "Frame is not being retransmitted"
1833 static const true_false_string pm_flags = {
1834 "STA will go to sleep",
1838 static const true_false_string md_flags = {
1839 "Data is buffered for STA at AP",
1843 static const true_false_string wep_flags = {
1848 static const true_false_string order_flags = {
1850 "Not strictly ordered"
1853 static const true_false_string cf_ess_flags = {
1854 "Transmitter is an AP",
1855 "Transmitter is a STA"
1859 static const true_false_string cf_privacy_flags = {
1860 "AP/STA can support WEP",
1861 "AP/STA cannot support WEP"
1864 static const true_false_string cf_preamble_flags = {
1865 "Short preamble allowed",
1866 "Short preamble not allowed"
1869 static const true_false_string cf_pbcc_flags = {
1870 "PBCC modulation allowed",
1871 "PBCC modulation not allowed"
1874 static const true_false_string cf_agility_flags = {
1875 "Channel agility in use",
1876 "Channel agility not in use"
1880 static const true_false_string cf_ibss_flags = {
1881 "Transmitter belongs to an IBSS",
1882 "Transmitter belongs to a BSS"
1885 static const value_string sta_cf_pollable[] = {
1886 {0x00, "Station is not CF-Pollable"},
1887 {0x02, "Station is CF-Pollable, "
1888 "not requesting to be placed on the CF-polling list"},
1889 {0x01, "Station is CF-Pollable, "
1890 "requesting to be placed on the CF-polling list"},
1891 {0x03, "Station is CF-Pollable, requesting never to be polled"},
1895 static const value_string ap_cf_pollable[] = {
1896 {0x00, "No point coordinator at AP"},
1897 {0x02, "Point coordinator at AP for delivery only (no polling)"},
1898 {0x01, "Point coordinator at AP for delivery and polling"},
1904 static const value_string auth_alg[] = {
1905 {0x00, "Open System"},
1906 {0x01, "Shared key"},
1910 static const value_string reason_codes[] = {
1912 {0x01, "Unspecified reason"},
1913 {0x02, "Previous authentication no longer valid"},
1914 {0x03, "Deauthenticated because sending STA is leaving (has left) "
1916 {0x04, "Disassociated due to inactivity"},
1917 {0x05, "Disassociated because AP is unable to handle all currently "
1918 "associated stations"},
1919 {0x06, "Class 2 frame received from nonauthenticated station"},
1920 {0x07, "Class 3 frame received from nonassociated station"},
1921 {0x08, "Disassociated because sending STA is leaving (has left) BSS"},
1922 {0x09, "Station requesting (re)association is not authenticated with "
1923 "responding station"},
1928 static const value_string status_codes[] = {
1929 {0x00, "Successful"},
1930 {0x01, "Unspecified failure"},
1931 {0x0A, "Cannot support all requested capabilities in the "
1932 "Capability information field"},
1933 {0x0B, "Reassociation denied due to inability to confirm that "
1934 "association exists"},
1935 {0x0C, "Association denied due to reason outside the scope of this "
1938 {0x0D, "Responding station does not support the specified authentication "
1940 {0x0E, "Received an Authentication frame with authentication sequence "
1941 "transaction sequence number out of expected sequence"},
1942 {0x0F, "Authentication rejected because of challenge failure"},
1943 {0x10, "Authentication rejected due to timeout waiting for next "
1944 "frame in sequence"},
1945 {0x11, "Association denied because AP is unable to handle additional "
1946 "associated stations"},
1947 {0x12, "Association denied due to requesting station not supporting all "
1948 "of the datarates in the BSSBasicServiceSet Parameter"},
1952 static hf_register_info hf[] = {
1954 {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
1955 "Data rate (.5 Mb/s units)", HFILL }},
1958 {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
1959 "Radio channel", HFILL }},
1961 {&hf_signal_strength,
1962 {"Signal Strength", "wlan.signal_strength", FT_UINT8, BASE_DEC, NULL, 0,
1963 "Signal strength (percentage)", HFILL }},
1966 {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
1967 "MAC Frame control", HFILL }},
1969 {&hf_fc_proto_version,
1970 {"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
1971 "MAC Protocol version", HFILL }}, /* 0 */
1974 {"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, VALS(frame_type), 0,
1975 "Frame type", HFILL }},
1977 {&hf_fc_frame_subtype,
1978 {"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
1979 "Frame subtype", HFILL }}, /* 2 */
1981 {&hf_fc_frame_type_subtype,
1982 {"Type/Subtype", "wlan.fc.type_subtype", FT_UINT16, BASE_DEC, VALS(frame_type_subtype_vals), 0,
1983 "Type and subtype combined", HFILL }},
1986 {"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
1987 "Protocol flags", HFILL }},
1990 {"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, VALS (&tofrom_ds), 0,
1991 "Data-frame DS-traversal status", HFILL }}, /* 3 */
1994 {"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), FLAG_TO_DS,
1995 "To DS flag", HFILL }}, /* 4 */
1998 {"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), FLAG_FROM_DS,
1999 "From DS flag", HFILL }}, /* 5 */
2002 {"More Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), FLAG_MORE_FRAGMENTS,
2003 "More Fragments flag", HFILL }}, /* 6 */
2006 {"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), FLAG_RETRY,
2007 "Retransmission flag", HFILL }},
2010 {"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), FLAG_POWER_MGT,
2011 "Power management status", HFILL }},
2014 {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
2015 "More data flag", HFILL }},
2018 {"WEP flag", "wlan.fc.wep", FT_BOOLEAN, 8, TFS (&wep_flags), FLAG_WEP,
2019 "WEP flag", HFILL }},
2022 {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
2023 "Strictly ordered flag", HFILL }},
2026 {"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
2027 "Association-ID field", HFILL }},
2030 {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
2031 "Duration field", HFILL }},
2034 {"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
2035 "Destination Hardware Address", HFILL }},
2038 {"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
2039 "Source Hardware Address", HFILL }},
2042 {"Source or Destination address", "wlan.addr", FT_ETHER, BASE_NONE, NULL, 0,
2043 "Source or Destination Hardware Address", HFILL }},
2046 {"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
2047 "Receiving Station Hardware Address", HFILL }},
2050 {"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
2051 "Transmitting Station Hardware Address", HFILL }},
2054 {"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
2055 "Basic Service Set ID", HFILL }},
2058 {"Fragment number", "wlan.frag", FT_UINT16, BASE_DEC, NULL, 0,
2059 "Fragment number", HFILL }},
2062 {"Sequence number", "wlan.seq", FT_UINT16, BASE_DEC, NULL, 0,
2063 "Sequence number", HFILL }},
2066 {"Frame Check Sequence (not verified)", "wlan.fcs", FT_UINT32, BASE_HEX,
2067 NULL, 0, "", HFILL }},
2069 {&hf_fragment_overlap,
2070 {"Fragment overlap", "wlan.fragment.overlap", FT_BOOLEAN, BASE_NONE,
2071 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
2073 {&hf_fragment_overlap_conflict,
2074 {"Conflicting data in fragment overlap", "wlan.fragment.overlap.conflict",
2075 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2076 "Overlapping fragments contained conflicting data", HFILL }},
2078 {&hf_fragment_multiple_tails,
2079 {"Multiple tail fragments found", "wlan.fragment.multipletails",
2080 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2081 "Several tails were found when defragmenting the packet", HFILL }},
2083 {&hf_fragment_too_long_fragment,
2084 {"Fragment too long", "wlan.fragment.toolongfragment",
2085 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2086 "Fragment contained data past end of packet", HFILL }},
2088 {&hf_fragment_error,
2089 {"Defragmentation error", "wlan.fragment.error",
2090 FT_NONE, BASE_NONE, NULL, 0x0,
2091 "Defragmentation error due to illegal fragments", HFILL }},
2094 {"802.11 Fragment", "wlan.fragment", FT_NONE, BASE_NONE, NULL, 0x0,
2095 "802.11 Fragment", HFILL }},
2098 {"802.11 Fragments", "wlan.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
2099 "WTP Fragments", HFILL }},
2102 {"Initialization Vector", "wlan.wep.iv", FT_UINT24, BASE_HEX, NULL, 0,
2103 "Initialization Vector", HFILL }},
2106 {"Key", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
2110 {"WEP CRC (not verified)", "wlan.wep.crc", FT_UINT32, BASE_HEX, NULL, 0,
2111 "WEP CRC", HFILL }},
2114 static hf_register_info ff[] = {
2116 {"Timestamp", "wlan_mgt.fixed.timestamp", FT_STRING, BASE_NONE,
2117 NULL, 0, "", HFILL }},
2120 {"Authentication Algorithm", "wlan_mgt.fixed.auth.alg",
2121 FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, "", HFILL }},
2123 {&ff_beacon_interval,
2124 {"Beacon Interval", "wlan_mgt.fixed.beacon", FT_DOUBLE, BASE_DEC, NULL, 0,
2127 {&hf_fixed_parameters,
2128 {"Fixed parameters", "wlan_mgt.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
2131 {&hf_tagged_parameters,
2132 {"Tagged parameters", "wlan_mgt.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
2136 {"Capabilities", "wlan_mgt.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
2137 "Capability information", HFILL }},
2140 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.sta",
2141 FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0,
2142 "CF-Poll capabilities for a STA", HFILL }},
2145 {"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.ap",
2146 FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0,
2147 "CF-Poll capabilities for an AP", HFILL }},
2150 {"ESS capabilities", "wlan_mgt.fixed.capabilities.ess",
2151 FT_BOOLEAN, 8, TFS (&cf_ess_flags), 0x0001, "ESS capabilities", HFILL }},
2155 {"IBSS status", "wlan_mgt.fixed.capabilities.ibss",
2156 FT_BOOLEAN, 8, TFS (&cf_ibss_flags), 0x0002, "IBSS participation", HFILL }},
2159 {"Privacy", "wlan_mgt.fixed.capabilities.privacy",
2160 FT_BOOLEAN, 8, TFS (&cf_privacy_flags), 0x0010, "WEP support", HFILL }},
2163 {"Short Preamble", "wlan_mgt.fixed.capabilities.preamble",
2164 FT_BOOLEAN, 8, TFS (&cf_preamble_flags), 0x0020, "Short Preamble", HFILL }},
2167 {"PBCC", "wlan_mgt.fixed.capabilities.pbcc",
2168 FT_BOOLEAN, 8, TFS (&cf_pbcc_flags), 0x0040, "PBCC Modulation", HFILL }},
2171 {"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
2172 FT_BOOLEAN, 8, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
2175 {"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
2176 FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
2179 {"Association ID", "wlan_mgt.fixed.aid",
2180 FT_UINT16, BASE_HEX, NULL, 0, "Association ID", HFILL }},
2183 {"Listen Interval", "wlan_mgt.fixed.listen_ival",
2184 FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval", HFILL }},
2187 {"Current AP", "wlan_mgt.fixed.current_ap",
2188 FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP", HFILL }},
2191 {"Reason code", "wlan_mgt.fixed.reason_code",
2192 FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
2193 "Reason for unsolicited notification", HFILL }},
2196 {"Status code", "wlan_mgt.fixed.status_code",
2197 FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
2198 "Status of requested event", HFILL }},
2201 {"Tag", "wlan_mgt.tag.number",
2202 FT_UINT16, BASE_DEC, NULL, 0,
2203 "Element ID", HFILL }},
2206 {"Tag length", "wlan_mgt.tag.length",
2207 FT_UINT16, BASE_DEC, NULL, 0, "Length of tag", HFILL }},
2209 {&tag_interpretation,
2210 {"Tag interpretation", "wlan_mgt.tag.interpretation",
2211 FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }}
2215 static gint *tree_array[] = {
2222 &ett_fixed_parameters,
2223 &ett_tagged_parameters,
2224 &ett_wep_parameters,
2227 module_t *wlan_module;
2229 proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
2230 "IEEE 802.11", "wlan");
2231 proto_register_field_array (proto_wlan, hf, array_length (hf));
2232 proto_wlan_mgt = proto_register_protocol ("IEEE 802.11 wireless LAN management frame",
2233 "802.11 MGT", "wlan_mgt");
2234 proto_register_field_array (proto_wlan_mgt, ff, array_length (ff));
2235 proto_register_subtree_array (tree_array, array_length (tree_array));
2237 register_dissector("wlan", dissect_ieee80211, proto_wlan);
2238 register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
2239 register_init_routine(wlan_defragment_init);
2241 /* Register configuration options */
2242 wlan_module = prefs_register_protocol(proto_wlan, NULL);
2243 prefs_register_bool_preference(wlan_module, "defragment",
2244 "Reassemble fragmented 802.11 datagrams",
2245 "Whether fragmented 802.11 datagrams should be reassembled",
2250 proto_reg_handoff_wlan(void)
2252 dissector_handle_t ieee80211_handle;
2253 dissector_handle_t ieee80211_radio_handle;
2256 * Get handles for the LLC and IPX dissectors.
2258 llc_handle = find_dissector("llc");
2259 ipx_handle = find_dissector("ipx");
2260 data_handle = find_dissector("data");
2262 ieee80211_handle = find_dissector("wlan");
2263 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle);
2264 ieee80211_radio_handle = create_dissector_handle(dissect_ieee80211_radio,
2266 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
2267 ieee80211_radio_handle);