Skip to content

How to Get the TTL of a Ping Reply in Batch Script

Learn how to extract and analyze TTL (Time To Live) values from ping replies in Windows Batch scripts to identify OS types, calculate network hops, and detect routing changes.

The TTL (Time To Live) value in a ping response is a deeply useful piece of network metadata. While most people ignore it, the TTL tells you two critical things: how many "hops" (routers) the packet passed through to reach the target, and what operating system the remote machine is likely running. For example, a TTL of 128 usually indicates a Windows machine, while 64 indicates Linux/Mac/IoT. A Batch script can extract this number to help you identify mystery devices on your network or verify the complexity of a network path.

This guide will explain how to parse and extract the TTL value from a ping.

Method 1: The "Simple Extraction" (FOR Loop)

We can use the find command to isolate the line containing the TTL and then use a FOR loop to grab the specific numeric value.

@echo off
setlocal enabledelayedexpansion

set "Target=8.8.8.8"

echo [PING] Querying %Target%...
echo.

set "ResultTTL="

:: Extract TTL directly
for /f "tokens=2 delims==" %%A in ('ping -n 1 -w 2000 %Target% ^| findstr "TTL="') do (
    for /f "tokens=1 delims= " %%B in ("%%A") do (
        set "ResultTTL=%%B"
    )
)

:: Validate result
if not defined ResultTTL (
    echo [ERROR] No TTL received. Host may be unreachable or blocking ICMP.
    pause
    exit /b 1
)

echo Detected TTL: !ResultTTL!
echo.

:: OS Guess + Hop calculation
set "hops=Unknown"

if !ResultTTL! GEQ 129 (
    echo [OS Guess] Likely a ROUTER or SWITCH (default TTL 255^)
    set /a hops=255-!ResultTTL!
) else if !ResultTTL! GEQ 65 (
    echo [OS Guess] Likely WINDOWS (default TTL 128^)
    set /a hops=128-!ResultTTL!
) else if !ResultTTL! GEQ 1 (
    echo [OS Guess] Likely LINUX / UNIX / macOS (default TTL 64^)
    set /a hops=64-!ResultTTL!
) else (
    echo [INFO] Could not determine OS from TTL.
)

echo [HOPS]    Approximately !hops! router(s) between you and %Target%

pause
endlocal

Method 2: Hop Count Calculator

TTL decreases by 1 for every router it passes through. If you know the default TTL of the remote machine, you can calculate the exact number of hops.

@echo off
setlocal enabledelayedexpansion

set "Target=8.8.8.8"

echo [AUDIT] Calculating hop count to %Target%...
echo.

set "ttl="

:: Extract TTL (simplified & more reliable)
for /f "tokens=2 delims==" %%A in ('ping -n 1 -w 2000 %Target% ^| findstr "TTL="') do (
    for /f "tokens=1 delims= " %%B in ("%%A") do set "ttl=%%B"
)

if not defined ttl (
    echo [ERROR] No reply from %Target%.
    pause
    exit /b 1
)

echo Received TTL: !ttl!
echo.

:: Determine most likely starting TTL (FIXED LOGIC)
set "startTTL="
set "osGuess=Unknown"

if !ttl! LEQ 64 (
    set "startTTL=64"
    set "osGuess=Linux/Unix/macOS"
) else if !ttl! LEQ 128 (
    set "startTTL=128"
    set "osGuess=Windows"
) else if !ttl! LEQ 255 (
    set "startTTL=255"
    set "osGuess=Router/Switch"
)

:: Calculate hops safely
set "hops=Unknown"
if defined startTTL (
    set /a hops=!startTTL!-!ttl!
)

echo   Assumed Start TTL: !startTTL! (!osGuess!)
echo   Hops (routers):    !hops!
echo.

