私はICMPプロトコルを試してみて、ICMPパケットを分析するLinux用のカーネルモジュールを作成しました(ICMPコードフィールドがマジックナンバーの場合にのみパケットを処理します)。このモジュールをテストするには、ICMPパケットを作成し、この分析モジュールが実行されているホストに送信する必要があります。実際、カーネル自体を(モジュールとして)実装できればいいのですが。カーネルのパケットクラフターのようなものを探しています。パケットを作成するチュートリアルではなく、パケットの存続期間を説明する記事がたくさん見つかりました。ユーザースペースのパケットクラフターは私の最後の手段であり、ICMPコードなどを設定できる場所のように非常に柔軟なものでもあります。そして、私はカーネルパニックを警戒していません:-) !!!!! パケット作成のアイデアは大歓迎です。
3 に答える
サー、カーネルモジュールを使用してICMPパケットを作成しないように強くお勧めします。
ユーザースペースのrawソケットを使用してICMPパケットを作成し、IPヘッダー自体をバイトごとに作成することもできます。したがって、それを使用して得ることができるのと同じくらい柔軟になることができます。
これを見てください
ip = (struct iphdr*) packet;
icmp = (struct icmphdr*) (packet + sizeof(struct iphdr));
/*
* here the ip packet is set up except checksum
*/
ip->ihl = 5;
ip->version = 4;
ip->tos = 0;
ip->tot_len = sizeof(struct iphdr) + sizeof(struct icmphdr);
ip->id = htons(random());
ip->ttl = 255;
ip->protocol = IPPROTO_ICMP;
ip->saddr = inet_addr(src_addr);
ip->daddr = inet_addr(dst_addr);
if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1)
{
perror("socket");
exit(EXIT_FAILURE);
}
/*
* IP_HDRINCL must be set on the socket so that
* the kernel does not attempt to automatically add
* a default ip header to the packet
*/
setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int));
/*
* here the icmp packet is created
* also the ip checksum is generated
*/
icmp->type = ICMP_ECHO;
icmp->code = 0;
icmp->un.echo.id = 0;
icmp->un.echo.sequence = 0;
icmp->checksum = 0;
icmp-> checksum = in_cksum((unsigned short *)icmp, sizeof(struct icmphdr));
ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr));
コードのこの部分が十分に柔軟に見える場合は、rawソケットについて読んでください:Dおそらく、それらはあなたのニーズに対する最も簡単で安全な答えです。
詳細については、次のリンクを確認してください
http://courses.cs.vt.edu/~cs4254/fall04/slides/raw_6.pdf
http://www.cs.binghamton.edu/~steflik/cs455/rawip.txt
http://cboard.cprogramming.com/networking-device-communication/107801-linux-raw-socket-programming.html 非常に優れたトピックであり、非常に便利なimo
ユーザースペースでのパケット作成にlibcrafterを試すことができます。とても使いやすいです!ライブラリは、最も一般的なネットワークプロトコルのパケットを作成またはデコードし、それらをネットワーク上で送信し、キャプチャして、要求と応答を照合することができます。
たとえば、次のコードはICMPパケットを作成して送信します。
string MyIP = GetMyIP("eth0");
/* Create an IP header */
IP ip_header;
/* Set the Source and Destination IP address */
ip_header.SetSourceIP(MyIP);
ip_header.SetDestinationIP("1.2.3.4");
/* Create an ICMP header */
ICMP icmp_header;
icmp_header.SetType(ICMP::EchoRequest);
icmp_header.SetIdentifier(RNG16());
/* Create a packet... */
Packet packet = ip_header / icmp_header;
packet.Send();
カーネル空間でICMPパケットを作成したいのはなぜですか?ただ楽しみのために?:-p
Linuxカーネルには、事前構成されたパケットを使用してネットワークをテストするためのパケットジェネレータツールpktgenが含まれています。このモジュールのソースコードはnet/core/pktgen.cにあります