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가 "잘못된 파일 설명자"오류로 실패했습니다. 실제로 잘못 된 것을 찾을 수 없습니다.
char ip[4];
printf ("source ip: %s\n", inet_ntop (AF_INET, &iph->saddr, ip, sizeof (struct sockaddr_in)));
버퍼가 IP 주소의 문자열 형식을 보관 유지하는데 충분한 크기가 아닌 :
valgrind를 사용하여 프로그램을 실행 했습니까? 제 생각 엔 당신이 잠시 동안 {{} 내부의 스택을 망가 뜨리고 있습니다. BTW는 ip [4] inet_ntop에서 ip [16] 이상으로 변경합니다. [INET_ADDRSTRLEN] – strkol
메모리 손상이 가장 좋습니다. 포인터 연산을 확인하십시오. –
게시 된 코드는 그대로 있습니다. 나는 이것이 실제 코드가 아닌 것으로 의심한다. (아마 "이것이 될 수 없다"라고 생각하는 것을 생략했을 것이다.) – cnicutar