/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 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.provision.service; import static org.opennms.core.utils.InetAddressUtils.getInetAddress; import static org.opennms.core.utils.InetAddressUtils.normalize; import static org.opennms.core.utils.InetAddressUtils.str; import java.net.InetAddress; import org.opennms.core.utils.InetAddressUtils; import org.opennms.core.utils.LogUtils; import org.opennms.netmgt.model.OnmsIpInterface; import org.opennms.netmgt.model.OnmsSnmpInterface; import org.opennms.netmgt.snmp.RowCallback; import org.opennms.netmgt.snmp.SnmpInstId; import org.opennms.netmgt.snmp.SnmpObjId; import org.opennms.netmgt.snmp.SnmpResult; import org.opennms.netmgt.snmp.SnmpRowResult; import org.opennms.netmgt.snmp.SnmpValue; import org.opennms.netmgt.snmp.TableTracker; /** * PhysInterfaceTableTracker * * @author brozow * @version $Id: $ */ public class IPAddressTableTracker extends TableTracker { public static final SnmpObjId IP_ADDRESS_PREFIX_TABLE_ENTRY = SnmpObjId.get(".1.3.6.1.2.1.4.32.1"); public static final SnmpObjId IP_ADDRESS_TABLE_ENTRY = SnmpObjId.get(".1.3.6.1.2.1.4.34.1"); public static final SnmpObjId IP_ADDRESS_IF_INDEX = SnmpObjId.get(IP_ADDRESS_TABLE_ENTRY, "3"); public static final SnmpObjId IP_ADDRESS_TYPE_INDEX = SnmpObjId.get(IP_ADDRESS_TABLE_ENTRY, "4"); public static final SnmpObjId IP_ADDRESS_PREFIX_INDEX = SnmpObjId.get(IP_ADDRESS_TABLE_ENTRY, "5"); public static final SnmpObjId IP_ADDRESS_PREFIX_ORIGIN_INDEX = SnmpObjId.get(IP_ADDRESS_PREFIX_TABLE_ENTRY, "5"); public static final SnmpObjId IP_ADDRESS_ORIGIN_INDEX = SnmpObjId.get(IP_ADDRESS_TABLE_ENTRY, "6"); public static final SnmpObjId IP_ADDRESS_STATUS_INDEX = SnmpObjId.get(IP_ADDRESS_TABLE_ENTRY, "7"); public static final SnmpObjId IP_ADDRESS_CREATED_INDEX = SnmpObjId.get(IP_ADDRESS_TABLE_ENTRY, "8"); public static final SnmpObjId IP_ADDRESS_LAST_CHANGED_INDEX = SnmpObjId.get(IP_ADDRESS_TABLE_ENTRY, "9"); public static final SnmpObjId IP_ADDRESS_ROW_STATUS_INDEX = SnmpObjId.get(IP_ADDRESS_TABLE_ENTRY, "10"); public static final SnmpObjId IP_ADDRESS_STORAGE_TYPE_INDEX = SnmpObjId.get(IP_ADDRESS_TABLE_ENTRY, "11"); public static final int TYPE_IPV4 = 1; public static final int TYPE_IPV6 = 2; private static final int IP_ADDRESS_TYPE_UNICAST = 1; // private static final int IP_ADDRESS_TYPE_ANYCAST = 2; // private static final int IP_ADDRESS_TYPE_BROADCAST = 3; private static SnmpObjId[] s_tableColumns = new SnmpObjId[] { IP_ADDRESS_IF_INDEX, IP_ADDRESS_PREFIX_INDEX, IP_ADDRESS_TYPE_INDEX }; class IPAddressRow extends SnmpRowResult { public IPAddressRow(final int columnCount, final SnmpInstId instance) { super(columnCount, instance); LogUtils.debugf(this, "column count = %d, instance = %s", columnCount, instance); } public Integer getIfIndex() { final SnmpValue value = getValue(IP_ADDRESS_IF_INDEX); return value.toInt(); } public String getIpAddress() { final SnmpResult result = getResult(IP_ADDRESS_IF_INDEX); SnmpInstId instance = result.getInstance(); final int[] instanceIds = instance.getIds(); final int addressType = instanceIds[0]; int addressIndex = 2; int addressLength = instanceIds[1]; // Begin NMS-4906 Lame Force 10 agent! if (addressType == TYPE_IPV4 && instanceIds.length != 6) { LogUtils.warnf(this, "BAD AGENT: Does not conform to RFC 4001 Section 4.1 Table Indexing!!! Report them immediately. Making a best guess!"); addressIndex = instanceIds.length - 4; addressLength = 4; } if (addressType == TYPE_IPV6 && instanceIds.length != 18) { LogUtils.warnf(this, "BAD AGENT: Does not conform to RFC 4001 Section 4.1 Table Indexing!!! Report them immediately. Making a best guess!"); addressIndex = instanceIds.length - 16; addressLength = 16; } // End NMS-4906 Lame Force 10 agent! if (addressIndex < 0 || addressIndex + addressLength > instanceIds.length) { LogUtils.warnf(this, "BAD AGENT: Returned instanceId %s does not enough bytes to contain address!. Skipping.", instance); return null; } if (addressType == TYPE_IPV4 || addressType == TYPE_IPV6) { final InetAddress address = getInetAddress(instanceIds, addressIndex, addressLength); return str(address); } return null; } public Integer getType() { final SnmpValue value = getValue(IP_ADDRESS_TYPE_INDEX); return value.toInt(); } private InetAddress getNetMask() { final SnmpValue value = getValue(IP_ADDRESS_PREFIX_INDEX); final SnmpInstId netmaskRef = value.toSnmpObjId().getInstance(IP_ADDRESS_PREFIX_ORIGIN_INDEX); // See bug NMS-5036 // {@see http://issues.opennms.org/browse/NMS-5036} if (netmaskRef == null) { LogUtils.warnf(this, "BAD AGENT: Null netmask instanceId"); return null; } final int[] rawIds = netmaskRef.getIds(); final int addressType = rawIds[1]; final int mask = rawIds[rawIds.length - 1]; int addressLength = rawIds[2]; int addressIndex = 3; // Begin NMS-4906 Lame Force 10 agent! if (addressType == TYPE_IPV4 && rawIds.length != 1+6+1) { LogUtils.warnf(this, "BAD AGENT: Does not conform to RFC 4001 Section 4.1 Table Indexing!!! Report them immediately. Making a best guess!"); addressIndex = rawIds.length - (4+1); addressLength = 4; } if (addressType == TYPE_IPV6 && rawIds.length != 1+18+1) { LogUtils.warnf(this, "BAD AGENT: Does not conform to RFC 4001 Section 4.1 Table Indexing!!! Report them immediately. Making a best guess!"); addressIndex = rawIds.length - (16 + 1); addressLength = 16; } // End NMS-4906 Lame Force 10 agent! if (addressIndex < 0 || addressIndex + addressLength > rawIds.length) { LogUtils.warnf(this, "BAD AGENT: Returned instanceId %s does not enough bytes to contain address!. Skipping.", netmaskRef); return null; } //final InetAddress address = getInetAddress(rawIds, addressIndex, addressLength); if (addressType == TYPE_IPV4) { return InetAddressUtils.convertCidrToInetAddressV4(mask); } else if (addressType == TYPE_IPV6) { return InetAddressUtils.convertCidrToInetAddressV6(mask); } else { LogUtils.warnf(this, "unknown address type, expected 1 (IPv4) or 2 (IPv6), but got %d", addressType); return null; } } public OnmsIpInterface createInterfaceFromRow() { final Integer ifIndex = getIfIndex(); final String ipAddr = getIpAddress(); final Integer type = getType(); final InetAddress netMask = getNetMask(); LogUtils.debugf(this, "createInterfaceFromRow: ifIndex = %s, ipAddress = %s, type = %s, netmask = %s", ifIndex, ipAddr, type, netMask); if (type != IP_ADDRESS_TYPE_UNICAST || ipAddr == null) { return null; } final OnmsSnmpInterface snmpIface = new OnmsSnmpInterface(null, ifIndex); snmpIface.setNetMask(netMask); snmpIface.setCollectionEnabled(true); final OnmsIpInterface iface = new OnmsIpInterface(ipAddr, null); iface.setSnmpInterface(snmpIface); iface.setIfIndex(ifIndex); final String hostName = normalize(ipAddr); LogUtils.debugf(this, "setIpHostName: %s", hostName); iface.setIpHostName(hostName == null? ipAddr : hostName); return iface; } private SnmpResult getResult(final SnmpObjId base) { for(final SnmpResult result : getResults()) { if (base.equals(result.getBase())) { return result; } } return null; } } /** * <p>Constructor for IPInterfaceTableTracker.</p> */ public IPAddressTableTracker() { super(s_tableColumns); } /** * <p>Constructor for IPInterfaceTableTracker.</p> * * @param rowProcessor a {@link org.opennms.netmgt.snmp.RowCallback} object. */ public IPAddressTableTracker(final RowCallback rowProcessor) { super(rowProcessor, s_tableColumns); } /** {@inheritDoc} */ @Override public SnmpRowResult createRowResult(final int columnCount, final SnmpInstId instance) { return new IPAddressRow(columnCount, instance); } /** {@inheritDoc} */ @Override public void rowCompleted(final SnmpRowResult row) { processIPAddressRow((IPAddressRow)row); } /** * <p>processIPInterfaceRow</p> * * @param row a {@link org.opennms.netmgt.provision.service.IPAddressTableTracker.IPAddressRow} object. */ public void processIPAddressRow(final IPAddressRow row) { } }