gpt4 book ai didi

c - 如何使用 RAW 套接字嗅探所有 ICMP 数据包

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:20:48 25 4
gpt4 key购买 nike

我正在学习 RAW 套接字。在下面的代码中,我试图打印所有 ICMP 数据包 header 信息。看起来像代码中的一些错误。任何人都可以在我错的地方帮助我。

# include <unistd.h>
# include <sys/socket.h>
# include <sys/types.h>
# include <string.h>
# include <netinet/in.h>
# include <stdio.h>
# include<stdlib.h>

main(){
int sockfd,retval,n;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
char buf[10000];

sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sockfd < 0){
perror("sock:");
exit(1);
}
clilen = sizeof(struct sockaddr_in);
while(1){
printf(" before recvfrom\n");
n=recvfrom(sockfd,buf,10000,0,(struct sockaddr *)&cliaddr,&clilen);
printf(" rec'd %d bytes\n",n);
buf[n]='\0';
printf(" msg from client = %s\n",buf);
}
}

o/p

before recvfrom
rec'd 60 bytes
msg from client = E
before recvfrom
rec'd 52 bytes

最佳答案

您正在尝试将原始数据包数据(包括 header )打印为字符串。在这种情况下,E 是 ascii 0x45 是 IP header 的第一个字节。高 4 位表示“IPv4”,低 4 位是 IHL(IP header 中 32 位字的数量),即 5*4 = 20 字节。

要正确访问此数据,您应该使用 linux 提供的 IP/ICMP header 结构。我已经稍微更新了您的代码以说明:

# include <unistd.h>
# include <sys/socket.h>
# include <sys/types.h>
# include <string.h>
# include <netinet/in.h>
# include <stdio.h>
# include<stdlib.h>

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

main(){
int sockfd,retval,n;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
char buf[10000];
int i;

sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sockfd < 0){
perror("sock:");
exit(1);
}
clilen = sizeof(struct sockaddr_in);
while(1){
printf(" before recvfrom\n");
n=recvfrom(sockfd,buf,10000,0,(struct sockaddr *)&cliaddr,&clilen);
printf(" rec'd %d bytes\n",n);

struct iphdr *ip_hdr = (struct iphdr *)buf;

printf("IP header is %d bytes.\n", ip_hdr->ihl*4);

for (i = 0; i < n; i++) {
printf("%02X%s", (uint8_t)buf[i], (i + 1)%16 ? " " : "\n");
}
printf("\n");

struct icmphdr *icmp_hdr = (struct icmphdr *)((char *)ip_hdr + (4 * ip_hdr->ihl));

printf("ICMP msgtype=%d, code=%d", icmp_hdr->type, icmp_hdr->code);
}
}

现在,如果我运行它并 ping 127.0.0.1:您会看到如下输出:

 before recvfrom
rec'd 84 bytes
IP header is 20 bytes.
45 00 00 54 00 00 40 00 40 01 3C A7 7F 00 00 01
7F 00 00 01 08 00 A9 DF 11 66 00 01 9A 77 1A 51
00 00 00 00 BA 1D 0F 00 00 00 00 00 10 11 12 13
14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23
24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33
34 35 36 37
ICMP msgtype=8, code=0 before recvfrom
rec'd 84 bytes
IP header is 20 bytes.
45 00 00 54 8D F3 00 00 40 01 EE B3 7F 00 00 01
7F 00 00 01 00 00 B1 DF 11 66 00 01 9A 77 1A 51
00 00 00 00 BA 1D 0F 00 00 00 00 00 10 11 12 13
14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23
24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33
34 35 36 37
ICMP msgtype=0, code=0 before recvfrom

此处显示了 msgtype 8(回显请求)和 msgtype 0(回显回复)。请注意,当以这种方式从数组访问数据时,您可能会遇到对齐问题(x86/x64 很乐意为您处理它,但其他架构可能不会那么慷慨)。我将把它作为练习留给读者 ;)。

关于c - 如何使用 RAW 套接字嗅探所有 ICMP 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14837453/

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