gosnmp
/
walk.go
169 строк · 4.6 Кб
1// Copyright 2012 The GoSNMP Authors. All rights reserved. Use of this
2// source code is governed by a BSD-style license that can be found in the
3// LICENSE file.
4
5package gosnmp
6
7import (
8"fmt"
9"strings"
10)
11
12func (x *GoSNMP) walk(getRequestType PDUType, rootOid string, walkFn WalkFunc) error {
13if rootOid == "" || rootOid == "." {
14rootOid = baseOid
15}
16
17if !strings.HasPrefix(rootOid, ".") {
18rootOid = string(".") + rootOid
19}
20
21oid := rootOid
22requests := 0
23maxReps := x.MaxRepetitions
24if maxReps == 0 {
25maxReps = defaultMaxRepetitions
26}
27
28// AppOpt 'c: do not check returned OIDs are increasing'
29checkIncreasing := true
30if x.AppOpts != nil {
31if _, ok := x.AppOpts["c"]; ok {
32if getRequestType == GetBulkRequest || getRequestType == GetNextRequest {
33checkIncreasing = false
34}
35}
36}
37
38RequestLoop:
39for {
40requests++
41
42var response *SnmpPacket
43var err error
44
45switch getRequestType {
46case GetBulkRequest:
47response, err = x.GetBulk([]string{oid}, uint8(x.NonRepeaters), maxReps)
48case GetNextRequest:
49response, err = x.GetNext([]string{oid})
50case GetRequest:
51response, err = x.Get([]string{oid})
52default:
53response, err = nil, fmt.Errorf("unsupported request type: %d", getRequestType)
54}
55
56if err != nil {
57return err
58}
59if len(response.Variables) == 0 {
60break RequestLoop
61}
62
63switch response.Error {
64case TooBig:
65x.Logger.Print("Walk terminated with TooBig")
66break RequestLoop
67case NoSuchName:
68x.Logger.Print("Walk terminated with NoSuchName")
69break RequestLoop
70case BadValue:
71x.Logger.Print("Walk terminated with BadValue")
72break RequestLoop
73case ReadOnly:
74x.Logger.Print("Walk terminated with ReadOnly")
75break RequestLoop
76case GenErr:
77x.Logger.Print("Walk terminated with GenErr")
78break RequestLoop
79case NoAccess:
80x.Logger.Print("Walk terminated with NoAccess")
81break RequestLoop
82case WrongType:
83x.Logger.Print("Walk terminated with WrongType")
84break RequestLoop
85case WrongLength:
86x.Logger.Print("Walk terminated with WrongLength")
87break RequestLoop
88case WrongEncoding:
89x.Logger.Print("Walk terminated with WrongEncoding")
90break RequestLoop
91case WrongValue:
92x.Logger.Print("Walk terminated with WrongValue")
93break RequestLoop
94case NoCreation:
95x.Logger.Print("Walk terminated with NoCreation")
96break RequestLoop
97case InconsistentValue:
98x.Logger.Print("Walk terminated with InconsistentValue")
99break RequestLoop
100case ResourceUnavailable:
101x.Logger.Print("Walk terminated with ResourceUnavailable")
102break RequestLoop
103case CommitFailed:
104x.Logger.Print("Walk terminated with CommitFailed")
105break RequestLoop
106case UndoFailed:
107x.Logger.Print("Walk terminated with UndoFailed")
108break RequestLoop
109case AuthorizationError:
110x.Logger.Print("Walk terminated with AuthorizationError")
111break RequestLoop
112case NotWritable:
113x.Logger.Print("Walk terminated with NotWritable")
114break RequestLoop
115case InconsistentName:
116x.Logger.Print("Walk terminated with InconsistentName")
117break RequestLoop
118case NoError:
119x.Logger.Print("Walk completed with NoError")
120}
121
122for i, pdu := range response.Variables {
123if pdu.Type == EndOfMibView || pdu.Type == NoSuchObject || pdu.Type == NoSuchInstance {
124x.Logger.Printf("BulkWalk terminated with type 0x%x", pdu.Type)
125break RequestLoop
126}
127if !strings.HasPrefix(pdu.Name, rootOid+".") {
128// Not in the requested root range.
129// if this is the first request, and the first variable in that request
130// and this condition is triggered - the first result is out of range
131// need to perform a regular get request
132// this request has been too narrowly defined to be found with a getNext
133// Issue #78 #93
134if requests == 1 && i == 0 {
135getRequestType = GetRequest
136continue RequestLoop
137} else if pdu.Name == rootOid && pdu.Type != NoSuchInstance {
138// Call walk function if the pdu instance is found
139// considering that the rootOid is a leafOid
140if err := walkFn(pdu); err != nil {
141return err
142}
143}
144break RequestLoop
145}
146
147if checkIncreasing && pdu.Name == oid {
148return fmt.Errorf("OID not increasing: %s", pdu.Name)
149}
150
151// Report our pdu
152if err := walkFn(pdu); err != nil {
153return err
154}
155}
156// Save last oid for next request
157oid = response.Variables[len(response.Variables)-1].Name
158}
159x.Logger.Printf("BulkWalk completed in %d requests", requests)
160return nil
161}
162
163func (x *GoSNMP) walkAll(getRequestType PDUType, rootOid string) (results []SnmpPDU, err error) {
164err = x.walk(getRequestType, rootOid, func(dataUnit SnmpPDU) error {
165results = append(results, dataUnit)
166return nil
167})
168return results, err
169}
170