networking-plugin/skills/layer2-discovery/SKILL.md
Layer 2 device discovery and topology mapping. Use when finding switch port assignments, enumerating hosts via ARP, or identifying unknown devices by MAC vendor.
npx skillsauth add laurigates/claude-plugins layer2-discoveryInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Scenario | Use this skill | Alternative | |----------|---------------|-------------| | Find which switch port a server is connected to | Yes | | | Enumerate hosts on the local segment via ARP | Yes | | | Identify unknown devices by MAC vendor | Yes | | | Map physical network topology (LLDP/CDP) | Yes | | | Check if a host is alive when ICMP is blocked | Yes (arping) | | | Detect duplicate IP addresses | Yes (arping -D) | | | Scan for open TCP/UDP ports on remote hosts | | network-discovery (RustScan, nmap) | | Trace the network path to a remote host | | network-diagnostics (trippy) | | Look up DNS records for a domain | | dns-tools (dog, dig) | | Load test an HTTP endpoint | | http-load-testing (oha) | | Monitor per-process bandwidth usage | | network-monitoring (bandwhich) |
Expert knowledge for Layer 2 network topology discovery and neighbor detection, operating below the IP layer for direct link-level visibility.
| Layer | Protocol | Information | Use Case | |-------|----------|-------------|----------| | L2 | LLDP/CDP | Switch ports, VLANs, neighbors | Topology mapping | | L2 | ARP | MAC-to-IP mappings | Local host discovery | | L3 | ICMP/TCP | IP reachability, ports | Remote host scanning |
Why L2 matters:
lldpd is an IEEE 802.1AB (LLDP) implementation that also supports:
Architecture:
lldpd - Daemon that sends/receives LLDP frameslldpcli - CLI to query daemon and configure settings# Debian/Ubuntu
sudo apt install lldpd
# macOS (for development/testing)
brew install lldpd
# Start daemon
sudo systemctl enable --now lldpd
# Show discovered neighbors (most common)
lldpcli show neighbors
# Detailed neighbor info with all TLVs
lldpcli show neighbors details
# Show local chassis information
lldpcli show chassis
# Show interface statistics
lldpcli show statistics
# Show all interfaces lldpd is monitoring
lldpcli show interfaces
# Show running configuration
lldpcli show configuration
-------------------------------------------------------------------------------
LLDP neighbors:
-------------------------------------------------------------------------------
Interface: eth0, via: LLDP, RID: 1, Time: 0 day, 00:05:32
Chassis:
ChassisID: mac 00:1a:2b:3c:4d:5e
SysName: switch-core-01
SysDescr: Cisco IOS Software, C3750 Software
MgmtIP: 10.0.0.1
Capability: Bridge, on
Capability: Router, off
Port:
PortID: ifname GigabitEthernet0/1
PortDescr: Server Room Rack A
TTL: 120
VLAN: 100, pvid: yes
Key fields:
# Enable CDP reception (for Cisco environments)
lldpcli configure lldp portidsubtype ifname
lldpcli configure cdp status rx-only
# Set system description
lldpcli configure system description "Application Server"
# Set interface description
lldpcli configure ports eth0 lldp portdescription "Primary uplink"
# Disable LLDP on specific interface
lldpcli configure ports eth1 lldp status disabled
Configuration file: /etc/lldpd.conf or /etc/lldpd.d/*.conf
# /etc/lldpd.conf
configure system description "Production Web Server"
configure lldp portidsubtype ifname
configure cdp status rx-only
Fast, Rust-based ARP scanner for local network host discovery.
# Install
cargo install arp-scan
# Basic scan (default interface)
arp-scan -l
# Specify interface
arp-scan -i en0 -l
# Scan specific subnet
arp-scan -i eth0 192.168.1.0/24
# Fast profile (less accuracy, more speed)
arp-scan -p fast -l
# Stealth profile (slower, harder to detect)
arp-scan -p stealth -l
# JSON output for parsing
arp-scan -l --json
# Show only responding hosts
arp-scan -l --alive-only
| Profile | Timing | Retries | Use Case |
|---------|--------|---------|----------|
| default | Balanced | 2 | General use |
| fast | Aggressive | 1 | Quick enumeration |
| stealth | Slow | 1 | Minimize detection |
# Get IPs only
arp-scan -l --json | jq -r '.hosts[].ip'
# Get MAC addresses
arp-scan -l --json | jq -r '.hosts[] | "\(.ip) \(.mac)"'
# Count discovered hosts
arp-scan -l --json | jq '.hosts | length'
arping sends ARP requests to a specific host - useful for:
# Basic ARP ping
arping 192.168.1.1
# Specify source interface
arping -I eth0 192.168.1.1
# Count of requests
arping -c 3 192.168.1.1
# Timeout in seconds
arping -w 5 192.168.1.1
# Duplicate address detection mode
arping -D 192.168.1.100
# 1. Find all hosts on local segment
arp-scan -l --json > /tmp/hosts.json
# 2. Check LLDP neighbors for switch info
lldpcli show neighbors
# 3. Correlate: which switch port serves which host
lldpcli show neighbors | grep -A 10 "Interface:"
# Get MAC vendor info (arp-scan-rs includes OUI database)
arp-scan -l
# Sample output includes vendor:
# 192.168.1.50 00:11:32:xx:xx:xx Synology Inc.
# 192.168.1.51 dc:a6:32:xx:xx:xx Raspberry Pi
# On the server, see which switch port you're connected to
lldpcli show neighbors | grep -E "(Interface|PortID|PortDescr)"
# Watch for LLDP changes
watch -n 30 'lldpcli show neighbors'
# Log neighbor events
journalctl -u lldpd -f
# Export neighbors as JSON (requires lldpd 1.0+)
lldpcli show neighbors -f json
# Parse with jq
lldpcli show neighbors -f json | jq '.lldp.interface[] | {
local_if: .name,
remote_chassis: .chassis[].name[].value,
remote_port: .port[].id[].value
}'
| Context | Command |
|---------|---------|
| Quick host list | arp-scan -l --json \| jq -r '.hosts[].ip' |
| Count hosts | arp-scan -l --json \| jq '.hosts \| length' |
| Fast scan | arp-scan -p fast -l --alive-only |
| LLDP neighbors JSON | lldpcli show neighbors -f json |
| Switch port info | lldpcli show neighbors \| grep -E "(PortID\|PortDescr)" |
| Single host check | arping -c 1 -w 1 192.168.1.1; echo $? |
| Flag | Long | Description |
|------|------|-------------|
| -l | --localnet | Scan local network |
| -i | --interface | Specify interface |
| -p | --profile | Scan profile (default/fast/stealth) |
| | --json | JSON output |
| | --alive-only | Only show responding hosts |
| Command | Description |
|---------|-------------|
| show neighbors | List discovered neighbors |
| show neighbors details | Full TLV information |
| show chassis | Local system info |
| show statistics | Frame counters |
| show interfaces | Monitored interfaces |
| show configuration | Running config |
| Flag | Description |
|------|-------------|
| -I | Source interface |
| -c | Number of requests |
| -w | Timeout in seconds |
| -D | Duplicate address detection |
| -q | Quiet mode |
# Check daemon is running
systemctl status lldpd
# Verify interface is being monitored
lldpcli show interfaces
# Check for blocked frames (some switches filter LLDP)
tcpdump -i eth0 ether proto 0x88cc
# Ensure interface is up
ip link show eth0
# ARP scanning requires raw socket access
sudo arp-scan -l
# Or grant capability
sudo setcap cap_net_raw+ep $(which arp-scan)
# Verify you're on the same L2 segment
ip route get 192.168.1.1
# Check for ARP blocking (rare)
ip neigh show
# Try arping for single-host debugging
arping -c 3 192.168.1.1
# Debian/Ubuntu
sudo apt install lldpd arping
# macOS
brew install lldpd arping
# arp-scan-rs (all platforms)
cargo install arp-scan
testing
Verify accumulated bug claims at upstream HEAD and dedup against trackers before filing issues. Use when filing upstream reports from backlogs, audit docs, or git-history findings.
documentation
Gate outward-bound text (upstream issues, docs, PR bodies) through isolated haiku fresh-reader critique before publishing. Use when an artifact must survive a reader with zero project context.
tools
Suggest improvements to SKILL.md content, descriptions, or tool config from eval results. Use when raising pass rates, fixing triggering, or iterating on a skill after evaluation.
tools
deadbranch CLI for stale-branch cleanup — dry-run preview, TUI or non-interactive delete, protects main/develop/WIP. Use when asked to clean up branches, prune branches, or remove stale branches.