Traceroute transmits packets with small TTL (Time To Live) values. The TTL is an IP header field that is used to prevent packets from running into endless loops. When a router that handles the packet subtracts one from the packet‘s TTL. The packet expires and it‘s discarded when the TTL reaches zero.
Traceroute sends ICMP Time Exceeded messages, (RFC 792 ), back to the sender when this occurs. By using small TTL values, the packets will quickly expire, so traceroute causes all routers along a packet‘s path to generate the ICMP messages that identify the router.
For example, TTL = 1 should produce the message from the first router, TTL = 2 generates a message from the second router in the path , and so on...
问题和解决办法
If you’re using a *nix or BSD-based operating system and trying to use traceroute
at home behind a NAT router, you probably have problems with intermediate routers timing out, i.e.:
3 * * * 4 * * * 5 * * * 6 * * *
Furthermore, you may have also noticed that Windows’ tracert
program doesn’t have this problem. The Unixtraceroute
program uses a bunch of UDP packets on a bunch of client ports to do its magic , whereas tracert uses ICMP packets, which I guess would have to be port forwarded on your router normally . Regardless, the solution is to use:
traceroute -I targethost.com
This forces traceroute
to use ICMP packets the way the Windows program does. Amazing! I’m sure there’s a downside to this approach, but so far it works like a charm.
traceroute 有
使用两种:使用ICMP的和使用UDP的。
Microsoft使用ICMP,所以win95上发出的traceRT应使用的是ICMP,但我没有用 sniffer查过;其它包括unix和cisco router都使用UDP.
ICMP traceroute :
===========
使用ICMP Echo Request , Echo Reply and TTL-expired .
源发出 ICMP
Equest,第一个request的TTL为1,第二个request的TTL为2,以后依此递增直至第30个;中间的router送回ICMP TTL-expired ( ICMP type 11)通知source,(packet同时因TTL超时而被drop),由此source知晓一路上经过的每一个router;最后的 destination送回ICMP Echo Reply 。
所以中间任何一个router上如果封了ICMP Echo Request , traceroute就不能工作 ;如果封了type 11 (TTL-expired), 中间的router全看不到 ,但能看到packet 到达了最后的destination;如果封了ICMP Echo Reply,中间的全能看到,最后的destination看不到 。
UDP traceroute:
==========
使用ICMP TTL-expired (type 11), ICMP port unreachable (type 3, code 3), UDP
port >32768 .
source发出UDP packet, source port使用随机的任何大于32768的高段port, destination port从33434开始每送个probe依此递增,直至33434+29,(cisco router上使用extended-traceroute命令可以修改这个起始的33434 port #),
同时TTL从1开始依此递增,直至1+29=30(最多送30个probe)。中间的router送回 ICMP TTL-expired,使得source得知了中间的每一个router,最后的destination送回TTL-expired 和ICMP port unreachable (因为任何主机上都没有应用使用UDP port# >32768这样的高段port )。
所以中间某处封掉UDP port>32768回导致traceroute不工作 ;封掉TTL超时会使source看不到中间的router(有的router根本不支持回送TTL超时);封掉type3 code3可能看不到destination .
另外需要知道的是,由于回送TTL-expired的信息需要CPU生成一个packet,必须打断 CPU,为保证其它工作的正常进行,cisco router每隔一秒才处理traceroute ,所以在source 上你可能看到中间一路 * * *,但却看得到最后的destination. 这时你应知道这是中间的router CPU太忙或者中间路由器不回送TTL-expired包的原因 ,不必大惊小怪的。:-)
下面是我自己的问题终于得到了解答:
在虚拟机的red hat上使用nat方式上网:
到百度2跳就到了。
然而使用windows公网来:
要9跳才完成。。。
分析如下:
windows中的tracert和linux中的traceroute -I,都是使用icmp协议,但是linux是在虚拟机的nat路由器后面,个人估计在收到linux上的ip包时候,nat路由器在替换ip头的时候没有考虑tracert这个功能,直接换了,然后直接传递到目的地址,目的地址有一个icmp echo Reply.从而我2跳就到了。。。
如果在linux上使用traceroute,默认使用udp协议,除了第一跳,剩下的都是* * *。八成是因为虚拟机nat 路由器,默认丢弃port>32767的包。 所以一切都解释了。圆满了。
来自:http://blog.csdn.net/lhq9220/article/details/6436984