traviscross / mtr

Official repository for mtr, a network diagnostic tool
http://www.bitwizard.nl/mtr/
GNU General Public License v2.0
2.66k stars 339 forks source link

Packet type unsupported #503

Closed gregewing closed 7 months ago

gregewing commented 7 months ago

Hi, I have a wierd one. for reasons I wont go into I have compiled using Cygwin, running in a windows 10 Vagrant (libvirt) box running in a docker container on an Ubuntu host.

When I try to get mtr to use TCP instead of ICMP, I get the message below:

mtr: Packet type unsupported: Not supported

and then the requested test does not run.

I'd really like to be able to run TCP tests, did I perhaps miss a dependency library?

matt-kimball commented 7 months ago

Only ICMP probes are supported on Windows, due to limitations of the Windows API.

rewolff commented 7 months ago

My guess is: MTR is reporting what the OS reports to MTR. MTR has to send out "slightly funny" packets and if windows refuses to send them out... That's tough luck and not much we can do about it.

gregewing commented 7 months ago

Only ICMP probes are supported on Windows, due to limitations of the Windows API.

bummer...

gregewing commented 7 months ago

My guess is: MTR is reporting what the OS reports to MTR. MTR has to send out "slightly funny" packets and if windows refuses to send them out... That's tough luck and not much we can do about it.

also bummer...

gregewing commented 7 months ago

Actually, the more I think about this this more unsure I am of what those responses mean... I'm also using iperf ( not compiled by me ) which is dependent on a different version of the cygwin1.dll, and it is quite capable of crafting tcp packets and putting them on the wire.

So is the API limitation mentioned above a limitation of how mtr was written, or something more generic? Can it be worked-around?

rewolff commented 7 months ago

iperf is not "crafting TCP packets". it is using the windows API to generate a TCP stream. In that case windows is building the TCP packets. Because we want "slightly odd" ones, we need to do that ourselves.

matt-kimball commented 7 months ago

To add to what Roger said - I wrote the Windows code. On Linux and other Unix-like operating systems, mtr uses a "raw" socket which allows it to build a packet's IP header and proto (ICMP / UDP) header itself, and also to read all ICMP packets received by the system. This second part is necessary, because when doing a trace, we determine which machines are at particular hops along the trace by causing the TTL field of the IP header to expire, which sends a TTL expired ICMP message back to the sender.

Under Windows, I was unable to successfully read all ICMP replies using the raw socket technique, even after spending much time attempting to do so. I'm not 100% sure why, since I couldn't find any documentation on it, but I think the Windows TCP/IP stack is filtering / redirecting ICMP replies such that it doesn't reach any application which has opened a raw socket. Perhaps this is done for security, as I recall many concerned commentary when it was announced that Windows XP would include a "raw" socket API. There is one exception to this filtering, however. If you use the API in icmpapi.h to send your outgoing pings, you will receive the ICMP replies for those. That API is documented here: https://learn.microsoft.com/en-us/windows/win32/api/icmpapi/

You'll notice that API only allows you to send outgoing ICMP packets - not TCP or UDP or anything else. That is the Windows API limitation I was referring to.

gregewing commented 7 months ago

Thank you for the very thorough and informative response.