In this quick beginner tutorial, we will make a simple ping sweep Linux shell script to get a list of all reachable IPs in a given network. I will use Kali Linux for this tutorial, but since we’re using bash to create this script, this method applies to all other Linux distribution.
What is a Ping Sweep?
A Ping Sweep is a way of determining whether hosts are alive in a network by utilizing their assigned IP addresses. You can use a Ping Sweep shell script to check all the hosts’ status in a network at the same time.
For instance, let’s assume we have a class C network with the network ID 192.168.2 and subnet 255.255.255.0. In this network, we can have a maximum of 254 hosts. We could start pinging manually each of the 254 hosts [it will take “forever”] or use a simple bash script to instantly scan the reachability status of the hosts in this network.
How does Ping Sweep work?
The Ping Sweep script uses [as implied] the ping utility to scan a network for host IP reachability. To build a Ping Sweep script, we need to understand how the ping utility works first briefly – you will learn the basics on the way.
Let’s find the IP address of our machine first. To do that, type in the Linux terminal the following command:
The IP address for my computer eth0 interface is 192.168.2.7, as highlighted in the picture below:
Now let’s ping this address one time using the -c 1 count parameter and write the ping output to a file named ips.txt. The ips.txt file will be created automatically.
Note the -c 1 stands for count 1 and means we will use 1 packet only to ping an IP.
ping -c 1 192.168.2.7 > ips.txt
Let’s see how the ping output is written in the ips.txt looks like using the cat command.
Note: cat is a standard Unix utility that reads files sequentially, writing them to standard output. In other words, you can read the content of a file without opening it.
As you can see above, we ping 192.168.2.7 IP with a count of 1, and we got 64 bytes from 192.168.2.7: icmp_seq=1 ttl=64 time=0.018 ms reply from this host. This means the host is up and reachable.
But what happens if we ping an IP that is not assigned to any host? Let’s have a look.
I will just execute the same ping command used above, but this time we will target an IP that is not assigned to any host in this network. I will randomly choose the 192.168.2.77 IP address.
ping -c 1 192.168.2.77 > ips.txt
Since there is no host assigned to this IP, the output will show Destination Host Unreachable with […] +1 errors, 100% packet loss.
Let’s compare the output between the reachable IP 192.168.2.7 and the unreachable IP 192.168.2.77 and see the difference.
It looks different, right?
This is important because we need to find a way to filter the hosts that are “up” from those that are “down” in the ips.txt file. For that, let’s look for a string that’s unique to the hosts that are up: 64 bytes
We can use the grep command to search the ips.txt file and list only the IPs with a 64 bytes string in their response.
Note: grep is a utility that searches for patterns in a file and prints each line that matches that pattern. In the example below, we choose the “64 bytes” as a pattern.
cat ips.txt | grep “64 bytes”
The grep output listed only the host IP that matches the 64 bytes pattern in the ips.txt file.
Let’s narrow the output of the grep command further to show only the host IP address without any other information. To do that, we will use the cut command with a space delimiter -d and a field -f of that space set to 4 to cut the unnecessary information out.
cat ip.txt | grep “64 bytes” | cut -d “ “ -f 4
The output filters out the IP address and a “:”
To filter out the column “:” we can use the translate tr parameter with a delimiter -d “:” to filter out the unwanted column using the following command:
cat ip.txt | grep “64 bytes” | cut -d “ “ -f 4 | tr -d “:”
Create The Ping Sweep Linux Script
To create the shell script (.sh), I will be using nano text editor. Feel free to use any other text editor of your choice. We will create/save the Ping Sweep script on the Desktop.
To navigate to your Desktop folder, type in the terminal:
Let’s create a file named pingsweep.sh with nano. Alternatively, you can use any other text editor you are familiar with.
The first thing we need to do is instruct the operating system to use the bash as a command interpreter. To do that, we will start by adding the following at the very top of our script:
Note: #!/bin/bash is a hard-coded function that tells the Linux operating system to use bash as a command interpreter.
Next, we will proceed creating a for loop:
for ip in `seq 1 10` ; do ping -c 1 $1.$ip | grep "64 bytes" | cut -d " " -f 4 | tr -d “:” & done
`seq 1 254` = sequence starting from 1 to 254 [pay attention to the backticks “]
-c 1 = count 1
$1 = user input [the first 3 octets of the network in this case]
.$ip = the sequence starting with 1 to 254
-d = delimiter
tr = translate
& = allows multithreading [ping all the IPs at once]
Explanation: For every IP in sequence starting from 1 to 254, do a count one ping where the network address is the user input $1 [the first three octets of the network in this case and defined when running the script], and the .$ip is the ‘seq 1 254’. List only the lines containing the “64 bytes” pattern. The rest of the command is used to filter out the unnecessary ping information and is explained in the previous section.
The pingsweep.sh script should look like this:
Type Ctrl+X and Y when prompted to exit and save the pingsweep.sh file to your Desktop.
Run The Ping Sweep Linux Script
To run the Ping Sweep script, we need to make the pingsweep.sh file executable. To do that, type in the terminal:
chmod +x pingsweep.sh
To execute the pingsweep.sh script, type in the terminal:
./pingsweep.sh 192.168.2 > ips.txt
To view the content in the ips.txt file, type the following command in the terminal:
As you can see above, 192.168.2.1, 192.168.2.7, and 192.168.2.5 are the active IPs detected in my network.
Let’s make a slight improvement to the pingsweep.sh script in case you forget how to run it.
Add the following code after #!/bin/bash:
if [ “$1” == “” ] then echo “Type the IP address to scan.” echo “Example: ./pingsweep.sh 192.168.2” else
Explanation: If the user input “$1” is empty “” then print “Type the IP address to scan. E.g., ./pingsweep.sh 192.168.2” else, bypass the conditional statement above and execute the script.
To indicate the end of the inner “if” statement above, we need to add the keyword “fi” at the end of the script.
Finally, this is how your pingsweep.sh file should look like:
#!/bin/bash if [ “$1” == “” ] then echo “Type the IP address to scan.” echo “Example: ./pingsweep.sh 192.168.2” else for ip in `seq 1 254` ; do ping -c 1 $1.$ip | grep "64 bytes" | cut -d " " -f 4 | tr -d “:” & done fi
Ping Sweep Use-case Scenario
Alright. We created our first Ping Sweep shell script and scanned a network for active IPs, but what can we do further with this information?
For instance, we could use nmap to scan for a specific port e.g., TCP port 80, for every single active IP in the list. To do so, scan the network for active IPs using the pingsweep.sh and write the output to the ips.txt file using the command below:
./pingsweep.sh 192.168.2 > ips.txt
Scan the TCP port 80 for all active IPs in the ips.txt by executing the following line in the terminal:
for ip in $(cat ips.txt); do nmap -p 80 -T4 $ip & done
Explanation: For “ip” in the “ips.txt” file, run nmap, and scan the port “-p” 80 at speed “-T4” for every IP “$ip” simultaneously “&” and finish “done”.
The generated output for my case looks like this:
Many Ping Sweep software options out there can do much more than the script we built in this guide. However, in some situations, e.g., restricted systems with no internet access, knowing how to make your own Ping Sweep script can be handy.
If you found this tutorial helpful, please share it with your friends and colleagues. Drop me a comment below if you have any suggestions on how to improve this guide further.