3

私はC言語で生のソケットを扱っています。生のイーサネット パケットを送受信する必要があります。パケットは、IEEE 802.3 ヘッダーで開始する必要があります。

MAC DST [0 ~ 5] - MAC SRC [6 ~ 11] - ETH タイプ [12 ~ 13]

Wireshark でパケットをキャッチすると、次の構造が表示されます。

MAC DST [0-5] - MAC SRC [6-11] - 長さ [12-13] - トレーラー [14-58]-....

これは私のコードです:

...
sraw = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_802_3));
...
retVal = setsockopt(sraw, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
...
val = 3;
retVal = setsockopt(sraw, SOL_SOCKET, SO_PRIORITY, &val, sizeof (val));
...
memcpy(ptr_eth_header->DstMac, dst_mac, 6);
memcpy(ptr_eth_header->SrcMac, src_mac, 6);
ptr_eth_header->Type = htons(ETH_P_802_3);
memcpy(buffer + ETHHDR_SIZE, data, 60);
...
sockaddr.sll_family = htons(PF_PACKET);
sockaddr.sll_protocol = htons(ETH_P_802_3);
sockaddr.sll_ifindex = ifr.ifr_ifru.ifru_ivalue;
sockaddr.sll_halen = 6;
memcpy(&(sockaddr.sll_addr), dst_mac, 6);
...
bytes = sendto(sraw, buffer, sizeof(buffer), 0, (struct sockaddr *) &(sockaddr), sizeof (struct sockaddr_ll));

それは単なるwiresharkの「問題」ですか?何か案は?

2 つ目の問題は、生のメッセージの受信に関するものです。プロセスは recvfrom でスタックしています。

これは私のコードです:

sraw = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_802_3));
...
retVal = setsockopt(sraw, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
...
val = 3;
retVal = setsockopt(sraw, SOL_SOCKET, SO_PRIORITY, &val, sizeof (val));
...
val = CLIENT_PACKET_SIZE;
retVal = setsockopt(sraw, SOL_SOCKET, SO_RCVBUF, &val, sizeof (val));

sockaddr.sll_family    = htons(PF_PACKET);
sockaddr.sll_ifindex   = ifr.ifr_ifindex;
sockaddr.sll_protocol  = htons(ETH_P_802_3);

buffer = malloc(CLIENT_PACKET_SIZE * sizeof(char));
while (count < PACKET_COUNT) {
    bytes = recvfrom(sraw, buffer, CLIENT_PACKET_SIZE, 0, (struct sockaddr *)&sockaddr, (socklen_t*)sizeof(sockaddr));
    ...
}

私たちを手伝ってくれますか?

前もって感謝します!

4

2 に答える 2

1

私は最初の質問についての回答を見つけました:EtherType>=0x0600の代わりにEthertype==0x0001を使用します

http://www.cavebear.com/archive/cavebear/Ethernet/type.html

2番目の質問はどうですか?私のコードの何が問題になっていますか?

于 2012-03-13T10:16:34.110 に答える
0

あなたの質問に一言で答えるのは難しいです。しかし、あなたのコードで recvfrom が動かなくなる理由を私に尋ねると、フィルター条件を満たすパケットを取得できない可能性があると言うでしょう。期待される形式で ifindex 値を渡していますか? ifindex sockaddr.sll_ifindex = ifr.ifr_ifru.ifru_ivalue; を渡しているようです。センドウでこのように。

他の理由としては、ソケットに設定したバッファ サイズがカーネルでサポートされていないか、カーネルがバッファを使い果たしているなど、さまざまな理由が考えられます。しかし、これらのいずれかの可能性は最小限です。

また、あなたのシナリオでは、ブロックする代わりに非ブロック ソケットを使用することをお勧めします。読み取り待ちのパケットがあることがわかっている場合にのみ、recvfrom を呼び出します。

于 2013-10-03T06:32:16.710 に答える