📄 snmptrapreceiverinterface.java
字号:
/* * SNMP Package * * Copyright (C) 2004, Jonathan Sevy <jsevy@mcs.drexel.edu> * * This is free software. Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */package snmp;import java.io.*;import java.net.*;import java.util.*;/*** The class SNMPTrapListenerInterface implements a server which listens for trap and inform request * messages sent from remote SNMP entities. The approach is that from version 1 and 2c of SNMP, using no * encryption of data. Communication occurs via UDP, using port 162, the standard SNMP trap port, or an* alternate (non-standard) port supplied in the constructor. This interface can handle both SNMPv1 and * SNMPv2 traps (which have different PDU types), and SNMPv2 Inform Requests.** Applications utilize this class with classes which implement the SNMPTrapListener or SNMPv2TrapListener or* SNMPv2InformRequestListener interfaces. These must provide a processTrap(), processv2Trap() or processInformRequest() * method, and are registered/unregistered with this class through its addv1TrapListener()/removev1TrapListener(),* addv2TrapListener()/removev2TrapListener(), or addv2InformRequestListener()/removev2InformRequestListener()* methods.*/public class SNMPTrapReceiverInterface implements Runnable{ public static final int SNMP_TRAP_PORT = 162; // largest size for datagram packet payload; based on // RFC 1157, need to handle messages of at least 484 bytes private int receiveBufferSize = 512; private DatagramSocket dSocket; private Thread receiveThread; private Vector v1TrapListenerVector; private Vector v2TrapListenerVector; private Vector v2InformRequestListenerVector; private PrintWriter errorLog; /** * Construct a new trap receiver object to receive traps from remote SNMP hosts. * Uses the standard SNMP trap reception port 162, and System.out to report errors. */ public SNMPTrapReceiverInterface() throws SocketException { // set System.out as the error writer this(new PrintWriter(System.out)); } /** * Construct a new trap receiver object to receive traps from remote SNMP hosts. * Uses the specified Writer to deliver error messages, and the standard SNMP trap * port 162. */ public SNMPTrapReceiverInterface(PrintWriter errorReceiver) throws SocketException { this(errorReceiver, SNMP_TRAP_PORT); } /** * Construct a new trap receiver object to receive traps from remote SNMP hosts. * Uses the specified port for trap reception, and System.out to report errors. */ public SNMPTrapReceiverInterface(int trapReceivePort) throws SocketException { this(new PrintWriter(System.out), trapReceivePort); } /** * Construct a new trap receiver object to receive traps from remote SNMP hosts. * This version will accept messages from all hosts using any community name. Uses the * specified Writer to deliver error messages and the specified port to listen on. */ public SNMPTrapReceiverInterface(PrintWriter errorReceiver, int trapReceivePort) throws SocketException { dSocket = new DatagramSocket(trapReceivePort); v1TrapListenerVector = new Vector(); v2TrapListenerVector = new Vector(); v2InformRequestListenerVector = new Vector(); receiveThread = new Thread(this); errorLog = errorReceiver; } /** * Set the specified PrintWriter to receive error messages. */ public void setErrorReceiver(PrintWriter errorReceiver) { errorLog = errorReceiver; } public void addv1TrapListener(SNMPv1TrapListener listener) { // see if listener already added; if so, ignore for (int i = 0; i < v1TrapListenerVector.size(); i++) { if (listener == v1TrapListenerVector.elementAt(i)) { return; } } // if got here, it's not in the list; add it v1TrapListenerVector.add(listener); } public void removev1TrapListener(SNMPv1TrapListener listener) { // see if listener in list; if so, remove, if not, ignore for (int i = 0; i < v1TrapListenerVector.size(); i++) { if (listener == v1TrapListenerVector.elementAt(i)) { v1TrapListenerVector.removeElementAt(i); break; } } } public void addv2TrapListener(SNMPv2TrapListener listener) { // see if listener already added; if so, ignore for (int i = 0; i < v2TrapListenerVector.size(); i++) { if (listener == v2TrapListenerVector.elementAt(i)) { return; } } // if got here, it's not in the list; add it v2TrapListenerVector.add(listener); } public void removev2TrapListener(SNMPv2TrapListener listener) { // see if listener in list; if so, remove, if not, ignore for (int i = 0; i < v2TrapListenerVector.size(); i++) { if (listener == v2TrapListenerVector.elementAt(i)) { v2TrapListenerVector.removeElementAt(i); break; } } } public void addv2InformRequestListener(SNMPv2InformRequestListener listener) { // see if listener already added; if so, ignore for (int i = 0; i < v2InformRequestListenerVector.size(); i++) { if (listener == v2InformRequestListenerVector.elementAt(i)) { return; } } // if got here, it's not in the list; add it v2InformRequestListenerVector.add(listener); } public void removev2InformRequestListener(SNMPv2InformRequestListener listener) { // see if listener in list; if so, remove, if not, ignore for (int i = 0; i < v2InformRequestListenerVector.size(); i++) { if (listener == v2InformRequestListenerVector.elementAt(i)) { v2InformRequestListenerVector.removeElementAt(i); break; } } } /** * Start listening for trap and inform messages. */ public void startReceiving() { // if receiveThread not already running, start it if (!receiveThread.isAlive()) { receiveThread = new Thread(this); receiveThread.start(); } } /** * Stop listening for trap and inform messages. */ public void stopReceiving() throws SocketException { // interrupt receive thread so it will die a natural death receiveThread.interrupt(); } /** * The run() method for the trap interface's listener. Just waits for trap or inform messages to * come in on port 162, then dispatches the recieved PDUs to each of the registered * listeners by calling their processTrap() or processInform() methods. */ public void run() { int errorStatus = 0; int errorIndex = 0; while (!receiveThread.isInterrupted()) { try { DatagramPacket inPacket = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize); dSocket.receive(inPacket); byte[] encodedMessage = inPacket.getData(); // get IP address of sender, to supply with SNMPv2 traps // which don't include this in the PDU InetAddress agentIPAddress = inPacket.getAddress(); /* errorLog.println("Message bytes length (in): " + inPacket.getLength()); errorLog.println("Message bytes (in):"); for (int i = 0; i < encodedMessage.length; ++i) { errorLog.print(hexByte(encodedMessage[i]) + " "); } errorLog.println("\n"); */ SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value); String communityName = receivedMessage.getCommunityName(); Object receivedPDU = receivedMessage.getPDUAsObject(); if (!(receivedPDU instanceof SNMPv1TrapPDU) && !(receivedPDU instanceof SNMPv2TrapPDU) && !(receivedPDU instanceof SNMPv2InformRequestPDU)) { throw new SNMPBadValueException("PDU received that's not a v1 or v2 trap or inform request; message payload of type " + receivedPDU.getClass().toString()); } // pass the received trap PDU to the processTrap or procesv2Trap method of any listeners if (receivedPDU instanceof SNMPv1TrapPDU) { for (int i = 0; i < v1TrapListenerVector.size(); i++) { SNMPv1TrapListener listener = (SNMPv1TrapListener)v1TrapListenerVector.elementAt(i); listener.processv1Trap((SNMPv1TrapPDU)receivedPDU, communityName); } } else if (receivedPDU instanceof SNMPv2TrapPDU) { for (int i = 0; i < v2TrapListenerVector.size(); i++) { SNMPv2TrapListener listener = (SNMPv2TrapListener)v2TrapListenerVector.elementAt(i); listener.processv2Trap((SNMPv2TrapPDU)receivedPDU, communityName, agentIPAddress); } } else if (receivedPDU instanceof SNMPv2InformRequestPDU) { for (int i = 0; i < v2InformRequestListenerVector.size(); i++) { SNMPv2InformRequestListener listener = (SNMPv2InformRequestListener)v2InformRequestListenerVector.elementAt(i); listener.processv2InformRequest((SNMPv2InformRequestPDU)receivedPDU, communityName, agentIPAddress); } } } catch (IOException e) { // just report the problem errorLog.println("IOException during request processing: " + e.toString()); errorLog.flush(); } catch (SNMPBadValueException e) { // just report the problem errorLog.println("SNMPBadValueException during request processing: " + e.toString()); errorLog.flush(); } catch (Exception e) { // just report the problem errorLog.println("Exception during request processing: " + e.toString()); errorLog.flush(); } } } private String hexByte(byte b) { int pos = b; if (pos < 0) pos += 256; String returnString = new String(); returnString += Integer.toHexString(pos/16); returnString += Integer.toHexString(pos%16); return returnString; } private String getHex(byte theByte) { int b = theByte; if (b < 0) b += 256; String returnString = new String(Integer.toHexString(b)); // add leading 0 if needed if (returnString.length()%2 == 1) returnString = "0" + returnString; return returnString; } /** * Set the size of the buffer used to receive response packets. RFC 1157 stipulates that an SNMP * implementation must be able to receive packets of at least 484 bytes, so if you try to set the * size to a value less than this, the receive buffer size will be set to 484 bytes. In addition, * the maximum size of a UDP packet payload is 65535 bytes, so setting the buffer to a larger size * will just waste memory. The default value is 512 bytes. The value may need to be increased if * get-requests are issued for multiple OIDs. */ public void setReceiveBufferSize(int receiveBufferSize) { if (receiveBufferSize >= 484) { this.receiveBufferSize = receiveBufferSize; } else { this.receiveBufferSize = 484; } } /** * Returns the current size of the buffer used to receive packets. */ public int getReceiveBufferSize() { return this.receiveBufferSize; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -