25

I just want to find out unused IP Address on a network. I think it is possible with nmap. Can any one say me the way pls?

Note:

I just need the free IP list alone.

2
  • Are there any additional requirements?
    – Sergey
    Oct 6, 2011 at 12:54
  • No more additional requirements. As of now i have found many IP address conflicts, i just want to find out the free ip address on a network and assign it.
    – karthick87
    Oct 6, 2011 at 15:48

6 Answers 6

26

A fast scanner is arp-scan which uses ARP to "see" other machines on a network. It also returns the MAC address and tries to determine the manufacturer of the network adapter.

Example usage (replace wlan0 by eth0 if needed):

$ sudo arp-scan -I wlan0 192.168.1.0/24
Interface: wlan0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.6 with 256 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.1.10    00:90:f5:33:e2:f2       CLEVO CO.
192.168.1.254   00:14:7f:72:cd:05       Thomson Telecom Belgium

2 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.6: 256 hosts scanned in 1.406 seconds (182.08 hosts/sec).  2 responded

Note that this utility only reports machines which are powered on. ping can be blocked, but arp-scan cannot be blocked since it's necessary for a machine to interact with other machines on a network. To be sure that an IP is unused, you'd better look at your router (for static/dynamic addresses) and DHCP server (for dynamic addresses).

5
  • I wanted to like this but it missed a couple hosts when I tested it?!? :( Oct 6, 2011 at 19:50
  • @bumblingfool: are you sure that the other hosts are on the same subnet? E.g. 192.168.1.x and not 192.168.2.x?
    – Lekensteyn
    Oct 6, 2011 at 19:52
  • Yes, all hosts are on the same subnet. I ran it a dozen more times and 2/3rds of the time all hosts showed up. Interestingly(?), it is always the same hosts that don't show up(if any)... This is on a wifi network but the signal is solid. Also, the above mentioned nmap method consistently doesn't miss any hosts. Oct 7, 2011 at 8:51
  • How many hosts are we talking about? Try increasing the delay between sending the packets using the -i parameter, e.g. -i 5 for 5 ms.
    – Lekensteyn
    Oct 7, 2011 at 9:36
  • 2/5. Increasing the delay did the trick. Thanks! Oct 7, 2011 at 11:04
15

sudo nmap -sP -PR 192.168.0.* (or whatever your network is) will do the trick.

To install it use sudo apt-get install nmap.

Source: serverfault.com.

Just tested this, works like a charm including obscured hosts, you need to add sudo to be able to use the -PR option.

6
  • 1
    I've just tested it an you need to run is as root (i.e. using sudo). Furthermore, it's probably blocked by the firewall as it also scans the ports of the host which also slows the search down.
    – Lekensteyn
    Oct 6, 2011 at 16:00
  • Read the original post plz, the 3rd comment explains how to not use the (unnecessary) port scan ;) Oct 6, 2011 at 17:32
  • You should include that in your answer then, not everyone wants to follow the sources. Also it'd be helpful to describe what the command actually does.
    – Lekensteyn
    Oct 6, 2011 at 17:35
  • done ;) works really nice. Oct 6, 2011 at 18:41
  • Havent tested (or ever used) arp-scan, thx for the sugestion! Oct 6, 2011 at 18:47
4

I find fping useful; among other things, it will ping a range of addresses and list which are 'alive' and which are 'unreachable'. fping is not installed by default.

sudo apt-get install fping

The simple approach is to just run it over a range of addresses.

fping -g 192.168.0.2 192.168.0.254 2>/dev/null

A bit more elaborately, to produce a list of unused IPs.

fping -g 192.168.0.2 192.168.0.254 2>/dev/null | grep 'is unreachable' | cut -d ' ' -f 1 | sort -t '.' -k 4 -n
2
  • 1
    Don't forget that this assumes the hosts respond to an ICMP Echo request (a.k.a. pings). Not every host does that, especially some MS Windows machines don't. Also firewalls usually disable this, even though they are online and have a MAC address in your network. This is a fast solution, but shouldn't be relied on in every situation.
    – eaydin
    Jul 22, 2017 at 9:08
  • You're right; a solution involving nmap, or some alternative to ping that can use protocols other than ICMP, would be more reliable.
    – bgvaughan
    Jul 24, 2017 at 17:02
3

I believe it is not the best solution but it does what you want. This script runs ping over 192.168.0.0/24 network and returns list of inactive IPs if there are not in ARP cache.

Advantages over previous solutions:

  • uses both methods: ping and ARP check
  • no need to run as root user
  • runs about 1.5min on my Core i3-2100

