1 package net.sf.snmpadaptor4j.api.opennms;
2
3 import java.net.InetAddress;
4 import java.util.Map.Entry;
5 import org.opennms.protocols.snmp.SnmpHandler;
6 import org.opennms.protocols.snmp.SnmpIPAddress;
7 import org.opennms.protocols.snmp.SnmpObjectId;
8 import org.opennms.protocols.snmp.SnmpParameters;
9 import org.opennms.protocols.snmp.SnmpPduPacket;
10 import org.opennms.protocols.snmp.SnmpPduRequest;
11 import org.opennms.protocols.snmp.SnmpPduTrap;
12 import org.opennms.protocols.snmp.SnmpPeer;
13 import org.opennms.protocols.snmp.SnmpSMI;
14 import org.opennms.protocols.snmp.SnmpSession;
15 import org.opennms.protocols.snmp.SnmpSyntax;
16 import org.opennms.protocols.snmp.SnmpVarBind;
17 import net.sf.snmpadaptor4j.api.SnmpTrapSender;
18 import net.sf.snmpadaptor4j.object.SnmpDataType;
19 import net.sf.snmpadaptor4j.object.SnmpOid;
20 import net.sf.snmpadaptor4j.object.SnmpTrap;
21 import net.sf.snmpadaptor4j.object.SnmpTrapData;
22 import net.sf.snmpadaptor4j.object.GenericSnmpTrap;
23 import net.sf.snmpadaptor4j.object.SpecificSnmpTrap;
24 import net.sf.snmpadaptor4j.object.GenericSnmpTrapType;
25
26
27
28
29
30 public final class OpennmsSnmpTrapSender
31 extends OpennmsSupport
32 implements SnmpTrapSender {
33
34
35
36
37 private static final SnmpObjectId TIME_STAMP_OID = new SnmpObjectId("1.3.6.1.2.1.1.3.0");
38
39
40
41
42 private static final SnmpObjectId TYPE_OID = new SnmpObjectId("1.3.6.1.6.3.1.1.4.1.0");
43
44
45
46
47 private static final SnmpObjectId AGENT_ADDRESS_OID = new SnmpObjectId("1.3.6.1.6.3.18.1.3.0");
48
49
50
51
52 private static final SnmpObjectId COMMUNITY_OID = new SnmpObjectId("1.3.6.1.6.3.18.1.4.0");
53
54
55
56
57 private static final SnmpObjectId ENTERPRISE_OID = new SnmpObjectId("1.3.6.1.6.3.1.1.4.3.0");
58
59
60
61
62 private static final SnmpOid GENERIC_COLD_START_TYPE_VALUE = SnmpOid.newInstance("1.3.6.1.6.3.1.1.5.1");
63
64
65
66
67 private static final SnmpOid GENERIC_WARM_START_TYPE_VALUE = SnmpOid.newInstance("1.3.6.1.6.3.1.1.5.2");
68
69
70
71
72 private static final SnmpOid GENERIC_LINK_DOWN_TYPE_VALUE = SnmpOid.newInstance("1.3.6.1.6.3.1.1.5.3");
73
74
75
76
77 private static final SnmpOid GENERIC_LINK_UP_TYPE_VALUE = SnmpOid.newInstance("1.3.6.1.6.3.1.1.5.4");
78
79
80
81
82 private static final SnmpOid GENERIC_AUTHENTICATION_FAILURE_TYPE_VALUE = SnmpOid.newInstance("1.3.6.1.6.3.1.1.5.5");
83
84
85
86
87 private static final SnmpOid GENERIC_EGP_NEIGHBOR_LOSS_TYPE_VALUE = SnmpOid.newInstance("1.3.6.1.6.3.1.1.5.6");
88
89
90
91
92 protected final class NullHandler
93 implements SnmpHandler {
94
95
96
97
98
99 public void snmpReceivedPdu (final SnmpSession session, final int command, final SnmpPduPacket pdu) {
100
101 }
102
103
104
105
106
107 public void snmpInternalError (final SnmpSession session, final int err, final SnmpSyntax pdu) {
108
109 }
110
111
112
113
114
115 public void snmpTimeoutError (final SnmpSession session, final SnmpSyntax pdu) {
116
117 }
118
119 }
120
121
122
123
124 private final SnmpIPAddress agentAddress;
125
126
127
128
129 private final String managerAddress;
130
131
132
133
134 private final int managerPort;
135
136
137
138
139 private final int managerVersion;
140
141
142
143
144 private final String managerCommunity;
145
146
147
148
149 private SnmpSession snmpSession;
150
151
152
153
154
155
156
157
158
159
160 OpennmsSnmpTrapSender (final InetAddress agentAddress, final String managerAddress, final int managerPort, final int managerVersion,
161 final String managerCommunity) {
162 super();
163 this.agentAddress = new SnmpIPAddress(agentAddress);
164 this.managerAddress = managerAddress;
165 this.managerPort = managerPort;
166 this.managerVersion = managerVersion;
167 this.managerCommunity = managerCommunity;
168 }
169
170
171
172
173
174 public String getName () {
175 return this.managerAddress + ":" + this.managerPort + "/" + this.managerCommunity;
176 }
177
178
179
180
181
182 public void open () throws Exception {
183 synchronized (this) {
184 if (this.snmpSession == null) {
185 if (this.logger.isTraceEnabled()) {
186 this.logger.trace("Connecting to " + this.managerAddress + ":" + this.managerPort + "...");
187 }
188 final SnmpPeer peer = new SnmpPeer(InetAddress.getByName(this.managerAddress));
189 peer.setPort(this.managerPort);
190 final SnmpParameters params = peer.getParameters();
191 params.setReadCommunity(this.managerCommunity);
192 switch (this.managerVersion) {
193 case 1:
194 params.setVersion(SnmpSMI.SNMPV1);
195 break;
196 default:
197 params.setVersion(SnmpSMI.SNMPV2);
198 break;
199 }
200 this.snmpSession = new SnmpSession(peer);
201 this.snmpSession.setDefaultHandler(new NullHandler());
202 Thread.sleep(100);
203 this.logger.trace("Connected");
204 }
205 else if (this.logger.isTraceEnabled()) {
206 this.logger.trace(this.managerAddress + ":" + this.managerPort + " already connected");
207 }
208 }
209 }
210
211
212
213
214
215 public void close () {
216 synchronized (this) {
217 if (this.snmpSession != null) {
218 if (this.logger.isTraceEnabled()) {
219 this.logger.trace("Disconnecting from " + this.managerAddress + ":" + this.managerPort + "...");
220 }
221 this.snmpSession.close();
222 this.snmpSession = null;
223 this.logger.trace("Disconnected");
224 }
225 else if (this.logger.isTraceEnabled()) {
226 this.logger.trace(this.managerAddress + ":" + this.managerPort + " already disconnected");
227 }
228 }
229 }
230
231
232
233
234
235 public boolean isConnected () {
236 return (this.snmpSession != null);
237 }
238
239
240
241
242
243 public void send (final SnmpTrap trap) throws Exception {
244 switch (this.managerVersion) {
245 case 1:
246 sendV1(trap);
247 break;
248 default:
249 sendV2(trap);
250 break;
251 }
252 }
253
254
255
256
257
258
259 private void sendV1 (final SnmpTrap trap) throws Exception {
260
261
262 final SnmpPduTrap trapPdu = new SnmpPduTrap();
263 trapPdu.setTimeStamp(trap.getTimeStamp());
264 if (trap.getSource() == null) {
265 throw new Exception("The source of trap is missing");
266 }
267 trapPdu.setEnterprise(new SnmpObjectId(trap.getSource().getOid()));
268 trapPdu.setAgentAddress(this.agentAddress);
269 if (trap instanceof SpecificSnmpTrap) {
270 trapPdu.setGeneric(SnmpPduTrap.GenericEnterpriseSpecific);
271 trapPdu.setSpecific(((SpecificSnmpTrap) trap).getType());
272 }
273 else if (trap instanceof GenericSnmpTrap) {
274 final GenericSnmpTrap genericTrap = (GenericSnmpTrap) trap;
275 if (genericTrap.getType() == GenericSnmpTrapType.coldStart) {
276 trapPdu.setGeneric(SnmpPduTrap.GenericColdStart);
277 }
278 else if (genericTrap.getType() == GenericSnmpTrapType.warmStart) {
279 trapPdu.setGeneric(SnmpPduTrap.GenericWarmStart);
280 }
281 else if (genericTrap.getType() == GenericSnmpTrapType.linkDown) {
282 trapPdu.setGeneric(SnmpPduTrap.GenericLinkDown);
283 }
284 else if (genericTrap.getType() == GenericSnmpTrapType.linkUp) {
285 trapPdu.setGeneric(SnmpPduTrap.GenericLinkUp);
286 }
287 else if (genericTrap.getType() == GenericSnmpTrapType.authenticationFailure) {
288 trapPdu.setGeneric(SnmpPduTrap.GenericAuthenticationFailure);
289 }
290 else if (genericTrap.getType() == GenericSnmpTrapType.egpNeighborLoss) {
291 trapPdu.setGeneric(SnmpPduTrap.GenericEgpNeighborLoss);
292 }
293 else {
294 throw new Exception("Generic trap type unknown");
295 }
296 trapPdu.setSpecific(0);
297 }
298 else {
299 throw new Exception("Trap type unknown");
300 }
301 for (Entry<SnmpOid, SnmpTrapData> entry : trap.getDataMap().entrySet()) {
302 trapPdu.addVarBind(new SnmpVarBind(new SnmpObjectId(entry.getKey().getOid()), newSnmpValue(entry.getValue().getType(), entry.getValue().getValue())));
303 }
304
305
306 synchronized (this) {
307 if (this.logger.isTraceEnabled()) {
308 this.logger.trace(trap + " sending to " + this.managerAddress + ":" + this.managerPort + "...");
309 }
310 if (this.snmpSession == null) {
311 throw new Exception("The connection to the SNMP manager is closed");
312 }
313 this.snmpSession.send(trapPdu);
314 if (this.logger.isTraceEnabled()) {
315 this.logger.trace(trap + " sent");
316 }
317 }
318
319 }
320
321
322
323
324
325
326 private void sendV2 (final SnmpTrap trap) throws Exception {
327
328
329 final SnmpPduRequest trapPdu = new SnmpPduRequest(SnmpPduPacket.V2TRAP);
330 trapPdu.addVarBind(new SnmpVarBind(OpennmsSnmpTrapSender.TIME_STAMP_OID, newSnmpValue(SnmpDataType.timeTicks, new Long(trap.getTimeStamp()))));
331 if (trap.getSource() == null) {
332 throw new Exception("The source of trap is missing");
333 }
334 SnmpOid typeValue;
335 if (trap instanceof SpecificSnmpTrap) {
336 typeValue = SnmpOid.newInstance(trap.getSource(), 0, ((SpecificSnmpTrap) trap).getType() + 1);
337 }
338 else if (trap instanceof GenericSnmpTrap) {
339 final GenericSnmpTrap genericTrap = (GenericSnmpTrap) trap;
340 if (genericTrap.getType() == GenericSnmpTrapType.coldStart) {
341 typeValue = OpennmsSnmpTrapSender.GENERIC_COLD_START_TYPE_VALUE;
342 }
343 else if (genericTrap.getType() == GenericSnmpTrapType.warmStart) {
344 typeValue = OpennmsSnmpTrapSender.GENERIC_WARM_START_TYPE_VALUE;
345 }
346 else if (genericTrap.getType() == GenericSnmpTrapType.linkDown) {
347 typeValue = OpennmsSnmpTrapSender.GENERIC_LINK_DOWN_TYPE_VALUE;
348 }
349 else if (genericTrap.getType() == GenericSnmpTrapType.linkUp) {
350 typeValue = OpennmsSnmpTrapSender.GENERIC_LINK_UP_TYPE_VALUE;
351 }
352 else if (genericTrap.getType() == GenericSnmpTrapType.authenticationFailure) {
353 typeValue = OpennmsSnmpTrapSender.GENERIC_AUTHENTICATION_FAILURE_TYPE_VALUE;
354 }
355 else if (genericTrap.getType() == GenericSnmpTrapType.egpNeighborLoss) {
356 typeValue = OpennmsSnmpTrapSender.GENERIC_EGP_NEIGHBOR_LOSS_TYPE_VALUE;
357 }
358 else {
359 throw new Exception("Generic trap type unknown");
360 }
361 }
362 else {
363 throw new Exception("Trap type unknown");
364 }
365 trapPdu.addVarBind(new SnmpVarBind(OpennmsSnmpTrapSender.TYPE_OID, newSnmpValue(SnmpDataType.objectIdentifier, typeValue)));
366 trapPdu.addVarBind(new SnmpVarBind(OpennmsSnmpTrapSender.AGENT_ADDRESS_OID, newSnmpValue(SnmpDataType.ipAddress, this.agentAddress.convertToIpAddress())));
367 trapPdu.addVarBind(new SnmpVarBind(OpennmsSnmpTrapSender.COMMUNITY_OID, newSnmpValue(SnmpDataType.octetString, this.managerCommunity)));
368 trapPdu.addVarBind(new SnmpVarBind(OpennmsSnmpTrapSender.ENTERPRISE_OID, newSnmpValue(SnmpDataType.objectIdentifier, trap.getSource())));
369 for (Entry<SnmpOid, SnmpTrapData> entry : trap.getDataMap().entrySet()) {
370 trapPdu.addVarBind(new SnmpVarBind(new SnmpObjectId(entry.getKey().getOid()), newSnmpValue(entry.getValue().getType(), entry.getValue().getValue())));
371 }
372
373
374 synchronized (this) {
375 if (this.logger.isTraceEnabled()) {
376 this.logger.trace(trap + " sending to " + this.managerAddress + ":" + this.managerPort + "...");
377 }
378 if (this.snmpSession == null) {
379 throw new Exception("The connection to the SNMP manager is closed");
380 }
381 this.snmpSession.send(trapPdu);
382 if (this.logger.isTraceEnabled()) {
383 this.logger.trace(trap + " sent");
384 }
385 }
386
387 }
388
389
390
391
392
393 @Override
394 public String toString () {
395 return "SnmpTrapSender:opennms[" + getName() + "]";
396 }
397
398 }