Understanding SNMP: The Backbone of Network Monitoring
A comprehensive guide to SNMP — how it works, OIDs, MIBs, versions, snmpwalk examples, traps, and how to build a real polling setup from scratch.
What is SNMP?
Simple Network Management Protocol (SNMP) is the industry-standard protocol for monitoring and managing network devices. Switches, routers, access points, UPS units, servers, industrial PLCs — if a device has a network interface and you need to know what it's doing, SNMP is almost certainly how you talk to it.
SNMP has been around since 1988. That longevity is not a coincidence — it's because the protocol solves a real problem in a way that scales from a single home router to a 10,000-device enterprise network without changing the fundamental approach.
I've worked with SNMP across railway signalling systems, factory floors, and enterprise networks for over 8 years. This guide covers everything from the basics to practical polling scripts you can run today.
How SNMP Works
SNMP operates on a manager-agent model:
┌─────────────────────┐ SNMP GET / GETNEXT / GETBULK
│ NMS / Manager │ ──────────────────────────────────────► ┌──────────────┐
│ (your monitoring │ ◄────────────────────────────────────── │ SNMP Agent │
│ server) │ SNMP Response │ (switch, │
│ │ │ router, │
│ │ ◄────────────────────────────────────── │ server...) │
└─────────────────────┘ SNMP TRAP (unsolicited alert) └──────────────┘
- SNMP Manager — your monitoring server (Zabbix, LibreNMS, custom script). Sends queries and receives responses.
- SNMP Agent — software built into the managed device. Responds to queries and sends traps.
- MIB — Management Information Base. A text file that defines what OIDs a device supports and what they mean.
- OID — Object Identifier. A unique numerical address for a specific piece of data on a device.
SNMP uses UDP port 161 for queries and UDP port 162 for traps. UDP is used (not TCP) because monitoring traffic needs to be lightweight — you might be polling thousands of OIDs per minute across hundreds of devices.
OIDs and MIBs Explained
OID Structure
Every measurable value on an SNMP device has an OID — a dotted numerical path through a global tree:
1.3.6.1.2.1.1.1.0
│ │ │ │ │ │ │ │ └── Instance (0 = scalar)
│ │ │ │ │ │ │ └──── sysDescr (object)
│ │ │ │ │ │ └────── system (group)
│ │ │ │ │ └──────── mib-2 (standard MIB)
│ │ │ │ └────────── mgmt
│ │ │ └──────────── internet
│ │ └────────────── dod
│ └──────────────── org
└────────────────── iso
The full path 1.3.6.1.2.1 is called the MIB-2 prefix — all standard network device OIDs live under here. Vendor-specific OIDs live under 1.3.6.1.4.1 (the enterprise branch).
Most Useful Standard OIDs
System Information
1.3.6.1.2.1.1.1.0 sysDescr — Device description string
1.3.6.1.2.1.1.3.0 sysUpTime — Uptime in centiseconds
1.3.6.1.2.1.1.5.0 sysName — Hostname
1.3.6.1.2.1.1.6.0 sysLocation — Physical location
Interface Statistics (per interface — replace X with ifIndex)
1.3.6.1.2.1.2.2.1.2.X ifDescr — Interface name (e.g. GigabitEthernet0/1)
1.3.6.1.2.1.2.2.1.5.X ifSpeed — Interface speed in bits/sec
1.3.6.1.2.1.2.2.1.8.X ifOperStatus — 1=up, 2=down, 3=testing
1.3.6.1.2.1.2.2.1.10.X ifInOctets — Bytes received (counter)
1.3.6.1.2.1.2.2.1.16.X ifOutOctets — Bytes sent (counter)
1.3.6.1.2.1.2.2.1.14.X ifInErrors — Input errors
1.3.6.1.2.1.2.2.1.20.X ifOutErrors — Output errors
IP Statistics
1.3.6.1.2.1.4.3.0 ipInReceives — Total IP packets received
1.3.6.1.2.1.4.10.0 ipOutRequests — Total IP packets sent
Vendor-Specific OIDs (Examples)
Cisco
1.3.6.1.4.1.9.9.109.1.1.1.1.3.X CPU utilization (5-min average)
1.3.6.1.4.1.9.9.48.1.1.1.5.X Memory used (bytes)
1.3.6.1.4.1.9.9.48.1.1.1.6.X Memory free (bytes)
Linux (net-snmp)
1.3.6.1.4.1.2021.10.1.3.1 CPU load average (1 min)
1.3.6.1.4.1.2021.4.5.0 Total RAM (KB)
1.3.6.1.4.1.2021.4.6.0 Available RAM (KB)
1.3.6.1.4.1.2021.9.1.6.1 Disk used (%)
MIB Files
A MIB file is a plain-text document (ASN.1 format) that maps OID numbers to human-readable names. Without MIBs, you work with raw numbers. With MIBs loaded, tools translate 1.3.6.1.2.1.1.1.0 to SNMPv2-MIB::sysDescr.0.
# Install standard MIBs on Linux
sudo apt install snmp-mibs-downloader
sudo download-mibs
# Enable MIBs in snmp.conf
sudo sed -i 's/^mibs :$/# mibs :/' /etc/snmp/snmp.conf
# Now snmpwalk shows names instead of numbers
snmpwalk -v2c -c public 192.168.1.1 system
# SNMPv2-MIB::sysDescr.0 = STRING: Cisco IOS Software...
# SNMPv2-MIB::sysUpTime.0 = Timeticks: (1234567) 1 day, 10:17:47.67SNMP Versions
SNMPv1 (1988) — Don't use in production
- Community string sent in plaintext
- Limited error handling
- No 64-bit counters (problem for high-speed interfaces)
- Only use for very old legacy devices with no alternative
SNMPv2c (1996) — Most common today
- Same security model as v1 (community string, plaintext)
- 64-bit counters (
ifHCInOctets,ifHCOutOctets) — essential for monitoring GigE/10GigE links GETBULKoperation — retrieve large tables efficiently in one request- Better error codes
# SNMPv2c query
snmpget -v2c -c public 192.168.1.1 1.3.6.1.2.1.1.3.0SNMPv3 (2004) — Use this for production
- Authentication — verifies the request comes from a trusted source (HMAC-MD5 or HMAC-SHA)
- Encryption — encrypts the payload (DES or AES128/AES256)
- No community strings — uses usernames and keys instead
- Required by security standards (ISO 27001, PCI-DSS, railway/industrial compliance)
# SNMPv3 query with auth + encryption
snmpget -v3 \
-u network_monitor \
-l authPriv \
-a SHA256 -A "AuthPassphrase123!" \
-x AES256 -X "PrivPassphrase456!" \
192.168.1.1 1.3.6.1.2.1.1.3.0Practical snmpwalk and snmpget Examples
Install SNMP tools
# Ubuntu/Debian
sudo apt install -y snmp snmp-mibs-downloader
# CentOS/RHEL
sudo yum install -y net-snmp-utilssnmpget — Query a single OID
# Get device uptime
snmpget -v2c -c public 192.168.1.1 1.3.6.1.2.1.1.3.0
# Get system name
snmpget -v2c -c public 192.168.1.1 sysName.0
# Get interface 1 operational status
snmpget -v2c -c public 192.168.1.1 ifOperStatus.1
# ifOperStatus.1 = INTEGER: up(1)snmpwalk — Walk an entire OID subtree
# Walk entire system group
snmpwalk -v2c -c public 192.168.1.1 system
# Walk all interfaces
snmpwalk -v2c -c public 192.168.1.1 interfaces
# Walk interface descriptions only
snmpwalk -v2c -c public 192.168.1.1 ifDescr
# Walk with numeric OIDs (useful for debugging)
snmpwalk -v2c -c public -On 192.168.1.1 ifDescrsnmpbulkwalk — Faster for large tables
# Get all interface statistics faster
snmpbulkwalk -v2c -c public -Cr25 192.168.1.1 ifTable
# -Cr25 = retrieve 25 rows per GETBULK requestCalculate Bandwidth Utilization
Interface counters are cumulative — you need two samples to calculate rate:
# Sample 1
T1=$(date +%s)
IN1=$(snmpget -v2c -c public -Oqv 192.168.1.1 ifHCInOctets.1)
# Wait 60 seconds
sleep 60
# Sample 2
T2=$(date +%s)
IN2=$(snmpget -v2c -c public -Oqv 192.168.1.1 ifHCInOctets.1)
# Calculate bits/second
INTERVAL=$((T2 - T1))
BPS=$(( (IN2 - IN1) * 8 / INTERVAL ))
echo "Inbound: ${BPS} bps = $((BPS / 1000000)) Mbps"SNMP Traps
Traps are unsolicited alerts sent from the agent to the manager. Instead of waiting for a poll, the device proactively notifies you when something happens — a link goes down, a fan fails, a threshold is breached.
Common Trap Types
Standard Traps (SNMPv2c)
linkDown — An interface went down
linkUp — An interface came back up
coldStart — Device rebooted (cold start)
warmStart — Device restarted without power cycle
authFailure — SNMP authentication failed (wrong community string)
Enterprise Traps (vendor-specific)
Cisco: ciscoEnvMonTemperatureNotification — Temperature threshold exceeded
APC UPS: upsOnBattery — UPS switched to battery power
Setting Up a Trap Receiver
# Install snmptrapd
sudo apt install -y snmpd snmptrapd
# /etc/snmp/snmptrapd.conf
authCommunity log,execute,net public
traphandle default /etc/snmp/trap-handler.sh
# Start trap receiver
sudo systemctl enable --now snmptrapd
# Watch traps in real time
snmptrapd -f -Lo -c /etc/snmp/snmptrapd.confSimple trap handler script:
#!/bin/bash
# /etc/snmp/trap-handler.sh
# Called by snmptrapd for every incoming trap
HOSTNAME=$1
IP=$2
# Read trap details from stdin
TRAP_DATA=$(cat)
# Log it
echo "$(date): TRAP from $HOSTNAME ($IP): $TRAP_DATA" >> /var/log/snmp-traps.log
# Send Telegram alert (optional)
# curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
# -d "chat_id=${CHAT_ID}" \
# -d "text=SNMP TRAP from $HOSTNAME: $TRAP_DATA"Configure a Cisco Switch to Send Traps
! Enable SNMP traps
snmp-server community public RO
snmp-server enable traps snmp linkdown linkup coldstart warmstart
snmp-server enable traps envmon temperature
snmp-server host 192.168.1.100 version 2c public
!
! Verify
show snmp
show snmp hostEnabling SNMP on Devices
Linux Server (net-snmp)
sudo apt install -y snmpd
# /etc/snmp/snmpd.conf — minimal production config
agentAddress udp:161
rocommunity public 192.168.1.0/24 # allow read from monitoring subnet only
syslocation "Server Room - Rack 3"
syscontact admin@yourcompany.com
# For SNMPv3
createUser network_monitor SHA "AuthPass123!" AES "PrivPass456!"
rouser network_monitor authpriv
sudo systemctl restart snmpd
sudo systemctl enable snmpdWindows Server
# Install SNMP feature
Add-WindowsFeature -Name SNMP-Service
# Configure via Group Policy or registry
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\ValidCommunities" `
-Name "public" -Value 4 # 4 = READ ONLY
# Set allowed managers
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\PermittedManagers" `
-Name "1" -Value "192.168.1.100"
Restart-Service SNMPBuilding a Simple Python SNMP Poller
pip install pysnmpfrom pysnmp.hlapi import (
getCmd, nextCmd, SnmpEngine, CommunityData,
UdpTransportTarget, ContextData, ObjectType, ObjectIdentity
)
def snmp_get(host: str, community: str, oid: str):
"""Poll a single OID from a device."""
error_indication, error_status, error_index, var_binds = next(
getCmd(
SnmpEngine(),
CommunityData(community, mpModel=1), # mpModel=1 = SNMPv2c
UdpTransportTarget((host, 161), timeout=2, retries=1),
ContextData(),
ObjectType(ObjectIdentity(oid)),
)
)
if error_indication:
print(f"Error: {error_indication}")
return None
if error_status:
print(f"Error status: {error_status}")
return None
for var_bind in var_binds:
return var_bind[1].prettyPrint()
# Poll uptime and interface status
host = "192.168.1.1"
community = "public"
uptime = snmp_get(host, community, "1.3.6.1.2.1.1.3.0")
sysname = snmp_get(host, community, "1.3.6.1.2.1.1.5.0")
iface1_status = snmp_get(host, community, "1.3.6.1.2.1.2.2.1.8.1")
print(f"Device: {sysname}")
print(f"Uptime: {uptime}")
print(f"Interface 1: {'UP' if iface1_status == '1' else 'DOWN'}")SNMP Security Best Practices
Change Default Community Strings
The default public (read) and private (write) community strings are known to every attacker. Change them:
# On Cisco
no snmp-server community public RO
snmp-server community N3tw0rkM0n!t0r RO
# On Linux
rocommunity N3tw0rkM0n!t0r 192.168.1.0/24
Restrict SNMP Access by IP
Never allow SNMP from 0.0.0.0/0. Always restrict to your monitoring server's IP:
# Linux snmpd.conf
rocommunity yourstring 192.168.1.100 # monitoring server only
# Cisco
snmp-server community yourstring RO 10 # ACL 10 defines allowed IPs
access-list 10 permit 192.168.1.100
access-list 10 deny any
Disable SNMP Write Access Unless Needed
SNMP write (SETREQUEST) can change device configuration. Disable it completely if you only need monitoring:
# Linux — never configure rwcommunity unless you need it
# Cisco
no snmp-server community private RW
Use SNMPv3 in Production
# Create SNMPv3 user on Linux
net-snmp-create-v3-user -ro -a SHA-256 -A "AuthPass!" -x AES -X "PrivPass!" monitor_user
# Test it
snmpget -v3 -u monitor_user -l authPriv \
-a SHA256 -A "AuthPass!" \
-x AES -X "PrivPass!" \
192.168.1.1 sysUpTime.0Frequently Asked Questions
What is the difference between SNMP GET and SNMP WALK?
snmpget retrieves a single specific OID — you must know the exact OID you want. snmpwalk traverses an entire OID subtree, returning all values under that branch. For example, snmpget on ifDescr.1 returns the name of interface 1 only. snmpwalk on ifDescr returns the names of ALL interfaces. Use snmpget when you know exactly what you need; use snmpwalk to explore what a device supports or to get all values in a table.
Why do SNMP interface counters wrap around or show negative values?
SNMP interface counters (ifInOctets, ifOutOctets) are 32-bit counters that wrap at 4,294,967,295 (about 4GB). On a 100Mbps link this wraps every ~5.7 minutes. On a 1Gbps link, every 34 seconds. Always use the 64-bit versions — ifHCInOctets and ifHCOutOctets (SNMPv2c only) — which wrap at 18.4 exabytes. If you see negative delta values, a counter wrap occurred between polls. Handle it: if (delta < 0) delta += 2^64.
What is SNMP community string and is it a password?
A community string acts like a simple password for SNMPv1/v2c — it's included in every request, and the device rejects requests with wrong community strings. However, it is sent in plaintext over the network, offers no encryption, and provides no per-user tracking. It's a weak authentication mechanism by modern standards. Use SNMPv3 with authPriv security level for real authentication and encryption.
How do I find the OID for a specific value on my device?
Three methods: (1) Run snmpwalk -v2c -c public <device-ip> and grep the output for the value you're looking for. (2) Download the vendor's MIB file and load it into a MIB browser (iReasoning, MIB Browser, or the free web tool at our SNMP OID Lookup tool). (3) Check the vendor's documentation — most enterprise vendors publish register maps and MIB files on their support portals.
Why is snmpwalk returning "Timeout: No Response"?
The most common causes: (1) UDP port 161 is blocked by a firewall between your host and the device — check with nmap -sU -p 161 <device-ip>. (2) The community string is wrong — verify against the device config. (3) SNMP is not enabled on the device. (4) The device only allows SNMP from specific source IPs — check the ACL on the device. (5) The device is on a different VLAN with no routing to your monitoring server.
Conclusion
SNMP is not glamorous, but it is foundational. Every serious network monitoring setup — from a small 10-device office network to a 10,000-port data centre — relies on SNMP for its core visibility layer.
The key things to take away: use SNMPv2c's 64-bit counters for interface monitoring, always restrict SNMP access by source IP, upgrade to SNMPv3 for any environment with security requirements, and remember that traps give you real-time alerting without polling overhead.
Related: SNMP Traps and Alert Receiver Setup | SNMPv3 Secure Configuration and Testing | Raspberry Pi as a Network Monitor