-
Notifications
You must be signed in to change notification settings - Fork 1
/
doc.go
210 lines (155 loc) · 6.49 KB
/
doc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
Package gsnmpgo is an snmp library for Go; it uses Go/CGo to wrap gsnmp.
gsnmpgo is pre 1.0, therefore API's may change, and tests are minimal.
ISSUES
Snmp walks aren't being done as "GETBULK" when using snmp v2c, rather repeated
getnexts are being done ie like snmp v1. The gsnmp C library doesn't implement
GETBULK directly, my intention is to write the C code to do it.
Threading: either gsnmp isn't totally thread safe, or I'm making errors with my
C calls from Go (more likely). I'm getting aborts with this message:
GLib-WARNING **: g_main_context_prepare(): main loop already active in another thread
My current workaround is to force Query() calls to be synchronous:
var mu sync.Mutex
mu.Lock()
_, _ = gsnmpgo.Query(params)
mu.Unlock()
INSTALLATION
gsnmpgo requires the following libraries, as well as library header files:
glib2.0, gsnmp, gnet-2.0
Here is an example of installation on Ubuntu Precise 12.04.1:
# setup Go
sudo aptitude install golang git
cat >> ~/.bashrc
export GOPATH="${HOME}/go"
^D
mkdir ~/go && source ~/.bashrc && cd ~/go
# install GoLLRB; ignore error about "no Go source files" - GoLLRB has a
# non-standard layout
go get -d github.com/petar/GoLLRB
go install github.com/petar/GoLLRB/llrb
# install tcgl/applog
go get code.google.com/p/tcgl/applog
# install gsnmpgo
go get -d github.com/soniah/gsnmpgo
sudo aptitude install libglib2.0-dev libgsnmp0-dev libgnet-dev
go install github.com/soniah/gsnmpgo
# test working (you will need to edit example.go and
# provide different uris)
cd src/github.com/soniah/gsnmpgo/examples
go run example.go
Builds ok with these C libs (Ubuntu versions shown):
libglib2.0-dev 2.32.3-0ubuntu1
libgsnmp0-dev 0.3.0-1.1
libgnet-dev 2.0.8-2.1
SUMMARY
(most of this code is in examples/example.go)
// do an snmp get; RFC 4088 is used for uris
uri := `snmp://public@192.168.1.10//(1.3.6.1.2.1.1.1.0)`
params := gsnmpgo.NewDefaultParams(uri)
results, err := gsnmpgo.Query(params)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// check your results
gsnmpgo.Dump(results)
// turn on debugging
gsnmpgo.Debug = true
SPECIFYING URIS
http://tools.ietf.org/html/rfc4088 is used for specifying snmp uris; as well
as doing an snmp get you can also do a snmp getnext or snmp walk:
// GET - notice you can have multiple OIDs
uri := `snmp://public@192.168.1.10//(1.3.6.1.2.1.1.1.0,1.3.6.1.2.1.1.2.0)`
// NEXT - notice the plus sign at the end
uri := `snmp://public@192.168.1.10//1.3.6.1.2.1+`
// WALK - notice the star at the end
// uri := `snmp://public@192.168.1.10//1.3.6.1.2.1.*`
RESULTS
The results are returned as an LLRB tree to provide "ordered map"
functionality (ie finding items by "key", and iterating "in order"). Items in
the tree are of type QueryResult:
type QueryResult struct {
Oid string
Value Varbinder
}
See http://github.com/petar/GoLLRB for more documentation on using the LLRB
tree.
SNMP types are represented by Go types that implement the Varbinder interface
(eg "Octet String" is VBT_OctetString, "IP Address" is VBT_IPAddress). Use a
type switch to make decisions based on the SNMP type:
ch := results.IterAscend()
for {
r := <-ch
if r == nil {
break
}
result := r.(gsnmpgo.QueryResult)
switch result.Value.(type) {
case gsnmpgo.VBT_OctetString:
fmt.Printf("OID %s is an octet string: %s\n", result.Oid, result.Value)
default:
fmt.Printf("OID %s is some other type\n", result.Oid)
}
}
The Varbinder interface has two convenience functions Integer() and String()
that allow you to get all your results "as a string" or "as a number":
type Varbinder interface {
Integer() *big.Int
fmt.Stringer
}
ch2 := results.IterAscend()
for {
r := <-ch2
if r == nil {
break
}
result := r.(gsnmpgo.QueryResult)
fmt.Printf("OID %s type: %T\n", result.Oid, result.Value)
fmt.Printf("OID %s as a number: %d\n", result.Oid, result.Value.Integer())
fmt.Printf("OID %s as a string: %s\n\n", result.Oid, result.Value)
}
Some of the Stringers are smart, for example gsnmpgo.VBT_Timeticks will be
formatted as days, hours, etc when returned as a string:
OID 1.3.6.1.2.1.1.3.0 as a number: 4381200
OID 1.3.6.1.2.1.1.3.0 as a string: 0 days, 12:10:12.00
TESTS
The tests use the Verax Snmp Simulator [1]; setup Verax before running "go test":
* download, install and run Verax with the default configuration
* in the gsnmpgo/testing directory, setup these symlinks (or equivalents for your system):
ln -s /usr/local/vxsnmpsimulator/device device
ln -s /usr/local/vxsnmpsimulator/conf/devices.conf.xml devices.conf.xml
* remove randomising elements from Verax device files:
cd testing/device/cisco
sed -i -e 's!\/\/\$.*!!' -e 's!^M!!' cisco_router.txt
cd ../os
sed -i -e 's!\/\/\$.*!!' -e 's!^M!!' os-linux-std.txt
[1] http://www.veraxsystems.com/en/products/snmpsimulator
HELPER FUNCTIONS
There are a number of helper functions. Many of these have tests that serve as
example usage.
PartitionAllP()
If you have a many oids to retrieve for a single device, you could:
* send all the oids in one SNMP Get - could cause network problems
* do an SNMP BulkWalk - but that isn't implemented yet, and maybe
your target device only supports SNMP v1 anyway
Instead, use PartitionAllP() to break up your large list of OIDs into
partitions of n.
Sonia Hamilton, sonia@snowfrog.net, http://www.snowfrog.net.
*/
package gsnmpgo
// gsnmpgo is a go/cgo wrapper around gsnmp.
//
// Copyright (C) 2012-2013 Sonia Hamilton sonia@snowfrog.net.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.