RAW ICMP 套接字:recvfrom() 未接收任何数据
RAW ICMP socket: recvfrom() not recieving any data
以下代码是一个旨在发送 ICMP 回显请求和接收回复的程序。
/*
Forgive my lack of error handling :)
*/
SOCKET ASOCKET = INVALID_SOCKET;
struct sockaddr saddr;
struct sockaddr_in *to = (struct sockaddr_in *) &saddr;
struct sockaddr_in from;
int fromsize = sizeof(from);
std::string ip = "[arbitrary ip address]";
struct ICMP {
USHORT type;
USHORT code;
USHORT cksum;
USHORT id;
USHORT seq;
}*_ICMP;
char sendBuffer[sizeof(struct ICMP)];
char recvBuffer[256];
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
memset(&saddr, NULL, sizeof(saddr));
ASOCKET = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
// Configure timeout
DWORD timeoutmilsec = 3000;
setsockopt(ASOCKET, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeoutmilsec, sizeof(timeoutmilsec));
to->sin_family = AF_INET;
inet_pton(AF_INET, ip.c_str(), &(to->sin_addr));
_ICMP = new ICMP();
_ICMP->type = 8;
_ICMP->code = 0;
_ICMP->cksum = 0;
_ICMP->id = rand();
_ICMP->seq++;
// I have omitted my declaration of checksum() for simplicity
_ICMP->cksum = checksum((u_short *)_ICMP, sizeof(struct ICMP));
memcpy(sendBuffer, _ICMP, sizeof(struct ICMP));
if (sendto(ASOCKET, sendBuffer, sizeof(sendBuffer), NULL, (sockaddr *)&saddr, sizeof(saddr)) == SOCKET_ERROR)
{
printf("sendto() failed with error: %un", WSAGetLastError());
return false;
}
if (recvfrom(ASOCKET, recvBuffer, sizeof(recvBuffer), NULL, (sockaddr *)&from, &fromsize) == SOCKET_ERROR)
{
if (WSAGetLastError() == TIMEOUTERROR)
{
printf("Timed outnn");
return false;
}
printf("recvfrom() failed with error: %un", WSAGetLastError());
return false;
}
我的问题是我的recvfrom()
调用没有收到任何数据并返回超时错误(10060(,尽管ping已被回复(Wireshark捕获请求并发送回复(。 sendto()
有效,但recvfrom()
行为奇怪,我无法弄清楚问题出在哪里。
我觉得有趣的是recvfrom()
只有当网关告诉我主机无法访问时,它才会接收数据;如果主机可访问并且响应了ping,则不会接收数据。
问题出在struct ICMP
.
ICMP的type
和code
应unsigned char
。
ICMP 的标头应为 8 字节,但 struct ICMP
的大小为 10 字节。
所以应该改为:
struct ICMP {
unsigned char type;
unsigned char code;
USHORT cksum;
USHORT id;
USHORT seq;
}*_ICMP;
事实证明,整个过程中都是我的防火墙阻止了响应。我的代码中唯一的错误是我的 ICMP 结构的大小(由 cshu 提到(。
感谢大家的帮助。
相关文章:
- 从输入中删除重复项,而不使用任何数据结构
- 有没有办法在函数 c++ 中输入任何数据类型?
- 我们可以直接为任何数据成员赋值. 为什么要使用构造函数?
- glGetBufferSubData() 不返回任何数据?
- 字符串流在清除后不接受任何数据
- GLSL 计算着色器 使用查找表设置缓冲区会导致不写入任何数据,与其他数据设置相同的缓冲区有效
- C 通用函数以除以任何数据类型
- 我可以通过向量附加特征矩阵而不复制任何数据
- 是否有任何数据类型或方法可以计算当前单元格中先前数组单元格的总和
- 将任何数据类型/对象作为参数传递以确定其大小
- 是否要确保一个线程修改的任何数据类型的共享变量对其他线程可见
- RAW ICMP 套接字:recvfrom() 未接收任何数据
- stl 中是否有任何数据结构可以在 O(1) 或 O(log n) 中插入元素,我可以在其上编写自己的bin_searc
- 为什么我的C++ ZeroMQ 订阅者没有收到任何数据
- Adafruit Fona与echo服务器建立连接,但不发送任何数据
- 为什么字符串变量"sum"不存储任何数据,程序不给出任何输出
- 难以创建可以容纳任何数据类型的模板通用向量
- 没有任何数据成员的类会导致内存泄漏吗?
- 引用计数(不存储任何数据)
- CLOB 不包含任何数据