적절한 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*)
ICMP 포트가 없습니다. – EJP
당신의 원본 주소가별로 중요하지 않습니다. IMHO – Hasturkun
sendto()와 recvfrom()에주는 28 바이트에 맞게 보내고 받기를 원하는 것이 모두 들어 있습니까? 특히 IP_HDRINCL을 정의 할 때 패킷이 조금 더 커야한다고 생각합니다. 또한 가능한 경우 컴파일하는 예제를 제공하십시오. 나는 당신의 "libsock"이 무엇인지 모른다. – thuovila