Oct 19, 2023 7 min read

How to Identify IP Hosts in Linux

Table of Contents

It's a common task—finding out the systems that are alive on a TCP/IP network. Quite often, the computers already know. But we as humans are not privy to that information—unless we request it. This article and video demonstrate how to request the IP addresses of hosts that are alive on the network.

I'm going to demonstrate several ways to do this, including:

  • NMAP
  • ip neigh
  • fping
  • arp
  • for and while loops

📺 Check out the video below, and read on for the rest of the article.

Video

💻
For these demonstrations, I have three hosts in a virtualized network:

- Gateway: 10.0.2.1
- Debian Server: 10.0.2.51
- Debian Client: 10.0.2.52

I run the commands from the Debian Client virtual machine.

NMAP

For me, the best tool is nmap. I use it all the time. However, on most Linux distributions, it is not installed by default. So, we need to install it first. For example, on Debian/Ubuntu:

sudo apt install nmap

Replace apt with your distro's package manager (dnf, yum, pacman, etc...)

Once installed, you can scan entire IP networks or individual machines—or both!

For example, if I wanted to scan the entire 10.0.2.0/24 network, I might use the following command:

nmap -sn 10.0.2.1-255

Let's do that from a Debian Client computer that has the IP address 10.0.2.52.
Take a look at the results:

