#!/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 # or run continuously: watch -n 30 ./trap-generator.sh # or via cron: */5 * * * * /opt/snmpsim-lab/trap-generator.sh # ============================================================================= 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 [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