Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ Command-line flags
------------------
- **-snmpcommunity**: The SNMP community string (_default_ = `public`)
- **-snmpretries**: The number of times to retry sending traps (_default_ = `1`)
- **-snmptrapaddress**: The address to send traps to (_default_ = `127.0.0.1:162`)
- **-snmptrapaddress**: The address to send traps to (_default_ = `127.0.0.1:162`)IP address to send traps to in the form w.x.y.x:port. Default is UDP. For TCP traps, use the form tcp:w.x.y.x:port. Valid types are udp,udp4,udp6,tcp,tcp4,tcp6
- **-webhookaddress**: The address to listen for incoming webhooks on (_default_ = `0.0.0.0:9099`)
14 changes: 13 additions & 1 deletion snmptrapper/send_trap.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,24 @@ import (
func sendTrap(alert types.Alert) {

// Prepare an SNMP handler:

var network = "udp"
var trapaddress = myConfig.SNMPTrapAddress
if strings.Count(trapaddress, ":") > 1 {
var sl1 []string = strings.SplitAfterN(trapaddress, ":", 2)
network = strings.TrimSuffix(strings.ToLower(sl1[0]), ":")
trapaddress = sl1[1]
}

snmp, err := snmpgo.NewSNMP(snmpgo.SNMPArguments{

Version: snmpgo.V2c,
Address: myConfig.SNMPTrapAddress,
Address: trapaddress,
Network: network,
Retries: myConfig.SNMPRetries,
Community: myConfig.SNMPCommunity,
})

if err != nil {
log.WithFields(logrus.Fields{"error": err}).Error("Failed to create snmpgo.SNMP object")
return
Expand Down
128 changes: 109 additions & 19 deletions trapdebug/trapdebug.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ package main
import (
"flag"
"net"
"strconv"
"strings"
"os"

logrus "github.com/Sirupsen/logrus"
gosnmptrap "github.com/ebookbug/gosnmptrap"
)

var (
listenPort = flag.Int("listenport", 162, "Port to listen for traps on")
listenType = flag.String("listentype", "udp", "Network udp|udp4|udp6|tcp|tcp4|tcp6")
log = logrus.WithFields(logrus.Fields{"logger": "trapdebug-listener"})
)

func init() {
Expand All @@ -23,36 +28,93 @@ func init() {

func main() {

logrus.WithFields(logrus.Fields{"port": *listenPort}).Info("Starting SNMP TrapDebugger")
*listenType = strings.ToLower(*listenType)

// Open a UDP socket:
socket, err := net.ListenUDP("udp4", &net.UDPAddr{
IP: net.IPv4(0, 0, 0, 0),
Port: *listenPort,
})
if err != nil {
logrus.WithFields(logrus.Fields{"error": err}).Fatal("Error opening socket")
// UDP
if (*listenType == "udp" || *listenType == "udp4" || *listenType == "udp6") {

// Open a UDP listener:
log.WithFields(logrus.Fields{"Protocol": *listenType, "Port": *listenPort}).Info("Open a UDP listener")

udpAddr, err := net.ResolveUDPAddr(*listenType, ":"+strconv.Itoa(*listenPort))
if err != nil {
logrus.WithFields(logrus.Fields{"error": err}).Fatal("Error creating UDPAddr")
}

listen, err := net.ListenUDP(*listenType, udpAddr)
if err != nil {
logrus.WithFields(logrus.Fields{"error": err}).Fatal("Error opening UDP listener")
}

defer listen.Close()
log.WithFields(logrus.Fields{"network": *listenType, "port": *listenPort}).Info("UDP listener started")

// Loop forever:
for {
// Make a buffer to read into:
buf := make([]byte, 2048)

// Read from the listener
read, from, _ := listen.ReadFromUDP(buf)

// Report that we have data:
logrus.WithFields(logrus.Fields{"client": from.IP}).Debug("Data received")

// Handle the data:
go HandleSNMPdata(buf[:read])
}
}
defer socket.Close()

// Loop forever:
for {
// Make a buffer to read into:
buf := make([]byte, 2048)
// TCP
if (*listenType == "tcp" || *listenType == "tcp4" || *listenType == "tcp6") {

// Open a TCP listener:
log.WithFields(logrus.Fields{"Protocol": *listenType, "Port": *listenPort}).Info("Open a TCP listener")

// Read from the socket:
read, from, _ := socket.ReadFromUDP(buf)
tcpAddr, err := net.ResolveTCPAddr(*listenType, ":"+strconv.Itoa(*listenPort))
if err != nil {
logrus.WithFields(logrus.Fields{"error": err}).Fatal("Error creating TCPAddr")
}

listen, err := net.ListenTCP(*listenType, tcpAddr)
if err != nil {
logrus.WithFields(logrus.Fields{"error": err}).Error("Open TCP listener failed")
return
}

defer listen.Close()
log.WithFields(logrus.Fields{"network": *listenType, "port": *listenPort}).Info("TCP listener started")

// loop forever
for {
conn, err := listen.Accept()
if err != nil {
logrus.WithFields(logrus.Fields{"error": err}).Error("TCP listener failed")
continue
}
// Report that we have data:
logrus.WithFields(logrus.Fields{"client": from.IP}).Debug("Data received")
logrus.WithFields(logrus.Fields{"port": *listenPort}).Debug("Data received")

// Handle the data:
go HandleUdp(buf[:read])
go HandleTCPdata(conn)
}
}
}

// handle TCP data
func HandleTCPdata(conn net.Conn) {

defer conn.Close()

buf := make([]byte, 2048)
n, err := conn.Read(buf)
if err != nil {
log.WithFields(logrus.Fields{"Error": err}).Error("error reading from TCP connection")
}
go HandleSNMPdata(buf[:n])
}

// Handle SNMP data:
func HandleUdp(data []byte) {
func HandleSNMPdata(data []byte) {

// Attempt to parse the SNMP data:
trap, err := gosnmptrap.ParseUdp(data)
Expand All @@ -69,4 +131,32 @@ func HandleUdp(data []byte) {
for trapOID, trapValue := range trap.Values {
logrus.WithFields(logrus.Fields{"OID": trapOID, "value": trapValue}).Info("Trap variable")
}
go writeToFile(string(data[:len(data)]))
}

// write notification to file
func writeToFile(data string) {

filename := "/tmp/snmptrap.txt"
log.WithFields(logrus.Fields{"File": filename}).Info("creating file")

f, err := os.Create(filename)
if err != nil {
log.WithFields(logrus.Fields{"Error": err}).Error("error creating file")
return
}

l, err := f.WriteString(strconv.Quote(data))
if err != nil {
log.WithFields(logrus.Fields{"Error": err}).Error("error writing data")
f.Close()
return
}

log.WithFields(logrus.Fields{"Length": l}).Info("bytes written successfully")
err = f.Close()
if err != nil {
log.WithFields(logrus.Fields{"Error": err}).Error("error closing file")
return
}
}