Get rid of unused variables, and mark unused arguments as such.
[obnox/wireshark/wip.git] / packet-ieee80211.c
1 /* packet-ieee80211.c
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
5  *
6  * $Id: packet-ieee80211.c,v 1.59 2002/04/22 08:14:12 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from README.developer
13  *
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.
18  * 
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.
23  * 
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.
27  *
28  * Credits:
29  * 
30  * The following people helped me by pointing out bugs etc. Thank you!
31  *
32  * Marco Molteni
33  * Lena-Marie Nilsson     
34  * Magnus Hultman-Persson
35  */
36
37 #ifdef HAVE_CONFIG_H
38 # include "config.h"
39 #endif
40
41 #include <stdio.h>
42 #include <stdlib.h>
43
44 #ifdef HAVE_SYS_TYPES_H
45 # include <sys/types.h>
46 #endif
47
48 #ifdef HAVE_NETINET_IN_H
49 # include <netinet/in.h>
50 #endif
51
52 #ifdef NEED_SNPRINTF_H
53 # ifdef HAVE_STDARG_H
54 #  include <stdarg.h>
55 # else
56 #  include <varargs.h>
57 # endif
58 # include "snprintf.h"
59 #endif
60
61 #include <string.h>
62 #include <glib.h>
63 #include <epan/bitswap.h>
64 #include <epan/proto.h>
65 #include <epan/packet.h>
66 #include <epan/resolv.h>
67 #include "prefs.h"
68 #include "reassemble.h"
69 #include "packet-ipx.h"
70 #include "packet-llc.h"
71 #include "packet-ieee80211.h"
72 #include "etypes.h"
73
74 /* Defragment fragmented 802.11 datagrams */
75 static gboolean wlan_defragment = TRUE;
76
77 /* Tables for reassembly of fragments. */
78 static GHashTable *wlan_fragment_table = NULL;
79 static GHashTable *wlan_reassembled_table = NULL;
80
81 /* ************************************************************************* */
82 /*                          Miscellaneous Constants                          */
83 /* ************************************************************************* */
84 #define SHORT_STR 256
85
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)
100
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
109
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)
118
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))
123
124
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 */
131
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 */
135
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           */
147
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 */
154
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)       */
163
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)
168
169
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)
175
176
177
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
191
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
200 #define TAG_TIM            0x05
201 #define TAG_IBSS_PARAMETER 0x06
202 #define TAG_CHALLENGE_TEXT 0x10
203
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"},
215         {MGT_ATIM,             "ATIM"},
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)"},
225         {DATA,                 "Data"},
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)"},
233         {0,                    NULL}
234 };
235
236 static int proto_wlan = -1;
237
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;
244
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;
253
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;
258
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;
265
266
267 /* ************************************************************************* */
268 /*                   Header values for Duration/ID field                     */
269 /* ************************************************************************* */
270 static int hf_did_duration = -1;
271 static int hf_assoc_id = -1;
272
273
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 */
282
283 static int hf_addr = -1;        /* Source or destination address subfield */
284
285
286 /* ************************************************************************* */
287 /*                Header values for sequence number field                    */
288 /* ************************************************************************* */
289 static int hf_frag_number = -1;
290 static int hf_seq_number = -1;
291
292 /* ************************************************************************* */
293 /*                   Header values for Frame Check field                     */
294 /* ************************************************************************* */
295 static int hf_fcs = -1;
296
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;
307
308
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                               */
322
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;
335
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;
342
343
344
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;
350
351 /* ************************************************************************* */
352 /*                               Protocol trees                              */
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;
360
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;
365
366 static dissector_handle_t llc_handle;
367 static dissector_handle_t ipx_handle;
368 static dissector_handle_t data_handle;
369
370 /* ************************************************************************* */
371 /*            Return the length of the current header (in bytes)             */
372 /* ************************************************************************* */
373 static int
374 find_header_length (guint16 fcf)
375 {
376   switch (COOK_FRAME_TYPE (fcf)) {
377
378   case MGT_FRAME:
379     return MGT_FRAME_HDR_LEN;
380
381   case CONTROL_FRAME:
382     switch (COMPOSE_FRAME_TYPE (fcf)) {
383
384     case CTRL_CTS:
385     case CTRL_ACKNOWLEDGEMENT:
386       return 10;
387
388     case CTRL_RTS:
389     case CTRL_PS_POLL:
390     case CTRL_CFP_END:
391     case CTRL_CFP_ENDACK:
392       return 16;
393     }
394     return 4;   /* XXX */
395
396   case DATA_FRAME:
397     return (COOK_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
398                                                        DATA_SHORT_HDR_LEN;
399   default:
400     return 4;   /* XXX */
401   }
402 }
403
404
405 /* ************************************************************************* */
406 /*          This is the capture function used to update packet counts        */
407 /* ************************************************************************* */
408 static void
409 capture_ieee80211_common (const u_char * pd, int offset, int len,
410                           packet_counts * ld, gboolean fixed_length_header)
411 {
412   guint16 fcf, hdr_length;
413
414   if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
415     ld->other++;
416     return;
417   }
418
419   fcf = pletohs (&pd[0]);
420
421   if (IS_WEP(COOK_FLAGS(fcf)))
422     {
423       ld->other++;
424       return;
425     }
426
427   switch (COMPOSE_FRAME_TYPE (fcf))
428     {
429
430     case DATA:                  /* We got a data frame */
431     case DATA_CF_ACK:           /* Data with ACK */
432     case DATA_CF_POLL:
433     case DATA_CF_ACK_POLL:
434       if (fixed_length_header)
435         hdr_length = DATA_LONG_HDR_LEN;
436       else
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.
443
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
448          as an IPX frame. */
449       if (!BYTES_ARE_IN_FRAME(offset+hdr_length, len, 2)) {
450         ld->other++;
451         return;
452       }
453       if (pd[offset+hdr_length] == 0xff && pd[offset+hdr_length+1] == 0xff) {
454         capture_ipx (pd, offset + hdr_length, len, ld);
455       }
456       else {
457         capture_llc (pd, offset + hdr_length, len, ld);
458       }
459       break;
460
461     default:
462       ld->other++;
463       break;
464     }
465 }
466
467 /*
468  * Handle 802.11 with a variable-length link-layer header.
469  */
470 void
471 capture_ieee80211 (const u_char * pd, int offset, int len, packet_counts * ld)
472 {
473   capture_ieee80211_common (pd, offset, len, ld, FALSE);
474 }
475
476 /*
477  * Handle 802.11 with a fixed-length link-layer header (padded to the
478  * maximum length).
479  */
480 void
481 capture_ieee80211_fixed (const u_char * pd, int offset, int len, packet_counts * ld)
482 {
483   capture_ieee80211_common (pd, offset, len, ld, TRUE);
484 }
485
486
487 /* ************************************************************************* */
488 /*          Add the subtree used to store the fixed parameters               */
489 /* ************************************************************************* */
490 static proto_tree *
491 get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
492 {
493   proto_item *fixed_fields;
494   fixed_fields =
495     proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
496                                 size, size, "Fixed parameters (%d bytes)",
497                                 size);
498
499   return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
500 }
501
502
503 /* ************************************************************************* */
504 /*            Add the subtree used to store tagged parameters                */
505 /* ************************************************************************* */
506 static proto_tree *
507 get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
508 {
509   proto_item *tagged_fields;
510
511   tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
512                                               tvb,
513                                               start,
514                                               size,
515                                               size,
516                                               "Tagged parameters (%d bytes)",
517                                               size);
518
519   return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
520 }
521
522
523 /* ************************************************************************* */
524 /*            Add the subtree used to store WEP parameters                   */
525 /* ************************************************************************* */
526 static void
527 get_wep_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
528 {
529   proto_item *wep_fields;
530   proto_tree *wep_tree;
531   int crc_offset = size - 4;
532
533   wep_fields = proto_tree_add_text(tree, tvb, start, 4, "WEP parameters");
534
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);
537
538   proto_tree_add_uint (wep_tree, hf_wep_key, tvb, start + 3, 1,
539                        COOK_WEP_KEY (tvb_get_guint8 (tvb, start + 3)));
540
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));
544 }
545
546 /* ************************************************************************* */
547 /*              Dissect and add fixed mgmt fields to protocol tree           */
548 /* ************************************************************************* */
549 static void
550 add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
551 {
552   const guint8 *dataptr;
553   char out_buff[SHORT_STR];
554   guint16 capability;
555   proto_item *cap_item;
556   static proto_tree *cap_tree;
557   double temp_double;
558
559   switch (lfcode)
560     {
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",
565                 dataptr[7],
566                 dataptr[6],
567                 dataptr[5],
568                 dataptr[4],
569                 dataptr[3],
570                 dataptr[2],
571                 dataptr[1],
572                 dataptr[0]);
573
574       proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
575       break;
576
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]",
582                                     temp_double);
583       break;
584
585
586     case FIELD_CAP_INFO:
587       capability = tvb_get_letohs (tvb, offset);
588
589       cap_item = proto_tree_add_uint_format (tree, ff_capture, 
590                                              tvb, offset, 2,
591                                              capability,
592                                              "Capability Information: 0x%04X",
593                                              capability);
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,
596                               capability);
597       proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 1,
598                               capability);
599       proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 1,
600                               capability);
601       proto_tree_add_boolean (cap_tree, ff_cf_preamble, tvb, offset, 1,
602                               capability);
603       proto_tree_add_boolean (cap_tree, ff_cf_pbcc, tvb, offset, 1,
604                               capability);
605       proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 1,
606                               capability);
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));
610
611       else                      /* This is a STA */
612         proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
613                              ((capability & 0xC) >> 2));
614       break;
615
616     case FIELD_AUTH_ALG:
617       proto_tree_add_item (tree, ff_auth_alg, tvb, offset, 2, TRUE);
618       break;
619
620     case FIELD_AUTH_TRANS_SEQ:
621       proto_tree_add_item (tree, ff_auth_seq, tvb, offset, 2, TRUE);
622       break;
623
624     case FIELD_CURRENT_AP_ADDR:
625       proto_tree_add_item (tree, ff_current_ap, tvb, offset, 6, FALSE);
626       break;
627
628     case FIELD_LISTEN_IVAL:
629       proto_tree_add_item (tree, ff_listen_ival, tvb, offset, 2, TRUE);
630       break;
631
632     case FIELD_REASON_CODE:
633       proto_tree_add_item (tree, ff_reason, tvb, offset, 2, TRUE);
634       break;
635
636     case FIELD_ASSOC_ID:
637       proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE);
638       break;
639
640     case FIELD_STATUS_CODE:
641       proto_tree_add_item (tree, ff_status_code, tvb, offset, 2, TRUE);
642       break;
643     }
644 }
645
646
647 /* ************************************************************************* */
648 /*           Dissect and add tagged (optional) fields to proto tree          */
649 /* ************************************************************************* */
650 static int
651 add_tagged_field (proto_tree * tree, tvbuff_t * tvb, int offset)
652 {
653   const guint8 *tag_data_ptr;
654   guint32 tag_no, tag_len;
655   unsigned int i;
656   int n, ret;
657   char out_buff[SHORT_STR];
658
659
660   tag_no = tvb_get_guint8(tvb, offset);
661   tag_len = tvb_get_guint8(tvb, offset + 1);
662
663   tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
664
665
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)",
670                                   tag_no);
671
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;
676     }
677
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)))
681     {
682       proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
683                                   "Tag Number: %u (Reserved tag number)",
684                                   tag_no);
685
686       proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
687
688       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
689                              tag_len, "Not interpreted");
690       return (int) tag_len + 2;
691     }
692
693
694   switch (tag_no)
695     {
696
697
698     case TAG_SSID:
699       proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
700                                   "Tag Number: %u (SSID parameter set)",
701                                   tag_no);
702
703       proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
704
705       memset (out_buff, 0, SHORT_STR);
706
707       memcpy (out_buff, tag_data_ptr, (size_t) tag_len);
708       out_buff[tag_len + 1] = 0;
709
710       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
711                              tag_len, out_buff);
712       break;
713
714
715
716     case TAG_SUPP_RATES:
717       proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
718                                   "Tag Number: %u (Supported Rates)", tag_no);
719
720       proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
721
722       memset (out_buff, 0, SHORT_STR);
723       strcpy (out_buff, "Supported rates: ");
724       n = strlen (out_buff);
725
726       for (i = 0; i < tag_len && n < SHORT_STR; i++)
727         {
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)" : "");
731             if (ret == -1) {
732               /* Some versions of snprintf return -1 if they'd truncate
733                  the output. */
734               break;
735             }
736             n += ret;
737         }
738       if (n < SHORT_STR)
739         snprintf (out_buff + n, SHORT_STR - n, "[Mbit/sec]");
740
741       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
742                              tag_len, out_buff);
743       break;
744
745
746
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)",
750                                   tag_no);
751
752       proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
753       memset (out_buff, 0, SHORT_STR);
754
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]);
759
760       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
761                              tag_len, out_buff);
762       break;
763
764
765
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)",
769                                   tag_no);
770
771       proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
772       memset (out_buff, 0, SHORT_STR);
773
774       snprintf (out_buff, SHORT_STR, "Current Channel: %u", tag_data_ptr[0]);
775       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
776                              tag_len, out_buff);
777       break;
778
779
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)",
783                                   tag_no);
784
785       proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
786       memset (out_buff, 0, SHORT_STR);
787
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));
792
793       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
794                              tag_len, out_buff);
795       break;
796
797
798     case TAG_TIM:
799       proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
800                                   "Tag Number: %u ((TIM) Traffic Indication Map)",
801                                   tag_no);
802
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],
808                 tag_data_ptr[2]);
809       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
810                              tag_len, out_buff);
811       break;
812
813
814
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)",
818                                   tag_no);
819
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));
824
825       proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
826                              tag_len, out_buff);
827       break;
828
829
830
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);
834
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,
839                              tag_len, out_buff);
840
841       break;
842
843     default:
844       return 0;
845     }
846
847   return tag_len + 2;
848 }
849
850 /* ************************************************************************* */
851 /*                     Dissect 802.11 management frame                       */
852 /* ************************************************************************* */
853 static void
854 dissect_ieee80211_mgt (guint16 fcf, tvbuff_t * tvb, packet_info * pinfo,
855         proto_tree * tree)
856 {
857   proto_item *ti = NULL;
858   proto_tree *mgt_tree;
859   proto_tree *fixed_tree;
860   proto_tree *tagged_tree;
861   guint32 next_idx;
862   guint32 next_len;
863   int tagged_parameter_tree_len;
864
865   CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
866
867   if (tree)
868     {
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);
871
872       switch (COMPOSE_FRAME_TYPE(fcf))
873         {
874
875         case MGT_ASSOC_REQ:
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);
879
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);
885
886           while (tagged_parameter_tree_len > 0) {
887             if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
888               break;
889             next_idx +=next_len;
890             tagged_parameter_tree_len -= next_len;
891           }
892           break;
893
894
895         case MGT_ASSOC_RESP:
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);
900
901           next_idx = 6; /* Size of fixed fields */
902
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);
907
908           while (tagged_parameter_tree_len > 0) {
909             if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
910               break;
911             next_idx +=next_len;
912             tagged_parameter_tree_len -= next_len;
913           }
914           break;
915
916
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);
922
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);
928
929           while (tagged_parameter_tree_len > 0) {
930             if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
931               break;
932             next_idx +=next_len;
933             tagged_parameter_tree_len -= next_len;
934           }
935           break;
936
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);
942
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);
948
949           while (tagged_parameter_tree_len > 0) {
950             if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
951               break;
952             next_idx +=next_len;
953             tagged_parameter_tree_len -= next_len;
954           }
955           break;
956
957
958         case MGT_PROBE_REQ:
959           next_idx = 0;
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);
964
965           while (tagged_parameter_tree_len > 0) {
966             if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
967               break;
968             next_idx +=next_len;
969             tagged_parameter_tree_len -= next_len;
970           }
971           break;
972
973
974         case MGT_PROBE_RESP:
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);
979
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);
985
986           while (tagged_parameter_tree_len > 0) {
987             if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
988               break;
989             next_idx +=next_len;
990             tagged_parameter_tree_len -= next_len;
991           }
992           break;
993
994
995         case MGT_BEACON:                /* Dissect protocol payload fields  */
996           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
997
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);
1001
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);
1007
1008           while (tagged_parameter_tree_len > 0) {
1009             if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
1010               break;
1011             next_idx +=next_len;
1012             tagged_parameter_tree_len -= next_len;
1013           }
1014           break;
1015
1016
1017         case MGT_ATIM:
1018           break;
1019
1020
1021         case MGT_DISASS:
1022           fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
1023           add_fixed_field (fixed_tree, tvb, 0, FIELD_REASON_CODE);
1024           break;
1025
1026
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);
1032
1033           next_idx = 6; /* Size of fixed fields */
1034
1035           tagged_parameter_tree_len =
1036                   tvb_reported_length_remaining(tvb, next_idx);
1037           if (tagged_parameter_tree_len != 0)
1038             {
1039               tagged_tree = get_tagged_parameter_tree (mgt_tree,
1040                                                        tvb,
1041                                                        next_idx,
1042                                                        tagged_parameter_tree_len);
1043
1044               while (tagged_parameter_tree_len > 0) {
1045                 if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
1046                   break;
1047                 next_idx +=next_len;
1048                 tagged_parameter_tree_len -= next_len;
1049               }
1050             }
1051           break;
1052
1053
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);
1057           break;
1058         }
1059     }
1060 }
1061
1062 static void
1063 set_src_addr_cols(packet_info *pinfo, const guint8 *addr, char *type)
1064 {
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);
1071 }
1072
1073 static void
1074 set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, char *type)
1075 {
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);
1082 }
1083
1084 static void
1085 show_fragments(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1086                fragment_data *fd_head)
1087 {
1088   guint32 offset;
1089   fragment_data *fd;
1090   proto_tree *ft;
1091   proto_item *fi;
1092
1093   fi = proto_tree_add_item(tree, hf_fragments, tvb, 0, -1, FALSE);
1094   ft = proto_item_add_subtree(fi, ett_fragments);
1095   offset = 0;
1096   for (fd = fd_head->next; fd != NULL; fd = fd->next){
1097     if (fd->flags & (FD_OVERLAP|FD_OVERLAPCONFLICT|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
1098       /*
1099        * This fragment has some flags set; create a subtree for it and
1100        * display the flags.
1101        */
1102       proto_tree *fet = NULL;
1103       proto_item *fei = NULL;
1104       int hf;
1105
1106       if (fd->flags & (FD_OVERLAPCONFLICT|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
1107         hf = hf_fragment_error;
1108       } else {
1109         hf = hf_fragment;
1110       }
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,
1119                                TRUE);
1120       }
1121       if (fd->flags&FD_MULTIPLETAILS) {
1122         proto_tree_add_boolean(fet, hf_fragment_multiple_tails, tvb, 0, 0,
1123                                TRUE);
1124       }
1125       if (fd->flags&FD_TOOLONGFRAGMENT) {
1126         proto_tree_add_boolean(fet, hf_fragment_too_long_fragment, tvb, 0, 0,
1127                                TRUE);
1128       }
1129     } else {
1130       /*
1131        * Nothing of interest for this fragment.
1132        */
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);
1136     }
1137     offset += fd->len;
1138   }
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]");
1142   }
1143 }
1144
1145 /* ************************************************************************* */
1146 /*                          Dissect 802.11 frame                             */
1147 /* ************************************************************************* */
1148 static void
1149 dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
1150                           proto_tree * tree, gboolean fixed_length_header,
1151                           gboolean has_radio_information)
1152 {
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;
1164   guint16 hdr_len;
1165   gboolean save_fragmented;
1166   tvbuff_t *volatile next_tvb;
1167   guint32 addr_type;
1168   volatile gboolean is_802_2;
1169
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);
1174
1175   fcf = tvb_get_letohs (tvb, 0);
1176   if (fixed_length_header)
1177     hdr_len = DATA_LONG_HDR_LEN;
1178   else
1179     hdr_len = find_header_length (fcf);
1180   frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
1181
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)"));
1186
1187   flags = COOK_FLAGS (fcf);
1188   more_frags = HAVE_FRAGMENTS (flags);
1189
1190   /* Add the radio information, if present, and the FC to the current tree */
1191   if (tree)
1192     {
1193       ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
1194                                            "IEEE 802.11");
1195       hdr_tree = proto_item_add_subtree (ti, ett_80211);
1196
1197       if (has_radio_information) {
1198         proto_tree_add_uint_format(hdr_tree, hf_data_rate,
1199                                    tvb, 0, 0,
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);
1203
1204         proto_tree_add_uint(hdr_tree, hf_channel,
1205                             tvb, 0, 0,
1206                             pinfo->pseudo_header->ieee_802_11.channel);
1207
1208         proto_tree_add_uint_format(hdr_tree, hf_signal_strength,
1209                                    tvb, 0, 0,
1210                                    pinfo->pseudo_header->ieee_802_11.signal_level,
1211                                    "Signal Strength: %u%%",
1212                                    pinfo->pseudo_header->ieee_802_11.signal_level);
1213       }
1214
1215       proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
1216                            tvb, 0, 1,
1217                            frame_type_subtype);
1218
1219       fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb, 0, 2,
1220                                             fcf,
1221                                             "Frame Control: 0x%04X",
1222                                             fcf);
1223
1224       fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
1225
1226
1227       proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb, 0, 1,
1228                            COOK_PROT_VERSION (fcf));
1229
1230       proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb, 0, 1,
1231                            COOK_FRAME_TYPE (fcf));
1232
1233       proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
1234                            tvb, 0, 1,
1235                            COOK_FRAME_SUBTYPE (fcf));
1236
1237       flag_item =
1238         proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb, 1, 1,
1239                                     flags, "Flags: 0x%X", flags);
1240
1241       flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
1242
1243       proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb, 1, 1,
1244                            COOK_DS_STATUS (flags));
1245
1246       proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb, 1, 1,
1247                               flags);
1248
1249       proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb, 1, 1, flags);
1250
1251       proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb, 1, 1, flags);
1252
1253       proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb, 1, 1,
1254                               flags);
1255
1256       proto_tree_add_boolean (flag_tree, hf_fc_wep, tvb, 1, 1, flags);
1257
1258       proto_tree_add_boolean (flag_tree, hf_fc_order, tvb, 1, 1, flags);
1259
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)));
1263      
1264       else
1265           proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
1266                                tvb_get_letohs (tvb, 2));
1267     }
1268
1269   /*
1270    * Decode the part of the frame header that isn't the same for all
1271    * frame types.
1272    */
1273   seq_control = 0;
1274   frag_number = 0;
1275   seq_number = 0;
1276
1277   switch (frame_type_subtype)
1278     {
1279
1280     case MGT_ASSOC_REQ:
1281     case MGT_ASSOC_RESP:
1282     case MGT_REASSOC_REQ:
1283     case MGT_REASSOC_RESP:
1284     case MGT_PROBE_REQ:
1285     case MGT_PROBE_RESP:
1286     case MGT_BEACON:
1287     case MGT_ATIM:
1288     case MGT_DISASS:
1289     case MGT_AUTHENTICATION:
1290     case MGT_DEAUTHENTICATION:
1291       /*
1292        * All management frame types have the same header.
1293        */
1294       src = tvb_get_ptr (tvb, 10, 6);
1295       dst = tvb_get_ptr (tvb, 4, 6);
1296
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);
1301
1302       seq_control = tvb_get_letohs(tvb, 22);
1303       frag_number = COOK_FRAGMENT_NUMBER(seq_control);
1304       seq_number = COOK_SEQUENCE_NUMBER(seq_control);
1305
1306       if (tree)
1307         {
1308           proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6, dst);
1309
1310           proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6, src);
1311
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);
1315
1316           proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
1317                                 tvb_get_ptr (tvb, 16, 6));
1318
1319           proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1320                                frag_number);
1321
1322           proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1323                                seq_number);
1324         }
1325       break;
1326
1327
1328     case CTRL_PS_POLL:
1329       src = tvb_get_ptr (tvb, 10, 6);
1330       dst = tvb_get_ptr (tvb, 4, 6);
1331
1332       set_src_addr_cols(pinfo, src, "BSSID");
1333       set_dst_addr_cols(pinfo, dst, "BSSID");
1334
1335       if (tree)
1336         {
1337           proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6, dst);
1338
1339           proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
1340         }
1341       break;
1342
1343
1344     case CTRL_RTS:
1345       src = tvb_get_ptr (tvb, 10, 6);
1346       dst = tvb_get_ptr (tvb, 4, 6);
1347
1348       set_src_addr_cols(pinfo, src, "TA");
1349       set_dst_addr_cols(pinfo, dst, "RA");
1350
1351       if (tree)
1352         {
1353           proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1354
1355           proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, src);
1356         }
1357       break;
1358
1359
1360     case CTRL_CTS:
1361       dst = tvb_get_ptr (tvb, 4, 6);
1362
1363       set_dst_addr_cols(pinfo, dst, "RA");
1364
1365       if (tree)
1366           proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1367       break;
1368
1369
1370     case CTRL_ACKNOWLEDGEMENT:
1371       dst = tvb_get_ptr (tvb, 4, 6);
1372
1373       set_dst_addr_cols(pinfo, dst, "RA");
1374
1375       if (tree)
1376         proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1377       break;
1378
1379
1380     case CTRL_CFP_END:
1381       src = tvb_get_ptr (tvb, 10, 6);
1382       dst = tvb_get_ptr (tvb, 4, 6);
1383
1384       set_src_addr_cols(pinfo, src, "BSSID");
1385       set_dst_addr_cols(pinfo, dst, "RA");
1386
1387       if (tree)
1388         {
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);
1391         }
1392       break;
1393
1394
1395     case CTRL_CFP_ENDACK:
1396       src = tvb_get_ptr (tvb, 10, 6);
1397       dst = tvb_get_ptr (tvb, 4, 6);
1398
1399       set_src_addr_cols(pinfo, src, "BSSID");
1400       set_dst_addr_cols(pinfo, dst, "RA");
1401
1402       if (tree)
1403         {
1404           proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, dst);
1405
1406           proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
1407         }
1408       break;
1409
1410
1411     case DATA:
1412     case DATA_NULL_FUNCTION:
1413     case DATA_CF_ACK:
1414     case DATA_CF_ACK_NOD:
1415     case DATA_CF_POLL:
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);
1420
1421       /* In order to show src/dst address we must always do the following */
1422       switch (addr_type)
1423         {
1424
1425         case DATA_ADDR_T1:
1426           src = tvb_get_ptr (tvb, 10, 6);
1427           dst = tvb_get_ptr (tvb, 4, 6);
1428           break;
1429
1430
1431         case DATA_ADDR_T2:
1432           src = tvb_get_ptr (tvb, 16, 6);
1433           dst = tvb_get_ptr (tvb, 4, 6);
1434           break;
1435
1436
1437         case DATA_ADDR_T3:
1438           src = tvb_get_ptr (tvb, 10, 6);
1439           dst = tvb_get_ptr (tvb, 16, 6);
1440           break;
1441
1442
1443         case DATA_ADDR_T4:
1444           src = tvb_get_ptr (tvb, 24, 6);
1445           dst = tvb_get_ptr (tvb, 16, 6);
1446           break;
1447         }
1448
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);
1453
1454       seq_control = tvb_get_letohs(tvb, 22);
1455       frag_number = COOK_FRAGMENT_NUMBER(seq_control);
1456       seq_number = COOK_SEQUENCE_NUMBER(seq_control);
1457
1458       /* Now if we have a tree we start adding stuff */
1459       if (tree)
1460         {
1461
1462
1463           switch (addr_type)
1464             {
1465
1466             case DATA_ADDR_T1:
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,
1472                                    frag_number);
1473               proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1474                                    seq_number);
1475
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);
1479               break;
1480               
1481               
1482             case DATA_ADDR_T2:
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,
1488                                    frag_number);
1489               proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1490                                    seq_number);
1491
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);
1495               break;
1496    
1497
1498             case DATA_ADDR_T3:
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);
1503
1504               proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
1505                                    frag_number);
1506               proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1507                                    seq_number);
1508
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);
1512               break;
1513               
1514
1515             case DATA_ADDR_T4:
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,
1522                                    frag_number);
1523               proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
1524                                    seq_number);
1525               proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6, src);
1526
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);
1530               break;
1531             }
1532
1533         }
1534       break;
1535     }
1536
1537   /*
1538    * Only management and data frames have a body, so we don't have
1539    * anything more to do for other types of frames.
1540    */
1541   switch (COOK_FRAME_TYPE (fcf))
1542     {
1543
1544     case MGT_FRAME:
1545       break;
1546
1547     case DATA_FRAME:
1548       /*
1549        * No-data frames don't have a body.
1550        */
1551       switch (frame_type_subtype)
1552         {
1553
1554         case DATA_NULL_FUNCTION:
1555         case DATA_CF_ACK_NOD:
1556         case DATA_CF_POLL_NOD:
1557         case DATA_CF_ACK_POLL_NOD:
1558           return;
1559         }
1560         break;
1561
1562     default:
1563       return;
1564     }
1565
1566   /*
1567    * For WEP-encrypted frames, dissect the WEP parameters and
1568    * display the payload as data.
1569    *
1570    * XXX - allow the key to be specified, and, if it is, decrypt
1571    * the payload and dissect it?
1572    */
1573   if (IS_WEP(COOK_FLAGS(fcf)))
1574     {
1575       int pkt_len = tvb_reported_length (tvb);
1576       int cap_len = tvb_length (tvb);
1577
1578       if (tree)
1579         {
1580           get_wep_parameter_tree (tree, tvb, hdr_len, pkt_len);
1581           pkt_len -= hdr_len + 4;
1582           cap_len -= hdr_len + 4;
1583
1584           /*
1585            * OK, pkt_len and cap_len have had the length of the 802.11
1586            * header and WEP parameters subtracted.
1587            *
1588            * If there's anything left:
1589            *
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;
1593            *
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
1597            *    crc_len;
1598            *
1599            *    otherwise, (i.e., we captured none of the WEP CRC),
1600            *    leave cap_len alone;
1601            *
1602            * and subtract the length of the WEP CRC from pkt_len.
1603            */
1604           if (cap_len >= pkt_len)
1605             cap_len -= 4;
1606           else if ((pkt_len - cap_len) >= 1 && (pkt_len - cap_len) <= 3)
1607             cap_len -= 4 - (pkt_len - cap_len);
1608           pkt_len -= 4;
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);
1611         }
1612         return;
1613     }
1614
1615   /*
1616    * Now dissect the body of a non-WEP-encrypted frame.
1617    */
1618
1619   /*
1620    * Do defragmentation if "wlan_defragment" is true.
1621    *
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
1629    * number.
1630    *
1631    * (This could get some false positives if we really *did* only
1632    * capture the last fragment of a fragmented packet, but that's
1633    * life.)
1634    */
1635   save_fragmented = pinfo->fragmented;
1636   if (wlan_defragment && (more_frags || frag_number != 0)) {
1637     fragment_data *fd_head;
1638
1639     /*
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
1643      * if it's done.
1644      */
1645     fd_head = fragment_add_seq_check(tvb, hdr_len, pinfo, seq_number,
1646                                      wlan_fragment_table,
1647                                      wlan_reassembled_table,
1648                                      frag_number,
1649                                      tvb_length_remaining(tvb, hdr_len),
1650                                      more_frags);
1651     if (fd_head != NULL) {
1652       /*
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
1656        * packets.
1657        *
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.
1662        */
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");
1667
1668         /* Show all fragments. */
1669         show_fragments(next_tvb, pinfo, hdr_tree, fd_head);
1670       } else {
1671         /*
1672          * Not fragmented, really.
1673          * Show it as a regular frame.
1674          */
1675         next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
1676       }
1677
1678       /* It's not fragmented. */
1679       pinfo->fragmented = FALSE;
1680     } else {
1681       /* We don't have the complete reassembled payload. */
1682       next_tvb = NULL;
1683     }
1684   } else {
1685     /*
1686      * If this is the first fragment, dissect its contents, otherwise
1687      * just show it as a fragment.
1688      */
1689     if (frag_number != 0) {
1690       /* Not the first fragment - don't dissect it. */
1691       next_tvb = NULL;
1692     } else {
1693       /* First fragment, or not fragmented.  Dissect what we have here. */
1694
1695       /* Get a tvbuff for the payload. */
1696       next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
1697
1698       /*
1699        * If this is the first fragment, but not the only fragment,
1700        * tell the next protocol that.
1701        */
1702       if (more_frags)
1703         pinfo->fragmented = TRUE;
1704       else
1705         pinfo->fragmented = FALSE;
1706     }
1707   }
1708
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;
1716     return;
1717   }
1718
1719   switch (COOK_FRAME_TYPE (fcf))
1720     {
1721
1722     case MGT_FRAME:
1723       dissect_ieee80211_mgt (fcf, next_tvb, pinfo, tree);
1724       break;
1725
1726
1727     case DATA_FRAME:
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.
1733
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
1738          as an IPX frame. */
1739       is_802_2 = TRUE;
1740       TRY {
1741         if (tvb_get_ntohs(next_tvb, 0) == 0xffff)
1742           is_802_2 = FALSE;
1743       }
1744       CATCH2(BoundsError, ReportedBoundsError) {
1745             ; /* do nothing */
1746
1747       }
1748       ENDTRY;
1749
1750       if (is_802_2)
1751         call_dissector(llc_handle, next_tvb, pinfo, tree);
1752       else
1753         call_dissector(ipx_handle, next_tvb, pinfo, tree);
1754       break;
1755     }
1756   pinfo->fragmented = save_fragmented;
1757 }
1758
1759 /*
1760  * Dissect 802.11 with a variable-length link-layer header.
1761  */
1762 static void
1763 dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1764 {
1765   dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE);
1766 }
1767
1768 /*
1769  * Dissect 802.11 with a variable-length link-layer header and a pseudo-
1770  * header containing radio information.
1771  */
1772 static void
1773 dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1774 {
1775   dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE);
1776 }
1777
1778 /*
1779  * Dissect 802.11 with a fixed-length link-layer header (padded to the
1780  * maximum length).
1781  */
1782 static void
1783 dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1784 {
1785   dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE);
1786 }
1787
1788 static void
1789 wlan_defragment_init(void)
1790 {
1791   fragment_table_init(&wlan_fragment_table);
1792   reassembled_table_init(&wlan_reassembled_table);
1793 }
1794
1795 void
1796 proto_register_wlan (void)
1797 {
1798   static const value_string frame_type[] = {
1799     {MGT_FRAME,     "Management frame"},
1800     {CONTROL_FRAME, "Control frame"},
1801     {DATA_FRAME,    "Data frame"},
1802     {0,             NULL}
1803   };
1804
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)"},
1810     {0, NULL}
1811   };
1812
1813   static const true_false_string tods_flag = {
1814     "TO DS: Should be false",
1815     "Not used"
1816   };
1817
1818   static const true_false_string fromds_flag = {
1819     "FROM DS: Should be false",
1820     "Not used"
1821   };
1822
1823   static const true_false_string more_frags = {
1824     "More fragments follow",
1825     "This is the last fragment"
1826   };
1827
1828   static const true_false_string retry_flags = {
1829     "Frame is being retransmitted",
1830     "Frame is not being retransmitted"
1831   };
1832
1833   static const true_false_string pm_flags = {
1834     "STA will go to sleep",
1835     "STA will stay up"
1836   };
1837
1838   static const true_false_string md_flags = {
1839     "Data is buffered for STA at AP",
1840     "No data buffered"
1841   };
1842
1843   static const true_false_string wep_flags = {
1844     "WEP is enabled",
1845     "WEP is disabled"
1846   };
1847
1848   static const true_false_string order_flags = {
1849     "Strictly ordered",
1850     "Not strictly ordered"
1851   };
1852
1853   static const true_false_string cf_ess_flags = {
1854     "Transmitter is an AP",
1855     "Transmitter is a STA"
1856   };
1857
1858
1859   static const true_false_string cf_privacy_flags = {
1860     "AP/STA can support WEP",
1861     "AP/STA cannot support WEP"
1862   };
1863
1864   static const true_false_string cf_preamble_flags = {
1865     "Short preamble allowed",
1866     "Short preamble not allowed"
1867   };
1868
1869   static const true_false_string cf_pbcc_flags = {
1870     "PBCC modulation allowed",
1871     "PBCC modulation not allowed"
1872   };
1873
1874   static const true_false_string cf_agility_flags = {
1875     "Channel agility in use",
1876     "Channel agility not in use"
1877   };
1878
1879
1880   static const true_false_string cf_ibss_flags = {
1881     "Transmitter belongs to an IBSS",
1882     "Transmitter belongs to a BSS"
1883   };
1884
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"},
1892     {0, NULL}
1893   };
1894
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"},
1899     {0x03, "Reserved"},
1900     {0, NULL}
1901   };
1902
1903
1904   static const value_string auth_alg[] = {
1905     {0x00, "Open System"},
1906     {0x01, "Shared key"},
1907     {0, NULL}
1908   };
1909
1910   static const value_string reason_codes[] = {
1911     {0x00, "Reserved"},
1912     {0x01, "Unspecified reason"},
1913     {0x02, "Previous authentication no longer valid"},
1914     {0x03, "Deauthenticated because sending STA is leaving (has left) "
1915      "IBSS or ESS"},
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"},
1924     {0x00, NULL}
1925   };
1926
1927
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 "
1936      "standard"},
1937
1938     {0x0D, "Responding station does not support the specified authentication "
1939      "algorithm"},
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"},
1949     {0x00, NULL}
1950   };
1951
1952   static hf_register_info hf[] = {
1953     {&hf_data_rate,
1954      {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
1955       "Data rate (.5 Mb/s units)", HFILL }},
1956
1957     {&hf_channel,
1958      {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
1959       "Radio channel", HFILL }},
1960
1961     {&hf_signal_strength,
1962      {"Signal Strength", "wlan.signal_strength", FT_UINT8, BASE_DEC, NULL, 0,
1963       "Signal strength (percentage)", HFILL }},
1964
1965     {&hf_fc_field,
1966      {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
1967       "MAC Frame control", HFILL }},
1968
1969     {&hf_fc_proto_version,
1970      {"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
1971       "MAC Protocol version", HFILL }}, /* 0 */
1972
1973     {&hf_fc_frame_type,
1974      {"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, VALS(frame_type), 0,
1975       "Frame type", HFILL }},
1976
1977     {&hf_fc_frame_subtype,
1978      {"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
1979       "Frame subtype", HFILL }},        /* 2 */
1980
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 }},
1984
1985     {&hf_fc_flags,
1986      {"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
1987       "Protocol flags", HFILL }},
1988
1989     {&hf_fc_data_ds,
1990      {"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, VALS (&tofrom_ds), 0,
1991       "Data-frame DS-traversal status", HFILL }},       /* 3 */
1992
1993     {&hf_fc_to_ds,
1994      {"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), FLAG_TO_DS,
1995       "To DS flag", HFILL }},           /* 4 */
1996
1997     {&hf_fc_from_ds,
1998      {"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), FLAG_FROM_DS,
1999       "From DS flag", HFILL }},         /* 5 */
2000
2001     {&hf_fc_more_frag,
2002      {"More Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), FLAG_MORE_FRAGMENTS,
2003       "More Fragments flag", HFILL }},  /* 6 */
2004
2005     {&hf_fc_retry,
2006      {"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), FLAG_RETRY,
2007       "Retransmission flag", HFILL }},
2008
2009     {&hf_fc_pwr_mgt,
2010      {"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), FLAG_POWER_MGT,
2011       "Power management status", HFILL }},
2012
2013     {&hf_fc_more_data,
2014      {"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
2015       "More data flag", HFILL }},
2016
2017     {&hf_fc_wep,
2018      {"WEP flag", "wlan.fc.wep", FT_BOOLEAN, 8, TFS (&wep_flags), FLAG_WEP,
2019       "WEP flag", HFILL }},
2020
2021     {&hf_fc_order,
2022      {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
2023       "Strictly ordered flag", HFILL }},
2024
2025     {&hf_assoc_id,
2026      {"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
2027       "Association-ID field", HFILL }},
2028
2029     {&hf_did_duration,
2030      {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
2031       "Duration field", HFILL }},
2032
2033     {&hf_addr_da,
2034      {"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
2035       "Destination Hardware Address", HFILL }},
2036
2037     {&hf_addr_sa,
2038      {"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
2039       "Source Hardware Address", HFILL }},
2040
2041     { &hf_addr,
2042       {"Source or Destination address", "wlan.addr", FT_ETHER, BASE_NONE, NULL, 0,
2043        "Source or Destination Hardware Address", HFILL }},
2044
2045     {&hf_addr_ra,
2046      {"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
2047       "Receiving Station Hardware Address", HFILL }},
2048
2049     {&hf_addr_ta,
2050      {"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
2051       "Transmitting Station Hardware Address", HFILL }},
2052
2053     {&hf_addr_bssid,
2054      {"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
2055       "Basic Service Set ID", HFILL }},
2056
2057     {&hf_frag_number,
2058      {"Fragment number", "wlan.frag", FT_UINT16, BASE_DEC, NULL, 0,
2059       "Fragment number", HFILL }},
2060
2061     {&hf_seq_number,
2062      {"Sequence number", "wlan.seq", FT_UINT16, BASE_DEC, NULL, 0,
2063       "Sequence number", HFILL }},
2064
2065     {&hf_fcs,
2066      {"Frame Check Sequence (not verified)", "wlan.fcs", FT_UINT32, BASE_HEX,
2067       NULL, 0, "", HFILL }},
2068
2069     {&hf_fragment_overlap,
2070       {"Fragment overlap", "wlan.fragment.overlap", FT_BOOLEAN, BASE_NONE,
2071        NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
2072
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 }},
2077
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 }},
2082
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 }},
2087
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 }},
2092
2093     {&hf_fragment,
2094       {"802.11 Fragment", "wlan.fragment", FT_NONE, BASE_NONE, NULL, 0x0,
2095        "802.11 Fragment", HFILL }},
2096
2097     {&hf_fragments,
2098       {"802.11 Fragments", "wlan.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
2099        "WTP Fragments", HFILL }},
2100
2101     {&hf_wep_iv,
2102      {"Initialization Vector", "wlan.wep.iv", FT_UINT24, BASE_HEX, NULL, 0,
2103       "Initialization Vector", HFILL }},
2104
2105     {&hf_wep_key,
2106      {"Key", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
2107       "Key", HFILL }},
2108
2109     {&hf_wep_crc,
2110      {"WEP CRC (not verified)", "wlan.wep.crc", FT_UINT32, BASE_HEX, NULL, 0,
2111       "WEP CRC", HFILL }},
2112   };
2113
2114   static hf_register_info ff[] = {
2115     {&ff_timestamp,
2116      {"Timestamp", "wlan_mgt.fixed.timestamp", FT_STRING, BASE_NONE,
2117       NULL, 0, "", HFILL }},
2118
2119     {&ff_auth_alg,
2120      {"Authentication Algorithm", "wlan_mgt.fixed.auth.alg",
2121       FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, "", HFILL }},
2122
2123     {&ff_beacon_interval,
2124      {"Beacon Interval", "wlan_mgt.fixed.beacon", FT_DOUBLE, BASE_DEC, NULL, 0,
2125       "", HFILL }},
2126
2127     {&hf_fixed_parameters,
2128      {"Fixed parameters", "wlan_mgt.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
2129       "", HFILL }},
2130
2131     {&hf_tagged_parameters,
2132      {"Tagged parameters", "wlan_mgt.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
2133       "", HFILL }},
2134
2135     {&ff_capture,
2136      {"Capabilities", "wlan_mgt.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
2137       "Capability information", HFILL }},
2138
2139     {&ff_cf_sta_poll,
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 }},
2143
2144     {&ff_cf_ap_poll,
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 }},
2148
2149     {&ff_cf_ess,
2150      {"ESS capabilities", "wlan_mgt.fixed.capabilities.ess",
2151       FT_BOOLEAN, 8, TFS (&cf_ess_flags), 0x0001, "ESS capabilities", HFILL }},
2152
2153
2154     {&ff_cf_ibss,
2155      {"IBSS status", "wlan_mgt.fixed.capabilities.ibss",
2156       FT_BOOLEAN, 8, TFS (&cf_ibss_flags), 0x0002, "IBSS participation", HFILL }},
2157
2158     {&ff_cf_privacy,
2159      {"Privacy", "wlan_mgt.fixed.capabilities.privacy",
2160       FT_BOOLEAN, 8, TFS (&cf_privacy_flags), 0x0010, "WEP support", HFILL }},
2161
2162     {&ff_cf_preamble,
2163      {"Short Preamble", "wlan_mgt.fixed.capabilities.preamble",
2164       FT_BOOLEAN, 8, TFS (&cf_preamble_flags), 0x0020, "Short Preamble", HFILL }},
2165
2166     {&ff_cf_pbcc,
2167      {"PBCC", "wlan_mgt.fixed.capabilities.pbcc",
2168       FT_BOOLEAN, 8, TFS (&cf_pbcc_flags), 0x0040, "PBCC Modulation", HFILL }},
2169
2170     {&ff_cf_agility,
2171      {"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
2172       FT_BOOLEAN, 8, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
2173
2174     {&ff_auth_seq,
2175      {"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
2176       FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
2177
2178     {&ff_assoc_id,
2179      {"Association ID", "wlan_mgt.fixed.aid",
2180       FT_UINT16, BASE_HEX, NULL, 0, "Association ID", HFILL }},
2181
2182     {&ff_listen_ival,
2183      {"Listen Interval", "wlan_mgt.fixed.listen_ival",
2184       FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval", HFILL }},
2185
2186     {&ff_current_ap,
2187      {"Current AP", "wlan_mgt.fixed.current_ap",
2188       FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP", HFILL }},
2189
2190     {&ff_reason,
2191      {"Reason code", "wlan_mgt.fixed.reason_code",
2192       FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
2193       "Reason for unsolicited notification", HFILL }},
2194
2195     {&ff_status_code,
2196      {"Status code", "wlan_mgt.fixed.status_code",
2197       FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
2198       "Status of requested event", HFILL }},
2199
2200     {&tag_number,
2201      {"Tag", "wlan_mgt.tag.number",
2202       FT_UINT16, BASE_DEC, NULL, 0,
2203       "Element ID", HFILL }},
2204
2205     {&tag_length,
2206      {"Tag length", "wlan_mgt.tag.length",
2207       FT_UINT16, BASE_DEC, NULL, 0, "Length of tag", HFILL }},
2208
2209     {&tag_interpretation,
2210      {"Tag interpretation", "wlan_mgt.tag.interpretation",
2211       FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }}
2212
2213   };
2214
2215   static gint *tree_array[] = {
2216     &ett_80211,
2217     &ett_fc_tree,
2218     &ett_proto_flags,
2219     &ett_fragments,
2220     &ett_fragment,
2221     &ett_80211_mgt,
2222     &ett_fixed_parameters,
2223     &ett_tagged_parameters,
2224     &ett_wep_parameters,
2225     &ett_cap_tree,
2226   };
2227   module_t *wlan_module;
2228
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));
2236
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);
2240
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",
2246         &wlan_defragment);
2247 }
2248
2249 void
2250 proto_reg_handoff_wlan(void)
2251 {
2252   dissector_handle_t ieee80211_handle;
2253   dissector_handle_t ieee80211_radio_handle;
2254
2255   /*
2256    * Get handles for the LLC and IPX dissectors.
2257    */
2258   llc_handle = find_dissector("llc");
2259   ipx_handle = find_dissector("ipx");
2260   data_handle = find_dissector("data");
2261
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,
2265                                                    proto_wlan);
2266   dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
2267                 ieee80211_radio_handle);
2268 }