:: LinkSkippy - Simple Windows link discovery tool supporting CDP & LLDP :: Copyright (C) 2024 Andrew Krause - https://github.com/andkrau/LinkSkippy :: :: This program is free software: you can redistribute it and/or modify :: it under the terms of the GNU General Public License as published by :: the Free Software Foundation, either version 3 of the License, or :: (at your option) any later version. :: :: This program is distributed in the hope that it will be useful, :: but WITHOUT ANY WARRANTY; without even the implied warranty of :: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the :: GNU General Public License for more details. :: :: You should have received a copy of the GNU General Public License :: along with this program. If not, see . @echo off title Requesting admin rights... net session >nul 2>&1 || (PowerShell -command "Start-Process '%~nx0' %1 -Verb runas" &exit /b) title LinkSkippy color 1f if "%1" NEQ "" set MODE=%1 if /i "%MODE%" NEQ "CDP" if /i "%MODE%" NEQ "LLDP" call :choose :begin call :logo echo. Configuring packet capture session... set ETL=%TEMP%\CDP.etl set TXT=%TEMP%\CDP.txt call :resetSession call :sleep 1 call :startSession echo. Waiting for %MODE% packet... :checkCounter for /f "tokens=* delims=" %%a in ('pktmon counters') do set result=%%a if "%result%" NEQ "All counters are zero." goto receivedPacket call :sleep 1 goto checkCounter :choose call :logo echo. Please choose [C]DP or [L]LDP... choice /c cl /n /t 30 /d c call :chose_%ERRORLEVEL% goto :eof :chose_1 set MODE=CDP goto :eof :chose_2 set MODE=LLDP goto :eof :logo cls echo. echo. # ##### echo. # # # # # # # # # # # ##### ##### # # echo. # # ## # # # # # # # # # # # # # echo. # # # # # #### ##### #### # # # # # # echo. # # # # # # # # # # # ##### ##### # echo. # # # ## # # # # # # # # # # echo. ####### # # # # # ##### # # # # # # echo. goto :eof :sleep set /a SECONDS=%1+1 ping -n %SECONDS% 127.0.0.1>nul goto :eof :startSession PowerShell Invoke-Command {^ New-NetEventSession -Name 'CDP' -CaptureMode RealtimeLocal -ErrorAction Stop;^ Add-NetEventPacketCaptureProvider -SessionName 'CDP' -Level 0x0 -LinkLayerAddress 'FF-FF-FF-FF-FF-FF' -CaptureType Physical -TruncationLength 1;^ }>nul 2>&1 call :forEachInterface enterPromiscuous PowerShell Invoke-Command {^ Start-NetEventSession -Name 'CDP';^ }>nul 2>&1 if /i %MODE% EQU CDP pktmon filter add "CDP" -m 01-00-0C-CC-CC-CC -d 0x2000>nul 2>&1 if /i %MODE% EQU LLDP pktmon filter add "LLDP" -d LLDP>nul 2>&1 pktmon start --capture --type flow --pkt-size 0 --file-name "%ETL%" --comp nics>nul 2>&1 goto :eof :resetSession del /q /s "%ETL%">nul 2>&1 del /q /s "%TXT%">nul 2>&1 pktmon stop>nul 2>&1 pktmon filter remove>nul 2>&1 PowerShell Invoke-Command {^ Stop-NetEventSession -Name 'CDP';^ }>nul 2>&1 call :forEachInterface exitPromiscuous PowerShell Invoke-Command {^ Remove-NetEventPacketCaptureProvider -SessionName 'CDP';^ Remove-NetEventSession -Name 'CDP';^ }>nul 2>&1 goto :eof :forEachInterface for /f "skip=3 tokens=1-3*" %%a in ('netsh interface show interface') do call :%1 %%a %%b %%c "%%d" goto :eof :enterPromiscuous if "%1" NEQ "Enabled" goto :eof for /f delims^=^,^"^ tokens^=^1-4 %%a in ('getmac /v /fo csv') do if "%%a" EQU "%~4" echo. Listening on %%a - %%c PowerShell Invoke-Command {^ Add-NetEventNetworkAdapter -Name '%~4' -PromiscuousMode $True;^ }>nul 2>&1 goto :eof :exitPromiscuous if "%1" NEQ "Enabled" goto :eof PowerShell Invoke-Command {^ Remove-NetEventNetworkAdapter -Name '%~4';^ }>nul 2>&1 goto :eof :receivedPacket echo. %MODE% packet received... pktmon stop>nul 2>&1 echo. Parsing packet data... start /min /wait pktmon etl2txt "%ETL%" --out "%TXT%" --verbose 3 IF /I %MODE% EQU CDP call :parseCDP IF /I %MODE% EQU LLDP call :parseLLDP call :resetSession echo. echo. Press any key to restart... pause>nul goto begin :parseCDP find "oui Cisco (0x00000c), pid CDP (0x2000)" "%TXT%" >nul 2>&1 if %errorlevel% EQU 0 ( echo. for /f "skip=2 tokens=1" %%a in ('find " > 01-00-0C-CC-CC-CC" "%TXT%"') do echo. MAC: %%a for /f "skip=2 tokens=1-4* delims=(),:" %%a in ('find "Device-ID (" "%TXT%"') do echo. Device:%%e for /f "skip=2 tokens=1-4* delims=(),:" %%a in ('find "Address (" "%TXT%"') do echo. Address:%%e for /f "skip=2 tokens=1-4* delims=(),:" %%a in ('find "Port-ID (" "%TXT%"') do echo. Port:%%e for /f "skip=2 tokens=1-4* delims=(),:" %%a in ('find "Capability (" "%TXT%"') do echo. Capability:%%e for /f "skip=2 tokens=1-4* delims=(),:" %%a in ('find "Platform (" "%TXT%"') do echo. Platform:%%e for /f "skip=2 tokens=1-4* delims=(),:" %%a in ('find "VTP Management Domain (" "%TXT%"') do echo. Domain:%%e for /f "skip=2 tokens=1-4* delims=(),:" %%a in ('find "Native VLAN ID (" "%TXT%"') do echo. VLAN:%%e for /f "skip=2 tokens=1-4* delims=(),:" %%a in ('find "Duplex (" "%TXT%"') do echo. Duplex:%%e ) goto :eof :parseLLDP for /f "skip=2 tokens=1 delims=[]" %%a in ('find /n "ethertype LLDP (0x88cc)" "%TXT%"') do set FIRSTLINE=%%a set TAB= SetLocal EnableDelayedExpansion if "%FIRSTLINE%" NEQ "" ( echo. for /f "skip=%FIRSTLINE% tokens=* delims=" %%a in ('TYPE "%TXT%"') do ( set LINE=%%a if "!LINE:%TAB%=!" EQU "End TLV (0), length 0" goto lldpEnded echo !LINE:%TAB%= ! ) ) :lldpEnded endlocal goto :eof