snmpsim/trap-generator.sh
2026-06-05 10:58:00 -04:00

233 lines
7.5 KiB
Bash

#!/bin/bash
# =============================================================================
# trap-generator.sh
# Sends random SNMP traps to a SevOne collector (UDP 162)
# Simulates a mixed Cisco environment: link traps, coldStart, warmStart,
# OSPF neighbor changes, BGP state changes, and CPU threshold alerts.
#
# Usage: ./trap-generator.sh <SevOne_IP>
# or run continuously: watch -n 30 ./trap-generator.sh <SevOne_IP>
# or via cron: */5 * * * * /opt/snmpsim-lab/trap-generator.sh <SevOne_IP>
# =============================================================================
SEVONE_IP="${1:-10.0.0.1}"
SEVONE_PORT="162"
COMMUNITY="public"
# The 10 simulated devices (hostname -> IP:port -> sysObjectID)
# We spoof the agent address so SevOne sees the trap as coming from each device
declare -A DEVICES
DEVICES["core-sw-01"]="9.60.154.118:10000:1.3.6.1.4.1.9.1.282"
DEVICES["core-sw-02"]="9.60.154.118:10001:1.3.6.1.4.1.9.1.282"
DEVICES["dist-sw-01"]="9.60.154.118:10002:1.3.6.1.4.1.9.1.659"
DEVICES["dist-sw-02"]="9.60.154.118:10003:1.3.6.1.4.1.9.1.659"
DEVICES["access-sw-01"]="9.60.154.118:10004:1.3.6.1.4.1.9.1.516"
DEVICES["access-sw-02"]="9.60.154.118:10005:1.3.6.1.4.1.9.1.516"
DEVICES["access-sw-03"]="9.60.154.118:10006:1.3.6.1.4.1.9.1.516"
DEVICES["rtr-01"]="9.60.154.118:10007:1.3.6.1.4.1.9.1.1861"
DEVICES["rtr-02"]="9.60.154.118:10008:1.3.6.1.4.1.9.1.1861"
DEVICES["fw-01"]="9.60.154.118:10009:1.3.6.1.4.1.9.1.1902"
# Interface names per device type
SWITCH_IFACES=("GigabitEthernet0/1" "GigabitEthernet0/2" "GigabitEthernet0/3" "GigabitEthernet0/4" "GigabitEthernet0/5" "TenGigabitEthernet1/1" "TenGigabitEthernet1/2")
ROUTER_IFACES=("GigabitEthernet0/0/0" "GigabitEthernet0/0/1" "Serial0/1/0")
FW_IFACES=("GigabitEthernet0/0" "GigabitEthernet0/1" "GigabitEthernet0/2" "Management0/0")
# Pick a random element from an array
random_element() {
local arr=("$@")
echo "${arr[$RANDOM % ${#arr[@]}]}"
}
# Pick a random device name
random_device() {
local keys=("${!DEVICES[@]}")
echo "${keys[$RANDOM % ${#keys[@]}]}"
}
# Get interface list for a device
get_ifaces() {
local device="$1"
if [[ "$device" == rtr* ]]; then
echo "${ROUTER_IFACES[@]}"
elif [[ "$device" == fw* ]]; then
echo "${FW_IFACES[@]}"
else
echo "${SWITCH_IFACES[@]}"
fi
}
# -------------------------------------------------------
# TRAP SENDERS
# Each function sends one specific trap type.
# snmptrap syntax:
# snmptrap -v2c -c <community> <target> <uptime> <trap-oid> [varbinds...]
# -------------------------------------------------------
send_linkDown() {
local device="$1"
local info="${DEVICES[$device]}"
local agent_ip=$(echo "$info" | cut -d: -f1)
local ifaces=($(get_ifaces "$device"))
local iface=$(random_element "${ifaces[@]}")
local ifindex=$((RANDOM % ${#ifaces[@]} + 1))
local uptime=$((RANDOM % 9000000 + 100000))
echo "[$(date '+%H:%M:%S')] linkDown | $device | $iface (ifIndex $ifindex)"
snmptrap -v2c -c "$COMMUNITY" "$SEVONE_IP:$SEVONE_PORT" \
"" \
1.3.6.1.6.3.1.1.5.3 \
1.3.6.1.2.1.2.2.1.1.$ifindex i $ifindex \
1.3.6.1.2.1.2.2.1.2.$ifindex s "$iface" \
1.3.6.1.2.1.2.2.1.7.$ifindex i 2 \
1.3.6.1.2.1.2.2.1.8.$ifindex i 2
}
send_linkUp() {
local device="$1"
local info="${DEVICES[$device]}"
local agent_ip=$(echo "$info" | cut -d: -f1)
local ifaces=($(get_ifaces "$device"))
local iface=$(random_element "${ifaces[@]}")
local ifindex=$((RANDOM % ${#ifaces[@]} + 1))
echo "[$(date '+%H:%M:%S')] linkUp | $device | $iface (ifIndex $ifindex)"
snmptrap -v2c -c "$COMMUNITY" "$SEVONE_IP:$SEVONE_PORT" \
"" \
1.3.6.1.6.3.1.1.5.4 \
1.3.6.1.2.1.2.2.1.1.$ifindex i $ifindex \
1.3.6.1.2.1.2.2.1.2.$ifindex s "$iface" \
1.3.6.1.2.1.2.2.1.7.$ifindex i 1 \
1.3.6.1.2.1.2.2.1.8.$ifindex i 1
}
send_coldStart() {
local device="$1"
echo "[$(date '+%H:%M:%S')] coldStart | $device"
snmptrap -v2c -c "$COMMUNITY" "$SEVONE_IP:$SEVONE_PORT" \
"" \
1.3.6.1.6.3.1.1.5.1
}
send_warmStart() {
local device="$1"
echo "[$(date '+%H:%M:%S')] warmStart | $device"
snmptrap -v2c -c "$COMMUNITY" "$SEVONE_IP:$SEVONE_PORT" \
"" \
1.3.6.1.6.3.1.1.5.2
}
send_ospfNbrStateChange() {
local device="$1"
# Only routers run OSPF
if [[ "$device" != rtr* ]]; then return; fi
local neighbor="10.$((RANDOM % 255)).$((RANDOM % 255)).$((RANDOM % 255))"
# OSPF states: 1=down 2=attempt 3=init 4=twoWay 5=exchangeStart 6=exchange 7=loading 8=full
local state=$((RANDOM % 8 + 1))
local state_names=("" "down" "attempt" "init" "twoWay" "exchangeStart" "exchange" "loading" "full")
echo "[$(date '+%H:%M:%S')] ospfNbrStateChange | $device | neighbor $neighbor -> ${state_names[$state]}"
snmptrap -v2c -c "$COMMUNITY" "$SEVONE_IP:$SEVONE_PORT" \
"" \
1.3.6.1.4.1.9.10.99.0.1 \
1.3.6.1.2.1.14.10.1.1.$neighbor a "$neighbor" \
1.3.6.1.2.1.14.10.1.6.$neighbor i $state \
1.3.6.1.2.1.14.4.1.2.0 s "0.0.0.0"
}
send_bgpEstablished() {
local device="$1"
# Only routers run BGP
if [[ "$device" != rtr* ]]; then return; fi
local peer="192.168.$((RANDOM % 255)).$((RANDOM % 255))"
local remote_as=$((RANDOM % 65000 + 1000))
echo "[$(date '+%H:%M:%S')] bgpEstablished | $device | peer $peer AS$remote_as"
snmptrap -v2c -c "$COMMUNITY" "$SEVONE_IP:$SEVONE_PORT" \
"" \
1.3.6.1.2.1.15.7.1 \
1.3.6.1.2.1.15.3.1.7.$peer i 6 \
1.3.6.1.2.1.15.3.1.9.$peer i $remote_as
}
send_bgpBackwardTransition() {
local device="$1"
if [[ "$device" != rtr* ]]; then return; fi
local peer="192.168.$((RANDOM % 255)).$((RANDOM % 255))"
local remote_as=$((RANDOM % 65000 + 1000))
# States: 1=idle 2=connect 3=active 4=openSent 5=openConfirm 6=established
local state=$((RANDOM % 5 + 1))
echo "[$(date '+%H:%M:%S')] bgpBackwardTransition | $device | peer $peer -> state $state"
snmptrap -v2c -c "$COMMUNITY" "$SEVONE_IP:$SEVONE_PORT" \
"" \
1.3.6.1.2.1.15.7.2 \
1.3.6.1.2.1.15.3.1.7.$peer i $state \
1.3.6.1.2.1.15.3.1.9.$peer i $remote_as
}
send_cpuThreshold() {
local device="$1"
local cpu=$((RANDOM % 40 + 60)) # 60-99%
echo "[$(date '+%H:%M:%S')] cpuThreshold | $device | CPU ${cpu}%"
snmptrap -v2c -c "$COMMUNITY" "$SEVONE_IP:$SEVONE_PORT" \
"" \
1.3.6.1.4.1.9.9.109.0.1 \
1.3.6.1.4.1.9.9.109.1.1.1.1.3.1 i $cpu \
1.3.6.1.4.1.9.9.109.1.1.1.1.4.1 i $((cpu - RANDOM % 10)) \
1.3.6.1.4.1.9.9.109.1.1.1.1.5.1 i $((cpu - RANDOM % 15))
}
# -------------------------------------------------------
# MAIN - pick random trap type and random device
# -------------------------------------------------------
# Weighted trap type selection
# Link traps are most common in real networks
TRAP_TYPES=(
"linkDown"
"linkDown"
"linkDown"
"linkUp"
"linkUp"
"linkUp"
"coldStart"
"warmStart"
"ospfNbrStateChange"
"ospfNbrStateChange"
"bgpEstablished"
"bgpBackwardTransition"
"cpuThreshold"
)
# Pick random trap type and device
trap_type=$(random_element "${TRAP_TYPES[@]}")
device=$(random_device)
echo "--- Sending trap: $trap_type from $device to $SEVONE_IP:$SEVONE_PORT ---"
case "$trap_type" in
linkDown) send_linkDown "$device" ;;
linkUp) send_linkUp "$device" ;;
coldStart) send_coldStart "$device" ;;
warmStart) send_warmStart "$device" ;;
ospfNbrStateChange) send_ospfNbrStateChange "$device" ;;
bgpEstablished) send_bgpEstablished "$device" ;;
bgpBackwardTransition) send_bgpBackwardTransition "$device" ;;
cpuThreshold) send_cpuThreshold "$device" ;;
esac