我最近遇到了一个场景,我发现ICMP网络无法访问[类型1,代码-3意味着目标无法访问,这是正确的跟踪路由工作,请参阅下面的rfc链接]数据包被丢弃当发送的字节超过'X'[某些]字节。
**查看此RFC,第3.1节 - http://tools.ietf.org/html/rfc4443#section-3.1 **
例如[source:FreeBSD based trace route code],
i = sendto(sndsock, (char *)outpacket,outpacketlength, 0,
(struct sockaddr *)&Dst, Dst.sin6_len); // to send packet of length "outpacketlength", from source buffer "outpacket" and to destination "Dst".
...
retval = recvmsg(rcvsock, mhdr, 0); // use recvmsg for receiving reply.
当我malloc并发送'X'字节的数据时,我收到了接收缓冲区中的回复。但是,不超过该限制。即,当“outpacketlen”为更大的'X'字节时,retval始终为0,即使你malloc并将缓冲区重置为'X'字节。但是,通过数据包捕获,我看到我的主机收到的数据包。意思是,我接收数据包但不接收缓冲区。如何/何时可能[任何格式错误的数据包信息?]?
如何调试此问题?
是否有可用于调试此类场景的工具?我在BSD中使用了“truss”实用程序。是否有更好的处理方式?
我应该如何调查接口和应用程序之间丢失的数据包?根据您的经验,哪些工具/实用程序/技术是有效的选择?
我错过了什么吗?感谢您的时间和投入。我很感激。
答案 0 :(得分:1)
您需要使用Wireshark并调查是否正确发送数据包。在sendto
之前放置一个断点,看看会发生什么。
答案 1 :(得分:0)
您所指的数据包是“在接口和应用程序之间被删除”ICMP错误消息,目的地无法访问? ICMP错误通常不会传递给发送触发错误的数据包的应用程序。我猜的逻辑是,假定使用UDP或TCP的“常规”应用程序准备在其应用程序协议流中突然接收到各种ICMP错误。
你没有提到你的具体平台,但我假设(我的帽子)FreeBSD。在那个平台上,我认为你必须使用原始IP套接字,如果你想收到ICMP错误。我可能是错的,或者您可能使用其他BSD变体,因此请检查您的IP协议手册页以获取合适的套接字选项。
在Linux中,您可以通过设置IP_RECVERR
套接字选项然后使用标记recvmsg()
调用MSG_ERRQUEUE
来接收此数据包。参见例如Read ICMP payload from a recvmsg with MSG_ERRQUEUE flag