Wireshark mailing list archives

Re: [tcpdump-workers] What's the difference between NdisMediumBare80211 (DLT_IEEE802_11) and NdisMediumRadio80211 (DLT_IEEE802_11_RADIO)


From: Yang Luo <hsluoyb () gmail com>
Date: Sat, 9 Apr 2016 12:25:25 +0800

Hi Guy,

On Thu, Apr 7, 2016 at 9:37 AM, Guy Harris <guy () alum mit edu> wrote:

On Apr 6, 2016, at 5:41 PM, Yang Luo <hsluoyb () gmail com> wrote:

I wonder why this mail went to my spam.. I don't know anything about
radiotap header so I'm afraid i'm not supplying it.

It's a way to provide "radio metadata" for packets; see

        http://www.radiotap.org

for a description of it.

If you were to implement that in the future, you'd get the "Media-Specific
OOB Data for Received 802.11 Packets":


https://msdn.microsoft.com/en-us/library/windows/hardware/ff559169(v=vs.85).aspx

in a DOT11_EXTSTA_RECV_CONTEXT structure:


https://msdn.microsoft.com/en-us/library/windows/hardware/ff548626(v=vs.85).aspx

when you receive a packet.  Then you'd provide a link-layer header type of
DLT_IEEE802_11_RADIO, and synthesize a radiotap header.  When you open the
device, you'd have to fetch the device's data rate mapping table with the
OID_DOT11_DATA_RATE_MAPPING_TABLE OID:


https://msdn.microsoft.com/en-us/library/windows/hardware/ff569139(v=vs.85).aspx


https://msdn.microsoft.com/en-us/library/windows/hardware/ff547679(v=vs.85).aspx

and associate that with the private data for the pcap_t.

Then, for each received packet:

   if DOT11_RECV_FLAG_RAW_PACKET_TIMESTAMP is set in uReceiveFlags,
provide a radiotap TSFT field with the value from the ullTimestamp field of
the structure;

   provide a radiotap Flags field with 0x10 set if the frame includes the
