This script performs SNMP-based network device discovery, supporting SNMPv1, SNMPv2c, and SNMPv3. It identifies device types (Router/Switch/Firewall) and retrieves detailed information including interfaces, network adapters, and immediate neighbors.
- Python: 3.12 or higher
- pysnmp: 7.1 or higher
- Dependencies: Installed via
pip install -r requirements.txt
# Create virtual environment
python3 -m venv venv
# Activate virtual environment
source venv/bin/activate # Linux/Mac
# OR
venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txtTo create a standalone executable binary using PyInstaller:
- Python 3.8+
- pip
Run the provided build script:
./build_binary.shThe executable will be located in dist/snmp-discovery-linux.
This project includes a GitHub Actions workflow to automatically build binaries for Linux and Windows.
- Push to the
mainbranch or create a tag (e.g.,v1.0.0). - Go to the "Actions" tab in your GitHub repository.
- Select the "Build Binaries" workflow.
- Download the artifacts (zip files) from the completed run.
python main.py <IP_ADDRESS> [OPTIONS]python main.py 192.168.1.1 --version 1 --community publicParameters:
--version 1: Use SNMPv1 protocol--community public: SNMP community string (default: "public")
# Using default version (2) and community
python main.py 192.168.1.1
# Explicit parameters
python main.py 192.168.1.1 --version 2 --community privateParameters:
--version 2: Use SNMPv2c protocol (default)--community private: Custom community string
python main.py 192.168.1.1 --version 3 \
--user snmpv3user \
--auth_key yourAuthPassword \
--auth_proto SHA \
--priv_proto NONEpython main.py 192.168.1.1 --version 3 \
--user snmpv3user \
--auth_key yourAuthPassword \
--priv_key yourPrivPassword \
--auth_proto SHA \
--priv_proto AESSNMPv3 Parameters:
--user: SNMPv3 username--auth_key: Authentication password--priv_key: Privacy/encryption password--auth_proto: Authentication protocolMD5- MD5 authenticationSHA- SHA-1 authentication (recommended)
--priv_proto: Privacy protocolDES- DES encryption3DES- Triple DES encryptionAES- AES-128 encryption (recommended)AES192- AES-192 encryptionAES256- AES-256 encryption
| Parameter | Required | Default | Description |
|---|---|---|---|
ip |
✅ Yes | - | Target device IP address |
--version |
No | 2 |
SNMP version (1, 2, or 3) |
--community |
For v1/v2c | public |
SNMP community string |
--user |
For v3 | - | SNMPv3 username |
--auth_key |
For v3 | - | SNMPv3 authentication password |
--priv_key |
For v3 | - | SNMPv3 privacy password |
--auth_proto |
For v3 | - | Auth protocol (MD5/SHA) |
--priv_proto |
For v3 | - | Privacy protocol (DES/3DES/AES/AES192/AES256) |
{
"Device Name": "router-01.example.com",
"Device type": "Router",
"IP Address": "192.168.1.1",
"Manufacturer": "Cisco",
"Model Number": "Unknown (Parsed from sysDescr)",
"System OID": "1.3.6.1.4.1.9.1.1",
"Description": "Cisco IOS Software...",
"Serial Number": "Unknown",
"Details": {
"Interfaces": [
{
"Interface Name": "GigabitEthernet0/0",
"Interface Number": "1",
"MAC Address": "00:1a:2b:3c:4d:5e",
"IP Address": "192.168.1.1"
}
],
"Network Adapters": [
{
"Name": "GigabitEthernet0/0",
"IP Address": "192.168.1.1",
"MAC Address": "00:1a:2b:3c:4d:5e",
"Netmask": "255.255.255.0"
}
],
"Immediate Neighbors": [
{
"Neighbor name": "Unknown (CDP)",
"Destination IP network": "192.168.1.2",
"Details": "Discovered via CDP"
}
]
}
}{
"error": "Device 192.168.1.1 is not reachable via SNMP or credentials are wrong."
}"Details": {
"Interfaces": [ /* Interface details */ ],
"Network Adapters": [ /* Adapter details */ ],
"Immediate Neighbors": [ /* Neighbor details */ ]
}"Details": {
"Ports": [ /* Port details with status */ ],
"Network Adapters": [ /* Adapter details */ ],
"Neighbors": [ /* Neighbor details */ ]
}"Details": {
"Ports": [ /* Port details with status */ ],
"Network Adapters": [ /* Adapter details */ ],
"Neighbors": [ /* Neighbor details */ ]
}#!/bin/bash
# discover_network.sh
IPS="192.168.1.1 192.168.1.2 192.168.1.3"
COMMUNITY="private"
for IP in $IPS; do
echo "Discovering $IP..."
python main.py $IP --community $COMMUNITY > output_$IP.json
done#!/bin/bash
# discover_subnet.sh
SUBNET="192.168.1"
START=1
END=254
COMMUNITY="private"
for i in $(seq $START $END); do
IP="$SUBNET.$i"
echo "Scanning $IP..."
timeout 180 python main.py $IP --community $COMMUNITY > output_$IP.json 2>&1 &
# Limit concurrent processes
if (( $(jobs -r | wc -l) >= 10 )); then
wait -n
fi
done
wait
echo "Discovery complete!"#!/bin/bash
# discover_from_file.sh
while IFS= read -r IP; do
echo "Discovering $IP..."
python main.py "$IP" --community private > "output_${IP//\./_}.json"
done < ip_list.txtAll operational logs are stored in logs/snmp_errors.log:
# View logs in real-time
tail -f logs/snmp_errors.log
# View last 50 log entries
tail -50 logs/snmp_errors.log
# Search for errors
grep ERROR logs/snmp_errors.logLog Levels:
INFO: Normal operations (validation, OID walks, etc.)ERROR: SNMP errors, timeouts, connection failuresWARNING: Max results reached, partial data
Causes:
- Wrong community string
- SNMP not enabled on device
- Firewall blocking UDP port 161
- Wrong SNMP version
Solutions:
# Test SNMP connectivity with snmpwalk
snmpwalk -v2c -c public 192.168.1.1 system
# Check firewall rules
sudo iptables -L -n | grep 161
# Verify SNMP is running on device
# (check device documentation)Cause: Large device with many interfaces
Solution: Increase timeout in core/snmp_manager.py:
timeout=120.0 # Increase from 60 to 120 secondsCause: SNMP MIB not fully supported by device
Solution: Check logs for specific OID errors:
grep "Error Indication" logs/snmp_errors.logCheck:
- Username is correct
- Authentication password matches device configuration
- Privacy password matches (if using authPriv)
- Protocol types match device configuration
# Test SNMPv3 with snmpget
snmpget -v3 -l authPriv -u username -a SHA -A authpass -x AES -X privpass 192.168.1.1 sysDescr.0Edit core/snmp_manager.py, line ~87:
timeout=60.0 # Default timeout in secondsEdit core/snmp_manager.py, line ~129:
max_results = 500 # Reduce for faster scanspython main.py 192.168.1.1 --community ciscopython main.py 10.0.0.1 --version 3 \
--user admin \
--auth_key Auth123! \
--priv_key Priv456! \
--auth_proto SHA \
--priv_proto AESpython main.py 172.16.1.1 --version 2 --community firewall_ro# SNMPv2c devices
python main.py 192.168.1.1 --community public > router1.json
python main.py 192.168.1.2 --community private > switch1.json
# SNMPv3 device
python main.py 192.168.1.3 --version 3 \
--user netadmin --auth_key Pass123 --priv_key Priv456 \
--auth_proto SHA --priv_proto AES > firewall1.json- Use SNMPv3 whenever possible for encrypted communication
- Use strong community strings if using v1/v2c (not "public" or "private")
- Restrict SNMP access with firewall rules to management networks only
- Use authPriv mode in SNMPv3 (authentication + encryption)
- Store credentials securely - don't hardcode in scripts
- Rotate passwords regularly
- Use read-only SNMP credentials when possible
# Set default community
export SNMP_COMMUNITY="mysecret"
python main.py 192.168.1.1 # Will use SNMP_COMMUNITY if not specified
# Set SNMPv3 credentials
export SNMP_USER="admin"
export SNMP_AUTH_KEY="authpassword"
export SNMP_PRIV_KEY="privpassword"For issues or questions:
- Check
logs/snmp_errors.logfor detailed error messages - Verify SNMP connectivity with standard SNMP tools
- Review device-specific SNMP configuration requirements
# SNMPv1
python main.py <IP> --version 1 --community <STRING>
# SNMPv2c (default)
python main.py <IP> --community <STRING>
# SNMPv3 (auth + privacy)
python main.py <IP> --version 3 --user <USER> \
--auth_key <AUTH> --priv_key <PRIV> \
--auth_proto SHA --priv_proto AES
# View logs
tail -f logs/snmp_errors.log
# Batch discovery
for ip in 192.168.1.{1..10}; do
python main.py $ip --community public > output_$ip.json
done