【发布时间】:2018-03-05 00:46:40
【问题描述】:
我想发送 ICMP 消息并接收回显。我花了一周时间研究原始套接字并搜索参考。然后我写下面的代码保证发送ICMP消息成功,因为'socket'和'send'的返回是ok的(不是负1)。不幸的是,“recvfrom”什么也没收到,下面是我在 Windows 上的简洁代码:
#define _WIN32_WINNT 0x501
#include <stdio.h>
#include <ws2tcpip.h>
#include <winsock2.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#pragma comment(lib,"Ws2_32.lib")
WSADATA wsaData;
int main(int args, char *argv[]){
WSAStartup(MAKEWORD(2,2),&wsaData);
//**************icmp book******************/
typedef struct icmp_hdr {
unsigned char icmp_type;
unsigned char icmp_code;
unsigned short icmp_checksum;
unsigned short icmp_id;
unsigned short icmp_sequence;
unsigned long icmp_timestamp;
} ICMP_HDR;
ICMP_HDR *icmp = NULL;
char buffer[sizeof(ICMP_HDR) + 32];
icmp = (ICMP_HDR *)buffer; //
icmp->icmp_type = 8;
icmp->icmp_code = 0;
icmp->icmp_id = 1314;
icmp->icmp_checksum = sizeof(ICMP_HDR) + 32;
icmp->icmp_sequence = 0;
icmp->icmp_timestamp = GetTickCount();
memset(&buffer[sizeof(ICMP_HDR)],'@',32);
int my_socket = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
struct in_addr my_addr;
my_addr.s_addr = inet_addr("127.0.0.1");
// inet_aton(argv[1],&my_addr);
struct sockaddr_in sa_t;
sa_t.sin_family = AF_INET;
sa_t.sin_port = htons(0);
sa_t.sin_addr = my_addr;
int p = sendto(my_socket,buffer,sizeof(ICMP_HDR)+32,0,(struct sockaddr *)&sa_t, sizeof(sa_t));
printf("return : %d\n ------s: %d\n",p,my_socket);
int tmp_add = sizeof(sa_t);
char buf[1024];
recvfrom(my_socket,buf,1024,0,(struct sockaddr *)&sa_t,&tmp_add);
printf("receive is: %s\n",buf);
return 1;
}
当我编译并运行这段代码时,我的期望是“recvfrom”函数会接收到任何东西。
但是“recvfrom”中没有任何内容,我需要两天时间,在这里谢谢。
【问题讨论】:
-
获取tour、阅读How to Ask和minimal reproducible example。您发布的代码不是 MCVE。你的目标是什么操作系统?
-
您的防火墙状态如何?您正在向本地主机发送 ICMP 回显命令,它可能已配置为不回复这些命令。
-
您也没有检查
WSAStartup()调用的返回值。sendto()调用返回什么值? -
@jwdonahue 谢谢。第一:当我 ping 127.0.0.1 时它工作正常第二:正如我所说,'sendto()' 的返回不是减一,实际上它返回 268,再次感谢。
-
既然您似乎正在发送 ICMP 回显请求,那么标准 ping 命令 1) 是否有效并且 2) 在接收端显示数据包?我的猜测是内核正在拦截 ICMP 8 消息并在它到达用户空间之前对其进行处理。或许尝试其他 ICMP 消息类型?