To scan your network run it with <first IP> <last IP> parameters.

#!/usr/bin/env python
from threading import Thread
import subprocess
from Queue import Queue

verbose = False

num_threads = 8
queue = Queue()
inactive_ips = [0 for i in range(256)]

lines = open("/proc/net/arp", "r").readlines()
arp_cache = [l.split()[0] for l in lines[1:] if l.split()[2] == "0x2"]

def ip_str_to_int(ip):
    ip = ip.rstrip().split('.')
    ipn = 0
    while ip:
        ipn = (ipn << 8) + int(ip.pop(0))
    return ipn

def ip_int_to_str(ip):
    ips = ''
    for i in range(4):
        ip, n = divmod(ip, 256)
        ips = str(n) + '.' + ips
    return ips[:-1] ## take out extra point


#wraps system ping command
def pinger(i, q):
    while True:
        ip_num = q.get()
        ip = ip_int_to_str(ip_num)
        if ip not in arp_cache:
            ret = subprocess.call("ping -c 1 %s" % ip,
                  shell=True,
                  stdout=open('/dev/null', 'w'),
                  stderr=subprocess.STDOUT)
            if ret != 0:
                  inactive_ips[ip_num % 256] = ip
        q.task_done()


if __name__ == '__main__':
    from optparse import OptionParser
    usage = "usage: %prog [options] [first IP] [last IP]"
    parser = OptionParser(usage=usage)
    parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="make lots of noise")
    parser.add_option("-q", action="store_false", dest="verbose", help="print only IP adresses")
    (options, args) = parser.parse_args()
    verbose = options.verbose

    first = ip_str_to_int(args[0] if len(args) > 0 else "192.168.0.1")
    last = ip_str_to_int(args[1] if len(args) > 1 else "192.168.0.254")

    if verbose:
        print "Scanning inactive network addresses from %s to %s" % (
            ip_int_to_str(first),
            ip_int_to_str(last))

    for i in range(num_threads):
        worker = Thread(target=pinger, args=(i, queue))
        worker.setDaemon(True)
        worker.start()

    for ip in range(first, last + 1):
        queue.put(ip)

    queue.join()
    for ip in inactive_ips:
        if ip:
            print ip

Update after downvote

I wrote it because nmap -PR 192.168.0.* did not work for me:

Starting Nmap 5.21 ( http://nmap.org ) at 2011-10-06 15:34 EEST
Nmap done: 256 IP addresses (0 hosts up) scanned in 0.03 seconds

Update 2

Fixed all the issues with ARP-cache.

10
  • 2
    What if a machine doesn't respond to ping? Does it mean the IP is not in use? Oct 6, 2011 at 12:30
  • @brunopereira81 I don't know any way to distinguish free IP from powered off host.
    – Sergey
    Oct 6, 2011 at 12:34
  • Not powered off, a computer's firewall can be configured to not respond to normal pings. That way you get no reply but that doesn't mean that the computer is off or that it doesn't have running services, its just ignoring normal pings. (I do not know the scenario relative to the question but) Imagine he pings a firewall/gateway that ignores his ping because its configured not to respond, he assumes that the IP is free so he uses it, behind that firewall/gateway can be X number of computers that just went down due to IP conflict! Oct 6, 2011 at 12:40
  • @brunopereira81 I know it is not ideal. That is why I call it "quick and dirty" :)
    – Sergey
    Oct 6, 2011 at 12:45
  • Good answer, I don't understand how downvoting such answer helps.
    – nikhil
    Oct 6, 2011 at 15:16
1

This should do it right in bash:

#!/bin/bash

#setting language variables for subshell making sure we grep for the right word
LC_ALL=C
LANG=C

# retrieve IP from user input
read -p "Input your network (example: 192.168.0): " my_net

for i in $(seq 1 254);
do 
  ip="$my_net.$i"
  check="$(ping -c1 "$ip")"
  if [ "$(grep "Unreachable" <<<"$check")" != "" ]
  then
    echo "$ip is unreachable"
  fi
done
0

i think it is simpler

# my_net define my Net_ID
my_net=192.168.1.
for i in `seq 1 254`;
do 
  ip="$my_net$i"
  ping -c2  $ip | grep "is unreachable" | cut -d" " -f1 &
done
2
  • You may want to have a look at your code. In my subnet it shows me all IPs even those which are taken.
    – Videonauth
    May 24, 2016 at 12:40
  • no , i test it and works fine for me , in fact you can't set those ip addresses are alive becuase i add grep "is unreachable" or if you live change it to grep -v time maybe work fine for you May 24, 2016 at 13:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .