Last modified by Frank Fock on 2024/05/25 20:52

Hide last authors
Frank Fock 1.1 1 The following code implements a simple SNMPv3 GETNEXT operation using USM and an user with SHA256 authentication protocol and AES128 privacy protocol. Feel free to extend and adapt this code in your project:
2
3
4 **SNMPv3 GETNEXT**
5
6 {{code language="java"}}
7 /*_############################################################################
8 _##
9 _## SNMP4J - UsmGetNext.java
10 _##
11 _## Copyright (C) 2019 Frank Fock (SNMP4J.org)
12 _##
13 _## Licensed under the Apache License, Version 2.0 (the "License");
14 _## you may not use this file except in compliance with the License.
15 _## You may obtain a copy of the License at
16 _##
17 _## http://www.apache.org/licenses/LICENSE-2.0
18 _##
19 _## Unless required by applicable law or agreed to in writing, software
20 _## distributed under the License is distributed on an "AS IS" BASIS,
21 _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 _## See the License for the specific language governing permissions and
23 _## limitations under the License.
24 _##
25 _##########################################################################*/
26
27 package org.snmp4j.getnext;
28
29 import org.snmp4j.*;
30 import org.snmp4j.event.ResponseEvent;
31 import org.snmp4j.event.ResponseListener;
32 import org.snmp4j.log.ConsoleLogFactory;
33 import org.snmp4j.log.LogFactory;
34 import org.snmp4j.log.LogLevel;
35 import org.snmp4j.mp.MPv3;
36 import org.snmp4j.mp.SnmpConstants;
37 import org.snmp4j.security.*;
38 import org.snmp4j.smi.*;
39 import org.snmp4j.transport.DefaultUdpTransportMapping;
40
41 import java.io.IOException;
42 import java.util.ArrayList;
43 import java.util.List;
44
45 public class UsmGetNext {
46
47 private Snmp snmp;
48 private USM usm;
49
50 public UsmGetNext() {
51 ConsoleLogFactory consoleLogFactory = new ConsoleLogFactory();
52 consoleLogFactory.getRootLogger().setLogLevel(LogLevel.DEBUG);
53 LogFactory.setLogFactory(consoleLogFactory);
54 }
55
56 public void initSnmp() throws IOException {
57 snmp = new Snmp();
58 snmp.getMessageDispatcher().addCommandResponder(new CommandResponder() {
59 @Override
60 public <A extends Address> void processPdu(CommandResponderEvent<A> commandResponderEvent) {
61 System.out.println(commandResponderEvent.toString());
62 }
63 });
64 // Very important to add snmp as command responder which will finally process the PDU:
65 snmp.getMessageDispatcher().addCommandResponder(snmp);
66
67 snmp.addTransportMapping(new DefaultUdpTransportMapping(new UdpAddress(0)));
68 snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());
69 SecurityProtocols.getInstance().addDefaultProtocols();
70 OctetString localEngineID = new OctetString(MPv3.createLocalEngineID());
71 usm = new USM(SecurityProtocols.getInstance(), localEngineID, 0);
72 usm.setEngineDiscoveryEnabled(true);
73 SecurityModels.getInstance().addSecurityModel(usm);
74
75 snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3(usm.getLocalEngineID().getValue()));
76 snmp.listen();
77 }
78
79 public void next(String address, String contextName, String securityName,
80 String authPassphrase, String privPassphrase, String... oids) throws IOException {
81 UsmUser usmUser = new UsmUser(new OctetString(securityName),
82 AuthHMAC192SHA256.ID, new OctetString(authPassphrase),
83 PrivAES128.ID, new OctetString(privPassphrase));
84 usm.addUser(usmUser);
85
86 List<VariableBinding> oidList = new ArrayList<>(oids.length);
87 for (String objectID : oids) {
88 oidList.add(new VariableBinding(new OID(objectID)));
89 }
90
91 Address targetAddress = GenericAddress.parse(address);
92 Target<Address> userTarget = new UserTarget<>();
93 userTarget.setAddress(targetAddress);
94 userTarget.setRetries(1);
95 // set timeout to 500 milliseconds: 2*500ms = 1s total timeout
96 userTarget.setTimeout(500);
97 userTarget.setVersion(SnmpConstants.version3);
98 userTarget.setSecurityLevel(SecurityLevel.AUTH_PRIV);
99 userTarget.setSecurityName(usmUser.getSecurityName());
100
101 ScopedPDU scopedPDU = new ScopedPDU();
102 scopedPDU.addAll(oidList);
103 scopedPDU.setContextName(new OctetString(contextName));
104 ResponseListener responseListener = new ResponseListener() {
105 @Override
106 public synchronized <A extends Address> void onResponse(ResponseEvent<A> responseEvent) {
107 // Free resources we will not wait for further events
108 snmp.cancel(responseEvent.getRequest(), this);
109 // Process response here:
110 if (responseEvent.getResponse() != null) {
111 System.out.println("Received: "+responseEvent.getResponse());
112 }
113 else {
114 if (responseEvent.getError() != null) {
115 System.err.println("Error: "+responseEvent.getError());
116 }
117 else {
118 System.err.println("Timed out.");
119 }
120 }
121 notify();
122 }
123 };
124 synchronized (responseListener) {
125 snmp.getNext(scopedPDU, userTarget, null, responseListener);
126 try {
127 responseListener.wait(500000);
128 } catch (InterruptedException e) {
129 e.printStackTrace();
130 }
131 }
132 }
133
134 public static void main(String[] args) {
135 if (args.length < 5) {
136 System.out.println("Usage: UsmGetNext <address> <secName> <authPassphrase> <privPassphrase> <oid>...");
137 System.out.println("where <address> is of the form 'udp:<hostname>/<port>'");
138 }
139 String targetAddress = args[0];
140 String context = "";
141 String securityName = args[1];
142 String authPasssphrase = args[2];
143 String privPasssphrase = args[3];
144 String[] oids = new String[args.length - 4];
145 System.arraycopy(args, 4, oids, 0, args.length - 4);
146 UsmGetNext usmGetNext = new UsmGetNext();
147 try {
148 usmGetNext.initSnmp();
149 usmGetNext.next(targetAddress, context, securityName, authPasssphrase, privPasssphrase, oids);
150 } catch (IOException e) {
151 e.printStackTrace();
152 }
153 }
154 }
155 {{/code}}
156
157
158 Download the full UsmGetNext sample project fromĀ [[https:~~/~~/snmp.app/dist/snapshot/org/snmp4j/snmp4j-getnext/1.1.0-SNAPSHOT/>>url:https://snmp.app/dist/snapshot/org/snmp4j/snmp4j-getnext/1.1.0-SNAPSHOT/]]
159
160
161 The following Unix Diff code block illustrates which changes to the above code have to be made to use the new DirectUserTarget (SNMP4J 3.4.0 or later) to directly specify an USM user without prior adding it to the local USM storage (table):
162
163 {{code language="diff"}}
164 --- /var/folders/s_/7lxtpzc55t19sn2_qnt9rm4h0000gn/T/fJLNBb_UsmGetNext.java 2020-03-06 22:29:22 +0000
165 +++ /var/folders/s_/7lxtpzc55t19sn2_qnt9rm4h0000gn/T/DFlCAb_UsmGetNext.java 2020-03-06 22:29:22 +0000
166 @@ -69,39 +69,39 @@
167 usm = new USM(SecurityProtocols.getInstance(), localEngineID, 0);
168 usm.setEngineDiscoveryEnabled(true);
169 SecurityModels.getInstance().addSecurityModel(usm);
170
171 snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3(usm.getLocalEngineID().getValue()));
172 snmp.listen();
173 }
174
175 public void next(String address, String contextName, String securityName,
176 String authPassphrase, String privPassphrase, String... oids) throws IOException {
177 - UsmUser usmUser = new UsmUser(new OctetString(securityName),
178 - AuthHMAC192SHA256.ID, new OctetString(authPassphrase),
179 - PrivAES128.ID, new OctetString(privPassphrase));
180 - usm.addUser(usmUser);
181 -
182 List<VariableBinding> oidList = new ArrayList<>(oids.length);
183 for (String objectID : oids) {
184 oidList.add(new VariableBinding(new OID(objectID)));
185 }
186
187 Address targetAddress = GenericAddress.parse(address);
188 - Target<Address> userTarget = new UserTarget<>();
189 + byte[] targetEngineID = snmp.discoverAuthoritativeEngineID(targetAddress, 1000);
190 + if (targetEngineID != null) {
191 + UsmUserEntry targetUser =
192 + snmp.createLocalizedUsmUserEntry(targetEngineID, new OctetString(securityName),
193 + AuthHMAC192SHA256.ID, OctetString.fromString(authPassphrase),
194 + PrivAES128.ID, OctetString.fromString(privPassphrase));
195 + DirectUserTarget<Address> userTarget = new DirectUserTarget<>();
196 userTarget.setAddress(targetAddress);
197 userTarget.setRetries(1);
198 // set timeout to 500 milliseconds: 2*500ms = 1s total timeout
199 userTarget.setTimeout(500);
200 userTarget.setVersion(SnmpConstants.version3);
201 - userTarget.setSecurityLevel(SecurityLevel.AUTH_PRIV);
202 - userTarget.setSecurityName(usmUser.getSecurityName());
203 + snmp.setLocalizedUserCredentials(userTarget, targetUser);
204
205 ScopedPDU scopedPDU = new ScopedPDU();
206 scopedPDU.addAll(oidList);
207 scopedPDU.setContextName(new OctetString(contextName));
208 ResponseListener responseListener = new ResponseListener() {
209 @Override
210 public synchronized <A extends Address> void onResponse(ResponseEvent<A> responseEvent) {
211 // Free resources we will not wait for further events
212 snmp.cancel(responseEvent.getRequest(), this);
213 // Process response here:
214 @@ -119,31 +119,35 @@
215 };
216 synchronized (responseListener) {
217 snmp.getNext(scopedPDU, userTarget, null, responseListener);
218 try {
219 responseListener.wait(500000);
220 } catch (InterruptedException e) {
221 e.printStackTrace();
222 }
223 }
224 }
225 + else {
226 + System.err.println("Timeout on engine ID discovery for "+targetAddress+", GETNEXT not sent.");
227 + }
228 + }
229
230 public static void main(String[] args) {
231 if (args.length < 5) {
232 System.out.println("Usage: UsmGetNext <address> <secName> <authPassphrase> <privPassphrase> <oid>...");
233 System.out.println("where <address> is of the form 'udp:<hostname>/<port>'");
234 }
235 String targetAddress = args[0];
236 String context = "";
237 String securityName = args[1];
238 - String authPasssphrase = args[2];
239 - String privPasssphrase = args[3];
240 + String authPasssphrase = args[2].length() == 0 ? null : args[2];
241 + String privPasssphrase = args[3].length() == 0 ? null : args[3];
242 String[] oids = new String[args.length - 4];
243 System.arraycopy(args, 4, oids, 0, args.length - 4);
244 UsmGetNext usmGetNext = new UsmGetNext();
245 try {
246 usmGetNext.initSnmp();
247 usmGetNext.next(targetAddress, context, securityName, authPasssphrase, privPasssphrase, oids);
248 } catch (IOException e) {
249 e.printStackTrace();
250 }
251 }
252 {{/code}}
253
254
255