package org.opennms.netmgt.snmp.mock; import java.math.BigInteger; import java.net.InetAddress; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.opennms.core.utils.InetAddressUtils; import org.opennms.core.utils.LogUtils; import org.opennms.netmgt.snmp.SnmpObjId; import org.opennms.netmgt.snmp.SnmpUtils; import org.opennms.netmgt.snmp.SnmpValue; import org.opennms.netmgt.snmp.SnmpValueFactory; public class MockSnmpValueFactory implements SnmpValueFactory { final Charset m_defaultCharset; public MockSnmpValueFactory() { m_defaultCharset = Charset.defaultCharset(); } @Override public SnmpValue getOctetString(final byte[] bytes) { return new MockSnmpValue.OctetStringSnmpValue(bytes); } @Override public SnmpValue getCounter32(final long val) { return new MockSnmpValue.Counter32SnmpValue(val); } @Override public SnmpValue getCounter64(final BigInteger val) { if (val == null) return null; return new MockSnmpValue.Counter64SnmpValue(val); } @Override public SnmpValue getGauge32(final long val) { return new MockSnmpValue.Gauge32SnmpValue(val); } @Override public SnmpValue getInt32(final int val) { return new MockSnmpValue.Integer32SnmpValue(val); } @Override public SnmpValue getIpAddress(final InetAddress val) { if (val == null) return null; return new MockSnmpValue.IpAddressSnmpValue(val); } @Override public SnmpValue getObjectId(final SnmpObjId objId) { return new MockSnmpValue.OidSnmpValue(objId); } @Override public SnmpValue getTimeTicks(final long val) { return new MockSnmpValue.TimeticksSnmpValue(val); } @Override public SnmpValue getValue(int type, byte[] bytes) { switch (type) { case SnmpValue.SNMP_COUNTER32: return new MockSnmpValue.Counter32SnmpValue(new BigInteger(bytes).longValue()); case SnmpValue.SNMP_COUNTER64: return new MockSnmpValue.Counter64SnmpValue(new BigInteger(bytes)); case SnmpValue.SNMP_END_OF_MIB: return MockSnmpValue.END_OF_MIB; case SnmpValue.SNMP_GAUGE32: return new MockSnmpValue.Gauge32SnmpValue(new BigInteger(bytes).longValue()); case SnmpValue.SNMP_INT32: return new MockSnmpValue.Integer32SnmpValue(new BigInteger(bytes).intValue()); case SnmpValue.SNMP_IPADDRESS: return new MockSnmpValue.IpAddressSnmpValue(bytes); case SnmpValue.SNMP_NO_SUCH_INSTANCE: return MockSnmpValue.NO_SUCH_INSTANCE; case SnmpValue.SNMP_NO_SUCH_OBJECT: return MockSnmpValue.NO_SUCH_OBJECT; case SnmpValue.SNMP_NULL: return MockSnmpValue.NULL_VALUE; case SnmpValue.SNMP_OBJECT_IDENTIFIER: return new MockSnmpValue.OidSnmpValue(new String(bytes)); case SnmpValue.SNMP_OCTET_STRING: return new MockSnmpValue.OctetStringSnmpValue(bytes); case SnmpValue.SNMP_TIMETICKS: return new MockSnmpValue.TimeticksSnmpValue(new BigInteger(bytes).longValue()); case SnmpValue.SNMP_OPAQUE: throw new IllegalArgumentException("Unable to handle opaque types in MockSnmpValue"); default: throw new IllegalArgumentException("Unknown SNMP value type: "+type); } } @Override public SnmpValue getNull() { return MockSnmpValue.NULL_VALUE; } @Override public SnmpValue getOpaque(final byte[] bs) { throw new IllegalArgumentException("Unable to handle opaque types in MockSnmpValue"); } private static final Pattern HEX_CHUNK_PATTERN = Pattern.compile("(..)[ :]?"); SnmpValue parseMibValue(final String mibVal) { if (mibVal.startsWith("OID:")) { return getObjectId(SnmpObjId.get(mibVal.substring("OID:".length()).trim())); } else if (mibVal.startsWith("Timeticks:")) { String timeticks = mibVal.substring("Timeticks:".length()).trim(); if (timeticks.contains("(")) { timeticks = timeticks.replaceAll("^.*\\((\\d*?)\\).*$", "$1"); } return getTimeTicks(Long.valueOf(timeticks)); } else if (mibVal.startsWith("STRING:")) { return getOctetString(mibVal.substring("STRING:".length()).trim().getBytes()); } else if (mibVal.startsWith("INTEGER:")) { return getInt32(Integer.valueOf(mibVal.substring("INTEGER:".length()).trim().replaceAll(" *.[Bb]ytes$", ""))); } else if (mibVal.startsWith("Gauge32:")) { return getGauge32(Long.valueOf(mibVal.substring("Gauge32:".length()).trim())); } else if (mibVal.startsWith("Counter32:")) { return getCounter32(Long.valueOf(mibVal.substring("Counter32:".length()).trim())); } else if (mibVal.startsWith("Counter64:")) { return getCounter64(BigInteger.valueOf(Long.valueOf(mibVal.substring("Counter64:".length()).trim()))); } else if (mibVal.startsWith("IpAddress:")) { return getIpAddress(InetAddressUtils.addr(mibVal.substring("IpAddress:".length()).trim())); } else if (mibVal.startsWith("Hex-STRING:")) { final String trimmed = mibVal.substring("Hex-STRING:".length()).trim(); final ByteBuffer bb = ByteBuffer.allocate(trimmed.length()); if (trimmed.matches("^.*[ :].*$")) { for (final String chunk : trimmed.split("[ :]")) { short s = Short.valueOf(chunk, 16); bb.put((byte)(s & 0xFF)); } } else { if (trimmed.length() % 2 != 0) { LogUtils.warnf(SnmpUtils.class, "Hex-STRING %s does not have ' ' or ':' separators, but it is an uneven number of characters.", trimmed); } final Matcher m = MockSnmpValueFactory.HEX_CHUNK_PATTERN.matcher(trimmed); while (m.find()) { short s = Short.valueOf(m.group(1), 16); bb.put((byte)(s & 0xFF)); } } final byte[] parsed = new byte[bb.position()]; bb.flip(); bb.get(parsed); return getOctetString(parsed); } else if (mibVal.startsWith("Network Address:")) { return getOctetString(mibVal.substring("Network Address:".length()).trim().getBytes()); } else if (mibVal.startsWith("BITS:")) { return getOctetString(mibVal.substring("BITS:".length()).trim().getBytes()); } else if (mibVal.equals("\"\"")) { return getNull(); } throw new IllegalArgumentException("Unknown Snmp Type: "+mibVal); } }