@echo off
setlocal EnableExtensions EnableDelayedExpansion

REM ============================================================
REM Ping sweep for 192.168.1.0/24 with progress bar
REM Saves alive IP addresses and MAC addresses to a text file.
REM ============================================================

cd /d "%~dp0"

set "OUT_FILE=ping_success_192_168_1_24.txt"
set "NET_A=192"
set "NET_B=168"
set "NET_C=1"

REM Default ping settings
set "PING_COUNT=1"
set "TIMEOUT_MS=100"

REM Progress settings
set "TOTAL=254"
set "BAR_WIDTH=30"
set "ALIVE_COUNT=0"

REM Optional arguments:
REM   ping_192_168_1_24_progress.bat 200 1
REM   where 200 = timeout in ms, 1 = ping count
if not "%~1"=="" set "TIMEOUT_MS=%~1"
if not "%~2"=="" set "PING_COUNT=%~2"

echo ============================================================
echo Ping sweep 192.168.1.0/24
echo Range: 192.168.1.1 - 192.168.1.254
echo Ping count: %PING_COUNT%
echo Timeout ms: %TIMEOUT_MS%
echo Output file: %OUT_FILE%
echo ============================================================
echo.

echo Ping sweep 192.168.1.0/24 > "%OUT_FILE%"
echo Range: 192.168.1.1 - 192.168.1.254 >> "%OUT_FILE%"
echo Ping count: %PING_COUNT% >> "%OUT_FILE%"
echo Timeout ms: %TIMEOUT_MS% >> "%OUT_FILE%"
echo Started: %DATE% %TIME% >> "%OUT_FILE%"
echo. >> "%OUT_FILE%"
echo IP;MAC >> "%OUT_FILE%"

for /L %%D in (1,1,254) do (

    set "CURRENT_IP=%NET_A%.%NET_B%.%NET_C%.%%D"

    ping -n %PING_COUNT% -w %TIMEOUT_MS% !CURRENT_IP! | find "TTL=" >nul

    if not errorlevel 1 (
        set /a ALIVE_COUNT+=1

        call :GetMacAddress !CURRENT_IP!

        echo !CURRENT_IP!;!CURRENT_MAC! >> "%OUT_FILE%"
        echo Alive: !CURRENT_IP!  MAC: !CURRENT_MAC!
    )

    call :ShowProgress %%D
)

echo. >> "%OUT_FILE%"
echo Finished: %DATE% %TIME% >> "%OUT_FILE%"
echo Alive hosts: %ALIVE_COUNT% >> "%OUT_FILE%"

echo.
echo ============================================================
echo Done.
echo Alive hosts: %ALIVE_COUNT%
echo Results saved to:
echo %OUT_FILE%
echo ============================================================
echo.

pause
exit /b


:GetMacAddress
REM ============================================================
REM Reads Windows ARP table and finds MAC address for given IP.
REM Input:
REM   %1 = IP address
REM Output:
REM   CURRENT_MAC variable
REM ============================================================

set "SEARCH_IP=%~1"
set "CURRENT_MAC=UNKNOWN"

REM Small delay is not usually needed, because ping already triggers ARP.
REM But ARP table is read immediately after successful ping.

for /f "tokens=1,2,3" %%A in ('arp -a') do (
    if "%%A"=="!SEARCH_IP!" (
        set "CURRENT_MAC=%%B"
    )
)

exit /b


:ShowProgress
set "CURRENT=%~1"

set /a PERCENT=CURRENT*100/TOTAL
set /a FILLED=PERCENT*BAR_WIDTH/100
set /a EMPTY=BAR_WIDTH-FILLED

set "BAR="

for /L %%B in (1,1,!FILLED!) do (
    set "BAR=!BAR!#"
)

for /L %%B in (1,1,!EMPTY!) do (
    set "BAR=!BAR!-"
)

REM Print progress every 5 addresses and on the last address.
set /a MOD=CURRENT%%5

if "!MOD!"=="0" (
    echo [!BAR!] !PERCENT!%%  !CURRENT!/!TOTAL!  Alive: !ALIVE_COUNT!
)

if "!CURRENT!"=="!TOTAL!" (
    echo [!BAR!] !PERCENT!%%  !CURRENT!/!TOTAL!  Alive: !ALIVE_COUNT!
)

exit /b