// unmarshal stores in v the value part of binding b. func (b *binding) unmarshal(v interface{}) error { convertClass(&b.Value) _, err := asn1.Unmarshal(b.Value.FullBytes, v) if err != nil { if _, ok := err.(asn1.StructuralError); ok { return fmt.Errorf("type mismatch: {class:%d tag:%d} vs. %T: %v", b.Value.Class, b.Value.Tag, v, err) } return err } v = convertType(v) return nil }
func (s *SNMP) do(req *request) (*response, error) { for i := range req.Bindings { req.Bindings[i].Value = null } var buf []byte var err error switch req.Type { case "Get": var p struct { Version int Community []byte Data struct { RequestID int32 ErrorStatus int ErrorIndex int Bindings []binding } `asn1:"application,tag:0"` } p.Version = 1 p.Community = []byte(s.Community) p.Data.RequestID = req.ID p.Data.Bindings = req.Bindings buf, err = asn1.Marshal(p) case "GetNext": var p struct { Version int Community []byte Data struct { RequestID int32 ErrorStatus int ErrorIndex int Bindings []binding } `asn1:"application,tag:1"` } p.Version = 1 p.Community = []byte(s.Community) p.Data.RequestID = req.ID p.Data.Bindings = req.Bindings buf, err = asn1.Marshal(p) case "GetBulk": var p struct { Version int Community []byte Data struct { RequestID int32 NonRepeaters int MaxRepetitions int Bindings []binding } `asn1:"application,tag:5"` } p.Version = 1 p.Community = []byte(s.Community) p.Data.RequestID = req.ID p.Data.NonRepeaters = 0 p.Data.MaxRepetitions = req.MaxRepetitions p.Data.Bindings = req.Bindings buf, err = asn1.Marshal(p) default: panic("unsupported type " + req.Type) } if err != nil { return nil, err } conn, err := net.DialUDP("udp", nil, s.Addr) if err != nil { return nil, err } defer conn.Close() if _, err := conn.Write(buf); err != nil { return nil, err } buf = make([]byte, 10000, 10000) if err := conn.SetReadDeadline(time.Now().Add(5 * time.Second)); err != nil { return nil, err } n, err := conn.Read(buf) if err != nil { return nil, err } if n == len(buf) { return nil, fmt.Errorf("response too big") } var p struct { Version int Community []byte Data struct { RequestID int32 ErrorStatus int ErrorIndex int Bindings []binding } `asn1:"tag:2"` } if _, err = asn1.Unmarshal(buf[:n], &p); err != nil { return nil, err } resp := &response{p.Data.RequestID, p.Data.ErrorStatus, p.Data.ErrorIndex, p.Data.Bindings} return resp, nil }