2013-03-17 5 views
3

적절한 ip 헤더와 icmp 헤더를 생성하여 icmp 원시 소켓을 사용하여 traceroute를 구현하려고합니다. 사용중인 포트 번호가 7이고 체크섬을 계산했습니다. 홉 한계가 각각 증가합니다 다른 주소에 존재위한 argv[1] 즉 입력 "127.0.0.1" 인 O/P가C에서 icmp를 사용하여 traceroute 구현

hop limit:0 Address:127.0.0.1 

Reached destination:127.0.0.1 with hop limit:1 

하지만 때 시간 및 패킷이 응답 메시지까지 전송되는 타입 0

#include "libsock" 
#include<netinet/ip.h> 
#include<netinet/ip_icmp.h> 


unsigned short 
csum (unsigned short *buf, int nwords) 
{ 
    unsigned long sum; 
    for (sum = 0; nwords > 0; nwords--) 
    sum += *buf++; 
    sum = (sum >> 16) + (sum & 0xffff); 
    sum += (sum >> 16); 
    return ~sum; 
} 

int 
main (int argc, char *argv[]) 
{ 
    if (argc != 2) 
    { 
     printf ("need destination for tracert\n"); 
     exit (0); 
    } 
    int sfd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); 
    char buf[4096] = { 0 }; 
    struct ip *ip_hdr = (struct ip *) buf; 
    int hop = 0; 

    int one = 1; 
    const int *val = &one; 
    if (setsockopt (sfd, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) 
    printf ("Cannot set HDRINCL!\n"); 

    struct sockaddr_in addr; 
    addr.sin_port = htons (7); 
    addr.sin_family = AF_INET; 
    inet_pton (AF_INET, argv[1], &(addr.sin_addr)); 


    while (1) 
    { 
     ip_hdr->ip_hl = 5; 
     ip_hdr->ip_v = 4; 
     ip_hdr->ip_tos = 0; 
     ip_hdr->ip_len = 20 + 8; 
     ip_hdr->ip_id = 10000; 
     ip_hdr->ip_off = 0; 
     ip_hdr->ip_ttl = hop; 
     ip_hdr->ip_p = IPPROTO_ICMP; 
     inet_pton (AF_INET, "172.30.104.59", &(ip_hdr->ip_src)); 
     inet_pton (AF_INET, argv[1], &(ip_hdr->ip_dst)); 
     ip_hdr->ip_sum = csum ((unsigned short *) buf, 9); 

     struct icmphdr *icmphd = (struct icmphdr *) (buf + 20); 
     icmphd->type = ICMP_ECHO; 
     icmphd->code = 0; 
     icmphd->checksum = 0; 
     icmphd->un.echo.id = 0; 
     icmphd->un.echo.sequence = hop + 1; 
     icmphd->checksum = csum ((unsigned short *) (buf + 20), 4); 
     sendto (sfd, buf, 28, 0, SA & addr, sizeof addr); 
     char buff[4096] = { 0 }; 
     struct sockaddr_in addr2; 
     socklen_t len = sizeof (struct sockaddr_in); 
     recvfrom (sfd, buff, 28, 0, SA & addr2, &len); 
     struct icmphdr *icmphd2 = (struct icmphdr *) (buff + 20); 
     if (icmphd2->type != 0) 
    printf ("hop limit:%d Address:%s\n", hop, inet_ntoa (addr2.sin_addr)); 
     else 
    { 
     printf ("Reached destination:%s with hop limit:%d\n", 
      inet_ntoa (addr2.sin_addr), hop); 
     exit (0); 
    } 

     hop++; 
    } 

    return 0; 
} 

의 에코 응답 포함 내 집안에 tracepath가 내 프로그램 블록을 작동시키는 사람은 recvfrom입니다.

이유를 말씀해 주실 수 있습니까?

감사합니다.

여기 libsock입니다 : -

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<arpa/inet.h> 
#include<sys/types.h> 
#include<netinet/in.h> 
#include<sys/socket.h> 
#include<unistd.h> 
#include<pthread.h> 
#include<poll.h> 
#include<stdio.h> 
#include<stdlib.h> 
#include<unistd.h> 
#include<sys/types.h> 
#include<sys/ipc.h> 
#include<fcntl.h> 
#include<sys/stat.h> 
#include<signal.h> 
#include<sys/sem.h> 
#include<poll.h> 
#include<pthread.h> 
#include<sys/select.h> 
#include<sys/un.h> 
#define SA (struct sockaddr*) 
+5

ICMP 포트가 없습니다. – EJP

+1

당신의 원본 주소가별로 중요하지 않습니다. IMHO – Hasturkun

+0

sendto()와 recvfrom()에주는 28 바이트에 맞게 보내고 받기를 원하는 것이 모두 들어 있습니까? 특히 IP_HDRINCL을 정의 할 때 패킷이 조금 더 커야한다고 생각합니다. 또한 가능한 경우 컴파일하는 예제를 제공하십시오. 나는 당신의 "libsock"이 무엇인지 모른다. – thuovila

답변

2

당신이 손으로 IP 헤더를 구축하려는 경우, 당신은 당신이 대상으로 제공 IP 주소로 라우팅 가능성이있는 IP를 소스 주소를 설정해야합니다. 예 : localhost의 경우 localhost가 localhost를 "핑 (ping)"할 수 있으므로 (즉, 여기에 라우팅 기능이 있음) 소스를 127.0.0.1로 설정할 수 있습니다.

보내고받는 크기가 너무 작게 보입니다. 가정용 컴퓨터에서 NAT 장치 뒤에 192.168.1.0/24 주소가 있으므로 다음과 같이 변경했습니다.

inet_pton (AF_INET, "192.168.1.168", &(ip_hdr->ip_src)); 
.... 
sendto (sfd, buf, sizeof(struct ip) + sizeof(struct icmphdr), 0, SA & addr, sizeof addr); 
.... 
recvfrom (sfd, buff, sizeof(buff), 0, SA & addr2, &len); 

예 출력 :

[email protected]:~/src/so$ sudo ./a.out 128.214.248.132 
hop limit:0 Address:192.168.1.1 
hop limit:1 Address:192.168.1.1 
hop limit:2 Address:91.156.128.1 
hop limit:3 Address:139.97.9.58 
hop limit:4 Address:139.97.6.209 
hop limit:5 Address:139.97.6.250 
hop limit:6 Address:193.110.224.14 
hop limit:7 Address:193.166.255.93 
Reached destination:128.214.248.132 with hop limit:8