001: /*
002: * GNetWatch
003: * Copyright 2006, 2007 Alexandre Fenyo
004: * gnetwatch@fenyo.net
005: *
006: * This file is part of GNetWatch.
007: *
008: * GNetWatch is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU General Public License as published by
010: * the Free Software Foundation; either version 2 of the License, or
011: * (at your option) any later version.
012: *
013: * GNetWatch is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with GNetWatch; if not, write to the Free Software
020: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
021: */
022:
023: package net.fenyo.gnetwatch;
024:
025: import org.apache.commons.logging.Log;
026: import org.apache.commons.logging.LogFactory;
027:
028: import java.net.*;
029: import java.io.*;
030:
031: import org.snmp4j.*;
032: import org.snmp4j.smi.*;
033: import org.snmp4j.mp.*;
034: import org.snmp4j.transport.*;
035: import org.snmp4j.util.*;
036: import org.snmp4j.event.*;
037: import org.snmp4j.security.*;
038:
039: /**
040: * An SNMP querier maintains SNMP parameters needed for the manager to talk to an agent.
041: * @author Alexandre Fenyo
042: * @version $Id: SNMPQuerier.java,v 1.17 2007/03/12 05:04:15 fenyo Exp $
043: */
044:
045: // grosse limitation en V3 : si 2 targets ont le même username mais pas le même pass ni valeur de sec, ca marchera pas
046: // car on n'a pas géré les engines
047: public class SNMPQuerier {
048: private static Log log = LogFactory.getLog(SNMPQuerier.class);
049:
050: private final SNMPManager snmp_manager;
051: private Target snmp_target;
052:
053: private final InetAddress address;
054:
055: private int version = 0; // SNMPv1
056: private int sec = SecurityLevel.AUTH_PRIV;
057: private int retries = 3;
058: private int timeout = 1500; // microsec
059: private int port = 161;
060: private String community = "public";
061: private String username = "";
062: private String password_auth = "";
063: private String password_priv = "";
064: private int pdu_max_size = 1000;
065:
066: private boolean snmp_capable = false;
067: private String last_sysdescr = null;
068:
069: /**
070: * Interface used to manage asynchronous SNMP answers.
071: */
072: public interface QuerierListener {
073: /**
074: * Called for each ansynchronous answer.
075: * @param event response event recived.
076: * @return void.
077: */
078: public void onResponse(final ResponseEvent event);
079:
080: /**
081: * Called after a timeout occured.
082: * @param event timeout event.
083: * @return void.
084: */
085: public void onTimeout(final ResponseEvent event);
086: }
087:
088: /**
089: * Constructor.
090: * @param address target address.
091: * @param snmp_manager SNMPManager instance.
092: */
093: protected SNMPQuerier(final InetAddress address,
094: final SNMPManager snmp_manager) {
095: this .snmp_manager = snmp_manager;
096: this .address = address;
097: parametersHaveChanged();
098: }
099:
100: /**
101: * Returns the target address.
102: * @param none.
103: * @return InetAddress target address.
104: */
105: public InetAddress getAddress() {
106: return address;
107: }
108:
109: /**
110: * Checks that the associated target has already answered a SNMP query.
111: * @param none.
112: * @return boolean true if the target has already answered a SNMP query.
113: */
114: public boolean isSNMPCapable() {
115: return snmp_capable;
116: }
117:
118: /**
119: * Returns the last sysdescr returned.
120: * @param none.
121: * @return String system description.
122: */
123: public String getLastSysdescr() {
124: return last_sysdescr;
125: }
126:
127: /**
128: * Must be called after some setters have been called.
129: * @param none.
130: * @return void.
131: */
132: public void update() {
133: parametersHaveChanged();
134: }
135:
136: /**
137: * Must be called after some setters have been called.
138: * @param none.
139: * @return void.
140: */
141: // final since it is invoked from the constructor
142: private final void parametersHaveChanged() {
143: if (version == 0 || version == 1) {
144: snmp_target = new CommunityTarget();
145: snmp_target.setAddress(new UdpAddress(address, port));
146: snmp_target
147: .setVersion((version == 0) ? SnmpConstants.version1
148: : SnmpConstants.version2c);
149: ((CommunityTarget) snmp_target)
150: .setCommunity(new OctetString(community));
151:
152: } else {
153: try {
154: UsmUserEntry entry = snmp_manager.getSNMP().getUSM()
155: .getUserTable().getUser(
156: new OctetString(username));
157: if (entry != null
158: && snmp_manager.getSNMP().getUSM().removeUser(
159: entry.getEngineID(),
160: entry.getUserName()) == null)
161: log.error("USM user not found");
162: snmp_manager
163: .getSNMP()
164: .getUSM()
165: .addUser(
166: new OctetString(username),
167: new UsmUser(
168: new OctetString(username),
169: sec != SecurityLevel.NOAUTH_NOPRIV ? AuthMD5.ID
170: : null,
171: sec != SecurityLevel.NOAUTH_NOPRIV ? new OctetString(
172: password_auth)
173: : null,
174: sec == SecurityLevel.AUTH_PRIV ? PrivDES.ID
175: : null,
176: sec == SecurityLevel.AUTH_PRIV ? new OctetString(
177: password_priv)
178: : null));
179: snmp_target = new UserTarget(new UdpAddress(address,
180: port), new OctetString(username),
181: new byte[] {}, sec);
182: snmp_target.setVersion(SnmpConstants.version3);
183: } catch (final IllegalArgumentException ex) {
184: log.error("Exception", ex);
185: }
186: }
187:
188: snmp_target.setRetries(retries);
189: snmp_target.setTimeout(timeout);
190: snmp_target.setMaxSizeRequestPDU(pdu_max_size);
191: }
192:
193: /**
194: * Returns the version attribute.
195: * @param none.
196: * @return int version attribute.
197: */
198: public int getVersion() {
199: return version;
200: }
201:
202: /**
203: * Returns the security attribute.
204: * @param none.
205: * @return int security attribute.
206: */
207: public int getSec() {
208: return sec;
209: }
210:
211: /**
212: * Returns the retries attribute.
213: * @param none.
214: * @return int retries attribute.
215: */
216: public int getRetries() {
217: return retries;
218: }
219:
220: /**
221: * Returns the timeout attribute.
222: * @param none.
223: * @return int timeout attribute.
224: */
225: public int getTimeout() {
226: return timeout;
227: }
228:
229: /**
230: * Returns the agent UDP port attribute.
231: * @param none.
232: * @return int agent UDP port.
233: */
234: public int getPort() {
235: return port;
236: }
237:
238: /**
239: * Returns the community string.
240: * @param none.
241: * @return String community string.
242: */
243: public String getCommunity() {
244: return community;
245: }
246:
247: /**
248: * Returns the username attribute.
249: * @param none.
250: * @return String username attribute.
251: */
252: public String getUsername() {
253: return username;
254: }
255:
256: /**
257: * Returns the password authentication attribute.
258: * @param none.
259: * @return String password authentication attribute.
260: */
261: public String getPasswordAuth() {
262: return password_auth;
263: }
264:
265: /**
266: * Returns the password privacy attribute.
267: * @param none.
268: * @return String password privacy attribute.
269: */
270: public String getPasswordPriv() {
271: return password_priv;
272: }
273:
274: /**
275: * Returns the PDU maximum size attribute.
276: * @param none.
277: * @return int PDU maximum size attribute.
278: */
279: public int getPDUMaxSize() {
280: return pdu_max_size;
281: }
282:
283: /**
284: * Sets the version attribute.
285: * @param version version.
286: * @return void.
287: */
288: public void setVersion(final int version) {
289: this .version = version;
290: }
291:
292: /**
293: * Sets the security attribute.
294: * @param sec security attribute.
295: * @return void.
296: */
297: public void setSec(final int sec) {
298: this .sec = sec;
299: }
300:
301: /**
302: * Sets the retries attribute.
303: * @param retries retries attribute.
304: * @return void.
305: */
306: public void setRetries(final int retries) {
307: this .retries = retries;
308: }
309:
310: /**
311: * Sets the timeout attribute.
312: * @param timeout timeout attribute.
313: * @return void.
314: */
315: public void setTimeout(final int timeout) {
316: this .timeout = timeout;
317: }
318:
319: /**
320: * Sets the agent UDP port attribute.
321: * @param port agent UDP port attribute.
322: * @return void.
323: */
324: public void setPort(final int port) {
325: this .port = port;
326: }
327:
328: /**
329: * Sets the community string attribute.
330: * @param community community string attribute.
331: * @return void.
332: */
333: public void setCommunity(final String community) {
334: this .community = community;
335: }
336:
337: /**
338: * Sets the username attribute.
339: * @param username username attribute.
340: * @return void.
341: */
342: public void setUsername(final String username) {
343: this .username = username;
344: }
345:
346: /**
347: * Sets the password authentication attribute.
348: * @param password_auth password authentication attribute.
349: * @return void.
350: */
351: public void setPasswordAuth(final String password_auth) {
352: this .password_auth = password_auth;
353: }
354:
355: /**
356: * Sets the password privacy attribute.
357: * @param password_priv password_privacy attribute.
358: * @return void.
359: */
360: public void setPasswordPriv(final String password_priv) {
361: this .password_priv = password_priv;
362: }
363:
364: /**
365: * Sets the PDU maximum size attribute.
366: * @param pdu_max_size PDU maximum size attribute.
367: * @return void.
368: */
369: public void setPDUMaxSize(final int pdu_max_size) {
370: this .pdu_max_size = pdu_max_size;
371: }
372:
373: /**
374: * Returns the SNMP4J Snmp instance used to perform further SNMP queries.
375: * @param none.
376: * @return Snmp Snmp instance.
377: */
378: private Snmp getSNMP() {
379: return snmp_manager.getSNMP();
380: }
381:
382: /**
383: * Creates a new empty PDU.
384: * @param none.
385: * @return PDU new PDU.
386: */
387: private PDU getPDU() {
388: if (version == 0)
389: return new PDUv1();
390: if (version == 1)
391: return new PDU();
392: return new ScopedPDU();
393: }
394:
395: /**
396: * Gets the system description OID content synchronously.
397: * @param none.
398: * @return String system description.
399: */
400: // snmptranslate -Td IF-MIB::ifName.1
401: // récupérer une table : http://lists.agentpp.org/pipermail/snmp4j/2005-October/000786.html
402: public String getSysDescr() {
403: final PDU pdu = getPDU();
404: pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.1")));
405: pdu.setType(PDU.GETNEXT);
406: try {
407: final ResponseEvent response = getSNMP().send(pdu,
408: snmp_target);
409:
410: if (response.getResponse() != null) {
411:
412: if (response.getResponse().get(0) != null
413: && response.getResponse().get(0).getVariable() != null) {
414: snmp_capable = true;
415: last_sysdescr = response.getResponse().get(0)
416: .getVariable().toString();
417: }
418:
419: return response.getResponse().toString();
420: }
421: } catch (final IOException ex) {
422: log.error("Exception", ex);
423: }
424: return null;
425: }
426:
427: /**
428: * Gets the system description OID content asynchronously.
429: * @param listener listener instance that will be called asynchronously.
430: * @return void.
431: */
432: public void getSysDescr(final QuerierListener listener) {
433: final PDU pdu = getPDU();
434: pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.1")));
435: pdu.setType(PDU.GETNEXT);
436: try {
437: getSNMP().send(pdu, snmp_target, null,
438: new ResponseListener() {
439: private Boolean invoked = false;
440:
441: public void onResponse(final ResponseEvent event) {
442: if (event.getResponse() == null) {
443: synchronized (invoked) {
444: if (invoked == true)
445: return;
446: invoked = true;
447: }
448: listener.onTimeout(event);
449: } else {
450: synchronized (invoked) {
451: if (invoked == true)
452: return;
453: invoked = true;
454: }
455: ((Snmp) event.getSource()).cancel(event
456: .getRequest(), this );
457:
458: snmp_capable = true;
459: if (event.getResponse() != null
460: && event.getResponse().get(0) != null
461: && event.getResponse().get(0)
462: .getVariable() != null)
463: last_sysdescr = event.getResponse()
464: .get(0).getVariable()
465: .toString();
466:
467: listener.onResponse(event);
468: }
469: }
470: });
471: } catch (final IOException ex) {
472: log.error("Exception", ex);
473: }
474: }
475:
476: /**
477: * Gets some columns of the interface list table synchronously.
478: * @param none.
479: * @return java.util.List<TableEvent> list of rows.
480: */
481: public java.util.List<TableEvent> getInterfaces() {
482: final PDUFactory pdu_factory = new DefaultPDUFactory(
483: PDU.GETNEXT);
484:
485: TableUtils table_utils = new TableUtils(getSNMP(), pdu_factory);
486: /* regarder IF-MIB::ifName */
487: final OID[] cols = new OID[] { new OID("1.3.6.1.2.1.2.2.1.1"), // IF-MIB::ifIndex
488: new OID("1.3.6.1.2.1.2.2.1.2"), // IF-MIB::ifDescr
489: new OID("1.3.6.1.2.1.2.2.1.3"), // IF-MIB::ifType
490: new OID("1.3.6.1.2.1.2.2.1.4"), // IF-MIB::ifMtu
491: new OID("1.3.6.1.2.1.2.2.1.5"), // IF-MIB::ifSpeed
492: new OID("1.3.6.1.2.1.2.2.1.6"), // IF-MIB::ifPhysAddress
493: new OID("1.3.6.1.2.1.2.2.1.7"), // IF-MIB::ifAdminStatus
494: new OID("1.3.6.1.2.1.2.2.1.8"), // IF-MIB::ifOperStatus
495: new OID("1.3.6.1.2.1.2.2.1.10"), // IF-MIB::ifInOctets
496: new OID("1.3.6.1.2.1.2.2.1.16"), // IF-MIB::ifOutOctets
497: };
498:
499: java.util.List<TableEvent> table = table_utils.getTable(
500: snmp_target, cols, null, null);
501: if (table != null && table.get(0) != null
502: && table.get(0).getColumns() != null)
503: snmp_capable = true;
504: return table;
505: }
506: }
|