2000-11-15 05:42:35 +00:00
|
|
|
/* packet-ieee80211.c
|
|
|
|
* Routines for Wireless LAN (IEEE 802.11) dissection
|
|
|
|
* Copyright 2000, Axis Communications AB
|
|
|
|
* Inquiries/bugreports should be sent to Johan.Jorgensen@axis.com
|
|
|
|
*
|
2001-04-20 20:34:31 +00:00
|
|
|
* $Id: packet-ieee80211.c,v 1.17 2001/04/20 20:34:28 guy Exp $
|
2000-11-15 05:42:35 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
2001-04-20 20:34:31 +00:00
|
|
|
* By Gerald Combs <gerald@ethereal.com>
|
2000-11-15 05:42:35 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
* Copied from README.developer
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
# include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
# include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef NEED_SNPRINTF_H
|
|
|
|
# ifdef HAVE_STDARG_H
|
|
|
|
# include <stdarg.h>
|
|
|
|
# else
|
|
|
|
# include <varargs.h>
|
|
|
|
# endif
|
|
|
|
# include "snprintf.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <glib.h>
|
Move the table of bit-swapped byte values to "epan/bitswap.c", and
declare it, and define a "BIT_SWAP" macro that uses it, in
"epan/bitswap.h".
Use that macro to bit-swap bytes in the IEEE 802.11 dissector, rather
than the macro that was used (said macro used GCCisms and didn't compile
on Windows).
Make an "init_plugin()" routine to enable a plugin and call its init
routine, and call it from "check_plugin_status()" and
"plugins_enable_cb()", rather than having very similar code in two
places; "patable" is now part of libethereal, and, at least on Windows,
attempts to refer to it from "libui" failed. Make "patable" static to
"epan/plugins.c". (This may still not work, as now "libui" is calling a
routine in "libethereal"; if that fails, perhaps it's time to get rid of
the "enable/disable plugins" stuff completely, as new-style plugins, at
least, register themselves as protocols and should be controllable from
the "Edit->Protocols" window just as built-in dissectors are.)
svn path=/trunk/; revision=2649
2000-11-15 09:37:53 +00:00
|
|
|
#include "bitswap.h"
|
2000-11-15 05:42:35 +00:00
|
|
|
#include "proto.h"
|
|
|
|
#include "packet.h"
|
|
|
|
#include "packet-llc.h"
|
|
|
|
#include "packet-ieee80211.h"
|
2001-04-17 06:43:21 +00:00
|
|
|
#include "etypes.h"
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Miscellaneous Constants */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
#define SHORT_STR 128
|
|
|
|
#define MGT_FRAME_LEN 24
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Define some very useful macros that are used to analyze frame types etc. */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
#define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+((x & 0xF0) >> 4)) /* Create key to (sub)type */
|
|
|
|
#define COOK_PROT_VERSION(x) ((x & 0x3))
|
|
|
|
#define COOK_FRAME_TYPE(x) ((x & 0xC) >> 2)
|
|
|
|
#define COOK_FRAME_SUBTYPE(x) ((x & 0xF0) >> 4)
|
2001-02-01 06:20:25 +00:00
|
|
|
#define COOK_ADDR_SELECTOR(x) (((x & 0x2)) && ((x & 0x1)))
|
|
|
|
#define COOK_ASSOC_ID(x) ((x & 0x3FFF))
|
2000-11-15 05:42:35 +00:00
|
|
|
#define COOK_FRAGMENT_NUMBER(x) (x & 0x000F)
|
|
|
|
#define COOK_SEQUENCE_NUMBER(x) ((x & 0xFFF0) >> 4)
|
|
|
|
#define COOK_FLAGS(x) ((x & 0xFF00) >> 8)
|
|
|
|
#define COOK_DS_STATUS(x) (x & 0x3)
|
|
|
|
#define COL_SHOW_INFO(fd,info) if (check_col(fd,COL_INFO)) \
|
|
|
|
col_add_str(fd,COL_INFO,info);
|
|
|
|
|
2001-02-01 06:20:25 +00:00
|
|
|
#define IS_TO_DS(x) ((x & 0x1))
|
|
|
|
#define IS_FROM_DS(x) ((x & 0x2))
|
|
|
|
#define HAVE_FRAGMENTS(x) ((x & 0x4))
|
|
|
|
#define IS_RETRY(x) ((x & 0x8))
|
|
|
|
#define POWER_MGT_STATUS(x) ((x & 0x10))
|
|
|
|
#define HAS_MORE_DATA(x) ((x & 0x20))
|
|
|
|
#define IS_WEP(x) ((x & 0x40))
|
|
|
|
#define IS_STRICTLY_ORDERED(x) ((x & 0x80))
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
#define MGT_RESERVED_RANGE(x) (((x>=0x06)&&(x<=0x07))||((x>=0x0D)&&(x<=0x0F)))
|
|
|
|
#define CTRL_RESERVED_RANGE(x) ((x>=0x10)&&(x<=0x19))
|
|
|
|
#define DATA_RESERVED_RANGE(x) ((x>=0x28)&&(x<=0x2f))
|
|
|
|
#define SPEC_RESERVED_RANGE(x) ((x>=0x30)&&(x<=0x3f))
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Constants used to identify cooked frame types */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
#define MGT_FRAME 0x00 /* Frame type is management */
|
|
|
|
#define CONTROL_FRAME 0x01 /* Frame type is control */
|
|
|
|
#define DATA_FRAME 0x02 /* Frame type is Data */
|
|
|
|
|
|
|
|
#define DATA_SHORT_HDR_LEN 24
|
|
|
|
#define DATA_LONG_HDR_LEN 30
|
|
|
|
#define MGT_FRAME_HDR_LEN 24 /* Length of Managment frame-headers */
|
|
|
|
#define CTLR
|
|
|
|
#define MGT_ASSOC_REQ 0x00 /* Management - association request */
|
|
|
|
#define MGT_ASSOC_RESP 0x01 /* Management - association response */
|
|
|
|
#define MGT_REASSOC_REQ 0x02 /* Management - reassociation request */
|
|
|
|
#define MGT_REASSOC_RESP 0x03 /* Management - reassociation response */
|
|
|
|
#define MGT_PROBE_REQ 0x04 /* Management - Probe request */
|
|
|
|
#define MGT_PROBE_RESP 0x05 /* Management - Probe response */
|
|
|
|
#define MGT_BEACON 0x08 /* Management - Beacon frame */
|
|
|
|
#define MGT_ATIM 0x09 /* Management - ATIM */
|
|
|
|
#define MGT_DISASS 0x0A /* Management - Disassociation */
|
|
|
|
#define MGT_AUTHENTICATION 0x0B /* Management - Authentication */
|
|
|
|
#define MGT_DEAUTHENTICATION 0x0C /* Management - Deauthentication */
|
|
|
|
|
|
|
|
#define CTRL_PS_POLL 0x1A /* Control - power-save poll */
|
|
|
|
#define CTRL_RTS 0x1B /* Control - request to send */
|
|
|
|
#define CTRL_CTS 0x1C /* Control - clear to send */
|
|
|
|
#define CTRL_ACKNOWLEDGEMENT 0x1D /* Control - acknowledgement */
|
|
|
|
#define CTRL_CFP_END 0x1E /* Control - contention-free period end */
|
|
|
|
#define CTRL_CFP_ENDACK 0x1F /* Control - contention-free period end/ack */
|
|
|
|
|
|
|
|
#define DATA 0x20 /* Data - Data */
|
|
|
|
#define DATA_CF_ACK 0x21 /* Data - Data + CF acknowledge */
|
|
|
|
#define DATA_CF_POLL 0x22 /* Data - Data + CF poll */
|
2001-02-01 06:20:25 +00:00
|
|
|
#define DATA_CF_ACK_POLL 0x23 /* Data - Data + CF acknowledge + CF poll */
|
2000-11-15 05:42:35 +00:00
|
|
|
#define DATA_NULL_FUNCTION 0x24 /* Data - Null function (no data) */
|
|
|
|
#define DATA_CF_ACK_NOD 0x25 /* Data - CF ack (no data) */
|
2001-02-01 06:20:25 +00:00
|
|
|
#define DATA_CF_POLL_NOD 0x26 /* Data - Data + CF poll (No data) */
|
|
|
|
#define DATA_CF_ACK_POLL_NOD 0x27 /* Data - CF ack + CF poll (no data) */
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
#define DATA_ADDR_T1 0x00
|
|
|
|
#define DATA_ADDR_T2 0x01
|
|
|
|
#define DATA_ADDR_T3 0x02
|
|
|
|
#define DATA_ADDR_T4 0x03
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Macros used to extract information about fixed fields */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
#define ESS_SET(x) ((x & 0x0001))
|
|
|
|
#define IBSS_SET(x) ((x & 0x0002))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Logical field codes (dissector's encoding of fixed fields) */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
#define FIELD_TIMESTAMP 0x01 /* 64-bit timestamp */
|
|
|
|
#define FIELD_BEACON_INTERVAL 0x02 /* 16-bit beacon interval */
|
|
|
|
#define FIELD_CAP_INFO 0x03 /* Add capability information tree */
|
|
|
|
#define FIELD_AUTH_ALG 0x04 /* Authentication algorithm used */
|
|
|
|
#define FIELD_AUTH_TRANS_SEQ 0x05 /* Authentication sequence number */
|
|
|
|
#define FIELD_CURRENT_AP_ADDR 0x06
|
|
|
|
#define FIELD_LISTEN_IVAL 0x07
|
|
|
|
#define FIELD_REASON_CODE 0x08
|
|
|
|
#define FIELD_ASSOC_ID 0x09
|
|
|
|
#define FIELD_STATUS_CODE 0x0A
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Logical field codes (IEEE 802.11 encoding of tags) */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
#define TAG_SSID 0x00
|
|
|
|
#define TAG_SUPP_RATES 0x01
|
|
|
|
#define TAG_FH_PARAMETER 0x02
|
|
|
|
#define TAG_DS_PARAMETER 0x03
|
|
|
|
#define TAG_CF_PARAMETER 0x04
|
|
|
|
#define TAG_TIM 0x05
|
|
|
|
#define TAG_IBSS_PARAMETER 0x06
|
|
|
|
#define TAG_CHALLENGE_TEXT 0x10
|
|
|
|
|
|
|
|
|
|
|
|
static int proto_wlan = -1;
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Header field info values for FC-field */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static int hf_fc_field = -1;
|
|
|
|
static int hf_fc_proto_version = -1;
|
|
|
|
static int hf_fc_frame_type = -1;
|
|
|
|
static int hf_fc_frame_subtype = -1;
|
|
|
|
|
|
|
|
static int hf_fc_flags = -1;
|
|
|
|
static int hf_fc_to_ds = -1;
|
|
|
|
static int hf_fc_from_ds = -1;
|
|
|
|
static int hf_fc_data_ds = -1;
|
|
|
|
|
|
|
|
static int hf_fc_more_frag = -1;
|
|
|
|
static int hf_fc_retry = -1;
|
|
|
|
static int hf_fc_pwr_mgt = -1;
|
|
|
|
static int hf_fc_more_data = -1;
|
|
|
|
static int hf_fc_wep = -1;
|
|
|
|
static int hf_fc_order = -1;
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Header values for Duration/ID field */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static int hf_did_duration = -1;
|
2001-02-01 06:20:25 +00:00
|
|
|
static int hf_assoc_id = -1;
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Header values for different address-fields (all 4 of them) */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static int hf_addr_da = -1; /* Destination address subfield */
|
|
|
|
static int hf_addr_sa = -1; /* Source address subfield */
|
|
|
|
static int hf_addr_ra = -1; /* Receiver address subfield */
|
|
|
|
static int hf_addr_ta = -1; /* Transmitter address subfield */
|
|
|
|
static int hf_addr_bssid = -1; /* address is bssid */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Header values for sequence number field */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static int hf_frag_number = -1;
|
|
|
|
static int hf_seq_number = -1;
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Header values for Frame Check field */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static int hf_fcs = -1;
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Fixed fields found in mgt frames */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static int ff_auth_alg = -1; /* Authentication algorithm field */
|
|
|
|
static int ff_auth_seq = -1; /* Authentication transaction sequence */
|
|
|
|
static int ff_current_ap = -1; /* Current AP MAC address */
|
|
|
|
static int ff_listen_ival = -1; /* Listen interval fixed field */
|
|
|
|
static int ff_timestamp = -1; /* 64 bit timestamp */
|
|
|
|
static int ff_beacon_interval = -1; /* 16 bit Beacon interval */
|
|
|
|
static int ff_assoc_id = -1; /* 16 bit AID field */
|
|
|
|
static int ff_reason = -1; /* 16 bit reason code */
|
|
|
|
static int ff_status_code = -1; /* Status code */
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Flags found in the capability field (fixed field) */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static int ff_capture = -1;
|
2001-02-01 06:20:25 +00:00
|
|
|
static int ff_cf_sta_poll = -1; /* CF pollable status for a STA */
|
2000-11-15 05:42:35 +00:00
|
|
|
static int ff_cf_ap_poll = -1; /* CF pollable status for an AP */
|
|
|
|
static int ff_cf_ess = -1;
|
|
|
|
static int ff_cf_ibss = -1;
|
|
|
|
static int ff_cf_privacy = -1;
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Tagged value format fields */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static int tag_number = -1;
|
|
|
|
static int tag_length = -1;
|
|
|
|
static int tag_interpretation = -1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int hf_fixed_parameters = -1; /* Protocol payload for management frames */
|
|
|
|
static int hf_tagged_parameters = -1; /* Fixed payload item */
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Protocol trees */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static gint ett_80211 = -1;
|
|
|
|
static gint ett_proto_flags = -1;
|
|
|
|
static gint ett_cap_tree = -1;
|
|
|
|
static gint ett_fc_tree = -1;
|
|
|
|
static gint ett_fixed_parameters = -1;
|
|
|
|
static gint ett_tagged_parameters = -1;
|
2001-01-03 10:34:42 +00:00
|
|
|
|
|
|
|
static dissector_handle_t llc_handle;
|
|
|
|
|
2000-11-15 05:42:35 +00:00
|
|
|
/* ************************************************************************* */
|
2001-02-01 06:20:25 +00:00
|
|
|
/* Return the length of the current header (in bytes) */
|
2000-11-15 05:42:35 +00:00
|
|
|
/* ************************************************************************* */
|
|
|
|
int
|
|
|
|
find_header_length (const u_char * pd, int offset)
|
|
|
|
{
|
|
|
|
guint16 frame_control;
|
|
|
|
|
|
|
|
frame_control = pntohs (pd);
|
2001-02-01 06:20:25 +00:00
|
|
|
return ((IS_FROM_DS(frame_control))
|
|
|
|
&& (IS_TO_DS(frame_control))) ? 30 : 24;
|
2000-11-15 05:42:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* This is the capture function used to update packet counts */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
void
|
|
|
|
capture_ieee80211 (const u_char * pd, int offset, packet_counts * ld)
|
|
|
|
{
|
|
|
|
guint16 fcf, hdr_length;
|
|
|
|
|
2001-01-10 23:28:46 +00:00
|
|
|
fcf = pletohs (&pd[0]);
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
hdr_length = MGT_FRAME_HDR_LEN; /* Set the header length of the frame */
|
|
|
|
|
|
|
|
switch (COMPOSE_FRAME_TYPE (fcf))
|
|
|
|
{
|
|
|
|
|
|
|
|
case DATA: /* We got a data frame */
|
|
|
|
hdr_length = find_header_length (pd, offset);
|
|
|
|
capture_llc (pd, offset + hdr_length, ld);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DATA_CF_ACK: /* Data with ACK */
|
|
|
|
hdr_length = find_header_length (pd, offset);
|
|
|
|
capture_llc (pd, offset + hdr_length, ld);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DATA_CF_POLL:
|
|
|
|
hdr_length = find_header_length (pd, offset);
|
|
|
|
capture_llc (pd, offset + hdr_length, ld);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DATA_CF_ACK_POLL:
|
|
|
|
hdr_length = find_header_length (pd, offset);
|
|
|
|
capture_llc (pd, offset + hdr_length, ld);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ld->other++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Add the subtree used to store the fixed parameters */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static proto_tree *
|
|
|
|
get_fixed_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
|
|
|
|
{
|
|
|
|
proto_item *fixed_fields;
|
|
|
|
fixed_fields =
|
|
|
|
proto_tree_add_uint_format (tree, hf_fixed_parameters, tvb, start,
|
|
|
|
size, size, "Fixed parameters (%d bytes)",
|
|
|
|
size);
|
|
|
|
|
|
|
|
return proto_item_add_subtree (fixed_fields, ett_fixed_parameters);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Add the subtree used to store tagged parameters */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static proto_tree *
|
|
|
|
get_tagged_parameter_tree (proto_tree * tree, tvbuff_t *tvb, int start, int size)
|
|
|
|
{
|
|
|
|
proto_item *tagged_fields;
|
|
|
|
|
|
|
|
tagged_fields = proto_tree_add_uint_format (tree, hf_tagged_parameters,
|
|
|
|
tvb,
|
|
|
|
start,
|
|
|
|
size,
|
|
|
|
size,
|
|
|
|
"Tagged parameters (%d bytes)",
|
|
|
|
size);
|
|
|
|
|
|
|
|
return proto_item_add_subtree (tagged_fields, ett_tagged_parameters);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Dissect and add fixed mgmt fields to protocol tree */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static void
|
|
|
|
add_fixed_field (proto_tree * tree, tvbuff_t * tvb, int offset, int lfcode)
|
|
|
|
{
|
2001-03-13 21:34:28 +00:00
|
|
|
const guint8 *dataptr;
|
2000-11-15 05:42:35 +00:00
|
|
|
char out_buff[SHORT_STR];
|
|
|
|
guint16 *temp16;
|
|
|
|
proto_item *cap_item;
|
|
|
|
static proto_tree *cap_tree;
|
|
|
|
|
|
|
|
switch (lfcode)
|
|
|
|
{
|
|
|
|
case FIELD_TIMESTAMP:
|
|
|
|
dataptr = tvb_get_ptr (tvb, offset, 8);
|
|
|
|
memset (out_buff, 0, SHORT_STR);
|
|
|
|
snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
|
Move the table of bit-swapped byte values to "epan/bitswap.c", and
declare it, and define a "BIT_SWAP" macro that uses it, in
"epan/bitswap.h".
Use that macro to bit-swap bytes in the IEEE 802.11 dissector, rather
than the macro that was used (said macro used GCCisms and didn't compile
on Windows).
Make an "init_plugin()" routine to enable a plugin and call its init
routine, and call it from "check_plugin_status()" and
"plugins_enable_cb()", rather than having very similar code in two
places; "patable" is now part of libethereal, and, at least on Windows,
attempts to refer to it from "libui" failed. Make "patable" static to
"epan/plugins.c". (This may still not work, as now "libui" is calling a
routine in "libethereal"; if that fails, perhaps it's time to get rid of
the "enable/disable plugins" stuff completely, as new-style plugins, at
least, register themselves as protocols and should be controllable from
the "Edit->Protocols" window just as built-in dissectors are.)
svn path=/trunk/; revision=2649
2000-11-15 09:37:53 +00:00
|
|
|
BIT_SWAP (dataptr[7]),
|
|
|
|
BIT_SWAP (dataptr[6]),
|
|
|
|
BIT_SWAP (dataptr[5]),
|
|
|
|
BIT_SWAP (dataptr[4]),
|
|
|
|
BIT_SWAP (dataptr[3]),
|
|
|
|
BIT_SWAP (dataptr[2]),
|
|
|
|
BIT_SWAP (dataptr[1]),
|
|
|
|
BIT_SWAP (dataptr[0]));
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case FIELD_BEACON_INTERVAL:
|
|
|
|
dataptr = tvb_get_ptr (tvb, offset, 2);
|
Move the table of bit-swapped byte values to "epan/bitswap.c", and
declare it, and define a "BIT_SWAP" macro that uses it, in
"epan/bitswap.h".
Use that macro to bit-swap bytes in the IEEE 802.11 dissector, rather
than the macro that was used (said macro used GCCisms and didn't compile
on Windows).
Make an "init_plugin()" routine to enable a plugin and call its init
routine, and call it from "check_plugin_status()" and
"plugins_enable_cb()", rather than having very similar code in two
places; "patable" is now part of libethereal, and, at least on Windows,
attempts to refer to it from "libui" failed. Make "patable" static to
"epan/plugins.c". (This may still not work, as now "libui" is calling a
routine in "libethereal"; if that fails, perhaps it's time to get rid of
the "enable/disable plugins" stuff completely, as new-style plugins, at
least, register themselves as protocols and should be controllable from
the "Edit->Protocols" window just as built-in dissectors are.)
svn path=/trunk/; revision=2649
2000-11-15 09:37:53 +00:00
|
|
|
out_buff[0] = BIT_SWAP (dataptr[1]);
|
|
|
|
out_buff[1] = BIT_SWAP (dataptr[0]);
|
2000-11-15 05:42:35 +00:00
|
|
|
temp16 = (guint16 *) out_buff;
|
|
|
|
proto_tree_add_uint (tree, ff_beacon_interval, tvb, offset, 2,
|
|
|
|
pntohs (temp16));
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case FIELD_CAP_INFO:
|
|
|
|
dataptr = tvb_get_ptr (tvb, offset, 2);
|
Move the table of bit-swapped byte values to "epan/bitswap.c", and
declare it, and define a "BIT_SWAP" macro that uses it, in
"epan/bitswap.h".
Use that macro to bit-swap bytes in the IEEE 802.11 dissector, rather
than the macro that was used (said macro used GCCisms and didn't compile
on Windows).
Make an "init_plugin()" routine to enable a plugin and call its init
routine, and call it from "check_plugin_status()" and
"plugins_enable_cb()", rather than having very similar code in two
places; "patable" is now part of libethereal, and, at least on Windows,
attempts to refer to it from "libui" failed. Make "patable" static to
"epan/plugins.c". (This may still not work, as now "libui" is calling a
routine in "libethereal"; if that fails, perhaps it's time to get rid of
the "enable/disable plugins" stuff completely, as new-style plugins, at
least, register themselves as protocols and should be controllable from
the "Edit->Protocols" window just as built-in dissectors are.)
svn path=/trunk/; revision=2649
2000-11-15 09:37:53 +00:00
|
|
|
out_buff[0] = BIT_SWAP (dataptr[1]);
|
|
|
|
out_buff[0] = BIT_SWAP (dataptr[0]);
|
2000-11-15 05:42:35 +00:00
|
|
|
temp16 = (guint16 *) out_buff;
|
|
|
|
|
|
|
|
cap_item = proto_tree_add_uint_format (tree, ff_capture,
|
|
|
|
tvb, offset, 2,
|
|
|
|
pntohs (temp16),
|
|
|
|
"Capability Information: %04X",
|
|
|
|
pntohs (temp16));
|
|
|
|
cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree);
|
|
|
|
proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 1,
|
|
|
|
pntohs (temp16));
|
|
|
|
proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 1,
|
|
|
|
pntohs (temp16));
|
|
|
|
proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 1,
|
|
|
|
pntohs (temp16));
|
|
|
|
if (ESS_SET (pntohs (temp16)) != 0) /* This is an AP */
|
|
|
|
proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2,
|
|
|
|
((pntohs (temp16) & 0xC) >> 2));
|
|
|
|
|
|
|
|
else /* This is a STA */
|
|
|
|
proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2,
|
|
|
|
((pntohs (temp16) & 0xC) >> 2));
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case FIELD_AUTH_ALG:
|
|
|
|
dataptr = tvb_get_ptr (tvb, offset, 2);
|
Move the table of bit-swapped byte values to "epan/bitswap.c", and
declare it, and define a "BIT_SWAP" macro that uses it, in
"epan/bitswap.h".
Use that macro to bit-swap bytes in the IEEE 802.11 dissector, rather
than the macro that was used (said macro used GCCisms and didn't compile
on Windows).
Make an "init_plugin()" routine to enable a plugin and call its init
routine, and call it from "check_plugin_status()" and
"plugins_enable_cb()", rather than having very similar code in two
places; "patable" is now part of libethereal, and, at least on Windows,
attempts to refer to it from "libui" failed. Make "patable" static to
"epan/plugins.c". (This may still not work, as now "libui" is calling a
routine in "libethereal"; if that fails, perhaps it's time to get rid of
the "enable/disable plugins" stuff completely, as new-style plugins, at
least, register themselves as protocols and should be controllable from
the "Edit->Protocols" window just as built-in dissectors are.)
svn path=/trunk/; revision=2649
2000-11-15 09:37:53 +00:00
|
|
|
out_buff[0] = BIT_SWAP (dataptr[1]);
|
|
|
|
out_buff[1] = BIT_SWAP (dataptr[0]);
|
2000-11-15 05:42:35 +00:00
|
|
|
temp16 = (guint16 *) out_buff;
|
|
|
|
proto_tree_add_uint (tree, ff_auth_alg, tvb, offset, 2,
|
|
|
|
pntohs (temp16));
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case FIELD_AUTH_TRANS_SEQ:
|
|
|
|
dataptr = tvb_get_ptr (tvb, offset, 2);
|
Move the table of bit-swapped byte values to "epan/bitswap.c", and
declare it, and define a "BIT_SWAP" macro that uses it, in
"epan/bitswap.h".
Use that macro to bit-swap bytes in the IEEE 802.11 dissector, rather
than the macro that was used (said macro used GCCisms and didn't compile
on Windows).
Make an "init_plugin()" routine to enable a plugin and call its init
routine, and call it from "check_plugin_status()" and
"plugins_enable_cb()", rather than having very similar code in two
places; "patable" is now part of libethereal, and, at least on Windows,
attempts to refer to it from "libui" failed. Make "patable" static to
"epan/plugins.c". (This may still not work, as now "libui" is calling a
routine in "libethereal"; if that fails, perhaps it's time to get rid of
the "enable/disable plugins" stuff completely, as new-style plugins, at
least, register themselves as protocols and should be controllable from
the "Edit->Protocols" window just as built-in dissectors are.)
svn path=/trunk/; revision=2649
2000-11-15 09:37:53 +00:00
|
|
|
out_buff[0] = BIT_SWAP (dataptr[1]);
|
|
|
|
out_buff[1] = BIT_SWAP (dataptr[0]);
|
2000-11-15 05:42:35 +00:00
|
|
|
temp16 = (guint16 *) out_buff;
|
|
|
|
proto_tree_add_uint (tree, ff_auth_seq, tvb, offset, 2,
|
|
|
|
pntohs (temp16));
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case FIELD_CURRENT_AP_ADDR:
|
|
|
|
dataptr = tvb_get_ptr (tvb, offset, 6);
|
|
|
|
memset (out_buff, 0, SHORT_STR);
|
Move the table of bit-swapped byte values to "epan/bitswap.c", and
declare it, and define a "BIT_SWAP" macro that uses it, in
"epan/bitswap.h".
Use that macro to bit-swap bytes in the IEEE 802.11 dissector, rather
than the macro that was used (said macro used GCCisms and didn't compile
on Windows).
Make an "init_plugin()" routine to enable a plugin and call its init
routine, and call it from "check_plugin_status()" and
"plugins_enable_cb()", rather than having very similar code in two
places; "patable" is now part of libethereal, and, at least on Windows,
attempts to refer to it from "libui" failed. Make "patable" static to
"epan/plugins.c". (This may still not work, as now "libui" is calling a
routine in "libethereal"; if that fails, perhaps it's time to get rid of
the "enable/disable plugins" stuff completely, as new-style plugins, at
least, register themselves as protocols and should be controllable from
the "Edit->Protocols" window just as built-in dissectors are.)
svn path=/trunk/; revision=2649
2000-11-15 09:37:53 +00:00
|
|
|
out_buff[0] = BIT_SWAP (dataptr[5]);
|
|
|
|
out_buff[1] = BIT_SWAP (dataptr[4]);
|
|
|
|
out_buff[2] = BIT_SWAP (dataptr[3]);
|
|
|
|
out_buff[3] = BIT_SWAP (dataptr[2]);
|
|
|
|
out_buff[4] = BIT_SWAP (dataptr[1]);
|
|
|
|
out_buff[5] = BIT_SWAP (dataptr[0]);
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
proto_tree_add_string (tree, ff_current_ap, tvb, offset, 6, out_buff);
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case FIELD_LISTEN_IVAL:
|
|
|
|
dataptr = tvb_get_ptr (tvb, offset, 2);
|
Move the table of bit-swapped byte values to "epan/bitswap.c", and
declare it, and define a "BIT_SWAP" macro that uses it, in
"epan/bitswap.h".
Use that macro to bit-swap bytes in the IEEE 802.11 dissector, rather
than the macro that was used (said macro used GCCisms and didn't compile
on Windows).
Make an "init_plugin()" routine to enable a plugin and call its init
routine, and call it from "check_plugin_status()" and
"plugins_enable_cb()", rather than having very similar code in two
places; "patable" is now part of libethereal, and, at least on Windows,
attempts to refer to it from "libui" failed. Make "patable" static to
"epan/plugins.c". (This may still not work, as now "libui" is calling a
routine in "libethereal"; if that fails, perhaps it's time to get rid of
the "enable/disable plugins" stuff completely, as new-style plugins, at
least, register themselves as protocols and should be controllable from
the "Edit->Protocols" window just as built-in dissectors are.)
svn path=/trunk/; revision=2649
2000-11-15 09:37:53 +00:00
|
|
|
out_buff[0] = BIT_SWAP (dataptr[1]);
|
|
|
|
out_buff[1] = BIT_SWAP (dataptr[0]);
|
2000-11-15 05:42:35 +00:00
|
|
|
temp16 = (guint16 *) out_buff;
|
|
|
|
proto_tree_add_uint (tree, ff_listen_ival, tvb, offset, 2,
|
|
|
|
pntohs (temp16));
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case FIELD_REASON_CODE:
|
|
|
|
dataptr = tvb_get_ptr (tvb, offset, 2);
|
Move the table of bit-swapped byte values to "epan/bitswap.c", and
declare it, and define a "BIT_SWAP" macro that uses it, in
"epan/bitswap.h".
Use that macro to bit-swap bytes in the IEEE 802.11 dissector, rather
than the macro that was used (said macro used GCCisms and didn't compile
on Windows).
Make an "init_plugin()" routine to enable a plugin and call its init
routine, and call it from "check_plugin_status()" and
"plugins_enable_cb()", rather than having very similar code in two
places; "patable" is now part of libethereal, and, at least on Windows,
attempts to refer to it from "libui" failed. Make "patable" static to
"epan/plugins.c". (This may still not work, as now "libui" is calling a
routine in "libethereal"; if that fails, perhaps it's time to get rid of
the "enable/disable plugins" stuff completely, as new-style plugins, at
least, register themselves as protocols and should be controllable from
the "Edit->Protocols" window just as built-in dissectors are.)
svn path=/trunk/; revision=2649
2000-11-15 09:37:53 +00:00
|
|
|
out_buff[0] = BIT_SWAP (dataptr[1]);
|
|
|
|
out_buff[1] = BIT_SWAP (dataptr[0]);
|
2000-11-15 05:42:35 +00:00
|
|
|
temp16 = (guint16 *) out_buff;
|
|
|
|
proto_tree_add_uint (tree, ff_reason, tvb, offset, 2, pntohs (temp16));
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case FIELD_ASSOC_ID:
|
|
|
|
dataptr = tvb_get_ptr (tvb, offset, 2);
|
Move the table of bit-swapped byte values to "epan/bitswap.c", and
declare it, and define a "BIT_SWAP" macro that uses it, in
"epan/bitswap.h".
Use that macro to bit-swap bytes in the IEEE 802.11 dissector, rather
than the macro that was used (said macro used GCCisms and didn't compile
on Windows).
Make an "init_plugin()" routine to enable a plugin and call its init
routine, and call it from "check_plugin_status()" and
"plugins_enable_cb()", rather than having very similar code in two
places; "patable" is now part of libethereal, and, at least on Windows,
attempts to refer to it from "libui" failed. Make "patable" static to
"epan/plugins.c". (This may still not work, as now "libui" is calling a
routine in "libethereal"; if that fails, perhaps it's time to get rid of
the "enable/disable plugins" stuff completely, as new-style plugins, at
least, register themselves as protocols and should be controllable from
the "Edit->Protocols" window just as built-in dissectors are.)
svn path=/trunk/; revision=2649
2000-11-15 09:37:53 +00:00
|
|
|
out_buff[0] = BIT_SWAP (dataptr[1]);
|
|
|
|
out_buff[1] = BIT_SWAP (dataptr[0]);
|
2000-11-15 05:42:35 +00:00
|
|
|
temp16 = (guint16 *) out_buff;
|
|
|
|
proto_tree_add_uint (tree, ff_assoc_id, tvb, offset, 2, pntohs (temp16));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FIELD_STATUS_CODE:
|
|
|
|
dataptr = tvb_get_ptr (tvb, offset, 2);
|
Move the table of bit-swapped byte values to "epan/bitswap.c", and
declare it, and define a "BIT_SWAP" macro that uses it, in
"epan/bitswap.h".
Use that macro to bit-swap bytes in the IEEE 802.11 dissector, rather
than the macro that was used (said macro used GCCisms and didn't compile
on Windows).
Make an "init_plugin()" routine to enable a plugin and call its init
routine, and call it from "check_plugin_status()" and
"plugins_enable_cb()", rather than having very similar code in two
places; "patable" is now part of libethereal, and, at least on Windows,
attempts to refer to it from "libui" failed. Make "patable" static to
"epan/plugins.c". (This may still not work, as now "libui" is calling a
routine in "libethereal"; if that fails, perhaps it's time to get rid of
the "enable/disable plugins" stuff completely, as new-style plugins, at
least, register themselves as protocols and should be controllable from
the "Edit->Protocols" window just as built-in dissectors are.)
svn path=/trunk/; revision=2649
2000-11-15 09:37:53 +00:00
|
|
|
out_buff[0] = BIT_SWAP (dataptr[1]);
|
|
|
|
out_buff[1] = BIT_SWAP (dataptr[0]);
|
2000-11-15 05:42:35 +00:00
|
|
|
temp16 = (guint16 *) out_buff;
|
|
|
|
proto_tree_add_uint (tree, ff_status_code, tvb, offset, 2,
|
|
|
|
pntohs (temp16));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Dissect and add tagged (optional) fields to proto tree */
|
|
|
|
/* ************************************************************************* */
|
|
|
|
static int
|
|
|
|
add_tagged_field (proto_tree * tree, tvbuff_t * tvb, int offset)
|
|
|
|
{
|
2001-03-13 21:34:28 +00:00
|
|
|
const guint8 *tag_info_ptr;
|
|
|
|
const guint8 *tag_data_ptr;
|
2000-11-15 05:42:35 +00:00
|
|
|
guint32 tag_no, tag_len;
|
|
|
|
int i, n;
|
|
|
|
char out_buff[SHORT_STR];
|
|
|
|
|
|
|
|
|
|
|
|
tag_info_ptr = tvb_get_ptr (tvb, offset, 2);
|
|
|
|
tag_no = tag_info_ptr[0];
|
|
|
|
tag_len = tag_info_ptr[1];
|
|
|
|
|
|
|
|
tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
|
|
|
|
|
|
|
|
|
|
|
|
if ((tag_no >= 17) && (tag_no <= 31))
|
|
|
|
{ /* Reserved for challenge text */
|
|
|
|
proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
|
2001-01-23 05:54:09 +00:00
|
|
|
"Tag Number: %u (Reserved for challenge text)",
|
2000-11-15 05:42:35 +00:00
|
|
|
tag_no);
|
|
|
|
|
|
|
|
proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
|
|
|
|
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
|
|
|
|
tag_len, "Not interpreted");
|
|
|
|
return (int) tag_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Next See if tag is reserved - if true, skip it! */
|
|
|
|
if (((tag_no >= 7) && (tag_no <= 15))
|
|
|
|
|| ((tag_no >= 32) && (tag_no <= 255)))
|
|
|
|
{
|
|
|
|
proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
|
2001-01-23 05:54:09 +00:00
|
|
|
"Tag Number: %u (Reserved tag number)",
|
2000-11-15 05:42:35 +00:00
|
|
|
tag_no);
|
|
|
|
|
|
|
|
proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
|
|
|
|
|
|
|
|
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
|
|
|
|
tag_len, "Not interpreted");
|
|
|
|
return (int) tag_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (tag_info_ptr[0])
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
case TAG_SSID:
|
|
|
|
proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
|
2001-01-23 05:54:09 +00:00
|
|
|
"Tag Number: %u (SSID parameter set)",
|
2000-11-15 05:42:35 +00:00
|
|
|
tag_no);
|
|
|
|
|
|
|
|
proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
|
|
|
|
|
|
|
|
memset (out_buff, 0, SHORT_STR);
|
|
|
|
|
|
|
|
memcpy (out_buff, tag_data_ptr, (size_t) tag_len);
|
|
|
|
out_buff[tag_len + 1] = 0;
|
|
|
|
|
|
|
|
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
|
|
|
|
tag_len, out_buff);
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case TAG_SUPP_RATES:
|
|
|
|
proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
|
2001-01-23 05:54:09 +00:00
|
|
|
"Tag Number: %u (Supported Rates)", tag_no);
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
|
|
|
|
|
|
|
|
memset (out_buff, 0, SHORT_STR);
|
|
|
|
strcpy (out_buff, "Supported rates: ");
|
|
|
|
n = strlen (out_buff);
|
|
|
|
|
|
|
|
for (i = 0; i < tag_len; i++)
|
|
|
|
{
|
2001-03-15 05:39:04 +00:00
|
|
|
n += snprintf (out_buff + n, SHORT_STR - n, "%2.1f%s ",
|
|
|
|
(tag_data_ptr[i] & 0x7F) * 0.5,
|
|
|
|
(tag_data_ptr[i] & 0x80) ? "(B)" : "");
|
2000-11-15 05:42:35 +00:00
|
|
|
}
|
|
|
|
snprintf (out_buff + n, SHORT_STR - n, "[Mbit/sec]");
|
|
|
|
|
|
|
|
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
|
|
|
|
tag_len, out_buff);
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case TAG_FH_PARAMETER:
|
|
|
|
proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
|
2001-01-23 05:54:09 +00:00
|
|
|
"Tag Number: %u (FH Parameter set)",
|
2000-11-15 05:42:35 +00:00
|
|
|
tag_no);
|
|
|
|
|
|
|
|
proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
|
|
|
|
memset (out_buff, 0, SHORT_STR);
|
|
|
|
|
|
|
|
snprintf (out_buff, SHORT_STR,
|
|
|
|
"Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, "
|
|
|
|
"Hop Index %2d", pntohs (tag_data_ptr), tag_data_ptr[2],
|
|
|
|
tag_data_ptr[3], tag_data_ptr[4]);
|
|
|
|
|
|
|
|
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
|
|
|
|
tag_len, out_buff);
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case TAG_DS_PARAMETER:
|
|
|
|
proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
|
2001-01-23 05:54:09 +00:00
|
|
|
"Tag Number: %u (DS Parameter set)",
|
2000-11-15 05:42:35 +00:00
|
|
|
tag_no);
|
|
|
|
|
|
|
|
proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
|
|
|
|
memset (out_buff, 0, SHORT_STR);
|
|
|
|
|
2001-01-23 05:54:09 +00:00
|
|
|
snprintf (out_buff, SHORT_STR, "Current Channel: %u", tag_data_ptr[0]);
|
2000-11-15 05:42:35 +00:00
|
|
|
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
|
|
|
|
tag_len, out_buff);
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case TAG_CF_PARAMETER:
|
|
|
|
proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
|
2001-01-23 05:54:09 +00:00
|
|
|
"Tag Number: %u (CF Parameter set)",
|
2000-11-15 05:42:35 +00:00
|
|
|
tag_no);
|
|
|
|
|
|
|
|
proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
|
|
|
|
memset (out_buff, 0, SHORT_STR);
|
|
|
|
|
|
|
|
snprintf (out_buff, SHORT_STR,
|
2001-01-23 05:54:09 +00:00
|
|
|
"CFP count %u, CFP period %u, CFP max duration %u, "
|
|
|
|
"CFP Remaining %u", tag_data_ptr[0], tag_data_ptr[1],
|
2000-11-15 05:42:35 +00:00
|
|
|
pntohs (tag_data_ptr + 2), pntohs (tag_data_ptr + 4));
|
|
|
|
|
|
|
|
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
|
|
|
|
tag_len, out_buff);
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case TAG_TIM:
|
|
|
|
proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
|
2001-01-23 05:54:09 +00:00
|
|
|
"Tag Number: %u ((TIM) Traffic Indication Map)",
|
2000-11-15 05:42:35 +00:00
|
|
|
tag_no);
|
|
|
|
|
|
|
|
proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
|
|
|
|
memset (out_buff, 0, SHORT_STR);
|
|
|
|
snprintf (out_buff, SHORT_STR,
|
2001-01-23 05:54:09 +00:00
|
|
|
"DTIM count %u, DTIM period %u, Bitmap control 0x%X, "
|
2000-11-15 05:42:35 +00:00
|
|
|
"(Bitmap suppressed)", tag_data_ptr[0], tag_data_ptr[1],
|
|
|
|
tag_data_ptr[2]);
|
|
|
|
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
|
|
|
|
tag_len, out_buff);
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case TAG_IBSS_PARAMETER:
|
|
|
|
proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
|
2001-01-23 05:54:09 +00:00
|
|
|
"Tag Number: %u (IBSS Parameter set)",
|
2000-11-15 05:42:35 +00:00
|
|
|
tag_no);
|
|
|
|
|
|
|
|
proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
|
|
|
|
memset (out_buff, 0, SHORT_STR);
|
|
|
|
snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
|
|
|
|
pntohs (tag_data_ptr));
|
|
|
|
|
|
|
|
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
|
|
|
|
tag_len, out_buff);
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case TAG_CHALLENGE_TEXT:
|
|
|
|
proto_tree_add_uint_format (tree, tag_number, tvb, offset, 1, tag_no,
|
2001-01-23 05:54:09 +00:00
|
|
|
"Tag Number: %u (Challenge text)", tag_no);
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
proto_tree_add_uint (tree, tag_length, tvb, offset + 1, 1, tag_len);
|
|
|
|
memset (out_buff, 0, SHORT_STR);
|
|
|
|
snprintf (out_buff, SHORT_STR, "Challenge text: %.47s", tag_data_ptr);
|
|
|
|
proto_tree_add_string (tree, tag_interpretation, tvb, offset, tag_len,
|
|
|
|
out_buff);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return tag_len + 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/* Dissect 802.11 frame */
|
|
|
|
/* ************************************************************************* */
|
2001-01-21 22:51:46 +00:00
|
|
|
static void
|
2000-11-15 05:42:35 +00:00
|
|
|
dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
|
|
|
|
{
|
|
|
|
guint16 fcf, flags;
|
2001-03-13 21:34:28 +00:00
|
|
|
const guint8 *src = NULL, *dst = NULL;
|
2000-11-15 05:42:35 +00:00
|
|
|
proto_item *ti;
|
|
|
|
proto_item *flag_item;
|
|
|
|
proto_item *fc_item;
|
|
|
|
static proto_tree *hdr_tree;
|
|
|
|
static proto_tree *flag_tree;
|
|
|
|
static proto_tree *fixed_tree;
|
|
|
|
static proto_tree *tagged_tree;
|
|
|
|
static proto_tree *fc_tree;
|
|
|
|
guint16 cap_len, hdr_len;
|
|
|
|
tvbuff_t *next_tvb;
|
|
|
|
guint32 next_idx;
|
|
|
|
guint32 addr_type;
|
|
|
|
|
|
|
|
cap_len = pinfo->captured_len;
|
|
|
|
fcf = tvb_get_letohs (tvb, 0);
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_PROTOCOL))
|
2000-11-19 08:54:37 +00:00
|
|
|
col_set_str (pinfo->fd, COL_PROTOCOL, "IEEE 802.11");
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
/* Add the FC to the current tree */
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
hdr_len = find_header_length (tvb_get_ptr (tvb, 0, cap_len), 0);
|
|
|
|
ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len,
|
|
|
|
"IEEE 802.11 Header");
|
|
|
|
hdr_tree = proto_item_add_subtree (ti, ett_80211);
|
|
|
|
|
2001-02-01 06:20:25 +00:00
|
|
|
fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb, 0, 2,
|
|
|
|
tvb_get_letohs (tvb, 0),
|
|
|
|
"Frame Control: 0x%04X",
|
|
|
|
tvb_get_letohs (tvb, 0));
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
|
|
|
|
|
|
|
|
|
|
|
|
proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb, 0, 1,
|
|
|
|
COOK_PROT_VERSION (tvb_get_letohs (tvb, 0)));
|
|
|
|
|
|
|
|
proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb, 0, 1,
|
|
|
|
COOK_FRAME_TYPE (tvb_get_letohs (tvb, 0)));
|
|
|
|
|
|
|
|
proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
|
|
|
|
tvb, 0, 1,
|
|
|
|
COOK_FRAME_SUBTYPE (tvb_get_letohs (tvb, 0)));
|
|
|
|
|
|
|
|
flags = COOK_FLAGS (tvb_get_letohs (tvb, 0));
|
|
|
|
|
|
|
|
flag_item =
|
|
|
|
proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb, 1, 1,
|
|
|
|
flags, "Flags: 0x%X", flags);
|
|
|
|
|
|
|
|
flag_tree = proto_item_add_subtree (flag_item, ett_proto_flags);
|
|
|
|
|
|
|
|
proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb, 1, 1,
|
|
|
|
COOK_DS_STATUS (flags));
|
|
|
|
|
|
|
|
proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb, 1, 1,
|
|
|
|
flags);
|
|
|
|
|
|
|
|
proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb, 1, 1, flags);
|
|
|
|
|
|
|
|
proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb, 1, 1, flags);
|
|
|
|
|
|
|
|
proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb, 1, 1,
|
|
|
|
flags);
|
|
|
|
|
|
|
|
proto_tree_add_boolean (flag_tree, hf_fc_wep, tvb, 1, 1, flags);
|
|
|
|
|
|
|
|
proto_tree_add_boolean (flag_tree, hf_fc_order, tvb, 1, 1, flags);
|
|
|
|
|
2001-02-01 06:20:25 +00:00
|
|
|
if ((COMPOSE_FRAME_TYPE(fcf))==CTRL_PS_POLL)
|
|
|
|
proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
|
|
|
|
COOK_ASSOC_ID(tvb_get_ntohs(tvb,2)));
|
|
|
|
|
|
|
|
else
|
|
|
|
proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
|
|
|
|
tvb_get_ntohs (tvb, 2));
|
2000-11-15 05:42:35 +00:00
|
|
|
}
|
|
|
|
|
2001-02-01 06:20:25 +00:00
|
|
|
/* Perform tasks which are common to a certain frame type */
|
2000-11-15 05:42:35 +00:00
|
|
|
switch (COOK_FRAME_TYPE (fcf))
|
|
|
|
{
|
|
|
|
|
|
|
|
case MGT_FRAME: /* All management frames share a common header */
|
|
|
|
src = tvb_get_ptr (tvb, 10, 6);
|
|
|
|
dst = tvb_get_ptr (tvb, 4, 6);
|
|
|
|
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_SRC))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_SRC, "%X:%X:%X:%X:%X:%X",
|
|
|
|
src[0], src[1], src[2], src[3], src[4], src[5]);
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_DST))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_DST, "%X:%X:%X:%X:%X:%X",
|
|
|
|
dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
|
|
|
|
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6,
|
|
|
|
tvb_get_ptr (tvb, 4, 6));
|
|
|
|
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6,
|
|
|
|
tvb_get_ptr (tvb, 10, 6));
|
|
|
|
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
|
|
|
|
tvb_get_ptr (tvb, 16, 6));
|
|
|
|
|
|
|
|
proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
|
|
|
|
COOK_FRAGMENT_NUMBER (tvb_get_ntohs
|
|
|
|
(tvb, 22)));
|
|
|
|
|
|
|
|
proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
|
|
|
|
COOK_SEQUENCE_NUMBER (tvb_get_ntohs
|
|
|
|
(tvb, 22)));
|
|
|
|
cap_len = cap_len - MGT_FRAME_LEN - 4;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case CONTROL_FRAME:
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case DATA_FRAME:
|
|
|
|
addr_type = COOK_ADDR_SELECTOR (fcf);
|
2001-02-01 06:20:25 +00:00
|
|
|
hdr_len = find_header_length (tvb_get_ptr (tvb, 0, cap_len), 0);
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
/* In order to show src/dst address we must always do the following */
|
|
|
|
switch (addr_type)
|
|
|
|
{
|
|
|
|
|
|
|
|
case DATA_ADDR_T1:
|
|
|
|
src = tvb_get_ptr (tvb, 10, 6);
|
|
|
|
dst = tvb_get_ptr (tvb, 4, 6);
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case DATA_ADDR_T2:
|
|
|
|
src = tvb_get_ptr (tvb, 16, 6);
|
|
|
|
dst = tvb_get_ptr (tvb, 4, 6);
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case DATA_ADDR_T3:
|
|
|
|
src = tvb_get_ptr (tvb, 10, 6);
|
|
|
|
dst = tvb_get_ptr (tvb, 16, 6);
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case DATA_ADDR_T4:
|
|
|
|
src = tvb_get_ptr (tvb, 24, 6);
|
|
|
|
dst = tvb_get_ptr (tvb, 16, 6);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_SRC))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_SRC,
|
|
|
|
"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
|
|
|
|
src[0], src[1], src[2], src[3], src[4], src[5]);
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_DST))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_DST,
|
|
|
|
"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
|
|
|
|
dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
|
|
|
|
|
|
|
|
/* Now if we have a tree we start adding stuff */
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
switch (addr_type)
|
|
|
|
{
|
|
|
|
|
|
|
|
case DATA_ADDR_T1:
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6,
|
|
|
|
tvb_get_ptr (tvb, 4, 6));
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6,
|
|
|
|
tvb_get_ptr (tvb, 10, 6));
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
|
|
|
|
tvb_get_ptr (tvb, 16, 6));
|
2001-02-01 06:20:25 +00:00
|
|
|
proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
|
|
|
|
COOK_FRAGMENT_NUMBER (tvb_get_ntohs
|
|
|
|
(tvb, 22)));
|
|
|
|
proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
|
|
|
|
COOK_SEQUENCE_NUMBER (tvb_get_ntohs
|
|
|
|
(tvb, 22)));
|
2000-11-15 05:42:35 +00:00
|
|
|
break;
|
2001-02-01 06:20:25 +00:00
|
|
|
|
|
|
|
|
2000-11-15 05:42:35 +00:00
|
|
|
case DATA_ADDR_T2:
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6,
|
|
|
|
tvb_get_ptr (tvb, 4, 6));
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
|
|
|
|
tvb_get_ptr (tvb, 10, 6));
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6,
|
|
|
|
tvb_get_ptr (tvb, 16, 6));
|
2001-02-01 06:20:25 +00:00
|
|
|
proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
|
|
|
|
COOK_FRAGMENT_NUMBER (tvb_get_ntohs
|
|
|
|
(tvb, 22)));
|
|
|
|
proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
|
|
|
|
COOK_SEQUENCE_NUMBER (tvb_get_ntohs
|
|
|
|
(tvb, 22)));
|
2000-11-15 05:42:35 +00:00
|
|
|
break;
|
2001-02-01 06:20:25 +00:00
|
|
|
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
case DATA_ADDR_T3:
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
|
|
|
|
tvb_get_ptr (tvb, 4, 6));
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 10, 6,
|
|
|
|
tvb_get_ptr (tvb, 10, 6));
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6,
|
|
|
|
tvb_get_ptr (tvb, 16, 6));
|
2001-02-01 06:20:25 +00:00
|
|
|
proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
|
|
|
|
COOK_FRAGMENT_NUMBER (tvb_get_ntohs
|
|
|
|
(tvb, 22)));
|
|
|
|
proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
|
|
|
|
COOK_SEQUENCE_NUMBER (tvb_get_ntohs
|
|
|
|
(tvb, 22)));
|
2000-11-15 05:42:35 +00:00
|
|
|
break;
|
2001-02-01 06:20:25 +00:00
|
|
|
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
case DATA_ADDR_T4:
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
|
|
|
|
tvb_get_ptr (tvb, 4, 6));
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
|
|
|
|
tvb_get_ptr (tvb, 10, 6));
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6,
|
|
|
|
tvb_get_ptr (tvb, 16, 6));
|
2001-02-01 06:20:25 +00:00
|
|
|
proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
|
|
|
|
COOK_FRAGMENT_NUMBER (tvb_get_ntohs
|
|
|
|
(tvb, 22)));
|
|
|
|
proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
|
|
|
|
COOK_SEQUENCE_NUMBER (tvb_get_ntohs
|
|
|
|
(tvb, 22)));
|
2000-11-15 05:42:35 +00:00
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6,
|
|
|
|
tvb_get_ptr (tvb, 24, 6));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (COMPOSE_FRAME_TYPE (fcf))
|
|
|
|
{
|
|
|
|
|
|
|
|
case MGT_ASSOC_REQ:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Association Request");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 4);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_HDR_LEN,
|
|
|
|
FIELD_CAP_INFO);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_HDR_LEN + 2,
|
|
|
|
FIELD_LISTEN_IVAL);
|
|
|
|
|
|
|
|
next_idx = MGT_FRAME_HDR_LEN + 4; /* Size of fixed fields */
|
|
|
|
tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
|
|
|
|
pinfo->captured_len - 4 -
|
|
|
|
next_idx);
|
|
|
|
|
|
|
|
|
|
|
|
while (pinfo->captured_len > (next_idx + 4))
|
|
|
|
next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case MGT_ASSOC_RESP:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Association Response");
|
|
|
|
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 6);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_CAP_INFO);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 2,
|
|
|
|
FIELD_STATUS_CODE);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 4,
|
|
|
|
FIELD_ASSOC_ID);
|
|
|
|
|
|
|
|
next_idx = MGT_FRAME_LEN + 6; /* Size of fixed fields */
|
|
|
|
|
|
|
|
tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
|
|
|
|
pinfo->captured_len - 4 -
|
|
|
|
next_idx);
|
|
|
|
|
|
|
|
while (pinfo->captured_len > (next_idx + 4))
|
|
|
|
next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MGT_REASSOC_REQ:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Reassociation Request");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 10);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_CAP_INFO);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 2,
|
|
|
|
FIELD_LISTEN_IVAL);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 4,
|
|
|
|
FIELD_CURRENT_AP_ADDR);
|
|
|
|
|
|
|
|
next_idx = MGT_FRAME_LEN + 10; /* Size of fixed fields */
|
|
|
|
tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
|
|
|
|
pinfo->captured_len - 4 -
|
|
|
|
next_idx);
|
|
|
|
|
|
|
|
while ((pinfo->captured_len) > (next_idx + 4))
|
|
|
|
next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MGT_REASSOC_RESP:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Reassociation Response");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 10);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_CAP_INFO);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 2,
|
|
|
|
FIELD_STATUS_CODE);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 4,
|
|
|
|
FIELD_ASSOC_ID);
|
|
|
|
|
|
|
|
next_idx = MGT_FRAME_LEN + 6; /* Size of fixed fields */
|
|
|
|
tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
|
|
|
|
pinfo->captured_len - 4 -
|
|
|
|
next_idx);
|
|
|
|
|
|
|
|
while (pinfo->captured_len > (next_idx + 4))
|
|
|
|
next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MGT_PROBE_REQ:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Probe Request");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
next_idx = MGT_FRAME_LEN;
|
|
|
|
tagged_tree = get_tagged_parameter_tree (tree, tvb, MGT_FRAME_LEN,
|
|
|
|
pinfo->captured_len - 4 -
|
|
|
|
next_idx);
|
|
|
|
|
|
|
|
while (pinfo->captured_len > (next_idx + 4))
|
|
|
|
next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case MGT_PROBE_RESP:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Probe Response");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 12);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_TIMESTAMP);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 8,
|
|
|
|
FIELD_BEACON_INTERVAL);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 10,
|
|
|
|
FIELD_CAP_INFO);
|
|
|
|
|
|
|
|
next_idx = MGT_FRAME_LEN + 12; /* Size of fixed fields */
|
|
|
|
tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
|
|
|
|
pinfo->captured_len - 4 -
|
|
|
|
next_idx);
|
|
|
|
|
|
|
|
while ((pinfo->captured_len) > (next_idx + 4))
|
|
|
|
next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case MGT_BEACON: /* Dissect protocol payload fields */
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Beacon frame");
|
|
|
|
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 12);
|
|
|
|
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_TIMESTAMP);
|
|
|
|
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 8,
|
|
|
|
FIELD_BEACON_INTERVAL);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 10,
|
|
|
|
FIELD_CAP_INFO);
|
|
|
|
|
|
|
|
next_idx = MGT_FRAME_LEN + 12; /* Size of fixed fields */
|
|
|
|
tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
|
|
|
|
pinfo->captured_len - 4 -
|
|
|
|
next_idx);
|
|
|
|
|
|
|
|
while (pinfo->captured_len > (next_idx + 4))
|
|
|
|
next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case MGT_ATIM:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "ATIM");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MGT_DISASS:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Dissassociate");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
fixed_tree =
|
|
|
|
get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, cap_len);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_REASON_CODE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MGT_AUTHENTICATION:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Authentication");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, 6);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_AUTH_ALG);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 2,
|
|
|
|
FIELD_AUTH_TRANS_SEQ);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN + 4,
|
|
|
|
FIELD_STATUS_CODE);
|
|
|
|
|
|
|
|
next_idx = MGT_FRAME_LEN + 6; /* Size of fixed fields */
|
|
|
|
|
|
|
|
if ((pinfo->captured_len - next_idx - 4) != 0)
|
|
|
|
{
|
|
|
|
tagged_tree = get_tagged_parameter_tree (tree,
|
|
|
|
tvb,
|
|
|
|
next_idx,
|
|
|
|
pinfo->captured_len -
|
|
|
|
next_idx - 4);
|
|
|
|
|
|
|
|
while ((pinfo->captured_len) > (next_idx - 4))
|
|
|
|
next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MGT_DEAUTHENTICATION:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Deauthentication");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
fixed_tree = get_fixed_parameter_tree (hdr_tree, tvb, MGT_FRAME_LEN, 2);
|
|
|
|
add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_REASON_CODE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case CTRL_PS_POLL:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Power-Save poll");
|
|
|
|
|
|
|
|
src = tvb_get_ptr (tvb, 10, 6);
|
|
|
|
dst = tvb_get_ptr (tvb, 4, 6);
|
|
|
|
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_SRC))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_SRC,
|
|
|
|
"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (BSSID)",
|
|
|
|
src[0], src[1], src[2], src[3], src[4], src[5]);
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_DST))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_DST,
|
|
|
|
"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (TA)",
|
|
|
|
dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
|
|
|
|
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
|
|
|
|
tvb_get_ptr (tvb, 4, 6));
|
|
|
|
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
|
|
|
|
tvb_get_ptr (tvb, 10, 6));
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case CTRL_RTS:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Request-to-send");
|
|
|
|
src = tvb_get_ptr (tvb, 10, 6);
|
|
|
|
dst = tvb_get_ptr (tvb, 4, 6);
|
|
|
|
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_SRC))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_SRC,
|
|
|
|
"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (TA)",
|
|
|
|
src[0], src[1], src[2], src[3], src[4], src[5]);
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_DST))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_DST,
|
|
|
|
"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (RA)",
|
|
|
|
dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
|
|
|
|
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
|
|
|
|
tvb_get_ptr (tvb, 4, 6));
|
|
|
|
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6,
|
|
|
|
tvb_get_ptr (tvb, 10, 6));
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case CTRL_CTS:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Clear-to-send");
|
|
|
|
|
|
|
|
dst = tvb_get_ptr (tvb, 4, 6);
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_DST))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_DST,
|
|
|
|
"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (RA)",
|
|
|
|
dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
|
|
|
|
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
|
|
|
|
tvb_get_ptr (tvb, 4, 6));
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case CTRL_ACKNOWLEDGEMENT:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Acknowledgement");
|
|
|
|
|
|
|
|
dst = tvb_get_ptr (tvb, 4, 6);
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_DST))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_DST,
|
|
|
|
"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (RA)",
|
|
|
|
dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
|
|
|
|
|
|
|
|
if (tree)
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
|
|
|
|
tvb_get_ptr (tvb, 4, 6));
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case CTRL_CFP_END:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "CF-End (Control-frame)");
|
|
|
|
|
|
|
|
src = tvb_get_ptr (tvb, 10, 6);
|
|
|
|
dst = tvb_get_ptr (tvb, 4, 6);
|
|
|
|
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_SRC))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_SRC, "%X:%X:%X:%X:%X:%X (BSSID)",
|
|
|
|
src[0], src[1], src[2], src[3], src[4], src[5]);
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_DST))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_DST, "%X:%X:%X:%X:%X:%X (RA)",
|
|
|
|
dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
|
|
|
|
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
|
|
|
|
tvb_get_ptr (tvb, 4, 6));
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
|
|
|
|
tvb_get_ptr (tvb, 10, 6));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case CTRL_CFP_ENDACK:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "CF-End + CF-Ack (Control-frame)");
|
|
|
|
|
|
|
|
src = tvb_get_ptr (tvb, 10, 6);
|
|
|
|
dst = tvb_get_ptr (tvb, 4, 6);
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_SRC))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_SRC, "%X:%X:%X:%X:%X:%X (BSSID)",
|
|
|
|
src[0], src[1], src[2], src[3], src[4], src[5]);
|
|
|
|
|
|
|
|
if (check_col (pinfo->fd, COL_DEF_DST))
|
|
|
|
col_add_fstr (pinfo->fd, COL_DEF_DST, "%X:%X:%X:%X:%X:%X (RA)",
|
|
|
|
dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
|
|
|
|
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
|
|
|
|
tvb_get_ptr (tvb, 4, 6));
|
|
|
|
|
|
|
|
proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
|
|
|
|
tvb_get_ptr (tvb, 10, 6));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case DATA:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Data");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
hdr_len = find_header_length (tvb_get_ptr (tvb, 0, cap_len), 0);
|
|
|
|
|
|
|
|
next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
|
2001-01-03 10:34:42 +00:00
|
|
|
call_dissector (llc_handle, next_tvb, pinfo, tree);
|
2000-11-15 05:42:35 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case DATA_CF_ACK:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Data + CF-Acknowledgement");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
hdr_len = find_header_length (tvb_get_ptr (tvb, 0, cap_len), 0);
|
|
|
|
|
|
|
|
next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
|
2001-01-03 10:34:42 +00:00
|
|
|
call_dissector (llc_handle, next_tvb, pinfo, tree);
|
2000-11-15 05:42:35 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case DATA_CF_POLL:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Data + CF-Poll");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
hdr_len = find_header_length (tvb_get_ptr (tvb, 0, cap_len), 0);
|
|
|
|
next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
|
2001-01-03 10:34:42 +00:00
|
|
|
call_dissector (llc_handle, next_tvb, pinfo, tree);
|
2000-11-15 05:42:35 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case DATA_CF_ACK_POLL:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Data + CF-Acknowledgement/Poll");
|
|
|
|
if (tree)
|
|
|
|
{
|
|
|
|
hdr_len = find_header_length (tvb_get_ptr (tvb, 0, cap_len), 0);
|
|
|
|
next_tvb = tvb_new_subset (tvb, hdr_len, -1, -1);
|
2001-01-03 10:34:42 +00:00
|
|
|
call_dissector (llc_handle, next_tvb, pinfo, tree);
|
2000-11-15 05:42:35 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case DATA_NULL_FUNCTION:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Null function (No data)");
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case DATA_CF_ACK_NOD:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Data + Acknowledgement(No data)");
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
2001-02-01 06:20:25 +00:00
|
|
|
case DATA_CF_POLL_NOD:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Data + CF-Poll (No data)");
|
|
|
|
break;
|
|
|
|
|
2000-11-15 05:42:35 +00:00
|
|
|
|
|
|
|
case DATA_CF_ACK_POLL_NOD:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Data + CF-Acknowledgement/Poll (No data)");
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
COL_SHOW_INFO (pinfo->fd, "Unrecognized (Reserved frame)");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
proto_register_wlan (void)
|
|
|
|
{
|
|
|
|
|
|
|
|
static const value_string tofrom_ds[] = {
|
2001-01-23 05:54:09 +00:00
|
|
|
{0, "Not leaving DS or network is operating in AD-HOC mode ( To DS: 0 From DS: 0)"},
|
2000-11-15 05:42:35 +00:00
|
|
|
{1, "Frame is exiting DS (To DS: 0 From DS: 1)"},
|
2001-01-23 05:54:09 +00:00
|
|
|
{2, "Frame is entering DS (To DS: 1 From DS: 0)"},
|
2000-11-15 05:42:35 +00:00
|
|
|
{3, "Frame part of WDS (To DS: 1 From DS: 1)"},
|
|
|
|
{0, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tods_flag = {
|
|
|
|
"TO DS: Should be false",
|
|
|
|
"Not used"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string fromds_flag = {
|
|
|
|
"FROM DS: Should be false",
|
|
|
|
"Not used"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string more_frags = {
|
|
|
|
"MSDU/MMPDU is fragmented",
|
|
|
|
"No fragments"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string retry_flags = {
|
|
|
|
"Frame is being retransmitted",
|
|
|
|
"Frame is not being retransmitted"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string pm_flags = {
|
|
|
|
"STA will go to sleep",
|
|
|
|
"STA will stay up"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string md_flags = {
|
|
|
|
"Data is buffered for STA at AP",
|
|
|
|
"No data buffered"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string wep_flags = {
|
|
|
|
"WEP is enabled",
|
|
|
|
"WEP is disabled"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string order_flags = {
|
|
|
|
"",
|
|
|
|
""
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string cf_ess_flags = {
|
|
|
|
"Transmitter is an AP",
|
|
|
|
"Transmitter is a STA"
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static const true_false_string cf_privacy_flags = {
|
|
|
|
"AP/STA can support WEP",
|
|
|
|
"AP/STA cannot support WEP"
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static const true_false_string cf_ibss_flags = {
|
|
|
|
"Transmitter belongs to an IBSS",
|
|
|
|
"Transmitter belongs to a BSS"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string sta_cf_pollable[] = {
|
|
|
|
{0x00, "Station is not CF-Pollable"},
|
|
|
|
{0x02, "Station is CF-Pollable, "
|
|
|
|
"not requesting to be placed on the CF-polling list"},
|
|
|
|
{0x01, "Station is CF-Pollable, "
|
|
|
|
"requesting to be placed on the CF-polling list"},
|
|
|
|
{0x03, "Station is CF-Pollable, requesting never to be polled"},
|
|
|
|
{0, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string ap_cf_pollable[] = {
|
|
|
|
{0x00, "No point coordinator at AP"},
|
|
|
|
{0x02, "Point coordinator at AP for delivery only (no polling)"},
|
|
|
|
{0x01, "Point coordinator at AP for delivery and polling"},
|
|
|
|
{0x03, "Reserved"},
|
|
|
|
{0, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static const value_string auth_alg[] = {
|
|
|
|
{0x00, "Open System"},
|
|
|
|
{0x01, "Shared key"},
|
|
|
|
{0, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string reason_codes[] = {
|
|
|
|
{0x00, "Reserved"},
|
|
|
|
{0x01, "Unspecified reason"},
|
|
|
|
{0x02, "Previous authentication no longer valid"},
|
|
|
|
{0x03, "Deauthenticated because sending STA is leaving (has left) "
|
|
|
|
"IBSS or ESS"},
|
|
|
|
{0x04, "Disassociated due to inactivity"},
|
|
|
|
{0x05, "Disassociated because AP is unable to handle all currently "
|
|
|
|
"associated stations"},
|
|
|
|
{0x06, "Class 2 frame received from nonauthenticated station"},
|
|
|
|
{0x07, "Class 3 frame received from nonassociated station"},
|
|
|
|
{0x08, "Disassociated because sending STA is leaving (has left) BSS"},
|
|
|
|
{0x09, "Station requesting (re)association is not authenticated with "
|
|
|
|
"responding station"},
|
|
|
|
{0x00, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static const value_string status_codes[] = {
|
|
|
|
{0x00, "Successful"},
|
|
|
|
{0x01, "Unspecified failure"},
|
|
|
|
{0x0A, "Cannot support all requested capabilities in the "
|
|
|
|
"Capability information field"},
|
|
|
|
{0x0B, "Reassociation denied due to inability to confirm that "
|
|
|
|
"association exists"},
|
|
|
|
{0x0C, "Association denied due to reason outside the scope of this "
|
|
|
|
"standard"},
|
|
|
|
|
|
|
|
{0x0D, "Responding station does not support the specified authentication "
|
|
|
|
"algorithm"},
|
|
|
|
{0x0E, "Received an Authentication frame with authentication sequence "
|
|
|
|
"transaction sequence number out of expected sequence"},
|
|
|
|
{0x0F, "Authentication rejected because of challenge failure"},
|
|
|
|
{0x10, "Authentication rejected due to timeout waiting for next "
|
|
|
|
"frame in sequence"},
|
|
|
|
{0x11, "Association denied because AP is unable to handle additional "
|
|
|
|
"associated stations"},
|
|
|
|
{0x12, "Association denied due to requesting station not supporting all "
|
|
|
|
"of the datarates in the BSSBasicServiceSet Parameter"},
|
|
|
|
{0x00, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static hf_register_info hf[] = {
|
|
|
|
{&hf_fc_field,
|
|
|
|
{"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0,
|
|
|
|
"MAC Frame control"}},
|
|
|
|
|
|
|
|
{&hf_fc_proto_version,
|
|
|
|
{"Version", "wlan.fc.version", FT_UINT8, BASE_DEC, NULL, 0,
|
|
|
|
"MAC Protocol version"}}, /* 0 */
|
|
|
|
|
|
|
|
{&hf_fc_frame_type,
|
|
|
|
{"Type", "wlan.fc.type", FT_UINT8, BASE_DEC, NULL, 0,
|
|
|
|
"Frame type"}},
|
|
|
|
|
|
|
|
{&hf_fc_frame_subtype,
|
|
|
|
{"Subtype", "wlan.fc.subtype", FT_UINT8, BASE_DEC, NULL, 0,
|
|
|
|
"Frame subtype"}}, /* 2 */
|
|
|
|
|
|
|
|
{&hf_fc_flags,
|
|
|
|
{"Protocol Flags", "wlan.flags", FT_UINT8, BASE_HEX, NULL, 0,
|
|
|
|
"Protocol flags"}},
|
|
|
|
|
|
|
|
{&hf_fc_data_ds,
|
|
|
|
{"DS status", "wlan.fc.ds", FT_UINT8, BASE_HEX, TFS (&tofrom_ds), 0,
|
|
|
|
"Data-frame DS-traversal status"}}, /* 3 */
|
|
|
|
|
|
|
|
{&hf_fc_to_ds,
|
|
|
|
{"To DS", "wlan.fc.tods", FT_BOOLEAN, 8, TFS (&tods_flag), 0x1,
|
|
|
|
"To DS flag"}}, /* 4 */
|
|
|
|
|
|
|
|
{&hf_fc_from_ds,
|
|
|
|
{"From DS", "wlan.fc.fromds", FT_BOOLEAN, 8, TFS (&fromds_flag), 0x2,
|
|
|
|
"From DS flag"}}, /* 5 */
|
|
|
|
|
|
|
|
{&hf_fc_more_frag,
|
|
|
|
{"Fragments", "wlan.fc.frag", FT_BOOLEAN, 8, TFS (&more_frags), 0x4,
|
|
|
|
"More Fragments flag"}}, /* 6 */
|
|
|
|
|
|
|
|
{&hf_fc_retry,
|
|
|
|
{"Retry", "wlan.fc.retry", FT_BOOLEAN, 8, TFS (&retry_flags), 0x8,
|
|
|
|
"Retransmission flag"}},
|
|
|
|
|
|
|
|
{&hf_fc_pwr_mgt,
|
|
|
|
{"PWR MGT", "wlan.fc.pwrmgt", FT_BOOLEAN, 8, TFS (&pm_flags), 0x10,
|
|
|
|
"Power management status"}},
|
|
|
|
|
|
|
|
{&hf_fc_more_data,
|
|
|
|
{"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), 0x20,
|
|
|
|
"More data flag"}},
|
|
|
|
|
|
|
|
{&hf_fc_wep,
|
|
|
|
{"WEP flag", "wlan.fc.wep", FT_BOOLEAN, 8, TFS (&wep_flags), 0x40,
|
|
|
|
"WEP flag"}},
|
|
|
|
|
|
|
|
{&hf_fc_order,
|
|
|
|
{"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), 0x80,
|
|
|
|
"Strictly ordered flag"}},
|
|
|
|
|
2001-02-01 06:20:25 +00:00
|
|
|
{&hf_assoc_id,
|
|
|
|
{"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
|
|
|
|
"Association-ID field" }},
|
|
|
|
|
2000-11-15 05:42:35 +00:00
|
|
|
{&hf_did_duration,
|
|
|
|
{"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,
|
|
|
|
"Duration field"}},
|
|
|
|
|
|
|
|
{&hf_addr_da,
|
|
|
|
{"Destination address", "wlan.da", FT_ETHER, BASE_NONE, NULL, 0,
|
|
|
|
"Destination Hardware address"}},
|
|
|
|
|
|
|
|
{&hf_addr_sa,
|
|
|
|
{"Source address", "wlan.sa", FT_ETHER, BASE_NONE, NULL, 0,
|
|
|
|
"Source Hardware address"}},
|
|
|
|
|
|
|
|
{&hf_addr_ra,
|
|
|
|
{"Receiver address", "wlan.ra", FT_ETHER, BASE_NONE, NULL, 0,
|
|
|
|
"Receiving Station Hardware Address"}},
|
|
|
|
|
|
|
|
{&hf_addr_ta,
|
|
|
|
{"Transmitter address", "wlan.ta", FT_ETHER, BASE_NONE, NULL, 0,
|
|
|
|
"Transmitting Station Hardware Address"}},
|
|
|
|
|
|
|
|
{&hf_addr_bssid,
|
|
|
|
{"BSS Id", "wlan.bssid", FT_ETHER, BASE_NONE, NULL, 0,
|
|
|
|
"Basic Service Set ID"}},
|
|
|
|
|
|
|
|
{&hf_frag_number,
|
|
|
|
{"Fragment number", "wlan.frag", FT_UINT16, BASE_HEX, NULL, 0,
|
|
|
|
"Fragment number"}},
|
|
|
|
|
|
|
|
{&hf_seq_number,
|
|
|
|
{"Sequence number", "wlan.seq", FT_UINT16, BASE_HEX, NULL, 0,
|
|
|
|
"Fragment number"}},
|
|
|
|
|
|
|
|
{&hf_fcs,
|
|
|
|
{"Frame Check Sequence (not verified)", "wlan.fcs", FT_UINT32, BASE_HEX,
|
|
|
|
NULL, 0, ""}},
|
|
|
|
|
|
|
|
{&ff_timestamp,
|
|
|
|
{"Timestamp", "wlan.fixed.timestamp", FT_STRING, BASE_NONE,
|
|
|
|
NULL, 0, ""}},
|
|
|
|
|
|
|
|
{&ff_auth_alg,
|
|
|
|
{"Authentication Algorithm", "wlan.fixed.auth.alg",
|
|
|
|
FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, ""}},
|
|
|
|
|
|
|
|
{&ff_beacon_interval,
|
|
|
|
{"Beacon Interval", "wlan.fixed.beacon", FT_UINT16, BASE_DEC, NULL, 0,
|
|
|
|
""}},
|
|
|
|
|
|
|
|
{&hf_fixed_parameters,
|
|
|
|
{"Fixed parameters", "wlan.fixed.all", FT_UINT16, BASE_DEC, NULL, 0,
|
|
|
|
""}},
|
|
|
|
|
|
|
|
{&hf_tagged_parameters,
|
|
|
|
{"Tagged parameters", "wlan.tagged.all", FT_UINT16, BASE_DEC, NULL, 0,
|
|
|
|
""}},
|
|
|
|
|
|
|
|
{&ff_capture,
|
|
|
|
{"Capabilities", "wlan.fixed.capabilities", FT_UINT16, BASE_HEX, NULL, 0,
|
|
|
|
"Capability information"}},
|
|
|
|
|
|
|
|
{&ff_cf_sta_poll,
|
|
|
|
{"CFP participation capabilities", "wlan.fixed.capabilities.cfpoll.sta",
|
|
|
|
FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0,
|
|
|
|
"CF-Poll capabilities for a STA"}},
|
|
|
|
|
|
|
|
{&ff_cf_ap_poll,
|
|
|
|
{"CFP participation capabilities", "wlan.fixed.capabilities.cfpoll.ap",
|
|
|
|
FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0,
|
|
|
|
"CF-Poll capabilities for an AP"}},
|
|
|
|
|
|
|
|
{&ff_cf_ess,
|
|
|
|
{"ESS capabilities", "wlan.fixed.capabilities.ess",
|
|
|
|
FT_BOOLEAN, 1, TFS (&cf_ess_flags), 0x0001, "ESS capabilities"}},
|
|
|
|
|
|
|
|
|
|
|
|
{&ff_cf_ibss,
|
|
|
|
{"IBSS status", "wlan.fixed.capabilities.ibss",
|
|
|
|
FT_BOOLEAN, 1, TFS (&cf_ibss_flags), 0x0002, "IBSS participation"}},
|
|
|
|
|
|
|
|
{&ff_cf_privacy,
|
|
|
|
{"Privacy", "wlan.fixed.capabilities.privacy",
|
|
|
|
FT_BOOLEAN, 1, TFS (&cf_privacy_flags), 0x0010, "WEP support"}},
|
|
|
|
|
|
|
|
|
|
|
|
{&ff_auth_seq,
|
|
|
|
{"Authentication SEQ", "wlan.fixed.auth_seq",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number"}},
|
|
|
|
|
|
|
|
{&ff_assoc_id,
|
|
|
|
{"Association ID", "wlan.fixed.aid",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0, "Association ID"}},
|
|
|
|
|
|
|
|
{&ff_listen_ival,
|
|
|
|
{"Listen Interval", "wlan.fixed.listen_ival",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0, "Listen Interval"}},
|
|
|
|
|
|
|
|
{&ff_current_ap,
|
|
|
|
{"Current AP", "wlan.fixed.current_ap",
|
|
|
|
FT_ETHER, BASE_NONE, NULL, 0, "MAC address of current AP"}},
|
|
|
|
|
|
|
|
{&ff_reason,
|
|
|
|
{"Reason code", "wlan.fixed.reason_code",
|
|
|
|
FT_UINT16, BASE_HEX, VALS (&reason_codes), 0,
|
|
|
|
"Reason for unsolicited notification"}},
|
|
|
|
|
|
|
|
{&ff_status_code,
|
|
|
|
{"Status code", "wlan.fixed.status_code",
|
|
|
|
FT_UINT16, BASE_HEX, VALS (&status_codes), 0,
|
|
|
|
"Status of requested event"}},
|
|
|
|
|
|
|
|
{&tag_number,
|
|
|
|
{"Tag", "wlan.tag.number",
|
|
|
|
FT_UINT16, BASE_DEC, NULL, 0,
|
|
|
|
"Element ID"}},
|
|
|
|
|
|
|
|
{&tag_length,
|
|
|
|
{"Tag length", "wlan.tag.length",
|
|
|
|
FT_UINT16, BASE_DEC, NULL, 0, "Length of tag"}},
|
|
|
|
|
|
|
|
{&tag_interpretation,
|
|
|
|
{"Tag interpretation", "wlan.tag.interpretation",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag"}}
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static gint *tree_array[] = { &ett_80211,
|
|
|
|
&ett_fc_tree,
|
|
|
|
&ett_proto_flags,
|
|
|
|
&ett_fixed_parameters,
|
|
|
|
&ett_tagged_parameters,
|
|
|
|
&ett_cap_tree,
|
|
|
|
};
|
|
|
|
|
2001-01-03 06:56:03 +00:00
|
|
|
proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
|
|
|
|
"IEEE 802.11", "wlan");
|
2000-11-15 05:42:35 +00:00
|
|
|
proto_register_field_array (proto_wlan, hf, array_length (hf));
|
|
|
|
proto_register_subtree_array (tree_array, array_length (tree_array));
|
|
|
|
}
|
2000-11-29 05:16:15 +00:00
|
|
|
|
|
|
|
void
|
2000-11-30 03:19:27 +00:00
|
|
|
proto_reg_handoff_wlan(void)
|
2000-11-29 05:16:15 +00:00
|
|
|
{
|
2001-01-03 10:34:42 +00:00
|
|
|
/*
|
|
|
|
* Get a handle for the LLC dissector.
|
|
|
|
*/
|
|
|
|
llc_handle = find_dissector("llc");
|
|
|
|
|
2001-01-09 06:32:10 +00:00
|
|
|
dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, dissect_ieee80211,
|
|
|
|
proto_wlan);
|
2000-11-29 05:16:15 +00:00
|
|
|
}
|