1

WinPCap を使用して、イーサネット ラベル (送信先アドレス、送信元アドレス、タイプ/長さフィールド) を取得して解析しようとしています。

私は主に WinPCap SDK からコピー/貼り付けしています。WinPCap パケット データ (pkt_data 内) を、宛先アドレス [6 バイト]、送信元アドレス [6 バイト]、タイプ/長さフィールド (short int)、およびパケット長 (int) を含む、ethernet という名前の構造体に格納しようとしています。

pkt_data は、最初の 6 バイトが宛先アドレス、次の 6 バイトが送信元アドレス、その後の 2 バイトがタイプ/長さフィールドとして並んでいると思いますが、よくわかりません。

この例で WinPCap が保存するラベルの正確なバイト順を知っている人はいますか?

/* If device is open, acquire attributes from packet */
if( ( res = pcap_next_ex( fp, &header, &pkt_data)) >= 0)
{
    if(res != 0)
    {
        /* Acquire the length of the capture */
        ethernet->length = header->caplen;

        /* Acquire destination MAC address */
        for (i = 0; i < 6; i++)
            ethernet->destAddress[i] = pkt_data[i];

        /* Acquire source MAC address */
        for ( i = 6; i < 12; i++ )
            ethernet->srcAddress[i] = pkt_data[i];

        /* Acquire etherType type/length designation field */
        ethernet->type = ( pkt_data[12] | pkt_data[13] );

        /* Acquire the remaining data of the packet */
        for ( i = 14; (i < header->caplen + 1); i++ )
            ethernet->data[i - 14] = pkt_data[i];
    }

    /* Device error: cannot read from packet */
    else if(res == -1)
        printf("Error reading the packets: %s\n", pcap_geterr(fp));
}
4

1 に答える 1

0

libpcap/WinPcap によってキャプチャされたパケット内のデータのバイト オーダーは、データがネットワーク上で送信されるバイト オーダーです。libpcap/WinPcap は、生のパケット データを提供します (Radiotap ラジオ ヘッダーなどの「疑似ヘッダー」情報は除きます。これらの情報はネットワーク上には表示されず、それらを生成するソフトウェアが使用する任意のバイト順です。たとえば、リトルエンディアンの場合)ラジオタップの)。

MAC アドレスは、48 ビットの数値ではなく、6 バイトのシーケンスと考えるのが最適であるため、バイト順の問題はありません。宛先アドレスが最初に来るので、pkt_data[0]スルーに入りpkt_data[5]ます。送信元アドレスが次に来るので、pkt_data[6]throughに入っていpkt_data[11]ます。

ご了承ください

    /* Acquire source MAC address */
    for ( i = 6; i < 12; i++ )
        ethernet->srcAddress[i] = pkt_data[i];

は間違っています -srcAddressおそらく 6 バイトの配列なので、srcAddress[0]throughsrcAddress[5]があり、 on がありませんsrcAddress[6]。あなたはそれを行うことができます

    /* Acquire source MAC address */
    for ( i = 0; i < 6; i++ )
        ethernet->srcAddress[i] = pkt_data[i + 6];

memcpy()ただし、ループを自分で記述するよりも、データをコピーする方がおそらく最も簡単です。

    memcpy(ethernet->dstAddress, &pkt_data[0], 6);
    memcpy(ethernet->srcAddress, &pkt_data[6], 6);

タイプ/長さフィールドはその後に続き、長さは 2 バイトなので、 と にpkt_data[12]ありpkt_data[13]ます。IEEE 802.3 標準に従って、「Length/Type フィールドは、最初に上位オクテットで送受信されます。」「最初の」オクテットはpkt_data[12]であるため、「上位オクテット」であり、値の上位 8 ビットにある必要があります。「2番目の」オクテットはpkt_data[13]、値の下位8ビットにあるため、

ethernet->type = (pkt_data[12]<<8) | pkt_data[13];
于 2012-10-11T17:31:25.833 に答える