イーサネット トレーラを含むデータグラムを送信するにはどうすればよいですか? SocketType.Raw を使用すると、IP ヘッダー全体を送信する必要があり、その方法がわかりません。
1793 次
2 に答える
2
そのトレーラーは、イーサネットフレームを最小の長さ(ペイロードの46バイト)にパディングするために使用されます。したがって、18バイト未満の小さなUDPパケットを送信します(IP + UDPは通常28バイトであるため)
于 2010-08-10T23:36:13.487 に答える
2
もしかしてこういうこと?
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <linux/if_packet.h> #include <linux/if_ether.h> #include <linux/if_arp.h> #include <sys/ioctl.h> int s; unsigned char buffer[513]; struct sockaddr_ll socket_address; int main (ボイド) { unsigned char seq; unsigned int ra; 整数の長さ; struct ifreq ifr; s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); もし (s == -1) { printf("ソケット作成エラー\n"); リターン (1); } memset(&ifr,0, sizeof(struct ifreq)); strncpy(ifr.ifr_name,"eth0",IFNAMSIZ); if(ioctl(s, SIOCGIFINDEX, &ifr) < 0) { perror("ioctl SIOCGIFINDEX"); 終了 (1); } printf("index %d\n",ifr.ifr_ifindex); printf("ソケットが作成されました\n"); memset(&socket_address,0,sizeof(socket_address)); socket_address.sll_family = PF_PACKET; socket_address.sll_protocol = htons(ETH_P_ALL); socket_address.sll_ifindex = ifr.ifr_ifindex; if (bind(s, (struct sockaddr *)(&socket_address), sizeof(socket_address)) < 0) { perror("バインド エラー"); 終了 (1); } printf("バインド\n"); 長さ=27; memset (バッファ、0、sizeof(バッファ)); //行き先 バッファ[0]=0xFF; バッファ[1]=0xFF; バッファ[2]=0xFF; バッファ[3]=0xFF; バッファ[4]=0xFF; バッファ[5]=0xFF; //ソース バッファ[6]=0x00; バッファ[7]=0x19; バッファ[8]=0xd1; バッファ[9]=0x02; バッファ[10]=0xdc; バッファ[11]=0xb3; //長さ バッファ[12]=((長さ-14)>>8)&0xFF; バッファ[13]=((長さ-14)>>0)&0xFF; //ペイロード バッファ[14]=0x12; バッファ[15]=0x34; for(ra=0;ra<20;ra++) { バッファ[16]=ra; if(send(s,buffer,length,0) < 0 ) { printf("sendto に失敗しました\n"); 壊す; } そうしないと { printf("送信\n"); } } 閉じる; リターン (1); }
これにより、wireshark で確認できる生のパケットが得られるはずです。IPリーダーが必要な場合、またはUDPなどにしたい場合は、このメソッドを使用して自分でヘッダーを作成できます(rfcを簡単に確認するか、wiresharkを使用して他のパケットヘッダーの束を確認するだけです) . udp の場合、チェックサムを計算する必要がないことに注意してください。0x0000 は、通過するはずの有効なチェックサムです。
末尾がゼロの udp パケットだけが必要な場合は、多少同じで、おそらく簡単です。お知らせください。
于 2010-08-12T22:21:56.273 に答える