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.10 2001/01/10 23:28:46 guy Exp $
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@unicom.net>
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.
36 #ifdef HAVE_SYS_TYPES_H
37 # include <sys/types.h>
40 #ifdef HAVE_NETINET_IN_H
41 # include <netinet/in.h>
44 #ifdef NEED_SNPRINTF_H
50 # include "snprintf.h"
59 #include "packet-llc.h"
60 #include "packet-ieee80211.h"
62 /* ************************************************************************* */
63 /* Miscellaneous Constants */
64 /* ************************************************************************* */
66 #define MGT_FRAME_LEN 24
68 /* ************************************************************************* */
69 /* Define some very useful macros that are used to analyze frame types etc. */
70 /* ************************************************************************* */
71 #define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+((x & 0xF0) >> 4)) /* Create key to (sub)type */
72 #define COOK_PROT_VERSION(x) ((x & 0x3))
73 #define COOK_FRAME_TYPE(x) ((x & 0xC) >> 2)
74 #define COOK_FRAME_SUBTYPE(x) ((x & 0xF0) >> 4)
75 #define COOK_ADDR_SELECTOR(x) (((x & 0x200) >> 8) + ((x & 0x100) >> 8))
77 #define COOK_FRAGMENT_NUMBER(x) (x & 0x000F)
78 #define COOK_SEQUENCE_NUMBER(x) ((x & 0xFFF0) >> 4)
79 #define COOK_FLAGS(x) ((x & 0xFF00) >> 8)
80 #define COOK_DS_STATUS(x) (x & 0x3)
81 #define COL_SHOW_INFO(fd,info) if (check_col(fd,COL_INFO)) \
82 col_add_str(fd,COL_INFO,info);
84 #define IS_TO_DS(x) ((x & 0x100) >> 8)
85 #define IS_FROM_DS(x) ((x & 0x200) >> 9)
86 #define HAVE_FRAGMENTS(x) ((x & 0x400) >> 10)
87 #define IS_RETRY(x) ((x & 0x800) >> 11)
88 #define POWER_MGT_STATUS(x) ((x & 0x1000))
89 #define HAS_MORE_DATA(x) ((x & 0x2000))
90 #define IS_WEP(x) ((x & 0x4000))
91 #define IS_STRICTLY_ORDERED(x) ((x & 0x8000))
93 #define MGT_RESERVED_RANGE(x) (((x>=0x06)&&(x<=0x07))||((x>=0x0D)&&(x<=0x0F)))
94 #define CTRL_RESERVED_RANGE(x) ((x>=0x10)&&(x<=0x19))
95 #define DATA_RESERVED_RANGE(x) ((x>=0x28)&&(x<=0x2f))
96 #define SPEC_RESERVED_RANGE(x) ((x>=0x30)&&(x<=0x3f))
99 /* ************************************************************************* */
100 /* Constants used to identify cooked frame types */
101 /* ************************************************************************* */
102 #define MGT_FRAME 0x00 /* Frame type is management */
103 #define CONTROL_FRAME 0x01 /* Frame type is control */
104 #define DATA_FRAME 0x02 /* Frame type is Data */
106 #define DATA_SHORT_HDR_LEN 24
107 #define DATA_LONG_HDR_LEN 30
108 #define MGT_FRAME_HDR_LEN 24 /* Length of Managment frame-headers */
110 #define MGT_ASSOC_REQ 0x00 /* Management - association request */
111 #define MGT_ASSOC_RESP 0x01 /* Management - association response */
112 #define MGT_REASSOC_REQ 0x02 /* Management - reassociation request */
113 #define MGT_REASSOC_RESP 0x03 /* Management - reassociation response */
114 #define MGT_PROBE_REQ 0x04 /* Management - Probe request */
115 #define MGT_PROBE_RESP 0x05 /* Management - Probe response */
116 #define MGT_BEACON 0x08 /* Management - Beacon frame */
117 #define MGT_ATIM 0x09 /* Management - ATIM */
118 #define MGT_DISASS 0x0A /* Management - Disassociation */
119 #define MGT_AUTHENTICATION 0x0B /* Management - Authentication */
120 #define MGT_DEAUTHENTICATION 0x0C /* Management - Deauthentication */
122 #define CTRL_PS_POLL 0x1A /* Control - power-save poll */
123 #define CTRL_RTS 0x1B /* Control - request to send */
124 #define CTRL_CTS 0x1C /* Control - clear to send */
125 #define CTRL_ACKNOWLEDGEMENT 0x1D /* Control - acknowledgement */
126 #define CTRL_CFP_END 0x1E /* Control - contention-free period end */
127 #define CTRL_CFP_ENDACK 0x1F /* Control - contention-free period end/ack */
129 #define DATA 0x20 /* Data - Data */
130 #define DATA_CF_ACK 0x21 /* Data - Data + CF acknowledge */
131 #define DATA_CF_POLL 0x22 /* Data - Data + CF poll */
132 #define DATA_CF_ACK_POLL 0x23 /* Data - Data + CF acknowledge & CF poll */
133 #define DATA_NULL_FUNCTION 0x24 /* Data - Null function (no data) */
134 #define DATA_CF_ACK_NOD 0x25 /* Data - CF ack (no data) */
135 #define DATA_CF_ACK_POLL_NOD 0x26 /* Data - CF ack + CF poll (no data) */
137 #define DATA_ADDR_T1 0x00
138 #define DATA_ADDR_T2 0x01
139 #define DATA_ADDR_T3 0x02
140 #define DATA_ADDR_T4 0x03
143 /* ************************************************************************* */
144 /* Macros used to extract information about fixed fields */
145 /* ************************************************************************* */
146 #define ESS_SET(x) ((x & 0x0001))
147 #define IBSS_SET(x) ((x & 0x0002))
151 /* ************************************************************************* */
152 /* Logical field codes (dissector's encoding of fixed fields) */
153 /* ************************************************************************* */
154 #define FIELD_TIMESTAMP 0x01 /* 64-bit timestamp */
155 #define FIELD_BEACON_INTERVAL 0x02 /* 16-bit beacon interval */
156 #define FIELD_CAP_INFO 0x03 /* Add capability information tree */
157 #define FIELD_AUTH_ALG 0x04 /* Authentication algorithm used */
158 #define FIELD_AUTH_TRANS_SEQ 0x05 /* Authentication sequence number */
159 #define FIELD_CURRENT_AP_ADDR 0x06
160 #define FIELD_LISTEN_IVAL 0x07
161 #define FIELD_REASON_CODE 0x08
162 #define FIELD_ASSOC_ID 0x09
163 #define FIELD_STATUS_CODE 0x0A
165 /* ************************************************************************* */
166 /* Logical field codes (IEEE 802.11 encoding of tags) */
167 /* ************************************************************************* */
168 #define TAG_SSID 0x00
169 #define TAG_SUPP_RATES 0x01
170 #define TAG_FH_PARAMETER 0x02
171 #define TAG_DS_PARAMETER 0x03
172 #define TAG_CF_PARAMETER 0x04
174 #define TAG_IBSS_PARAMETER 0x06
175 #define TAG_CHALLENGE_TEXT 0x10
178 /* ************************************************************************* */
179 /* Various constants used in this module */
180 /* ************************************************************************* */
181 static const char *capture_proto_name = "IEEE 802.11";
184 static int proto_wlan = -1;
185 /* ************************************************************************* */
186 /* Header field info values for FC-field */
187 /* ************************************************************************* */
188 static int hf_fc_field = -1;
189 static int hf_fc_proto_version = -1;
190 static int hf_fc_frame_type = -1;
191 static int hf_fc_frame_subtype = -1;
193 static int hf_fc_flags = -1;
194 static int hf_fc_to_ds = -1;
195 static int hf_fc_from_ds = -1;
196 static int hf_fc_data_ds = -1;
198 static int hf_fc_more_frag = -1;
199 static int hf_fc_retry = -1;
200 static int hf_fc_pwr_mgt = -1;
201 static int hf_fc_more_data = -1;
202 static int hf_fc_wep = -1;
203 static int hf_fc_order = -1;
206 /* ************************************************************************* */
207 /* Header values for Duration/ID field */
208 /* ************************************************************************* */
209 static int hf_did_duration = -1;
213 /* ************************************************************************* */
214 /* Header values for different address-fields (all 4 of them) */
215 /* ************************************************************************* */
216 static int hf_addr_da = -1; /* Destination address subfield */
217 static int hf_addr_sa = -1; /* Source address subfield */
218 static int hf_addr_ra = -1; /* Receiver address subfield */
219 static int hf_addr_ta = -1; /* Transmitter address subfield */
220 static int hf_addr_bssid = -1; /* address is bssid */
224 /* ************************************************************************* */
225 /* Header values for sequence number field */
226 /* ************************************************************************* */
227 static int hf_frag_number = -1;
228 static int hf_seq_number = -1;
230 /* ************************************************************************* */
231 /* Header values for Frame Check field */
232 /* ************************************************************************* */
233 static int hf_fcs = -1;
236 /* ************************************************************************* */
237 /* Fixed fields found in mgt frames */
238 /* ************************************************************************* */
239 static int ff_auth_alg = -1; /* Authentication algorithm field */
240 static int ff_auth_seq = -1; /* Authentication transaction sequence */
241 static int ff_current_ap = -1; /* Current AP MAC address */
242 static int ff_listen_ival = -1; /* Listen interval fixed field */
243 static int ff_timestamp = -1; /* 64 bit timestamp */
244 static int ff_beacon_interval = -1; /* 16 bit Beacon interval */
245 static int ff_assoc_id = -1; /* 16 bit AID field */
246 static int ff_reason = -1; /* 16 bit reason code */
247 static int ff_status_code = -1; /* Status code */
249 /* ************************************************************************* */
250 /* Flags found in the capability field (fixed field) */
251 /* ************************************************************************* */
252 static int ff_capture = -1;
253 static int ff_cf_sta_poll = -1; /* CF pollable status for a STA */
254 static int ff_cf_ap_poll = -1; /* CF pollable status for an AP */
255 static int ff_cf_ess = -1;
256 static int ff_cf_ibss = -1;
257 static int ff_cf_privacy = -1;
259 /* ************************************************************************* */
260 /* Tagged value format fields */
261 /* ************************************************************************* */
262 static int tag_number = -1;
263 static int tag_length = -1;
264 static int tag_interpretation = -1;
268 static int hf_fixed_parameters = -1; /* Protocol payload for management frames */
269 static int hf_tagged_parameters = -1; /* Fixed payload item */
271 /* ************************************************************************* */
273 /* ************************************************************************* */
274 static gint ett_80211 = -1;
275 static gint ett_proto_flags = -1;
276 static gint ett_cap_tree = -1;
277 static gint ett_fc_tree = -1;
278 static gint ett_fixed_parameters = -1;
279 static gint ett_tagged_parameters = -1;
281 static dissector_handle_t llc_handle;
283 /* ************************************************************************* */
285 /* ************************************************************************* */
287 find_header_length (const u_char * pd, int offset)
289 guint16 frame_control;
291 frame_control = pntohs (pd);
292 return ((IS_FROM_DS (frame_control))
293 && (IS_TO_DS (frame_control))) ? 30 : 24;
297 /* ************************************************************************* */
298 /* This is the capture function used to update packet counts */
299 /* ************************************************************************* */
301 capture_ieee80211 (const u_char * pd, int offset, packet_counts * ld)
303 guint16 fcf, hdr_length;
305 fcf = pletohs (&pd[0]);
308 hdr_length = MGT_FRAME_HDR_LEN; /* Set the header length of the frame */
310 switch (COMPOSE_FRAME_TYPE (fcf))
313 case DATA: /* We got a data frame */
314 hdr_length = find_header_length (pd, offset);
315 capture_llc (pd, offset + hdr_length, ld);
318 case DATA_CF_ACK: /* Data with ACK */
319 hdr_length = find_header_length (pd, offset);
320 capture_llc (pd, offset + hdr_length, ld);
324 hdr_length = find_header_length (pd, offset);
325 capture_llc (pd, offset + hdr_length, ld);
328 case DATA_CF_ACK_POLL:
329 hdr_length = find_header_length (pd, offset);
330 capture_llc (pd, offset + hdr_length, ld);
341 /* ************************************************************************* */
342 /* Add the subtree used to store the fixed parameters */
343 /* ************************************************************************* */
345 get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
347 proto_item *fixed_fields;
349 proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
350 size, size, "Fixed parameters (%d bytes)",
353 return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
357 /* ************************************************************************* */
358 /* Add the subtree used to store tagged parameters */
359 /* ************************************************************************* */
361 get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
363 proto_item *tagged_fields;
365 tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
370 "Tagged parameters (%d bytes)",
373 return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
378 /* ************************************************************************* */
379 /* Dissect and add fixed mgmt fields to protocol tree */
380 /* ************************************************************************* */
382 add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
385 char out_buff[SHORT_STR];
387 proto_item *cap_item;
388 static proto_tree *cap_tree;
392 case FIELD_TIMESTAMP:
393 dataptr = tvb_get_ptr (tvb, offset, 8);
394 memset (out_buff, 0, SHORT_STR);
395 snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
396 BIT_SWAP (dataptr[7]),
397 BIT_SWAP (dataptr[6]),
398 BIT_SWAP (dataptr[5]),
399 BIT_SWAP (dataptr[4]),
400 BIT_SWAP (dataptr[3]),
401 BIT_SWAP (dataptr[2]),
402 BIT_SWAP (dataptr[1]),
403 BIT_SWAP (dataptr[0]));
405 proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
409 case FIELD_BEACON_INTERVAL:
410 dataptr = tvb_get_ptr (tvb, offset, 2);
411 out_buff[0] = BIT_SWAP (dataptr[1]);
412 out_buff[1] = BIT_SWAP (dataptr[0]);
413 temp16 = (guint16 *) out_buff;
414 proto_tree_add_uint (tree, ff_beacon_interval, tvb, offset, 2,
420 dataptr = tvb_get_ptr (tvb, offset, 2);
421 out_buff[0] = BIT_SWAP (dataptr[1]);
422 out_buff[0] = BIT_SWAP (dataptr[0]);
423 temp16 = (guint16 *) out_buff;
425 cap_item = proto_tree_add_uint_format (tree, ff_capture,
428 "Capability Information: %04X",
430 cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree);
431 proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 1,
433 proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 1,
435 proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 1,
437 if (ESS_SET (pntohs (temp16)) != 0) /* This is an AP */
438 proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2,
439 ((pntohs (temp16) & 0xC) >> 2));
441 else /* This is a STA */
442 proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
443 ((pntohs (temp16) & 0xC) >> 2));
448 dataptr = tvb_get_ptr (tvb, offset, 2);
449 out_buff[0] = BIT_SWAP (dataptr[1]);
450 out_buff[1] = BIT_SWAP (dataptr[0]);
451 temp16 = (guint16 *) out_buff;
452 proto_tree_add_uint (tree, ff_auth_alg, tvb, offset, 2,
457 case FIELD_AUTH_TRANS_SEQ:
458 dataptr = tvb_get_ptr (tvb, offset, 2);
459 out_buff[0] = BIT_SWAP (dataptr[1]);
460 out_buff[1] = BIT_SWAP (dataptr[0]);
461 temp16 = (guint16 *) out_buff;
462 proto_tree_add_uint (tree, ff_auth_seq, tvb, offset, 2,
467 case FIELD_CURRENT_AP_ADDR:
468 dataptr = tvb_get_ptr (tvb, offset, 6);
469 memset (out_buff, 0, SHORT_STR);
470 out_buff[0] = BIT_SWAP (dataptr[5]);
471 out_buff[1] = BIT_SWAP (dataptr[4]);
472 out_buff[2] = BIT_SWAP (dataptr[3]);
473 out_buff[3] = BIT_SWAP (dataptr[2]);
474 out_buff[4] = BIT_SWAP (dataptr[1]);
475 out_buff[5] = BIT_SWAP (dataptr[0]);
477 proto_tree_add_string (tree, ff_current_ap, tvb, offset, 6, out_buff);
481 case FIELD_LISTEN_IVAL:
482 dataptr = tvb_get_ptr (tvb, offset, 2);
483 out_buff[0] = BIT_SWAP (dataptr[1]);
484 out_buff[1] = BIT_SWAP (dataptr[0]);
485 temp16 = (guint16 *) out_buff;
486 proto_tree_add_uint (tree, ff_listen_ival, tvb, offset, 2,
491 case FIELD_REASON_CODE:
492 dataptr = tvb_get_ptr (tvb, offset, 2);
493 out_buff[0] = BIT_SWAP (dataptr[1]);
494 out_buff[1] = BIT_SWAP (dataptr[0]);
495 temp16 = (guint16 *) out_buff;
496 proto_tree_add_uint (tree, ff_reason, tvb, offset, 2, pntohs (temp16));
501 dataptr = tvb_get_ptr (tvb, offset, 2);
502 out_buff[0] = BIT_SWAP (dataptr[1]);
503 out_buff[1] = BIT_SWAP (dataptr[0]);
504 temp16 = (guint16 *) out_buff;
505 proto_tree_add_uint (tree, ff_assoc_id, tvb, offset, 2, pntohs (temp16));
508 case FIELD_STATUS_CODE:
509 dataptr = tvb_get_ptr (tvb, offset, 2);
510 out_buff[0] = BIT_SWAP (dataptr[1]);
511 out_buff[1] = BIT_SWAP (dataptr[0]);
512 temp16 = (guint16 *) out_buff;
513 proto_tree_add_uint (tree, ff_status_code, tvb, offset, 2,
520 /* ************************************************************************* */
521 /* Dissect and add tagged (optional) fields to proto tree */
522 /* ************************************************************************* */
524 add_tagged_field (proto_tree * tree, tvbuff_t * tvb, int offset)
526 guint8 *tag_info_ptr;
527 guint8 *tag_data_ptr;
528 guint32 tag_no, tag_len;
530 char out_buff[SHORT_STR];
533 tag_info_ptr = tvb_get_ptr (tvb, offset, 2);
534 tag_no = tag_info_ptr[0];
535 tag_len = tag_info_ptr[1];
537 tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
540 if ((tag_no >= 17) && (tag_no <= 31))
541 { /* Reserved for challenge text */
542 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
543 "Tag Number: %d (Reserved for challenge text)",
546 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
547 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
548 tag_len, "Not interpreted");
549 return (int) tag_len;
552 /* Next See if tag is reserved - if true, skip it! */
553 if (((tag_no >= 7) && (tag_no <= 15))
554 || ((tag_no >= 32) && (tag_no <= 255)))
556 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
557 "Tag Number: %d (Reserved tag number)",
560 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
562 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
563 tag_len, "Not interpreted");
564 return (int) tag_len;
568 switch (tag_info_ptr[0])
573 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
574 "Tag Number: %d (SSID parameter set)",
577 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
579 memset (out_buff, 0, SHORT_STR);
581 memcpy (out_buff, tag_data_ptr, (size_t) tag_len);
582 out_buff[tag_len + 1] = 0;
584 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
591 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
592 "Tag Number: %d (Supported Rates)", tag_no);
594 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
596 memset (out_buff, 0, SHORT_STR);
597 strcpy (out_buff, "Supported rates: ");
598 n = strlen (out_buff);
600 for (i = 0; i < tag_len; i++)
603 if (tag_data_ptr[i] >= 128)
605 tag_data_ptr[i] -= 128;
606 n += snprintf (out_buff + n, SHORT_STR - n, "%2.1f ", (float)
607 (((float) tag_data_ptr[i]) * 0.5));
611 n += snprintf (out_buff + n, SHORT_STR - n, "%2.1f ", (float)
612 (((float) tag_data_ptr[i]) * 0.5));
615 snprintf (out_buff + n, SHORT_STR - n, "[Mbit/sec]");
617 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
623 case TAG_FH_PARAMETER:
624 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
625 "Tag Number: %d (FH Parameter set)",
628 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
629 memset (out_buff, 0, SHORT_STR);
631 snprintf (out_buff, SHORT_STR,
632 "Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, "
633 "Hop Index %2d", pntohs (tag_data_ptr), tag_data_ptr[2],
634 tag_data_ptr[3], tag_data_ptr[4]);
636 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
642 case TAG_DS_PARAMETER:
643 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
644 "Tag Number: %d (DS Parameter set)",
647 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
648 memset (out_buff, 0, SHORT_STR);
650 snprintf (out_buff, SHORT_STR, "Current Channel: %d", tag_data_ptr[0]);
651 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
656 case TAG_CF_PARAMETER:
657 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
658 "Tag Number: %d (CF Parameter set)",
661 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
662 memset (out_buff, 0, SHORT_STR);
664 snprintf (out_buff, SHORT_STR,
665 "CFP count %d, CFP period %d, CFP max duration %d, "
666 "CFP Remaining %d", tag_data_ptr[0], tag_data_ptr[1],
667 pntohs (tag_data_ptr + 2), pntohs (tag_data_ptr + 4));
669 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
675 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
676 "Tag Number: %d (CF Parameter set)",
679 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
680 memset (out_buff, 0, SHORT_STR);
681 snprintf (out_buff, SHORT_STR,
682 "DTIM count %d, DTIM period %d, Bitmap control 0x%X, "
683 "(Bitmap suppressed)", tag_data_ptr[0], tag_data_ptr[1],
685 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
691 case TAG_IBSS_PARAMETER:
692 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
693 "Tag Number: %d (IBSS Parameter set)",
696 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
697 memset (out_buff, 0, SHORT_STR);
698 snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
699 pntohs (tag_data_ptr));
701 proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
707 case TAG_CHALLENGE_TEXT:
708 proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
709 "Tag Number: %d (Challenge text)", tag_no);
711 proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
712 memset (out_buff, 0, SHORT_STR);
713 snprintf (out_buff, SHORT_STR, "Challenge text: %.47s", tag_data_ptr);
714 proto_tree_add_string (tree, tag_interpretation, tvb, offset, tag_len,
728 /* ************************************************************************* */
729 /* Dissect 802.11 frame */
730 /* ************************************************************************* */
732 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
735 guint8 *src = NULL, *dst = NULL;
737 proto_item *flag_item;
739 static proto_tree *hdr_tree;
740 static proto_tree *flag_tree;
741 static proto_tree *fixed_tree;
742 static proto_tree *tagged_tree;
743 static proto_tree *fc_tree;
744 guint16 cap_len, hdr_len;
749 cap_len = pinfo->captured_len;
750 fcf = tvb_get_letohs (tvb, 0);
752 CHECK_DISPLAY_AS_DATA(proto_wlan, tvb, pinfo, tree);
754 pinfo->current_proto = capture_proto_name;
756 if (check_col (pinfo->fd, COL_PROTOCOL))
757 col_set_str (pinfo->fd, COL_PROTOCOL, "IEEE 802.11");
759 /* Add the FC to the current tree */
762 hdr_len = find_header_length (tvb_get_ptr (tvb, 0, cap_len), 0);
763 ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
764 "IEEE 802.11 Header");
765 hdr_tree = proto_item_add_subtree (ti, ett_80211);
768 proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb, 0, 2,
769 tvb_get_letohs (tvb, 0),
770 "Frame Control: 0x%04X",
771 tvb_get_letohs (tvb, 0));
773 fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
776 proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb, 0, 1,
777 COOK_PROT_VERSION (tvb_get_letohs (tvb, 0)));
779 proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb, 0, 1,
780 COOK_FRAME_TYPE (tvb_get_letohs (tvb, 0)));
782 proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
784 COOK_FRAME_SUBTYPE (tvb_get_letohs (tvb, 0)));
786 flags = COOK_FLAGS (tvb_get_letohs (tvb, 0));
789 proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb, 1, 1,
790 flags, "Flags: 0x%X", flags);
792 flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
794 proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb, 1, 1,
795 COOK_DS_STATUS (flags));
797 /* proto_tree_add_boolean(flag_tree,hf_fc_to_ds,tvb,1,1,
800 proto_tree_add_boolean(flag_tree,hf_fc_from_ds,tvb,1,1,
803 proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb, 1, 1,
806 proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb, 1, 1, flags);
808 proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb, 1, 1, flags);
810 proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb, 1, 1,
813 proto_tree_add_boolean (flag_tree, hf_fc_wep, tvb, 1, 1, flags);
815 proto_tree_add_boolean (flag_tree, hf_fc_order, tvb, 1, 1, flags);
817 proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
818 tvb_get_ntohs (tvb, 2));
822 /* Perform Tasks which are common to a certain frame type */
823 switch (COOK_FRAME_TYPE (fcf))
826 case MGT_FRAME: /* All management frames share a common header */
827 src = tvb_get_ptr (tvb, 10, 6);
828 dst = tvb_get_ptr (tvb, 4, 6);
831 if (check_col (pinfo->fd, COL_DEF_SRC))
832 col_add_fstr (pinfo->fd, COL_DEF_SRC, "%X:%X:%X:%X:%X:%X",
833 src[0], src[1], src[2], src[3], src[4], src[5]);
835 if (check_col (pinfo->fd, COL_DEF_DST))
836 col_add_fstr (pinfo->fd, COL_DEF_DST, "%X:%X:%X:%X:%X:%X",
837 dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
841 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6,
842 tvb_get_ptr (tvb, 4, 6));
844 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6,
845 tvb_get_ptr (tvb, 10, 6));
847 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
848 tvb_get_ptr (tvb, 16, 6));
850 proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
851 COOK_FRAGMENT_NUMBER (tvb_get_ntohs
854 proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
855 COOK_SEQUENCE_NUMBER (tvb_get_ntohs
857 cap_len = cap_len - MGT_FRAME_LEN - 4;
869 addr_type = COOK_ADDR_SELECTOR (fcf);
871 /* In order to show src/dst address we must always do the following */
876 src = tvb_get_ptr (tvb, 10, 6);
877 dst = tvb_get_ptr (tvb, 4, 6);
882 src = tvb_get_ptr (tvb, 16, 6);
883 dst = tvb_get_ptr (tvb, 4, 6);
888 src = tvb_get_ptr (tvb, 10, 6);
889 dst = tvb_get_ptr (tvb, 16, 6);
894 src = tvb_get_ptr (tvb, 24, 6);
895 dst = tvb_get_ptr (tvb, 16, 6);
899 if (check_col (pinfo->fd, COL_DEF_SRC))
900 col_add_fstr (pinfo->fd, COL_DEF_SRC,
901 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
902 src[0], src[1], src[2], src[3], src[4], src[5]);
904 if (check_col (pinfo->fd, COL_DEF_DST))
905 col_add_fstr (pinfo->fd, COL_DEF_DST,
906 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
907 dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
909 /* Now if we have a tree we start adding stuff */
918 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6,
919 tvb_get_ptr (tvb, 4, 6));
920 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6,
921 tvb_get_ptr (tvb, 10, 6));
922 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
923 tvb_get_ptr (tvb, 16, 6));
928 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6,
929 tvb_get_ptr (tvb, 4, 6));
930 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
931 tvb_get_ptr (tvb, 10, 6));
932 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6,
933 tvb_get_ptr (tvb, 16, 6));
938 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
939 tvb_get_ptr (tvb, 4, 6));
940 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6,
941 tvb_get_ptr (tvb, 10, 6));
942 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6,
943 tvb_get_ptr (tvb, 16, 6));
948 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
949 tvb_get_ptr (tvb, 4, 6));
950 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
951 tvb_get_ptr (tvb, 10, 6));
952 proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6,
953 tvb_get_ptr (tvb, 16, 6));
954 proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6,
955 tvb_get_ptr (tvb, 24, 6));
965 switch (COMPOSE_FRAME_TYPE (fcf))
969 COL_SHOW_INFO (pinfo->fd, "Association Request");
972 fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 4);
973 add_fixed_field (fixed_tree, tvb, MGT_FRAME_HDR_LEN,
975 add_fixed_field (fixed_tree, tvb, MGT_FRAME_HDR_LEN + 2,
978 next_idx = MGT_FRAME_HDR_LEN + 4; /* Size of fixed fields */
979 tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
980 pinfo->captured_len - 4 -
984 while (pinfo->captured_len > (next_idx + 4))
985 next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
992 COL_SHOW_INFO (pinfo->fd, "Association Response");
996 fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 6);
997 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_CAP_INFO);
998 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 2,
1000 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 4,
1003 next_idx = MGT_FRAME_LEN + 6; /* Size of fixed fields */
1005 tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
1006 pinfo->captured_len - 4 -
1009 while (pinfo->captured_len > (next_idx + 4))
1010 next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
1015 case MGT_REASSOC_REQ:
1016 COL_SHOW_INFO (pinfo->fd, "Reassociation Request");
1019 fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 10);
1020 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_CAP_INFO);
1021 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 2,
1023 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 4,
1024 FIELD_CURRENT_AP_ADDR);
1026 next_idx = MGT_FRAME_LEN + 10; /* Size of fixed fields */
1027 tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
1028 pinfo->captured_len - 4 -
1031 while ((pinfo->captured_len) > (next_idx + 4))
1032 next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
1036 case MGT_REASSOC_RESP:
1037 COL_SHOW_INFO (pinfo->fd, "Reassociation Response");
1040 fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 10);
1041 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_CAP_INFO);
1042 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 2,
1044 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 4,
1047 next_idx = MGT_FRAME_LEN + 6; /* Size of fixed fields */
1048 tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
1049 pinfo->captured_len - 4 -
1052 while (pinfo->captured_len > (next_idx + 4))
1053 next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
1060 COL_SHOW_INFO (pinfo->fd, "Probe Request");
1063 next_idx = MGT_FRAME_LEN;
1064 tagged_tree = get_tagged_parameter_tree (tree, tvb, MGT_FRAME_LEN,
1065 pinfo->captured_len - 4 -
1068 while (pinfo->captured_len > (next_idx + 4))
1069 next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
1075 case MGT_PROBE_RESP:
1076 COL_SHOW_INFO (pinfo->fd, "Probe Response");
1079 fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 12);
1080 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_TIMESTAMP);
1081 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 8,
1082 FIELD_BEACON_INTERVAL);
1083 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 10,
1086 next_idx = MGT_FRAME_LEN + 12; /* Size of fixed fields */
1087 tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
1088 pinfo->captured_len - 4 -
1091 while ((pinfo->captured_len) > (next_idx + 4))
1092 next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
1097 case MGT_BEACON: /* Dissect protocol payload fields */
1098 COL_SHOW_INFO (pinfo->fd, "Beacon frame");
1102 fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 12);
1104 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_TIMESTAMP);
1106 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 8,
1107 FIELD_BEACON_INTERVAL);
1108 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 10,
1111 next_idx = MGT_FRAME_LEN + 12; /* Size of fixed fields */
1112 tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
1113 pinfo->captured_len - 4 -
1116 while (pinfo->captured_len > (next_idx + 4))
1117 next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
1125 COL_SHOW_INFO (pinfo->fd, "ATIM");
1132 COL_SHOW_INFO (pinfo->fd, "Dissassociate");
1136 get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, cap_len);
1137 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_REASON_CODE);
1141 case MGT_AUTHENTICATION:
1142 COL_SHOW_INFO (pinfo->fd, "Authentication");
1145 fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 6);
1146 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_AUTH_ALG);
1147 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 2,
1148 FIELD_AUTH_TRANS_SEQ);
1149 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 4,
1152 next_idx = MGT_FRAME_LEN + 6; /* Size of fixed fields */
1154 if ((pinfo->captured_len - next_idx - 4) != 0)
1156 tagged_tree = get_tagged_parameter_tree (tree,
1159 pinfo->captured_len -
1162 while ((pinfo->captured_len) > (next_idx - 4))
1163 next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
1168 case MGT_DEAUTHENTICATION:
1169 COL_SHOW_INFO (pinfo->fd, "Deauthentication");
1172 fixed_tree = get_fixed_parameter_tree (hdr_tree, tvb, MGT_FRAME_LEN, 2);
1173 add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_REASON_CODE);
1180 COL_SHOW_INFO (pinfo->fd, "Power-Save poll");
1182 src = tvb_get_ptr (tvb, 10, 6);
1183 dst = tvb_get_ptr (tvb, 4, 6);
1186 if (check_col (pinfo->fd, COL_DEF_SRC))
1187 col_add_fstr (pinfo->fd, COL_DEF_SRC,
1188 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (BSSID)",
1189 src[0], src[1], src[2], src[3], src[4], src[5]);
1191 if (check_col (pinfo->fd, COL_DEF_DST))
1192 col_add_fstr (pinfo->fd, COL_DEF_DST,
1193 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (TA)",
1194 dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
1198 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
1199 tvb_get_ptr (tvb, 4, 6));
1201 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
1202 tvb_get_ptr (tvb, 10, 6));
1210 COL_SHOW_INFO (pinfo->fd, "Request-to-send");
1211 src = tvb_get_ptr (tvb, 10, 6);
1212 dst = tvb_get_ptr (tvb, 4, 6);
1215 if (check_col (pinfo->fd, COL_DEF_SRC))
1216 col_add_fstr (pinfo->fd, COL_DEF_SRC,
1217 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (TA)",
1218 src[0], src[1], src[2], src[3], src[4], src[5]);
1220 if (check_col (pinfo->fd, COL_DEF_DST))
1221 col_add_fstr (pinfo->fd, COL_DEF_DST,
1222 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (RA)",
1223 dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
1227 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
1228 tvb_get_ptr (tvb, 4, 6));
1230 proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
1231 tvb_get_ptr (tvb, 10, 6));
1239 COL_SHOW_INFO (pinfo->fd, "Clear-to-send");
1241 dst = tvb_get_ptr (tvb, 4, 6);
1243 if (check_col (pinfo->fd, COL_DEF_DST))
1244 col_add_fstr (pinfo->fd, COL_DEF_DST,
1245 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (RA)",
1246 dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
1250 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
1251 tvb_get_ptr (tvb, 4, 6));
1258 case CTRL_ACKNOWLEDGEMENT:
1259 COL_SHOW_INFO (pinfo->fd, "Acknowledgement");
1261 dst = tvb_get_ptr (tvb, 4, 6);
1263 if (check_col (pinfo->fd, COL_DEF_DST))
1264 col_add_fstr (pinfo->fd, COL_DEF_DST,
1265 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (RA)",
1266 dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
1269 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
1270 tvb_get_ptr (tvb, 4, 6));
1276 COL_SHOW_INFO (pinfo->fd, "CF-End (Control-frame)");
1278 src = tvb_get_ptr (tvb, 10, 6);
1279 dst = tvb_get_ptr (tvb, 4, 6);
1282 if (check_col (pinfo->fd, COL_DEF_SRC))
1283 col_add_fstr (pinfo->fd, COL_DEF_SRC, "%X:%X:%X:%X:%X:%X (BSSID)",
1284 src[0], src[1], src[2], src[3], src[4], src[5]);
1286 if (check_col (pinfo->fd, COL_DEF_DST))
1287 col_add_fstr (pinfo->fd, COL_DEF_DST, "%X:%X:%X:%X:%X:%X (RA)",
1288 dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
1292 proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
1293 tvb_get_ntohs (tvb, 2));
1295 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
1296 tvb_get_ptr (tvb, 4, 6));
1298 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
1299 tvb_get_ptr (tvb, 10, 6));
1306 case CTRL_CFP_ENDACK:
1307 COL_SHOW_INFO (pinfo->fd, "CF-End + CF-Ack (Control-frame)");
1309 src = tvb_get_ptr (tvb, 10, 6);
1310 dst = tvb_get_ptr (tvb, 4, 6);
1312 if (check_col (pinfo->fd, COL_DEF_SRC))
1313 col_add_fstr (pinfo->fd, COL_DEF_SRC, "%X:%X:%X:%X:%X:%X (BSSID)",
1314 src[0], src[1], src[2], src[3], src[4], src[5]);
1316 if (check_col (pinfo->fd, COL_DEF_DST))
1317 col_add_fstr (pinfo->fd, COL_DEF_DST, "%X:%X:%X:%X:%X:%X (RA)",
1318 dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
1322 proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
1323 tvb_get_ntohs (tvb, 2));
1325 proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
1326 tvb_get_ptr (tvb, 4, 6));
1328 proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
1329 tvb_get_ptr (tvb, 10, 6));
1337 COL_SHOW_INFO (pinfo->fd, "Data");
1340 hdr_len = find_header_length (tvb_get_ptr (tvb, 0, cap_len), 0);
1342 next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
1343 call_dissector (llc_handle, next_tvb, pinfo, tree);
1350 COL_SHOW_INFO (pinfo->fd, "Data + CF-Acknowledgement");
1353 hdr_len = find_header_length (tvb_get_ptr (tvb, 0, cap_len), 0);
1355 next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
1356 call_dissector (llc_handle, next_tvb, pinfo, tree);
1363 COL_SHOW_INFO (pinfo->fd, "Data + CF-Poll");
1366 hdr_len = find_header_length (tvb_get_ptr (tvb, 0, cap_len), 0);
1367 next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
1368 call_dissector (llc_handle, next_tvb, pinfo, tree);
1374 case DATA_CF_ACK_POLL:
1375 COL_SHOW_INFO (pinfo->fd, "Data + CF-Acknowledgement/Poll");
1378 hdr_len = find_header_length (tvb_get_ptr (tvb, 0, cap_len), 0);
1379 next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
1380 call_dissector (llc_handle, next_tvb, pinfo, tree);
1386 case DATA_NULL_FUNCTION:
1387 COL_SHOW_INFO (pinfo->fd, "Null function (No data)");
1391 case DATA_CF_ACK_NOD:
1392 COL_SHOW_INFO (pinfo->fd, "Data + Acknowledgement(No data)");
1397 case DATA_CF_ACK_POLL_NOD:
1398 COL_SHOW_INFO (pinfo->fd, "Data + CF-Acknowledgement/Poll (No data)");
1404 COL_SHOW_INFO (pinfo->fd, "Unrecognized (Reserved frame)");
1411 proto_register_wlan (void)
1414 static const value_string tofrom_ds[] = {
1415 {0, "Network operating in AD-HOC mode ( To DS: 0 From DS: 0)"},
1416 {1, "Frame is exiting DS (To DS: 0 From DS: 1)"},
1417 {2, "Frame is entering DS (To DS: 0 From DS: 1)"},
1418 {3, "Frame part of WDS (To DS: 1 From DS: 1)"},
1422 static const true_false_string tods_flag = {
1423 "TO DS: Should be false",
1427 static const true_false_string fromds_flag = {
1428 "FROM DS: Should be false",
1432 static const true_false_string more_frags = {
1433 "MSDU/MMPDU is fragmented",
1437 static const true_false_string retry_flags = {
1438 "Frame is being retransmitted",
1439 "Frame is not being retransmitted"
1442 static const true_false_string pm_flags = {
1443 "STA will go to sleep",
1447 static const true_false_string md_flags = {
1448 "Data is buffered for STA at AP",
1452 static const true_false_string wep_flags = {
1457 static const true_false_string order_flags = {
1462 static const true_false_string cf_ess_flags = {
1463 "Transmitter is an AP",
1464 "Transmitter is a STA"
1468 static const true_false_string cf_privacy_flags = {
1469 "AP/STA can support WEP",
1470 "AP/STA cannot support WEP"
1474 static const true_false_string cf_ibss_flags = {
1475 "Transmitter belongs to an IBSS",
1476 "Transmitter belongs to a BSS"
1479 static const value_string sta_cf_pollable[] = {
1480 {0x00, "Station is not CF-Pollable"},
1481 {0x02, "Station is CF-Pollable, "
1482 "not requesting to be placed on the CF-polling list"},
1483 {0x01, "Station is CF-Pollable, "
1484 "requesting to be placed on the CF-polling list"},
1485 {0x03, "Station is CF-Pollable, requesting never to be polled"},
1489 static const value_string ap_cf_pollable[] = {
1490 {0x00, "No point coordinator at AP"},
1491 {0x02, "Point coordinator at AP for delivery only (no polling)"},
1492 {0x01, "Point coordinator at AP for delivery and polling"},
1498 static const value_string auth_alg[] = {
1499 {0x00, "Open System"},
1500 {0x01, "Shared key"},
1504 static const value_string reason_codes[] = {
1506 {0x01, "Unspecified reason"},
1507 {0x02, "Previous authentication no longer valid"},
1508 {0x03, "Deauthenticated because sending STA is leaving (has left) "
1510 {0x04, "Disassociated due to inactivity"},
1511 {0x05, "Disassociated because AP is unable to handle all currently "
1512 "associated stations"},
1513 {0x06, "Class 2 frame received from nonauthenticated station"},
1514 {0x07, "Class 3 frame received from nonassociated station"},
1515 {0x08, "Disassociated because sending STA is leaving (has left) BSS"},
1516 {0x09, "Station requesting (re)association is not authenticated with "
1517 "responding station"},
1522 static const value_string status_codes[] = {
1523 {0x00, "Successful"},
1524 {0x01, "Unspecified failure"},
1525 {0x0A, "Cannot support all requested capabilities in the "
1526 "Capability information field"},
1527 {0x0B, "Reassociation denied due to inability to confirm that "
1528 "association exists"},
1529 {0x0C, "Association denied due to reason outside the scope of this "
1532 {0x0D, "Responding station does not support the specified authentication "
1534 {0x0E, "Received an Authentication frame with authentication sequence "
1535 "transaction sequence number out of expected sequence"},
1536 {0x0F, "Authentication rejected because of challenge failure"},
1537 {0x10, "Authentication rejected due to timeout waiting for next "
1538 "frame in sequence"},
1539 {0x11, "Association denied because AP is unable to handle additional "
1540 "associated stations"},
1541 {0x12, "Association denied due to requesting station not supporting all "
1542 "of the datarates in the BSSBasicServiceSet Parameter"},
1548 static hf_register_info hf[] = {
1550 {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
1551 "MAC Frame control"}},
1553 {&hf_fc_proto_version,
1554 {"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
1555 "MAC Protocol version"}}, /* 0 */
1558 {"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, NULL, 0,
1561 {&hf_fc_frame_subtype,
1562 {"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
1563 "Frame subtype"}}, /* 2 */
1566 {"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
1570 {"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, TFS (&tofrom_ds), 0,
1571 "Data-frame DS-traversal status"}}, /* 3 */
1574 {"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), 0x1,
1575 "To DS flag"}}, /* 4 */
1578 {"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), 0x2,
1579 "From DS flag"}}, /* 5 */
1582 {"Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), 0x4,
1583 "More Fragments flag"}}, /* 6 */
1586 {"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), 0x8,
1587 "Retransmission flag"}},
1590 {"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), 0x10,
1591 "Power management status"}},
1594 {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), 0x20,
1598 {"WEP flag", "wlan.fc.wep", FT_BOOLEAN, 8, TFS (&wep_flags), 0x40,
1602 {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), 0x80,
1603 "Strictly ordered flag"}},
1606 {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
1610 {"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
1611 "Destination Hardware address"}},
1614 {"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
1615 "Source Hardware address"}},
1618 {"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
1619 "Receiving Station Hardware Address"}},
1622 {"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
1623 "Transmitting Station Hardware Address"}},
1626 {"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
1627 "Basic Service Set ID"}},
1630 {"Fragment number", "wlan.frag", FT_UINT16, BASE_HEX, NULL, 0,
1631 "Fragment number"}},
1634 {"Sequence number", "wlan.seq", FT_UINT16, BASE_HEX, NULL, 0,
1635 "Fragment number"}},
1638 {"Frame Check Sequence (not verified)", "wlan.fcs", FT_UINT32, BASE_HEX,
1642 {"Timestamp", "wlan.fixed.timestamp", FT_STRING, BASE_NONE,
1646 {"Authentication Algorithm", "wlan.fixed.auth.alg",
1647 FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, ""}},
1649 {&ff_beacon_interval,
1650 {"Beacon Interval", "wlan.fixed.beacon", FT_UINT16, BASE_DEC, NULL, 0,
1653 {&hf_fixed_parameters,
1654 {"Fixed parameters", "wlan.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
1657 {&hf_tagged_parameters,
1658 {"Tagged parameters", "wlan.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
1662 {"Capabilities", "wlan.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
1663 "Capability information"}},
1666 {"CFP participation capabilities", "wlan.fixed.capabilities.cfpoll.sta",
1667 FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0,
1668 "CF-Poll capabilities for a STA"}},
1671 {"CFP participation capabilities", "wlan.fixed.capabilities.cfpoll.ap",
1672 FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0,
1673 "CF-Poll capabilities for an AP"}},
1676 {"ESS capabilities", "wlan.fixed.capabilities.ess",
1677 FT_BOOLEAN, 1, TFS (&cf_ess_flags), 0x0001, "ESS capabilities"}},
1681 {"IBSS status", "wlan.fixed.capabilities.ibss",
1682 FT_BOOLEAN, 1, TFS (&cf_ibss_flags), 0x0002, "IBSS participation"}},
1685 {"Privacy", "wlan.fixed.capabilities.privacy",
1686 FT_BOOLEAN, 1, TFS (&cf_privacy_flags), 0x0010, "WEP support"}},
1690 {"Authentication SEQ", "wlan.fixed.auth_seq",
1691 FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number"}},
1694 {"Association ID", "wlan.fixed.aid",
1695 FT_UINT16, BASE_HEX, NULL, 0, "Association ID"}},
1698 {"Listen Interval", "wlan.fixed.listen_ival",
1699 FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval"}},
1702 {"Current AP", "wlan.fixed.current_ap",
1703 FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP"}},
1706 {"Reason code", "wlan.fixed.reason_code",
1707 FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
1708 "Reason for unsolicited notification"}},
1711 {"Status code", "wlan.fixed.status_code",
1712 FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
1713 "Status of requested event"}},
1716 {"Tag", "wlan.tag.number",
1717 FT_UINT16, BASE_DEC, NULL, 0,
1721 {"Tag length", "wlan.tag.length",
1722 FT_UINT16, BASE_DEC, NULL, 0, "Length of tag"}},
1724 {&tag_interpretation,
1725 {"Tag interpretation", "wlan.tag.interpretation",
1726 FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag"}}
1732 static gint *tree_array[] = { &ett_80211,
1735 &ett_fixed_parameters,
1736 &ett_tagged_parameters,
1740 proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
1741 "IEEE 802.11", "wlan");
1742 proto_register_field_array (proto_wlan, hf, array_length (hf));
1743 proto_register_subtree_array (tree_array, array_length (tree_array));
1747 proto_reg_handoff_wlan(void)
1750 * Get a handle for the LLC dissector.
1752 llc_handle = find_dissector("llc");
1754 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, dissect_ieee80211,