套接字文件描述符自动更改

时间:2012-06-11 09:16:28

标签: c sockets networking file-descriptor

我尝试使用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;
}

在我的输出中,不是打印无限循环的数据包信息,而是只打印一个信息包。所以我已经检查了gdb。我用了display sockfd。在套接字调用之后,sockfd的值为7.然后在while循环中,在执行dest ip的printf之后,sockfd值更改为808988216.因此,recv失败,并且文件描述符错误&#34;错误。我无法找到实际出错的地方。

提前致谢: - )

1 个答案:

答案 0 :(得分:3)

这是一个缓冲区溢出:

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

缓冲区不足以容纳IP地址的字符串形式。另外,关于可用空间的第四个参数是inet_ntop(),它应该是:

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