How to determine whether a 802.11 raw packet has F

2019-09-10 08:33发布

I have a NDIS 6 filter driver working on Windows Vista and later systems.

I have bound it below NativeWiFi Filter so I can see 802.11 packets instead of fake Ethernet packets.

And I have set the NDIS_PACKET_TYPE_802_11_RAW_DATA and NDIS_PACKET_TYPE_802_11_RAW_MGMT in the packet filter based on: https://msdn.microsoft.com/en-us/library/windows/hardware/ff554833(v=vs.85).aspx, so I can receive the Raw 802.11 Packets indications from the miniport.

Then I switched my wireless adapter to Monitor Mode.

By now my filter driver can receive all the 802.11 control and management packets.

My question is how to determine whether a 802.11 raw packet has FCS (frame check sequence, 4bytes) in my driver?

I'm asking this because i'm adding Radiotap header (http://radiotap.org/) to the packets and radiotap has a field called Flags that specified whether the 802.11 packet has a FCS or not.

My experiment with my laptop with a wireless adapter Qualcomm Atheros AR9485WB-EG Wireless Network Adapter shows that Beacon and Reassociation Response packets have FCS and all other 802.11 packets don't have one. And the wrong Flags in the radiotap header will cause Wireshark to show Malformed Packet for those packets. This is why I need to determine the availability of FCS in my driver.

My code is like below, and I want to know how to write the if condition.

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

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

Any methods? Thanks!

1条回答
Root(大扎)
2楼-- · 2019-09-10 09:14

My experiment with my laptop with a wireless adapter Qualcomm Atheros AR9485WB-EG Wireless Network Adapter shows that Beacon and Reassociation Response packets have FCS and all other 802.11 packets don't have one.

No, it doesn't. When I looked at the same capture, and forced the "FCS at end" flag on, I found that a LOT of frames other than those frames had an FCS that Wireshark reported as valid. Do NOT assume that, just because a frame didn't show a "Malformed frame" error, it didn't have an FCS; the "Malformed frame" errors are due to Wireshark thinking the FCS is frame data, and trying to dissect items larger than the 4 bytes of the FCS. For data frames, the 802.11 dissector doesn't dissect the payload, and if the payload has a length field of its own, as IPv4 and IPv6 frames do, that length will be used, and the FCS will be treated as extra data after the payload and not cause a "Malformed frame" error.

What you should try is to check whether uReceiveFlags has DOT11_RECV_FLAG_RAW_PACKET set and, if so, assume the frame has an FCS, otherwise assume it doesn't.

And remember that, in monitor mode, frames that couldn't be completely received may still be provided to the host, so some "Malformed frame" errors in monitor mode may be due to, for example, the frame being cut short by the radio, so don't assume that a "Malformed frame" error means that the frame shouldn't have had the "FCS at end" flag set.

查看更多
登录 后发表回答