:: Smarter interpretation
if "!hops!"=="0" (
    echo [INFO] Target is likely on your local network (0 hops).
) else if !hops! LEQ 5 (
    echo [OK] Very short path - same ISP or region.
) else if !hops! LEQ 15 (
    echo [OK] Normal internet path.
) else if !hops! LEQ 30 (
    echo [INFO] Long path - distant or complex routing.
) else if !hops! GTR 30 (
    echo [WARN] Unusually high hop count. Possible routing inefficiency.
)

pause
endlocal

Method 3: TTL Monitoring Over Time

Track TTL changes to detect routing shifts, if your ISP changes your traffic path, the TTL will change.

@echo off
setlocal enabledelayedexpansion

set "Target=8.8.8.8"
set "LogFile=%USERPROFILE%\ttl_audit.csv"
set "Interval=60"
set "PreviousTTL="

echo [MONITOR] Tracking TTL changes for %Target%
echo          Log: %LogFile%
echo          Interval: %Interval% seconds
echo          Press CTRL+C to stop.
echo.

:: CSV header
if not exist "%LogFile%" echo Date,Time,Target,TTL,Hops,Change >> "%LogFile%"

:Loop
set "currentTTL="

:: ✅ FIXED TTL extraction (simpler + more reliable)
for /f "tokens=2 delims==" %%A in ('ping -n 1 -w 2000 %Target% ^| findstr "TTL="') do (
    for /f "tokens=1 delims= " %%B in ("%%A") do set "currentTTL=%%B"
)

:: Handle timeout
if not defined currentTTL (
    echo [!time!] TIMEOUT - no reply from %Target%
    echo !date!,!time!,%Target%,TIMEOUT,N/A,TIMEOUT >> "%LogFile%"
    set "PreviousTTL="
    goto :Wait
)

:: ✅ FIXED base TTL detection (accurate ranges)
set "baseTTL="
if !currentTTL! LEQ 64 (
    set "baseTTL=64"
) else if !currentTTL! LEQ 128 (
    set "baseTTL=128"
) else (
    set "baseTTL=255"
)

:: Safe hop calculation
set /a "hops=baseTTL-currentTTL"

:: Detect TTL change
set "change=none"

if defined PreviousTTL (
    if !currentTTL! neq !PreviousTTL! (
        set "change=CHANGED from !PreviousTTL!"
        echo [!time!] [ALERT] TTL CHANGED: !PreviousTTL! -^> !currentTTL! (route may have shifted^)
        echo !date!,!time!,%Target%,!currentTTL!,!hops!,"!change!" >> "%LogFile%"
    ) else (
        echo [!time!] TTL: !currentTTL! (hops: !hops!^) - stable
    )
) else (
    echo [!time!] TTL: !currentTTL! (hops: !hops!^) - initial reading
    echo !date!,!time!,%Target%,!currentTTL!,!hops!,initial >> "%LogFile%"
)

set "PreviousTTL=!currentTTL!"

:Wait
timeout /t %Interval% >nul
goto :Loop

Method 4: Network Device Scanner (OS Fingerprinting)

Scan a range of IPs and fingerprint each device's likely operating system based on its TTL response.

@echo off
setlocal enabledelayedexpansion

set "Subnet=192.168.1"
set "StartIP=1"
set "EndIP=254"
set "LogFile=%USERPROFILE%\device_fingerprint.csv"

echo [SCANNER] Fingerprinting devices on %Subnet%.%StartIP%-%EndIP%
echo          Output: %LogFile%
echo.

:: CSV header
echo IP,TTL,EstimatedOS,Hops > "%LogFile%"

echo   IP ADDRESS         TTL    OS GUESS            HOPS
echo   =========================================================