FCS (you'll probably have to experiment a bit to see whether you get the
FCS or not - the answer might differ for data and management frames, based
on Network Monitor's behavior) and with 0x40 set if
DOT11_RECV_FLAG_RAW_PACKET_FCS_FAILURE is set in uReceiveFlags;


FCS is the suffix 4 bytes of a packet. Actually I didn't see those 4 bytes
in the packets (only 802.11 data for now) using Wireshark (captured by
npcap-nmap-0.06-r13-wifi.exe). So I'm afraid  it's the case that I can't
get FCS for data frames? As I didn't start the work of capturing management
frames yet. it will not be considered for now.

So I think I will just leave FLags field with 0x00 then.



   provide a radiotap Rate field whose value is the result of looking up
the ucDataRate field's value in the data rate mapping table and returning
the usDataRateValue value from that table - if it's not found, don't
provide the Rate field;

   provide a radiotap Channel field where the frequency value is the
uChCenterFrequency field of the structure and the flags are derived from
the uChCenterFrequency and uPhyId fields of the structure - assuming that
the uPhyId value is one of the ones from


https://msdn.microsoft.com/en-us/library/windows/hardware/ff548741(v=vs.85).aspx

   then the mapping would be:

        dot11_phy_type_fhss - set 0x0800 in the flags (11 legacy FHSS);

        dot11_phy_type_ofdm - set 0x0040 in the flags (11a);

        dot11_phy_type_hrdsss - set 0x0020 in the flags (11b);

        dot11_phy_type_erp - set 0x0040 in the flags (11g, unknown whether
it's pure or not);

   and, unless it's dot11_phy_type_irbaseband, set 0x0100 if the frequency
is in the 5 GHz range or set 0x0080 if it's in the 2.4 GHz range;


How to determine if uChCenterFrequency is 5GHz or 2.4GHz? What about the
following conditions?
if (pwInfo->uChCenterFrequency == 5000)
and
if (pwInfo->uChCenterFrequency == 2400)


Also I found the frequency of Radiotap "Channel" field is 16bit, but
uChCenterFrequency is a ULONG type (32bit). They are both MHz unit. I hope
a direct assignment is OK?



   provide a radiotap Antenna signal field whose value is the value of the
lRSSI field in the structure;


Again a size truncating issue. I found radiotap Antenna signal field is
8bit. And pwInfo->lRSSI is a LONG type (32bit). is a direct assignment OK?



   if the phy is dot11_phy_type_ht, provide a radiotap MCS field where the
known field is 0 and the other fields are also zeroed out (i.e., it's 11n,
but we don't know anything else about it);

   if the phy is dot11_phy_type_vht, provide a radiotap VHT field where
the known field is 0 and the other fields are also zeroed out (i.e., it's
11ac, but we don't know anything else about it).


So simply speaking, if phy is dot11_phy_type_ht, then MCS field (3 bytes)
all zero.
If phy is dot11_phy_type_vht, then VHT field (12 bytes) all zero.


Also, another question is, how large buffer is needed at most for the whole
Radiotap header (including Radiotap data)?
Like the below code, I allocated a buffer of 256 bytes. I don't know if
this is enough big. Or if there are any better handle ways?


For now, all the code about the Radiotap is here:
---------------------------------------------------------------

PDOT11_EXTSTA_RECV_CONTEXT  pwInfo;
IEEE80211_RADIOTAP_HEADER RadiotapHeader = { 0 };
CHAR buf[256];
int cur = 0;
pwInfo = NET_BUFFER_LIST_INFO(pNetBufList, MediaSpecificInformation);

// [Radiotap] "TSFT" field.
if ((pwInfo->uReceiveFlags & DOT11_RECV_FLAG_RAW_PACKET_TIMESTAMP) ==
DOT11_RECV_FLAG_RAW_PACKET_TIMESTAMP)
{
RadiotapHeader.it_present |= IEEE80211_RADIOTAP_TSFT;
RtlCopyMemory(buf + cur, &pwInfo->ullTimestamp, sizeof(INT64) /
sizeof(UCHAR));
cur += sizeof(INT64) / sizeof(UCHAR);
}

// [Radiotap] "Flags" field.
if (TRUE) // The packet doesn't have FCS. We always have no FCS for all
packets currently.
{
RadiotapHeader.it_present |= IEEE80211_RADIOTAP_FLAGS;
*((UCHAR*)buf + cur) = 0x0; // 0x0: none
cur += sizeof(UCHAR) / sizeof(UCHAR);
}
else // The packet has FCS.
{
RadiotapHeader.it_present |= IEEE80211_RADIOTAP_FLAGS;
*((UCHAR*)buf + cur) = 0x10; // 0x10: frame includes FCS

// FCS check fails.
if ((pwInfo->uReceiveFlags & DOT11_RECV_FLAG_RAW_PACKET_FCS_FAILURE) ==
DOT11_RECV_FLAG_RAW_PACKET_FCS_FAILURE)
{
*((UCHAR*)buf + cur) |= 0x40; // 0x40: frame failed FCS check
}

cur += sizeof(UCHAR) / sizeof(UCHAR);
}

// [Radiotap] "Rate" field.
// Not finished.
if (TRUE) // looking up the ucDataRate field's value in the data rate
mapping table
{
RadiotapHeader.it_present |= IEEE80211_RADIOTAP_RATE;
//RtlCopyMemory(buf + cur, &pwInfo->ullTimestamp, sizeof(INT64) /
sizeof(UCHAR));
//cur += sizeof(INT64) / sizeof(UCHAR);
}

// [Radiotap] "Channel" field.
if (TRUE)
{
USHORT flags = 0;
if (pwInfo->uPhyId == dot11_phy_type_fhss)
{
flags = IEEE80211_CHAN_GFSK; // 0x0800
}
else if (pwInfo->uPhyId == dot11_phy_type_ofdm)
{
flags = IEEE80211_CHAN_OFDM; // 0x0040
}
else if (pwInfo->uPhyId == dot11_phy_type_hrdsss)
{
flags = IEEE80211_CHAN_CCK; // 0x0020
}
else if (pwInfo->uPhyId == dot11_phy_type_erp)
{
flags = IEEE80211_CHAN_OFDM; // 0x0040
}
else if (pwInfo->uPhyId != dot11_phy_type_irbaseband)
{
if (pwInfo->uChCenterFrequency == 5000) // 5 GHz
{
flags = IEEE80211_CHAN_5GHZ; // 0x0100
}
else if (pwInfo->uChCenterFrequency == 2400) // 2.4 GHz
{
flags = IEEE80211_CHAN_2GHZ; // 0x0080
}
else
{
// should be a else here?
}
}

RadiotapHeader.it_present |= IEEE80211_RADIOTAP_CHANNEL;
*((USHORT*)buf + cur) = flags;
cur += sizeof(USHORT) / sizeof(UCHAR);
*((USHORT*)buf + cur) = pwInfo->uChCenterFrequency;
cur += sizeof(USHORT) / sizeof(UCHAR);
}

// [Radiotap] "Antenna signal" field.
if (TRUE)
{
RadiotapHeader.it_present |= IEEE80211_RADIOTAP_DBM_ANTSIGNAL;
RtlCopyMemory(buf + cur, &pwInfo->lRSSI, sizeof(UCHAR) / sizeof(UCHAR));
cur += sizeof(UCHAR) / sizeof(UCHAR);
}

// [Radiotap] "MCS" field.
if (pwInfo->uPhyId == dot11_phy_type_ht)
{
RadiotapHeader.it_present |= IEEE80211_RADIOTAP_MCS;
RtlZeroMemory(buf + cur, 3 * sizeof(UCHAR) / sizeof(UCHAR));
cur += 3 * sizeof(UCHAR) / sizeof(UCHAR);
}
// [Radiotap] "VHT" field.
else if (pwInfo->uPhyId == dot11_phy_type_vht)
{
RadiotapHeader.it_present |= IEEE80211_RADIOTAP_VHT;
RtlZeroMemory(buf + cur, 12 * sizeof(UCHAR) / sizeof(UCHAR));
cur += 12 * sizeof(UCHAR) / sizeof(UCHAR);
}

---------------------------------------------------------------

Cheers,
Yang



And I have confirmed that my captured packets are parsed well using
NdisMediumBare80211. In Wireshark it shows "IEEE 802.11 Data".

That means that you're just supplying packets that begin with an 802.11
header, with no form of radio information preceding it, so...

So I think I will just use this value.

...that is exactly what you should be doing.
___________________________________________________________________________
Sent via:    Wireshark-dev mailing list <wireshark-dev () wireshark org>
Archives:    https://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
             mailto:wireshark-dev-request () wireshark org?subject=unsubscribe

Current thread: