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
10
#cgo LDFLAGS: -lnetsnmp
13
#include <net-snmp/net-snmp-config.h>
14
#include <net-snmp/output_api.h>
15
#include <net-snmp/config_api.h>
17
u_char* getPktStart(u_char* pkt, ulong len, ulong off){
29
"github.com/gosnmp/gosnmp"
32
func isPlayback() bool {
36
type netSnmpValType int
73
func berToSnmpValType(in gosnmp.Asn1BER) (C.char, error) {
79
case gosnmp.OctetString:
81
case gosnmp.IPAddress:
83
case gosnmp.ObjectIdentifier:
85
case gosnmp.Counter32:
87
case gosnmp.Counter64:
89
case gosnmp.OpaqueFloat:
91
case gosnmp.OpaqueDouble:
93
case gosnmp.TimeTicks:
95
case gosnmp.Uinteger32:
98
return 0, errors.New("unhandled asn1 ber type" + in.String())
102
func verToSnmpVer(in gosnmp.SnmpVersion) (C.int, error) {
104
case gosnmp.Version1:
105
return C.SNMP_VERSION_1, nil
106
case gosnmp.Version2c:
107
return C.SNMP_VERSION_2c, nil
108
case gosnmp.Version3:
109
return C.SNMP_VERSION_3, nil
111
return 0, errors.New("handled snmp version " + in.String())
115
func netSnmpPduPkt(fname string, gopdu gosnmp.SnmpPDU, gosess *gosnmp.GoSNMP, reqid uint32, verbose bool) ([]byte, error) {
120
oid := oidStringToInts(gopdu.Name)
123
netSnmpEnableLogging()
126
//enable reverse encode
127
C.netsnmp_ds_set_boolean(C.NETSNMP_DS_LIBRARY_ID,
128
C.NETSNMP_DS_LIB_REVERSE_ENCODE,
129
C.NETSNMP_DEFAULT_ASNENCODING_DIRECTION)
132
sess := &C.struct_snmp_session{
133
version: C.SNMP_DEFAULT_VERSION,
134
community: (*C.uchar)((unsafe.Pointer)(C.CString(gosess.Community))),
135
community_len: C.size_t(len(gosess.Community)),
137
defer C.free(unsafe.Pointer(sess.community))
140
pdu := C.snmp_pdu_create(C.SNMP_MSG_SET)
141
defer C.free(unsafe.Pointer(pdu))
142
tmp, err := verToSnmpVer(gosess.Version)
146
pdu.version = C.long(tmp)
147
pdu.reqid = C.long(reqid)
149
tstoid := [1024]C.oid{}
150
tstoidcnt := C.size_t(0)
152
tstoid[i] = C.oid(oid[i])
155
cval := C.CString(valToString(gopdu))
156
defer C.free(unsafe.Pointer(cval))
157
ctype, err := berToSnmpValType(gopdu.Type)
161
rv := C.snmp_add_var(pdu, (*C.oid)(unsafe.Pointer(&tstoid)), tstoidcnt, ctype, cval)
163
C.snmp_perror(errout)
164
err = fmt.Errorf("net-snmp error: snmp_add_var: %s", C.GoString(errout))
170
pktout := (*C.uchar)(C.malloc(C.size_t(sz)))
171
pktoutlen := C.size_t(sz)
172
var pktoutoffset C.size_t
174
rv = C.snmp_build(&pktout, &pktoutlen, &pktoutoffset, sess, pdu)
176
C.snmp_error(sess, nil, nil, &errout)
177
err = fmt.Errorf("net-snmp error: snmp_build: %s", C.GoString(errout))
180
defer C.free(unsafe.Pointer(pktout))
182
return C.GoBytes(unsafe.Pointer(C.getPktStart(pktout, pktoutlen, pktoutoffset)), C.int(pktoutoffset)), nil
186
func netSnmpEnableLogging() {
187
C.snmp_enable_stderrlog()
188
C.snmp_set_do_debugging(1)
189
C.snmp_set_dump_packet(1)
191
C.debug_register_tokens(tmp)
192
C.free(unsafe.Pointer(tmp))
195
func oidStringToInts(in string) []int {
196
out := make([]int, 0, len(in))
198
for _, oi := range strings.Split(in, ".") {
199
tmp, err := strconv.Atoi(oi)
201
out = append(out, tmp)
207
func valToString(gopdu gosnmp.SnmpPDU) string {
210
case gosnmp.OctetString:
211
b, ok := gopdu.Value.([]byte)
221
return fmt.Sprintf("%v", val)