1   package com.mccrory.scott.spumoni;
2   
3   ////////////////////////////////////////////////////////////////////////////////
4   // SnmpD is based on Bob Snider's adaptation of JoeSNMP's TrapD test class,
5   // which is a part of the OpenNMS project (http://www.opennms.org).  Thanks
6   // go out to Bob, Brian and the rest of the OpenNMS crew for their excellent
7   // work. 
8   //
9   // This library is free software; you can redistribute it and/or
10  // modify it under the terms of the GNU Lesser General Public
11  // License as published by the Free Software Foundation; either
12  // version 2.1 of the License, or (at your option) any later version.
13  //
14  // (Also available online at http://www.fsf.org/copyleft/lesser.html)
15  //
16  // This library is distributed in the hope that it will be useful,
17  // but WITHOUT ANY WARRANTY; without even the implied warranty of
18  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  // Lesser General Public License for more details.
20  //
21  // You should have received a copy of the GNU Lesser General Public
22  // License along with this library; if not, write to the Free Software
23  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  ////////////////////////////////////////////////////////////////////////////////
25  
26  import java.util.HashMap;
27  
28  import org.opennms.protocols.snmp.SnmpAgentHandler;
29  import org.opennms.protocols.snmp.SnmpAgentSession;
30  import org.opennms.protocols.snmp.SnmpOctetString;
31  import org.opennms.protocols.snmp.SnmpPduPacket;
32  import org.opennms.protocols.snmp.SnmpPduRequest;
33  import org.opennms.protocols.snmp.SnmpPduTrap;
34  import org.opennms.protocols.snmp.SnmpPeer;
35  import org.opennms.protocols.snmp.SnmpVarBind;
36  
37  /**
38   * <P><code>SnmpD</code> implements a sample SNMP daemon.
39   * It listens for messages received from remote agents on (default) port 161.
40   * It is based on Bob Snider's adaptation of JoeSNMP's TrapD test class,
41   * which is a part of the <A HREF="http://www.opennms.org">OpenNMS</a>
42   * project.  Thanks go out to Bob, Brian and the rest of the OpenNMS crew
43   * for their excellent work.</P>
44   *
45   * @author <A HREF="mailto:shivakumar.patil@stdc.com">Shivakumar C. Patil</A>
46   * @author <A HREF="mailto:weave@opennms.org">Brian Weaver</A>
47   * @author <A HREF="http://www.opennms.org/">OpenNMS</A>
48   * @author <A HREF="mailto:bob@seekone.com">Bob Snider</A>
49   * @author <a href="mailto:smccrory@users.sourceforge.net">Scott McCrory</a>
50   * @version CVS $Id: SnmpD.java,v 1.12 2002/08/04 22:04:53 smccrory Exp $
51   */
52  public class SnmpD implements SnmpAgentHandler {
53  
54      /** The HashMap we use to keep track of oid handlers **/
55      private HashMap oidHandlerMap = new HashMap();
56  
57      /**
58       * The main routine. All arguments are ignored. The program
59       * will terminate if any error in the trap session occur. However,
60       * malformed packets will be discarded in the error handling method
61       * of this class.
62       *
63       * @param args  The command line arguments -- IGNORED.
64       */
65      public static void main(String args[]) {
66  
67          try {
68              SnmpAgentSession testDaemonSession = new SnmpAgentSession(new SnmpD(), 161);
69              System.out.println("SNMP Agent Started");
70              synchronized (testDaemonSession) {
71                  testDaemonSession.wait();
72              }
73              System.out.println("SNMP Agent Exiting");
74              testDaemonSession.close();
75          }
76          catch (Exception e) {
77              System.out.println("Exception in main(): " + e);
78              e.printStackTrace();
79          }
80  
81      }
82  
83      /**
84       * Register an oid handler to our lookup map.
85       * The oid should be an end value node number.
86       *
87       * @param oid           The oid
88       * @param oidHandler    The handler for this oid
89       */
90      public void registerOidHandler(String oid, OidHandler oidHandler) {
91  
92          oidHandlerMap.put(oid, oidHandler);
93  
94      }
95  
96      /**
97       * Process session errors.
98       *
99       * @param session   The trap session in error.
100      * @param error The error condition.
101      * @param ref       The reference object, if any.
102      *
103      */
104     public void SnmpAgentSessionError(
105         SnmpAgentSession session,
106         int error,
107         java.lang.Object ref) {
108 
109         System.out.println("An error occured in the trap session");
110         System.out.println("Session error code = " + error);
111 
112         if (ref != null) {
113             System.out.println("Session error reference: " + ref.toString());
114         }
115 
116         if (error == SnmpAgentSession.ERROR_EXCEPTION) {
117             synchronized (session) {
118                 session.notify(); // close the session
119             }
120         }
121 
122     }
123 
124     /**
125      * The main method which receives SNMPv2c PDUs and forwards them to
126      * their specific handler methods.
127      *
128      * @param session       The Session that received the PDU.
129      * @param manager       The address of the remote sender.
130      * @param port          The remote port where the pdu was transmitted from.
131      * @param community The decoded community string.
132      * @param pdu           The decoded V2 pdu.
133      *
134      */
135     public void snmpReceivedPdu(
136         SnmpAgentSession session,
137         java.net.InetAddress manager,
138         int port,
139         SnmpOctetString community,
140         SnmpPduPacket pdu) {
141 
142         // Get the PDU's command and length
143         int cmd = pdu.getCommand();
144         int length = pdu.getLength();
145 
146         // Get the PDU "var bind" list
147         SnmpVarBind[] vblist = new SnmpVarBind[length];
148 
149         // Now iterate through each PDU "var bind" element and get the critical info
150         for (int i = 0; i < length; i++) {
151 
152             SnmpVarBind vb = pdu.getVarBindAt(i);
153             vblist[i] = new SnmpVarBind(vb.getName());
154 
155             // Get the oid and strip off leading "." character if present
156             // that may be used to indicate the root of the mib tree
157             String oid = vb.getName().toString();
158             if (oid.startsWith(".")) {
159                 oid = oid.substring(1);
160             }
161 
162             // See if we have an OidHandler registered for this oid
163             // and if so, pass the requests on to it.
164             if (oidHandlerMap.containsKey(oid)) {
165 
166                 OidHandler oidHandler = (OidHandler) oidHandlerMap.get(oid);
167 
168                 switch (cmd) {
169                     case SnmpPduPacket.SET :
170                         vblist[i] = oidHandler.handleSet(vblist[i]);
171                         break;
172                     case SnmpPduPacket.GET :
173                         vblist[i] = oidHandler.handleGet(vblist[i]);
174                         break;
175                     case SnmpPduPacket.GETNEXT :
176                         vblist[i] = oidHandler.handleGetnext(vblist[i]);
177                         break;
178                     case SnmpPduPacket.RESPONSE :
179                         vblist[i] = oidHandler.handleResponse(vblist[i]);
180                         break;
181                     case SnmpPduPacket.INFORM :
182                         vblist[i] = oidHandler.handleInform(vblist[i]);
183                         break;
184                     case SnmpPduPacket.V2TRAP :
185                         vblist[i] = oidHandler.handleV2Trap(vblist[i]);
186                         break;
187                     case SnmpPduPacket.REPORT :
188                         vblist[i] = oidHandler.handleReport(vblist[i]);
189                         break;
190                     case SnmpPduPacket.GETBULK :
191                         vblist[i] = oidHandler.handleGetbulk(vblist[i]);
192                         break;
193                     case SnmpPduTrap.TRAP :
194                         vblist[i] = oidHandler.handleTrap(vblist[i]);
195                         break;
196                     default :
197                         System.out.println("Unknown SNMP Command \"" + cmd + "\"");
198                         break;
199                 }
200                 
201             }
202             else {
203                 System.out.println("Requested OID '" + oid + "' is not registered");
204             }
205 
206         }
207         
208         // Assemble our SNMP response to the request
209         SnmpPduRequest newReq = new SnmpPduRequest(SnmpPduPacket.RESPONSE, vblist);
210         newReq.setRequestId(pdu.getRequestId());
211 
212         // Send the response back to the manager if we can
213         try {
214             session.send(new SnmpPeer(manager, port), newReq);
215         }
216         catch (Exception e) {
217             System.out.println("Error sending response " + e);
218         }
219         
220     }
221 }