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 > > _______________________________________________ SNMP4J mailing list [email protected] http://lists.agentpp.org/mailman/listinfo/snmp4j
