ieee80211-radiotap: Add support for headers to be bit-based as well as TLVs.
Johannes Berg pointed out this was the intent of the TLV definitions and supplied some code for implementing that. I simply made it work.
This commit is contained in:
parent
eabf92859e
commit
e61fe552d0
|
@ -221,6 +221,11 @@ struct ieee80211_radiotap_tlv {
|
||||||
guint8 data[];
|
guint8 data[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* TLVs we understand. */
|
||||||
|
#define IEEE80211_RADIOTAP_TLV_S1G 32
|
||||||
|
#define IEEE80211_RADIOTAP_TLV_U_SIG 33
|
||||||
|
#define IEEE80211_RADIOTAP_TLV_EHT 34
|
||||||
|
|
||||||
/* Channel flags. */
|
/* Channel flags. */
|
||||||
/* 0x00000008 undefined (reserved?) */
|
/* 0x00000008 undefined (reserved?) */
|
||||||
#define IEEE80211_CHAN_700MHZ 0x00000001 /* S1G 700 MHz spectrum channel. */
|
#define IEEE80211_CHAN_700MHZ 0x00000001 /* S1G 700 MHz spectrum channel. */
|
||||||
|
|
|
@ -1038,6 +1038,19 @@ capture_radiotap(const guchar * pd, int offset, int len, capture_packet_info_t *
|
||||||
return call_capture_dissector(ieee80211_cap_handle, pd, offset + it_len, len, cpinfo, pseudo_header);
|
return call_capture_dissector(ieee80211_cap_handle, pd, offset + it_len, len, cpinfo, pseudo_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_tlv_items(proto_tree *tree, tvbuff_t *tvb, int offset)
|
||||||
|
{
|
||||||
|
offset -= 4;
|
||||||
|
|
||||||
|
proto_tree_add_item(tree, hf_radiotap_tlv_type, tvb,
|
||||||
|
offset, 2, ENC_LITTLE_ENDIAN);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
proto_tree_add_item(tree, hf_radiotap_tlv_datalen, tvb,
|
||||||
|
offset, 2, ENC_LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
static const true_false_string tfs_known_unknown = {
|
static const true_false_string tfs_known_unknown = {
|
||||||
"Known",
|
"Known",
|
||||||
"Unknown"
|
"Unknown"
|
||||||
|
@ -1172,7 +1185,7 @@ static const value_string he_midamble_periodicity_vals[] = {
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dissect_radiotap_he_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
dissect_radiotap_he_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
||||||
int offset, struct ieee_802_11ax *info_11ax)
|
int offset, struct ieee_802_11ax *info_11ax, gboolean is_tlv)
|
||||||
{
|
{
|
||||||
guint16 ppdu_format = tvb_get_letohs(tvb, offset) &
|
guint16 ppdu_format = tvb_get_letohs(tvb, offset) &
|
||||||
IEEE80211_RADIOTAP_HE_PPDU_FORMAT_MASK;
|
IEEE80211_RADIOTAP_HE_PPDU_FORMAT_MASK;
|
||||||
|
@ -1304,6 +1317,10 @@ dissect_radiotap_he_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
|
||||||
he_info_tree = proto_tree_add_subtree(tree, tvb, offset, 12,
|
he_info_tree = proto_tree_add_subtree(tree, tvb, offset, 12,
|
||||||
ett_radiotap_he_info, NULL, "HE information");
|
ett_radiotap_he_info, NULL, "HE information");
|
||||||
|
|
||||||
|
if (is_tlv) {
|
||||||
|
add_tlv_items(he_info_tree, tvb, offset);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add the bitmasks for each of D1 through D6 */
|
/* Add the bitmasks for each of D1 through D6 */
|
||||||
proto_tree_add_bitmask(he_info_tree, tvb, offset,
|
proto_tree_add_bitmask(he_info_tree, tvb, offset,
|
||||||
hf_radiotap_he_info_data_1, ett_radiotap_he_info_data_1,
|
hf_radiotap_he_info_data_1, ett_radiotap_he_info_data_1,
|
||||||
|
@ -1463,8 +1480,8 @@ he_sig_b_symbols_custom(gchar *result, guint32 value)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dissect_radiotap_he_mu_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
dissect_radiotap_he_mu_info(tvbuff_t *tvb, packet_info *pinfo _U_,
|
||||||
int offset)
|
proto_tree *tree, int offset, gboolean is_tlv)
|
||||||
{
|
{
|
||||||
proto_tree *he_mu_info_tree = NULL;
|
proto_tree *he_mu_info_tree = NULL;
|
||||||
guint16 flags1 = tvb_get_letohs(tvb, offset);
|
guint16 flags1 = tvb_get_letohs(tvb, offset);
|
||||||
|
@ -1669,6 +1686,10 @@ dissect_radiotap_he_mu_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
|
||||||
he_mu_info_tree = proto_tree_add_subtree(tree, tvb, offset, 12,
|
he_mu_info_tree = proto_tree_add_subtree(tree, tvb, offset, 12,
|
||||||
ett_radiotap_he_mu_info, NULL, "HE-MU information");
|
ett_radiotap_he_mu_info, NULL, "HE-MU information");
|
||||||
|
|
||||||
|
if (is_tlv) {
|
||||||
|
add_tlv_items(he_mu_info_tree, tvb, offset);
|
||||||
|
}
|
||||||
|
|
||||||
proto_tree_add_bitmask(he_mu_info_tree, tvb, offset,
|
proto_tree_add_bitmask(he_mu_info_tree, tvb, offset,
|
||||||
hf_radiotap_he_mu_info_flags_1,
|
hf_radiotap_he_mu_info_flags_1,
|
||||||
ett_radiotap_he_mu_info_flags_1,
|
ett_radiotap_he_mu_info_flags_1,
|
||||||
|
@ -2228,61 +2249,30 @@ static int * const s1g_data2_headers[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dissect_radiotap_tlv(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
dissect_radiotap_s1g(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
||||||
int offset, struct ieee_802_11_phdr *phdr _U_)
|
int offset, struct ieee_802_11_phdr *phdr, gboolean is_tlv _U_)
|
||||||
{
|
{
|
||||||
guint16 type = tvb_get_letohs(tvb, offset);
|
|
||||||
guint16 length = tvb_get_letohs(tvb, offset + 2);
|
|
||||||
proto_tree *unknown_tlv = NULL;
|
|
||||||
proto_tree *s1g_tree = NULL;
|
proto_tree *s1g_tree = NULL;
|
||||||
|
|
||||||
/* Insert code here to call the dissector for your TLV type */
|
phdr->phy = PHDR_802_11_PHY_11AH;
|
||||||
switch (type) {
|
s1g_tree = proto_tree_add_subtree(tree, tvb, offset, 6,
|
||||||
case IEEE80211_RADIOTAP_TLV_S1G:
|
ett_radiotap_s1g, NULL, "S1G");
|
||||||
phdr->phy = PHDR_802_11_PHY_11AH;
|
|
||||||
s1g_tree = proto_tree_add_subtree(tree, tvb, offset, 6,
|
|
||||||
ett_radiotap_s1g, NULL, "S1G");
|
|
||||||
|
|
||||||
proto_tree_add_item(s1g_tree, hf_radiotap_tlv_type, tvb,
|
add_tlv_items(s1g_tree, tvb, offset);
|
||||||
offset, 2, ENC_LITTLE_ENDIAN);
|
|
||||||
offset += 2;
|
|
||||||
|
|
||||||
proto_tree_add_item(s1g_tree, hf_radiotap_tlv_datalen, tvb,
|
proto_tree_add_bitmask(s1g_tree, tvb, offset,
|
||||||
offset, 2, ENC_LITTLE_ENDIAN);
|
hf_radiotap_s1g_known, ett_radiotap_s1g_known,
|
||||||
offset += 2;
|
s1g_known_headers, ENC_LITTLE_ENDIAN);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
proto_tree_add_bitmask(s1g_tree, tvb, offset,
|
proto_tree_add_bitmask(s1g_tree, tvb, offset,
|
||||||
hf_radiotap_s1g_known, ett_radiotap_s1g_known,
|
hf_radiotap_s1g_data_1, ett_radiotap_s1g_data_1,
|
||||||
s1g_known_headers, ENC_LITTLE_ENDIAN);
|
s1g_data1_headers, ENC_LITTLE_ENDIAN);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
proto_tree_add_bitmask(s1g_tree, tvb, offset,
|
proto_tree_add_bitmask(s1g_tree, tvb, offset,
|
||||||
hf_radiotap_s1g_data_1, ett_radiotap_s1g_data_1,
|
hf_radiotap_s1g_data_2, ett_radiotap_s1g_data_2,
|
||||||
s1g_data1_headers, ENC_LITTLE_ENDIAN);
|
s1g_data2_headers, ENC_LITTLE_ENDIAN);
|
||||||
offset += 2;
|
|
||||||
|
|
||||||
proto_tree_add_bitmask(s1g_tree, tvb, offset,
|
|
||||||
hf_radiotap_s1g_data_2, ett_radiotap_s1g_data_2,
|
|
||||||
s1g_data2_headers, ENC_LITTLE_ENDIAN);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
unknown_tlv = proto_tree_add_subtree(tree, tvb, offset,
|
|
||||||
length + 4,
|
|
||||||
ett_radiotap_unknown_tlv,
|
|
||||||
NULL, "Unknown TLV");
|
|
||||||
proto_tree_add_item(unknown_tlv, hf_radiotap_tlv_type, tvb,
|
|
||||||
offset, 2, ENC_LITTLE_ENDIAN);
|
|
||||||
offset += 2;
|
|
||||||
|
|
||||||
proto_tree_add_item(unknown_tlv, hf_radiotap_tlv_datalen, tvb,
|
|
||||||
offset, 2, ENC_LITTLE_ENDIAN);
|
|
||||||
offset += 2;
|
|
||||||
|
|
||||||
proto_tree_add_item(unknown_tlv, hf_radiotap_unknown_tlv_data,
|
|
||||||
tvb, offset, length, ENC_NA);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -3049,18 +3039,8 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* u
|
||||||
|
|
||||||
offset = (int)((guchar *) iter.this_arg - (guchar *) data);
|
offset = (int)((guchar *) iter.this_arg - (guchar *) data);
|
||||||
|
|
||||||
if (iter.tlv_mode) {
|
|
||||||
|
|
||||||
offset -= sizeof(struct ieee80211_radiotap_tlv);
|
|
||||||
|
|
||||||
dissect_radiotap_tlv(tvb, pinfo, radiotap_tree, offset,
|
|
||||||
&phdr);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iter.this_arg_index == IEEE80211_RADIOTAP_VENDOR_NAMESPACE
|
if (iter.this_arg_index == IEEE80211_RADIOTAP_VENDOR_NAMESPACE
|
||||||
&& tree) {
|
&& tree && !iter.tlv_mode) {
|
||||||
proto_tree *ven_tree;
|
proto_tree *ven_tree;
|
||||||
proto_item *vt;
|
proto_item *vt;
|
||||||
const gchar *manuf_name;
|
const gchar *manuf_name;
|
||||||
|
@ -3645,10 +3625,13 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* u
|
||||||
* without this field.
|
* without this field.
|
||||||
*/
|
*/
|
||||||
phdr.phy = PHDR_802_11_PHY_11AX;
|
phdr.phy = PHDR_802_11_PHY_11AX;
|
||||||
dissect_radiotap_he_info(tvb, pinfo, radiotap_tree, offset, &phdr.phy_info.info_11ax);
|
dissect_radiotap_he_info(tvb, pinfo, radiotap_tree,
|
||||||
|
offset, &phdr.phy_info.info_11ax,
|
||||||
|
iter.tlv_mode);
|
||||||
break;
|
break;
|
||||||
case IEEE80211_RADIOTAP_HE_MU:
|
case IEEE80211_RADIOTAP_HE_MU:
|
||||||
dissect_radiotap_he_mu_info(tvb, pinfo, item_tree, offset);
|
dissect_radiotap_he_mu_info(tvb, pinfo, item_tree,
|
||||||
|
offset, iter.tlv_mode);
|
||||||
break;
|
break;
|
||||||
case IEEE80211_RADIOTAP_0_LENGTH_PSDU:
|
case IEEE80211_RADIOTAP_0_LENGTH_PSDU:
|
||||||
dissect_radiotap_0_length_psdu(tvb, pinfo, item_tree, offset, &phdr);
|
dissect_radiotap_0_length_psdu(tvb, pinfo, item_tree, offset, &phdr);
|
||||||
|
@ -3660,9 +3643,38 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* u
|
||||||
case IEEE80211_RADIOTAP_TLVS:
|
case IEEE80211_RADIOTAP_TLVS:
|
||||||
/* used for padding */
|
/* used for padding */
|
||||||
break;
|
break;
|
||||||
|
case IEEE80211_RADIOTAP_TLV_S1G:
|
||||||
|
dissect_radiotap_s1g(tvb, pinfo, item_tree, offset,
|
||||||
|
&phdr, iter.tlv_mode);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
proto_tree_add_item(item_tree, hf_radiotap_unknown_tlv_data, tvb,
|
if (iter.tlv_mode) {
|
||||||
offset, iter.this_arg_size, ENC_NA);
|
proto_tree *unknown_tlv;
|
||||||
|
|
||||||
|
unknown_tlv = proto_tree_add_subtree(tree, tvb,
|
||||||
|
offset,
|
||||||
|
length + 4,
|
||||||
|
ett_radiotap_unknown_tlv,
|
||||||
|
NULL, "Unknown TLV");
|
||||||
|
proto_tree_add_item(unknown_tlv,
|
||||||
|
hf_radiotap_tlv_type, tvb,
|
||||||
|
offset, 2, ENC_LITTLE_ENDIAN);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
proto_tree_add_item(unknown_tlv,
|
||||||
|
hf_radiotap_tlv_datalen, tvb,
|
||||||
|
offset, 2, ENC_LITTLE_ENDIAN);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
proto_tree_add_item(unknown_tlv,
|
||||||
|
hf_radiotap_unknown_tlv_data,
|
||||||
|
tvb, offset, length, ENC_NA);
|
||||||
|
} else {
|
||||||
|
proto_tree_add_item(item_tree,
|
||||||
|
hf_radiotap_unknown_tlv_data,
|
||||||
|
tvb, offset,
|
||||||
|
iter.this_arg_size, ENC_NA);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -532,6 +532,7 @@ struct p2p_phdr {
|
||||||
#define PHDR_802_11_PHY_11AD 9 /* 802.11ad */
|
#define PHDR_802_11_PHY_11AD 9 /* 802.11ad */
|
||||||
#define PHDR_802_11_PHY_11AH 10 /* 802.11ah */
|
#define PHDR_802_11_PHY_11AH 10 /* 802.11ah */
|
||||||
#define PHDR_802_11_PHY_11AX 11 /* 802.11ax */
|
#define PHDR_802_11_PHY_11AX 11 /* 802.11ax */
|
||||||
|
#define PHDR_802_11_PHY_11BE 12 /* 802.11be - EHT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PHY-specific information.
|
* PHY-specific information.
|
||||||
|
|
Loading…
Reference in New Issue