Quick Tip: Ping an IP Range From the Command Line

A few weeks ago I was finishing up some year-end infrastructure documentation and realized I had a wayward host on my network. Specifically, I’d lost a wireless access point. I had failed to document the access point’s IP address and wasn’t looking forward to aimlessly pinging hosts on my network and navigating to the hosts that responded in hopes of finding a web interface. While tools like Angry IP Scanner, which allows you to ping a pre-determined IP range and reports hosts that respond, exist for Windows I use OS X and CentOS daily and wanted a UNIX-native solution that would be reusable should I ever lose another host. With that goal in mind, I came up with a quick and dirty bit of shell script that’s nothing more than a simple for loop.

Let’s say we wanted to ping the entire usable address space on the 192.168.1.0/24 network and see which hosts responded. We could quickly do so with the following one-liner.

[bash]for x in {1..254}; do ping -c 1 192.168.1.$x | grep "from"; done[/bash]

For the sake of completeness we’ll examine the above code snippet in detail, looking at what each bit of code does and run through an execution example.

[bash]for x in {1..254};[/bash]

In this code snippet, we’re using brace expansion so the BASH interpreter will evaluate the expression inside the braces as 1 2 3 4 5 and so on. As the content of the braces is evaluated each numerical value passed through the for loop that was instantiated by the word for at the beginning of the line and assigned to the variable x.

[bash]do ping -c 2 192.168.1.$x | grep -i from[/bash]

In this code snippet. we’re executing a simple ping and specifying that a single packet (within a typical LAN there’s really no need to ping a machine more than once if you’re only interested in seeing if it’s alive or not) should be sent to each address that is passed in from the result of the earlier brace expansion. Additionally, we’re filtering the output of the ping command using grep and only outputting the ping statistics for those hosts that responded.

[bash]done;[/bash]

This simply terminates the for loop.

Let’s step through an example execution of the full code snippet:

  1. The BASH interpreter begins the for loop and assignes 1, the first value returned from the brace expansion, to the variable x.

  2. The variable x is passed into the ping command and yields 192.168.1.1 as $x is replaced with 1.

  3. The ping command executes and sends a packet to 192.168.1.1.

  4. The output of the ping command is filtered through grep and output is only sent to the screen if the the host at 192.168.1.1 responded to the ping.

  5. The for loop executes again with the value of 2 and the entire process happens again.

With this tool I was able to narrow a field of ~ 30 possibilites to 3 and find the rouge node quickly. Should you want to use this code against another network the target IP range can be easily changed by altering the values inside the braces and updating the first three octets of the address in the ping command itself.

//J

Leave a Reply

Your email address will not be published. Required fields are marked *