/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2006-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.netmgt.scriptd.helper; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.HashMap; import org.opennms.core.utils.Base64; import org.opennms.core.utils.InetAddressUtils; import org.opennms.netmgt.EventConstants; import org.opennms.netmgt.eventd.EventUtil; import org.opennms.netmgt.snmp.SnmpObjId; import org.opennms.netmgt.snmp.SnmpTrapBuilder; import org.opennms.netmgt.snmp.SnmpUtils; import org.opennms.netmgt.snmp.SnmpV1TrapBuilder; import org.opennms.netmgt.snmp.SnmpV2TrapBuilder; import org.opennms.netmgt.snmp.SnmpV3TrapBuilder; import org.opennms.netmgt.xml.event.Event; import org.opennms.netmgt.xml.event.Parm; import org.opennms.netmgt.xml.event.Snmp; import org.opennms.netmgt.xml.event.Value; /** * This "helper" class provides a convenience interface for generating and * forwarding SNMP traps. This class was created in order to make it easier to * write simple scripts to generate traps based on events or to forward traps, * using scripting languages that are able to access Java classes (such as * BeanShell). * * @author <a href="mailto:jim.doble@tavve.com">Jim Doble </a> * @author <a href="http://www.opennms.org/">OpenNMS.org </a> */ public class SnmpTrapHelper { /** * The sysUpTimeOID, which should be the first varbind in a V2 trap */ private static final String SNMP_SYSUPTIME_OID = ".1.3.6.1.2.1.1.3.0"; /** * The snmpTrapOID, which should be the second varbind in a V2 trap */ private static final String SNMP_TRAP_OID = ".1.3.6.1.6.3.1.1.4.1.0"; /** * The snmpTrapAddress, which may occur in a V2 trap */ private static final String SNMP_TRAP_ADDRESS_OID = ".1.3.6.1.6.3.18.1.3.0"; /** * The snmpTrapCommunity, which may occur in a V2 trap */ private static final String SNMP_TRAP_COMMUNITY_OID = ".1.3.6.1.6.3.18.1.4.0"; /** * The SNMP trap enterprise OID, which if present in a V2 trap is the last * varbind */ private static final String SNMP_TRAP_ENTERPRISE_OID = ".1.3.6.1.6.3.1.1.4.3.0"; /** * OID prefix for generic SNMP traps */ private static final String SNMP_TRAPS = ".1.3.6.1.6.3.1.1.5"; /** * The SNMP generic value for an enterprise-specific trap */ private static final int ENTERPRISE_SPECIFIC = 6; /** * Map of factories for generating different types of SNMP variable binding * content */ private HashMap<String, Object> m_factoryMap; /** * Constructs a new SNMPTrapHelper. */ public SnmpTrapHelper() { // create the trap session // create and populate the factory map m_factoryMap = new HashMap<String, Object>(); m_factoryMap.put(EventConstants.TYPE_SNMP_OCTET_STRING, new SnmpOctetStringFactory()); m_factoryMap.put(EventConstants.TYPE_SNMP_INT32, new SnmpInt32Factory()); m_factoryMap.put(EventConstants.TYPE_SNMP_NULL, new SnmpNullFactory()); m_factoryMap.put(EventConstants.TYPE_SNMP_OBJECT_IDENTIFIER, new SnmpObjectIdFactory()); m_factoryMap.put(EventConstants.TYPE_SNMP_IPADDRESS, new SnmpIPAddressFactory()); m_factoryMap.put(EventConstants.TYPE_SNMP_TIMETICKS, new SnmpTimeTicksFactory()); m_factoryMap.put(EventConstants.TYPE_SNMP_COUNTER32, new SnmpCounter32Factory()); m_factoryMap.put(EventConstants.TYPE_SNMP_GAUGE32, new SnmpGauge32Factory()); m_factoryMap.put(EventConstants.TYPE_SNMP_OPAQUE, new SnmpOpaqueFactory()); m_factoryMap.put(EventConstants.TYPE_SNMP_COUNTER64, new SnmpCounter64Factory()); } /** * Stops the SnmpTrapHelper. If there is a valid SnmpTrapSession, that trap * session is stopped. */ public void stop() { } /** * Common interface for all variabe binding factories */ private interface VarBindFactory { /** * Constructs a new SnmpVarBind with the specified name and value. The * value is assumed to have been encoded with the specified encoding * (i.e. XML_ENCODING_TEXT, or XML_ENCODING_BASE64). * @param trap TODO * @param name * The name (a.k.a. "id") of the variable binding to be * created * @param encoding * Describes the way in which the value content has been * encoded (i.e. XML_ENCODING_TEXT, or XML_ENCODING_BASE64) * @param value * The variable binding value * * @return The newly-created variable binding * @exception Throws * SnmpTrapHelperException if the variable binding cannot * be created for any reason (e.g. encoding not * supported, invalid value, etc.). */ public void addVarBind(SnmpTrapBuilder trap, String name, String encoding, String value) throws SnmpTrapHelperException; } /** * Variable binding factory for SnmpOctetString */ private class SnmpOctetStringFactory implements VarBindFactory { /** * Constructs a new SnmpVarBind with the specified name and value. The * value will be encoded as an SnmpOctetString. The value is assumed to * have been encoded with the specified encoding (i.e. * XML_ENCODING_TEXT, XML_ENCODING_BASE64, or XML_ENCODING_MAC_ADDRESS). * @param name * The name (a.k.a. "id") of the variable binding to be * created * @param encoding * Describes the way in which the value content has been * encoded (i.e. XML_ENCODING_TEXT, XML_ENCODING_BASE64, or XML_ENCODING_MAC_ADDRESS) * @param value * The variable binding value * * @return The newly-created variable binding * @exception Throws * SnmpTrapHelperException if the variable binding cannot * be created for any reason (e.g. encoding not * supported, invalid value, etc.). */ public void addVarBind(SnmpTrapBuilder trap, String name, String encoding, String value) throws SnmpTrapHelperException { byte[] contents; if (EventConstants.XML_ENCODING_TEXT.equals(encoding)) { contents = value.getBytes(); } else if (EventConstants.XML_ENCODING_BASE64.equals(encoding)) { contents = Base64.decodeBase64(value.toCharArray()); } else if (EventConstants.XML_ENCODING_MAC_ADDRESS.equals(encoding)) { contents = InetAddressUtils.macAddressStringToBytes(value); } else { throw new SnmpTrapHelperException("Encoding " + encoding + "is invalid for SnmpOctetString"); } trap.addVarBind(SnmpObjId.get(name), SnmpUtils.getValueFactory().getOctetString(contents)); } } /** * Variable binding factory for SnmpInt32 */ private class SnmpInt32Factory implements VarBindFactory { /** * Constructs a new SnmpVarBind with the specified name and value. The * value will be encoded as an SnmpInt32. The value is assumed to have * been encoded with the specified encoding (only XML_ENCODING_TEXT is * supported). * @param name * The name (a.k.a. "id") of the variable binding to be * created * @param encoding * Describes the way in which the value content has been * encoded (i.e. XML_ENCODING_TEXT, or XML_ENCODING_BASE64) * @param value * The variable binding value * * @return The newly-created variable binding * @exception Throws * SnmpTrapHelperException if the variable binding cannot * be created for any reason (e.g. encoding not * supported, invalid value, etc.). */ public void addVarBind(SnmpTrapBuilder trap, String name, String encoding, String value) throws SnmpTrapHelperException { if (EventConstants.XML_ENCODING_TEXT.equals(encoding)) { try { trap.addVarBind(SnmpObjId.get(name), SnmpUtils.getValueFactory().getInt32(Integer.parseInt(value))); } catch (NumberFormatException e) { throw new SnmpTrapHelperException("Value " + value + "is invalid for SnmpInt32"); } catch (NullPointerException e) { throw new SnmpTrapHelperException("Value is null for SnmpInt32"); } } else { throw new SnmpTrapHelperException("Encoding " + encoding + "is invalid for SnmpInt32"); } } } /** * Variable binding factory for SnmpNull */ private class SnmpNullFactory implements VarBindFactory { /** * Constructs a new SnmpVarBind with the specified name and value. The * value will be encoded as an SnmpNull.The value and encoding * parameters are ignored. * @param name * The name (a.k.a. "id") of the variable binding to be * created * @param encoding * This parameter value is ignored. * @param value * This parameter value is ignored. * * @return The newly-created variable binding */ public void addVarBind(SnmpTrapBuilder trap, String name, String encoding, String value) { trap.addVarBind(SnmpObjId.get(name), SnmpUtils.getValueFactory().getNull()); } } /** * Variable binding factory for SnmpObjectId */ private class SnmpObjectIdFactory implements VarBindFactory { /** * Constructs a new SnmpVarBind with the specified name and value. The * value will be encoded as an SnmpObjectId. The value is assumed to * have been encoded with the specified encoding (only XML_ENCODING_TEXT * is supported). * @param name * The name (a.k.a. "id") of the variable binding to be * created * @param encoding * Describes the way in which the value content has been * encoded (i.e. XML_ENCODING_TEXT, or XML_ENCODING_BASE64) * @param value * The variable binding value * * @return The newly-created variable binding * @exception Throws * SnmpTrapHelperException if the variable binding cannot * be created for any reason (e.g. encoding not * supported, invalid value, etc.). */ public void addVarBind(SnmpTrapBuilder trap, String name, String encoding, String value) throws SnmpTrapHelperException { if (EventConstants.XML_ENCODING_TEXT.equals(encoding)) { trap.addVarBind(SnmpObjId.get(name), SnmpUtils.getValueFactory().getObjectId(SnmpObjId.get(value))); } else { throw new SnmpTrapHelperException("Encoding " + encoding + "is invalid for SnmpObjectId"); } } } /** * Variable binding factory for SnmpIPAddress */ private class SnmpIPAddressFactory implements VarBindFactory { /** * Constructs a new SnmpVarBind with the specified name and value. The * value will be encoded as an SnmpIPAddress. The value is assumed to * have been encoded with the specified encoding (only XML_ENCODING_TEXT * is supported). * @param name * The name (a.k.a. "id") of the variable binding to be * created * @param encoding * Describes the way in which the value content has been * encoded (i.e. XML_ENCODING_TEXT, or XML_ENCODING_BASE64) * @param value * The variable binding value * * @return The newly-created variable binding * @exception Throws * SnmpTrapHelperException if the variable binding cannot * be created for any reason (e.g. encoding not * supported, invalid value, etc.). */ public void addVarBind(SnmpTrapBuilder trap, String name, String encoding, String value) throws SnmpTrapHelperException { if (EventConstants.XML_ENCODING_TEXT.equals(encoding)) { final InetAddress addr = InetAddressUtils.addr(value); if (addr == null) { throw new SnmpTrapHelperException("Value " + value + "is invalid, or host unknown for SnmpIPAddress"); } trap.addVarBind(SnmpObjId.get(name), SnmpUtils.getValueFactory().getIpAddress(addr)); } else { throw new SnmpTrapHelperException("Encoding " + encoding + "is invalid for SnmpIPAddress"); } } } /** * Variable binding factory for SnmpTimeTicks */ private class SnmpTimeTicksFactory implements VarBindFactory { /** * Constructs a new SnmpVarBind with the specified name and value. The * value will be encoded as an SnmpTimeTicks. The value is assumed to * have been encoded with the specified encoding (only XML_ENCODING_TEXT * is supported). * @param name * The name (a.k.a. "id") of the variable binding to be * created * @param encoding * Describes the way in which the value content has been * encoded (i.e. XML_ENCODING_TEXT, or XML_ENCODING_BASE64) * @param value * The variable binding value * * @return The newly-created variable binding * @exception Throws * SnmpTrapHelperException if the variable binding cannot * be created for any reason (e.g. encoding not * supported, invalid value, etc.). */ public void addVarBind(SnmpTrapBuilder trap, String name, String encoding, String value) throws SnmpTrapHelperException { if (EventConstants.XML_ENCODING_TEXT.equals(encoding)) { try { trap.addVarBind(SnmpObjId.get(name), SnmpUtils.getValueFactory().getTimeTicks(Long.parseLong(value))); } catch (NumberFormatException e) { throw new SnmpTrapHelperException("Value " + value + "is invalid for SnmpTimeTicks"); } catch (IllegalArgumentException e) { throw new SnmpTrapHelperException("Value " + value + "is invalid for SnmpTimeTicks"); } catch (NullPointerException e) { throw new SnmpTrapHelperException("Value is null for SnmpTimeTicks"); } } else { throw new SnmpTrapHelperException("Encoding " + encoding + "is invalid for SnmpTimeTicks"); } } } /** * Variable binding factory for SnmpCounter32 */ private class SnmpCounter32Factory implements VarBindFactory { /** * Constructs a new SnmpVarBind with the specified name and value. The * value will be encoded as an SnmpCounter32. The value is assumed to * have been encoded with the specified encoding (only XML_ENCODING_TEXT * is supported). * @param name * The name (a.k.a. "id") of the variable binding to be * created * @param encoding * Describes the way in which the value content has been * encoded (i.e. XML_ENCODING_TEXT, or XML_ENCODING_BASE64) * @param value * The variable binding value * * @return The newly-created variable binding * @exception Throws * SnmpTrapHelperException if the variable binding cannot * be created for any reason (e.g. encoding not * supported, invalid value, etc.). */ public void addVarBind(SnmpTrapBuilder trap, String name, String encoding, String value) throws SnmpTrapHelperException { if (EventConstants.XML_ENCODING_TEXT.equals(encoding)) { try { trap.addVarBind(SnmpObjId.get(name), SnmpUtils.getValueFactory().getCounter32(Long.parseLong(value))); } catch (NumberFormatException e) { throw new SnmpTrapHelperException("Value " + value + "is invalid for SnmpCounter32"); } catch (IllegalArgumentException e) { throw new SnmpTrapHelperException("Value " + value + "is invalid for SnmpCounter32"); } catch (NullPointerException e) { throw new SnmpTrapHelperException("Value is null for SnmpCounter32"); } } else { throw new SnmpTrapHelperException("Encoding " + encoding + "is invalid for SnmpCounter32"); } } } /** * Variable binding factory for SnmpGauge32 */ private class SnmpGauge32Factory implements VarBindFactory { /** * Constructs a new SnmpVarBind with the specified name and value. The * value will be encoded as an SnmpGauge32. The value is assumed to have * been encoded with the specified encoding (only XML_ENCODING_TEXT is * supported). * @param name * The name (a.k.a. "id") of the variable binding to be * created * @param encoding * Describes the way in which the value content has been * encoded (i.e. XML_ENCODING_TEXT, or XML_ENCODING_BASE64) * @param value * The variable binding value * * @return The newly-created variable binding * @exception Throws * SnmpTrapHelperException if the variable binding cannot * be created for any reason (e.g. encoding not * supported, invalid value, etc.). */ public void addVarBind(SnmpTrapBuilder trap, String name, String encoding, String value) throws SnmpTrapHelperException { if (EventConstants.XML_ENCODING_TEXT.equals(encoding)) { try { trap.addVarBind(SnmpObjId.get(name), SnmpUtils.getValueFactory().getGauge32(Long.parseLong(value))); } catch (NumberFormatException e) { throw new SnmpTrapHelperException("Value " + value + "is invalid for SnmpGauge32"); } catch (IllegalArgumentException e) { throw new SnmpTrapHelperException("Value " + value + "is invalid for SnmpGauge32"); } catch (NullPointerException e) { throw new SnmpTrapHelperException("Value is null for SnmpGauge32"); } } else { throw new SnmpTrapHelperException("Encoding " + encoding + "is invalid for SnmpGauge32"); } } } /** * Variable binding factory for SnmpOpaque */ private class SnmpOpaqueFactory implements VarBindFactory { /** * Constructs a new SnmpVarBind with the specified name and value. The * value will be encoded as an SnmpOpaque. The value is assumed to have * been encoded with the specified encoding (only XML_ENCODING_BASE64 is * supported). * @param name * The name (a.k.a. "id") of the variable binding to be * created * @param encoding * Describes the way in which the value content has been * encoded (i.e. XML_ENCODING_TEXT, or XML_ENCODING_BASE64) * @param value * The variable binding value * * @return The newly-created variable binding * @exception Throws * SnmpTrapHelperException if the variable binding cannot * be created for any reason (e.g. encoding not * supported, invalid value, etc.). */ public void addVarBind(SnmpTrapBuilder trap, String name, String encoding, String value) throws SnmpTrapHelperException { if (EventConstants.XML_ENCODING_BASE64.equals(encoding)) { trap.addVarBind(SnmpObjId.get(name), SnmpUtils.getValueFactory().getOpaque(Base64.decodeBase64(value.toCharArray()))); } else { throw new SnmpTrapHelperException("Encoding " + encoding + "is invalid for SnmpOpaque"); } } } /** * Variable binding factory for SnmpCounter64 */ private class SnmpCounter64Factory implements VarBindFactory { /** * Constructs a new SnmpVarBind with the specified name and value. The * value will be encoded as an SnmpCounter64. The value is assumed to * have been encoded with the specified encoding (only XML_ENCODING_TEXT * is supported). * @param name * The name (a.k.a. "id") of the variable binding to be * created * @param encoding * Describes the way in which the value content has been * encoded (i.e. XML_ENCODING_TEXT, or XML_ENCODING_BASE64) * @param value * The variable binding value * * @return The newly-created variable binding * @exception Throws * SnmpTrapHelperException if the variable binding cannot * be created for any reason (e.g. encoding not * supported, invalid value, etc.). */ public void addVarBind(SnmpTrapBuilder trap, String name, String encoding, String value) throws SnmpTrapHelperException { if (EventConstants.XML_ENCODING_TEXT.equals(encoding)) { try { trap.addVarBind(SnmpObjId.get(name), SnmpUtils.getValueFactory().getCounter64(new BigInteger(value))); } catch (IllegalArgumentException e) { throw new SnmpTrapHelperException("Value " + value + "is invalid for SnmpCounter64"); } catch (NullPointerException e) { throw new SnmpTrapHelperException("Value is null for SnmpCounter64"); } } else { throw new SnmpTrapHelperException("Encoding " + encoding + "is invalid for SnmpCounter64"); } } } /** * Create an SNMP V1 trap with the specified enterprise IS, agent address, * generic ID, specific ID, and time stamp. * * @param entId * The enterprise ID for the trap. * @param agentAddr * The agent address for the trap. * @param generic * The generic ID for the trap. * @param specific * The specific ID for the trap. * @param timeStamp * The time stamp for the trap. * @return The newly-created trap. * @throws java.net.UnknownHostException if any. */ public SnmpV1TrapBuilder createV1Trap(String entId, String agentAddr, int generic, int specific, long timeStamp) throws UnknownHostException { SnmpV1TrapBuilder trap = SnmpUtils.getV1TrapBuilder(); trap.setEnterprise(SnmpObjId.get(entId)); trap.setAgentAddress(InetAddressUtils.addr(agentAddr)); trap.setGeneric(generic); trap.setSpecific(specific); trap.setTimeStamp(timeStamp); return trap; } /** * Create an SNMP V2 trap with the specified trap object ID, and sysUpTime * value. * * @param trapOid * The trap object id. * @param sysUpTime * The system up time. * @return The newly-created trap. * @exception Throws * SnmpTrapHelperException if the trap cannot be created for * any reason. * @throws org.opennms.netmgt.scriptd.helper.SnmpTrapHelperException if any. */ public SnmpTrapBuilder createV2Trap(String trapOid, String sysUpTime) throws SnmpTrapHelperException { SnmpTrapBuilder packet = SnmpUtils.getV2TrapBuilder(); addVarBinding(packet, SNMP_SYSUPTIME_OID, EventConstants.TYPE_SNMP_TIMETICKS, sysUpTime); addVarBinding(packet, SNMP_TRAP_OID, EventConstants.TYPE_SNMP_OBJECT_IDENTIFIER, trapOid); return packet; } /** * Create an SNMP V2 inform with the specified trap object ID, and sysUpTime * value. * * @param trapOid * The trap object id. * @param sysUpTime * The system up time. * @return The newly-created trap. * @exception Throws * SnmpTrapHelperException if the trap cannot be created for * any reason. * @throws org.opennms.netmgt.scriptd.helper.SnmpTrapHelperException if any. */ public SnmpV2TrapBuilder createV2Inform(String trapOid, String sysUpTime) throws SnmpTrapHelperException { SnmpV2TrapBuilder packet = SnmpUtils.getV2InformBuilder(); addVarBinding(packet, SNMP_SYSUPTIME_OID, EventConstants.TYPE_SNMP_TIMETICKS, sysUpTime); addVarBinding(packet, SNMP_TRAP_OID, EventConstants.TYPE_SNMP_OBJECT_IDENTIFIER, trapOid); return packet; } /** * Create an SNMP V3 trap with the specified trap object ID, and sysUpTime * value. * * @param trapOid * The trap object id. * @param sysUpTime * The system up time. * @return The newly-created trap. * @exception Throws * SnmpTrapHelperException if the trap cannot be created for * any reason. * @throws org.opennms.netmgt.scriptd.helper.SnmpTrapHelperException if any. */ public SnmpV3TrapBuilder createV3Trap(String trapOid, String sysUpTime) throws SnmpTrapHelperException { SnmpV3TrapBuilder packet = SnmpUtils.getV3TrapBuilder(); addVarBinding(packet, SNMP_SYSUPTIME_OID, EventConstants.TYPE_SNMP_TIMETICKS, sysUpTime); addVarBinding(packet, SNMP_TRAP_OID, EventConstants.TYPE_SNMP_OBJECT_IDENTIFIER, trapOid); return packet; } /** * Create an SNMP V3 trap with the specified trap object ID, and sysUpTime * value. * * @param trapOid * The trap object id. * @param sysUpTime * The system up time. * @return The newly-created trap. * @exception Throws * SnmpTrapHelperException if the trap cannot be created for * any reason. * @throws org.opennms.netmgt.scriptd.helper.SnmpTrapHelperException if any. */ public SnmpV3TrapBuilder createV3Inform(String trapOid, String sysUpTime) throws SnmpTrapHelperException { SnmpV3TrapBuilder packet = SnmpUtils.getV3InformBuilder(); addVarBinding(packet, SNMP_SYSUPTIME_OID, EventConstants.TYPE_SNMP_TIMETICKS, sysUpTime); addVarBinding(packet, SNMP_TRAP_OID, EventConstants.TYPE_SNMP_OBJECT_IDENTIFIER, trapOid); return packet; } /** * * This helper method helps SNMP trap daemon * administrator to set up authentication * An snmpv3 trap is sent using the sender * EngineID that needs to be known * over remote trap receivers * * @return The local engine ID * */ public String getLocalEngineID() { return "0x"+SnmpUtils.getLocalEngineID(); } /** * Create a new variable binding and add it to the specified SNMP V1 trap. * The value encoding is assumed to be XML_ENCODING_TEXT. * * @param trap * The trap to which the variable binding should be added. * @param name * The name (a.k.a. "id") of the variable binding to be created * @param type * The type of variable binding to be created * @param value * The variable binding value * @exception Throws * SnmpTrapHelperException if the variable binding cannot be * added to the trap for any reason. * @throws org.opennms.netmgt.scriptd.helper.SnmpTrapHelperException if any. */ public void addVarBinding(SnmpTrapBuilder trap, String name, String type, String value) throws SnmpTrapHelperException { addVarBinding(trap, name, type, EventConstants.XML_ENCODING_TEXT, value); } /** * Create a new variable binding and add it to the specified SNMP V1 trap. * * @param trap * The trap to which the variable binding should be added. * @param name * The name (a.k.a. "id") of the variable binding to be created * @param type * The type of variable binding to be created * @param encoding * Describes the way in which the value content has been encoded * (i.e. XML_ENCODING_TEXT, or XML_ENCODING_BASE64) * @param value * The variable binding value * @exception Throws * SnmpTrapHelperException if the variable binding cannot be * added to the trap for any reason. * @throws org.opennms.netmgt.scriptd.helper.SnmpTrapHelperException if any. */ public void addVarBinding(SnmpTrapBuilder trap, String name, String type, String encoding, String value) throws SnmpTrapHelperException { if (name == null) { throw new SnmpTrapHelperException("Name is null"); } VarBindFactory factory = (VarBindFactory) m_factoryMap.get(type); if (factory == null) { throw new SnmpTrapHelperException("Type " + type + " is invalid or not implemented"); } factory.addVarBind(trap, name, encoding, value); } /** * Create an SNMP V1 trap, based on the content of the specified event, and * forward the trap to the specified address and port. It is assumed that * the specified event represents an SNMP V1 or V2 trap that was received by * OpenNMS (TrapD). * * @param event * The event upon which the trap content should be based * @param destAddr * The address to which the trap should be forwarded * @param destPort * The port to which the trap should be forwarded * @exception Throws * SnmpTrapHelperException if the variable binding cannot be * added to the trap for any reason. * @throws org.opennms.netmgt.scriptd.helper.SnmpTrapHelperException if any. */ public void forwardV1Trap(Event event, String destAddr, int destPort) throws SnmpTrapHelperException { // the event must correspond to an SNMP trap Snmp snmpInfo = event.getSnmp(); if (snmpInfo == null) { throw new SnmpTrapHelperException("Cannot forward an event with no SNMP info: " + event.getUei()); } // check the version of the original trap String version = snmpInfo.getVersion(); SnmpV1TrapBuilder trap = SnmpUtils.getV1TrapBuilder(); if ("v1".equals(version)) { trap.setEnterprise(SnmpObjId.get(snmpInfo.getId())); InetAddress agentAddress; agentAddress = InetAddressUtils.addr(event.getSnmphost()); if (agentAddress == null) { throw new SnmpTrapHelperException("Invalid ip address."); } trap.setAgentAddress(agentAddress); if (snmpInfo.hasGeneric()) { trap.setGeneric(snmpInfo.getGeneric()); } if (snmpInfo.hasSpecific()) { trap.setSpecific(snmpInfo.getSpecific()); } trap.setTimeStamp(snmpInfo.getTimeStamp()); // varbinds int i = 0; for (Parm parm : event.getParmCollection()) { try { Value value = parm.getValue(); addVarBinding(trap, parm.getParmName(), value.getType(), value.getEncoding(), value.getContent()); } catch (SnmpTrapHelperException e) { throw new SnmpTrapHelperException(e.getMessage() + " in event parm[" + i + "]"); } finally { i++; } } } else if ("v2".equals(version)) { // converting V2 trap to V1 (see RFC2576) trap.setEnterprise(SnmpObjId.get(snmpInfo.getId())); String addr = null; for (Parm parm : event.getParmCollection()) { if (SNMP_TRAP_ADDRESS_OID.equals(parm.getParmName())) { addr = parm.getValue().getContent(); break; } } if (addr == null) { addr = "0.0.0.0"; } InetAddress agentAddress; agentAddress = InetAddressUtils.addr(addr); if (agentAddress == null) { throw new SnmpTrapHelperException("Invalid ip address."); } trap.setAgentAddress(agentAddress); trap.setGeneric(snmpInfo.getGeneric()); trap.setSpecific(snmpInfo.getSpecific()); trap.setTimeStamp(snmpInfo.getTimeStamp()); // varbinds int i = 0; for (Parm parm : event.getParmCollection()) { Value value = parm.getValue(); // omit any parms with type=Counter64 if (!(EventConstants.TYPE_SNMP_COUNTER64.equals(value.getType()))) { try { addVarBinding(trap, parm.getParmName(), value.getType(), value.getEncoding(), value.getContent()); } catch (SnmpTrapHelperException e) { throw new SnmpTrapHelperException(e.getMessage() + " in event parm[" + i + "]"); } } i++; } } else { throw new SnmpTrapHelperException("Invalid SNMP version: " + version); } // send the trap sendTrap(destAddr, destPort, snmpInfo.getCommunity(), trap); } private void sendTrap(String destAddr, int destPort, String community, SnmpTrapBuilder trap) throws SnmpTrapHelperException { try { trap.send(destAddr, destPort, community); } catch (Throwable e) { throw new SnmpTrapHelperException("Failed to send trap "+e.getMessage(), e); } } /** * Create an SNMP V2 trap, based on the content of the specified event, and * forward the trap to the specified address and port. It is assumed that * the specified event represents an SNMP V1 or V2 trap that was received by * OpenNMS (TrapD). * * @param event * The event upon which the trap content should be based * @param destAddr * The address to which the trap should be forwarded * @param destPort * The port to which the trap should be forwarded * @exception Throws * SnmpTrapHelperException if the variable binding cannot be * added to the trap for any reason. * @throws org.opennms.netmgt.scriptd.helper.SnmpTrapHelperException if any. */ public void forwardV2Trap(Event event, String destAddr, int destPort) throws SnmpTrapHelperException { // the event must correspond to an SNMP trap Snmp snmpInfo = event.getSnmp(); if (snmpInfo == null) { throw new SnmpTrapHelperException("Cannot forward an event with no SNMP info: " + event.getUei()); } // check the version of the original trap String version = snmpInfo.getVersion(); SnmpTrapBuilder packet = SnmpUtils.getV2TrapBuilder(); if ("v1".equals(version)) { // converting V1 trap to V2 (see RFC2576) addVarBinding(packet, SNMP_SYSUPTIME_OID, EventConstants.TYPE_SNMP_TIMETICKS, Long.toString(snmpInfo.getTimeStamp())); String oid; if (snmpInfo.getGeneric() == ENTERPRISE_SPECIFIC && snmpInfo.hasSpecific()) { oid = snmpInfo.getId() + ".0." + snmpInfo.getSpecific(); } else { oid = SNMP_TRAPS + '.' + (snmpInfo.getGeneric() + 1); } addVarBinding(packet, SNMP_TRAP_OID, EventConstants.TYPE_SNMP_OBJECT_IDENTIFIER, oid); // add the V1 var bindings boolean addrPresent = false; boolean communityPresent = false; boolean enterprisePresent = false; int i = 0; for (Parm parm : event.getParmCollection()) { Value value = parm.getValue(); try { addVarBinding(packet, parm.getParmName(), value.getType(), value.getEncoding(), value.getContent()); } catch (SnmpTrapHelperException e) { throw new SnmpTrapHelperException(e.getMessage() + " in event parm[" + i + "]"); } if (SNMP_TRAP_ADDRESS_OID.equals(parm.getParmName())) { addrPresent = true; } else if (SNMP_TRAP_COMMUNITY_OID.equals(parm.getParmName())) { communityPresent = true; } else if (SNMP_TRAP_ENTERPRISE_OID.equals(parm.getParmName())) { enterprisePresent = true; } i++; } if (!addrPresent) { addVarBinding(packet, SNMP_TRAP_ADDRESS_OID, EventConstants.TYPE_SNMP_IPADDRESS, event.getSnmphost()); } if (!communityPresent) { addVarBinding(packet, SNMP_TRAP_COMMUNITY_OID, EventConstants.TYPE_SNMP_OCTET_STRING, snmpInfo.getCommunity()); } if (!enterprisePresent) { addVarBinding(packet, SNMP_TRAP_ENTERPRISE_OID, EventConstants.TYPE_SNMP_OBJECT_IDENTIFIER, snmpInfo.getId()); } } else if ("v2".equals(version)) { addVarBinding(packet, SNMP_SYSUPTIME_OID, EventConstants.TYPE_SNMP_TIMETICKS, Long.toString(snmpInfo.getTimeStamp())); String oid; if (snmpInfo.getGeneric() == ENTERPRISE_SPECIFIC) { oid = snmpInfo.getId() + "." + snmpInfo.getSpecific(); } else { oid = SNMP_TRAPS + '.' + (snmpInfo.getGeneric() + 1); } addVarBinding(packet, SNMP_TRAP_OID, EventConstants.TYPE_SNMP_OBJECT_IDENTIFIER, oid); int i = 0; for (Parm parm : event.getParmCollection()) { Value value = parm.getValue(); try { addVarBinding(packet, parm.getParmName(), value.getType(), value.getEncoding(), value.getContent()); } catch (SnmpTrapHelperException e) { throw new SnmpTrapHelperException(e.getMessage() + " in event parm[" + i + "]"); } i++; } } else { throw new SnmpTrapHelperException("Invalid SNMP version: " + version); } // send the trap sendTrap(destAddr, destPort, snmpInfo.getCommunity(), packet); } /** * Create an SNMP trap, based on the content of the specified event, and * forward the trap to the specified address and port. It is assumed that * the specified event represents an SNMP V1 or V2 trap that was received by * OpenNMS (TrapD). The type of trap to be created depends on the type of * the original trap (i.e. if the original trap was an SNMP V1 trap, an SNMP * V1 trap will be created; if the original trap was an SNMP V2 trap, an * SNMP V2 trap will be created). * * @param event * The event upon which the trap content should be based * @param destAddr * The address to which the trap should be forwarded * @param destPort * The port to which the trap should be forwarded * @exception Throws * SnmpTrapHelperException if the variable binding cannot be * added to the trap for any reason. * @throws org.opennms.netmgt.scriptd.helper.SnmpTrapHelperException if any. */ public void forwardTrap(Event event, String destAddr, int destPort) throws SnmpTrapHelperException { Snmp snmpInfo = event.getSnmp(); if (snmpInfo == null) { throw new SnmpTrapHelperException("Cannot forward an event with no SNMP info: " + event.getUei()); } String version = snmpInfo.getVersion(); if ("v1".equals(version)) { forwardV1Trap(event, destAddr, destPort); } else if ("v2".equals(version)) { forwardV2Trap(event, destAddr, destPort); } else { throw new SnmpTrapHelperException("Invalid SNMP version: " + version); } } /** * Create an SNMP trap, based on the content of an event derived from a * TL1 autonomous message received by Tl1d, and forward the trap to the * specified address and port. The type of trap created depends on the value * of the "trapVersion" parameter. The "community" parameter determines the * SNMP community string of the resulting trap, defaulting to "public". * * @param event * The event upon which the trap content should be based * @param destAddr * The address to which the trap should be sent * @param destPort * The port to which the trap should be sent * @param trapVersion * The SNMP version ("v1" or "v2c") of the trap * @param community * The SNMP community string for the trap (defaults to "public") * @throws org.opennms.netmgt.scriptd.helper.SnmpTrapHelperException if any. * @throws java.net.UnknownHostException if any. * @exception Throws * SnmpTrapHelperException if the event is not of the appropriate type. * @exception Throws * UnknownHostException if agent-addr resolution fails for the case of an SNMPv1 trap * @exception Throws * SnmpTrapHelperException if the event is not of the appropriate type. * @exception Throws * UnknownHostException if agent-addr resolution fails for the case of an SNMPv1 trap */ public void sendTL1AutonomousMsgTrap(Event event, String destAddr, int destPort, String trapVersion, String community) throws SnmpTrapHelperException, UnknownHostException { // Check first thing that the event is of the right type. if (! org.opennms.netmgt.EventConstants.TL1_AUTONOMOUS_MESSAGE_UEI.equals(event.getUei())) { throw new SnmpTrapHelperException("The event must have a UEI of " + org.opennms.netmgt.EventConstants.TL1_AUTONOMOUS_MESSAGE_UEI); } // Create a TrapBuilder and bootstrap it according to trapVersion SnmpTrapBuilder trapBuilder = null; // What to do about timestamp? Hard-wiring to zero for now. long trapTimeStamp = 0; final String iface = event.getInterface(); if ("v1".equalsIgnoreCase(trapVersion)) { trapBuilder = createV1Trap(".1.3.6.1.4.1.5813.1", // OPENNMS-MIB::openNMS-traps iface, ENTERPRISE_SPECIFIC, 2, // OPENNMS-MIB::openNMS-tl1AutonomousMessageTrap trapTimeStamp); } else if ("v2c".equalsIgnoreCase(trapVersion)) { trapBuilder = createV2Trap(".1.3.6.1.4.1.5813.1.0.2", // OPENNMS-MIB::openNMS-tl1AutonomousMessageTrap Long.toString(trapTimeStamp)); } else { throw new SnmpTrapHelperException("The trap SNMP version must be either v1 or v2c"); } // Add all the MIB-specified varbinds addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.1.8.0", // OPENNMS-MIB::openNMS-event-nodeid EventConstants.TYPE_SNMP_OCTET_STRING, Long.toString(event.getNodeid())); addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.1.9.0", // OPENNMS-MIB::openNMS-event-time EventConstants.TYPE_SNMP_OCTET_STRING, event.getTime()); addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.1.10.0", // OPENNMS-MIB::openNMS-event-host EventConstants.TYPE_SNMP_OCTET_STRING, event.getHost()); addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.1.11.0", // OPENNMS-MIB::openNMS-event-interface EventConstants.TYPE_SNMP_OCTET_STRING, iface); addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.1.13.0", // OPENNMS-MIB::openNMS-event-service EventConstants.TYPE_SNMP_OCTET_STRING, event.getService()); addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.1.18.0", // OPENNMS-MIB::openNMS-event-severity EventConstants.TYPE_SNMP_OCTET_STRING, event.getSeverity()); addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.2.1.1.0", // OPENNMS-MIB::tl1amRawMessage EventConstants.TYPE_SNMP_OCTET_STRING, EventUtil.expandParms("%parm[raw-message]%", event)); addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.2.1.2.0", // OPENNMS-MIB::tl1amAlarmCode EventConstants.TYPE_SNMP_OCTET_STRING, EventUtil.expandParms("%parm[alarm-code]%", event)); addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.2.1.3.0", // OPENNMS-MIB::tl1amAutonomousTag EventConstants.TYPE_SNMP_OCTET_STRING, EventUtil.expandParms("%parm[atag]%", event)); addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.2.1.4.0", // OPENNMS-MIB::tl1amVerb EventConstants.TYPE_SNMP_OCTET_STRING, EventUtil.expandParms("%parm[verb]%", event)); addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.2.1.5.0", // OPENNMS-MIB::tl1amAutoBlock EventConstants.TYPE_SNMP_OCTET_STRING, EventUtil.expandParms("%parm[autoblock]%", event)); addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.2.1.6.0", // OPENNMS-MIB::tl1amAID EventConstants.TYPE_SNMP_OCTET_STRING, EventUtil.expandParms("%parm[aid]%", event)); addVarBinding(trapBuilder, ".1.3.6.1.4.1.5813.20.2.1.7.0", // OPENNMS-MIB::tl1amAdditionalParams EventConstants.TYPE_SNMP_OCTET_STRING, EventUtil.expandParms("%parm[additionalParams]%", event)); // Finally, send the trap! this.sendTrap(destAddr, destPort, community, trapBuilder); } }