编码SNMP消息并从代理读取响应

I am trying to send a very basic SNMP Get request to a client using Go. I have an SNMP message for getting the OID 1.3.6.1.2.1.1 that I manually encoded into a byte slice according to this post as well as soniah/gosnmp. I am able to write the message to a host but am unable to read a response (or am not receiving a response). The program hangs when reading from the net.Conn. Does that mean there was no response at all? Or that the SNMP message I am trying to send is incorrect?

Here is my code:

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net"
    "time"
)

func main() {
    conn, err := net.DialTimeout("udp", "host:161", 5*time.Second)
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    fmt.Println(conn.RemoteAddr())

    var snmpMsg []byte

    // Type: Sequence, Length: 37
    msg := []byte{0x30, 0x25}
    snmpMsg = append(snmpMsg, msg...)

    // Type: Integer, Len: 1, Val: 1 (SNMP Version 2c)
    version := []byte{0x02, 0x01, 0x1}
    snmpMsg = append(snmpMsg, version...)

    // Type: Octet String, Len: 7, Val: "private"
    community := []byte{0x04, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65}
    snmpMsg = append(snmpMsg, community...)

    // Type: GetRequest, Len: 23
    pdu := []byte{0xa0, 0x17}
    snmpMsg = append(snmpMsg, pdu...)

    // Type: Integer, Len: 1, Val: 1 (Is the RequestID value supposed to be something specific?)
    requestID := []byte{0x02, 0x01, 0x01}
    snmpMsg = append(snmpMsg, requestID...)

    // Type: Integer, Len: 1, Val: 0
    errStatus := []byte{0x02, 0x01, 0x00}
    snmpMsg = append(snmpMsg, errStatus...)

    // Type: Integer, Len: 1, Val: 0
    errIndex := []byte{0x02, 0x01, 0x00}
    snmpMsg = append(snmpMsg, errIndex...)

    // Type: Sequence, Len: 12
    varBindList := []byte{0x30, 0x0c}
    snmpMsg = append(snmpMsg, varBindList...)

    // Type: Sequence, Len: 10
    varBind := []byte{0x30, 0x0a}
    snmpMsg = append(snmpMsg, varBind...)

    // Type: Object Identifier, Len: 6, Val: 1.3.6.1.2.1.1
    oid := []byte{0x06, 0x07, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01}
    snmpMsg = append(snmpMsg, oid...)

    // Type: Null, Len: 0
    value := []byte{0x05, 0x00}
    snmpMsg = append(snmpMsg, value...)

    n, err := conn.Write(snmpMsg)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Message size: %d, Bytes written: %d
", len(snmpMsg), n)

    // Program hangs here; does the same with `conn.Read()`.
    b, err := ioutil.ReadAll(conn)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(b))
}

I don't need to decode the response yet, I'm more concerned with just getting and reading a response. Any suggestions?

If you can run Wireshark to listen on the network for your request and anticipated response, that should clear things up for you I think.

If your request is malformed, you should see Wireshark complaining about that. If your SNMP agent does not respond for one reason or the other - you won't see the response on the wire.

In some settings response may come from/to different IP address - that may be a cause of the time out. And wrong community name can be another reason.

In addition to Ilya's answer, if the SNMP agent has decent diagnostics, it might give you a reason why it's not answering.

If it does not, then test with a decent agent first to get the initial problems out of the way.