# # Thanks to Steve Brown for porting this patch to # wireshark 1.02 # --- epan/dissectors/packet-ieee80211.c.orig 2008-07-10 13:39:26.000000000 -0400 +++ epan/dissectors/packet-ieee80211.c 2008-07-28 08:31:19.000000000 -0400 @@ -47,6 +47,9 @@ * * Dutin Johnson - 802.11n and portions of 802.11k and 802.11ma * dustin@dustinj.us & dustin.johnson@cacetech.com + * + * 01/31/2008 - Added dissection of 802.11s + * Javier Cardona */ /* @@ -365,6 +368,11 @@ #define KEY_EXTIV 0x20 #define EXTIV_LEN 8 +/* + * Bits from the Mesh Flags field + */ +#define MESH_FLAGS_ADDRESS_EXTENSION 0x3 + /* ************************************************************************* */ /* Constants used to identify cooked frame types */ @@ -488,6 +496,10 @@ #define FIELD_EXTENDED_CHANNEL_SWITCH_ANNOUNCEMENT 0x2E #define FIELD_HT_INFORMATION 0x2F #define FIELD_HT_ACTION_CODE 0x30 +#define FIELD_MESH_MGT_ACTION_PS_CODE 0x31 /* Mesh Management action peer link code */ +#define FIELD_MESH_MGT_ACTION_PL_CODE 0x32 /* Mesh Management action peer link code */ + + /* ************************************************************************* */ /* Logical field codes (IEEE 802.11 encoding of tags) */ @@ -513,12 +525,6 @@ #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 @@ -527,7 +533,32 @@ #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_NEIGHBOR_REPORT 0x34 +//#define TAG_NEIGHBOR_REPORT 0x34 + +#define MESH_OVERRIDES +#ifndef MESH_OVERRIDES +#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 +#else +#define TAG_SUPPORTED_CHANNELS 0xE0 +#define TAG_CHANNEL_SWITCH_ANN 0xE1 +#define TAG_MEASURE_REQ 0xE2 +#define TAG_MEASURE_REP 0xE3 +#define TAG_QUIET 0xE4 +#define TAG_IBSS_DFS 0xE5 +/* Not yet assigned by ANA */ +#define TAG_MESH_CONFIGURATION 51 /* 36 */ +#define TAG_MESH_ID 52 /* 37 */ +#define TAG_MESH_PEER_LINK_MGMT 55 /* 40 */ +#define TAG_MESH_PREQ 68 /* 53 */ +#define TAG_MESH_PREP 69 /* 54 */ +#define TAG_MESH_PERR 70 /* 55 */ +#endif + #define TAG_HT_INFO 0x3D /* IEEE Stc 802.11n/D2.0 */ #define TAG_SECONDARY_CHANNEL_OFFSET 0x3E /* IEEE Stc 802.11n/D1.10/D2.0 */ #define TAG_EXTENDED_CAPABILITIES 0X7F /* IEEE Stc 802.11n/D1.10/D2.0 */ @@ -640,6 +671,13 @@ #define CAT_DLS 2 #define CAT_BLOCK_ACK 3 +#define CAT_MESH_PEER_LINK 30 /* Per 802.11s draft 1.08. ANA will probably revise this */ +#define CAT_MESH_LINK_METRIC 31 +#define CAT_MESH_PATH_SELECTION 32 +#define CAT_MESH_INTERWORKING 33 +#define CAT_MESH_RESOURCE_COORDINATION 34 +#define CAT_MESH_SECURITY_ARCHITECTURE 35 + #define CAT_RADIO_MEASUREMENT 6 #define CAT_HT 7 #define CAT_MGMT_NOTIFICATION 17 @@ -674,6 +712,32 @@ #define HT_ACTION_MIMO_COMPRESSED_BEAMFORMING 6 #define HT_ACTION_ANT_SEL_FEEDBACK 7 #define HT_ACTION_HT_INFO_EXCHANGE 8 + + +#define MESH_PL_PEER_LINK_OPEN 0 +#define MESH_PL_PEER_LINK_CONFIRM 1 +#define MESH_PL_PEER_LINK_CLOSE 2 + +#define MESH_PS_PATH_REQUEST 0 +#define MESH_PS_PATH_REPLY 1 +#define MESH_PS_PATH_ERROR 2 +#define MESH_PS_ROOT_ANNOUNCEMENT 3 + +/* 11s draft, table 7-22 */ +#define MESH_LINK_CANCELLED 2 +#define MESH_MAX_NEIGHBORS 3 +#define MESH_CONFIG_POLICY_VIOLATION 4 +#define MESH_CLOSE_RCVD 5 +#define MESH_MAX_RETRIES 6 +#define MESH_CONFIRM_TIMEOUT 7 + +#define MESH_MGMT_IE_CONFIGURATION 36 +#define MESH_MGMT_IE_ID 37 +#define MESH_MGMT_IE_PEER_LINK 40 +#define MESH_MGMT_IE_PREQ 53 +#define MESH_MGMT_IE_PREP 54 +#define MESH_MGMT_IE_PERR 55 + /*** End: Action Fixed Parameter ***/ static int proto_wlan = -1; @@ -838,6 +902,16 @@ static int hf_fcs_bad = -1; /* ************************************************************************* */ +/* Header values for Mesh Header field */ +/* ************************************************************************* */ +static int hf_mesh_ttl = -1; +static int hf_mesh_seq = -1; +static int hf_mesh_flags = -1; +static int hf_mesh_ae1 = -1; +static int hf_mesh_ae2 = -1; +static int hf_mesh_ae3 = -1; + +/* ************************************************************************* */ /* Header values for reassembly */ /* ************************************************************************* */ static int hf_fragments = -1; @@ -1025,6 +1099,44 @@ static int ff_mimo_csi_snr = -1; /*** End: MIMO CSI Matrices Report - Dustin Johnson ***/ + +/*** Begin: Mesh Frame Format ***/ +static int ff_mesh_mgt_action_ps_code = -1;/* Mesh Management path selection action code */ +static int ff_mesh_mgt_action_pl_code = -1;/* Mesh Management peer link action code */ +static int ff_mesh_mgt_ie_id = -1; /* Mesh Management ID */ +static int ff_mesh_mgt_ttl = -1; /* Mesh Management TTL */ +static int ff_mesh_mgt_dstcount = -1; /* Mesh Management dst count */ +static int ff_mesh_mgt_hopcount = -1; /* Mesh Management hop count */ +static int ff_mesh_mgt_rreqid = -1; /* Mesh Management PREQ ID */ +static int ff_mesh_mgt_sa = -1; /* Mesh Management src addr */ +static int ff_mesh_mgt_ssn = -1; /* Mesh Management src sequence number */ +static int ff_mesh_mgt_metric = -1; /* Mesh Management metric */ +static int ff_mesh_mgt_flags = -1; /* Mesh Management PREQ flags */ +static int ff_mesh_mgt_dest_flags= -1; /* Mesh Management destination flags */ +static int ff_mesh_mgt_da = -1; /* Mesh Management dst addr */ +static int ff_mesh_mgt_dsn = -1; /* Mesh Management dst sequence number */ +static int ff_mesh_mgt_srccount = -1; /* Mesh Management src count */ +static int ff_mesh_mgt_lifetime = -1; /* Mesh Management lifetime */ +static int ff_mesh_mgt_dest_do_flags = -1; /* Mesh Management Destination Only flag */ +static int ff_mesh_mgt_dest_rf_flags = -1; /* Mesh Management Reply and Forward flag */ + + +/* variable header fields */ +static int hf_mesh_mgt_pl_subtype = -1;/* Mesh Management peer link frame subtype */ +static int hf_mesh_mgt_pl_local_link_id = -1;/* Mesh Management local link id */ +static int hf_mesh_mgt_pl_peer_link_id = -1;/* Mesh Management peer link id */ +static int hf_mesh_mgt_pl_reason_code = -1;/* Mesh Management peer link reason code */ +static int hf_mesh_config_version = -1; +static int hf_mesh_config_path_sel_protocol = -1; +static int hf_mesh_config_path_sel_metric = -1; +static int hf_mesh_config_congestion_control = -1; +static int hf_mesh_config_channel_prec = -1; +static int hf_mesh_config_capability = -1; + + +/*** End: Mesh Frame Format ***/ + + /* ************************************************************************* */ /* Flags found in the capability field (fixed field) */ /* ************************************************************************* */ @@ -1434,6 +1546,8 @@ static gint ett_qos_parameters = -1; static gint ett_qos_ps_buf_state = -1; static gint ett_wep_parameters = -1; +static gint ett_msh_parameters = -1; +static gint ett_msh_dest_flags_tree = -1; static gint ett_rsn_cap_tree = -1; @@ -1626,6 +1740,57 @@ } } +/* ************************************************************************* */ +/* Return the length of the mesh header if any (in bytes) + * + * Per IEEE 802.11-07/0799r8: + * 7.1.3.5a.1 The Mesh Header field (...) is present in Data frames if and + * only if they are transmitted between peer MPs with an established peer + * link. Data frames including the Mesh Header field are referred to as + * Mesh Data frames. + * + * We need a stateful sniffer for that. For now, use heuristics: If we + * find valid mesh flags (currently, only MESH_FLAGS_ADDRESS_EXTENSION) at the + * offset where mesh flags should be, assume we're dealing with a mesh header. + * ************************************************************************* */ +static int +find_mesh_header_length(const guchar * pd, int offset, guint16 fcf) +{ + guint8 mesh_flags; + + switch (FCF_FRAME_TYPE (fcf)) { + + case MGT_FRAME: + /* TODO: Multihop Action Frames */ + return 0; + + case DATA_FRAME: + mesh_flags = pd[offset]; + + /* heuristics: */ + /* asume mesh if all reserved bits in the mesh_flags field are zero */ + if (mesh_flags & ~MESH_FLAGS_ADDRESS_EXTENSION) + return 0; + + switch(mesh_flags & ~MESH_FLAGS_ADDRESS_EXTENSION) { +#if 0 + case 0: return 5; + case 1: return 11; + case 2: return 17; + case 3: return 23; +#else + case 0: return 6; + case 1: return 12; + case 2: return 18; + case 3: return 24; +#endif + } + + default: + return 0; + } +} + mimo_control_t get_mimo_control (tvbuff_t *tvb, int offset) { guint16 mimo; @@ -1870,8 +2035,11 @@ { if (fixed_length_header) hdr_length = DATA_LONG_HDR_LEN; - else + else { hdr_length = find_header_length (fcf, 0, is_ht); + hdr_length += find_mesh_header_length(pd, offset + hdr_length, fcf); + g_warning("ieee capture hdr_length %d\n", hdr_length); + } if (datapad) hdr_length = roundup2(hdr_length, 4); /* I guess some bridges take Netware Ethernet_802_3 frames, @@ -2342,6 +2510,17 @@ break; } + /* Mesh Management */ + case FIELD_MESH_MGT_ACTION_PS_CODE: + proto_tree_add_item (tree, ff_mesh_mgt_action_ps_code, tvb, offset, 1, TRUE); + length += 1; + break; + + case FIELD_MESH_MGT_ACTION_PL_CODE: + proto_tree_add_item (tree, ff_mesh_mgt_action_pl_code, tvb, offset, 1, TRUE); + length += 1; + break; + case FIELD_DLS_ACTION_CODE: proto_tree_add_item (tree, ff_dls_action_code, tvb, offset, 1, TRUE); length += 1; @@ -2889,6 +3068,88 @@ } break; } + case CAT_MESH_PEER_LINK: + /* Non-IE fixed fields here. edit TAG_MESH_* for IE fields */ + switch (tvb_get_guint8(tvb, 1)) + { + guint offset; + case MESH_PL_PEER_LINK_OPEN: + offset = 0; + offset += add_fixed_field (action_tree, tvb, offset, FIELD_CATEGORY_CODE); + offset += add_fixed_field (action_tree, tvb, offset, FIELD_MESH_MGT_ACTION_PL_CODE); + offset += add_fixed_field (action_tree, tvb, offset, FIELD_CAP_INFO); + length = offset; + break; + + case MESH_PL_PEER_LINK_CONFIRM: + offset = 0; + offset += add_fixed_field (action_tree, tvb, offset, FIELD_CATEGORY_CODE); + offset += add_fixed_field (action_tree, tvb, offset, FIELD_MESH_MGT_ACTION_PL_CODE); + offset += add_fixed_field (action_tree, tvb, offset, FIELD_CAP_INFO); + offset += add_fixed_field (action_tree, tvb, offset, FIELD_STATUS_CODE); + offset += add_fixed_field (action_tree, tvb, offset, FIELD_ASSOC_ID); + length = offset; + break; + + case MESH_PL_PEER_LINK_CLOSE: + offset = 0; + offset += add_fixed_field (action_tree, tvb, offset, FIELD_CATEGORY_CODE); + offset += add_fixed_field (action_tree, tvb, offset, FIELD_MESH_MGT_ACTION_PL_CODE); + offset += add_fixed_field (action_tree, tvb, offset, FIELD_REASON_CODE); + length = offset; /* Size of fixed fields */ + break; + + default: + offset = 0; + offset += add_fixed_field (action_tree, tvb, offset, FIELD_CATEGORY_CODE); + offset += add_fixed_field (action_tree, tvb, offset, FIELD_MESH_MGT_ACTION_PL_CODE); + length = offset; /* Size of fixed fields */ + break; + } + break; + + case CAT_MESH_PATH_SELECTION: + switch (tvb_get_guint8(tvb, 1)) + { + guint offset; + /* defined values */ + case MESH_PS_PATH_REQUEST: + offset = 0; + offset += add_fixed_field (action_tree, tvb, offset, FIELD_CATEGORY_CODE); + offset += add_fixed_field (action_tree, tvb, offset, FIELD_MESH_MGT_ACTION_PS_CODE); + length = offset; + break; + + case MESH_PS_PATH_REPLY: + offset = 0; + offset += add_fixed_field (action_tree, tvb, offset, FIELD_CATEGORY_CODE); + offset += add_fixed_field (action_tree, tvb, offset, FIELD_MESH_MGT_ACTION_PS_CODE); + length = offset; + break; + + case MESH_PS_PATH_ERROR: + offset = 0; + offset += add_fixed_field (action_tree, tvb, offset, FIELD_CATEGORY_CODE); + offset += add_fixed_field (action_tree, tvb, offset, FIELD_MESH_MGT_ACTION_PS_CODE); + length = offset; + break; + + case MESH_PS_ROOT_ANNOUNCEMENT: + offset = 0; + offset += add_fixed_field (action_tree, tvb, 0, FIELD_CATEGORY_CODE); + offset += add_fixed_field (action_tree, tvb, 1, FIELD_MESH_MGT_ACTION_PS_CODE); + length = offset; + break; + + /* undefined values */ + default: + offset = 0; + offset += add_fixed_field (action_tree, tvb, 0, FIELD_CATEGORY_CODE); + offset += add_fixed_field (action_tree, tvb, 1, FIELD_MESH_MGT_ACTION_PS_CODE); + length = offset; + break; + } + break; case CAT_MGMT_NOTIFICATION: /* Management notification frame */ { @@ -4044,7 +4305,7 @@ { TAG_TS_DELAY, "TS Delay"}, { TAG_TCLAS_PROCESS, "TCLAS Processing"}, { TAG_HT_CAPABILITY, "HT Capabilities (802.11n D1.10)"}, - { TAG_NEIGHBOR_REPORT, "Neighbor Report"}, +// { TAG_NEIGHBOR_REPORT, "Neighbor Report"}, { TAG_HT_INFO, "HT Information (802.11n D1.10)"}, { TAG_SECONDARY_CHANNEL_OFFSET, "Secondary Channel Offset (802.11n D1.10)"}, { TAG_QOS_CAPABILITY, "QoS Capability"}, @@ -4059,6 +4320,12 @@ { TAG_QUIET, "Quiet"}, { TAG_IBSS_DFS, "IBSS DFS"}, { TAG_EXTENDED_CAPABILITIES, "Extended Capabilities"}, + { TAG_MESH_ID, "Mesh ID"}, + { TAG_MESH_CONFIGURATION, "Mesh Configuration"}, + { TAG_MESH_PEER_LINK_MGMT, "Mesh Peer Link Management"}, + { TAG_MESH_PREQ, "Mesh Path Request"}, + { TAG_MESH_PREP, "Mesh Path Response"}, + { TAG_MESH_PERR, "Mesh Path Error"}, #if 0 /*Not yet assigned tag numbers by ANA */ { TAG_EXTENDED_CHANNEL_SWITCH_ANNOUNCEMENT, "Extended Channel Switch Announcement"}, { TAG_SUPPORTED_REGULATORY_CLASSES, "Supported Regulatory Classes"}, @@ -4672,6 +4939,117 @@ } /*** End: Power Capability Tag - Dustin Johnson ***/ + case TAG_MESH_PEER_LINK_MGMT: + { + offset += 2; + proto_tree_add_item (tree, hf_mesh_mgt_pl_subtype, tvb, offset, 1, TRUE); + offset += 1; + switch (tvb_get_guint8(tvb, 1)) + { /* IE subtype */ + case MESH_PL_PEER_LINK_OPEN: + proto_tree_add_item (tree, hf_mesh_mgt_pl_local_link_id, tvb, offset, 2, TRUE); + break; + + case MESH_PL_PEER_LINK_CONFIRM: + proto_tree_add_item (tree, hf_mesh_mgt_pl_local_link_id, tvb, offset, 2, TRUE); + proto_tree_add_item (tree, hf_mesh_mgt_pl_peer_link_id, tvb, offset + 2, 2, TRUE); + break; + + case MESH_PL_PEER_LINK_CLOSE: + proto_tree_add_item (tree, hf_mesh_mgt_pl_local_link_id, tvb, offset, 2, TRUE); + proto_tree_add_item (tree, hf_mesh_mgt_pl_peer_link_id, tvb, offset + 2, 2, TRUE); + proto_tree_add_item (tree, hf_mesh_mgt_pl_reason_code, tvb, offset + 4, 2, TRUE); + break; + + /* undefined values */ + default: + proto_tree_add_text (tree, tvb, offset, tag_len, "Unknown Peer Link Message Subtype"); + break; + } + break; + } + + case TAG_MESH_CONFIGURATION: + { + offset += 2; + proto_tree_add_item (tree, hf_mesh_config_version, tvb, offset, 1, TRUE); + proto_tree_add_item (tree, hf_mesh_config_path_sel_protocol, tvb, offset + 1, 4, TRUE); + proto_tree_add_item (tree, hf_mesh_config_path_sel_metric, tvb, offset + 5, 4, TRUE); + proto_tree_add_item (tree, hf_mesh_config_congestion_control, tvb, offset + 9, 4, TRUE); + proto_tree_add_item (tree, hf_mesh_config_channel_prec, tvb, offset + 13, 4, TRUE); + proto_tree_add_item (tree, hf_mesh_config_capability, tvb, offset + 17, 2, TRUE); + break; + } + + case TAG_MESH_ID: + { + guint8 *id; + offset += 2; + + id = tvb_get_ephemeral_string(tvb, offset, tag_len); + proto_tree_add_string (tree, tag_interpretation, tvb, offset, tag_len, (char *) id); + if (check_col (pinfo->cinfo, COL_INFO)) { + if (tag_len > 0) { + col_append_fstr(pinfo->cinfo, COL_INFO, ", MESHID=\"%s\"", + format_text(id, tag_len)); + } + } + break; + } + + case TAG_MESH_PREQ: + { + guint8 flags; + proto_item *item; + proto_tree *subtree; + + offset += 2; + proto_tree_add_item (tree, ff_mesh_mgt_flags, tvb, offset, 1, TRUE); + proto_tree_add_item (tree, ff_mesh_mgt_hopcount, tvb, offset + 1, 1, TRUE); + proto_tree_add_item (tree, ff_mesh_mgt_ttl, tvb, offset + 2, 1, TRUE); + proto_tree_add_item (tree, ff_mesh_mgt_rreqid, tvb, offset + 3, 4, TRUE); + proto_tree_add_item (tree, ff_mesh_mgt_sa, tvb, offset + 7, 6, FALSE); + proto_tree_add_item (tree, ff_mesh_mgt_ssn, tvb, offset + 13, 4, TRUE); + /* TODO: display proxied address if present */ + proto_tree_add_item (tree, ff_mesh_mgt_lifetime, tvb, offset + 17, 4, TRUE); + proto_tree_add_item (tree, ff_mesh_mgt_metric, tvb, offset + 21, 4, TRUE); + proto_tree_add_item (tree, ff_mesh_mgt_dstcount, tvb, offset + 25, 1, TRUE); + flags = tvb_get_letohs (tvb, offset + 26); + item = proto_tree_add_item (tree, ff_mesh_mgt_dest_flags, tvb, offset + 26, 1, TRUE); + subtree = proto_item_add_subtree(item, ett_msh_dest_flags_tree); + proto_tree_add_boolean(subtree, ff_mesh_mgt_dest_do_flags, tvb, offset + 26, 1, flags); + proto_tree_add_boolean(subtree, ff_mesh_mgt_dest_rf_flags, tvb, offset + 26, 1, flags); + proto_tree_add_item (tree, ff_mesh_mgt_da, tvb, offset + 27, 6, FALSE); + proto_tree_add_item (tree, ff_mesh_mgt_dsn, tvb, offset + 33, 4, TRUE); + break; + } + + case TAG_MESH_PREP: + { + offset += 2; + proto_tree_add_item (tree, ff_mesh_mgt_flags, tvb, offset, 1, TRUE); + proto_tree_add_item (tree, ff_mesh_mgt_hopcount, tvb, offset + 1, 1, TRUE); + proto_tree_add_item (tree, ff_mesh_mgt_ttl, tvb, offset + 2, 1, TRUE); + proto_tree_add_item (tree, ff_mesh_mgt_da, tvb, offset + 3, 6, FALSE); + proto_tree_add_item (tree, ff_mesh_mgt_dsn, tvb, offset + 9, 4, TRUE); + /* TODO: display proxied address if present */ + proto_tree_add_item (tree, ff_mesh_mgt_lifetime, tvb, offset + 13, 4, TRUE); + proto_tree_add_item (tree, ff_mesh_mgt_metric, tvb, offset + 17, 4, TRUE); + proto_tree_add_item (tree, ff_mesh_mgt_sa, tvb, offset + 21, 6, FALSE); + proto_tree_add_item (tree, ff_mesh_mgt_ssn, tvb, offset + 27, 4, TRUE); + break; + } + + case TAG_MESH_PERR: + { + offset += 2; + proto_tree_add_item (tree, ff_mesh_mgt_flags, tvb, offset, 1, TRUE); + proto_tree_add_item (tree, ff_mesh_mgt_srccount, tvb, offset + 1, 1, FALSE); + proto_tree_add_item (tree, ff_mesh_mgt_sa, tvb, offset + 2, 6, FALSE); + proto_tree_add_item (tree, ff_mesh_mgt_ssn, tvb, offset + 8, 4, TRUE); + break; + } + /*** Begin: Supported Channels Tag - Dustin Johnson ***/ case TAG_SUPPORTED_CHANNELS: { @@ -5130,6 +5508,7 @@ } /*** End: Extended Capabilities Tag - Dustin Johnson ***/ /*** Begin: Neighbor Report Tag - Dustin Johnson ***/ +#if 0 case TAG_NEIGHBOR_REPORT: { #define SUB_TAG_TSF_INFO 0x01 @@ -5236,6 +5615,7 @@ } break; } +#endif /*** End: Neighbor Report Tag - Dustin Johnson ***/ #if 0 /*Not yet assigned tag numbers by ANA */ /*** Begin: Extended Channel Switch Announcement Tag - Dustin Johnson ***/ @@ -6492,6 +6872,58 @@ } } + if (tree && (FCF_ADDR_SELECTOR(fcf) == DATA_ADDR_T4)) + { + proto_item *msh_fields; + proto_tree *msh_tree; + + guint16 mshoff; + guint8 mesh_flags; + guint8 mesh_ttl; + guint32 mesh_seq_number; + guint8 mesh_hdr_len; + const guint8 *ptr; + + mshoff = ohdr_len; + ptr = tvb_get_ptr(tvb, mshoff, len); + mesh_hdr_len = find_mesh_header_length(ptr, 0, fcf); + mesh_flags = tvb_get_guint8(tvb, mshoff + 0); + mesh_ttl = tvb_get_guint8(tvb, mshoff + 1); + mesh_seq_number = 0xffffff & tvb_get_letohl(tvb, mshoff + 2); + + /* heuristic method to determine if this is a mesh frame */ + if (mesh_flags & ~MESH_FLAGS_ADDRESS_EXTENSION) { + g_warning("Invalid mesh flags: %x. Interpreting as WDS frame.\n", mesh_flags); + break; + } + + msh_fields = proto_tree_add_text(hdr_tree, tvb, mshoff, mesh_hdr_len, "Mesh Header"); + msh_tree = proto_item_add_subtree (msh_fields, ett_msh_parameters); + + proto_tree_add_boolean_format (msh_tree, hf_mesh_flags, + tvb, mshoff, 1, mesh_flags, "Address Extension %x", mesh_flags & MESH_FLAGS_ADDRESS_EXTENSION); + proto_tree_add_uint (msh_tree, hf_mesh_ttl, tvb, mshoff + 1, 1, mesh_ttl); + proto_tree_add_uint (msh_tree, hf_mesh_seq, tvb, mshoff + 2, 3, mesh_seq_number); + switch (mesh_hdr_len) { + case 24: + ptr = tvb_get_ptr (tvb, mshoff + 18, 6); + proto_tree_add_ether(msh_tree, hf_mesh_ae3, tvb, mshoff + 18, 6, ptr); + case 18: + ptr = tvb_get_ptr (tvb, mshoff + 12, 6); + proto_tree_add_ether(msh_tree, hf_mesh_ae2, tvb, mshoff + 12, 6, ptr); + case 12: + ptr = tvb_get_ptr (tvb, mshoff + 6, 6); + proto_tree_add_ether(msh_tree, hf_mesh_ae1, tvb, mshoff + 6, 6, ptr); + case 6: + break; + default: + g_error("Invalid mesh header length (%d)\n", mesh_hdr_len); + } + hdr_len += mesh_hdr_len; + len -= mesh_hdr_len; + reported_len -= mesh_hdr_len; + } + break; case CONTROL_FRAME: @@ -7543,8 +7975,8 @@ "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)"}, + {FLAG_TO_DS|FLAG_FROM_DS, "WDS (AP to AP) or Mesh (MP to MP) Frame " + "(To DS: 1 From DS: 1)"}, {0, NULL} }; @@ -7985,6 +8417,12 @@ {CAT_QOS, "Quality of Service (QoS)"}, {CAT_DLS, "Direct-Link Setup (DLS)"}, {CAT_BLOCK_ACK, "Block Ack"}, + {CAT_MESH_PEER_LINK, "Mesh Peer Link"}, + {CAT_MESH_LINK_METRIC, "Mesh Link Metric"}, + {CAT_MESH_PATH_SELECTION, "Mesh Path Selection"}, + {CAT_MESH_INTERWORKING, "Mesh Internetworking"}, + {CAT_MESH_RESOURCE_COORDINATION, "Mesh Resource Coordination"}, + {CAT_MESH_SECURITY_ARCHITECTURE, "Mesh Security Arch"}, {CAT_RADIO_MEASUREMENT, "Radio Measurement"}, {CAT_HT, "High Throughput"}, {CAT_MGMT_NOTIFICATION, "Management Notification"}, @@ -8015,6 +8453,52 @@ {0x00, NULL} }; + static const value_string mesh_mgt_action_ps_codes[] ={ + {MESH_PS_PATH_REQUEST, "Path Request"}, + {MESH_PS_PATH_REPLY, "Path Reply"}, + {MESH_PS_PATH_ERROR, "Path Error"}, + {MESH_PS_ROOT_ANNOUNCEMENT, "Root Announcement"}, + {0, NULL} + }; + + static const value_string mesh_mgt_action_pl_codes[] ={ + {MESH_PL_PEER_LINK_OPEN, "Peer Link Open"}, + {MESH_PL_PEER_LINK_CONFIRM, "Peer Link Confirm"}, + {MESH_PL_PEER_LINK_CLOSE, "Peer Link Close"}, + {0, NULL} + }; + + static const value_string mesh_mgt_pl_reason_codes[] = { + {MESH_LINK_CANCELLED, "Link Cancelled"}, + {MESH_MAX_NEIGHBORS, "Maximum Number of Peers Reached"}, + {MESH_CONFIG_POLICY_VIOLATION, "Policy Violation"}, + {MESH_CLOSE_RCVD, "Close Received"}, + {MESH_MAX_RETRIES, "Maximum Retries"}, + {MESH_CONFIRM_TIMEOUT, "Confirm Timeout"}, + {0x00, NULL} + }; + + static const value_string mesh_mgt_ie_codes[] ={ + /* TODO: incomplete */ + {MESH_MGMT_IE_CONFIGURATION, "Mesh Configuration"}, + {MESH_MGMT_IE_ID, "Mesh ID"}, + {MESH_MGMT_IE_PEER_LINK, "Peer Link Management"}, + {MESH_MGMT_IE_PREQ, "Path Request"}, + {MESH_MGMT_IE_PREP, "Path Response"}, + {MESH_MGMT_IE_PERR, "Path Error"}, + {0, NULL} + }; + + static const true_false_string mesh_dest_rf_flags ={ + "[RF = 1] Intermediate Nodes That Respond Will Also Forward", + "[RF = 0] Intermediate Nodes That Respond Will Not Forward" + }; + + static const true_false_string mesh_dest_do_flags ={ + "[DO = 1] Only Destination Will Respond", + "[DO = 0] Intermediate Nodes May Respond" + }; + static const value_string ack_policy[] = { {0x00, "Normal Ack"}, {0x01, "No Ack"}, @@ -8485,6 +8969,19 @@ {"Block Ack Request Type", "wlan.ba.type", FT_UINT8, BASE_HEX, VALS(&hf_block_ack_type_flags), 0, "Block Ack Request Type", HFILL }}, /*** End: Block Ack Request/Block Ack - Dustin Johnson***/ + + {&hf_mesh_flags, + {"Mesh Flags", "wlan.mesh.flags", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Mesh flags", HFILL }}, + + {&hf_mesh_seq, + {"Mesh Seq", "wlan.mesh.seq", FT_UINT32, BASE_DEC, NULL, 0, + "Mesh End-to-End sequence number", HFILL }}, + + {&hf_mesh_ttl, + {"Mesh TTL", "wlan.mesh.ttl", FT_UINT8, BASE_DEC, NULL, 0, + "Mesh TTL", HFILL }}, }; static hf_register_info hf_prism[] = { @@ -9536,7 +10033,7 @@ "Status of requested event", HFILL }}, {&ff_category_code, - {"Category code", "wlan_mgt.fixed.category_code", + {"Category code", "wlan_mgt.fixed.cat_code", FT_UINT16, BASE_DEC, VALS (&category_codes), 0, "Management action category", HFILL }}, @@ -9559,6 +10056,133 @@ FT_UINT16, BASE_HEX, VALS (&wme_status_codes), 0, "Management notification setup response status code", HFILL }}, + {&ff_mesh_mgt_action_ps_code, + {"Action code", "wlan_mgt.fixed.action_code", + FT_UINT16, BASE_HEX, VALS (&mesh_mgt_action_ps_codes), 0, + "Mesh Management Path Selection action code", HFILL }}, + + {&ff_mesh_mgt_action_pl_code, + {"Action code", "wlan_mgt.fixed.action_code", + FT_UINT16, BASE_HEX, VALS (&mesh_mgt_action_pl_codes), 0, + "Mesh Management Peer Link action code", HFILL }}, + + {&hf_mesh_mgt_pl_local_link_id, + {"Local Link ID", "wlan.pl.local_id", + FT_UINT16, BASE_HEX, NULL, 0, + "Mesh Management Local Link ID", HFILL }}, + + {&hf_mesh_mgt_pl_subtype, + {"Peer Link Subtype", "wlan.pl.subtype", + FT_UINT16, BASE_HEX, VALS (&mesh_mgt_action_pl_codes), 0, + "Mesh Management Peer Link Subtype", HFILL }}, + + {&hf_mesh_mgt_pl_reason_code, + {"Reason Code", "wlan.pl.reason_code", + FT_UINT16, BASE_HEX, VALS (&mesh_mgt_pl_reason_codes), 0, + "Mesh Management Reason Code", HFILL }}, + + {&hf_mesh_mgt_pl_peer_link_id, + {"Peer Link ID", "wlan.pl.peer_id", + FT_UINT16, BASE_HEX, NULL, 0, + "Mesh Management Peer Link ID", HFILL }}, + + {&hf_mesh_config_version, + {"Version", "wlan.mesh.config.version", + FT_UINT16, BASE_HEX, NULL, 0, + "Mesh Configuration Version", HFILL }}, + + {&hf_mesh_config_path_sel_protocol, + {"Path Selection Protocol", "wlan.mesh.config.ps_protocol", + FT_UINT16, BASE_HEX, NULL, 0, + "Mesh Configuration Path Selection Protocol", HFILL }}, + + {&hf_mesh_config_path_sel_metric, + {"Path Selection Metric", "wlan.mesh.config.ps_metric", + FT_UINT16, BASE_HEX, NULL, 0, + "Mesh Configuration Path Selection Metric", HFILL }}, + + {&hf_mesh_config_congestion_control, + {"Congestion Control", "wlan.mesh.config.cong_ctl", + FT_UINT16, BASE_HEX, NULL, 0, + "Mesh Configuration Congestion Control", HFILL }}, + + {&hf_mesh_config_channel_prec, + {"Channel Precedence", "wlan.mesh.config.chan_prec", + FT_UINT16, BASE_HEX, NULL, 0, + "Mesh Configuration Channel Precedence", HFILL }}, + + {&hf_mesh_config_capability, + {"Capability", "wlan.mesh.config.cap", + FT_UINT16, BASE_HEX, NULL, 0, + "Mesh Configuration Capability", HFILL }}, + + {&ff_mesh_mgt_ie_id, + {"Mesh Managment IE ID", "wlan.mesh_ie", + FT_UINT8, BASE_HEX, VALS (&mesh_mgt_ie_codes), 0, + "Information Element ID", HFILL }}, + + {&ff_mesh_mgt_ttl, + {"Message TTL", "wlan.mesh_ttl", + FT_UINT8, BASE_DEC, NULL, 0, "Message TTL", HFILL }}, + + {&ff_mesh_mgt_dstcount, + {"Destination Count", "wlan.preq.dstcnt", + FT_UINT8, BASE_DEC, NULL, 0, "Destination Count", HFILL }}, + + {&ff_mesh_mgt_hopcount, + {"Hop Count", "wlan.mesh.hopcount", + FT_UINT8, BASE_DEC, NULL, 0, "Hop Count", HFILL }}, + + {&ff_mesh_mgt_rreqid, + {"PREQ ID", "wlan.mesh.preqid", + FT_UINT32, BASE_DEC, NULL, 0, "PREQ ID", HFILL }}, + + {&ff_mesh_mgt_sa, + {"Source Address", "wlan.mesh.sa", + FT_ETHER, BASE_NONE, NULL, 0, "Source MAC address", HFILL }}, + + {&ff_mesh_mgt_ssn, + {"SSN", "wlan.mesh.ssn", + FT_UINT32, BASE_DEC, NULL, 0, "Source Sequence Number", HFILL }}, + + {&ff_mesh_mgt_metric, + {"Metric", "wlan.mesh.metric", + FT_UINT32, BASE_DEC, NULL, 0, "Route Metric", HFILL }}, + + {&ff_mesh_mgt_flags, + {"Flags", "wlan.mesh.mgt.flags", + FT_UINT8, BASE_HEX, NULL, 0, "Flags", HFILL }}, + + {&ff_mesh_mgt_dest_flags, + {"Destination Flags", "wlan.preq.dest_flags", + FT_UINT8, BASE_HEX, NULL, 0, "Destination Flags", HFILL }}, + + {&ff_mesh_mgt_dest_do_flags, + {"Destination Flags", "wlan.preq.dest_flags.do", + FT_BOOLEAN, 8, TFS (&mesh_dest_do_flags), 0x01, + "Dest Flags", HFILL }}, + + {&ff_mesh_mgt_dest_rf_flags, + {"Destination Flags", "wlan.preq.dest_flags.rf", + FT_BOOLEAN, 8, TFS (&mesh_dest_rf_flags), 0x02, + "Dest Flags", HFILL }}, + + {&ff_mesh_mgt_da, + {"Destination Address", "wlan.mesh.da", + FT_ETHER, BASE_NONE, NULL, 0, "Destination MAC address", HFILL }}, + + {&ff_mesh_mgt_dsn, + {"DSN", "wlan.mesh.dsn", + FT_UINT32, BASE_DEC, NULL, 0, "Destination Sequence Number", HFILL }}, + + {&ff_mesh_mgt_srccount, + {"Source Count", "wlan.mesh.srccount", + FT_UINT8, BASE_DEC, NULL, 0, "Source Count", HFILL }}, + + {&ff_mesh_mgt_lifetime, + {"Lifetime", "wlan.mesh.lifetime", + FT_UINT32, BASE_DEC, NULL, 0, "Route Lifetime", HFILL }}, + {&ff_qos_action_code, {"Action code", "wlan_mgt.fixed.action_code", FT_UINT16, BASE_HEX, VALS (&qos_action_codes), 0, @@ -10842,6 +11466,8 @@ &ett_qos_parameters, &ett_qos_ps_buf_state, &ett_wep_parameters, + &ett_msh_parameters, + &ett_msh_dest_flags_tree, &ett_cap_tree, &ett_rsn_cap_tree, &ett_ht_cap_tree,