Solution to route/proxy SNMP Traps (or Netflow, generic UDP, etc) for network monitoring?

A co-worker just showed me samplicator. This tool looks to be just about a perfect solution what I was looking for. From the tool's website:

This simple program listens for UDP datagrams on a network port, and sends copies of these datagrams on to a set of destinations. Optionally, it can perform sampling, i.e. rather than forwarding every packet, forward only 1 in N. Another option is that it can "spoof" the IP source address, so that the copies appear to come from the original source, rather than the relay. Currently only supports IPv4.

It can been used to distribute e.g. Netflow packets, SNMP traps (but not informs), or Syslog messages to multiple receivers.


I would go implementing the solution myself, as I don't know if you will find something as specific as you want.

I would use a high-level language like ruby to implement the balance rules and even the trap listener. For instance, using this libraries seems easy.

Listen to traps:

m = SNMP::TrapListener.new(:Port => 1062, :Community => 'public') do |manager|
  manager.on_trap_default { |trap| p trap }
end
m.join

You should add the balance logic in the on_trap_default block.

Send traps:

Manager.open(:Version => :SNMPv1) do |snmp|
  snmp.trap_v1(
    "enterprises.9",
    "10.1.2.3",
    :enterpriseSpecific,
    42,
    12345,
    [VarBind.new("1.3.6.1.2.3.4", Integer.new(1))])
end

To build the daemon you could use the daemon-kit ruby gem.

If you keep it simple and define good objects you can maintain the software with not much effort.


Your main problem is going to be, how do you know the actual ip of the device you are receiving the traps from?

If you are using SNMP v1, you can get the ip off the header of the trap. If you are using v2 or v3 traps, you will need to correlate the snmpengine id to the ip that you have previously fetched from the device. Engineid is typically not a mandatory config item for most SNMP implementations, and hence you can't fully rely on that alone.

The fallback is that you can use the source ip from the udp packet header. Ofcourse, this will fail, if your trap is routed through another EMS/NMS or if you have a NAT between the device and your mgmt application.

  1. If you don't need to support NAT/forwarded traps from other NMS, then just make a copy of the udp packet, and route based on the ip

  2. If you need to support that, you have to parse the SNMP trap and check for engine id match for v2/v3, for v1 you can read it off the agent-address field in the SNMP header.