gpt4 book ai didi

c - 在 C 中使用 icmp 实现 traceroute

转载 作者:行者123 更新时间:2023-12-03 11:49:26 25 4
gpt4 key购买 nike

我正在尝试通过构造适当的 ip header 和 icmp header 来使用 icmp 原始套接字实现 traceroute。我使用的端口号是 7 并且我已经计算了校验和。每次增加跳数限制并发送一个数据包直到回复消息包含类型 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;
}

当输入即 argv[1]"127.0.0.1" o/p 是
hop limit:0 Address:127.0.0.1

Reached destination:127.0.0.1 with hop limit:1

但是对于我的局域网中存在的其他地址,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*)

最佳答案

如果您想手动构建 IP header ,您必须将源地址设置为一个 IP,该 IP 可路由到您提供的作为目的地的 IP 地址。例如。对于本地主机,您可以将源设置为 127.0.0.1,因为本地主机“可以 ping”本地主机(即在那里具有可路由性)。

你给发送和接收的尺寸看起来真的太小了。我在我的家用电脑上进行了以下更改(它位于 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);

示例输出:
thuovila@glx:~/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

关于c - 在 C 中使用 icmp 实现 traceroute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15458438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com