60

Constraints:
1. Speed matters.
2. I am allowed to ping once.

I'm debating whether to use Python or shellscripting. Is there a method faster than bash?

Here is the current code,

for ip in $(seq int1 int2); do
    ping -c 1 xxx.xxx.xxx.$ip | grep "bytes from" &
done

Anything faster than this?

  • Refer to d3v3l's answer [here](http://stackoverflow.com/questions/733418/how-can-i-write-a-linux-bash-script-that-tells-me-which-computer-are-on-in-my-l). – Sunny R Gupta Dec 26 '12 at 09:45

10 Answers10

108

You should use nmap:

nmap -T5 -sn 192.168.0.0-255
nmap -T insane -sn 192.168.0.0-255 # same as above but w/named template

The -T 5/insane option uses the "insane" template, which:

insane mode assumes that you are on an extraordinarily fast network or are willing to sacrifice some accuracy for speed. -T4 (aggressive) prohibits the dynamic scan delay from exceeIf you are on a decent broadband or ethernet connection, I would recommend always using -T4. Some people love -T5 though it is too aggressive ding 10 ms for TCP ports and -T5 (insane) caps that value at 5 ms. If you are on a decent broadband or ethernet connection, I would recommend always using -T4. Some people love -T5 though it is too aggressive for my taste.

The -sn option means "no port scan":

This option tells Nmap not to do a port scan after host discovery, and only print out the available hosts that responded to the host discovery probes. This is often known as a “ping scan”, but you can also request that traceroute and NSE host scripts be run. This is by default one step more intrusive than the list scan, and can often be used for the same purposes. It allows light reconnaissance of a target network without attracting much attention. Knowing how many hosts are up is more valuable to attackers than the list provided by list scan of every single IP and host name.

Elijah Lynn
  • 12,272
  • 10
  • 61
  • 91
Roman Newaza
  • 11,405
  • 11
  • 58
  • 89
  • Thanks. Didn't think about this. Would there be a fast way to do this in Python as well? Seems everything I find is almost a page long. –  Dec 26 '12 at 10:15
  • 6
    I see no reason you need Python for this task. – Roman Newaza Dec 26 '12 at 10:27
  • Tried this one. It's really cool 'cause nmap automatically filters hosts that are up and it gives you host type + MAC Address. Excellent. Thanks also for explaining about Python. Taking a pentest course where they suggest to use higher level languages. But the goal is speed here. –  Dec 28 '12 at 08:17
  • You can run nmap command from python using result=subprocess.Popen() command to run shell code from command line. – Prabhu Aug 03 '13 at 21:14
  • 3
    As mentioned below, you can speed up the nmap ping scan by adjusting the timeout. On a local network with low latency you can use `nmap -T5 -sP 192.168.0.0/24`. It goes from 25 sec. to 2 sec. for a /24 subnet. – ripat May 30 '15 at 05:52
  • 7
    The `-sP` flag (no port scan) has been renamed to `-sn`, quote from `man nmap`: _"In previous releases of Nmap, -sn was known as -sP"_ – Ronny Andersson Oct 19 '15 at 14:02
  • Thanks, I just updated `-sP` to `-sn`. – Elijah Lynn Jan 20 '23 at 19:08
55

The following (evil) code runs more than TWICE as fast as the nmap method

for i in {1..254} ;do (ping 192.168.1.$i -c 1 -w 5  >/dev/null && echo "192.168.1.$i" &) ;done

takes around 10 seconds, where the standard nmap

nmap -sP 192.168.1.1-254

takes 25 seconds...

Mike Redrobe
  • 1,248
  • 13
  • 12
  • 2
    Thank you, that was answered but yes that is the best answer :) –  Feb 18 '14 at 17:25
  • 3
    You can adjust timeouts and nmap will be very fast. – Daniele Vrut Dec 08 '14 at 09:57
  • 1
    It seems like this is sequentially trying each IP in the network one after the other in series, which seems fundamentally slow. The 5ms timeout (`-w 5`) makes it loop quickly but it's possible that a valid host on a network might take longer than that to respond, so this might lead to false negatives. You could adjust this to some higher values but that would obviously make it much slower. – Hartley Brody Sep 23 '17 at 16:46
  • 5
    No, it is actually doing 255 pings in parallel (that's why it's evil!). The & symbol at the end means 'do in background' without waiting. – Mike Redrobe Sep 24 '17 at 20:45
  • why is this not the best answer? "Roman Newaza" answer is too slow. It shouldn't even be a suggestion. At the very least make the function work like this answer so it isn't useless. – moeiscool Mar 07 '18 at 17:09
  • 4
    Added benefit of the evil answer ... nmap is not always installed by default. – jwal Apr 14 '18 at 02:14
  • This works extremely well and quickly. Some networks have been banning nmap from even running on them. – Terrance Jul 17 '18 at 18:49
  • 1
    Use capital w ("-W") for macos/BSD – beauk Dec 12 '18 at 05:12
  • Also, nmap is not installed on all corporate workstations where as ping usually seems to be - presumably, for support staff troubleshooting. – Tony Barganski Dec 17 '18 at 17:05
  • Thanks a lot for this somewhat dirty, but available everywhere solution! – 0x01 Mar 12 '19 at 12:15
  • This is great! However, shall You find yourself on a macos system, just drop `-w 5` – Filip Paczyński May 04 '21 at 20:03
  • For older bash versions i needed to change the range statement and rearange the ping command to look like this: `for i in $(seq 1 254) ;do (ping -c 1 -w 5 192.168.0.$i >/dev/null && echo "192.168.0.$i" &); done` – Flo Nov 02 '22 at 09:11
  • If you need speed then remove `echo` - `for i in {1..254} ;do (ping 192.168.0.$i -c 1 >/dev/null &) ;done` – Lem Aug 12 '23 at 17:46
