首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pcap/监视器模式w/无线电抽头:数据包大小似乎永远很小?

pcap/监视器模式w/无线电抽头:数据包大小似乎永远很小?
EN

Stack Overflow用户
提问于 2021-02-13 01:15:49
回答 1查看 219关注 0票数 0

由于某种原因,我似乎一直从c/c++的pcap中得到10字节802.11的MAC头,我不知道为什么.。

一些介绍细节:

  • 是的,我在监视器模式下
  • 是的,我用的是wlan1mon
  • 我检查了pcap_open_live返回的非空值。
  • 我检查了pcap_datalink返回了127个(802.11 w/无线电头)
  • 我已经很难找到一个很好的参考802.11麦迪头球。以太网报头、IPv4报头等都有非常好的引用,这些引用涉及到每个字段的所有必要细节,以及如何知道它是否存在和/或有效.但是,甚至没有人说addr4是否完全被省略,如果没有必要,或者它是否只是0填充/未填充。或者标题的排列给出了不同的类型/子类型(一个地点建议,有时帧只是确认的控件、持续时间和MAC,但我发现的其他站点都没有这样的说法)。

下面是对代码段的快速引用:我做了一个宏Assert (我通常给出一个更长的符合规范的名称,但现在只是这样),它有一个条件作为第一个参数,如果它失败了,它使用一个stringstream构造一个字符串,如果它是假的,就抛出一个runtime_error。这使我可以做出非常描述性的错误消息,在必要时包括局部变量值。

好吧,这是我现在的处境请注意,这是我第一个使用pcap的程序,我将它完全写在Raspberry Pi上,vim是从Windows的git-bash开始的,所以我并不完全处于理想的格式化环境中。而且,当我试图让愚蠢的事情不发生的时候,事情会变得很混乱。

代码语言:javascript
复制
namespace
{
    struct ieee80211_radiotap_header {
            u_int8_t        it_version;     /* set to 0 */
            u_int8_t        it_pad;
            u_int16_t       it_len;         /* entire length */
            u_int32_t       it_present;     /* fields present */
    } __attribute__((__packed__));
    static_assert ( sizeof(ieee80211_radiotap_header)==8 , "Bad packed structure" ) ;

    /* Presence bits */
    enum {
            RADIOTAP_TSFT                           = 0 ,
            RADIOTAP_FLAGS                          = 1 ,
            RADIOTAP_RATE                           = 2 ,
            RADIOTAP_CHANNEL                = 3 ,
            RADIOTAP_FHSS                           = 4 ,
            RADIOTAP_ANTENNA_SIGNAL         = 5 ,
            RADIOTAP_ANTENNA_NOISE          = 6 ,
            RADIOTAP_LOCK_QUALITY           = 7 ,
            RADIOTAP_TX_ATTENUATION         = 8 ,
            RADIOTAP_DB_TX_ATTENUATION  = 9 ,
            RADIOTAP_DBM_TX_POWER           = 10 ,
            RADIOTAP_ANTENNA                = 11 ,
            RADIOTAP_DB_ANTENNA_SIGNAL  = 12 ,
    } ;


    typedef array<uint8_t,6>        MAC ;
    static_assert ( is_pod<MAC>::value , "MAC is not a POD type" ) ;
    static_assert ( sizeof(MAC)==6 , "MAC is not 6-Bytes" ) ;
    string MAC2String ( MAC const& m ) {
            string rval = "__:__:__:__" ;
            for ( auto iByte(0) ; iByte<6 ; ++iByte ) {
                    static char const * const hex = "0123456789abcdef" ;
                    rval[3*iByte]   =       hex [ ( m[iByte] & 0xF0 ) >> 4 ] ;
                    rval[3*iByte+1] =       hex [ m[iByte] & 0x0F ] ;
            }
            return rval ;
    }

    void handlePacket ( u_char * args , pcap_pkthdr const * header , u_char const * packet ) {
            static_assert ( sizeof(u_char)==1 , "Huh?" ) ;

            //cout << "Packet; " << header->caplen << " of " << header->len << " captured" << endl ;

            size_t  expectedSize    =       sizeof(ieee80211_radiotap_header) ;

            Assert ( header->caplen>=expectedSize , "Capture is not big enough; expecting " << expectedSize << " so far, but only have " << header->caplen ) ;

            uint8_t const*  radioHeader             =       packet ;
            auto    rx              =       reinterpret_cast<ieee80211_radiotap_header const*> ( radioHeader ) ;

            expectedSize += rx->it_len - sizeof(ieee80211_radiotap_header) ; // add the radiotap body length
            Assert ( header->caplen>=expectedSize , "Capture is not big enough; expecting " << expectedSize << " so far, but only have " << header->caplen ) ;

            // Look at the 802.11 Radiotap Header




            if ( header->caplen == expectedSize ) {
                    cout << "Packet contains ONLY " << expectedSize << "-Byte RadioTap header" << endl ;
                    return ;
            }

            // From this point forward, all error messages should subtract rx->it_len so that the error reflects the 802.11 frame onward
            // and does not include the radiotap header.


            // Look at the 802.11 MAC Header

            expectedSize += 2+2+2+4 ; // everything but the four addresses
            Assert ( header->caplen>=expectedSize , "Frame is not big enough; expecting " << expectedSize-rx->it_len << " so far, but only have " << header->caplen-rx->it_len ) ;

            uint8_t const*  frameHeader             =       radioHeader + rx->it_len ;

            uint8_t version         =       frameHeader[0] & 3 ;
            Assert ( version==0 , "Bad 802.11 MAC version: " << int(version) ) ;

            uint8_t frameType       =       ( frameHeader[0] >> 2 ) & 0x03 ;
            uint8_t frameSubtype=   ( frameHeader[0] >> 4 ) & 0x0F ;
            bool    toDS            =       frameHeader[1] & 0x01 ;
            bool    fromDS          =       frameHeader[1] & 0x02 ;
            bool    isWEP           =       frameHeader[1] & (1<<6) ;

            MAC const*              addr1   =       reinterpret_cast<MAC const*> ( frameHeader + 4 ) ;
            MAC const*              addr2   =       reinterpret_cast<MAC const*> ( frameHeader + 10 ) ;
            MAC const*              addr3   =       reinterpret_cast<MAC const*> ( frameHeader + 16 ) ;
            MAC const*              addr4   =       reinterpret_cast<MAC const*> ( frameHeader + 24 ) ;

            MAC const*      bssid (0) ;
            MAC const*      da ;
            MAC const*      sa ;
            MAC const*      ra ;
            MAC const*      ta ;
            char const*     desc ;

            // Table found here: https://www.rfwireless-world.com/Articles/WLAN-MAC-layer-protocol.html
            if ( !toDS && !fromDS ) {
                    desc = "STA->STA" ;
                    da      =       addr1 ;
                    sa      =       addr2 ;
                    bssid=  addr3 ;
                    // inferred
                    ta      =       sa ;
                    ra      =       da ;
                    expectedSize += 6+6+6 ;
            } else if ( !toDS && fromDS ) {
                    desc = "Base->STA" ;
                    da      =       addr1 ;
                    bssid=  addr2 ;
                    sa      =       addr3 ;
                    // inferred
                    ta      =       bssid ;
                    ra      =       da ;
                    expectedSize += 6+6+6 ;
            } else if ( toDS && !fromDS ) {
                    desc = "STA->Base" ;
                    bssid=  addr1 ;
                    sa      =       addr2 ;
                    da      =       addr3 ;
                    // inferred
                    ta      =       sa ;
                    ra      =       bssid ;
                    expectedSize += 6+6+6 ;
            } else if ( toDS && fromDS ) {
                    desc = "Base->Base" ;
                    ra      =       addr1 ;
                    ta      =       addr2 ;
                    da      =       addr3 ;
                    sa      =       addr4 ;
                    expectedSize += 6+6+6+6 ;
            }
            Assert ( header->caplen>=expectedSize , "Frame is not big enough; expecting " << expectedSize-rx->it_len << " so far, but only have " << header->caplen-rx->it_len << " for a " << desc << " frame of type " << int(frameType) << '/' << int(frameSubtype) ) ;



            cout << desc << "\t" << MAC2String(*ta) << '/' << MAC2String(*sa) << "  -->  " << MAC2String(*ra) << '/' << MAC2String(*da) << endl ;

            //cout << MAC2String(addr1) << " / " << MAC2String(addr2) << "  -->  " << MAC2String(addr3) << " / " << MAC2String(addr4) << endl ;

            //cout << "   " << int(frameType) << " / " << int(frameSubtype) << endl ;
    }
}




int main ( int , char const* * )
{
    cout << "Hello, world" << endl ;

    auto    devName                 =       "wlan1mon" ;

    char    errBuf[PCAP_ERRBUF_SIZE] ;
    auto    maxTime                 =       0 ; // ms
    auto    maxPacketCount  =       0 ;

    auto    dev                     =       pcap_open_live ( devName , BUFSIZ , maxPacketCount , maxTime , errBuf ) ;
    Assert ( dev!=0 , "Failed to open pcap: " << errBuf ) ;

    auto    linkType                =       pcap_datalink ( dev ) ;
    // IEEE 802.11 link type is 105, from tcpdump.org/linktypes.html
    // 127 is the 802.11 radiotap which is even better
    Assert ( linkType==127 , "Link type was " << linkType << ", but expected " << 127 ) ;

    pcap_loop ( dev , maxPacketCount , handlePacket , /*user*/0 ) ;

    cout << "Exiting" << endl ;

    return 0 ;
}

但我很快得到的是一个错误,即802.11帧(在无线电抽头之后)是10字节长的(这是代码中的最后一个Assert,在to/from DS之后)。

我尝试过几种读取框架控件的组合(一次读取整个小端uint16_t,或逐字节读取,b0-第一或b0-最后,等等),因为它的排列方式似乎没有很好的规范。我确实经常遇到STA->STA框架(正如这段代码所检测到的/报告的),考虑到我的环境,这似乎不太可能。

我遗漏了什么?很明显我漏掉了什么。

作为参考,无线电抽头it_len总是18字节或21字节,这也似乎很奇怪。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-18 23:18:10

我已经很难找到一个很好的参考802.11麦迪头球。

如果说“好”是指“简单”,不幸的是,这是不可能的,因为头并不像802.3以太网头那样简单。:-)

总是有IEEE 802.11-2016年;参见第9.2节"MAC帧格式“。

(一个站点表示,有时候,框架只是用于确认的控件、持续时间和MAC,但我发现的其他站点都没有这样的说法)。

帧控制、持续时间、接收地址和CRC。这就是-,这是14个八位数,而CRC是最后的4个八位数,所以如果数据包中没有CRC,那将是10个八位数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66181031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档