user@debian:~$ nmap -sn 10.0.2.1-255
Starting Nmap 7.93 ( https://nmap.org ) at 2023-09-26 06:09 EDT
Nmap scan report for 10.0.2.1
Host is up (0.00042s latency).
Nmap scan report for 10.0.2.51
Host is up (0.00040s latency).
Nmap scan report for 10.0.2.52
Host is up (0.00024s latency).
Nmap done: 255 IP addresses (3 hosts up) scanned in 6.98 seconds

This shows three hosts are alive at the following IP addresses:

  • 10.0.2.1 (the gateway for my virtualization network)
  • 10.0.2.51 (a Debian Server)
  • 10.0.2.52 (a Debian Client—the local system where I ran the nmap command)

Let's say that I wanted to find out more about the Debian Server, To scan an individual host, I would use the following command:

nmap 10.0.2.51

Easy! The results in this case look like this:

user@debian:~$ nmap 10.0.2.51
Starting Nmap 7.93 ( https://nmap.org ) at 2023-09-26 06:12 EDT
Nmap scan report for 10.0.2.51
Host is up (0.00058s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT   STATE SERVICE
22/tcp open  ssh

From the output, we can see that the Debian Server (10.0.2.51) has one port open—SSH, on port 22. Everything else is filtered out.

But that gets more into the security side of things. Keep in mind that we are only scratching the surface of NMAP. Practice with it!

🗒️
If you are interested in the NMAP program, I suggest checking out the NMAP creator's website and book.

ip neigh

This command is built into Linux and it's super-easy to use. Just type the command to see what systems are visible on the network. For example:

user@debian:~$ ip neigh
10.0.2.1 dev enp1s0 lladdr 52:54:00:a3:2f:ac REACHABLE 
10.0.2.51 dev enp1s0 lladdr 52:54:00:50:9c:4a STALE 

In this case, we see two systems: the gateway we mentioned before (10.0.2.1) and the Debian Server (10.0.2.51). You'll note that 10.0.2.1 is REACHABLE and that 10.0.2.51 is STALE. That means that we have been in communication with 10.0.2.1 in the recent past—which makes sense, it is the gateway, and so it will be contacted often. However, we have not been in communication with 10.0.2.51 in a while. The connection has become stale. But we can make it REACHABLE again simply by pinging the computer and then checking with ip neigh again.

user@debian:~$ ping 10.0.2.51
PING 10.0.2.51 (10.0.2.51) 56(84) bytes of data.
64 bytes from 10.0.2.51: icmp_seq=1 ttl=64 time=0.335 ms
64 bytes from 10.0.2.51: icmp_seq=2 ttl=64 time=0.252 ms
64 bytes from 10.0.2.51: icmp_seq=3 ttl=64 time=0.306 ms
^C
--- 10.0.2.51 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2037ms
rtt min/avg/max/mdev = 0.252/0.297/0.335/0.034 ms
user@debian:~$ ip neigh
10.0.2.1 dev enp1s0 lladdr 52:54:00:a3:2f:ac REACHABLE 
10.0.2.51 dev enp1s0 lladdr 52:54:00:50:9c:4a REACHABLE 

No mention of our local IP (10.0.2.52) because the command doesn't see that as necessary information—after all, we know who we are, right?

😁
That's a philosophical question best left to smarter minds!

Seriously, the command expects that a person using the computer knows the local IP. That's an example of Linux being Linux and only giving the information that is strictly needed. Contrast that with NMAP which doesn't assume anything.

👍
Of course, you can, and should, abbreviate. The ip neigh command can be abbreviated to ip n.

📚 Going a bit further: If you need to output just a portion of the ip neigh results, you could try the following:

ip neigh | awk '{ print $1}'

That will output the located IP addresses only. Export however you see fit!


💡
ip neigh is part of the ip command. "neigh" is actually an object of the ip command and is short for "neighbor". To find out more about the command, check out the manual page: man ip.

fping

Another tool similar to ip neigh. It must be installed (for example sudo apt install fping). This can be used to quickly identify if a host is alive, for example:

fping 10.0.2.1

Or it can check an entire network:

fping -g 10.0.2.0/24

To send only a single ping to all hosts on the network, while discarding unwanted information, try this:

fping -g -r 1 10.0.2.0/24 2>1 | grep "alive"

🗒️
For more information about fping, issue the command man fping, once installed.

arp

The arp command looks for hosts on the network and, if they exist, returns their IP address and corresponding MAC address. To use this deprecated command you'll need to install net-tools: sudo apt install net-tools. That gives you access to arp, route, ifconfig, netstat, and other older networking tools. In most Linux distros, you will need to issue the sudo command first. For example:

sudo arp 10.0.2.1

That will result in something similar to the following:

user@debian:~$ sudo arp 10.0.2.1
Address   HWtype  HWaddress           Flags Mask  Iface
_gateway  ether   52:54:00:a3:2f:ac   C           enp1s0

We find out the MAC address of our gateway, which is 52:54:00:a3:2f:ac.

You could also scan all systems that the computer has had contact with by using the -a or -e options. For example:

sudo arp -a

Which could result in something similar to:

user@debian:~$ sudo arp -a
_gateway (10.0.2.1) at 52:54:00:a3:2f:ac [ether] on enp1s0
? (10.0.2.51) at 52:54:00:50:9c:4a [ether] on enp1s0

The results might require a little bit of back story. ARP stands for Address Resolution Protocol. It resolves (or translates) between IP addresses and MAC addresses. IP addresses are logical and are assigned within the operating system. However, MAC addresses are "physical" and are stored in a ROM chip of the network interface card. Ultimately, the two have to work together to get our data out to the physical network. So we need to resolve between them.

The command shows the relationship. In the above example, the IP address 10.0.2.1 is using the MAC address 52:54:00:a3:2f:ac. Likewise, the IP address 10.0.2.51 (the Debian Server) has the MAC address 52:54:00:50:9c:4a. By default the arp -a command only shows active and known connections. You might have to ping or otherwise connect to a remote system to show it with an arp.

🗝️
As mentioned, arp is a deprecated command in Linux. You might have noticed that the ip neighbor command also shows resolved MAC addresses. Generally, that is what I would use first.

As always, to find out more information about the command, use the --help or man options.

for and while loops

You could also make use of for or while loops in Bash. For example:

for ip in $(seq 1 254); do ping -c 1 10.0.2.$ip>/dev/null; [ $? -eq 0 ] && echo "10.0.2.$ip UP" || : ; done

This will run a for loop that pings every IP address on the 10.0.2.0 network. Careful! These scripts could be time-consuming. For example, this command, run on one of my test networks with 20 or so hosts, took 12 minutes to complete. And that was only scanning 254 possible IPs. (The script could definitely be written better!)


👨🏻‍💻 TECH TIP: Use the time command before the for command to see how long it actually takes to run the for loop.


In cases such as these, I prefer the while loop. For an example of a while loop (with if-then-else statement) check out the SuperPing script I wrote here. Note that this particular script is not meant to find "any" hosts on the network. It is designed to determine whether a specific group of hosts are currently alive on the network.

💡
Remember this—there's always more than one way to do things in Linux. There are plenty of other methods that I didn't cover here: Python scripts, SED and AWK options, and lots of other Bash options. If the tools mentioned in this article don't satisfy your needs, you might need to build your own!
For me, Bash is usually best. Check out Bash Shell Scripting by Sander van Vugt on InformIT or on O'Reilly (subscription required).
👍
I hope you enjoyed this article!
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Prowse Tech.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.