Senthil, OK, thanks! I knew why I ask you to try it ;-) Is fixed in the repository now.
Best regards, Frank Senthil Muniswamy wrote:
Frank, There is a bug in the getValue() method. When there is scope, port bytes are not set correctly because of wrong index. It should be: retval[addr.length+scopeSize] = (byte)((port >> 8) & 0xFF); retval[addr.length+scopeSize+1] = (byte)(port & 0xFF); Thanks, Senthil On Wed, Mar 25, 2009 at 6:03 PM, Frank Fock <[email protected]> wrote:Senthil, Here is my implementation that works with Java 1.5 or later and does not break 1.4 compatibility: /** * Sets this transport address from an OcetString containing the address * value in format as specified by the TRANSPORT-ADDRESS-MIB. * @param transportAddress * an OctetString containing the IP address bytes and the two port bytes * in network byte order. * @throws UnknownHostException * if the address is invalid. */ public void setTransportAddress(OctetString transportAddress) throws UnknownHostException { OctetString inetAddr = transportAddress.substring(0, transportAddress.length()-2); byte[] addr = inetAddr.getValue(); if ((addr.length == 8) || (addr.length == 20)) { // address with zone (scope) index byte[] ipaddr = new byte[addr.length-4]; System.arraycopy(addr, 0, ipaddr, 0, ipaddr.length); int sz = ipaddr.length; int scope = ((addr[sz] << 24) + ((addr[sz+1] & 0xff) << 16) + ((addr[sz+2] & 0xFF) << 8) + (addr[sz+3] & 0xFF)); try { Class[] params = new Class[] { String.class, byte[].class, int.class }; Method m = Inet6Address.class.getMethod("getByAddress", params); Object[] args = new Object[] { null, ipaddr, new Integer(scope) }; Object o = m.invoke(Inet6Address.class, args); setInetAddress((InetAddress)o); } catch (Exception ex) { logger.warn("Java < 1.5 does not support scoped IPv6 addresses, "+ "ignoring scope ID for " + transportAddress); setInetAddress(InetAddress.getByAddress(ipaddr)); } } else { setInetAddress(InetAddress.getByAddress(addr)); } port = ((transportAddress.get(transportAddress.length()-2) & 0xFF) << 8); port += (transportAddress.get(transportAddress.length()-1) & 0xFF); } /** * Returns the address value as a byte array. * @return * a byte array with IP address bytes and two additional bytes containing * the port in network byte order. If the address is a zoned (scoped) IP * address, four additional bytes with the scope ID are returned between * address and port bytes. * @since 1.5 */ public byte[] getValue() { byte[] addr = getInetAddress().getAddress(); int scopeSize = 0; int scopeID = 0; if (getInetAddress() instanceof Inet6Address) { try { Inet6Address ip6Addr = (Inet6Address) getInetAddress(); Method m = Inet6Address.class.getMethod("getScopeId", null); Object scope = m.invoke(ip6Addr, null); scopeID = ((Number)scope).intValue(); scopeSize = 4; } catch (Exception ex) { // ignore } } byte[] retval = new byte[addr.length+2+scopeSize]; System.arraycopy(addr, 0, retval, 0, addr.length); if (scopeSize > 0) { int offset = addr.length; retval[offset++] = (byte)((scopeID & 0xFF000000) >> 24); retval[offset++] = (byte)((scopeID & 0x00FF0000) >> 16); retval[offset++] = (byte)((scopeID & 0x0000FF00) >> 8); retval[offset++] = (byte) (scopeID & 0x000000FF); } retval[addr.length ] = (byte)((port >> 8) & 0xFF); retval[addr.length+1] = (byte)(port & 0xFF); return retval; } Please let me know if it works for you. Best regards, Frank Frank Fock wrote:Senthil, Thanks for your fix. However, IPv4 zoned addresses are not handled correctly by it. I am working on solution that covers those too. Best regards, Frank Senthil Muniswamy wrote:Frank, I am using SNMP4J-Agent and TransportIpAddress.setTransportAddress(OctetString transportAddress) causes exception if snmpTargetAddrTAddress is set with TAddress (IPv6 Address with Scope). I have made below changes to TransportIpAddress to handle the scope, could you please confirm if this is correct? public void setTransportAddress(OctetString transportAddress) throws UnknownHostException { OctetString inetAddr = transportAddress.substring(0, transportAddress.length()-2); byte[] addr = inetAddr.getValue(); if(addr.length <= 16) { setInetAddress(InetAddress.getByAddress(addr)); } else { byte[] ip6addr = new byte[16]; System.arraycopy(addr, 0, ip6addr, 0, ip6addr.length); int scope = ((addr[16] << 24) + ((addr[17] & 0xff) << 16) + ((addr[18] & 0xFF) << 8) + (addr[19] & 0xFF)); setInetAddress(Inet6Address.getByAddress(null, ip6addr, scope)); } port = ((transportAddress.get(transportAddress.length()-2) & 0xFF) << 8); port += (transportAddress.get(transportAddress.length()-1) & 0xFF); } public byte[] getValue() { byte[] addr = getInetAddress().getAddress(); int size = 2; if(getInetAddress() instanceof Inet6Address && ((Inet6Address)getInetAddress()).getScopeId() > 0) { size = size+4; } byte[] retval = new byte[addr.length+size]; System.arraycopy(addr, 0, retval, 0, addr.length); if(size > 2) { int scope = ((Inet6Address)getInetAddress()).getScopeId(); retval[addr.length] = (byte)((scope & 0xFF000000) >> 24); retval[addr.length+1] = (byte)((scope & 0x00FF0000) >> 16); retval[addr.length+2] = (byte)((scope & 0x0000FF00) >> 8); retval[addr.length+3] = (byte)(scope & 0x000000FF); } retval[retval.length-2] = (byte)((port >> 8) & 0xFF); retval[retval.length-1] = (byte)(port & 0xFF); return retval; } public int getBERLength() { return getValue().length; } Thanks, Senthil _______________________________________________ SNMP4J mailing list [email protected] http://lists.agentpp.org/mailman/listinfo/snmp4j-- AGENT++ http://www.agentpp.com http://www.mibexplorer.com http://www.mibdesigner.com
-- AGENT++ http://www.agentpp.com http://www.mibexplorer.com http://www.mibdesigner.com _______________________________________________ SNMP4J mailing list [email protected] http://lists.agentpp.org/mailman/listinfo/snmp4j
