-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathclient.go
More file actions
141 lines (122 loc) · 3.45 KB
/
client.go
File metadata and controls
141 lines (122 loc) · 3.45 KB
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
// Copyright 2016 Paul Stuart. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.
package snmputil
import (
"errors"
"fmt"
"net"
"time"
"github.com/gosnmp/gosnmp"
)
const (
defaultPort = 161
)
// Profile contains the settings needed to establish an SNMP connection
type Profile struct {
Host, Community, Version string
Port, Timeout, Retries int
// for SNMP v3
SecLevel, AuthUser, AuthPass, AuthProto, PrivProto, PrivPass string
}
// newClient returns an snmp client that has connected to an snmp agent
func newClient(p Profile) (*gosnmp.GoSNMP, error) {
var ok bool
var aProto gosnmp.SnmpV3AuthProtocol
var pProto gosnmp.SnmpV3PrivProtocol
var msgFlags gosnmp.SnmpV3MsgFlags
authProto := map[string]gosnmp.SnmpV3AuthProtocol{
"NoAuth": gosnmp.NoAuth,
"MD5": gosnmp.MD5,
"SHA": gosnmp.SHA,
}
privacy := map[string]gosnmp.SnmpV3PrivProtocol{
"NoPriv": gosnmp.NoPriv,
"DES": gosnmp.DES,
"AES": gosnmp.AES,
}
authCheck := func() error {
if len(p.AuthPass) < 1 {
return errors.New("no SNMPv3 password for host " + p.Host)
}
if aProto, ok = authProto[p.AuthProto]; !ok {
return fmt.Errorf("invalid auth protocol %s for host %s", p.AuthProto, p.Host)
}
return nil
}
v3auth := func() (*gosnmp.UsmSecurityParameters, error) {
if len(p.AuthUser) < 1 {
return nil, fmt.Errorf("username not found for snmpv3 host %s", p.Host)
}
switch p.SecLevel {
case "NoAuthNoPriv":
msgFlags = gosnmp.NoAuthNoPriv
return &gosnmp.UsmSecurityParameters{
UserName: p.AuthUser,
AuthenticationProtocol: gosnmp.NoAuth,
PrivacyProtocol: gosnmp.NoPriv,
}, nil
case "AuthNoPriv":
msgFlags = gosnmp.AuthNoPriv
return &gosnmp.UsmSecurityParameters{
UserName: p.AuthUser,
AuthenticationProtocol: aProto,
AuthenticationPassphrase: p.AuthPass,
PrivacyProtocol: gosnmp.NoPriv,
}, authCheck()
case "AuthPriv":
msgFlags = gosnmp.AuthPriv
if len(p.PrivPass) < 1 {
return nil, errors.New("missing snmp v3 privacy password")
}
if pProto, ok = privacy[p.PrivProto]; !ok {
return nil, fmt.Errorf("invalid in Privcy Protocol %s for host %s", p.PrivProto, p.Host)
}
return &gosnmp.UsmSecurityParameters{
UserName: p.AuthUser,
AuthenticationProtocol: aProto,
AuthenticationPassphrase: p.AuthPass,
PrivacyProtocol: pProto,
PrivacyPassphrase: p.PrivPass,
}, authCheck()
default:
return nil, fmt.Errorf("invalid security level %s for host %s", p.SecLevel, p.Host)
}
}
_, err := net.LookupHost(p.Host)
if err != nil {
return nil, err
}
if p.Port == 0 {
p.Port = defaultPort
}
client := &gosnmp.GoSNMP{
Target: p.Host,
Port: uint16(p.Port),
Timeout: time.Duration(p.Timeout) * time.Second,
Retries: p.Retries,
}
switch p.Version {
case "1":
client.Version = gosnmp.Version1
client.Community = p.Community
case "", "2", "2c":
client.Version = gosnmp.Version2c
client.Community = p.Community
case "3":
usmParams, err := v3auth()
if err != nil {
return nil, err
}
client.MsgFlags = msgFlags
client.SecurityModel = gosnmp.UserSecurityModel
client.SecurityParameters = usmParams
client.Version = gosnmp.Version3
default:
return nil, errors.New("invalid snmp version")
}
if snmpLogger != nil {
client.Logger = gosnmp.NewLogger(snmpLogger)
}
return client, client.Connect()
}