当ICMP端口不可达时,recv()不会给予SOCKET_ERROR

8zzbczxx  于 2023-04-05  发布在  其他
关注(0)|答案(1)|浏览(134)
平台

Winows 11

我想做的

我正在使用rfc1122 - 3.2.2.1 Destination Unreachable编写一个UDP ping工具,这与Linux上的traceroute UDP模式相同。步骤如下:
1.向目标主机发送UDP数据包
1.目标主机接收UDP数据包(但在非服务端口上)
1.目标主机发回一个ICMP端口不可达数据包(类型3,代码3)
1.接收来自目标主机的ICMP端口不可达数据包

问题

根据Microsoft文档- recv,recv()在获取ICMP端口不可达时应该返回SOCKET_ERROR,但它没有。

检查

ICMP数据包实际上来了。(通过WireShark)

伪代码
int main(void)
{
    SOCKET sk;
    struct sockaddr_in dst_sockaddr;
    char buf[1280];
    int ret;

    /* specified the destination */
    dst_sockaddr.sin_family = AF_INET;
    dst_sockaddr.sin_port = MY_DST_PORT;  // a non-service port
    dst_sockaddr.sin_addr.S_un.S_addr = MY_DST_IP;

    /* create socket */
    sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    connect(sk, (struct sockaddr *)&dst_addr, sizeof(struct sockaddr_in));  // for using recv()

    /* send */
    send(sk, "hello", 5, 0);

    /* recv */
    ret = recv(sk, buf, sizeof(buf), 0);  // Blocked here!!
    printf("recv() returns %d\n", ret);

    closesocket(sk);
    return 0;
}
其他类似问题
  1. x/net/icmp: listen icmp in Windows not work properly
    不用于UDP套接字,它用于原始套接字。
  2. Windows UDP套接字:recvfrom()失败,错误为10054
    命令SIO_UDP_CONNRESET适用于Windows XP。
问题

如果我收到ICMP端口不可达的数据包,我想得到SOCKET_ERROR。是否有任何细节我错过了?或者一些套接字选项,IO控制我需要启用?感谢阅读我的问题。

ovfsdjhp

ovfsdjhp1#

可能的原因(在我的情况下):
ICMP不可达数据包被防火墙拦截(甚至WireShark也能捕获)
本案例的解决方案:
将此应用程序添加到防火墙白名单。
参考文献:
WireShark: Ethernet capture setup
Can firewall block packets visible in Wireshark?

相关问题