Hi net-devs,

I've got a problem on AIX operating system when IPv6 is enabled,which can be easily reproduced by attached test case NetworkInterfaceTest.java. On AIX paltform, the /proc file system behaves differently from Linux, so we cannot just read required lines from /proc/net/if_inet6 but to call ioctl to get needed information. A patch is available for OpenJDK8 code base, see attachment patch.diff.

Is anybody interested in this topic?

I'm quite aware of the fact that so far there's no publicly available building scripts for OpenJDK8 on AIX operating system, but before everything settles down, is anybody willing to review the patch? any ideas about how to integrate it?

Best regards!

/* This test checks if the interface's addresses returned by getNetworkInterfaces are unique */

import java.net.*;
import java.util.*;

public class NetworkInterfaceTest {
	java.net.NetworkInterface pnics;
	java.util.Enumeration nics1;

	NetworkInterfaceTest() {
		java.net.NetworkInterface jnic;
		java.util.Enumeration<NetworkInterface> nics;
		List lst = new ArrayList();
		List lst1 = new ArrayList();

		try {
			nics = java.net.NetworkInterface.getNetworkInterfaces();
			while (nics.hasMoreElements()) {
				jnic = (java.net.NetworkInterface) nics.nextElement();
				lst = jnic.getInterfaceAddresses();
				nics1 = jnic.getInetAddresses();
				while (nics1.hasMoreElements()) {
					InetAddress addr1 = (InetAddress) nics1.nextElement();
					if (!(lst1.contains(addr1))) {
						lst1.add(addr1);
					}
				}
                if(lst.size() != lst1.size()){
                    System.out.println(this.getClass().getName()+" failed!");
                }else{
                    System.out.println(this.getClass().getName()+" passed!");
                }
				lst1.clear();
			}
		} catch (java.lang.Exception e) {
			e.printStackTrace();
		}
	}

    public static void main(String[] args) {
        new NetworkInterfaceTest();
    }
}


diff -r 7539cc99befe src/solaris/native/java/net/NetworkInterface.c
--- a/src/solaris/native/java/net/NetworkInterface.c	Thu Oct 13 10:35:43 2011 -0700
+++ b/src/solaris/native/java/net/NetworkInterface.c	Fri Oct 14 17:44:02 2011 +0800
@@ -22,6 +22,8 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+#define MAX(x,y) ((x) > (y) ? (x) : (y))				
+#define SIZE(p) MAX((p).sa_len, sizeof(p))
 
 
 #include <errno.h>
@@ -1095,12 +1097,96 @@
     return ifs;
 }
 
-
+#if defined(AF_INET6)                                           
+#if defined(AIX) 
+/*                                                                              
+ * Enumerates and returns all IPv6 interfaces on AIX                          
+ */                                                                              
+static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {                     
+    struct ifconf ifc;                                                          
+    struct ifreq *ifreqP;                                                      
+    char *buf;                                                                  
+    int numifs;                                                                 
+    unsigned i;                                                                 
+    unsigned bufsize;                                                           
+    char *cp, *cplimit;								
+                                                                                
+    /* use SIOCGSIZIFCONF to get size for  SIOCGIFCONF */                       
+                                                                                
+    ifc.ifc_buf = NULL;                                                          
+    if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) {                      
+        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",     
+                        "ioctl SIOCGSIZIFCONF failed");                          
+        return ifs;                                                             
+    }                                                                          
+    bufsize = ifc.ifc_len;                                                     
+                                                                                
+    buf = (char *)malloc(bufsize);                                              
+    if (!buf) {                                                                 
+        JNU_ThrowOutOfMemoryError(env, "Network interface native buffer allocation failed");  
+        return ifs;                                                            
+    }                                                                         
+    ifc.ifc_len = bufsize;                                                     
+    ifc.ifc_buf = buf;                                                          
+    if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {          
+        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",   
+                        "ioctl CSIOCGIFCONF failed");                          
+        (void) free(buf);                                                       
+        return ifs;                                                              
+    }                                                                          
+                                                                              
+    /*                                                                        
+     * Iterate through each interface                                        
+     */                                                                       
+    ifreqP = ifc.ifc_req;                                                      
+    cp=(char *)ifc.ifc_req;						
+    cplimit=cp+ifc.ifc_len;                                                   
+    for (;cp<cplimit;cp+=(sizeof(ifreqP->ifr_name) + SIZE(ifreqP->ifr_addr))){  
+       ifreqP=(struct ifreq *)cp;					
+       struct ifreq if2;                                                        
+                                                                               
+       memset((char *)&if2, 0, sizeof(if2));                                   
+       strcpy(if2.ifr_name, ifreqP->ifr_name);                              
+                                                                                
+       /*                                                                       
+        * Skip interface that aren't UP                                          
+        */                                                                      
+       if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) >= 0) {                      
+            if (!(if2.ifr_flags & IFF_UP)) {                                     
+                continue;                                                        
+            }                                                                  
+        }                                                                       
+                                                                               
+        if (ifreqP->ifr_addr.sa_family != AF_INET6)                            
+            continue;                                                           
+                                                                                
+       /*                                                                       
+        * Add to the list                                                      
+        */                                                                      
+        ifs = addif(env, sock, ifreqP->ifr_name, ifs,              
+                    (struct sockaddr *)&(ifreqP->ifr_addr),                    
+                     AF_INET6,0,-1);   /*AIX_FIXME - should prefix be zero?*/   
+                                                                                
+       /*                                                                      
+        * If an exception occurred then free the list                           
+        */                                                                     
+       if ((*env)->ExceptionOccurred(env)) {                                    
+           free(buf);                                                           
+           freeif(ifs);                                                         
+           return NULL;                                                          
+       }                                                                         
+    }                                                                           
+                                                                               
+    /*                                                                          
+     * Free socket and buffer                                                  
+     */                                                                         
+    free(buf);                                                                  
+    return ifs;                                                                 
+}                                                                               
+#else
 /*
  * Enumerates and returns all IPv6 interfaces on Linux
  */
-
-#ifdef AF_INET6
 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
     FILE *f;
     char addr6[40], devname[21];
@@ -1142,6 +1228,7 @@
     return ifs;
 }
 #endif
+#endif
 
 
 static int getIndex(int sock, const char *name){

Reply via email to