I'm trying to write (my own primitive) traceroute command that would write out all IPs that packets are hoping through.
So I've put the ping command inside a for loop
#!/bin/bash
domain=${1-www.google.com}; #If no argument, then do www.google.com.
for ((i=1; i<=30; i++)) # max. 30 hops
do
ping -t $i $domain # I would later add "grep" to extract IPs
done
exit 0;
What is wrong with this script? All I get is 30 "Usage: ping [...]" replies.
EDIT: I see it: I've written $1 instead of $i. :o But don't you worry, I will most surely come back for help with grep! :rolleyes:
I've seen other scripts that used, say, -c 2, but I don't (really) understand why (yes, I looked at man ping).
In ICMP's first 8 bits I'll be getting #11 (TTL expired) and not #0 (ECHO_REPLY), which is what switch -c is referring to. Well, what is wrong with my "logic"?
ADD: Should I use -c 1 for each hop on the way, is that right?
How to find the right maximum TTL number? for example, pinging google.com it takes 14 hops. So, if I do the for loop 30 times, the last 16 IPs are all (almost) the same.
By the way you should check the ping option available for your OS version
(look at the -c option that let you ping a <count> times so the ping isn't "endless")
Hi ctsgnb,
the "default option" works also without the colon.
I'd be most grateful for any help on 2. question (on choosing max. TTL) ...
and of course any correction on my "thinking" in 1. point (on -c switch). :o
ADD: I think I should let ping run inside the for loop, until I'd get ECHO_REPLY, and then break the for loop.
PING www.l.google.com (209.85.135.99) 56(84) bytes of data.
From 209.85.253.26 icmp_seq=1 Time to live exceeded
--- www.l.google.com ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
Here should be the break-like statement: above is TTL_EXPIRED, below ECHO_REPLY. Is that right?
PING www.l.google.com (209.85.135.99) 56(84) bytes of data.
64 bytes from mu-in-f99.1e100.net (209.85.135.99): icmp_req=1 ttl=250 time=45.0 ms
--- www.l.google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 45.052/45.052/45.052/0.000 ms
So, for emulating traceroute it should be -c 1, right?
Can you help me with my 2nd question: how could I "break" from the for loop when above quoted change (from TTL_EXPIRED to ECHO_REPLY) occurred? Perhaps with a help from grep? How? :o
There isn't actual word "ECHO_REPLY" but a line that starts with "64 bytes from [...]" when the script reaches the target computer (eg. google.com). Now, how do you write an if statement like:
if (line starts with "64 bytes from [...]")
do
break;
fi
You're right, I should use while or until, but I don't know how to express the terminating if statement.
But I'm not pinging "the same thing", because I increase TTL in each iteration and get new servers where the packet "expires".
This is (almost) it:
#!/bin/bash
domain=${1-www.google.com}; #If no argument, then do www.google.com.
for ((i=1; i<=30; i++))
do
ping -c 1 -t $i $domain | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
done
exit 0;
Above script outputs this:
209.85.135.147 # target: google.com
192.168.1.1 # default gateway
209.85.135.147 # wrong
85.10.0.254
209.85.135.105 # wrong
95.176.241.10
209.85.135.106 # wrong
209.85.135.106 # wrong: twice in a row because the 4th hop returns all stars (* * *) as in built-in traceroute
85.10.0.73
209.85.135.105 # wrong
85.10.0.74
209.85.135.103 # wrong
212.18.32.97
209.85.135.99 # wrong
212.18.39.214
209.85.135.147 # target reached: all below are unnecessary PINGs
72.14.219.148
209.85.135.99
etc.
EDIT: Wait, I'm doing it wrong: I also pickup google's IP from each line "PING www.l.google.com (209.85.135.103) 56(84) bytes of data.". How do I exclude these IPs with grep?