[SNMP4J] IPv6 Address with Scope

Frank Fock fock at agentpp.com
Thu Mar 26 22:47:41 CET 2009


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 <fock at agentpp.com> 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
>>>> SNMP4J at agentpp.org
>>>> 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




More information about the SNMP4J mailing list