14

Try this for a unique list.

ping -c 5 -b 10.10.0.255 | grep 'bytes from' | awk '{ print $4 }' | sort | uniq

another method (fetches live hosts):

fping -ag 192.168.1.0/24

Sunny R Gupta
  • 5,026
  • 1
  • 31
  • 40
  • 1
    Thank you Sunny. Using fping seems appealing. I will try tomorrow when I connect to the lab. –  Dec 26 '12 at 10:14
  • 2
    Sunny, thank you for your help :). The first command took a while to execute even though I liked the fact that you used awk. The second command was better and I like the output with -ag which was cool. However, for the test that I am doing speed is crucial. So far nothing I tried could beat nmap. So I placed a like on your answer, but I am selecting Roman's because it was the one that helped the most, speed-wise. Tks for helping. –  Dec 28 '12 at 08:34
  • 1
    That failed to work for me. -w was not an option. I did get it working this way though `for i in {1..254}; do (ping -vc 1 -t 4 192.168.1.$i); done` – davidcondrey Dec 26 '16 at 23:53
5

Try both of these commands and see for yourself why arp is faster:

PING:

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

ARP:

for ip in $(seq 1 254); do arp -n 10.185.0.$ip | grep Address; [ $? -eq 0 ] && echo "10.185.0.$ip UP" || : ; done

Community
  • 1
  • 1
1

This is python code for the ping in range of the 192.168.0.0-192.168.0.100. You can change for loop as you comfort.

# -*- coding: utf-8 -*-
import socket
import os
import sys

up_ip =[] #list to store the ip-addresses of server online
for x in range(100):  #here range is 0-100. You can change the range according to your comfort

    server_ip = '192.168.0.'+ str(x)
    print "Trying ,server_ip,... \n"

    rep = os.system('ping -c 1 ' + server_ip)

    if rep == 0:
        up_ip.append(server_ip)
        print '******************* Server Is Up **************** \n'
    else:
        print 'server is down \n'

print up_ip
Rohan Bari
  • 7,482
  • 3
  • 14
  • 34
Vilas Joshi
  • 309
  • 2
  • 7
1

If time matters (and I know the feeling):

for i in {1..254}; do
echo -n -e "$i      \r"     
timeout --preserve-status .2  ping -c1 -q 10.0.0.$i  &> /dev/null
[ $? -eq 0 ]&&echo 10.0.0.$i is happy to serve to his master!
done # as I am

The command:

timeout --preserve-status .2  ping -c1 -q 10.0.0.107 &> /dev/null  ;echo $? 

returns 143 with non-existing PC and 0 with existing PC and waits for the answer just and only for .2 second because TIME MATTERS! And therefore I have to look for my lost keys now.

xerostomus
  • 466
  • 4
  • 11
1
subnet="182.17.207"
fun(){
       ip="$subnet.$1"
       res=`ping -c 1 $ip | grep "1 packets transmitted, 1 received" | wc -l`
       if [ $res == 1 ]
       then
           echo "$ip => live"
       fi
}
for i in $(seq 1 254)
do
   fun $i &
   sleep 0.005
done
sleep 0.5
echo

Fast using linux fork, sleep is optional .. just to print in order.

NotTooTechy
  • 448
  • 5
  • 9
0

This script runs on Git Bash (MINGW64) on Windows and return a messages depending of the ping result.

#!/bin/bash
#$1 should be something like "19.62.55"

if [ -z "$1" ]
  then
    echo "No identify of the network supplied, i.e. 19.62.55"
else
    ipAddress=$1

    for i in {1..256} ;do 
    (
        {
        ping -w 5 $ipAddress.$i ; 
        result=$(echo $?);
        } &> /dev/null


        if [ $result = 0 ]; then
            echo Successful Ping From : $ipAddress.$i
        else
            echo Failed Ping From : $ipAddress.$i
        fi &);
    done

fi
Diego4016
  • 31
  • 7
0

BSD's

for i in $(seq 1 254); do (ping -c1 -W5 192.168.1.$i >/dev/null && echo "192.168.1.$i" &) ;done

  • 1
    I doubt that this helps or even works at all. To convince me otherwise please add an explanation how this works and why it is supposed to help. – Yunnosch May 13 '20 at 20:52
0

I really like the original reply but it did not give me the sequential sequence I was looking for.

I approached this a little different and it works great:

for ip in {int1..int2} 
do
    ping -c 1 xxx.xxx.xxx.$ip | grep "bytes from"
done
James Risner
  • 5,451
  • 11
  • 25
  • 47