*
* $Id$
*
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* Copied from README.developer
#include <stdio.h>
#include <stdlib.h>
-#ifdef NEED_SNPRINTF_H
-# include "snprintf.h"
-#endif
-
#include <string.h>
#include <glib.h>
#include <epan/bitswap.h>
#include "packet-ipx.h"
#include "packet-llc.h"
#include "packet-ieee80211.h"
-#include "etypes.h"
+#include <epan/etypes.h>
+#include <epan/oui.h>
#include <epan/crc32.h>
#include <epan/tap.h>
+#include <epan/emem.h>
#include <ctype.h>
#include "isprint.h"
+#ifdef HAVE_AIRPCAP
+#include <airpcap.h>
+#else
+/* XXX - This is probably a bit much */
+#define MAX_ENCRYPTION_KEYS 64
+#endif
+
+#ifndef roundup2
+#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
+#endif
+
/* Defragment fragmented 802.11 datagrams */
static gboolean wlan_defragment = TRUE;
static GHashTable *wlan_reassembled_table = NULL;
/* Stuff for the WEP decoder */
+/* XXX - Instead of making the user specify the number of WEP keys manually,
+ * we may want to change the "WEP key count" option to a toggle that
+ * enables/disables WEP decryption, and automatically figure out how
+ * many keys we have by parsing the key list.
+ */
static gint num_wepkeys = 0;
static guint8 **wep_keys = NULL;
static int *wep_keylens = NULL;
/* When this is set, an unlimited number of WEP keys can be set in the
environment:
- ETHEREAL_WEPKEYNUM=##
- ETHEREAL_WEPKEY1=aa:bb:cc:dd:...
- ETHEREAL_WEPKEY2=aa:bab:cc:dd:ee:...
+ WIRESHARK_WEPKEYNUM=##
+ WIRESHARK_WEPKEY1=aa:bb:cc:dd:...
+ WIRESHARK_WEPKEY2=aa:bab:cc:dd:ee:...
... you get the idea.
*/
#ifndef USE_ENV
-static char *wep_keystr[] = {NULL, NULL, NULL, NULL};
+static char *wep_keystr[MAX_ENCRYPTION_KEYS];
#endif
/* ************************************************************************* */
/* ************************************************************************* */
/* 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)
-#define COOK_ADDR_SELECTOR(x) ((x) & 0x300)
-#define COOK_ASSOC_ID(x) ((x) & 0x3FFF)
-#define COOK_FRAGMENT_NUMBER(x) ((x) & 0x000F)
-#define COOK_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
-#define COOK_QOS_PRIORITY(x) ((x) & 0x0007)
-#define COOK_QOS_ACK_POLICY(x) (((x) & 0x0060) >> 5)
-#define COOK_FLAGS(x) (((x) & 0xFF00) >> 8)
-#define COOK_DS_STATUS(x) ((x) & 0x3)
-#define COOK_WEP_KEY(x) (((x) & 0xC0) >> 6)
-#define KEY_EXTIV 0x20
-#define EXTIV_LEN 8
+/*
+ * Extract the protocol version from the frame control field
+ */
+#define FCF_PROT_VERSION(x) ((x) & 0x3)
+
+/*
+ * Extract the frame type from the frame control field.
+ */
+#define FCF_FRAME_TYPE(x) (((x) & 0xC) >> 2)
+/*
+ * Extract the frame subtype from the frame control field.
+ */
+#define FCF_FRAME_SUBTYPE(x) (((x) & 0xF0) >> 4)
+
+/*
+ * Convert the frame type and subtype from the frame control field into
+ * one of the MGT_, CTRL_, or DATA_ values.
+ */
+#define COMPOSE_FRAME_TYPE(x) (((x & 0x0C)<< 2)+FCF_FRAME_SUBTYPE(x)) /* Create key to (sub)type */
+
+/*
+ * The subtype field of a data frame is, in effect, composed of 4 flag
+ * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have
+ * any data), and QoS.
+ */
+#define DATA_FRAME_IS_CF_ACK(x) ((x) & 0x01)
+#define DATA_FRAME_IS_CF_POLL(x) ((x) & 0x02)
+#define DATA_FRAME_IS_NULL(x) ((x) & 0x04)
+#define DATA_FRAME_IS_QOS(x) ((x) & 0x08)
+
+/*
+ * Extract the flags from the frame control field.
+ */
+#define FCF_FLAGS(x) (((x) & 0xFF00) >> 8)
+
+/*
+ * Bits from the flags field.
+ */
#define FLAG_TO_DS 0x01
#define FLAG_FROM_DS 0x02
#define FLAG_MORE_FRAGMENTS 0x04
#define FLAG_RETRY 0x08
#define FLAG_POWER_MGT 0x10
#define FLAG_MORE_DATA 0x20
-#define FLAG_WEP 0x40
+#define FLAG_PROTECTED 0x40
#define FLAG_ORDER 0x80
+/*
+ * Test bits in the flags field.
+ */
#define IS_TO_DS(x) ((x) & FLAG_TO_DS)
#define IS_FROM_DS(x) ((x) & FLAG_FROM_DS)
#define HAVE_FRAGMENTS(x) ((x) & FLAG_MORE_FRAGMENTS)
#define IS_RETRY(x) ((x) & FLAG_RETRY)
#define POWER_MGT_STATUS(x) ((x) & FLAG_POWER_MGT)
#define HAS_MORE_DATA(x) ((x) & FLAG_MORE_DATA)
-#define IS_WEP(x) (!wlan_ignore_wep && ((x) & FLAG_WEP))
+#define IS_PROTECTED(x) (!wlan_ignore_wep && ((x) & FLAG_PROTECTED))
#define IS_STRICTLY_ORDERED(x) ((x) & FLAG_ORDER)
-#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))
+/*
+ * Extract subfields from the flags field.
+ */
+#define FLAGS_DS_STATUS(x) ((x) & (FLAG_FROM_DS|FLAG_TO_DS))
+
+/*
+ * Extract an indication of the types of addresses in a data frame from
+ * the frame control field.
+ */
+#define FCF_ADDR_SELECTOR(x) ((x) & ((FLAG_TO_DS|FLAG_FROM_DS) << 8))
+
+#define DATA_ADDR_T1 0
+#define DATA_ADDR_T2 (FLAG_FROM_DS << 8)
+#define DATA_ADDR_T3 (FLAG_TO_DS << 8)
+#define DATA_ADDR_T4 ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
+
+/*
+ * Extract the fragment number and sequence number from the sequence
+ * control field.
+ */
+#define SEQCTL_FRAGMENT_NUMBER(x) ((x) & 0x000F)
+#define SEQCTL_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
+
+/*
+ * Extract subfields from the QoS control field.
+ */
+#define QOS_TID(x) ((x) & 0x000F)
+#define QOS_PRIORITY(x) ((x) & 0x0007)
+#define QOS_EOSP(x) (((x) & 0x0010) >> 4) /* end of service period */
+#define QOS_ACK_POLICY(x) (((x) & 0x0060) >> 5)
+#define QOS_FIELD_CONTENT(x) (((x) & 0xFF00) >> 8)
+
+#define QOS_FLAG_EOSP 0x08
+
+/*
+ * Extract subfields from the result of QOS_FIELD_CONTENT().
+ */
+#define QOS_PS_BUF_STATE(x) (((x) & 0x02) >> 1)
+#define QOS_PS_BUF_AC(x) (((x) & 0x0C) >> 2)
+#define QOS_PS_BUF_LOAD(x) (((x) & 0xF0) >> 4)
+
+/*
+ * Extract the association ID from the value in an association ID field.
+ */
+#define ASSOC_ID(x) ((x) & 0x3FFF)
+
+/*
+ * Extract subfields from the key octet in WEP-encrypted frames.
+ */
+#define KEY_OCTET_WEP_KEY(x) (((x) & 0xC0) >> 6)
+
+#define KEY_EXTIV 0x20
+#define EXTIV_LEN 8
/* ************************************************************************* */
#define DATA_LONG_HDR_LEN 30
#define MGT_FRAME_HDR_LEN 24 /* Length of Managment frame-headers */
-#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 MGT_ACTION 0x0D /* Management - Action */
-
-#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 */
-#define DATA_CF_ACK_POLL 0x23 /* Data - Data + CF acknowledge + CF poll */
-#define DATA_NULL_FUNCTION 0x24 /* Data - Null function (no data) */
-#define DATA_CF_ACK_NOD 0x25 /* Data - CF ack (no data) */
-#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) */
-#define DATA_QOS_DATA 0x28 /* Data - QoS Data */
-#define DATA_QOS_NULL 0x2c /* Data - QoS Null */
+/*
+ * COMPOSE_FRAME_TYPE() values for management frames.
+ */
+#define MGT_ASSOC_REQ 0x00 /* association request */
+#define MGT_ASSOC_RESP 0x01 /* association response */
+#define MGT_REASSOC_REQ 0x02 /* reassociation request */
+#define MGT_REASSOC_RESP 0x03 /* reassociation response */
+#define MGT_PROBE_REQ 0x04 /* Probe request */
+#define MGT_PROBE_RESP 0x05 /* Probe response */
+#define MGT_BEACON 0x08 /* Beacon frame */
+#define MGT_ATIM 0x09 /* ATIM */
+#define MGT_DISASS 0x0A /* Disassociation */
+#define MGT_AUTHENTICATION 0x0B /* Authentication */
+#define MGT_DEAUTHENTICATION 0x0C /* Deauthentication */
+#define MGT_ACTION 0x0D /* Action */
-#define DATA_ADDR_T1 0
-#define DATA_ADDR_T2 (FLAG_FROM_DS << 8)
-#define DATA_ADDR_T3 (FLAG_TO_DS << 8)
-#define DATA_ADDR_T4 ((FLAG_TO_DS|FLAG_FROM_DS) << 8)
+/*
+ * COMPOSE_FRAME_TYPE() values for control frames.
+ */
+#define CTRL_BLOCK_ACK_REQ 0x18 /* Block ack Request */
+#define CTRL_BLOCK_ACK 0x19 /* Block ack */
+#define CTRL_PS_POLL 0x1A /* power-save poll */
+#define CTRL_RTS 0x1B /* request to send */
+#define CTRL_CTS 0x1C /* clear to send */
+#define CTRL_ACKNOWLEDGEMENT 0x1D /* acknowledgement */
+#define CTRL_CFP_END 0x1E /* contention-free period end */
+#define CTRL_CFP_ENDACK 0x1F /* contention-free period end/ack */
+
+/*
+ * COMPOSE_FRAME_TYPE() values for data frames.
+ */
+#define DATA 0x20 /* Data */
+#define DATA_CF_ACK 0x21 /* Data + CF-Ack */
+#define DATA_CF_POLL 0x22 /* Data + CF-Poll */
+#define DATA_CF_ACK_POLL 0x23 /* Data + CF-Ack + CF-Poll */
+#define DATA_NULL_FUNCTION 0x24 /* Null function (no data) */
+#define DATA_CF_ACK_NOD 0x25 /* CF-Ack (no data) */
+#define DATA_CF_POLL_NOD 0x26 /* CF-Poll (No data) */
+#define DATA_CF_ACK_POLL_NOD 0x27 /* CF-Ack + CF-Poll (no data) */
+
+#define DATA_QOS_DATA 0x28 /* QoS Data */
+#define DATA_QOS_DATA_CF_ACK 0x29 /* QoS Data + CF-Ack */
+#define DATA_QOS_DATA_CF_POLL 0x2A /* QoS Data + CF-Poll */
+#define DATA_QOS_DATA_CF_ACK_POLL 0x2B /* QoS Data + CF-Ack + CF-Poll */
+#define DATA_QOS_NULL 0x2C /* QoS Null */
+#define DATA_QOS_CF_POLL_NOD 0x2E /* QoS CF-Poll (No Data) */
+#define DATA_QOS_CF_ACK_POLL_NOD 0x2F /* QoS CF-Ack + CF-Poll (No Data) */
/* ************************************************************************* */
#define TAG_COUNTRY_INFO 0x07
#define TAG_FH_HOPPING_PARAMETER 0x08
#define TAG_FH_HOPPING_TABLE 0x09
+#define TAG_REQUEST 0x0A
+#define TAG_QBSS_LOAD 0x0B
+#define TAG_EDCA_PARAM_SET 0x0C
+#define TAG_TRAF_SPEC 0x0D
+#define TAG_TRAF_CLASS 0x0E
+#define TAG_SCHEDULE 0x0F
#define TAG_CHALLENGE_TEXT 0x10
+#define TAG_POWER_CONSTRAINT 0x20
+#define TAG_POWER_CAPABILITY 0x21
+#define TAG_TPC_REQUEST 0x22
+#define TAG_TPC_REPORT 0x23
+#define TAG_SUPPORTED_CHANNELS 0x24
+#define TAG_CHANNEL_SWITCH_ANN 0x25
+#define TAG_MEASURE_REQ 0x26
+#define TAG_MEASURE_REP 0x27
+#define TAG_QUIET 0x28
+#define TAG_IBSS_DFS 0x29
#define TAG_ERP_INFO 0x2A
+#define TAG_TS_DELAY 0x2B
+#define TAG_TCLAS_PROCESS 0x2C
+#define TAG_QOS_CAPABILITY 0x2E
#define TAG_ERP_INFO_OLD 0x2F /* IEEE Std 802.11g/D4.0 */
#define TAG_RSN_IE 0x30
#define TAG_EXT_SUPP_RATES 0x32
+#define TAG_AGERE_PROPRIETARY 0x80
#define TAG_CISCO_UNKNOWN_1 0x85 /* Cisco Compatible eXtensions? */
#define TAG_CISCO_UNKNOWN_2 0x88 /* Cisco Compatible eXtensions? */
#define TAG_VENDOR_SPECIFIC_IE 0xDD
+#define TAG_SYMBOL_PROPRIETARY 0xAD
#define WPA_OUI "\x00\x50\xF2"
#define RSN_OUI "\x00\x0F\xAC"
{MGT_AUTHENTICATION, "Authentication"},
{MGT_DEAUTHENTICATION, "Deauthentication"},
{MGT_ACTION, "Action"},
+
+ {CTRL_BLOCK_ACK_REQ, "802.11 Block Ack Req"},
+ {CTRL_BLOCK_ACK, "802.11 Block Ack"},
{CTRL_PS_POLL, "Power-Save poll"},
{CTRL_RTS, "Request-to-send"},
{CTRL_CTS, "Clear-to-send"},
{CTRL_ACKNOWLEDGEMENT, "Acknowledgement"},
{CTRL_CFP_END, "CF-End (Control-frame)"},
{CTRL_CFP_ENDACK, "CF-End + CF-Ack (Control-frame)"},
+
{DATA, "Data"},
- {DATA_CF_ACK, "Data + CF-Acknowledgement"},
+ {DATA_CF_ACK, "Data + CF-Ack"},
{DATA_CF_POLL, "Data + CF-Poll"},
- {DATA_CF_ACK_POLL, "Data + CF-Acknowledgement/Poll"},
+ {DATA_CF_ACK_POLL, "Data + CF-Ack + CF-Poll"},
{DATA_NULL_FUNCTION, "Null function (No data)"},
- {DATA_CF_ACK_NOD, "Data + Acknowledgement (No data)"},
- {DATA_CF_POLL_NOD, "Data + CF-Poll (No data)"},
- {DATA_CF_ACK_POLL_NOD, "Data + CF-Acknowledgement/Poll (No data)"},
+ {DATA_CF_ACK_NOD, "Acknowledgement (No data)"},
+ {DATA_CF_POLL_NOD, "CF-Poll (No data)"},
+ {DATA_CF_ACK_POLL_NOD, "CF-Ack/Poll (No data)"},
{DATA_QOS_DATA, "QoS Data"},
- {DATA_QOS_NULL, "QoS Null (No data)"},
+ {DATA_QOS_DATA_CF_ACK, "QoS Data + CF-Acknowledgment"},
+ {DATA_QOS_DATA_CF_POLL, "QoS Data + CF-Poll"},
+ {DATA_QOS_DATA_CF_ACK_POLL, "QoS Data + CF-Ack + CF-Poll"},
+ {DATA_QOS_NULL, "QoS Null function (No data)"},
+ {DATA_QOS_CF_POLL_NOD, "QoS CF-Poll (No Data)"},
+ {DATA_QOS_CF_ACK_POLL_NOD, "QoS CF-Ack + CF-Poll (No data)"},
{0, NULL}
};
"Voice",
};
+
+#define CAT_SPECTRUM_MGMT 0
+#define CAT_QOS 1
+#define CAT_DLS 2
+#define CAT_BLOCK_ACK 3
+#define CAT_MGMT_NOTIFICATION 17
+
+#define SM_ACTION_MEASUREMENT_REQUEST 0
+#define SM_ACTION_MEASUREMENT_REPORT 1
+#define SM_ACTION_TPC_REQUEST 2
+#define SM_ACTION_TPC_REPORT 3
+#define SM_ACTION_CHAN_SWITCH_ANNC 4
+
static int proto_wlan = -1;
+static packet_info * g_pinfo;
/* ************************************************************************* */
/* Header field info values for radio information */
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_protected = -1;
static int hf_fc_order = -1;
/* ************************************************************************* */
static int hf_qos_priority = -1;
static int hf_qos_ack_policy = -1;
+static int hf_qos_eosp = -1;
+static int hf_qos_field_content = -1;
+/*static int hf_qos_txop_limit = -1;*/
+/* FIXME: hf_ values not defined
+static int hf_qos_buf_state = -1;
+static int hf_qos_buf_ac = -1;
+static int hf_qos_buf_load = -1;
+*/
+/*static int hf_qos_txop_dur_req = -1;
+static int hf_qos_queue_size = -1;*/
/* ************************************************************************* */
/* Header values for sequence number field */
static int ff_cf_agility = -1;
static int ff_short_slot_time = -1;
static int ff_dsss_ofdm = -1;
+static int ff_cf_spec_man = -1;
+static int ff_cf_apsd = -1;
+static int ff_cf_del_blk_ack = -1;
+static int ff_cf_imm_blk_ack = -1;
/* ************************************************************************* */
/* Tagged value format fields */
static int tag_number = -1;
static int tag_length = -1;
static int tag_interpretation = -1;
+static int tag_oui = -1;
+
static int tim_length = -1;
static int tim_dtim_count = -1;
static int rsn_cap_ptksa_replay_counter = -1;
static int rsn_cap_gtksa_replay_counter = -1;
+static int hf_aironet_ie_type = -1;
+static int hf_aironet_ie_version = -1;
+static int hf_aironet_ie_data = -1;
+static int hf_aironet_ie_qos_unk1 = -1;
+static int hf_aironet_ie_qos_paramset = -1;
+static int hf_aironet_ie_qos_val = -1;
+
+/*QBSS - Version 1,2,802.11e*/
+
+static int hf_qbss2_cal = -1;
+static int hf_qbss2_gl = -1;
+static int hf_qbss_cu = -1;
+static int hf_qbss2_cu = -1;
+static int hf_qbss_scount = -1;
+static int hf_qbss2_scount = -1;
+static int hf_qbss_version = -1;
+static int hf_qbss_adc = -1;
+
/* ************************************************************************* */
/* Protocol trees */
/* ************************************************************************* */
static gint ett_fixed_parameters = -1;
static gint ett_tagged_parameters = -1;
static gint ett_qos_parameters = -1;
+static gint ett_qos_ps_buf_state = -1;
static gint ett_wep_parameters = -1;
static gint ett_rsn_cap_tree = -1;
{
int len;
- switch (COOK_FRAME_TYPE (fcf)) {
+ switch (FCF_FRAME_TYPE (fcf)) {
case MGT_FRAME:
return MGT_FRAME_HDR_LEN;
case CTRL_PS_POLL:
case CTRL_CFP_END:
case CTRL_CFP_ENDACK:
+ case CTRL_BLOCK_ACK_REQ:
+ case CTRL_BLOCK_ACK:
return 16;
}
return 4; /* XXX */
case DATA_FRAME:
- len = (COOK_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
+ len = (FCF_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN :
DATA_SHORT_HDR_LEN;
- switch (COMPOSE_FRAME_TYPE (fcf)) {
-
- case DATA_QOS_DATA:
- case DATA_QOS_NULL:
+ if (DATA_FRAME_IS_QOS(COMPOSE_FRAME_TYPE(fcf)))
return len + 2;
-
- default:
+ else
return len;
- }
+
default:
return 4; /* XXX */
}
/* ************************************************************************* */
static void
capture_ieee80211_common (const guchar * pd, int offset, int len,
- packet_counts * ld, gboolean fixed_length_header)
+ packet_counts * ld, gboolean fixed_length_header,
+ gboolean datapad)
{
guint16 fcf, hdr_length;
return;
}
- fcf = pletohs (&pd[0]);
+ fcf = pletohs (&pd[offset]);
- if (IS_WEP(COOK_FLAGS(fcf)))
+ if (IS_PROTECTED(FCF_FLAGS(fcf)))
{
ld->other++;
return;
hdr_length = DATA_LONG_HDR_LEN;
else
hdr_length = find_header_length (fcf);
+ if (datapad)
+ hdr_length = roundup2(hdr_length, 4);
/* I guess some bridges take Netware Ethernet_802_3 frames,
which are 802.3 frames (with a length field rather than
a type field, but with no 802.2 header in the payload),
void
capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
{
- capture_ieee80211_common (pd, offset, len, ld, FALSE);
+ capture_ieee80211_common (pd, offset, len, ld, FALSE, FALSE);
+}
+
+/*
+ * Handle 802.11 with a variable-length link-layer header and data padding.
+ */
+void
+capture_ieee80211_datapad (const guchar * pd, int offset, int len,
+ packet_counts * ld)
+{
+ capture_ieee80211_common (pd, offset, len, ld, FALSE, TRUE);
}
/*
void
capture_ieee80211_fixed (const guchar * pd, int offset, int len, packet_counts * ld)
{
- capture_ieee80211_common (pd, offset, len, ld, TRUE);
+ capture_ieee80211_common (pd, offset, len, ld, TRUE, FALSE);
}
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",
+ g_snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
dataptr[7],
dataptr[6],
dataptr[5],
break;
case FIELD_BEACON_INTERVAL:
- temp_double = (double) tvb_get_letohs (tvb, offset);
+ capability = tvb_get_letohs (tvb, offset);
+ temp_double = (double)capability;
temp_double = temp_double * 1024 / 1000000;
proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
temp_double,"Beacon Interval: %f [Seconds]",
temp_double);
+ if (check_col (g_pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(g_pinfo->cinfo, COL_INFO, ",BI=%d", capability);
+ }
break;
capability);
proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 2,
capability);
+ proto_tree_add_boolean (cap_tree, ff_cf_spec_man, tvb, offset, 2,
+ capability);
proto_tree_add_boolean (cap_tree, ff_short_slot_time, tvb, offset, 2,
capability);
+ proto_tree_add_boolean (cap_tree, ff_cf_apsd, tvb, offset, 2,
+ capability);
proto_tree_add_boolean (cap_tree, ff_dsss_ofdm, tvb, offset, 2,
capability);
+ proto_tree_add_boolean (cap_tree, ff_cf_del_blk_ack, tvb, offset, 2,
+ capability);
+ proto_tree_add_boolean (cap_tree, ff_cf_imm_blk_ack, tvb, offset, 2,
+ capability);
break;
case FIELD_AUTH_ALG:
break;
case FIELD_ASSOC_ID:
- proto_tree_add_uint(tree, ff_assoc_id, tvb, offset, 2,
- COOK_ASSOC_ID(tvb_get_letohs(tvb,offset)));
+ proto_tree_add_uint(tree, ff_assoc_id, tvb, offset, 2,
+ ASSOC_ID(tvb_get_letohs(tvb,offset)));
/* proto_tree_add_item (tree, ff_assoc_id, tvb, offset, 2, TRUE); */
break;
}
}
-static char *wpa_cipher_str[] =
+static const char *wpa_cipher_str[] =
{
"NONE",
"WEP (40-bit)",
"WEP (104-bit)",
};
-static char *
+static const char *
wpa_cipher_idx2str(guint idx)
{
if (idx < sizeof(wpa_cipher_str)/sizeof(wpa_cipher_str[0]))
return "UNKNOWN";
}
-static char *wpa_keymgmt_str[] =
+static const char *wpa_keymgmt_str[] =
{
"NONE",
"WPA",
"PSK",
};
-static char *
+static const char *
wpa_keymgmt_idx2str(guint idx)
{
if (idx < sizeof(wpa_keymgmt_str)/sizeof(wpa_keymgmt_str[0]))
return "UNKNOWN";
}
-static void
-dissect_vendor_specific_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
- guint32 tag_len, const guint8 *tag_val)
+static void
+dissect_vendor_ie_wpawme(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
+ int offset, guint32 tag_len, const guint8 *tag_val)
{
guint32 tag_val_off = 0;
- char out_buff[SHORT_STR], *pos;
+ char out_buff[SHORT_STR];
guint i;
-
+
/* Wi-Fi Protected Access (WPA) Information Element */
if (tag_val_off + 6 <= tag_len && !memcmp(tag_val, WPA_OUI"\x01", 4)) {
- snprintf(out_buff, SHORT_STR, "WPA IE, type %u, version %u",
+ g_snprintf(out_buff, SHORT_STR, "WPA IE, type %u, version %u",
tag_val[tag_val_off + 3], pletohs(&tag_val[tag_val_off + 4]));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
offset += 6;
if (tag_val_off + 4 <= tag_len) {
/* multicast cipher suite */
if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
- snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
+ g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
offset += 4;
tag_val_off += 4;
/* unicast cipher suites */
if (tag_val_off + 2 <= tag_len) {
- snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u",
+ g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u",
pletohs(tag_val + tag_val_off));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
offset += 2;
i = 1;
while (tag_val_off + 4 <= tag_len) {
if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
- snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
+ g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
offset += 4;
}
/* authenticated key management suites */
if (tag_val_off + 2 <= tag_len) {
- snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u",
+ g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u",
pletohs(tag_val + tag_val_off));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
offset += 2;
i = 1;
while (tag_val_off + 4 <= tag_len) {
if (!memcmp(&tag_val[tag_val_off], WPA_OUI, 3)) {
- snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
+ g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
offset += 4;
if (tag_val_off < tag_len)
proto_tree_add_string(tree, tag_interpretation, tvb,
offset, tag_len - tag_val_off, "Not interpreted");
+ proto_item_append_text(ietree, ": WPA");
} else if (tag_val_off + 7 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x00", 5)) {
/* Wireless Multimedia Enhancements (WME) Information Element */
- snprintf(out_buff, SHORT_STR, "WME IE: type %u, subtype %u, version %u, parameter set %u",
+ g_snprintf(out_buff, SHORT_STR, "WME IE: type %u, subtype %u, version %u, parameter set %u",
tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
tag_val[tag_val_off + 6]);
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
+ proto_item_append_text(ietree, ": WME");
} else if (tag_val_off + 24 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x01", 5)) {
/* Wireless Multimedia Enhancements (WME) Parameter Element */
- snprintf(out_buff, SHORT_STR, "WME PE: type %u, subtype %u, version %u, parameter set %u",
+ g_snprintf(out_buff, SHORT_STR, "WME PE: type %u, subtype %u, version %u, parameter set %u",
tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5],
tag_val[tag_val_off + 6]);
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 7, out_buff);
offset += 8;
tag_val_off += 8;
for (i = 0; i < 4; i++) {
- snprintf(out_buff, SHORT_STR, "WME AC Parameters: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
+ g_snprintf(out_buff, SHORT_STR, "WME AC Parameters: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
(tag_val[tag_val_off] & 0x60) >> 5,
wme_acs[(tag_val[tag_val_off] & 0x60) >> 5],
(tag_val[tag_val_off] & 0x10) ? "" : "not ",
offset += 4;
tag_val_off += 4;
}
+ proto_item_append_text(ietree, ": WME");
} else if (tag_val_off + 56 <= tag_len && !memcmp(tag_val, WME_OUI"\x02\x02", 5)) {
/* Wireless Multimedia Enhancements (WME) TSPEC Element */
guint16 ts_info, msdu_size, surplus_bandwidth;
};
const char *field;
- snprintf(out_buff, SHORT_STR, "WME TSPEC: type %u, subtype %u, version %u",
+ g_snprintf(out_buff, SHORT_STR, "WME TSPEC: type %u, subtype %u, version %u",
tag_val[tag_val_off + 3], tag_val[tag_val_off + 4], tag_val[tag_val_off + 5]);
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 6, out_buff);
offset += 6;
tag_val_off += 6;
ts_info = tvb_get_letohs(tvb, offset);
- snprintf(out_buff, SHORT_STR, "WME TS Info: Priority %u (%s) (%s), Contention-based access %sset, %s",
+ g_snprintf(out_buff, SHORT_STR, "WME TS Info: Priority %u (%s) (%s), Contention-based access %sset, %s",
(ts_info >> 11) & 0x7, qos_tags[(ts_info >> 11) & 0x7], qos_acs[(ts_info >> 11) & 0x7],
(ts_info & 0x0080) ? "" : "not ",
direction[(ts_info >> 5) & 0x3]);
tag_val_off += 2;
msdu_size = tvb_get_letohs(tvb, offset);
- snprintf(out_buff, SHORT_STR, "WME TSPEC: %s MSDU Size %u",
+ g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s MSDU Size %u",
(msdu_size & 0x8000) ? "Fixed" : "Nominal", msdu_size & 0x7fff);
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
offset += 2;
tag_val_off += 2;
- snprintf(out_buff, SHORT_STR, "WME TSPEC: Maximum MSDU Size %u", tvb_get_letohs(tvb, offset));
+ g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Maximum MSDU Size %u", tvb_get_letohs(tvb, offset));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
offset += 2;
tag_val_off += 2;
while ((field = val_to_str(tag_val_off, fields, "Unknown"))) {
- snprintf(out_buff, SHORT_STR, "WME TSPEC: %s %u", field, tvb_get_letohl(tvb, offset));
+ g_snprintf(out_buff, SHORT_STR, "WME TSPEC: %s %u", field, tvb_get_letohl(tvb, offset));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
offset += 4;
tag_val_off += 4;
}
surplus_bandwidth = tvb_get_letohs(tvb, offset);
- snprintf(out_buff, SHORT_STR, "WME TSPEC: Surplus Bandwidth Allowance Factor %u.%u",
+ g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Surplus Bandwidth Allowance Factor %u.%u",
(surplus_bandwidth >> 13) & 0x7, (surplus_bandwidth & 0x1fff));
offset += 2;
tag_val_off += 2;
- snprintf(out_buff, SHORT_STR, "WME TSPEC: Medium Time %u", tvb_get_letohs(tvb, offset));
+ g_snprintf(out_buff, SHORT_STR, "WME TSPEC: Medium Time %u", tvb_get_letohs(tvb, offset));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
offset += 2;
- tag_val_off += 2;
- } else if (tag_val_off + 4 <= tag_len && !memcmp(tag_val, RSN_OUI"\x04", 4)) {
- /* IEEE 802.11i / Key Data Encapsulation / Data Type=4 - PMKID.
- * This is only used within EAPOL-Key frame Key Data. */
- pos = out_buff;
- pos += snprintf(pos, out_buff + SHORT_STR - pos, "RSN PMKID: ");
- if (tag_len - 4 != PMKID_LEN) {
- pos += snprintf(pos, out_buff + SHORT_STR - pos,
- "(invalid PMKID len=%d, expected 16) ", tag_len - 4);
+ tag_val_off += 2;
+ proto_item_append_text(ietree, ": WME");
+ }
+}
+
+static void
+dissect_vendor_ie_rsn(proto_tree * ietree, proto_tree * tree, tvbuff_t * tvb,
+ int offset, guint32 tag_len, const guint8 *tag_val)
+{
+ guint32 tag_val_off = 0;
+ char out_buff[SHORT_STR], *pos;
+ guint i;
+
+ if (tag_val_off + 4 <= tag_len && !memcmp(tag_val, RSN_OUI"\x04", 4)) {
+ /* IEEE 802.11i / Key Data Encapsulation / Data Type=4 - PMKID.
+ * This is only used within EAPOL-Key frame Key Data. */
+ pos = out_buff;
+ pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "RSN PMKID: ");
+ if (tag_len - 4 != PMKID_LEN) {
+ pos += g_snprintf(pos, out_buff + SHORT_STR - pos,
+ "(invalid PMKID len=%d, expected 16) ", tag_len - 4);
+ }
+ for (i = 0; i < tag_len - 4; i++) {
+ pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
+ tag_val[tag_val_off + 4 + i]);
+ }
+ proto_tree_add_string(tree, tag_interpretation, tvb, offset,
+ tag_len, out_buff);
}
- for (i = 0; i < tag_len - 4; i++) {
- pos += snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
- tag_val[tag_val_off + 4 + i]);
+ proto_item_append_text(ietree, ": RSN");
+}
+
+typedef enum {
+ AIRONET_IE_VERSION = 3,
+ AIRONET_IE_QOS,
+ AIRONET_IE_QBSS_V2 = 14
+} aironet_ie_type_t;
+
+static const value_string aironet_ie_type_vals[] = {
+ { AIRONET_IE_VERSION, "CCX version"},
+ { AIRONET_IE_QOS, "Qos"},
+ { AIRONET_IE_QBSS_V2, "QBSS V2 - CCA"},
+
+ { 0, NULL }
+};
+
+static void
+dissect_vendor_ie_aironet(proto_item * aironet_item, proto_tree * ietree,
+ tvbuff_t * tvb, int offset, guint32 tag_len)
+{
+ guint8 type;
+ int i;
+ gboolean dont_change = FALSE; /* Don't change the IE item text to default */
+
+ type = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item (ietree, hf_aironet_ie_type, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ switch (type) {
+ case AIRONET_IE_VERSION:
+ proto_tree_add_item (ietree, hf_aironet_ie_version, tvb, offset, 1, TRUE);
+ proto_item_append_text(aironet_item, ": Aironet CCX version = %d",
+ tvb_get_guint8(tvb, offset));
+ dont_change = TRUE;
+ break;
+ case AIRONET_IE_QOS:
+ proto_tree_add_item (ietree, hf_aironet_ie_qos_unk1, tvb, offset, 1, TRUE);
+ offset += 1;
+ proto_tree_add_item (ietree, hf_aironet_ie_qos_paramset, tvb, offset, 1, TRUE);
+ offset += 1;
+
+ /* XXX: just copied over from WME. Maybe "Best Effort" and "Background"
+ * need to be swapped. Also, the "TXOP" may be TXOP - or not.
+ */
+ for (i = 0; i < 4; i++) {
+ guint8 byte1, byte2;
+ guint16 txop;
+ byte1 = tvb_get_guint8(tvb, offset);
+ byte2 = tvb_get_guint8(tvb, offset + 1);
+ txop = tvb_get_letohs(tvb, offset + 2);
+ proto_tree_add_bytes_format(ietree, hf_aironet_ie_qos_val, tvb, offset, 4,
+ tvb_get_ptr(tvb, offset, 4),
+ "CCX QoS Parameters??: ACI %u (%s), Admission Control %sMandatory, AIFSN %u, ECWmin %u, ECWmax %u, TXOP %u",
+ (byte1 & 0x60) >> 5, wme_acs[(byte1 & 0x60) >> 5],
+ (byte1 & 0x10) ? "" : "not ", byte1 & 0x0f,
+ byte2 & 0x0f, (byte2 & 0xf0) >> 4,
+ txop);
+ offset += 4;
+ }
+ break;
+ case AIRONET_IE_QBSS_V2:
+ /* Extract Values */
+ proto_tree_add_item (ietree, hf_qbss2_scount, tvb, offset, 2, TRUE);
+ proto_tree_add_item (ietree, hf_qbss2_cu, tvb, offset + 2, 1, FALSE);
+ proto_tree_add_item (ietree, hf_qbss2_cal, tvb, offset + 3, 1, FALSE);
+ proto_tree_add_item (ietree, hf_qbss2_gl, tvb, offset + 4, 1, FALSE);
+ break;
+ default:
+ proto_tree_add_item(ietree, hf_aironet_ie_data, tvb, offset,
+ tag_len - 1, FALSE);
+ break;
+ }
+ if (!dont_change) {
+ proto_item_append_text(aironet_item, ": Aironet %s",
+ val_to_str(type, aironet_ie_type_vals, "Unknown"));
}
- proto_tree_add_string(tree, tag_interpretation, tvb, offset,
- tag_len, out_buff);
- } else
- proto_tree_add_string_format(tree, tag_interpretation,
- tvb, offset, tag_len, "",
- "Tag interpretation: Vendor \"%s\" not interpreted",
- get_manuf_name(tag_val));
}
-static void
+static void
dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset,
guint32 tag_len, const guint8 *tag_val)
{
return;
}
- snprintf(out_buff, SHORT_STR, "RSN IE, version %u",
+ g_snprintf(out_buff, SHORT_STR, "RSN IE, version %u",
pletohs(&tag_val[tag_val_off]));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
/* multicast cipher suite */
if (!memcmp(&tag_val[tag_val_off], RSN_OUI, 3)) {
- snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
+ g_snprintf(out_buff, SHORT_STR, "Multicast cipher suite: %s",
wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
offset += 4;
/* unicast cipher suites */
count = pletohs(tag_val + tag_val_off);
- snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u", count);
+ g_snprintf(out_buff, SHORT_STR, "# of unicast cipher suites: %u", count);
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
offset += 2;
tag_val_off += 2;
while (tag_val_off + 4 <= tag_len && i <= count) {
if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
goto done;
- snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
+ g_snprintf(out_buff, SHORT_STR, "Unicast cipher suite %u: %s",
i, wpa_cipher_idx2str(tag_val[tag_val_off + 3]));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
offset += 4;
/* authenticated key management suites */
count = pletohs(tag_val + tag_val_off);
- snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u", count);
+ g_snprintf(out_buff, SHORT_STR, "# of auth key management suites: %u", count);
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
offset += 2;
tag_val_off += 2;
while (tag_val_off + 4 <= tag_len && i <= count) {
if (memcmp(&tag_val[tag_val_off], RSN_OUI, 3) != 0)
goto done;
- snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
+ g_snprintf(out_buff, SHORT_STR, "auth key management suite %u: %s",
i, wpa_keymgmt_idx2str(tag_val[tag_val_off + 3]));
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 4, out_buff);
offset += 4;
goto done;
rsn_capab = pletohs(&tag_val[tag_val_off]);
- snprintf(out_buff, SHORT_STR, "RSN Capabilities 0x%04x", rsn_capab);
+ g_snprintf(out_buff, SHORT_STR, "RSN Capabilities 0x%04x", rsn_capab);
cap_item = proto_tree_add_uint_format(tree, rsn_cap, tvb,
offset, 2, rsn_capab,
"RSN Capabilities: 0x%04X", rsn_capab);
goto done;
count = pletohs(tag_val + tag_val_off);
- snprintf(out_buff, SHORT_STR, "# of PMKIDs: %u", count);
+ g_snprintf(out_buff, SHORT_STR, "# of PMKIDs: %u", count);
proto_tree_add_string(tree, tag_interpretation, tvb, offset, 2, out_buff);
offset += 2;
tag_val_off += 2;
if (tag_val_off + PMKID_LEN > tag_len)
goto done;
pos = out_buff;
- pos += snprintf(pos, out_buff + SHORT_STR - pos, "PMKID %u: ", i);
+ pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "PMKID %u: ", i);
for (j = 0; j < PMKID_LEN; j++) {
- pos += snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
+ pos += g_snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
tag_val[tag_val_off + j]);
}
proto_tree_add_string(tree, tag_interpretation, tvb, offset,
{ TAG_CISCO_UNKNOWN_1, "Cisco Unknown 1 + Device Name" },
{ TAG_CISCO_UNKNOWN_2, "Cisco Unknown 2" },
{ TAG_VENDOR_SPECIFIC_IE, "Vendor Specific" },
+ { TAG_SYMBOL_PROPRIETARY, "Symbol Proprietary"},
+ { TAG_AGERE_PROPRIETARY, "Agere Proprietary"},
+ { TAG_REQUEST, "Request"},
+ { TAG_QBSS_LOAD, "QBSS Load Element"},
+ { TAG_EDCA_PARAM_SET, "EDCA Parameter Set"},
+ { TAG_TRAF_SPEC, "Traffic Specification"},
+ { TAG_TRAF_CLASS, "Traffic Classification"},
+ { TAG_SCHEDULE, "Schedule"},
+ { TAG_TS_DELAY, "TS Delay"},
+ { TAG_TCLAS_PROCESS, "TCLAS Processing"},
+ { TAG_QOS_CAPABILITY, "QoS Capability"},
+ { TAG_POWER_CONSTRAINT, "Power Constraint"},
+ { TAG_POWER_CAPABILITY, "Power Capability"},
+ { TAG_TPC_REQUEST, "TPC Request"},
+ { TAG_TPC_REPORT, "TPC Report"},
+ { TAG_SUPPORTED_CHANNELS, "Supported Channels"},
+ { TAG_CHANNEL_SWITCH_ANN, "Channel Switch Announcement"},
+ { TAG_MEASURE_REQ, "Measurement Request"},
+ { TAG_MEASURE_REP, "Measurement Report"},
+ { TAG_QUIET, "Quiet"},
+ { TAG_IBSS_DFS, "IBSS DFS"},
{ 0, NULL }
};
{ 0, NULL }
};
+static int beacon_padding = 0; /* beacon padding bug */
static int
add_tagged_field (packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int offset)
{
+ guint32 oui;
+ const guint8 *tag_val;
const guint8 *tag_data_ptr;
guint32 tag_no, tag_len;
unsigned int i;
ti=proto_tree_add_text(orig_tree,tvb,offset,tag_len+2,"%s",
val_to_str(tag_no, tag_num_vals,
- (tag_no >= 17 && tag_no <= 31) ?
+ (tag_no >= 17 && tag_no <= 31) ?
"Reserved for challenge text" : "Reserved tag number" ));
tree=proto_item_add_subtree(ti,ett_80211_mgt_ie);
{
case TAG_SSID:
+ if(beacon_padding == 0) /* padding bug */
{
char *ssid;
- ssid = tvb_get_string(tvb, offset + 2, tag_len);
+ ssid = tvb_get_ephemeral_string(tvb, offset + 2, tag_len);
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
tag_len, ssid);
if (check_col (pinfo->cinfo, COL_INFO)) {
} else {
proto_item_append_text(ti, ": Broadcast");
}
- g_free(ssid);
+ beacon_padding++; /* padding bug */
}
break;
case TAG_SUPP_RATES:
case TAG_EXT_SUPP_RATES:
+ if (tag_len < 1)
+ {
+ proto_tree_add_text (tree, tvb, offset + 2, tag_len,
+ "Tag length %u too short, must be > 0", tag_len);
+ break;
+ }
+ tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
+
tag_data_ptr = tvb_get_ptr (tvb, offset + 2, tag_len);
for (i = 0, n = 0; i < tag_len && n < SHORT_STR; i++) {
- ret = snprintf (print_buff + n, SHORT_STR - n, "%2.1f%s ",
+ ret = g_snprintf (print_buff + n, SHORT_STR - n, "%2.1f%s ",
(tag_data_ptr[i] & 0x7F) * 0.5,
(tag_data_ptr[i] & 0x80) ? "(B)" : "");
if (ret == -1 || ret >= SHORT_STR - n) {
}
n += ret;
}
- snprintf (out_buff, SHORT_STR, "Supported rates: %s [Mbit/sec]", print_buff);
+ g_snprintf (out_buff, SHORT_STR, "Supported rates: %s [Mbit/sec]", print_buff);
out_buff[SHORT_STR-1] = '\0';
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
tag_len, out_buff);
tag_len);
break;
}
- snprintf (out_buff, SHORT_STR,
+ g_snprintf (out_buff, SHORT_STR,
"Dwell time 0x%04X, Hop Set %2d, Hop Pattern %2d, Hop Index %2d",
tvb_get_letohs(tvb, offset + 2),
tvb_get_guint8(tvb, offset + 4),
tag_len);
break;
}
- snprintf (out_buff, SHORT_STR, "Current Channel: %u",
+ g_snprintf (out_buff, SHORT_STR, "Current Channel: %u",
tvb_get_guint8(tvb, offset + 2));
out_buff[SHORT_STR-1] = '\0';
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
tag_len);
break;
}
- snprintf (out_buff, SHORT_STR, "CFP count: %u",
+ g_snprintf (out_buff, SHORT_STR, "CFP count: %u",
tvb_get_guint8(tvb, offset + 2));
out_buff[SHORT_STR-1] = '\0';
proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 2,
1, out_buff, "%s", out_buff);
- snprintf (out_buff, SHORT_STR, "CFP period: %u",
+ g_snprintf (out_buff, SHORT_STR, "CFP period: %u",
tvb_get_guint8(tvb, offset + 3));
out_buff[SHORT_STR-1] = '\0';
proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 3,
1, out_buff, "%s", out_buff);
- snprintf (out_buff, SHORT_STR, "CFP max duration: %u",
+ g_snprintf (out_buff, SHORT_STR, "CFP max duration: %u",
tvb_get_letohs(tvb, offset + 4));
out_buff[SHORT_STR-1] = '\0';
proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 4,
2, out_buff, "%s", out_buff);
- snprintf (out_buff, SHORT_STR, "CFP Remaining: %u",
+ g_snprintf (out_buff, SHORT_STR, "CFP Remaining: %u",
tvb_get_letohs(tvb, offset + 6));
out_buff[SHORT_STR-1] = '\0';
proto_tree_add_string_format(tree, tag_interpretation, tvb, offset + 6,
2, out_buff, "%s", out_buff);
proto_item_append_text(ti, ": CFP count %u, CFP period %u, CFP max duration %u, "
- "CFP Remaining %u",
+ "CFP Remaining %u",
tvb_get_guint8(tvb, offset + 2),
tvb_get_guint8(tvb, offset + 3),
tvb_get_letohs(tvb, offset + 4),
}
}
if (bmaplen>1 || bmap[0]) {
- int len=snprintf (out_buff, SHORT_STR,
+ int len=g_snprintf (out_buff, SHORT_STR,
"Bitmap: traffic for AID's:");
int i=0;
for (i=0;i<bmaplen*8;i++) {
if (bmap[i/8] & (1<<(i%8))) {
- int aid=i+bmapoff*8;
- len+=snprintf (out_buff+len, SHORT_STR-len," %u", aid);
- proto_item_append_text(ti, " %u", aid);
+ int aid=i+2*bmapoff*8;
+ len+=g_snprintf (out_buff+len, SHORT_STR-len," %u", aid);
+ proto_item_append_text(ti, " %u", aid);
if (len>=SHORT_STR) {
break;
}
tag_len);
break;
}
- snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
+ g_snprintf (out_buff, SHORT_STR, "ATIM window 0x%X",
tvb_get_letohs(tvb, offset + 2));
out_buff[SHORT_STR-1] = '\0';
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
}
tvb_memcpy(tvb, ccode, offset + 2, 2);
ccode[2] = '\0';
- snprintf (out_buff, SHORT_STR, "Country Code: %s, %s Environment",
- format_text(ccode, 2),
+ g_snprintf (out_buff, SHORT_STR, "Country Code: %s, %s Environment",
+ format_text(ccode, 2),
val_to_str(tvb_get_guint8(tvb, offset + 4), environment_vals,"Unknown (0x%02x)"));
out_buff[SHORT_STR-1] = '\0';
proto_item_append_text(ti, ": %s", out_buff);
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,3, out_buff);
for (i = 3; (i + 3) <= tag_len; i += 3)
- {
+ {
guint8 val1, val2, val3;
val1 = tvb_get_guint8(tvb, offset + 2 + i);
val2 = tvb_get_guint8(tvb, offset + 3 + i);
}
break;
+ case TAG_QBSS_LOAD:
+ if (tag_len < 4 || tag_len >5)
+ {
+ proto_tree_add_text (tree, tvb, offset + 2, tag_len, "Wrong QBSS Tag Length %u", tag_len);
+ break;
+ }
+
+ if (tag_len == 4)
+ {
+ /* QBSS Version 1 */
+ proto_tree_add_string (tree, tag_interpretation, tvb, offset + 1,
+ tag_len, "Cisco QBSS Version 1 - non CCA");
+
+ /* Extract Values */
+ proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 1);
+ proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
+ proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
+ proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 1, FALSE);
+ }
+ else if (tag_len == 5)
+ {
+ /* QBSS Version 2 */
+ proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
+ tag_len, "802.11e CCA Version");
+
+ /* Extract Values */
+ proto_tree_add_uint (tree, hf_qbss_version, tvb, offset + 2, tag_len, 2);
+ proto_tree_add_item (tree, hf_qbss_scount, tvb, offset + 2, 2, TRUE);
+ proto_tree_add_item (tree, hf_qbss_cu, tvb, offset + 4, 1, FALSE);
+ proto_tree_add_item (tree, hf_qbss_adc, tvb, offset + 5, 2, FALSE);
+ }
+ break;
+
case TAG_FH_HOPPING_PARAMETER:
if (tag_len < 2)
{
tag_len);
break;
}
- snprintf (out_buff, SHORT_STR, "Prime Radix: %u, Number of Channels: %u",
+ g_snprintf (out_buff, SHORT_STR, "Prime Radix: %u, Number of Channels: %u",
tvb_get_guint8(tvb, offset + 2),
tvb_get_guint8(tvb, offset + 3));
out_buff[SHORT_STR-1] = '\0';
break;
case TAG_CHALLENGE_TEXT:
- snprintf (out_buff, SHORT_STR, "Challenge text: %s",
+ g_snprintf (out_buff, SHORT_STR, "Challenge text: %s",
tvb_bytes_to_str(tvb, offset + 2, tag_len));
out_buff[SHORT_STR-1] = '\0';
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
break;
}
erp_info = tvb_get_guint8 (tvb, offset + 2);
- snprintf (print_buff, SHORT_STR, "%sNon-ERP STAs, %suse protection, %s preambles",
+ g_snprintf (print_buff, SHORT_STR, "%sNon-ERP STAs, %suse protection, %s preambles",
erp_info & 0x01 ? "" : "no ",
erp_info & 0x02 ? "" : "do not ",
- erp_info & 0x04 ? "short or long": "long");
+ /* 802.11g, 7.3.2.13: 1 means "one or more ... STAs
+ * are not short preamble capable" */
+ erp_info & 0x04 ? "long": "short or long");
print_buff[SHORT_STR-1] = '\0';
- snprintf (out_buff, SHORT_STR,
+ g_snprintf (out_buff, SHORT_STR,
"ERP info: 0x%x (%s)",erp_info,print_buff);
out_buff[SHORT_STR-1] = '\0';
proto_tree_add_string (tree, tag_interpretation, tvb, offset + 2,
break;
case TAG_CISCO_UNKNOWN_1:
- /* The Name of the sending device starts at offset 10 and is up to
+ /* The Name of the sending device starts at offset 10 and is up to
15 or 16 bytes in length, \0 padded */
if (tag_len < 26)
{
tag_len);
break;
}
- snprintf (out_buff, SHORT_STR, "%.16s",
+ /* A cisco AP transmits the first 15 bytes of the AP name, probably
+ followed by '\0' for ASCII termination */
+ g_snprintf (out_buff, SHORT_STR, "%.16s",
tvb_format_stringzpad(tvb, offset + 12, 16));
out_buff[SHORT_STR-1] = '\0';
proto_tree_add_string_format (tree, tag_interpretation, tvb, offset + 2,
- tag_len, "", "Tag interpretation: Unknown + Name: %s",
- out_buff);
+ tag_len, "", "Tag interpretation: Unknown + Name: %s #Clients: %u",
+ out_buff,
+ /* Total number off associated clients and
+ repeater access points */
+ tvb_get_guint8(tvb, offset + 28));
if (check_col (pinfo->cinfo, COL_INFO)) {
col_append_fstr(pinfo->cinfo, COL_INFO, ", Name: \"%s\"", out_buff);
}
break;
case TAG_VENDOR_SPECIFIC_IE:
- dissect_vendor_specific_ie(tree, tvb, offset + 2, tag_len,
- tvb_get_ptr (tvb, offset + 2, tag_len));
+ tvb_ensure_bytes_exist (tvb, offset + 2, tag_len);
+ if (tag_len >= 3) {
+ oui = tvb_get_ntoh24(tvb, offset + 2);
+ tag_val = tvb_get_ptr(tvb, offset + 2, tag_len);
+
+#define WPAWME_OUI 0x0050F2
+#define RSNOUI_VAL 0x000FAC
+
+ switch (oui) {
+ case WPAWME_OUI:
+ dissect_vendor_ie_wpawme(ti, tree, tvb, offset + 2, tag_len, tag_val);
+ break;
+ case RSNOUI_VAL:
+ dissect_vendor_ie_rsn(ti, tree, tvb, offset + 2, tag_len, tag_val);
+ break;
+ case OUI_CISCOWL: /* Cisco Wireless (Aironet) */
+ dissect_vendor_ie_aironet(ti, tree, tvb, offset + 5, tag_len - 3);
+ break;
+ default:
+ proto_tree_add_bytes_format (tree, tag_oui, tvb, offset + 2, 3,
+ "", "Vendor: %s", get_manuf_name(tag_val));
+ proto_item_append_text(ti, ": %s", get_manuf_name(tag_val));
+ proto_tree_add_string (tree, tag_interpretation, tvb, offset + 5,
+ tag_len - 3, "Not interpreted");
+ break;
+ }
+
+ }
break;
case TAG_RSN_IE:
{
int next_len;
+ beacon_padding = 0; /* this is for the beacon padding confused with ssid fix */
while (tagged_parameters_len > 0) {
if ((next_len=add_tagged_field (pinfo, tree, tvb, offset))==0)
break;
int offset;
int tagged_parameter_tree_len;
+ g_pinfo = pinfo;
+
CHECK_DISPLAY_AS_X(data_handle,proto_wlan_mgt, tvb, pinfo, tree);
ti = proto_tree_add_item (tree, proto_wlan_mgt, tvb, 0, -1, FALSE);
fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
-
offset = 4; /* Size of fixed fields */
+
tagged_parameter_tree_len =
tvb_reported_length_remaining(tvb, offset);
tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
tagged_parameter_tree_len);
-
ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
tagged_parameter_tree_len);
break;
add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
-
offset = 6; /* Size of fixed fields */
tagged_parameter_tree_len =
tvb_reported_length_remaining(tvb, offset);
tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
tagged_parameter_tree_len);
-
ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
tagged_parameter_tree_len);
break;
add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
add_fixed_field (fixed_tree, tvb, 2, FIELD_LISTEN_IVAL);
add_fixed_field (fixed_tree, tvb, 4, FIELD_CURRENT_AP_ADDR);
-
offset = 10; /* Size of fixed fields */
+
tagged_parameter_tree_len =
tvb_reported_length_remaining(tvb, offset);
tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
tagged_parameter_tree_len);
-
ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
tagged_parameter_tree_len);
break;
case MGT_REASSOC_RESP:
- fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 10);
+ fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 6);
add_fixed_field (fixed_tree, tvb, 0, FIELD_CAP_INFO);
add_fixed_field (fixed_tree, tvb, 2, FIELD_STATUS_CODE);
add_fixed_field (fixed_tree, tvb, 4, FIELD_ASSOC_ID);
-
offset = 6; /* Size of fixed fields */
+
tagged_parameter_tree_len =
tvb_reported_length_remaining(tvb, offset);
tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
tagged_parameter_tree_len);
-
ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
tagged_parameter_tree_len);
break;
tvb_reported_length_remaining(tvb, offset);
tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
tagged_parameter_tree_len);
-
ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
tagged_parameter_tree_len);
break;
add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
-
offset = 12; /* Size of fixed fields */
+
tagged_parameter_tree_len =
tvb_reported_length_remaining(tvb, offset);
tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
tagged_parameter_tree_len);
-
ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
tagged_parameter_tree_len);
break;
case MGT_BEACON: /* Dissect protocol payload fields */
fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 12);
-
add_fixed_field (fixed_tree, tvb, 0, FIELD_TIMESTAMP);
add_fixed_field (fixed_tree, tvb, 8, FIELD_BEACON_INTERVAL);
add_fixed_field (fixed_tree, tvb, 10, FIELD_CAP_INFO);
-
offset = 12; /* Size of fixed fields */
+
tagged_parameter_tree_len =
tvb_reported_length_remaining(tvb, offset);
tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
tagged_parameter_tree_len);
-
ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
tagged_parameter_tree_len);
break;
add_fixed_field (fixed_tree, tvb, 0, FIELD_AUTH_ALG);
add_fixed_field (fixed_tree, tvb, 2, FIELD_AUTH_TRANS_SEQ);
add_fixed_field (fixed_tree, tvb, 4, FIELD_STATUS_CODE);
-
offset = 6; /* Size of fixed fields */
tagged_parameter_tree_len =
tvb,
offset,
tagged_parameter_tree_len);
-
ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
tagged_parameter_tree_len);
}
case MGT_ACTION:
- fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
- add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
-
switch (tvb_get_guint8(tvb, 0))
{
- case 17: /* Management notification frame */
+ case CAT_SPECTRUM_MGMT:
+ switch (tvb_get_guint8(tvb, 1))
+ {
+ case SM_ACTION_MEASUREMENT_REQUEST:
+ case SM_ACTION_MEASUREMENT_REPORT:
+ case SM_ACTION_TPC_REQUEST:
+ case SM_ACTION_TPC_REPORT:
+ fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 3);
+ add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
+ add_fixed_field (fixed_tree, tvb, 1, FIELD_ACTION_CODE);
+ add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
+ offset = 3; /* Size of fixed fields */
+ break;
+
+ case SM_ACTION_CHAN_SWITCH_ANNC:
+ fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
+ add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
+ offset = 2; /* Size of fixed fields */
+ break;
+
+ default:
+ fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 2);
+ add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
+ offset = 2; /* Size of fixed fields */
+ break;
+ }
+ break;
+
+ case CAT_MGMT_NOTIFICATION: /* Management notification frame */
+ fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 4);
+ add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
add_fixed_field (fixed_tree, tvb, 1, FIELD_WME_ACTION_CODE);
add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
add_fixed_field (fixed_tree, tvb, 3, FIELD_WME_STATUS_CODE);
-
offset = 4; /* Size of fixed fields */
-
- tagged_parameter_tree_len =
- tvb_reported_length_remaining(tvb, offset);
- if (tagged_parameter_tree_len != 0)
- {
- tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
- tagged_parameter_tree_len);
-
- ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
- tagged_parameter_tree_len);
- }
break;
- default: /* Management action frame */
- add_fixed_field (fixed_tree, tvb, 1, FIELD_ACTION_CODE);
- add_fixed_field (fixed_tree, tvb, 2, FIELD_DIALOG_TOKEN);
+ default:
+ fixed_tree = get_fixed_parameter_tree (mgt_tree, tvb, 0, 1);
+ add_fixed_field (fixed_tree, tvb, 0, FIELD_CATEGORY_CODE);
+ offset = 1; /* Size of fixed fields */
break;
}
+
+ tagged_parameter_tree_len =
+ tvb_reported_length_remaining(tvb, offset);
+ if (tagged_parameter_tree_len != 0)
+ {
+ tagged_tree = get_tagged_parameter_tree (mgt_tree, tvb, offset,
+ tagged_parameter_tree_len);
+ ieee_80211_add_tagged_parameters (tvb, offset, pinfo, tagged_tree,
+ tagged_parameter_tree_len);
+ }
break;
}
}
static void
-set_src_addr_cols(packet_info *pinfo, const guint8 *addr, char *type)
+set_src_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
{
if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "%s (%s)",
get_ether_name(addr), type);
if (check_col(pinfo->cinfo, COL_UNRES_DL_SRC))
- col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s (%s)",
- ether_to_str(addr), type);
+ col_add_fstr(pinfo->cinfo, COL_UNRES_DL_SRC, "%s",
+ ether_to_str(addr));
}
static void
-set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, char *type)
+set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, const char *type)
{
if (check_col(pinfo->cinfo, COL_RES_DL_DST))
col_add_fstr(pinfo->cinfo, COL_RES_DL_DST, "%s (%s)",
get_ether_name(addr), type);
if (check_col(pinfo->cinfo, COL_UNRES_DL_DST))
- col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s (%s)",
- ether_to_str(addr), type);
+ col_add_fstr(pinfo->cinfo, COL_UNRES_DL_DST, "%s",
+ ether_to_str(addr));
+}
+
+static guint32
+crc32_802_tvb_padded(tvbuff_t *tvb, guint hdr_len, guint hdr_size, guint len)
+{
+ guint32 c_crc;
+
+ c_crc = crc32_ccitt_tvb(tvb, hdr_len);
+ c_crc = crc32_ccitt_seed(tvb_get_ptr(tvb, hdr_size, len), len, ~c_crc);
+
+ /* Byte reverse. */
+ c_crc = ((unsigned char)(c_crc>>0)<<24) |
+ ((unsigned char)(c_crc>>8)<<16) |
+ ((unsigned char)(c_crc>>16)<<8) |
+ ((unsigned char)(c_crc>>24)<<0);
+
+ return ( c_crc );
}
typedef enum {
dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo,
proto_tree * tree, gboolean fixed_length_header,
gboolean has_radio_information, gint fcs_len,
- gboolean wlan_broken_fc)
+ gboolean wlan_broken_fc, gboolean datapad)
{
guint16 fcf, flags, frame_type_subtype;
guint16 seq_control;
guint32 seq_number, frag_number;
gboolean more_frags;
- const guint8 *src = NULL, *dst = NULL, *bssid = NULL;
+ const guint8 *src = NULL;
+ const guint8 *dst = NULL;
+ const guint8 *bssid = NULL;
proto_item *ti = NULL;
proto_item *flag_item;
proto_item *fc_item;
proto_tree *hdr_tree = NULL;
proto_tree *flag_tree;
proto_tree *fc_tree;
- guint16 hdr_len;
+ guint16 hdr_len, ohdr_len;
gboolean has_fcs;
gint len, reported_len, ivlen;
gboolean save_fragmented;
hdr_len = DATA_LONG_HDR_LEN;
else
hdr_len = find_header_length (fcf);
+ ohdr_len = hdr_len;
+ if (datapad)
+ hdr_len = roundup2(hdr_len, 4);
frame_type_subtype = COMPOSE_FRAME_TYPE(fcf);
if (check_col (pinfo->cinfo, COL_INFO))
val_to_str(frame_type_subtype, frame_type_subtype_vals,
"Unrecognized (Reserved frame)"));
- flags = COOK_FLAGS (fcf);
+ flags = FCF_FLAGS (fcf);
more_frags = HAVE_FRAGMENTS (flags);
+
/* Add the radio information, if present, and the FC to the current tree */
if (tree)
{
}
proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype,
- tvb,
+ tvb,
wlan_broken_fc?1:0, 1,
frame_type_subtype);
- fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb,
+ fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb,
0, 2,
fcf,
"Frame Control: 0x%04X (%s)",
fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
- proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb,
+ proto_tree_add_uint (fc_tree, hf_fc_proto_version, tvb,
wlan_broken_fc?1:0, 1,
- COOK_PROT_VERSION (fcf));
+ FCF_PROT_VERSION (fcf));
- proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb,
+ proto_tree_add_uint (fc_tree, hf_fc_frame_type, tvb,
wlan_broken_fc?1:0, 1,
- COOK_FRAME_TYPE (fcf));
+ FCF_FRAME_TYPE (fcf));
proto_tree_add_uint (fc_tree, hf_fc_frame_subtype,
- tvb,
+ tvb,
wlan_broken_fc?1:0, 1,
- COOK_FRAME_SUBTYPE (fcf));
+ FCF_FRAME_SUBTYPE (fcf));
flag_item =
- proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb,
+ proto_tree_add_uint_format (fc_tree, hf_fc_flags, tvb,
wlan_broken_fc?0: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,
+ proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb,
wlan_broken_fc?0:1, 1,
- COOK_DS_STATUS (flags));
- proto_tree_add_boolean_hidden (flag_tree, hf_fc_to_ds, tvb, 1, 1,
+ FLAGS_DS_STATUS (flags));
+ proto_tree_add_boolean_hidden (flag_tree, hf_fc_to_ds, tvb, 1, 1,
flags);
- proto_tree_add_boolean_hidden (flag_tree, hf_fc_from_ds, tvb, 1, 1,
+ proto_tree_add_boolean_hidden (flag_tree, hf_fc_from_ds, tvb, 1, 1,
flags);
- proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb,
+ proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb,
wlan_broken_fc?0:1, 1,
flags);
- proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb,
+ proto_tree_add_boolean (flag_tree, hf_fc_retry, tvb,
wlan_broken_fc?0:1, 1, flags);
- proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb,
+ proto_tree_add_boolean (flag_tree, hf_fc_pwr_mgt, tvb,
wlan_broken_fc?0:1, 1, flags);
- proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb,
+ proto_tree_add_boolean (flag_tree, hf_fc_more_data, tvb,
wlan_broken_fc?0:1, 1,
flags);
- proto_tree_add_boolean (flag_tree, hf_fc_wep, tvb,
+ proto_tree_add_boolean (flag_tree, hf_fc_protected, tvb,
wlan_broken_fc?0:1, 1, flags);
- proto_tree_add_boolean (flag_tree, hf_fc_order, tvb,
+ proto_tree_add_boolean (flag_tree, hf_fc_order, tvb,
wlan_broken_fc?0:1, 1, flags);
if (frame_type_subtype == CTRL_PS_POLL)
proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
- COOK_ASSOC_ID(tvb_get_letohs(tvb,2)));
+ ASSOC_ID(tvb_get_letohs(tvb,2)));
else
proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
frag_number = 0;
seq_number = 0;
- switch (COOK_FRAME_TYPE (fcf))
+ switch (FCF_FRAME_TYPE (fcf))
{
case MGT_FRAME:
whdr->type = frame_type_subtype;
seq_control = tvb_get_letohs(tvb, 22);
- frag_number = COOK_FRAGMENT_NUMBER(seq_control);
- seq_number = COOK_SEQUENCE_NUMBER(seq_control);
+ frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
+ seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
+
+ if (check_col (pinfo->cinfo, COL_INFO))
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ ",SN=%d", seq_number);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ ",FN=%d",frag_number);
+ }
if (tree)
{
proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6, src);
}
break;
+
+ case CTRL_BLOCK_ACK_REQ:
+ {
+ src = tvb_get_ptr (tvb, 10, 6);
+ dst = tvb_get_ptr (tvb, 4, 6);
+
+ set_src_addr_cols(pinfo, src, "TA");
+ set_dst_addr_cols(pinfo, dst, "RA");
+
+ if (tree)
+ {
+ proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
+
+ proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
+ }
+ /* TODO BAR */
+ break;
+ }
+
+ case CTRL_BLOCK_ACK:
+ {
+ src = tvb_get_ptr (tvb, 10, 6);
+ dst = tvb_get_ptr (tvb, 4, 6);
+
+ set_src_addr_cols(pinfo, src, "TA");
+ set_dst_addr_cols(pinfo, dst, "RA");
+
+ if (tree)
+ {
+ proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6, src);
+
+ proto_tree_add_ether (hdr_tree, hf_addr_ta, tvb, 10, 6, dst);
+ }
+ /* TODO BAR Format */
+ break;
+ }
}
break;
case DATA_FRAME:
- addr_type = COOK_ADDR_SELECTOR (fcf);
+ addr_type = FCF_ADDR_SELECTOR (fcf);
/* In order to show src/dst address we must always do the following */
switch (addr_type)
whdr->type = frame_type_subtype;
seq_control = tvb_get_letohs(tvb, 22);
- frag_number = COOK_FRAGMENT_NUMBER(seq_control);
- seq_number = COOK_SEQUENCE_NUMBER(seq_control);
+ frag_number = SEQCTL_FRAGMENT_NUMBER(seq_control);
+ seq_number = SEQCTL_SEQUENCE_NUMBER(seq_control);
+
+ if (check_col (pinfo->cinfo, COL_INFO))
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ ",SN=%d", seq_number);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ ",FN=%d",frag_number);
+ }
/* Now if we have a tree we start adding stuff */
if (tree)
reported_len -= 4;
if (tree)
{
- guint32 fcs = crc32_802_tvb(tvb, hdr_len + len);
guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len);
+ guint32 fcs;
+
+ if (datapad)
+ fcs = crc32_802_tvb_padded(tvb, ohdr_len, hdr_len, len);
+ else
+ fcs = crc32_802_tvb(tvb, hdr_len + len);
if (fcs == sent_fcs)
proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb,
hdr_len + len, 4, sent_fcs,
}
}
- if (tree && (frame_type_subtype == DATA_QOS_DATA || frame_type_subtype == DATA_QOS_NULL)) {
- proto_item *qos_fields;
- proto_tree *qos_tree;
-
- guint16 qos_control, qos_priority, qos_ack_policy;
-
- qos_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len - 2, 2,
- "QoS parameters");
- qos_tree = proto_item_add_subtree (qos_fields, ett_qos_parameters);
-
- qos_control = tvb_get_letohs(tvb, hdr_len - 2);
- qos_priority = COOK_QOS_PRIORITY(qos_control);
- qos_ack_policy = COOK_QOS_ACK_POLICY(qos_control);
- proto_tree_add_uint_format (qos_tree, hf_qos_priority, tvb,
- hdr_len - 2, 2, qos_priority,
- "Priority: %d (%s) (%s)",
- qos_priority, qos_tags[qos_priority], qos_acs[qos_priority]);
- proto_tree_add_uint_format (qos_tree, hf_qos_ack_policy, tvb,
- hdr_len - 2, 2, qos_ack_policy,
- "Ack Policy: %d (%sAcknowledge)",
- qos_ack_policy, qos_ack_policy ? "Do not " : "");
- }
+
/*
* Only management and data frames have a body, so we don't have
* anything more to do for other types of frames.
*/
- switch (COOK_FRAME_TYPE (fcf))
+ switch (FCF_FRAME_TYPE (fcf))
{
case MGT_FRAME:
break;
case DATA_FRAME:
+ if (tree && DATA_FRAME_IS_QOS(frame_type_subtype))
+ {
+
+ proto_item *qos_fields;
+ proto_tree *qos_tree;
+
+ guint16 qosoff;
+ guint16 qos_control;
+ guint16 qos_priority;
+ guint16 qos_ack_policy;
+ guint16 qos_eosp;
+ guint16 qos_field_content;
+
+ /*
+ * We calculate the offset to the QoS header data as
+ * an offset relative to the end of the header. But
+ * when the header has been padded to align the data
+ * this must be done relative to true header size, not
+ * the padded/aligned value. To simplify this work we
+ * stash the original header size in ohdr_len instead
+ * of recalculating it.
+ */
+ qosoff = ohdr_len - 2;
+ qos_fields = proto_tree_add_text(hdr_tree, tvb, qosoff, 2,
+ "QoS parameters");
+ qos_tree = proto_item_add_subtree (qos_fields, ett_qos_parameters);
+
+ qos_control = tvb_get_letohs(tvb, qosoff + 0);
+ qos_priority = QOS_PRIORITY(qos_control);
+ qos_ack_policy = QOS_ACK_POLICY(qos_control);
+ qos_eosp = QOS_EOSP(qos_control);
+ qos_field_content = QOS_FIELD_CONTENT( qos_control);
+
+ proto_tree_add_uint_format (qos_tree, hf_qos_priority, tvb,
+ qosoff, 2, qos_priority,
+ "Priority: %d (%s) (%s)",
+ qos_priority, qos_tags[qos_priority], qos_acs[qos_priority]);
+
+ if (flags & FLAG_FROM_DS) {
+ proto_tree_add_boolean (qos_tree, hf_qos_eosp, tvb,
+ qosoff, 1, qos_eosp);
+
+ if (DATA_FRAME_IS_CF_POLL(frame_type_subtype)) {
+ /* txop limit */
+ proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
+ qosoff + 1, 1, qos_field_content, "TXOP Limit: %d ", qos_field_content);
+
+ } else {
+ /* qap ps buffer state */
+ proto_item *qos_ps_buf_state_fields;
+ proto_tree *qos_ps_buf_state_tree;
+ guint16 buf_state;
+ guint16 buf_ac;
+ guint16 buf_load;
+
+ buf_state = QOS_PS_BUF_STATE(qos_field_content);
+ buf_ac = QOS_PS_BUF_AC(qos_field_content); /*access category */
+ buf_load = QOS_PS_BUF_LOAD(qos_field_content);
+
+ qos_ps_buf_state_fields = proto_tree_add_text(qos_tree, tvb, qosoff + 1, 1,
+ "QAP PS Buffer State: 0x%x", qos_field_content);
+ qos_ps_buf_state_tree = proto_item_add_subtree (qos_ps_buf_state_fields, ett_qos_ps_buf_state);
+
+/* FIXME: hf_ values not defined
+ proto_tree_add_boolean (qos_ps_buf_state_tree, hf_qos_buf_state, tvb,
+ 1, 1, buf_state);
+
+ proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_ac, tvb,
+ qosoff + 1, 1, buf_ac, "Priority: %d (%s)",
+ buf_ac, wme_acs[buf_ac]);
+
+ proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_load, tvb,
+ qosoff + 1, 1, buf_load, "Buffered load: %d ", (buf_load * 4096));
+*/
+
+ }
+ } else if (qos_eosp) {
+ /* txop limit requested */
+ proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
+ qosoff + 1, 1, qos_field_content, "Queue Size: %d ", (qos_field_content * 254));
+ } else {
+ /* queue size */
+ proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb,
+ qosoff + 1, 1, qos_field_content, "TXOP Limit Requested: %d ", qos_field_content);
+ }
+
+ proto_tree_add_uint (qos_tree, hf_qos_ack_policy, tvb, qosoff, 1,
+ qos_ack_policy);
+
+ } /* end of qos control field */
+
/*
* No-data frames don't have a body.
*/
- switch (frame_type_subtype)
- {
+ if (DATA_FRAME_IS_NULL(frame_type_subtype))
+ return;
- case DATA_NULL_FUNCTION:
- case DATA_CF_ACK_NOD:
- case DATA_CF_POLL_NOD:
- case DATA_CF_ACK_POLL_NOD:
- case DATA_QOS_NULL:
- return;
- }
- break;
+ break;
+
+ case CONTROL_FRAME:
+ return;
default:
return;
}
- if (IS_WEP(COOK_FLAGS(fcf))) {
+ if (IS_PROTECTED(FCF_FLAGS(fcf))) {
/*
* It's a WEP-encrypted frame; dissect the WEP parameters and decrypt
* the data, if we have a matching key. Otherwise display it as data.
guint8 key, keybyte;
keybyte = tvb_get_guint8(tvb, hdr_len + 3);
- key = COOK_WEP_KEY(keybyte);
+ key = KEY_OCTET_WEP_KEY(keybyte);
if ((keybyte & KEY_EXTIV) && (len >= EXTIV_LEN)) {
/* Extended IV; this frame is likely encrypted with TKIP or CCMP */
if (tree) {
* determined to be possible only with one of the encryption protocols.
*/
if (tvb_get_guint8(tvb, hdr_len + 1) & 0x20) {
- snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
+ g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
tvb_get_letohl(tvb, hdr_len + 4),
tvb_get_guint8(tvb, hdr_len),
tvb_get_guint8(tvb, hdr_len + 2));
proto_tree_add_string(wep_tree, hf_tkip_extiv, tvb, hdr_len,
EXTIV_LEN, out_buff);
- }
+ }
if (tvb_get_guint8(tvb, hdr_len + 2) == 0) {
- snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
+ g_snprintf(out_buff, SHORT_STR, "0x%08X%02X%02X",
tvb_get_letohl(tvb, hdr_len + 4),
tvb_get_guint8(tvb, hdr_len + 1),
tvb_get_guint8(tvb, hdr_len));
next_tvb = tvb_new_subset(tvb, hdr_len + ivlen, len, reported_len);
if (tree && can_decrypt)
- proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
- hdr_len + ivlen + len, 4,
+ proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
+ hdr_len + ivlen + len, 4,
tvb_get_ntohl(tvb, hdr_len + ivlen + len),
- "WEP ICV: 0x%08x (not verified)",
+ "WEP ICV: 0x%08x (not verified)",
tvb_get_ntohl(tvb, hdr_len + ivlen + len));
if (pinfo->ethertype != ETHERTYPE_CENTRINO_PROMISC)
} else {
if (tree)
- proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
- hdr_len + ivlen + len, 4,
+ proto_tree_add_uint_format (wep_tree, hf_wep_icv, tvb,
+ hdr_len + ivlen + len, 4,
tvb_get_ntohl(tvb, hdr_len + ivlen + len),
- "WEP ICV: 0x%08x (correct)",
+ "WEP ICV: 0x%08x (correct)",
tvb_get_ntohl(tvb, hdr_len + ivlen + len));
add_new_data_source(pinfo, next_tvb, "Decrypted WEP data");
goto end_of_wlan;
}
- switch (COOK_FRAME_TYPE (fcf))
+ switch (FCF_FRAME_TYPE (fcf))
{
case MGT_FRAME:
dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
- pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE);
+ pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
+}
+
+/*
+ * Dissect 802.11 with a variable-length link-layer header and data padding.
+ */
+static void
+dissect_ieee80211_datapad (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+{
+ dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE,
+ pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, TRUE);
}
/*
dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE,
- pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE);
+ pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE);
}
/*
static void
dissect_ieee80211_bsfc (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
- dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE);
+ dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE, FALSE);
}
/*
static void
dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
- dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE);
+ dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE, FALSE);
}
static void
void
proto_register_ieee80211 (void)
{
+ int i;
+ GString *key_name, *key_title, *key_desc;
+
static const value_string frame_type[] = {
{MGT_FRAME, "Management frame"},
{CONTROL_FRAME, "Control frame"},
};
static const value_string tofrom_ds[] = {
- {0, "Not leaving DS or network is operating in AD-HOC mode (To DS: 0 From DS: 0)"},
- {FLAG_TO_DS, "Frame is entering DS (To DS: 1 From DS: 0)"},
- {FLAG_FROM_DS, "Frame is exiting DS (To DS: 0 From DS: 1)"},
- {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS (To DS: 1 From DS: 1)"},
+ {0, "Not leaving DS or network is operating "
+ "in AD-HOC mode (To DS: 0 From DS: 0)"},
+ {FLAG_TO_DS, "Frame from STA to DS via an AP (To DS: 1 "
+ "From DS: 0)"},
+ {FLAG_FROM_DS, "Frame from DS to a STA via AP(To DS: 0 "
+ "From DS: 1)"},
+ {FLAG_TO_DS|FLAG_FROM_DS, "Frame part of WDS from one AP to another "
+ "AP (To DS: 1 From DS: 1)"},
{0, NULL}
};
"No data buffered"
};
- static const true_false_string wep_flags = {
- "WEP is enabled",
- "WEP is disabled"
+ static const true_false_string protected_flags = {
+ "Data is protected",
+ "Data is not protected"
};
static const true_false_string order_flags = {
"DSSS-OFDM modulation not allowed"
};
+ static const true_false_string cf_spec_man_flags = {
+ "dot11SpectrumManagementRequired TRUE",
+ "dot11SpectrumManagementRequired FALSE",
+ };
+
+ static const true_false_string cf_apsd_flags = {
+ "apsd implemented",
+ "apsd not implemented",
+ };
+ static const true_false_string cf_del_blk_ack_flags = {
+ "delayed block ack implemented",
+ "delayed block ack not implented",
+ };
+
+ static const true_false_string cf_imm_blk_ack_flags = {
+ "immediate block ack implemented",
+ "immediate block ack not implented",
+ };
static const true_false_string cf_ibss_flags = {
"Transmitter belongs to an IBSS",
"Transmitter belongs to a BSS"
};
+ static const true_false_string eosp_flag = {
+ "End of service period",
+ "Service period"
+ };
+
static const value_string sta_cf_pollable[] = {
{0x00, "Station is not CF-Pollable"},
{0x02, "Station is CF-Pollable, "
{0x01, "Station is CF-Pollable, "
"requesting to be placed on the CF-polling list"},
{0x03, "Station is CF-Pollable, requesting never to be polled"},
+ {0x0200, "QSTA requesting association in QBSS"},
{0, NULL}
};
{0x02, "Point coordinator at AP for delivery only (no polling)"},
{0x01, "Point coordinator at AP for delivery and polling"},
{0x03, "Reserved"},
+ {0x0200, "QAP (HC) does not use CFP for delivery of unicast data type frames"},
+ {0x0202, "QAP (HC) uses CFP for delivery, but does not send CF-Polls to non-QoS STAs"},
+ {0x0201, "QAP (HC) uses CFP for delivery, and sends CF-Polls to non-QoS STAs"},
+ {0x0203, "Reserved"},
{0, NULL}
};
{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"},
+ "responding station"},
+ {0x0A, "Disassociated because the information in the Power Capability "
+ "element is unacceptable"},
+ {0x0B, "Disassociated because the information in the Supported"
+ "Channels element is unacceptable"},
{0x0D, "Invalid Information Element"},
{0x0E, "Michael MIC failure"},
{0x0F, "4-Way Handshake timeout"},
{0x16, "Invalid RSN IE Capabilities"},
{0x17, "IEEE 802.1X Authentication failed"},
{0x18, "Cipher suite is rejected per security policy"},
+ {0x20, "Disassociated for unspecified, QoS-related reason"},
+ {0x21, "Disassociated because QAP lacks sufficient bandwidth for this QSTA"},
+ {0x22, "Disassociated because of excessive number of frames that need to be "
+ "acknowledged, but are not acknowledged for AP transmissions and/or poor "
+ "channel conditions"},
+ {0x23, "Disassociated because QSTA is transmitting outside the limits of its TXOPs"},
+ {0x24, "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)"},
+ {0x25, "Requested from peer QSTA as it does not want to use the mechanism"},
+ {0x26, "Requested from peer QSTA as the QSTA received frames using the mechanism "
+ "for which a set up is required"},
+ {0x27, "Requested from peer QSTA due to time out"},
+ {0x2D, "Peer QSTA does not support the requested cipher suite"},
{0x00, NULL}
};
"PBCC encoding"},
{0x15, "Association denied due to requesting station not supporting "
"channel agility"},
+ {0x16, "Association request rejected because Spectrum Management"
+ "capability is required"},
+ {0x17, "Association request rejected because the information in the"
+ "Power Capability element is unacceptable"},
+ {0x18, "Association request rejected because the information in the"
+ "Supported Channels element is unacceptable"},
{0x19, "Association denied due to requesting station not supporting "
"short slot operation"},
{0x1A, "Association denied due to requesting station not supporting "
"DSSS-OFDM operation"},
+ {0x20, "Unspecified, QoS-related failure"},
+ {0x21, "Association denied due to QAP having insufficient bandwidth "
+ "to handle another QSTA"},
+ {0x22, "Association denied due to excessive frame loss rates and/or "
+ "poor conditions on current operating channel"},
+ {0x23, "Association (with QBSS) denied due to requesting station not "
+ "supporting the QoS facility"},
+ {0x24, "Association denied due to requesting station not supporting "
+ "Block Ack"},
+ {0x25, "The request has been declined."},
+ {0x26, "The request has not been successful as one or more parameters "
+ "have invalid values."},
+ {0x27, "The TS has not been created because the request cannot be honored. "
+ "However, a suggested TSPEC is provided so that the initiating QSTA may "
+ "attempt to set another TS with the suggested changes to the TSPEC."},
{0x28, "Invalid Information Element"},
{0x29, "Group Cipher is not valid"},
{0x2A, "Pairwise Cipher is not valid"},
{0x2C, "Unsupported RSN IE version"},
{0x2D, "Invalid RSN IE Capabilities"},
{0x2E, "Cipher suite is rejected per security policy"},
+ {0x2F, "The TS has not been created. However, the HC may be capable of "
+ "creating a TS, in response to a request, after the time indicated in the TS Delay element."},
+ {0x30, "Direct Link is not allowed in the BSS by policy"},
+ {0x31, "Destination STA is not present within this QBSS."},
+ {0x32, "The Destination STA is not a QSTA."},
{0x00, NULL}
};
static const value_string category_codes[] = {
- {0x11, "Management notification frame"},
- {0x00, NULL}
+ {CAT_SPECTRUM_MGMT, "Spectrum Management"},
+ {CAT_QOS, "QoS"},
+ {CAT_DLS, "DLS"},
+ {CAT_BLOCK_ACK, "Block Ack"},
+ {CAT_MGMT_NOTIFICATION, "Management notification frame"},
+ {0, NULL}
};
- static const value_string action_codes[] = {
- {0x00, NULL}
+ static const value_string action_codes[] ={
+ {SM_ACTION_MEASUREMENT_REQUEST, "Measurement Request"},
+ {SM_ACTION_MEASUREMENT_REPORT, "Measurement Report"},
+ {SM_ACTION_TPC_REQUEST, "TPC Request"},
+ {SM_ACTION_TPC_REPORT, "TPC Report"},
+ {SM_ACTION_CHAN_SWITCH_ANNC, "Channel Switch Announcement"},
+ {0, NULL}
};
static const value_string wme_action_codes[] = {
{0x00, NULL}
};
+ static const value_string ack_policy[] = {
+ {0x00, "Normal Ack"},
+ {0x02, "No Ack"},
+ {0x01, "No explicit Ack"},
+ {0x03, "Block Ack"},
+ {0x00, NULL}
+ };
+
static hf_register_info hf[] = {
{&hf_data_rate,
{"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0,
{"More Data", "wlan.fc.moredata", FT_BOOLEAN, 8, TFS (&md_flags), FLAG_MORE_DATA,
"More data flag", HFILL }},
- {&hf_fc_wep,
- {"WEP flag", "wlan.fc.wep", FT_BOOLEAN, 8, TFS (&wep_flags), FLAG_WEP,
- "WEP flag", HFILL }},
+ {&hf_fc_protected,
+ {"Protected flag", "wlan.fc.protected", FT_BOOLEAN, 8, TFS (&protected_flags), FLAG_PROTECTED,
+ "Protected flag", HFILL }},
{&hf_fc_order,
{"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), FLAG_ORDER,
{"Priority", "wlan.qos.priority", FT_UINT16, BASE_DEC, NULL, 0,
"802.1D Tag", HFILL }},
+ {&hf_qos_eosp,
+ {"EOSP", "wlan.qos.eosp", FT_BOOLEAN, 8, TFS (&eosp_flag), QOS_FLAG_EOSP,
+ "EOSP Field", HFILL }},
+
{&hf_qos_ack_policy,
- {"Ack Policy", "wlan.qos.ack", FT_UINT16, BASE_DEC, NULL, 0,
+ {"Ack Policy", "wlan.qos.ack", FT_UINT16, BASE_HEX, VALS (&ack_policy), 0,
"Ack Policy", HFILL }},
+ {&hf_qos_field_content,
+ {"Content", "wlan.qos.fc_content", FT_UINT16, BASE_DEC, NULL, 0,
+ "Content1", HFILL }},
+
+/* {&hf_qos_buffer_state,
+ {"QAP PS buffer State", "wlan.qos.ps_buf_state", FT_UINT16, BASE_DEC, NULL, 0,
+ "QAP PS buffer State", HFILL }},
+
+ {&hf_qos_txop_dur_req,
+ {"TXOP Duration Requested", "wlan.qos.txop_dur_req", FT_UINT16, BASE_DEC, NULL, 0,
+ "TXOP Duration Requested", HFILL }},
+
+ {&hf_qos_queue_size,
+ {"Queue Size", "wlan.qos.queue_size", FT_UINT16, BASE_DEC, NULL, 0,
+ "Queue Size", HFILL }},*/
+
{&hf_fcs,
{"Frame check sequence", "wlan.fcs", FT_UINT32, BASE_HEX,
NULL, 0, "FCS", HFILL }},
BASE_HEX, NULL, 0, "CCMP Extended Initialization Vector", HFILL }},
{&hf_wep_key,
- {"Key", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
- "Key", HFILL }},
+ {"Key Index", "wlan.wep.key", FT_UINT8, BASE_DEC, NULL, 0,
+ "Key Index", HFILL }},
{&hf_wep_icv,
{"WEP ICV", "wlan.wep.icv", FT_UINT32, BASE_HEX, NULL, 0,
{&ff_cf_sta_poll,
{"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.sta",
- FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0x000C,
+ FT_UINT16, BASE_HEX, VALS (&sta_cf_pollable), 0x020C,
"CF-Poll capabilities for a STA", HFILL }},
{&ff_cf_ap_poll,
{"CFP participation capabilities", "wlan_mgt.fixed.capabilities.cfpoll.ap",
- FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0x000C,
+ FT_UINT16, BASE_HEX, VALS (&ap_cf_pollable), 0x020C,
"CF-Poll capabilities for an AP", HFILL }},
{&ff_cf_privacy,
{"Channel Agility", "wlan_mgt.fixed.capabilities.agility",
FT_BOOLEAN, 16, TFS (&cf_agility_flags), 0x0080, "Channel Agility", HFILL }},
+ {&ff_cf_spec_man,
+ {"Spectrum Management", "wlan_mgt.fixed.capabilities.spec_man",
+ FT_BOOLEAN, 16, TFS (&cf_spec_man_flags), 0x0100, "Spectrum Management", HFILL }},
+
{&ff_short_slot_time,
{"Short Slot Time", "wlan_mgt.fixed.capabilities.short_slot_time",
FT_BOOLEAN, 16, TFS (&short_slot_time_flags), 0x0400, "Short Slot Time",
HFILL }},
+ {&ff_cf_apsd,
+ {"Automatic Power Save Delivery", "wlan_mgt.fixed.capabilities.apsd",
+ FT_BOOLEAN, 16, TFS (&cf_apsd_flags), 0x0800, "Automatic Power Save "
+ "Delivery", HFILL }},
+
{&ff_dsss_ofdm,
{"DSSS-OFDM", "wlan_mgt.fixed.capabilities.dsss_ofdm",
FT_BOOLEAN, 16, TFS (&dsss_ofdm_flags), 0x2000, "DSSS-OFDM Modulation",
HFILL }},
+ {&ff_cf_del_blk_ack,
+ {"Delayed Block Ack", "wlan_mgt.fixed.capabilities.del_blk_ack",
+ FT_BOOLEAN, 16, TFS (&cf_del_blk_ack_flags), 0x4000, "Delayed Block "
+ "Ack", HFILL }},
+
+ {&ff_cf_imm_blk_ack,
+ {"Immediate Block Ack", "wlan_mgt.fixed.capabilities.imm_blk_ack",
+ FT_BOOLEAN, 16, TFS (&cf_imm_blk_ack_flags), 0x8000, "Immediate Block "
+ "Ack", HFILL }},
+
{&ff_auth_seq,
{"Authentication SEQ", "wlan_mgt.fixed.auth_seq",
FT_UINT16, BASE_HEX, NULL, 0, "Authentication sequence number", HFILL }},
{&ff_category_code,
{"Category code", "wlan_mgt.fixed.category_code",
- FT_UINT16, BASE_HEX, VALS (&category_codes), 0,
+ FT_UINT16, BASE_DEC, VALS (&category_codes), 0,
"Management action category", HFILL }},
{&ff_action_code,
{"Action code", "wlan_mgt.fixed.action_code",
- FT_UINT16, BASE_HEX, VALS (&action_codes), 0,
+ FT_UINT16, BASE_DEC, VALS (&action_codes), 0,
"Management action code", HFILL }},
{&ff_dialog_token,
{"Tag interpretation", "wlan_mgt.tag.interpretation",
FT_STRING, BASE_NONE, NULL, 0, "Interpretation of tag", HFILL }},
+ {&tag_oui,
+ {"OUI", "wlan_mgt.tag.oui",
+ FT_BYTES, BASE_NONE, NULL, 0, "OUI of vendor specific IE", HFILL }},
+
{&tim_length,
{"TIM length", "wlan_mgt.tim.length",
FT_UINT8, BASE_DEC, NULL, 0,
"wlan_mgt.rsn.capabilities.gtksa_replay_counter",
FT_UINT16, BASE_HEX, VALS (&rsn_cap_replay_counter), 0x0030,
"RSN GTKSA Replay Counter capabilities", HFILL }},
+
+ {&hf_aironet_ie_type,
+ {"Aironet IE type", "wlan_mgt.aironet.type",
+ FT_UINT8, BASE_DEC, VALS(aironet_ie_type_vals), 0, "", HFILL }},
+
+ {&hf_aironet_ie_version,
+ {"Aironet IE CCX version?", "wlan_mgt.aironet.version",
+ FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+ { &hf_aironet_ie_data,
+ { "Aironet IE data", "wlan_mgmt.aironet.data",
+ FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
+
+ {&hf_qbss_version,
+ {"QBSS Version", "wlan_mgt.qbss.version",
+ FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+ {&hf_qbss_scount,
+ {"Station Count", "wlan_mgt.qbss.scount",
+ FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
+
+ {&hf_qbss_cu,
+ {"Channel Utilization", "wlan_mgt.qbss.cu",
+ FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+ {&hf_qbss_adc,
+ {"Available Admission Capabilities", "wlan_mgt.qbss.adc",
+ FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+ {&hf_qbss2_cu,
+ {"Channel Utilization", "wlan_mgt.qbss2.cu",
+ FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+ {&hf_qbss2_gl,
+ {"G.711 CU Quantum", "wlan_mgt.qbss2.glimit",
+ FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+ {&hf_qbss2_cal,
+ {"Call Admission Limit", "wlan_mgt.qbss2.cal",
+ FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+ {&hf_qbss2_scount,
+ {"Station Count", "wlan_mgt.qbss2.scount",
+ FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
+
+ {&hf_aironet_ie_qos_unk1,
+ {"Aironet IE QoS unknown1", "wlan_mgt.aironet.qos.unk1",
+ FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
+
+ {&hf_aironet_ie_qos_paramset,
+ {"Aironet IE QoS paramset", "wlan_mgt.aironet.qos.paramset",
+ FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
+
+ {&hf_aironet_ie_qos_val,
+ {"Aironet IE QoS valueset", "wlan_mgt.aironet.qos.val",
+ FT_BYTES, BASE_NONE, NULL, 0, "", HFILL }},
+
};
static gint *tree_array[] = {
&ett_fixed_parameters,
&ett_tagged_parameters,
&ett_qos_parameters,
+ &ett_qos_ps_buf_state,
&ett_wep_parameters,
&ett_cap_tree,
&ett_rsn_cap_tree,
};
module_t *wlan_module;
- static const enum_val_t wep_keys_options[] = {
- {"0", "0", 0},
- {"1", "1", 1},
- {"2", "2", 2},
- {"3", "3", 3},
- {"4", "4", 4},
- {NULL, NULL, -1},
- };
+ enum_val_t *wep_keys_options = g_malloc(sizeof(enum_val_t) * (MAX_ENCRYPTION_KEYS + 2));
proto_wlan = proto_register_protocol ("IEEE 802.11 wireless LAN",
register_dissector("wlan", dissect_ieee80211, proto_wlan);
register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan);
+ register_dissector("wlan_datapad", dissect_ieee80211_datapad, proto_wlan);
register_init_routine(wlan_defragment_init);
wlan_tap = register_tap("wlan");
&wlan_ignore_wep);
#ifndef USE_ENV
+
+ for (i = 0; i <= MAX_ENCRYPTION_KEYS; i++) {
+ key_name = g_string_new("");
+ g_string_sprintf(key_name, "%d", i);
+ wep_keys_options[i].name = key_name->str;
+ wep_keys_options[i].description = key_name->str;
+ wep_keys_options[i].value = i;
+ g_string_free(key_name, FALSE);
+ }
+ wep_keys_options[i].name = NULL;
+ wep_keys_options[i].description = NULL;
+ wep_keys_options[i].value = -1;
+
+ key_desc = g_string_new("");
+ g_string_sprintf(key_desc, "How many WEP keys do we have to choose from? (0 to disable, up to %d)", MAX_ENCRYPTION_KEYS);
prefs_register_enum_preference(wlan_module, "wep_keys",
- "WEP key count",
- "How many WEP keys do we have to choose from? (0 to disable, up to 4)",
+ "WEP key count", key_desc->str,
&num_wepkeys, wep_keys_options, FALSE);
-
- prefs_register_string_preference(wlan_module, "wep_key1",
- "WEP key #1",
- "First WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
- &wep_keystr[0]);
- prefs_register_string_preference(wlan_module, "wep_key2",
- "WEP key #2",
- "Second WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
- &wep_keystr[1]);
- prefs_register_string_preference(wlan_module, "wep_key3",
- "WEP key #3",
- "Third WEP key (A:B:C:D:E) [40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
- &wep_keystr[2]);
- prefs_register_string_preference(wlan_module, "wep_key4",
- "WEP key #4",
- "Fourth WEP key (A:B:C:D:E) [40bit] (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key length you're using",
- &wep_keystr[3]);
+ g_string_free(key_desc, FALSE);
+
+ for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
+ key_name = g_string_new("");
+ key_title = g_string_new("");
+ key_desc = g_string_new("");
+ wep_keystr[i] = NULL;
+ /* prefs_register_*_preference() expects unique strings, so
+ * we build them using g_string_sprintf and just leave them
+ * allocated. */
+ g_string_sprintf(key_name, "wep_key%d", i + 1);
+ g_string_sprintf(key_title, "WEP key #%d", i + 1);
+ g_string_sprintf(key_desc, "WEP key #%d bytes in hexadecimal (A:B:C:D:E) "
+ "[40bit], (A:B:C:D:E:F:G:H:I:J:K:L:M) [104bit], or whatever key "
+ "length you're using", i + 1);
+
+ prefs_register_string_preference(wlan_module, key_name->str,
+ key_title->str, key_desc->str, &wep_keystr[i]);
+
+ g_string_free(key_name, FALSE);
+ g_string_free(key_title, FALSE);
+ g_string_free(key_desc, FALSE);
+ }
#endif
}
key[0] = buf[0];
key[1] = buf[1];
key[2] = buf[2];
- keyidx = COOK_WEP_KEY(buf[3]);
+ keyidx = KEY_OCTET_WEP_KEY(buf[3]);
if (key_override >= 0)
keyidx = key_override;
}
static void init_wepkeys(void) {
- char *tmp;
+ const char *tmp;
int i;
GByteArray *bytes;
gboolean res;
#ifdef USE_ENV
- guint8 buf[128];
+ guint8 *buf;
- tmp = getenv("ETHEREAL_WEPKEYNUM");
+ tmp = getenv("WIRESHARK_WEPKEYNUM");
if (!tmp) {
num_wepkeys = 0;
return;
wep_keylens[i] = 0;
#ifdef USE_ENV
- sprintf(buf, "ETHEREAL_WEPKEY%d", i+1);
+ buf=ep_alloc(128);
+ g_snprintf(buf, 128, "WIRESHARK_WEPKEY%d", i+1);
tmp = getenv(buf);
#else
tmp = wep_keystr[i];