1

Im creating a network scanner batch script that basically pings 192.168.0.x with x from 0 to 255.

One of the major problems im facing is how long it takes to finish the scan, so I decided to change the timeout length using the -w option on ping.

@echo off
title Net Scan

for /f "tokens=1-2 delims=:" %%a in ('ipconfig^|find "IPv4"') do set ip=%%b
set ip=%ip:~1,-3%

for /l %%i in (0,1,255) do ping -n 1 -w 250 %ip%%%i | FIND "TTL="
pause 

The issue is any -w value below the ~500 millisecond mark won't make the timeout period any shorter, Making me believe that effectively there's a lower bound on the timeout values for ping. I havent found any articles about this online, and "ping /?" doesent answer my question

aschipfl
  • 33,626
  • 12
  • 54
  • 99
PedrosoFV
  • 41
  • 8
  • 3
    You've sort of answered your own question here. There's no official documentation anywhere (that I'm aware of), but timeouts under 500 milliseconds round up to 500 milliseconds. – SomethingDark Oct 21 '20 at 04:08
  • There is some overhead and variation to every time you instantiate ping, and the 1 ping only is very wonky on its timing, I usually use 200 ms, but it can fluctuate from 100 ms to 500 ms when I do that, depending on factors unknown. Even setting it to 1 second with only 1 ping can cause it to take less than 1 second, which is strange. However its much more consistent for any multiple of 1000 there-after. That said if its only 255 addresses I use something similar, as its only a 4 minute wait, but if its something larger or speed is key I use parallel processing to dump the info to a file – Ben Personick Oct 21 '20 at 04:27
  • @SomethingDark Actually the ping timeout will fluxulate at less than 500 MS (usually 100 MS to 500 MS) so long as you do "One. Ping. Only" If you do 2+ pings it will fluxulate just Above 1 second per iteration. This is a common issue and has been for years. Further it's not clearly documented but the default timeout is 3s so forgoing -w xxxx is not any better. I have occasionally seen some systems where with TCP offload etc working beautifully this worked more as expected, so ymmv. Test for yourself `ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 100 10.180.7.10 >NUL&echo=!time!` (need to `cmd /V` ofc. ) – Ben Personick Oct 21 '20 at 04:38
  • You could ping multiple targets in parallel, so the timeout value and the retry interval will no longer be a problem; take a look at the following posts of mine: [Arrange the pinging of multiple website in order with batch?](https://stackoverflow.com/a/50840684) and [Improving Batch File for loop with start subcommand](https://stackoverflow.com/a/40964527) – aschipfl Oct 21 '20 at 09:23
  • 1
    @SomethingDark Yep, I just wanted to make sure. Since there was no documentation I figured it would be better to ask here. – PedrosoFV Oct 21 '20 at 11:37
  • @BenPersonick Thanks for the info + workarounds! It helped a lot :) Also im not sure why my question has been closed for being off topic, I guess stack overflow doesent like discussions about more general issues like this one – PedrosoFV Oct 21 '20 at 11:45
  • 1
    Glad to help! Been This is an issue with questions like this on stack exchange, its "off topic" in part because the Q was a bit nebulous, but other nebulous questions do get answered here about behaviot, and in part because this is a mix between scripting, networking, and windows functionality. Probably they expect it to go on "superuser", but in general the more open ended a Question the more likely it will be considered off topic. If you need broader help you can always visit Experts Exchange where they will go ad far as writing a script for you. – Ben Personick Oct 21 '20 at 14:03

1 Answers1

1

This is a fairly well known issue with PING on a windows System.

When running PING with only 1 iteration it can behave unexpectedly, and even ping at LESS than 1 second on the 1st timeout, when the timeout is set to 1 second, which is more strange than the delay added, but not that uncommon (see below I captured one such example it he wild.).

The default timeout is also not stated clearly, but is 3 seconds.

You can test ping and see it behaving wildly with 1 ping set at any value less than 2 seconds, but really the matter seems to be that it can fluxuate by about 500 MS above the value expected due to overhead in instantiating the ping command and calling the TCP/IP stack etc.

I have worked with systems I set up with 10g NICs on a port agg to a nexus switch offloading most of the TCP/IP work to the physical card where the value specified to ping didn't have almost any issue with the timeout.

However I have found that wrapping the PING command inside of a For /F loop will actually reduce the time needed to execute the pings noticeably making it more likely to be.

The only Other alternative is to spawn many parallel command windows, echo the results to a file and then read it, which is still faster.

You can test on the CLI by running this:

echo=%time%&ping -n 1 10.180.7.10>NUL&CALL echo=^%time^%

Note that Ping behaves much more consistently at -n 2 and greater, or with 2000 MS timout or greater.

There the default will be 1 second between timeouts with a fluxulation of x milliseconds, usually the fluxation is much smaller about 100 - 200 ms.


here are some examples from a VM I have:

Cherry Picked:

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 10 10.180.7.10 >NUL&echo=!time!
 0:19:35.16
 0:19:35.45
 (300 MS per ping)

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 1000 10.180.7.10 >NUL&echo=!time!
 0:21:49.29
 0:21:49.95
 (660 MS per ping)

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 1000 10.180.7.10 >NUL&echo=!time!
 0:22:41.45
 0:22:42.45
 (1000 MS per Ping)

C:\Windows\system32>ECHO=!TIME!&Ping -n 2 -l 1 -4 -w 1 10.180.7.10 >NUL&echo=!time!
 0:19:57.54
 0:19:59.45
 (1910 MS - AKA: 955 MS per Ping)

C:\Windows\system32>ECHO=!TIME!&Ping -n 10 -l 1 -4 -w 10 10.180.7.10 >NUL&echo=!time!
 0:18:33.11
 0:18:46.96
 (13850 MS - AKA: 1385 MS per Ping)

C:\Windows\system32>ECHO=!TIME!&Ping -n 10 -l 1 -4 -w 1 10.180.7.1 >NUL&echo=!time!
 0:20:33.93
 0:20:42.99
 (9060 MS - AKA: 906 MS per ping)

Larger Set:

C:\Windows\system32>cmd /v
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

C:\Windows\system32>ECHO=!TIME!&Ping -n 10 -l 1 -4 -w 10 10.180.7.10 >NUL&echo=!time!
 0:18:33.11
 0:18:46.96

C:\Windows\system32>ECHO=!TIME!&Ping -n 10 -l 1 -4 -w 10 10.180.7.10 >NUL&echo=!time!
 0:19:12.39
 0:19:25.95

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 10 10.180.7.10 >NUL&echo=!time!
 0:19:35.16
 0:19:35.45

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 1 10.180.7.10 >NUL&echo=!time!
 0:19:43.61
 0:19:43.95

C:\Windows\system32>ECHO=!TIME!&Ping -n 2 -l 1 -4 -w 1 10.180.7.10 >NUL&echo=!time!
 0:19:57.54
 0:19:59.45

C:\Windows\system32>ECHO=!TIME!&Ping -n 2 -l 1 -4 -w 1 10.180.7.1 >NUL&echo=!time!
 0:20:14.24
 0:20:15.29

C:\Windows\system32>ECHO=!TIME!&Ping -n 10 -l 1 -4 -w 1 10.180.7.1 >NUL&echo=!time!
 0:20:33.93
 0:20:42.99

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 1 10.180.7.1 >NUL&echo=!time!
 0:20:57.54
 0:20:57.60

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 1 10.180.7.10 >NUL&echo=!time!
 0:21:08.76
 0:21:08.95

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 100 10.180.7.10 >NUL&echo=!time!
 0:21:43.01
 0:21:43.45

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 1000 10.180.7.10 >NUL&echo=!time!
 0:21:49.29
 0:21:49.95

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 2000 10.180.7.10 >NUL&echo=!time!
 0:22:22.54
 0:22:24.45

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 2000 10.180.7.10 >NUL&echo=!time!
 0:22:34.04
 0:22:35.95

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 1000 10.180.7.10 >NUL&echo=!time!
 0:22:41.45
 0:22:42.45

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 500 10.180.7.10 >NUL&echo=!time!
 0:22:53.92
 0:22:54.45

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 100 10.180.7.10 >NUL&echo=!time!
 0:23:01.53
 0:23:01.95

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 100 10.180.7.10 >NUL&echo=!time!
 0:23:05.81
 0:23:05.95

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 100 10.180.7.10 >NUL&echo=!time!
 0:23:08.98
 0:23:09.45

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 100 10.180.7.10 >NUL&echo=!time!
 0:23:12.93
 0:23:13.45

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 100 10.180.7.10 >NUL&echo=!time!
 0:23:19.37
 0:23:19.45

C:\Windows\system32>ECHO=!TIME!&Ping -n 1 -l 1 -4 -w 2300 10.180.7.10 >NUL&echo=!time!
 0:43:17.04
 0:43:18.95


A Faster alternatives

One faster alternative is to Wrap Ping in a For /F loop


@ECHO OFF
FOR /f "tokens=2 delims=:" %%a in ('
  ipconfig^|find "IPv4"
') do (
  FOR /f "tokens=1-3 delims=. " %%A in ("%%a") do (
    ECHO="%%a"_"%%b" ECHO="%%A"_"%%B"_"%%C"
    FOR /l %%L in (0,1,255) DO (
      FOR /F "Tokens=*" %%l IN ('
        ping -n 1 -w 100 %%A.%%B.%%C.%%L 
         ^| FIND /I /V "Pinging "
          ^| FIND /I /V "Ping Statistics FOR"
           ^| FIND /I /V "Packets: "
            ^| FIND /I /V "Approximate round trip "
             ^| FIND /I /V "Minimum = "
      ') DO (
        CALL ECHO. ^%%TIME^%% - %%A.%%B.%%C.%%L -- %%l
      )
    )
  )
)


Another Faster Alternative method to ping a large set of addresses is to parallelize the pinging and output to a file, and then type the contents


@ECHO OFF
FOR /f "tokens=2 delims=:" %%a in ('
  ipconfig^|find "IPv4"
') do (
  FOR /f "tokens=1-3 delims=. " %%A in ("%%a") do (
    ECHO="%%a"_"%%b" ECHO="%%A"_"%%B"_"%%C"
    FOR /l %%L in (0,1,255) DO (
      START CMD /C "ping -n 1 -w 100 %%A.%%B.%%C.%%L >>%%A.%%B.%%C.%%L_Ping.log"
    )
  )
)

timeout 10
for /R %%_ IN (*_Ping.log) DO (
  FOR /F "Tokens=*" %%l IN ('
    TYPE "%%~f_" | FIND /I /V "Pinging " | FIND /I /V "Ping Statistics FOR" | FIND /I /V "Packets: " | FIND /I /V "Approximate round trip " | FIND /I /V "Minimum = "
  ') DO (
    FOR /F "Tokens=1 delims=_" %%# IN ("%%~n_") DO (
      CALL ECHO. %%TIME%% - %%# -- %%l
    )
  )
)
Ben Personick
  • 3,074
  • 1
  • 22
  • 29