gosnmp

Форк
0
/
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

5
package gosnmp
6

7
import (
8
	"fmt"
9
	"strings"
10
)
11

12
func (x *GoSNMP) walk(getRequestType PDUType, rootOid string, walkFn WalkFunc) error {
13
	if rootOid == "" || rootOid == "." {
14
		rootOid = baseOid
15
	}
16

17
	if !strings.HasPrefix(rootOid, ".") {
18
		rootOid = string(".") + rootOid
19
	}
20

21
	oid := rootOid
22
	requests := 0
23
	maxReps := x.MaxRepetitions
24
	if maxReps == 0 {
25
		maxReps = defaultMaxRepetitions
26
	}
27

28
	// AppOpt 'c: do not check returned OIDs are increasing'
29
	checkIncreasing := true
30
	if x.AppOpts != nil {
31
		if _, ok := x.AppOpts["c"]; ok {
32
			if getRequestType == GetBulkRequest || getRequestType == GetNextRequest {
33
				checkIncreasing = false
34
			}
35
		}
36
	}
37

38
RequestLoop:
39
	for {
40
		requests++
41

42
		var response *SnmpPacket
43
		var err error
44

45
		switch getRequestType {
46
		case GetBulkRequest:
47
			response, err = x.GetBulk([]string{oid}, uint8(x.NonRepeaters), maxReps)
48
		case GetNextRequest:
49
			response, err = x.GetNext([]string{oid})
50
		case GetRequest:
51
			response, err = x.Get([]string{oid})
52
		default:
53
			response, err = nil, fmt.Errorf("unsupported request type: %d", getRequestType)
54
		}
55

56
		if err != nil {
57
			return err
58
		}
59
		if len(response.Variables) == 0 {
60
			break RequestLoop
61
		}
62

63
		switch response.Error {
64
		case TooBig:
65
			x.Logger.Print("Walk terminated with TooBig")
66
			break RequestLoop
67
		case NoSuchName:
68
			x.Logger.Print("Walk terminated with NoSuchName")
69
			break RequestLoop
70
		case BadValue:
71
			x.Logger.Print("Walk terminated with BadValue")
72
			break RequestLoop
73
		case ReadOnly:
74
			x.Logger.Print("Walk terminated with ReadOnly")
75
			break RequestLoop
76
		case GenErr:
77
			x.Logger.Print("Walk terminated with GenErr")
78
			break RequestLoop
79
		case NoAccess:
80
			x.Logger.Print("Walk terminated with NoAccess")
81
			break RequestLoop
82
		case WrongType:
83
			x.Logger.Print("Walk terminated with WrongType")
84
			break RequestLoop
85
		case WrongLength:
86
			x.Logger.Print("Walk terminated with WrongLength")
87
			break RequestLoop
88
		case WrongEncoding:
89
			x.Logger.Print("Walk terminated with WrongEncoding")
90
			break RequestLoop
91
		case WrongValue:
92
			x.Logger.Print("Walk terminated with WrongValue")
93
			break RequestLoop
94
		case NoCreation:
95
			x.Logger.Print("Walk terminated with NoCreation")
96
			break RequestLoop
97
		case InconsistentValue:
98
			x.Logger.Print("Walk terminated with InconsistentValue")
99
			break RequestLoop
100
		case ResourceUnavailable:
101
			x.Logger.Print("Walk terminated with ResourceUnavailable")
102
			break RequestLoop
103
		case CommitFailed:
104
			x.Logger.Print("Walk terminated with CommitFailed")
105
			break RequestLoop
106
		case UndoFailed:
107
			x.Logger.Print("Walk terminated with UndoFailed")
108
			break RequestLoop
109
		case AuthorizationError:
110
			x.Logger.Print("Walk terminated with AuthorizationError")
111
			break RequestLoop
112
		case NotWritable:
113
			x.Logger.Print("Walk terminated with NotWritable")
114
			break RequestLoop
115
		case InconsistentName:
116
			x.Logger.Print("Walk terminated with InconsistentName")
117
			break RequestLoop
118
		case NoError:
119
			x.Logger.Print("Walk completed with NoError")
120
		}
121

122
		for i, pdu := range response.Variables {
123
			if pdu.Type == EndOfMibView || pdu.Type == NoSuchObject || pdu.Type == NoSuchInstance {
124
				x.Logger.Printf("BulkWalk terminated with type 0x%x", pdu.Type)
125
				break RequestLoop
126
			}
127
			if !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
134
				if requests == 1 && i == 0 {
135
					getRequestType = GetRequest
136
					continue 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
140
					if err := walkFn(pdu); err != nil {
141
						return err
142
					}
143
				}
144
				break RequestLoop
145
			}
146

147
			if checkIncreasing && pdu.Name == oid {
148
				return fmt.Errorf("OID not increasing: %s", pdu.Name)
149
			}
150

151
			// Report our pdu
152
			if err := walkFn(pdu); err != nil {
153
				return err
154
			}
155
		}
156
		// Save last oid for next request
157
		oid = response.Variables[len(response.Variables)-1].Name
158
	}
159
	x.Logger.Printf("BulkWalk completed in %d requests", requests)
160
	return nil
161
}
162

163
func (x *GoSNMP) walkAll(getRequestType PDUType, rootOid string) (results []SnmpPDU, err error) {
164
	err = x.walk(getRequestType, rootOid, func(dataUnit SnmpPDU) error {
165
		results = append(results, dataUnit)
166
		return nil
167
	})
168
	return results, err
169
}
170

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.