Skip to main content

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

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
note

Why not hardcode tokens=6?** The position of the TTL value varies between Windows versions, locales, and IPv4 vs. IPv6 responses. By searching for TTL= as a string and then extracting the value after the = sign, the script works regardless of how many words appear before it in the ping reply line.

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
note

Why monitor TTL over time?** If your TTL suddenly changes from 120 to 110, it means your traffic is now passing through 10 more routers than before. This could indicate that your ISP has changed your routing path, which directly explains sudden increases in latency or changes in connection quality.

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
Caveat

TTL-based OS fingerprinting is an educated guess, not a definitive identification. A Linux server can be configured to use TTL 128, and network appliances may use non-standard defaults. Use this as a starting point for investigation, not as proof.

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 TTLOperating Systems
64Linux, macOS, Android, iOS, most Unix
128Windows (all modern versions)
255Network 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.