Skip to content
Open
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
42 changes: 28 additions & 14 deletions snmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type WapSNMP struct {
timeout time.Duration // Timeout to use for all SNMP packets.
retries int // Number of times to retry an operation.
conn net.Conn // Cache the UDP connection in the object.
debug bool // Enable debugging information
}

// SNMPValue type to express an oid value pair.
Expand All @@ -37,14 +38,14 @@ func NewWapSNMP(target, community string, version SNMPVersion, timeout time.Dura
if err != nil {
return nil, fmt.Errorf(`error connecting to ("udp", "%s"): %s`, targetPort, err)
}
return &WapSNMP{target, community, version, timeout, retries, conn}, nil
return &WapSNMP{target, community, version, timeout, retries, conn, false}, nil
}

// NewWapSNMPOnConn creates a new WapSNMP object from an existing net.Conn.
//
// It does not check if the provided target is valid.
func NewWapSNMPOnConn(target, community string, version SNMPVersion, timeout time.Duration, retries int, conn net.Conn) *WapSNMP {
return &WapSNMP{target, community, version, timeout, retries, conn}
return &WapSNMP{target, community, version, timeout, retries, conn, false}
}

// RandomRequestID generates a valid SNMP request ID.
Expand All @@ -53,29 +54,37 @@ func RandomRequestID() int {
}

// poll sends a packet and wait for a response. Both operations can timeout, they're retried up to retries times.
func poll(conn net.Conn, toSend []byte, respondBuffer []byte, retries int, timeout time.Duration) (int, error) {
func poll(conn net.Conn, toSend []byte, respondBuffer []byte, retries int, timeout time.Duration, debug bool) (int, error) {
var err error
for i := 0; i < retries+1; i++ {
deadline := time.Now().Add(timeout)

if err = conn.SetWriteDeadline(deadline); err != nil {
log.Printf("Couldn't set write deadline. Retrying. Retry %d/%d\n", i, retries)
if debug {
log.Printf("Couldn't set write deadline. Retrying. Retry %d/%d\n", i, retries)
}
continue
}
if _, err = conn.Write(toSend); err != nil {
log.Printf("Couldn't write. Retrying. Retry %d/%d\n", i, retries)
if debug {
log.Printf("Couldn't write. Retrying. Retry %d/%d\n", i, retries)
}
continue
}

deadline = time.Now().Add(timeout)
if err = conn.SetReadDeadline(deadline); err != nil {
log.Printf("Couldn't set read deadline. Retrying. Retry %d/%d\n", i, retries)
if debug {
log.Printf("Couldn't set read deadline. Retrying. Retry %d/%d\n", i, retries)
}
continue
}

numRead := 0
if numRead, err = conn.Read(respondBuffer); err != nil {
log.Printf("Couldn't read. Retrying. Retry %d/%d\n", i, retries)
if debug {
log.Printf("Couldn't read. Retrying. Retry %d/%d\n", i, retries)
}
continue
}

Expand All @@ -84,6 +93,11 @@ func poll(conn net.Conn, toSend []byte, respondBuffer []byte, retries int, timeo
return 0, err
}

// Enable/Disalbe debugging
func (w *WapSNMP) Debug(debugOption bool) {
w.debug = debugOption
}

// Get sends an SNMP get request requesting the value for an oid.
func (w WapSNMP) Get(oid Oid) (interface{}, error) {
requestID := RandomRequestID()
Expand All @@ -96,7 +110,7 @@ func (w WapSNMP) Get(oid Oid) (interface{}, error) {
}

response := make([]byte, bufSize, bufSize)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout, w.debug)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -130,7 +144,7 @@ func (w WapSNMP) GetMultiple(oids []Oid) (map[string]interface{}, error) {
}

response := make([]byte, bufSize, bufSize)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout, w.debug)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -166,7 +180,7 @@ func (w WapSNMP) Set(oid Oid, value interface{}) (interface{}, error) {
}

response := make([]byte, bufSize, bufSize)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout, w.debug)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -200,7 +214,7 @@ func (w WapSNMP) SetMultiple(toset map[string]interface{}) (map[string]interface
}

response := make([]byte, bufSize, bufSize)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout, w.debug)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -236,7 +250,7 @@ func (w WapSNMP) GetNext(oid Oid) (*Oid, interface{}, error) {
}

response := make([]byte, bufSize)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout, w.debug)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -275,7 +289,7 @@ func (w WapSNMP) GetBulk(oid Oid, maxRepetitions int) (map[string]interface{}, e
}

response := make([]byte, bufSize, bufSize)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout, w.debug)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -312,7 +326,7 @@ func (w WapSNMP) GetBulkArray(oid Oid, maxRepetitions int) ([]SNMPValue, error)
}

response := make([]byte, bufSize, bufSize)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout)
numRead, err := poll(w.conn, req, response, w.retries, w.timeout, w.debug)
if err != nil {
return nil, err
}
Expand Down