2012-11-24 32 views
5

. Đây là một nhiệm vụ, nó phải có ổ cắm thô. Tôi cần lập trình một ping icmp đơn giản. Tôi đã sử dụng số này làm cơ sở http://www.pdbuchan.com/rawsock/icmp4.c. Tại dòng 127 là wlan0, Im sử dụng eth0. Trong dòng 290 Tôi mã này:Cách nhận yêu cầu ICMP trong C với ổ cắm thô

'

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); 

' Vấn đề là ip_dst và ip_src đang được hiển thị như IP máy của tôi, và loại icmp là 0 và không 8. Wireshark cho thấy cả hai icmp trả lời và yêu cầu. Có lẽ recvfrom của tôi là sai, nhưng tôi nghe một cái gì đó về Linux riêng TCP/IP có thể được xử lý các gói tin. Nếu đó là sự thật, giải pháp cho điều đó là gì?

chỉnh sửa: Tôi đã kiểm tra điều này raw socket listener nhưng nó không giải quyết được sự cố của tôi.

+0

Sáng tạo có trên liên kết tôi đã đăng. Đó là từ các ví dụ của trang web đó. Tôi đã chèn mã này vào dòng 290 của icmp4.c – liwing

Trả lời

6

Tôi không nghĩ bạn có thể nhận được trả lời khi sử dụng IPPROTO_RAW.

Bạn phải sử dụng

socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); 

Với IPPROTO_ICMP bạn chỉ phải gửi một gói ICMP, không phải là gói tin IP nói chung.

Khi nhận được, bạn sẽ nhận được toàn bộ gói IP và phải trích xuất trả lời ICMP. Lưu ý rằng bạn sẽ nhận được một bản sao của tất cả các gói ICMP được gửi đến máy chủ để bạn phải lọc chúng.

Nhìn vào a real ping để lấy cảm hứng.

+0

OK, vì vậy tôi đã làm điều này http://pastebin.com/62JmMddE; Chương trình của tôi in ip_dst và ip_src cả IP của tôi vẫn còn. Và nếu tôi đặt một cấu trúc không NULL trong recvfrom, tôi nhận được lỗi địa chỉ xấu. Ping thực sự đó chỉ đưa ra một lệnh sockaddr_in được khai báo mới, giống như im đang cố gắng thực hiện. – liwing

+0

lol, tôi sẽ không bao giờ biết về vấn đề này inet_ntoa. Cảm ơn nhiều. Tôi vẫn không nhận được nó khi tôi nên sử dụng tham số sockaddr không NULL trong recvfrom. – liwing

Các vấn đề liên quan