On Apr 8, 2016, at 9:25 PM, Yang Luo <[email protected]> wrote:

> On Thu, Apr 7, 2016 at 9:37 AM, Guy Harris <[email protected]> wrote:
> 
>>    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.

Yes, that's the right thing to do.

>>    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)

No, it's a range, not a value.  A test we use in Wireshark for CommView files 
is to check whether the center frequency is > 2484, so do

        if (pwInfo->uChCenterFrequency > 2484)
                5 GHz band;
        else
                2.4 GHz band;

> 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?

It's OK for now, but 2^16 MHz is 65 GHz, and there's apparently some discussion 
of 60 GHz wireless communication, so, while a 16-bit frequency field might not 
become a problem in the short term, it might become a problem later.  That'd 
require a change to radiotap.

If the frequency is > 65535 MHz, I'd leave the channel field out.

>>    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?

100 dBm is 10,000,000,000 milliwatts, at least if I'm interpreting

        https://en.wikipedia.org/wiki/Decibel

correctly, so that's 10,000,000 watts.

I *really* would not want to be anywhere near a Wi-Fi station transmitting at 
that power level. :-)

-100 dBm is 1/10,000,000,000 milliwatts, which is .1 picowatt; I'm not a radio 
expert, but I suspect there might not be any radios capable of detecting that 
low a power level except in specialized physics or radio astronomy cases.  
(It's 1/10th the power consumption of an average human cell:

        
https://en.wikipedia.org/wiki/Orders_of_magnitude_(power)#Picowatt_.2810.E2.88.9212_watt.29

so it's not much power.)

So I don't think you have to worry about a dBm power level that doesn't fit in 
8 bits.  You should leave out the antenna signal field if the value doesn't fit 
in 8 bits.

>>    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.

Yes.  It would nice if Microsoft were to specify, and vendors' drivers were to 
supply, more information, but at least supplying "empty" MCS and VHT fields 
will let the program processing the capture know that the packet was an HT or 
VHT packet.

> 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?

The beginning of the radiotap header is 8 bytes.

Then the fields you'd supply, if *all* the fields were present, would be:

        TSFT: 8 bytes

        Flags: 1 byte

        Rate: 1 byte

        Channel: 4 bytes

        Antenna signal: 1 byte, plus 1 byte of alignment *if* this is a VHT 
frame

        MCS or VHT: MCS = 12 bytes, VHT = 12 bytes

so the largest radiotap header you'd supply would be 8+8+1+1+4+2+12 = 36 bytes.

> 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;

You should actually initialize it to 8, to leave room for the 
IEEE80211_RADIOTAP_HEADER at the beginning.

It's probably easiest to construct the IEEE80211_RADIOTAP_HEADER while you're 
filling in the rest of the radiotap header, and then copy it in place at the 
end.

>                       // [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);
>                       }

You're providing a Flags field in all cases, so I'd just do

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

>                               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);
>                       }

The frequency comes before the channel, so that should be

                                *((USHORT*)buf + cur) = 
pwInfo->uChCenterFrequency;
                                cur += sizeof(USHORT) / sizeof(UCHAR);
                                *((USHORT*)buf + cur) = flags;
                                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);
>                       }

You'd need to do

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

before putting the VHT field into the packet, because the VHT field has to be 
aligned on a 2-byte boundary, and the antenna field is on a 2-byte boundary but 
is only 1 byte long.  (The MCS field, however, doesn't have to be aligned on a 
2-byte boundary, so you *don't* need to pad anything for HT frames.)

After all this is done, you'd need to do

        // Set the total length of the radiotap header
        RadiotapHeader.it_len = cur;

and then do

        RtlCopyMemory(buf, &RadiotapHeader, sizeof RadiotapHeader);

to put the IEEE80211_RADIOTAP_HEADER at the beginning of the radiotap header.

___________________________________________________________________________
Sent via:    Wireshark-dev mailing list <[email protected]>
Archives:    https://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
             mailto:[email protected]?subject=unsubscribe

Reply via email to