5

これは割り当てであり、rawソケットを使用する必要があります。簡単なicmppingをプログラムする必要があります。これをベースとして使用しましたhttp://www.pdbuchan.com/rawsock/icmp4.c。127行目はwlan0で、Imはeth0を使用しています。290行目でこれをコーディングしました:

struct sockaddr_in rec;
  
unsigned char * pkt = (unsigned char *) malloc (IP_MAXPACKET * sizeof (unsigned char));

if (recvfrom (sd, (void*)pkt, IP4_HDRLEN + ICMP_HDRLEN+datalen , 0, NULL, (socklen_t*)sizeof (struct sockaddr)) < 0)  {
  perror ("recvfrom() failed ");
  exit (EXIT_FAILURE);
}
struct ip *ip = (struct ip *)pkt;
struct icmphdr *icmp = (struct icmphdr *)(pkt + IP4_HDRLEN);

printf("%s %s %d\n",(char*)inet_ntoa(*(struct in_addr*)&ip->ip_dst),
        (char*)inet_ntoa(*(struct in_addr*)&ip->ip_src),
        icmp->type);
free (pkt);

問題は、ip_dstとip_srcがマシンのIPとして表示され、icmpタイプが8ではなく0として表示されることです。Wiresharkはicmp応答と要求の両方を表示します。おそらく私のrecvfromは間違っていますが、Linux独自のTCP/IPがパケットを処理している可能性があると聞きました。それが本当なら、その回避策は何ですか?

編集:このrawソケットリスナーをチェックしましたが、問題は解決しませんでした。

4

1 に答える 1

7

IPPROTO_RAWを使用していると返信が取れないと思います。

あなたは使用する必要があります

socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);

IPPROTO_ICMPでは、IPパケット全体ではなく、ICMPパケットのみを送信する必要があります。

ただし、受信すると、IPパケット全体が取得され、ICMP応答を抽出する必要があります。ホストに送信されたすべてのICMPパケットのコピーを取得するため、それらをフィルタリングする必要があることに注意してください。

于 2012-11-25T05:35:37.140 に答える