for /L %%i in (%StartIP%,1,%EndIP%) do (
    set "ip=%Subnet%.%%i"
    set "ttl="

    for /f "delims=" %%L in ('ping -n 1 -w 200 !ip! 2^>nul ^| find "TTL="') do (
        set "line=%%L"
        for /f "tokens=2 delims==" %%t in ("!line:*TTL=!") do (
            for /f "tokens=1" %%v in ("%%t") do set "ttl=%%v"
        )
    )

    if defined ttl (
        :: Determine OS and hops
        if !ttl! gtr 128 (
            set "os=Router/Switch"
            set /a "hops=255-!ttl!"
        ) else if !ttl! gtr 64 (
            set "os=Windows"
            set /a "hops=128-!ttl!"
        ) else (
            set "os=Linux/Unix/Mac"
            set /a "hops=64-!ttl!"
        )

        echo   !ip!    TTL: !ttl!    !os!    !hops! hop(s^)
        echo !ip!,!ttl!,!os!,!hops! >> "%LogFile%"
    )
)

echo   =========================================================
echo.
echo [DONE] Results saved to: %LogFile%

pause
endlocal

How to Avoid Common Errors

Wrong Way: Hardcoding the Token Position

In some regions or versions of Windows, the word before "TTL" might shift position. If you hardcode tokens=6 and the reply format differs, your script captures "ms" or a fragment instead of the TTL value.

Correct Way: Search for TTL= as a string and extract the value after the = sign. This works regardless of how many words precede it:

for /f "delims=" %%L in ('ping -n 1 target ^| find "TTL="') do (
    set "line=%%L"
    for /f "tokens=2 delims==" %%t in ("!line:*TTL=!") do (
        for /f "tokens=1" %%v in ("%%t") do set "ttl=%%v"
    )
)

Wrong Way: Not Clearing the Variable Before Parsing

If a ping fails (Request Timed Out), there is no TTL in the output. Your variable retains the value from the previous successful ping, making you think the host is still alive.

Correct Way: Always clear the variable before the FOR loop:

set "ResultTTL="
for /f ... ('ping ...') do ( set "ResultTTL=%%a" )
if not defined ResultTTL echo Host is unreachable.

Wrong Way: Comparing TTL to Exact Values Only

Checking if "%ResultTTL%"=="128" only matches devices that are exactly 0 hops away. A Windows machine 5 hops away has a TTL of 123, not 128.

Correct Way: Use range comparisons to determine the closest default TTL:

if !ttl! gtr 128 ( default is 255 )
else if !ttl! gtr 64 ( default is 128 )
else ( default is 64 )

Wrong Way: Missing enabledelayedexpansion

Variables set inside FOR loops or IF blocks need delayed expansion to be read correctly in the same block.

Correct Way: Enable delayed expansion and use !variable! syntax:

setlocal enabledelayedexpansion

Best Practices and Rules

1. Distance Calculation

If you know a Windows server starts at TTL 128, calculate the distance:

set /a "hops=128-!ResultTTL!"
echo Distance: !hops! router(s)

2. Spotting Anomalies

Unusually low TTLs (like 1 or 2) on a device that should be nearby may indicate packet manipulation, a routing loop, or a misconfigured device. Investigate any TTL that doesn't match expectations.

3. Log to CSV

If you are auditing ISP routing, log TTLs over time (Method 3). If the TTL suddenly changes, it means your traffic path has shifted, which directly explains changes in latency or connection quality.

4. Default TTL Reference

Default TTL Operating Systems
64 Linux, macOS, Android, iOS, most Unix
128 Windows (all modern versions)
255 Network equipment (routers, switches, firewalls)

5. TTL Is Not Definitive

TTL-based OS fingerprinting is an educated guess. System administrators can change default TTL values, and some devices use non-standard defaults. Always verify with additional methods when identification is critical.

6. Always Use setlocal / endlocal

Without setlocal, every variable your script creates persists in the parent shell session, causing potential conflicts when running multiple scripts in sequence.

Conclusions

Extracting the TTL from a ping reply provides a low-level look at your network topology that standard latency checks miss. By identifying the number of hops and the likely OS of remote devices, you turn a simple connectivity check into a forensic audit tool. This precision is essential for professional system administration, security research, and optimizing the performance of distributed networks.

Navigation