Beispiel #1
0
// 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
}
Beispiel #2
0
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
}