3

RAW ソケット プログラミングを使用して、NIC に近づくすべての UDP パケットをキャプチャしようとしました。ここで私は奇妙な問題を抱えています。プログラムの実行中に、ソケット記述子が自動的に変更されます。コードは次のとおりです。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <arpa/inet.h>

int main () {

int sockfd = socket (PF_INET, SOCK_RAW, IPPROTO_UDP);
if (sockfd < 0) {
    perror ("socket failed");
    return -1;
}

char *buf = malloc (8192);
memset (buf, 0, 8192);
if (!buf) {
    perror ("calloc failed\n");
    return -1;
}

int ret_recv;
i:
while ((ret_recv = recv (sockfd, buf, 8192, 0)) > -1) {
    printf ("%d\n", ret_recv);
    struct iphdr *iph = (struct iphdr *) buf;
    //struct udphdr *udph = (struct udphdr *) (buf + sizeof (struct iphdr));
    struct tcphdr *tcph = (struct tcphdr *) (buf + sizeof (struct iphdr));
    char ip[4];
    printf ("source ip: %s\n", inet_ntop (AF_INET, &iph->saddr, ip, sizeof (struct sockaddr_in)));
    printf ("dest ip: %s\n", inet_ntop (AF_INET, &iph->daddr, ip, sizeof (struct sockaddr_in)));
    //printf ("port: %d\n", ntohs (udph->source));
    printf ("port: %d\n", ntohs (tcph->source));
}
perror ("recv failed");
//goto i;
return 0;
}

私の出力では、パケット情報の印刷の無限ループの代わりに、情報の 1 つのパケットのみが印刷されています。だから私はgdbでチェックしました。使用しdisplay sockfdました。ソケット呼び出しの後、sockfd の値は 7 でした。次に while ループ内で、dest ip の printf を実行した後、sockfd 値は 808988216 に変更されました。そのため、recv は「不正なファイル記述子」エラーで失敗しました。実際に何が悪かったのかわかりません。

前もって感謝します :-)

4

1 に答える 1

3

バッファオーバーフローは次のとおりです。

char ip[4];
    printf ("source ip: %s\n", inet_ntop (AF_INET, &iph->saddr, ip, sizeof (struct sockaddr_in)));

バッファーは、IP アドレスの文字列形式を保持するのに十分な大きさではありません。また、4 番目の引数はinet_ntop()、使用可能なスペースについて嘘をついています。次のようにする必要があります。

char ip[INET_ADDRSTRLEN];
printf ("source ip: %s\n", inet_ntop (AF_INET, &iph->saddr, ip, sizeof ip));
于 2012-06-11T09:28:16.253 に答える