1. /*
  2. * @(#)file SnmpAdaptorServer.java
  3. * @(#)author Sun Microsystems, Inc.
  4. * @(#)version 4.98
  5. * @(#)date 04/09/15
  6. *
  7. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  8. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  9. *
  10. */
  11. package com.sun.jmx.snmp.daemon;
  12. // java imports
  13. //
  14. import java.util.Vector;
  15. import java.util.Enumeration;
  16. import java.net.DatagramSocket;
  17. import java.net.DatagramPacket;
  18. import java.net.InetAddress;
  19. import java.net.SocketException;
  20. import java.net.UnknownHostException;
  21. import java.io.ObjectInputStream;
  22. import java.io.IOException;
  23. import java.io.InterruptedIOException;
  24. // jmx imports
  25. //
  26. import javax.management.MBeanServer;
  27. import javax.management.MBeanRegistration;
  28. import javax.management.ObjectName;
  29. import javax.management.InstanceAlreadyExistsException;
  30. import com.sun.jmx.snmp.SnmpIpAddress;
  31. import com.sun.jmx.snmp.SnmpMessage;
  32. import com.sun.jmx.snmp.SnmpOid;
  33. import com.sun.jmx.snmp.SnmpPduFactory;
  34. import com.sun.jmx.snmp.SnmpPduPacket;
  35. import com.sun.jmx.snmp.SnmpPduRequest;
  36. import com.sun.jmx.snmp.SnmpPduTrap;
  37. import com.sun.jmx.snmp.SnmpTimeticks;
  38. import com.sun.jmx.snmp.SnmpVarBind;
  39. import com.sun.jmx.snmp.SnmpVarBindList;
  40. import com.sun.jmx.snmp.SnmpDefinitions;
  41. import com.sun.jmx.snmp.SnmpStatusException;
  42. import com.sun.jmx.snmp.SnmpTooBigException;
  43. import com.sun.jmx.snmp.InetAddressAcl;
  44. import com.sun.jmx.snmp.SnmpPeer;
  45. import com.sun.jmx.snmp.SnmpParameters;
  46. // SNMP Runtime imports
  47. //
  48. import com.sun.jmx.snmp.SnmpPduFactoryBER;
  49. import com.sun.jmx.snmp.agent.SnmpMibAgent;
  50. import com.sun.jmx.snmp.agent.SnmpMibHandler;
  51. import com.sun.jmx.snmp.agent.SnmpUserDataFactory;
  52. import com.sun.jmx.snmp.agent.SnmpErrorHandlerAgent;
  53. import com.sun.jmx.snmp.IPAcl.SnmpAcl;
  54. import com.sun.jmx.snmp.tasks.ThreadService;
  55. /**
  56. * Implements an adaptor on top of the SNMP protocol.
  57. * <P>
  58. * When this SNMP protocol adaptor is started it creates a datagram socket
  59. * and is able to receive requests and send traps or inform requests.
  60. * When it is stopped, the socket is closed and neither requests
  61. * and nor traps/inform request are processed.
  62. * <P>
  63. * The default port number of the socket is 161. This default value can be
  64. * changed by specifying a port number:
  65. * <UL>
  66. * <LI>in the object constructor</LI>
  67. * <LI>using the {@link com.sun.jmx.snmp.daemon.CommunicatorServer#setPort
  68. * setPort} method before starting the adaptor</LI>
  69. * </UL>
  70. * The default object name is defined by {@link
  71. * com.sun.jmx.snmp.ServiceName#DOMAIN com.sun.jmx.snmp.ServiceName.DOMAIN}
  72. * and {@link com.sun.jmx.snmp.ServiceName#SNMP_ADAPTOR_SERVER
  73. * com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER}.
  74. * <P>
  75. * The SNMP protocol adaptor supports versions 1 and 2 of the SNMP protocol
  76. * in a stateless way: when it receives a v1 request, it replies with a v1
  77. * response, when it receives a v2 request it replies with a v2 response.
  78. * <BR>The method {@link #snmpV1Trap snmpV1Trap} sends traps using SNMP v1
  79. * format.
  80. * The method {@link #snmpV2Trap snmpV2Trap} sends traps using SNMP v2 format.
  81. * The method {@link #snmpInformRequest snmpInformRequest} sends inform
  82. * requests using SNMP v2 format.
  83. * <P>
  84. * To receive data packets, the SNMP protocol adaptor uses a buffer
  85. * which size can be configured using the property <CODE>bufferSize</CODE>
  86. * (default value is 1024).
  87. * Packets which do not fit into the buffer are rejected.
  88. * Increasing <CODE>bufferSize</CODE> allows the exchange of bigger packets.
  89. * However, the underlying networking system may impose a limit on the size
  90. * of UDP packets.
  91. * Packets which size exceed this limit will be rejected, no matter what
  92. * the value of <CODE>bufferSize</CODE> actually is.
  93. * <P>
  94. * An SNMP protocol adaptor may serve several managers concurrently. The
  95. * number of concurrent managers can be limited using the property
  96. * <CODE>maxActiveClientCount</CODE>.
  97. * <p>
  98. * The SNMP protocol adaptor specifies a default value (10) for the
  99. * <CODE>maxActiveClientCount</CODE> property. When the adaptor is stopped,
  100. * the active requests are interrupted and an error result is sent to
  101. * the managers.
  102. * <p><b>This API is a Sun Microsystems internal API and is subject
  103. * to change without notice.</b></p>
  104. */
  105. public class SnmpAdaptorServer extends CommunicatorServer
  106. implements SnmpAdaptorServerMBean, MBeanRegistration, SnmpDefinitions,
  107. SnmpMibHandler {
  108. // PRIVATE VARIABLES
  109. //------------------
  110. /**
  111. * Port number for sending SNMP traps.
  112. * <BR>The default value is 162.
  113. */
  114. private int trapPort = 162;
  115. /**
  116. * Port number for sending SNMP inform requests.
  117. * <BR>The default value is 162.
  118. */
  119. private int informPort = 162;
  120. /**
  121. * The <CODE>InetAddress</CODE> used when creating the datagram socket.
  122. * <BR>It is specified when creating the SNMP protocol adaptor.
  123. * If not specified, the local host machine is used.
  124. */
  125. InetAddress address = null;
  126. /**
  127. * The IP address based ACL used by this SNMP protocol adaptor.
  128. */
  129. private Object ipacl = null;
  130. /**
  131. * The factory object.
  132. */
  133. private SnmpPduFactory pduFactory = null;
  134. /**
  135. * The user-data factory object.
  136. */
  137. private SnmpUserDataFactory userDataFactory = null;
  138. /**
  139. * Indicates if the SNMP protocol adaptor sends a response in case
  140. * of authentication failure
  141. */
  142. private boolean authRespEnabled = true;
  143. /**
  144. * Indicates if authentication traps are enabled.
  145. */
  146. private boolean authTrapEnabled = true;
  147. /**
  148. * The enterprise OID.
  149. * <BR>The default value is "1.3.6.1.4.1.42".
  150. */
  151. private SnmpOid enterpriseOid = new SnmpOid("1.3.6.1.4.1.42");
  152. /**
  153. * The buffer size of the SNMP protocol adaptor.
  154. * This buffer size is used for both incoming request and outgoing
  155. * inform requests.
  156. * <BR>The default value is 1024.
  157. */
  158. int bufferSize = 1024;
  159. private transient long startUpTime = 0;
  160. private transient DatagramSocket socket = null;
  161. transient DatagramSocket trapSocket = null;
  162. private transient SnmpSession informSession = null;
  163. private transient DatagramPacket packet = null;
  164. transient Vector mibs = new Vector();
  165. private transient SnmpMibTree root;
  166. /**
  167. * Whether ACL must be used.
  168. */
  169. private transient boolean useAcl = true;
  170. // SENDING SNMP INFORMS STUFF
  171. //---------------------------
  172. /**
  173. * Number of times to try an inform request before giving up.
  174. * The default number is 3.
  175. */
  176. private int maxTries = 3 ;
  177. /**
  178. * The amount of time to wait for an inform response from the manager.
  179. * The default amount of time is 3000 millisec.
  180. */
  181. private int timeout = 3 * 1000 ;
  182. // VARIABLES REQUIRED FOR IMPLEMENTING SNMP GROUP (MIBII)
  183. //-------------------------------------------------------
  184. /**
  185. * The <CODE>snmpOutTraps</CODE> value defined in MIB-II.
  186. */
  187. int snmpOutTraps=0;
  188. /**
  189. * The <CODE>snmpOutGetResponses</CODE> value defined in MIB-II.
  190. */
  191. private int snmpOutGetResponses=0;
  192. /**
  193. * The <CODE>snmpOutGenErrs</CODE> value defined in MIB-II.
  194. */
  195. private int snmpOutGenErrs=0;
  196. /**
  197. * The <CODE>snmpOutBadValues</CODE> value defined in MIB-II.
  198. */
  199. private int snmpOutBadValues=0;
  200. /**
  201. * The <CODE>snmpOutNoSuchNames</CODE> value defined in MIB-II.
  202. */
  203. private int snmpOutNoSuchNames=0;
  204. /**
  205. * The <CODE>snmpOutTooBigs</CODE> value defined in MIB-II.
  206. */
  207. private int snmpOutTooBigs=0;
  208. /**
  209. * The <CODE>snmpOutPkts</CODE> value defined in MIB-II.
  210. */
  211. int snmpOutPkts=0;
  212. /**
  213. * The <CODE>snmpInASNParseErrs</CODE> value defined in MIB-II.
  214. */
  215. private int snmpInASNParseErrs=0;
  216. /**
  217. * The <CODE>snmpInBadCommunityUses</CODE> value defined in MIB-II.
  218. */
  219. private int snmpInBadCommunityUses=0;
  220. /**
  221. * The <CODE>snmpInBadCommunityNames</CODE> value defined in MIB-II.
  222. */
  223. private int snmpInBadCommunityNames=0;
  224. /**
  225. * The <CODE>snmpInBadVersions</CODE> value defined in MIB-II.
  226. */
  227. private int snmpInBadVersions=0;
  228. /**
  229. * The <CODE>snmpInGetRequests</CODE> value defined in MIB-II.
  230. */
  231. private int snmpInGetRequests=0;
  232. /**
  233. * The <CODE>snmpInGetNexts</CODE> value defined in MIB-II.
  234. */
  235. private int snmpInGetNexts=0;
  236. /**
  237. * The <CODE>snmpInSetRequests</CODE> value defined in MIB-II.
  238. */
  239. private int snmpInSetRequests=0;
  240. /**
  241. * The <CODE>snmpInPkts</CODE> value defined in MIB-II.
  242. */
  243. private int snmpInPkts=0;
  244. /**
  245. * The <CODE>snmpInTotalReqVars</CODE> value defined in MIB-II.
  246. */
  247. private int snmpInTotalReqVars=0;
  248. /**
  249. * The <CODE>snmpInTotalSetVars</CODE> value defined in MIB-II.
  250. */
  251. private int snmpInTotalSetVars=0;
  252. /**
  253. * The <CODE>snmpInTotalSetVars</CODE> value defined in rfc 1907 MIB-II.
  254. */
  255. private int snmpSilentDrops=0;
  256. private static final String InterruptSysCallMsg =
  257. "Interrupted system call";
  258. static final SnmpOid sysUpTimeOid = new SnmpOid("1.3.6.1.2.1.1.3.0") ;
  259. static final SnmpOid snmpTrapOidOid = new SnmpOid("1.3.6.1.6.3.1.1.4.1.0");
  260. private ThreadService threadService;
  261. private static int threadNumber = 6;
  262. static {
  263. String s = System.getProperty("com.sun.jmx.snmp.threadnumber");
  264. if (s != null) {
  265. try {
  266. threadNumber = Integer.parseInt(System.getProperty(s));
  267. } catch (Exception e) {
  268. // ???
  269. System.err.println("Got wrong value for " +
  270. "com.sun.jmx.snmp.threadnumber: "+s);
  271. System.err.println("Use the default value: "+threadNumber);
  272. }
  273. }
  274. }
  275. // PUBLIC CONSTRUCTORS
  276. //--------------------
  277. /**
  278. * Initializes this SNMP protocol adaptor using the default port (161).
  279. * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
  280. * implementation of the <CODE>InetAddressAcl</CODE> interface.
  281. */
  282. public SnmpAdaptorServer() {
  283. this(true, null, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
  284. null) ;
  285. }
  286. /**
  287. * Initializes this SNMP protocol adaptor using the specified port.
  288. * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
  289. * implementation of the <CODE>InetAddressAcl</CODE> interface.
  290. *
  291. * @param port The port number for sending SNMP responses.
  292. */
  293. public SnmpAdaptorServer(int port) {
  294. this(true, null, port, null) ;
  295. }
  296. /**
  297. * Initializes this SNMP protocol adaptor using the default port (161)
  298. * and the specified IP address based ACL implementation.
  299. *
  300. * @param acl The <CODE>InetAddressAcl</CODE> implementation.
  301. * <code>null</code> means no ACL - everybody is authorized.
  302. *
  303. * @since 1.5
  304. */
  305. public SnmpAdaptorServer(InetAddressAcl acl) {
  306. this(false, acl, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
  307. null) ;
  308. }
  309. /**
  310. * Initializes this SNMP protocol adaptor using the default port (161)
  311. * and the
  312. * specified <CODE>InetAddress</CODE>.
  313. * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
  314. * implementation of the <CODE>InetAddressAcl</CODE> interface.
  315. *
  316. * @param addr The IP address to bind.
  317. */
  318. public SnmpAdaptorServer(InetAddress addr) {
  319. this(true, null, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
  320. addr) ;
  321. }
  322. /**
  323. * Initializes this SNMP protocol adaptor using the specified port and the
  324. * specified IP address based ACL implementation.
  325. *
  326. * @param acl The <CODE>InetAddressAcl</CODE> implementation.
  327. * <code>null</code> means no ACL - everybody is authorized.
  328. * @param port The port number for sending SNMP responses.
  329. *
  330. * @since 1.5
  331. */
  332. public SnmpAdaptorServer(InetAddressAcl acl, int port) {
  333. this(false, acl, port, null) ;
  334. }
  335. /**
  336. * Initializes this SNMP protocol adaptor using the specified port and the
  337. * specified <CODE>InetAddress</CODE>.
  338. * Use the {@link com.sun.jmx.snmp.IPAcl.SnmpAcl} default
  339. * implementation of the <CODE>InetAddressAcl</CODE> interface.
  340. *
  341. * @param port The port number for sending SNMP responses.
  342. * @param addr The IP address to bind.
  343. */
  344. public SnmpAdaptorServer(int port, InetAddress addr) {
  345. this(true, null, port, addr) ;
  346. }
  347. /**
  348. * Initializes this SNMP protocol adaptor using the specified IP
  349. * address based ACL implementation and the specified
  350. * <CODE>InetAddress</CODE>.
  351. *
  352. * @param acl The <CODE>InetAddressAcl</CODE> implementation.
  353. * @param addr The IP address to bind.
  354. *
  355. * @since 1.5
  356. */
  357. public SnmpAdaptorServer(InetAddressAcl acl, InetAddress addr) {
  358. this(false, acl, com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_PORT,
  359. addr) ;
  360. }
  361. /**
  362. * Initializes this SNMP protocol adaptor using the specified port, the
  363. * specified address based ACL implementation and the specified
  364. * <CODE>InetAddress</CODE>.
  365. *
  366. * @param acl The <CODE>InetAddressAcl</CODE> implementation.
  367. * @param port The port number for sending SNMP responses.
  368. * @param addr The IP address to bind.
  369. *
  370. * @since 1.5
  371. */
  372. public SnmpAdaptorServer(InetAddressAcl acl, int port, InetAddress addr) {
  373. this(false, acl, port, addr);
  374. }
  375. /**
  376. * Initializes this SNMP protocol adaptor using the specified port and the
  377. * specified <CODE>InetAddress</CODE>.
  378. * This constructor allows to initialize an SNMP adaptor without using
  379. * the ACL mechanism (by setting the <CODE>useAcl</CODE> parameter to
  380. * false).
  381. * <br>This constructor must be used in particular with a platform that
  382. * does not support the <CODE>java.security.acl</CODE> package like pJava.
  383. *
  384. * @param useAcl Specifies if this new SNMP adaptor uses the ACL mechanism.
  385. * If the specified parameter is set to <CODE>true</CODE>, this
  386. * constructor is equivalent to
  387. * <CODE>SnmpAdaptorServer((int)port,(InetAddress)addr)</CODE>.
  388. * @param port The port number for sending SNMP responses.
  389. * @param addr The IP address to bind.
  390. */
  391. public SnmpAdaptorServer(boolean useAcl, int port, InetAddress addr) {
  392. this(useAcl,null,port,addr);
  393. }
  394. // If forceAcl is `true' and InetAddressAcl is null, then a default
  395. // SnmpAcl object is created.
  396. //
  397. private SnmpAdaptorServer(boolean forceAcl, InetAddressAcl acl,
  398. int port, InetAddress addr) {
  399. super(CommunicatorServer.SNMP_TYPE) ;
  400. // Initialize the ACL implementation.
  401. //
  402. if (acl == null && forceAcl) {
  403. try {
  404. acl = (InetAddressAcl)
  405. new SnmpAcl("SNMP protocol adaptor IP ACL");
  406. } catch (UnknownHostException e) {
  407. if (isDebugOn()) {
  408. debug("constructor",
  409. "UnknowHostException when creating ACL");
  410. debug("constructor", e);
  411. }
  412. }
  413. } else {
  414. this.useAcl = (acl!=null) || forceAcl;
  415. }
  416. init(acl, port, addr) ;
  417. }
  418. // GETTERS AND SETTERS
  419. //--------------------
  420. /**
  421. * Gets the number of managers that have been processed by this
  422. * SNMP protocol adaptor since its creation.
  423. *
  424. * @return The number of managers handled by this SNMP protocol adaptor
  425. * since its creation. This counter is not reset by the <CODE>stop</CODE>
  426. * method.
  427. */
  428. public int getServedClientCount() {
  429. return super.getServedClientCount();
  430. }
  431. /**
  432. * Gets the number of managers currently being processed by this
  433. * SNMP protocol adaptor.
  434. *
  435. * @return The number of managers currently being processed by this
  436. * SNMP protocol adaptor.
  437. */
  438. public int getActiveClientCount() {
  439. return super.getActiveClientCount();
  440. }
  441. /**
  442. * Gets the maximum number of managers that this SNMP protocol adaptor can
  443. * process concurrently.
  444. *
  445. * @return The maximum number of managers that this SNMP protocol adaptor
  446. * can process concurrently.
  447. */
  448. public int getMaxActiveClientCount() {
  449. return super.getMaxActiveClientCount();
  450. }
  451. /**
  452. * Sets the maximum number of managers this SNMP protocol adaptor can
  453. * process concurrently.
  454. *
  455. * @param c The number of managers.
  456. *
  457. * @exception java.lang.IllegalStateException This method has been invoked
  458. * while the communicator was <CODE>ONLINE</CODE> or <CODE>STARTING</CODE>.
  459. */
  460. public void setMaxActiveClientCount(int c)
  461. throws java.lang.IllegalStateException {
  462. super.setMaxActiveClientCount(c);
  463. }
  464. /**
  465. * Returns the Ip address based ACL used by this SNMP protocol adaptor.
  466. * @return The <CODE>InetAddressAcl</CODE> implementation.
  467. *
  468. * @since 1.5
  469. */
  470. public InetAddressAcl getInetAddressAcl() {
  471. return (InetAddressAcl)ipacl;
  472. }
  473. /**
  474. * Returns the port used by this SNMP protocol adaptor for sending traps.
  475. * By default, port 162 is used.
  476. *
  477. * @return The port number for sending SNMP traps.
  478. */
  479. public Integer getTrapPort() {
  480. return new Integer(trapPort) ;
  481. }
  482. /**
  483. * Sets the port used by this SNMP protocol adaptor for sending traps.
  484. *
  485. * @param port The port number for sending SNMP traps.
  486. */
  487. public void setTrapPort(Integer port) {
  488. setTrapPort(port.intValue());
  489. }
  490. /**
  491. * Sets the port used by this SNMP protocol adaptor for sending traps.
  492. *
  493. * @param port The port number for sending SNMP traps.
  494. */
  495. public void setTrapPort(int port) {
  496. int val= port ;
  497. if (val < 0) throw new
  498. IllegalArgumentException("Trap port cannot be a negative value");
  499. trapPort= val ;
  500. }
  501. /**
  502. * Returns the port used by this SNMP protocol adaptor for sending
  503. * inform requests. By default, port 162 is used.
  504. *
  505. * @return The port number for sending SNMP inform requests.
  506. */
  507. public int getInformPort() {
  508. return informPort;
  509. }
  510. /**
  511. * Sets the port used by this SNMP protocol adaptor for sending
  512. * inform requests.
  513. *
  514. * @param port The port number for sending SNMP inform requests.
  515. */
  516. public void setInformPort(int port) {
  517. if (port < 0)
  518. throw new IllegalArgumentException("Inform request port "+
  519. "cannot be a negative value");
  520. informPort= port ;
  521. }
  522. /**
  523. * Returns the protocol of this SNMP protocol adaptor.
  524. *
  525. * @return The string "snmp".
  526. */
  527. public String getProtocol() {
  528. return "snmp";
  529. }
  530. /**
  531. * Returns the buffer size of this SNMP protocol adaptor.
  532. * This buffer size is used for both incoming request and outgoing
  533. * inform requests.
  534. * By default, buffer size 1024 is used.
  535. *
  536. * @return The buffer size.
  537. */
  538. public Integer getBufferSize() {
  539. return new Integer(bufferSize) ;
  540. }
  541. /**
  542. * Sets the buffer size of this SNMP protocol adaptor.
  543. * This buffer size is used for both incoming request and outgoing
  544. * inform requests.
  545. *
  546. * @param s The buffer size.
  547. *
  548. * @exception java.lang.IllegalStateException This method has been invoked
  549. * while the communicator was <CODE>ONLINE</CODE> or <CODE>STARTING</CODE>.
  550. */
  551. public void setBufferSize(Integer s)
  552. throws java.lang.IllegalStateException {
  553. if ((state == ONLINE) || (state == STARTING)) {
  554. throw new IllegalStateException("Stop server before carrying out"+
  555. " this operation");
  556. }
  557. bufferSize = s.intValue() ;
  558. }
  559. /**
  560. * Gets the number of times to try sending an inform request before
  561. * giving up.
  562. * By default, a maximum of 3 tries is used.
  563. * @return The maximun number of tries.
  564. */
  565. final public int getMaxTries() {
  566. return maxTries;
  567. }
  568. /**
  569. * Changes the maximun number of times to try sending an inform
  570. * request before giving up.
  571. * @param newMaxTries The maximun number of tries.
  572. */
  573. final public synchronized void setMaxTries(int newMaxTries) {
  574. if (newMaxTries < 0)
  575. throw new IllegalArgumentException();
  576. maxTries = newMaxTries;
  577. }
  578. /**
  579. * Gets the timeout to wait for an inform response from the manager.
  580. * By default, a timeout of 3 seconds is used.
  581. * @return The value of the timeout property.
  582. */
  583. final public int getTimeout() {
  584. return timeout;
  585. }
  586. /**
  587. * Changes the timeout to wait for an inform response from the manager.
  588. * @param newTimeout The timeout (in milliseconds).
  589. */
  590. final public synchronized void setTimeout(int newTimeout) {
  591. if (newTimeout < 0)
  592. throw new IllegalArgumentException();
  593. timeout= newTimeout;
  594. }
  595. /**
  596. * Returns the message factory of this SNMP protocol adaptor.
  597. *
  598. * @return The factory object.
  599. */
  600. public SnmpPduFactory getPduFactory() {
  601. return pduFactory ;
  602. }
  603. /**
  604. * Sets the message factory of this SNMP protocol adaptor.
  605. *
  606. * @param factory The factory object (null means the default factory).
  607. */
  608. public void setPduFactory(SnmpPduFactory factory) {
  609. if (factory == null)
  610. pduFactory = new SnmpPduFactoryBER() ;
  611. else
  612. pduFactory = factory ;
  613. }
  614. /**
  615. * Set the user-data factory of this SNMP protocol adaptor.
  616. *
  617. * @param factory The factory object (null means no factory).
  618. * @see com.sun.jmx.snmp.agent.SnmpUserDataFactory
  619. */
  620. public void setUserDataFactory(SnmpUserDataFactory factory) {
  621. userDataFactory = factory ;
  622. }
  623. /**
  624. * Get the user-data factory associated with this SNMP protocol adaptor.
  625. *
  626. * @return The factory object (null means no factory).
  627. * @see com.sun.jmx.snmp.agent.SnmpUserDataFactory
  628. */
  629. public SnmpUserDataFactory getUserDataFactory() {
  630. return userDataFactory;
  631. }
  632. /**
  633. * Returns <CODE>true</CODE> if authentication traps are enabled.
  634. * <P>
  635. * When this feature is enabled, the SNMP protocol adaptor sends
  636. * an <CODE>authenticationFailure</CODE> trap each time an
  637. * authentication fails.
  638. * <P>
  639. * The default behaviour is to send authentication traps.
  640. *
  641. * @return <CODE>true</CODE> if authentication traps are enabled,
  642. * <CODE>false</CODE> otherwise.
  643. */
  644. public boolean getAuthTrapEnabled() {
  645. return authTrapEnabled ;
  646. }
  647. /**
  648. * Sets the flag indicating if traps need to be sent in case of
  649. * authentication failure.
  650. *
  651. * @param enabled Flag indicating if traps need to be sent.
  652. */
  653. public void setAuthTrapEnabled(boolean enabled) {
  654. authTrapEnabled = enabled ;
  655. }
  656. /**
  657. * Returns <code>true</code> if this SNMP protocol adaptor sends a
  658. * response in case of authentication failure.
  659. * <P>
  660. * When this feature is enabled, the SNMP protocol adaptor sends a
  661. * response with <CODE>noSuchName</CODE> or <CODE>readOnly</CODE> when
  662. * the authentication failed. If the flag is disabled, the
  663. * SNMP protocol adaptor trashes the PDU silently.
  664. * <P>
  665. * The default behavior is to send responses.
  666. *
  667. * @return <CODE>true</CODE> if responses are sent.
  668. */
  669. public boolean getAuthRespEnabled() {
  670. return authRespEnabled ;
  671. }
  672. /**
  673. * Sets the flag indicating if responses need to be sent in case of
  674. * authentication failure.
  675. *
  676. * @param enabled Flag indicating if responses need to be sent.
  677. */
  678. public void setAuthRespEnabled(boolean enabled) {
  679. authRespEnabled = enabled ;
  680. }
  681. /**
  682. * Returns the enterprise OID. It is used by
  683. * {@link #snmpV1Trap snmpV1Trap} to fill the 'enterprise' field of the
  684. * trap request.
  685. *
  686. * @return The OID in string format "x.x.x.x".
  687. */
  688. public String getEnterpriseOid() {
  689. return enterpriseOid.toString() ;
  690. }
  691. /**
  692. * Sets the enterprise OID.
  693. *
  694. * @param oid The OID in string format "x.x.x.x".
  695. *
  696. * @exception IllegalArgumentException The string format is incorrect
  697. */
  698. public void setEnterpriseOid(String oid) throws IllegalArgumentException {
  699. enterpriseOid = new SnmpOid(oid) ;
  700. }
  701. /**
  702. * Returns the names of the MIBs available in this SNMP protocol adaptor.
  703. *
  704. * @return An array of MIB names.
  705. */
  706. public String[] getMibs() {
  707. String[] result = new String[mibs.size()] ;
  708. int i = 0 ;
  709. for (Enumeration e = mibs.elements() ; e.hasMoreElements() ;) {
  710. SnmpMibAgent mib = (SnmpMibAgent)e.nextElement() ;
  711. result[i++] = mib.getMibName();
  712. }
  713. return result ;
  714. }
  715. // GETTERS FOR SNMP GROUP (MIBII)
  716. //-------------------------------
  717. /**
  718. * Returns the <CODE>snmpOutTraps</CODE> value defined in MIB-II.
  719. *
  720. * @return The <CODE>snmpOutTraps</CODE> value.
  721. */
  722. public Long getSnmpOutTraps() {
  723. return new Long(snmpOutTraps);
  724. }
  725. /**
  726. * Returns the <CODE>snmpOutGetResponses</CODE> value defined in MIB-II.
  727. *
  728. * @return The <CODE>snmpOutGetResponses</CODE> value.
  729. */
  730. public Long getSnmpOutGetResponses() {
  731. return new Long(snmpOutGetResponses);
  732. }
  733. /**
  734. * Returns the <CODE>snmpOutGenErrs</CODE> value defined in MIB-II.
  735. *
  736. * @return The <CODE>snmpOutGenErrs</CODE> value.
  737. */
  738. public Long getSnmpOutGenErrs() {
  739. return new Long(snmpOutGenErrs);
  740. }
  741. /**
  742. * Returns the <CODE>snmpOutBadValues</CODE> value defined in MIB-II.
  743. *
  744. * @return The <CODE>snmpOutBadValues</CODE> value.
  745. */
  746. public Long getSnmpOutBadValues() {
  747. return new Long(snmpOutBadValues);
  748. }
  749. /**
  750. * Returns the <CODE>snmpOutNoSuchNames</CODE> value defined in MIB-II.
  751. *
  752. * @return The <CODE>snmpOutNoSuchNames</CODE> value.
  753. */
  754. public Long getSnmpOutNoSuchNames() {
  755. return new Long(snmpOutNoSuchNames);
  756. }
  757. /**
  758. * Returns the <CODE>snmpOutTooBigs</CODE> value defined in MIB-II.
  759. *
  760. * @return The <CODE>snmpOutTooBigs</CODE> value.
  761. */
  762. public Long getSnmpOutTooBigs() {
  763. return new Long(snmpOutTooBigs);
  764. }
  765. /**
  766. * Returns the <CODE>snmpInASNParseErrs</CODE> value defined in MIB-II.
  767. *
  768. * @return The <CODE>snmpInASNParseErrs</CODE> value.
  769. */
  770. public Long getSnmpInASNParseErrs() {
  771. return new Long(snmpInASNParseErrs);
  772. }
  773. /**
  774. * Returns the <CODE>snmpInBadCommunityUses</CODE> value defined in MIB-II.
  775. *
  776. * @return The <CODE>snmpInBadCommunityUses</CODE> value.
  777. */
  778. public Long getSnmpInBadCommunityUses() {
  779. return new Long(snmpInBadCommunityUses);
  780. }
  781. /**
  782. * Returns the <CODE>snmpInBadCommunityNames</CODE> value defined in
  783. * MIB-II.
  784. *
  785. * @return The <CODE>snmpInBadCommunityNames</CODE> value.
  786. */
  787. public Long getSnmpInBadCommunityNames() {
  788. return new Long(snmpInBadCommunityNames);
  789. }
  790. /**
  791. * Returns the <CODE>snmpInBadVersions</CODE> value defined in MIB-II.
  792. *
  793. * @return The <CODE>snmpInBadVersions</CODE> value.
  794. */
  795. public Long getSnmpInBadVersions() {
  796. return new Long(snmpInBadVersions);
  797. }
  798. /**
  799. * Returns the <CODE>snmpOutPkts</CODE> value defined in MIB-II.
  800. *
  801. * @return The <CODE>snmpOutPkts</CODE> value.
  802. */
  803. public Long getSnmpOutPkts() {
  804. return new Long(snmpOutPkts);
  805. }
  806. /**
  807. * Returns the <CODE>snmpInPkts</CODE> value defined in MIB-II.
  808. *
  809. * @return The <CODE>snmpInPkts</CODE> value.
  810. */
  811. public Long getSnmpInPkts() {
  812. return new Long(snmpInPkts);
  813. }
  814. /**
  815. * Returns the <CODE>snmpInGetRequests</CODE> value defined in MIB-II.
  816. *
  817. * @return The <CODE>snmpInGetRequests</CODE> value.
  818. */
  819. public Long getSnmpInGetRequests() {
  820. return new Long(snmpInGetRequests);
  821. }
  822. /**
  823. * Returns the <CODE>snmpInGetNexts</CODE> value defined in MIB-II.
  824. *
  825. * @return The <CODE>snmpInGetNexts</CODE> value.
  826. */
  827. public Long getSnmpInGetNexts() {
  828. return new Long(snmpInGetNexts);
  829. }
  830. /**
  831. * Returns the <CODE>snmpInSetRequests</CODE> value defined in MIB-II.
  832. *
  833. * @return The <CODE>snmpInSetRequests</CODE> value.
  834. */
  835. public Long getSnmpInSetRequests() {
  836. return new Long(snmpInSetRequests);
  837. }
  838. /**
  839. * Returns the <CODE>snmpInTotalSetVars</CODE> value defined in MIB-II.
  840. *
  841. * @return The <CODE>snmpInTotalSetVars</CODE> value.
  842. */
  843. public Long getSnmpInTotalSetVars() {
  844. return new Long(snmpInTotalSetVars);
  845. }
  846. /**
  847. * Returns the <CODE>snmpInTotalReqVars</CODE> value defined in MIB-II.
  848. *
  849. * @return The <CODE>snmpInTotalReqVars</CODE> value.
  850. */
  851. public Long getSnmpInTotalReqVars() {
  852. return new Long(snmpInTotalReqVars);
  853. }
  854. /**
  855. * Returns the <CODE>snmpSilentDrops</CODE> value defined in RFC
  856. * 1907 NMPv2-MIB .
  857. *
  858. * @return The <CODE>snmpSilentDrops</CODE> value.
  859. *
  860. * @since 1.5
  861. */
  862. public Long getSnmpSilentDrops() {
  863. return new Long(snmpSilentDrops);
  864. }
  865. /**
  866. * Returns the <CODE>snmpProxyDrops</CODE> value defined in RFC
  867. * 1907 NMPv2-MIB .
  868. *
  869. * @return The <CODE>snmpProxyDrops</CODE> value.
  870. *
  871. * @since 1.5
  872. */
  873. public Long getSnmpProxyDrops() {
  874. return new Long(0);
  875. }
  876. // PUBLIC METHODS
  877. //---------------
  878. /**
  879. * Allows the MBean to perform any operations it needs before being
  880. * registered in the MBean server.
  881. * If the name of the SNMP protocol adaptor MBean is not specified,
  882. * it is initialized with the default value:
  883. * {@link com.sun.jmx.snmp.ServiceName#DOMAIN
  884. * com.sun.jmx.snmp.ServiceName.DOMAIN}:{@link
  885. * com.sun.jmx.snmp.ServiceName#SNMP_ADAPTOR_SERVER
  886. * com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER}.
  887. * If any exception is raised, the SNMP protocol adaptor MBean will
  888. * not be registered in the MBean server.
  889. *
  890. * @param server The MBean server to register the service with.
  891. * @param name The object name.
  892. *
  893. * @return The name of the SNMP protocol adaptor registered.
  894. *
  895. * @exception java.lang.Exception
  896. */
  897. public ObjectName preRegister(MBeanServer server, ObjectName name)
  898. throws java.lang.Exception {
  899. if (name == null) {
  900. name = new ObjectName(server.getDefaultDomain() + ":" +
  901. com.sun.jmx.snmp.ServiceName.SNMP_ADAPTOR_SERVER);
  902. }
  903. return (super.preRegister(server, name));
  904. }
  905. /**
  906. * Not used in this context.
  907. */
  908. public void postRegister (Boolean registrationDone) {
  909. super.postRegister(registrationDone);
  910. }
  911. /**
  912. * Not used in this context.
  913. */
  914. public void preDeregister() throws java.lang.Exception {
  915. super.preDeregister();
  916. }
  917. /**
  918. * Not used in this context.
  919. */
  920. public void postDeregister() {
  921. super.postDeregister();
  922. }
  923. /**
  924. * Adds a new MIB in the SNMP MIB handler.
  925. *
  926. * @param mib The MIB to add.
  927. *
  928. * @return A reference to the SNMP MIB handler.
  929. *
  930. * @exception IllegalArgumentException If the parameter is null.
  931. */
  932. public SnmpMibHandler addMib(SnmpMibAgent mib)
  933. throws IllegalArgumentException {
  934. if (mib == null) {
  935. throw new IllegalArgumentException() ;
  936. }
  937. if(!mibs.contains(mib))
  938. mibs.addElement(mib);
  939. root.register(mib);
  940. return this;
  941. }
  942. /**
  943. * Adds a new MIB in the SNMP MIB handler.
  944. * This method is to be called to set a specific agent to a specific OID.
  945. * This can be useful when dealing with MIB overlapping.
  946. * Some OID can be implemented in more than one MIB. In this case,
  947. * the OID nearer agent will be used on SNMP operations.
  948. *
  949. * @param mib The MIB to add.
  950. * @param oids The set of OIDs this agent implements.
  951. *
  952. * @return A reference to the SNMP MIB handler.
  953. *
  954. * @exception IllegalArgumentException If the parameter is null.
  955. *
  956. * @since 1.5
  957. */
  958. public SnmpMibHandler addMib(SnmpMibAgent mib, SnmpOid[] oids)
  959. throws IllegalArgumentException {
  960. if (mib == null) {
  961. throw new IllegalArgumentException() ;
  962. }
  963. //If null oid array, just add it to the mib.
  964. if(oids == null)
  965. return addMib(mib);
  966. if(!mibs.contains(mib))
  967. mibs.addElement(mib);
  968. for (int i = 0; i < oids.length; i++) {
  969. root.register(mib, oids[i].longValue());
  970. }
  971. return this;
  972. }
  973. /**
  974. * Adds a new MIB in the SNMP MIB handler. In SNMP V1 and V2 the
  975. * <CODE>contextName</CODE> is useless and this method
  976. * is equivalent to <CODE>addMib(SnmpMibAgent mib)</CODE>.
  977. *
  978. * @param mib The MIB to add.
  979. * @param contextName The MIB context name.
  980. * @return A reference on the SNMP MIB handler.
  981. *
  982. * @exception IllegalArgumentException If the parameter is null.
  983. *
  984. * @since 1.5
  985. */
  986. public SnmpMibHandler addMib(SnmpMibAgent mib, String contextName)
  987. throws IllegalArgumentException {
  988. return addMib(mib);
  989. }
  990. /**
  991. * Adds a new MIB in the SNMP MIB handler. In SNMP V1 and V2 the
  992. * <CODE>contextName</CODE> is useless and this method
  993. * is equivalent to <CODE>addMib(SnmpMibAgent mib, SnmpOid[] oids)</CODE>.
  994. *
  995. * @param mib The MIB to add.
  996. * @param contextName The MIB context. If null is passed, will be
  997. * registered in the default context.
  998. * @param oids The set of OIDs this agent implements.
  999. *
  1000. * @return A reference to the SNMP MIB handler.
  1001. *
  1002. * @exception IllegalArgumentException If the parameter is null.
  1003. *
  1004. * @since 1.5
  1005. */
  1006. public SnmpMibHandler addMib(SnmpMibAgent mib,
  1007. String contextName,
  1008. SnmpOid[] oids)
  1009. throws IllegalArgumentException {
  1010. return addMib(mib, oids);
  1011. }
  1012. /**
  1013. * Removes the specified MIB from the SNMP protocol adaptor.
  1014. * In SNMP V1 and V2 the <CODE>contextName</CODE> is useless and this
  1015. * method is equivalent to <CODE>removeMib(SnmpMibAgent mib)</CODE>.
  1016. *
  1017. * @param mib The MIB to be removed.
  1018. * @param contextName The context name used at registration time.
  1019. *
  1020. * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was
  1021. * a MIB included in the SNMP MIB handler, <CODE>false</CODE>
  1022. * otherwise.
  1023. *
  1024. * @since 1.5
  1025. */
  1026. public boolean removeMib(SnmpMibAgent mib, String contextName) {
  1027. return removeMib(mib);
  1028. }
  1029. /**
  1030. * Removes the specified MIB from the SNMP protocol adaptor.
  1031. *
  1032. * @param mib The MIB to be removed.
  1033. *
  1034. * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was a MIB
  1035. * included in the SNMP MIB handler, <CODE>false</CODE> otherwise.
  1036. */
  1037. public boolean removeMib(SnmpMibAgent mib) {
  1038. root.unregister(mib);
  1039. return (mibs.removeElement(mib)) ;
  1040. }
  1041. /**
  1042. * Removes the specified MIB from the SNMP protocol adaptor.
  1043. *
  1044. * @param mib The MIB to be removed.
  1045. * @param oids The oid the MIB was previously registered for.
  1046. * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was
  1047. * a MIB included in the SNMP MIB handler, <CODE>false</CODE>
  1048. * otherwise.
  1049. *
  1050. * @since 1.5
  1051. */
  1052. public boolean removeMib(SnmpMibAgent mib, SnmpOid[] oids) {
  1053. root.unregister(mib, oids);
  1054. return (mibs.removeElement(mib)) ;
  1055. }
  1056. /**
  1057. * Removes the specified MIB from the SNMP protocol adaptor.
  1058. *
  1059. * @param mib The MIB to be removed.
  1060. * @param contextName The context name used at registration time.
  1061. * @param oids The oid the MIB was previously registered for.
  1062. * @return <CODE>true</CODE> if the specified <CODE>mib</CODE> was
  1063. * a MIB included in the SNMP MIB handler, <CODE>false</CODE>
  1064. * otherwise.
  1065. *
  1066. * @since 1.5
  1067. */
  1068. public boolean removeMib(SnmpMibAgent mib,
  1069. String contextName,
  1070. SnmpOid[] oids) {
  1071. return removeMib(mib, oids);
  1072. }
  1073. // SUBCLASSING OF COMMUNICATOR SERVER
  1074. //-----------------------------------
  1075. /**
  1076. * Creates the datagram socket.
  1077. */
  1078. protected void doBind()
  1079. throws CommunicationException, InterruptedException {
  1080. try {
  1081. synchronized (this) {
  1082. socket = new DatagramSocket(port, address) ;
  1083. }
  1084. dbgTag = makeDebugTag();
  1085. } catch (SocketException e) {
  1086. if (e.getMessage().equals(InterruptSysCallMsg))
  1087. throw new InterruptedException(e.toString()) ;
  1088. else {
  1089. if (isDebugOn()) {
  1090. debug("doBind", "cannot bind on port " + port);
  1091. }
  1092. throw new CommunicationException(e) ;
  1093. }
  1094. }
  1095. }
  1096. /**
  1097. * Return the actual port to which the adaptor is bound.
  1098. * Can be different from the port given at construction time if
  1099. * that port number was 0.
  1100. * @return the actual port to which the adaptor is bound.
  1101. **/
  1102. public int getPort() {
  1103. synchronized (this) {
  1104. if (socket != null) return socket.getLocalPort();
  1105. }
  1106. return super.getPort();
  1107. }
  1108. /**
  1109. * Closes the datagram socket.
  1110. */
  1111. protected void doUnbind()
  1112. throws CommunicationException, InterruptedException {
  1113. if (isTraceOn()) {
  1114. trace("doUnbind","Finally close the socket");
  1115. }
  1116. synchronized (this) {
  1117. if (socket != null) {
  1118. socket.close() ;
  1119. socket = null ;
  1120. // Important to inform finalize() that the socket is closed...
  1121. }
  1122. }
  1123. closeTrapSocketIfNeeded() ;
  1124. closeInformSocketIfNeeded() ;
  1125. }
  1126. void createSnmpRequestHandler(SnmpAdaptorServer server, int id,
  1127. DatagramSocket s, DatagramPacket p,
  1128. SnmpMibTree tree, Vector m, Object a,
  1129. SnmpPduFactory factory,
  1130. SnmpUserDataFactory dataFactory,
  1131. MBeanServer f, ObjectName n) {
  1132. final SnmpRequestHandler handler =
  1133. new SnmpRequestHandler(this, id, s, p, tree, m, a, factory,
  1134. dataFactory, f, n);
  1135. threadService.submitTask(handler);
  1136. }
  1137. /**
  1138. * Reads a packet from the datagram socket and creates a request
  1139. * handler which decodes and processes the request.
  1140. */
  1141. protected void doReceive()
  1142. throws CommunicationException, InterruptedException {
  1143. // Let's wait for something to be received.
  1144. //
  1145. try {
  1146. packet = new DatagramPacket(new byte[bufferSize], bufferSize) ;
  1147. socket.receive(packet);
  1148. int state = getState();
  1149. if(state != ONLINE) {
  1150. if (isTraceOn()) {
  1151. trace("doReceive",
  1152. "received a message but state not online, returning.");
  1153. }
  1154. return;
  1155. }
  1156. createSnmpRequestHandler(this, servedClientCount, socket,
  1157. packet, root, mibs, ipacl, pduFactory,
  1158. userDataFactory, topMBS, objectName);
  1159. } catch (SocketException e) {
  1160. // Let's check if we have been interrupted by stop().
  1161. //
  1162. if (e.getMessage().equals(InterruptSysCallMsg))
  1163. throw new InterruptedException(e.toString()) ;
  1164. else
  1165. throw new CommunicationException(e) ;
  1166. } catch (InterruptedIOException e) {
  1167. throw new InterruptedException(e.toString()) ;
  1168. } catch (CommunicationException e) {
  1169. throw e ;
  1170. } catch (Exception e) {
  1171. throw new CommunicationException(e) ;
  1172. }
  1173. if (isTraceOn()) {
  1174. trace("doReceive", "received a message");
  1175. }
  1176. }
  1177. protected void doError(Exception e) throws CommunicationException {
  1178. return;
  1179. }
  1180. /**
  1181. * Not used in this context.
  1182. */
  1183. protected void doProcess()
  1184. throws CommunicationException, InterruptedException {
  1185. }
  1186. /**
  1187. * The number of times the communicator server will attempt
  1188. * to bind before giving up.
  1189. * We attempt only once...
  1190. * @return 1
  1191. **/
  1192. protected int getBindTries() {
  1193. return 1;
  1194. }
  1195. /**
  1196. * Stops this SNMP protocol adaptor.
  1197. * Closes the datagram socket.
  1198. * <p>
  1199. * Has no effect if this SNMP protocol adaptor is <CODE>OFFLINE</CODE> or
  1200. * <CODE>STOPPING</CODE>.
  1201. */
  1202. public void stop(){
  1203. final int port = getPort();
  1204. if (isTraceOn()) {
  1205. trace("stop", "Stopping: using port " + port);
  1206. }
  1207. if ((state == ONLINE) || (state == STARTING)){
  1208. super.stop();
  1209. try {
  1210. DatagramSocket sn = new DatagramSocket(0);
  1211. try {
  1212. byte[] ob = new byte[1];
  1213. DatagramPacket pk;
  1214. if (address != null)
  1215. pk = new DatagramPacket(ob , 1, address, port);
  1216. else
  1217. pk = new DatagramPacket(ob , 1,
  1218. java.net.InetAddress.getLocalHost(), port);
  1219. if (isTraceOn()) {
  1220. trace("stop", "Sending: using port " + port);
  1221. }
  1222. sn.send(pk);
  1223. } finally {
  1224. sn.close();
  1225. }
  1226. } catch (Throwable e){
  1227. if (isDebugOn()) {
  1228. debug("stop", e);
  1229. }
  1230. }
  1231. }
  1232. }
  1233. // SENDING SNMP TRAPS STUFF
  1234. //-------------------------
  1235. /**
  1236. * Sends a trap using SNMP V1 trap format.
  1237. * <BR>The trap is sent to each destination defined in the ACL file
  1238. * (if available).
  1239. * If no ACL file or no destinations are available, the trap is sent
  1240. * to the local host.
  1241. *
  1242. * @param generic The generic number of the trap.
  1243. * @param specific The specific number of the trap.
  1244. * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
  1245. *
  1246. * @exception IOException An I/O error occurred while sending the trap.
  1247. * @exception SnmpStatusException If the trap exceeds the limit defined
  1248. * by <CODE>bufferSize</CODE>.
  1249. */
  1250. public void snmpV1Trap(int generic, int specific,
  1251. SnmpVarBindList varBindList)
  1252. throws IOException, SnmpStatusException {
  1253. if (isTraceOn()) {
  1254. trace("snmpV1Trap", "generic=" + generic +
  1255. ", specific=" + specific);
  1256. }
  1257. // First, make an SNMP V1 trap pdu
  1258. //
  1259. SnmpPduTrap pdu = new SnmpPduTrap() ;
  1260. pdu.address = null ;
  1261. pdu.port = trapPort ;
  1262. pdu.type = pduV1TrapPdu ;
  1263. pdu.version = snmpVersionOne ;
  1264. pdu.community = null ;
  1265. pdu.enterprise = enterpriseOid ;
  1266. pdu.genericTrap = generic ;
  1267. pdu.specificTrap = specific ;
  1268. pdu.timeStamp = getSysUpTime();
  1269. if (varBindList != null) {
  1270. pdu.varBindList = new SnmpVarBind[varBindList.size()] ;
  1271. varBindList.copyInto(pdu.varBindList);
  1272. }
  1273. else
  1274. pdu.varBindList = null ;
  1275. // If the local host cannot be determined, we put 0.0.0.0 in agentAddr
  1276. try {
  1277. if (address != null)
  1278. pdu.agentAddr = handleMultipleIpVersion(address.getAddress());
  1279. else pdu.agentAddr =
  1280. handleMultipleIpVersion(InetAddress.getLocalHost().getAddress());
  1281. } catch (UnknownHostException e) {
  1282. byte[] zeroedAddr = new byte[4];
  1283. pdu.agentAddr = handleMultipleIpVersion(zeroedAddr) ;
  1284. }
  1285. // Next, send the pdu to all destinations defined in ACL
  1286. //
  1287. sendTrapPdu(pdu) ;
  1288. }
  1289. private SnmpIpAddress handleMultipleIpVersion(byte[] address) {
  1290. if(address.length == 4)
  1291. return new SnmpIpAddress(address);
  1292. else {
  1293. if(isDebugOn())
  1294. debug("handleMultipleIPVersion",
  1295. "Not an IPv4 address, return null");
  1296. return null;
  1297. }
  1298. }
  1299. /**
  1300. * Sends a trap using SNMP V1 trap format.
  1301. * <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
  1302. * destination using the specified community string (and the ACL file
  1303. * is not used).
  1304. *
  1305. * @param addr The <CODE>InetAddress</CODE> destination of the trap.
  1306. * @param cs The community string to be used for the trap.
  1307. * @param generic The generic number of the trap.
  1308. * @param specific The specific number of the trap.
  1309. * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
  1310. *
  1311. * @exception IOException An I/O error occurred while sending the trap.
  1312. * @exception SnmpStatusException If the trap exceeds the limit defined
  1313. * by <CODE>bufferSize</CODE>.
  1314. */
  1315. public void snmpV1Trap(InetAddress addr, String cs, int generic,
  1316. int specific, SnmpVarBindList varBindList)
  1317. throws IOException, SnmpStatusException {
  1318. if (isTraceOn()) {
  1319. trace("snmpV1Trap", "generic=" + generic + ", specific=" +
  1320. specific);
  1321. }
  1322. // First, make an SNMP V1 trap pdu
  1323. //
  1324. SnmpPduTrap pdu = new SnmpPduTrap() ;
  1325. pdu.address = null ;
  1326. pdu.port = trapPort ;
  1327. pdu.type = pduV1TrapPdu ;
  1328. pdu.version = snmpVersionOne ;
  1329. if(cs != null)
  1330. pdu.community = cs.getBytes();
  1331. else
  1332. pdu.community = null ;
  1333. pdu.enterprise = enterpriseOid ;
  1334. pdu.genericTrap = generic ;
  1335. pdu.specificTrap = specific ;
  1336. pdu.timeStamp = getSysUpTime();
  1337. if (varBindList != null) {
  1338. pdu.varBindList = new SnmpVarBind[varBindList.size()] ;
  1339. varBindList.copyInto(pdu.varBindList);
  1340. }
  1341. else
  1342. pdu.varBindList = null ;
  1343. // If the local host cannot be determined, we put 0.0.0.0 in agentAddr
  1344. try {
  1345. if (address != null)
  1346. pdu.agentAddr = handleMultipleIpVersion(address.getAddress());
  1347. else pdu.agentAddr =
  1348. handleMultipleIpVersion(InetAddress.getLocalHost().getAddress());
  1349. } catch (UnknownHostException e) {
  1350. byte[] zeroedAddr = new byte[4];
  1351. pdu.agentAddr = handleMultipleIpVersion(zeroedAddr) ;
  1352. }
  1353. // Next, send the pdu to the specified destination
  1354. //
  1355. if(addr != null)
  1356. sendTrapPdu(addr, pdu) ;
  1357. else
  1358. sendTrapPdu(pdu);
  1359. }
  1360. /**
  1361. * Sends a trap using SNMP V1 trap format.
  1362. * <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
  1363. * destination using the specified parameters (and the ACL file is not
  1364. * used).
  1365. * Note that if the specified <CODE>InetAddress</CODE> destination is null,
  1366. * then the ACL file mechanism is used.
  1367. *
  1368. * @param addr The <CODE>InetAddress</CODE> destination of the trap.
  1369. * @param agentAddr The agent address to be used for the trap.
  1370. * @param cs The community string to be used for the trap.
  1371. * @param enterpOid The enterprise OID to be used for the trap.
  1372. * @param generic The generic number of the trap.
  1373. * @param specific The specific number of the trap.
  1374. * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
  1375. * @param time The time stamp (overwrite the current time).
  1376. *
  1377. * @exception IOException An I/O error occurred while sending the trap.
  1378. * @exception SnmpStatusException If the trap exceeds the limit defined
  1379. * by <CODE>bufferSize</CODE>.
  1380. *
  1381. * @since 1.5
  1382. */
  1383. public void snmpV1Trap(InetAddress addr,
  1384. SnmpIpAddress agentAddr,
  1385. String cs,
  1386. SnmpOid enterpOid,
  1387. int generic,
  1388. int specific,
  1389. SnmpVarBindList varBindList,
  1390. SnmpTimeticks time)
  1391. throws IOException, SnmpStatusException {
  1392. snmpV1Trap(addr,
  1393. trapPort,
  1394. agentAddr,
  1395. cs,
  1396. enterpOid,
  1397. generic,
  1398. specific,
  1399. varBindList,
  1400. time);
  1401. }
  1402. /**
  1403. * Sends a trap using SNMP V1 trap format.
  1404. * <BR>The trap is sent to the specified <CODE>SnmpPeer</CODE> destination.
  1405. * The community string used is the one located in the
  1406. * <CODE>SnmpPeer</CODE> parameters
  1407. * (<CODE>SnmpParameters.getRdCommunity() </CODE>).
  1408. *
  1409. * @param peer The <CODE>SnmpPeer</CODE> destination of the trap.
  1410. * @param agentAddr The agent address to be used for the trap.
  1411. * @param enterpOid The enterprise OID to be used for the trap.
  1412. * @param generic The generic number of the trap.
  1413. * @param specific The specific number of the trap.
  1414. * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
  1415. * @param time The time stamp (overwrite the current time).
  1416. *
  1417. * @exception IOException An I/O error occurred while sending the trap.
  1418. * @exception SnmpStatusException If the trap exceeds the limit
  1419. * defined by <CODE>bufferSize</CODE>.
  1420. *
  1421. * @since 1.5
  1422. */
  1423. public void snmpV1Trap(SnmpPeer peer,
  1424. SnmpIpAddress agentAddr,
  1425. SnmpOid enterpOid,
  1426. int generic,
  1427. int specific,
  1428. SnmpVarBindList varBindList,
  1429. SnmpTimeticks time)
  1430. throws IOException, SnmpStatusException {
  1431. SnmpParameters p = (SnmpParameters) peer.getParams();
  1432. snmpV1Trap(peer.getDestAddr(),
  1433. peer.getDestPort(),
  1434. agentAddr,
  1435. p.getRdCommunity(),
  1436. enterpOid,
  1437. generic,
  1438. specific,
  1439. varBindList,
  1440. time);
  1441. }
  1442. private void snmpV1Trap(InetAddress addr,
  1443. int port,
  1444. SnmpIpAddress agentAddr,
  1445. String cs,
  1446. SnmpOid enterpOid,
  1447. int generic,
  1448. int specific,
  1449. SnmpVarBindList varBindList,
  1450. SnmpTimeticks time)
  1451. throws IOException, SnmpStatusException {
  1452. if (isTraceOn()) {
  1453. trace("snmpV1Trap", "generic=" + generic + ", specific=" +
  1454. specific);
  1455. }
  1456. // First, make an SNMP V1 trap pdu
  1457. //
  1458. SnmpPduTrap pdu = new SnmpPduTrap() ;
  1459. pdu.address = null ;
  1460. pdu.port = port ;
  1461. pdu.type = pduV1TrapPdu ;
  1462. pdu.version = snmpVersionOne ;
  1463. //Diff start
  1464. if(cs != null)
  1465. pdu.community = cs.getBytes();
  1466. else
  1467. pdu.community = null ;
  1468. //Diff end
  1469. // Diff start
  1470. if(enterpOid != null)
  1471. pdu.enterprise = enterpOid;
  1472. else
  1473. pdu.enterprise = enterpriseOid ;
  1474. //Diff end
  1475. pdu.genericTrap = generic ;
  1476. pdu.specificTrap = specific ;
  1477. //Diff start
  1478. if(time != null)
  1479. pdu.timeStamp = time.longValue();
  1480. else
  1481. pdu.timeStamp = getSysUpTime();
  1482. //Diff end
  1483. if (varBindList != null) {
  1484. pdu.varBindList = new SnmpVarBind[varBindList.size()] ;
  1485. varBindList.copyInto(pdu.varBindList);
  1486. }
  1487. else
  1488. pdu.varBindList = null ;
  1489. if (agentAddr == null) {
  1490. // If the local host cannot be determined,
  1491. // we put 0.0.0.0 in agentAddr
  1492. try {
  1493. final InetAddress inetAddr =
  1494. (address!=null)?address:InetAddress.getLocalHost();
  1495. agentAddr = handleMultipleIpVersion(inetAddr.getAddress());
  1496. } catch (UnknownHostException e) {
  1497. byte[] zeroedAddr = new byte[4];
  1498. agentAddr = handleMultipleIpVersion(zeroedAddr);
  1499. }
  1500. }
  1501. pdu.agentAddr = agentAddr;
  1502. // Next, send the pdu to the specified destination
  1503. //
  1504. // Diff start
  1505. if(addr != null)
  1506. sendTrapPdu(addr, pdu) ;
  1507. else
  1508. sendTrapPdu(pdu);
  1509. //End diff
  1510. }
  1511. /**
  1512. * Sends a trap using SNMP V2 trap format.
  1513. * <BR>The trap is sent to the specified <CODE>SnmpPeer</CODE> destination.
  1514. * <BR>The community string used is the one located in the
  1515. * <CODE>SnmpPeer</CODE> parameters
  1516. * (<CODE>SnmpParameters.getRdCommunity() </CODE>).
  1517. * <BR>The variable list included in the outgoing trap is composed of
  1518. * the following items:
  1519. * <UL>
  1520. * <LI><CODE>sysUpTime.0</CODE> with the value specified by
  1521. * <CODE>time</CODE></LI>
  1522. * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
  1523. * <CODE>trapOid</CODE></LI>
  1524. * <LI><CODE>all the (oid,values)</CODE> from the specified
  1525. * <CODE>varBindList</CODE></LI>
  1526. * </UL>
  1527. *
  1528. * @param peer The <CODE>SnmpPeer</CODE> destination of the trap.
  1529. * @param trapOid The OID identifying the trap.
  1530. * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
  1531. * @param time The time stamp (overwrite the current time).
  1532. *
  1533. * @exception IOException An I/O error occurred while sending the trap.
  1534. * @exception SnmpStatusException If the trap exceeds the limit
  1535. * defined by <CODE>bufferSize</CODE>.
  1536. *
  1537. * @since 1.5
  1538. */
  1539. public void snmpV2Trap(SnmpPeer peer,
  1540. SnmpOid trapOid,
  1541. SnmpVarBindList varBindList,
  1542. SnmpTimeticks time)
  1543. throws IOException, SnmpStatusException {
  1544. SnmpParameters p = (SnmpParameters) peer.getParams();
  1545. snmpV2Trap(peer.getDestAddr(),
  1546. peer.getDestPort(),
  1547. p.getRdCommunity(),
  1548. trapOid,
  1549. varBindList,
  1550. time);
  1551. }
  1552. /**
  1553. * Sends a trap using SNMP V2 trap format.
  1554. * <BR>The trap is sent to each destination defined in the ACL file
  1555. * (if available). If no ACL file or no destinations are available,
  1556. * the trap is sent to the local host.
  1557. * <BR>The variable list included in the outgoing trap is composed of
  1558. * the following items:
  1559. * <UL>
  1560. * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
  1561. * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
  1562. * <CODE>trapOid</CODE></LI>
  1563. * <LI><CODE>all the (oid,values)</CODE> from the specified
  1564. * <CODE>varBindList</CODE></LI>
  1565. * </UL>
  1566. *
  1567. * @param trapOid The OID identifying the trap.
  1568. * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
  1569. *
  1570. * @exception IOException An I/O error occurred while sending the trap.
  1571. * @exception SnmpStatusException If the trap exceeds the limit defined
  1572. * by <CODE>bufferSize</CODE>.
  1573. */
  1574. public void snmpV2Trap(SnmpOid trapOid, SnmpVarBindList varBindList)
  1575. throws IOException, SnmpStatusException {
  1576. if (isTraceOn()) {
  1577. trace("snmpV2Trap", "trapOid=" + trapOid);
  1578. }
  1579. // First, make an SNMP V2 trap pdu
  1580. // We clone varBindList and insert sysUpTime and snmpTrapOid
  1581. //
  1582. SnmpPduRequest pdu = new SnmpPduRequest() ;
  1583. pdu.address = null ;
  1584. pdu.port = trapPort ;
  1585. pdu.type = pduV2TrapPdu ;
  1586. pdu.version = snmpVersionTwo ;
  1587. pdu.community = null ;
  1588. SnmpVarBindList fullVbl ;
  1589. if (varBindList != null)
  1590. fullVbl = (SnmpVarBindList)varBindList.clone() ;
  1591. else
  1592. fullVbl = new SnmpVarBindList(2) ;
  1593. SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
  1594. fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
  1595. fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
  1596. 0);
  1597. pdu.varBindList = new SnmpVarBind[fullVbl.size()] ;
  1598. fullVbl.copyInto(pdu.varBindList) ;
  1599. // Next, send the pdu to all destinations defined in ACL
  1600. //
  1601. sendTrapPdu(pdu) ;
  1602. }
  1603. /**
  1604. * Sends a trap using SNMP V2 trap format.
  1605. * <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
  1606. * destination using the specified community string (and the ACL file
  1607. * is not used).
  1608. * <BR>The variable list included in the outgoing trap is composed of
  1609. * the following items:
  1610. * <UL>
  1611. * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
  1612. * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
  1613. * <CODE>trapOid</CODE></LI>
  1614. * <LI><CODE>all the (oid,values)</CODE> from the specified
  1615. * <CODE>varBindList</CODE></LI>
  1616. * </UL>
  1617. *
  1618. * @param addr The <CODE>InetAddress</CODE> destination of the trap.
  1619. * @param cs The community string to be used for the trap.
  1620. * @param trapOid The OID identifying the trap.
  1621. * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
  1622. *
  1623. * @exception IOException An I/O error occurred while sending the trap.
  1624. * @exception SnmpStatusException If the trap exceeds the limit
  1625. * defined by <CODE>bufferSize</CODE>.
  1626. */
  1627. public void snmpV2Trap(InetAddress addr, String cs, SnmpOid trapOid,
  1628. SnmpVarBindList varBindList)
  1629. throws IOException, SnmpStatusException {
  1630. if (isTraceOn()) {
  1631. trace("snmpV2Trap", "trapOid=" + trapOid);
  1632. }
  1633. // First, make an SNMP V2 trap pdu
  1634. // We clone varBindList and insert sysUpTime and snmpTrapOid
  1635. //
  1636. SnmpPduRequest pdu = new SnmpPduRequest() ;
  1637. pdu.address = null ;
  1638. pdu.port = trapPort ;
  1639. pdu.type = pduV2TrapPdu ;
  1640. pdu.version = snmpVersionTwo ;
  1641. if(cs != null)
  1642. pdu.community = cs.getBytes();
  1643. else
  1644. pdu.community = null;
  1645. SnmpVarBindList fullVbl ;
  1646. if (varBindList != null)
  1647. fullVbl = (SnmpVarBindList)varBindList.clone() ;
  1648. else
  1649. fullVbl = new SnmpVarBindList(2) ;
  1650. SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
  1651. fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
  1652. fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
  1653. 0);
  1654. pdu.varBindList = new SnmpVarBind[fullVbl.size()] ;
  1655. fullVbl.copyInto(pdu.varBindList) ;
  1656. // Next, send the pdu to the specified destination
  1657. //
  1658. if(addr != null)
  1659. sendTrapPdu(addr, pdu);
  1660. else
  1661. sendTrapPdu(pdu);
  1662. }
  1663. /**
  1664. * Sends a trap using SNMP V2 trap format.
  1665. * <BR>The trap is sent to the specified <CODE>InetAddress</CODE>
  1666. * destination using the specified parameters (and the ACL file is not
  1667. * used).
  1668. * Note that if the specified <CODE>InetAddress</CODE> destination is null,
  1669. * then the ACL file mechanism is used.
  1670. * <BR>The variable list included in the outgoing trap is composed of the
  1671. * following items:
  1672. * <UL>
  1673. * <LI><CODE>sysUpTime.0</CODE> with the value specified by
  1674. * <CODE>time</CODE></LI>
  1675. * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
  1676. * <CODE>trapOid</CODE></LI>
  1677. * <LI><CODE>all the (oid,values)</CODE> from the specified
  1678. * <CODE>varBindList</CODE></LI>
  1679. * </UL>
  1680. *
  1681. * @param addr The <CODE>InetAddress</CODE> destination of the trap.
  1682. * @param cs The community string to be used for the trap.
  1683. * @param trapOid The OID identifying the trap.
  1684. * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
  1685. * @param time The time stamp (overwrite the current time).
  1686. *
  1687. * @exception IOException An I/O error occurred while sending the trap.
  1688. * @exception SnmpStatusException If the trap exceeds the limit
  1689. * defined by <CODE>bufferSize</CODE>.
  1690. *
  1691. * @since 1.5
  1692. */
  1693. public void snmpV2Trap(InetAddress addr,
  1694. String cs,
  1695. SnmpOid trapOid,
  1696. SnmpVarBindList varBindList,
  1697. SnmpTimeticks time)
  1698. throws IOException, SnmpStatusException {
  1699. snmpV2Trap(addr,
  1700. trapPort,
  1701. cs,
  1702. trapOid,
  1703. varBindList,
  1704. time);
  1705. }
  1706. private void snmpV2Trap(InetAddress addr,
  1707. int port,
  1708. String cs,
  1709. SnmpOid trapOid,
  1710. SnmpVarBindList varBindList,
  1711. SnmpTimeticks time)
  1712. throws IOException, SnmpStatusException {
  1713. if (isTraceOn()) {
  1714. trace("snmpV2Trap", "trapOid=" + trapOid +
  1715. "\ncommunity=" + cs + "\naddr=" + addr +
  1716. "\nvarBindList=" + varBindList + "\ntime=" + time +
  1717. "\ntrapPort=" + port);
  1718. }
  1719. // First, make an SNMP V2 trap pdu
  1720. // We clone varBindList and insert sysUpTime and snmpTrapOid
  1721. //
  1722. SnmpPduRequest pdu = new SnmpPduRequest() ;
  1723. pdu.address = null ;
  1724. pdu.port = port ;
  1725. pdu.type = pduV2TrapPdu ;
  1726. pdu.version = snmpVersionTwo ;
  1727. if(cs != null)
  1728. pdu.community = cs.getBytes();
  1729. else
  1730. pdu.community = null;
  1731. SnmpVarBindList fullVbl ;
  1732. if (varBindList != null)
  1733. fullVbl = (SnmpVarBindList)varBindList.clone() ;
  1734. else
  1735. fullVbl = new SnmpVarBindList(2) ;
  1736. // Only difference with other
  1737. SnmpTimeticks sysUpTimeValue = null;
  1738. if(time != null)
  1739. sysUpTimeValue = time;
  1740. else
  1741. sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
  1742. //End of diff
  1743. fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
  1744. fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
  1745. 0);
  1746. pdu.varBindList = new SnmpVarBind[fullVbl.size()] ;
  1747. fullVbl.copyInto(pdu.varBindList) ;
  1748. // Next, send the pdu to the specified destination
  1749. //
  1750. // Diff start
  1751. if(addr != null)
  1752. sendTrapPdu(addr, pdu) ;
  1753. else
  1754. sendTrapPdu(pdu);
  1755. //End diff
  1756. }
  1757. /**
  1758. * Send the specified trap PDU to the passed <CODE>InetAddress</CODE>.
  1759. * @param address The destination address.
  1760. * @param pdu The pdu to send.
  1761. * @exception IOException An I/O error occurred while sending the trap.
  1762. * @exception SnmpStatusException If the trap exceeds the limit
  1763. * defined by <CODE>bufferSize</CODE>.
  1764. *
  1765. * @since 1.5
  1766. */
  1767. public void snmpPduTrap(InetAddress address, SnmpPduPacket pdu)
  1768. throws IOException, SnmpStatusException {
  1769. if(address != null)
  1770. sendTrapPdu(address, pdu);
  1771. else
  1772. sendTrapPdu(pdu);
  1773. }
  1774. /**
  1775. * Send the specified trap PDU to the passed <CODE>SnmpPeer</CODE>.
  1776. * @param peer The destination peer. The Read community string is used of
  1777. * <CODE>SnmpParameters</CODE> is used as the trap community string.
  1778. * @param pdu The pdu to send.
  1779. * @exception IOException An I/O error occurred while sending the trap.
  1780. * @exception SnmpStatusException If the trap exceeds the limit defined
  1781. * by <CODE>bufferSize</CODE>.
  1782. * @since 1.5
  1783. */
  1784. public void snmpPduTrap(SnmpPeer peer,
  1785. SnmpPduPacket pdu)
  1786. throws IOException, SnmpStatusException {
  1787. if(peer != null) {
  1788. pdu.port = peer.getDestPort();
  1789. sendTrapPdu(peer.getDestAddr(), pdu);
  1790. }
  1791. else {
  1792. pdu.port = getTrapPort().intValue();
  1793. sendTrapPdu(pdu);
  1794. }
  1795. }
  1796. /**
  1797. * Send the specified trap PDU to every destinations from the ACL file.
  1798. */
  1799. private void sendTrapPdu(SnmpPduPacket pdu)
  1800. throws SnmpStatusException, IOException {
  1801. // Make an SNMP message from the pdu
  1802. //
  1803. SnmpMessage msg = null ;
  1804. try {
  1805. msg = (SnmpMessage)pduFactory.encodeSnmpPdu(pdu, bufferSize) ;
  1806. if (msg == null) {
  1807. throw new SnmpStatusException(
  1808. SnmpDefinitions.snmpRspAuthorizationError) ;
  1809. }
  1810. }
  1811. catch (SnmpTooBigException x) {
  1812. if (isDebugOn()) {
  1813. debug("sendTrapPdu", "trap pdu is too big");
  1814. debug("sendTrapPdu", "trap hasn't been sent to anyone");
  1815. }
  1816. throw new SnmpStatusException(SnmpDefinitions.snmpRspTooBig) ;
  1817. // FIXME: is the right exception to throw ?
  1818. // We could simply forward SnmpTooBigException ?
  1819. }
  1820. // Now send the SNMP message to each destination
  1821. //
  1822. int sendingCount = 0 ;
  1823. openTrapSocketIfNeeded() ;
  1824. if (ipacl != null) {
  1825. Enumeration ed = ((InetAddressAcl)ipacl).getTrapDestinations() ;
  1826. while (ed.hasMoreElements()) {
  1827. msg.address = (InetAddress)ed.nextElement() ;
  1828. Enumeration ec = ((InetAddressAcl)ipacl).
  1829. getTrapCommunities(msg.address) ;
  1830. while (ec.hasMoreElements()) {
  1831. msg.community = ((String)ec.nextElement()).getBytes() ;
  1832. try {
  1833. sendTrapMessage(msg) ;
  1834. sendingCount++ ;
  1835. }
  1836. catch (SnmpTooBigException x) {
  1837. if (isDebugOn()) {
  1838. debug("sendTrapPdu", "trap pdu is too big");
  1839. debug("sendTrapPdu", "trap hasn't been sent to "+
  1840. msg.address);
  1841. }
  1842. }
  1843. }
  1844. }
  1845. }
  1846. // If there is no destination defined or if everything has failed
  1847. // we tried to send the trap to the local host (as suggested by
  1848. // mister Olivier Reisacher).
  1849. //
  1850. if (sendingCount == 0) {
  1851. try {
  1852. msg.address = InetAddress.getLocalHost() ;
  1853. sendTrapMessage(msg) ;
  1854. } catch (SnmpTooBigException x) {
  1855. if (isDebugOn()) {
  1856. debug("sendTrapPdu", "trap pdu is too big");
  1857. debug("sendTrapPdu", "trap hasn't been sent");
  1858. }
  1859. } catch (UnknownHostException e) {
  1860. if (isDebugOn()) {
  1861. debug("sendTrapPdu", "cannot get the local host");
  1862. debug("sendTrapPdu", "trap hasn't been sent");
  1863. }
  1864. }
  1865. }
  1866. closeTrapSocketIfNeeded() ;
  1867. }
  1868. /**
  1869. * Send the specified trap PDU to the specified destination.
  1870. */
  1871. private void sendTrapPdu(InetAddress addr, SnmpPduPacket pdu)
  1872. throws SnmpStatusException, IOException {
  1873. // Make an SNMP message from the pdu
  1874. //
  1875. SnmpMessage msg = null ;
  1876. try {
  1877. msg = (SnmpMessage)pduFactory.encodeSnmpPdu(pdu, bufferSize) ;
  1878. if (msg == null) {
  1879. throw new SnmpStatusException(
  1880. SnmpDefinitions.snmpRspAuthorizationError) ;
  1881. }
  1882. } catch (SnmpTooBigException x) {
  1883. if (isDebugOn()) {
  1884. debug("sendTrapPdu", "trap pdu is too big");
  1885. debug("sendTrapPdu",
  1886. "trap hasn't been sent to the specified host");
  1887. }
  1888. throw new SnmpStatusException(SnmpDefinitions.snmpRspTooBig) ;
  1889. // FIXME: is the right exception to throw ?
  1890. // We could simply forward SnmpTooBigException ?
  1891. }
  1892. // Now send the SNMP message to specified destination
  1893. //
  1894. openTrapSocketIfNeeded() ;
  1895. if (addr != null) {
  1896. msg.address = addr;
  1897. try {
  1898. sendTrapMessage(msg) ;
  1899. } catch (SnmpTooBigException x) {
  1900. if (isDebugOn()) {
  1901. debug("sendTrapPdu", "trap pdu is too big");
  1902. debug("sendTrapPdu", "trap hasn't been sent to " +
  1903. msg.address);
  1904. }
  1905. }
  1906. }
  1907. closeTrapSocketIfNeeded() ;
  1908. }
  1909. /**
  1910. * Send the specified message on trapSocket.
  1911. */
  1912. private void sendTrapMessage(SnmpMessage msg)
  1913. throws IOException, SnmpTooBigException {
  1914. byte[] buffer = new byte[bufferSize] ;
  1915. DatagramPacket packet = new DatagramPacket(buffer, buffer.length) ;
  1916. int encodingLength = msg.encodeMessage(buffer) ;
  1917. packet.setLength(encodingLength) ;
  1918. packet.setAddress(msg.address) ;
  1919. packet.setPort(msg.port) ;
  1920. if (isTraceOn()) {
  1921. trace("sendTrapMessage", "sending trap to " + msg.address + ":" +
  1922. msg.port);
  1923. }
  1924. trapSocket.send(packet) ;
  1925. if (isTraceOn()) {
  1926. trace("sendTrapMessage", "sent to " + msg.address + ":" +
  1927. msg.port);
  1928. }
  1929. snmpOutTraps++;
  1930. snmpOutPkts++;
  1931. }
  1932. /**
  1933. * Open trapSocket if it's not already done.
  1934. */
  1935. synchronized void openTrapSocketIfNeeded() throws SocketException {
  1936. if (trapSocket == null) {
  1937. trapSocket = new DatagramSocket(0, address) ;
  1938. if (isTraceOn()) {
  1939. trace("openTrapSocketIfNeeded", "using port " +
  1940. trapSocket.getLocalPort() + " to send traps");
  1941. }
  1942. }
  1943. }
  1944. /**
  1945. * Close trapSocket if the SNMP protocol adaptor is not ONLINE.
  1946. */
  1947. synchronized void closeTrapSocketIfNeeded() {
  1948. if ((trapSocket != null) && (state != ONLINE)) {
  1949. trapSocket.close() ;
  1950. trapSocket = null ;
  1951. }
  1952. }
  1953. // SENDING SNMP INFORMS STUFF
  1954. //---------------------------
  1955. /**
  1956. * Sends an inform using SNMP V2 inform request format.
  1957. * <BR>The inform request is sent to each destination defined in the ACL
  1958. * file (if available).
  1959. * If no ACL file or no destinations are available, the inform request is
  1960. * sent to the local host.
  1961. * <BR>The variable list included in the outgoing inform is composed of
  1962. * the following items:
  1963. * <UL>
  1964. * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
  1965. * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
  1966. * <CODE>trapOid</CODE></LI>
  1967. * <LI><CODE>all the (oid,values)</CODE> from the specified
  1968. * <CODE>varBindList</CODE></LI>
  1969. * </UL>
  1970. * To send an inform request, the SNMP adaptor server must be active.
  1971. *
  1972. * @param cb The callback that is invoked when a request is complete.
  1973. * @param trapOid The OID identifying the trap.
  1974. * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
  1975. *
  1976. * @return A vector of {@link com.sun.jmx.snmp.daemon.SnmpInformRequest}
  1977. * objects.
  1978. * <P>If there is no destination host for this inform request,
  1979. * the returned vector will be empty.
  1980. *
  1981. * @exception IllegalStateException This method has been invoked while
  1982. * the SNMP adaptor server was not active.
  1983. * @exception IOException An I/O error occurred while sending the
  1984. * inform request.
  1985. * @exception SnmpStatusException If the inform request exceeds the
  1986. * limit defined by <CODE>bufferSize</CODE>.
  1987. */
  1988. public Vector snmpInformRequest(SnmpInformHandler cb, SnmpOid trapOid,
  1989. SnmpVarBindList varBindList)
  1990. throws IllegalStateException, IOException, SnmpStatusException {
  1991. if (!isActive()) {
  1992. throw new IllegalStateException(
  1993. "Start SNMP adaptor server before carrying out this operation");
  1994. }
  1995. if (isTraceOn()) {
  1996. trace("snmpInformRequest", "trapOid=" + trapOid);
  1997. }
  1998. // First, make an SNMP inform pdu:
  1999. // We clone varBindList and insert sysUpTime and snmpTrapOid variables.
  2000. //
  2001. SnmpVarBindList fullVbl ;
  2002. if (varBindList != null)
  2003. fullVbl = (SnmpVarBindList)varBindList.clone() ;
  2004. else
  2005. fullVbl = new SnmpVarBindList(2) ;
  2006. SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
  2007. fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
  2008. fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
  2009. 0);
  2010. // Next, send the pdu to the specified destination
  2011. //
  2012. openInformSocketIfNeeded() ;
  2013. // Now send the SNMP message to each destination
  2014. //
  2015. Vector informReqList = new Vector();
  2016. InetAddress addr = null;
  2017. String cs = null;
  2018. if (ipacl != null) {
  2019. Enumeration ed = ((InetAddressAcl)ipacl).getInformDestinations() ;
  2020. while (ed.hasMoreElements()) {
  2021. addr = (InetAddress)ed.nextElement() ;
  2022. Enumeration ec = ((InetAddressAcl)ipacl).
  2023. getInformCommunities(addr) ;
  2024. while (ec.hasMoreElements()) {
  2025. cs = (String)ec.nextElement() ;
  2026. informReqList.addElement(
  2027. informSession.makeAsyncRequest(addr, cs, cb,
  2028. fullVbl,getInformPort())) ;
  2029. }
  2030. }
  2031. }
  2032. return informReqList ;
  2033. }
  2034. /**
  2035. * Sends an inform using SNMP V2 inform request format.
  2036. * <BR>The inform is sent to the specified <CODE>InetAddress</CODE>
  2037. * destination
  2038. * using the specified community string.
  2039. * <BR>The variable list included in the outgoing inform is composed
  2040. * of the following items:
  2041. * <UL>
  2042. * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
  2043. * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
  2044. * <CODE>trapOid</CODE></LI>
  2045. * <LI><CODE>all the (oid,values)</CODE> from the specified
  2046. * <CODE>varBindList</CODE></LI>
  2047. * </UL>
  2048. * To send an inform request, the SNMP adaptor server must be active.
  2049. *
  2050. * @param addr The <CODE>InetAddress</CODE> destination for this inform
  2051. * request.
  2052. * @param cs The community string to be used for the inform request.
  2053. * @param cb The callback that is invoked when a request is complete.
  2054. * @param trapOid The OID identifying the trap.
  2055. * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
  2056. *
  2057. * @return The inform request object.
  2058. *
  2059. * @exception IllegalStateException This method has been invoked
  2060. * while the SNMP adaptor server was not active.
  2061. * @exception IOException An I/O error occurred while sending the
  2062. * inform request.
  2063. * @exception SnmpStatusException If the inform request exceeds the
  2064. * limit defined by <CODE>bufferSize</CODE>.
  2065. */
  2066. public SnmpInformRequest snmpInformRequest(InetAddress addr,
  2067. String cs,
  2068. SnmpInformHandler cb,
  2069. SnmpOid trapOid,
  2070. SnmpVarBindList varBindList)
  2071. throws IllegalStateException, IOException, SnmpStatusException {
  2072. return snmpInformRequest(addr,
  2073. getInformPort(),
  2074. cs,
  2075. cb,
  2076. trapOid,
  2077. varBindList);
  2078. }
  2079. /**
  2080. * Sends an inform using SNMP V2 inform request format.
  2081. * <BR>The inform is sent to the specified <CODE>SnmpPeer</CODE>
  2082. * destination.
  2083. * <BR>The community string used is the one located in the
  2084. * <CODE>SnmpPeer</CODE> parameters
  2085. * (<CODE>SnmpParameters.getInformCommunity() </CODE>).
  2086. * <BR>The variable list included in the outgoing inform is composed
  2087. * of the following items:
  2088. * <UL>
  2089. * <LI><CODE>sysUpTime.0</CODE> with its current value</LI>
  2090. * <LI><CODE>snmpTrapOid.0</CODE> with the value specified by
  2091. * <CODE>trapOid</CODE></LI>
  2092. * <LI><CODE>all the (oid,values)</CODE> from the specified
  2093. * <CODE>varBindList</CODE></LI>
  2094. * </UL>
  2095. * To send an inform request, the SNMP adaptor server must be active.
  2096. *
  2097. * @param peer The <CODE>SnmpPeer</CODE> destination for this inform
  2098. * request.
  2099. * @param cb The callback that is invoked when a request is complete.
  2100. * @param trapOid The OID identifying the trap.
  2101. * @param varBindList A list of <CODE>SnmpVarBind</CODE> instances or null.
  2102. *
  2103. * @return The inform request object.
  2104. *
  2105. * @exception IllegalStateException This method has been invoked while
  2106. * the SNMP adaptor server was not active.
  2107. * @exception IOException An I/O error occurred while sending the
  2108. * inform request.
  2109. * @exception SnmpStatusException If the inform request exceeds the
  2110. * limit defined by <CODE>bufferSize</CODE>.
  2111. *
  2112. * @since 1.5
  2113. */
  2114. public SnmpInformRequest snmpInformRequest(SnmpPeer peer,
  2115. SnmpInformHandler cb,
  2116. SnmpOid trapOid,
  2117. SnmpVarBindList varBindList)
  2118. throws IllegalStateException, IOException, SnmpStatusException {
  2119. SnmpParameters p = (SnmpParameters) peer.getParams();
  2120. return snmpInformRequest(peer.getDestAddr(),
  2121. peer.getDestPort(),
  2122. p.getInformCommunity(),
  2123. cb,
  2124. trapOid,
  2125. varBindList);
  2126. }
  2127. /**
  2128. * Method that maps an SNMP error status in the passed protocolVersion
  2129. * according to the provided pdu type.
  2130. * @param errorStatus The error status to convert.
  2131. * @param protocolVersion The protocol version.
  2132. * @param reqPduType The pdu type.
  2133. */
  2134. public static final int mapErrorStatus(int errorStatus,
  2135. int protocolVersion,
  2136. int reqPduType) {
  2137. return SnmpSubRequestHandler.mapErrorStatus(errorStatus,
  2138. protocolVersion,
  2139. reqPduType);
  2140. }
  2141. private SnmpInformRequest snmpInformRequest(InetAddress addr,
  2142. int port,
  2143. String cs,
  2144. SnmpInformHandler cb,
  2145. SnmpOid trapOid,
  2146. SnmpVarBindList varBindList)
  2147. throws IllegalStateException, IOException, SnmpStatusException {
  2148. if (!isActive()) {
  2149. throw new IllegalStateException(
  2150. "Start SNMP adaptor server before carrying out this operation");
  2151. }
  2152. if (isTraceOn()) {
  2153. trace("snmpInformRequest", "trapOid=" + trapOid);
  2154. }
  2155. // First, make an SNMP inform pdu:
  2156. // We clone varBindList and insert sysUpTime and snmpTrapOid variables.
  2157. //
  2158. SnmpVarBindList fullVbl ;
  2159. if (varBindList != null)
  2160. fullVbl = (SnmpVarBindList)varBindList.clone() ;
  2161. else
  2162. fullVbl = new SnmpVarBindList(2) ;
  2163. SnmpTimeticks sysUpTimeValue = new SnmpTimeticks(getSysUpTime()) ;
  2164. fullVbl.insertElementAt(new SnmpVarBind(snmpTrapOidOid, trapOid), 0) ;
  2165. fullVbl.insertElementAt(new SnmpVarBind(sysUpTimeOid, sysUpTimeValue),
  2166. 0);
  2167. // Next, send the pdu to the specified destination
  2168. //
  2169. openInformSocketIfNeeded() ;
  2170. return informSession.makeAsyncRequest(addr, cs, cb, fullVbl, port) ;
  2171. }
  2172. /**
  2173. * Open informSocket if it's not already done.
  2174. */
  2175. synchronized void openInformSocketIfNeeded() throws SocketException {
  2176. if (informSession == null) {
  2177. informSession = new SnmpSession(this) ;
  2178. if (isTraceOn()) {
  2179. trace("openInformSocketIfNeeded",
  2180. "to send inform requests and receive inform responses");
  2181. }
  2182. }
  2183. }
  2184. /**
  2185. * Close informSocket if the SNMP protocol adaptor is not ONLINE.
  2186. */
  2187. synchronized void closeInformSocketIfNeeded() {
  2188. if ((informSession != null) && (state != ONLINE)) {
  2189. informSession.destroySession() ;
  2190. informSession = null ;
  2191. }
  2192. }
  2193. /**
  2194. * Gets the IP address to bind.
  2195. * This getter is used to initialize the DatagramSocket in the
  2196. * SnmpSocket object created for the inform request stuff.
  2197. */
  2198. InetAddress getAddress() {
  2199. return address;
  2200. }
  2201. // PROTECTED METHODS
  2202. //------------------
  2203. /**
  2204. * Finalizer of the SNMP protocol adaptor objects.
  2205. * This method is called by the garbage collector on an object
  2206. * when garbage collection determines that there are no more
  2207. * references to the object.
  2208. * <P>Closes the datagram socket associated to this SNMP protocol adaptor.
  2209. */
  2210. protected void finalize() {
  2211. try {
  2212. if (socket != null) {
  2213. socket.close() ;
  2214. socket = null ;
  2215. }
  2216. threadService.terminate();
  2217. } catch (Exception e) {
  2218. trace("finalize","Exception in finalizer: " +e);
  2219. }
  2220. }
  2221. // PACKAGE METHODS
  2222. //----------------
  2223. /**
  2224. * Returns the string used in debug traces.
  2225. */
  2226. String makeDebugTag() {
  2227. return "SnmpAdaptorServer["+ getProtocol() + ":" + getPort() + "]";
  2228. }
  2229. void updateRequestCounters(int pduType) {
  2230. switch(pduType) {
  2231. case pduGetRequestPdu:
  2232. snmpInGetRequests++;
  2233. break;
  2234. case pduGetNextRequestPdu:
  2235. snmpInGetNexts++;
  2236. break;
  2237. case pduSetRequestPdu:
  2238. snmpInSetRequests++;
  2239. break;
  2240. default:
  2241. break;
  2242. }
  2243. snmpInPkts++ ;
  2244. }
  2245. void updateErrorCounters(int errorStatus) {
  2246. switch(errorStatus) {
  2247. case snmpRspNoError:
  2248. snmpOutGetResponses++;
  2249. break;
  2250. case snmpRspGenErr:
  2251. snmpOutGenErrs++;
  2252. break;
  2253. case snmpRspBadValue:
  2254. snmpOutBadValues++;
  2255. break;
  2256. case snmpRspNoSuchName:
  2257. snmpOutNoSuchNames++;
  2258. break;
  2259. case snmpRspTooBig:
  2260. snmpOutTooBigs++;
  2261. break;
  2262. default:
  2263. break;
  2264. }
  2265. snmpOutPkts++ ;
  2266. }
  2267. void updateVarCounters(int pduType, int n) {
  2268. switch(pduType) {
  2269. case pduGetRequestPdu:
  2270. case pduGetNextRequestPdu:
  2271. case pduGetBulkRequestPdu:
  2272. snmpInTotalReqVars += n ;
  2273. break ;
  2274. case pduSetRequestPdu:
  2275. snmpInTotalSetVars += n ;
  2276. break ;
  2277. }
  2278. }
  2279. void incSnmpInASNParseErrs(int n) {
  2280. snmpInASNParseErrs += n ;
  2281. }
  2282. void incSnmpInBadVersions(int n) {
  2283. snmpInBadVersions += n ;
  2284. }
  2285. void incSnmpInBadCommunityUses(int n) {
  2286. snmpInBadCommunityUses += n ;
  2287. }
  2288. void incSnmpInBadCommunityNames(int n) {
  2289. snmpInBadCommunityNames += n ;
  2290. }
  2291. void incSnmpSilentDrops(int n) {
  2292. snmpSilentDrops += n ;
  2293. }
  2294. // PRIVATE METHODS
  2295. //----------------
  2296. /**
  2297. * Returns the time (in hundreths of second) elapsed since the SNMP
  2298. * protocol adaptor startup.
  2299. */
  2300. long getSysUpTime() {
  2301. return (System.currentTimeMillis() - startUpTime) / 10 ;
  2302. }
  2303. /**
  2304. * Control the way the SnmpAdaptorServer service is deserialized.
  2305. */
  2306. private void readObject(ObjectInputStream stream)
  2307. throws IOException, ClassNotFoundException {
  2308. // Call the default deserialization of the object.
  2309. //
  2310. stream.defaultReadObject();
  2311. // Call the specific initialization for the SnmpAdaptorServer service.
  2312. // This is for transient structures to be initialized to specific
  2313. // default values.
  2314. //
  2315. mibs = new Vector() ;
  2316. }
  2317. /**
  2318. * Common initializations.
  2319. */
  2320. private void init(Object acl, int p, InetAddress a) {
  2321. root= new SnmpMibTree();
  2322. // The default Agent is initialized with a SnmpErrorHandlerAgent agent.
  2323. root.setDefaultAgent(new SnmpErrorHandlerAgent());
  2324. // For the trap time, use the time the agent started ...
  2325. //
  2326. startUpTime= java.lang.System.currentTimeMillis();
  2327. maxActiveClientCount = 10;
  2328. // Create the default message factory
  2329. pduFactory = new SnmpPduFactoryBER() ;
  2330. port = p ;
  2331. ipacl = acl ;
  2332. address = a ;
  2333. if ((ipacl == null) && (useAcl == true))
  2334. throw new IllegalArgumentException("ACL object cannot be null") ;
  2335. threadService = new ThreadService(threadNumber);
  2336. }
  2337. SnmpMibAgent getAgentMib(SnmpOid oid) {
  2338. return root.getAgentMib(oid);
  2339. }
  2340. protected Thread createMainThread() {
  2341. final Thread t = super.createMainThread();
  2342. t.setDaemon(true);
  2343. return t;
  2344. }
  2345. }