[SNMP4J] IPv6 Address with Scope

Frank Fock fock at agentpp.com
Wed Mar 25 23:03:15 CET 2009


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




More information about the SNMP4J mailing list