2012-06-11 4 views
2

Я попытался захватить все UDP-пакеты, приближающиеся к моей сетевой карте, используя программирование сокетов RAW. Здесь я получаю странную проблему. Пока моя программа работает, мой дескриптор сокета автоматически изменяется. Вот код:Изменения дескриптора файла сокета автоматически

#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 после выполнения printf файла dest ip значение sockfd было изменено на 808988216. Таким образом, recv завершился с ошибкой «плохой файловой дескриптор». Я не могу найти, что на самом деле пошло не так.

Заранее спасибо :-)

+1

ли вы запустить программу с Valgrind? Я предполагаю, что вы повредили стек внутри {}. BTW измените char ip [4] на inet_ntop на ip [16] или лучше на ip [INET_ADDRSTRLEN] – strkol

+1

Повреждение памяти лучше всего. Проверьте свою арифметику указателя. –

+0

Введенный код является правильным, как есть. Я подозреваю, что это не настоящий код (вы, вероятно, опускаете что-то, думая «Это не может быть»). – cnicutar

ответ

2

Вот переполнение буфера:

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)); 
Смежные вопросы