Today, I ran the traceroute program on a machine running FreeBSD. It failed once and again.
traceroute: sendto: Permission denied.
So I tried to ping. Ping failed, too. I then checked out the configuration of the firewall, which actually denied the pass through of ICMP packet. So I set it to allow ICMP pacakges to pass through the firewall. Ping worked as I expected. But traceroute still failed.
I was very confused, I tried to run the tcpdump to find out why. Tcpdump showed that traceroute was sending UDP packet. Oh, my gosh. I had always thought traceroute was implemented on ICMP. After I read the tcpdump manpage. I found traceroute default on using udp protocal, but user can switch to use icmp by indicating the -M icmp or -I(The capitalized i). Alternatively, you can also command traceroute to use raw packet of specified protocol for tracerouting by specifying -P(beware P is capitalized). When you use raw packet, the default protocol is 253 (rfc3692). So, I ran traceroute using the command as: traceroute -P ICMP www.the_host.com, everything worked fine.