[jbossnative-commits] JBoss Native SVN: r1021 - in trunk/sight/native: os/linux and 1 other directory.

jbossnative-commits at lists.jboss.org jbossnative-commits at lists.jboss.org
Wed Sep 12 11:15:56 EDT 2007


Author: mladen.turk at jboss.com
Date: 2007-09-12 11:15:56 -0400 (Wed, 12 Sep 2007)
New Revision: 1021

Modified:
   trunk/sight/native/include/sight_types.h
   trunk/sight/native/os/linux/netadapter.c
Log:
Implement Linux NetworkAdapter - stage 2

Modified: trunk/sight/native/include/sight_types.h
===================================================================
--- trunk/sight/native/include/sight_types.h	2007-09-11 17:18:14 UTC (rev 1020)
+++ trunk/sight/native/include/sight_types.h	2007-09-12 15:15:56 UTC (rev 1021)
@@ -216,7 +216,10 @@
 #define SIGHT_TCP_TIME_WAIT    11
 #define SIGHT_TCP_DELETE_TCB   12
 
+#define SIGHT_IFO_UP            1
+#define SIGHT_IFO_DOWN          2
 
+
 #ifdef __cplusplus
 }
 #endif

Modified: trunk/sight/native/os/linux/netadapter.c
===================================================================
--- trunk/sight/native/os/linux/netadapter.c	2007-09-11 17:18:14 UTC (rev 1020)
+++ trunk/sight/native/os/linux/netadapter.c	2007-09-12 15:15:56 UTC (rev 1021)
@@ -143,9 +143,17 @@
 }
 
 #define PROC_INET6_FILE "/proc/net/if_inet6"
+#define PROC_NET_DEV    "/proc/net/dev"
 
 typedef struct net_ifc_data_t {
     int             type;
+    int             index;
+    int             flags;
+    char            ip4a[128];
+    char            ip6a[128];
+    char            maca[64];
+    char            mask[64];
+    char            badr[64];
 } net_ifc_data_t;
 
 typedef struct net_adapter_enum_t {
@@ -159,19 +167,48 @@
 {
     net_ifc_data_t *d = (net_ifc_data_t *)data;
     if (d) {
-        
         free(d);
     }
 }
 
+static char *hex_base = "0123456789abcdefx";
+
+static void make_mac(void *data, char *dest)
+{
+    int i, j = 0;
+    unsigned char buf[IFHWADDRLEN];
+    char *sp = dest;
+
+    memcpy(buf, data, IFHWADDRLEN);
+    *dest = '\0';
+    for (i = 0; i < IFHWADDRLEN; i++) {
+        if (buf[i]) {
+            j = 1;
+            break;    
+        }
+    }
+    if (!j)
+        return;
+    for (i = 0; i < IFHWADDRLEN - 1; i++) {
+        *sp++ = hex_base[buf[i] >> 4];
+        *sp++ = hex_base[buf[i] & 0x0f];
+        *sp++ = ':';
+    }
+    *sp++ = hex_base[buf[i] >> 4];
+    *sp++ = hex_base[buf[i] & 0x0f];
+    *sp++ = '\0';
+}
+
 SIGHT_EXPORT_DECLARE(jlong, NetworkAdapter, enum0)(SIGHT_STDARGS,
                                                    jlong pool)
 {
     net_adapter_enum_t *e;
-    int i;
+    int i, j;
     struct ifconf  ifc;
     struct ifreq  *ifr;
     sight_arr_t   *i6a;
+    sight_arr_t   *i4a;
+    net_ifc_data_t *id;
 
     UNREFERENCED_O;
     UNREFERENCED(pool);
@@ -190,6 +227,7 @@
         throwAprException(_E, apr_get_os_error());
         goto cleanup;
     }
+
     ifc.ifc_buf = NULL;    
     if (ioctl(e->sd, SIOCGIFCONF, (char *)&ifc) < 0) {
         throwAprException(_E, apr_get_os_error());
@@ -207,47 +245,154 @@
     ifr = ifc.ifc_req;
     for (i = 0; i < ifc.ifc_len; i += sizeof(struct ifreq), ifr++) {
         cache_entry_t  *ce;
+        char las[128] = "";
+        struct sockaddr_in *sa;
+        printf("IPV4: %10s\n",  ifr->ifr_name);
+
+        sa = (struct sockaddr_in *)&ifr->ifr_addr;
+        inet_ntop(AF_INET, &sa->sin_addr, las, 64);
         ce = cache_add(e->ifc, ifr->ifr_name);
-        if (!ce->data) {
-            net_ifc_data_t *id;
+        if (!(id = (net_ifc_data_t *)ce->data)) {        
+            struct ifreq ifi;
             if (!(id = (net_ifc_data_t *)sight_calloc(_E,
                                                       sizeof(net_ifc_data_t),
                                                       THROW_FMARK))) {
                 free(ifc.ifc_buf);
                 goto cleanup;
             }
+            memset(&ifi, 0, sizeof(struct ifreq));
+            strcpy(ifi.ifr_name, ifr->ifr_name);
+
+            if (ioctl(e->sd, SIOCGIFINDEX, (char *)&ifi) < 0) {
+                throwAprException(_E, apr_get_os_error());
+                free(ifc.ifc_buf);
+                free(id);
+                goto cleanup;
+            }
+            id->index = ifi.ifr_ifindex;
+
+            if (ioctl(e->sd, SIOCGIFFLAGS, (char *)&ifi) < 0) {
+                throwAprException(_E, apr_get_os_error());
+                free(ifc.ifc_buf);
+                free(id);
+                goto cleanup;
+            }
+            id->flags = ifi.ifr_flags;
+            strcpy(id->ip4a, las);
+
+            if (ioctl(e->sd, SIOCGIFHWADDR, (char *)&ifi) >= 0) {
+                /* Can we have IPV4 without MAC address ? */
+                make_mac(ifi.ifr_hwaddr.sa_data, id->maca);
+            }
+
+            if (ioctl(e->sd, SIOCGIFNETMASK, (char *)&ifi) >= 0) {
+                sa = (struct sockaddr_in *)&ifi.ifr_netmask;
+                inet_ntop(AF_INET, &sa->sin_addr, id->mask, 64);
+            }
+
+            if ((id->flags & IFF_BROADCAST) &&
+                ioctl(e->sd, SIOCGIFBRDADDR, (char *)&ifi) >= 0) {                  
+                sa = (struct sockaddr_in *)&ifi.ifr_broadaddr;
+                inet_ntop(AF_INET, &sa->sin_addr, id->badr, 64);
+            }
             id->type = AF_INET;
             ce->data = id;
         }
+        else {
+            strcpy(id->ip4a, las);
+        }
+
     }
     
     free(ifc.ifc_buf);
+    /* Add missing interfaces from /proc/net/dev */
+    if ((i4a = sight_arr_rload(PROC_NET_DEV)) != NULL) {
+        for (i = 2; i < i4a->siz; i++) {
+            cache_entry_t  *ce;
+            char *pname;
+            if (!(pname = strchr(i4a->arr.ca[i], ':')))
+                continue;
+            *pname = '\0';
+            ce = cache_add(e->ifc, i4a->arr.ca[i]);
+            if (!(id = (net_ifc_data_t *)ce->data)) {
+                struct ifreq ifi;
+                struct sockaddr_in *sa;
+
+                if (!(id = (net_ifc_data_t *)sight_calloc(_E,
+                                                          sizeof(net_ifc_data_t),
+                                                          THROW_FMARK))) {
+                    sight_arr_free(i4a);
+                    goto cleanup;
+                }
+                strcpy(ifi.ifr_name, i4a->arr.ca[i]);
+                id->type  = AF_INET;
+                if (ioctl(e->sd, SIOCGIFINDEX, (char *)&ifi) >= 0)
+                    id->index = ifi.ifr_ifindex;
+                else
+                    id->index = -1;
+                if (ioctl(e->sd, SIOCGIFFLAGS, (char *)&ifi) >= 0)
+                    id->flags = ifi.ifr_flags;
+
+                if (ioctl(e->sd, SIOCGIFHWADDR, (char *)&ifi) >= 0) {
+                    /* Can we have IPV4 without MAC address ? */
+                    make_mac(ifi.ifr_hwaddr.sa_data, id->maca);
+                }
+
+                if (ioctl(e->sd, SIOCGIFNETMASK, (char *)&ifi) >= 0) {
+                    sa = (struct sockaddr_in *)&ifi.ifr_netmask;
+                    inet_ntop(AF_INET, &sa->sin_addr, id->mask, 64);
+                }
+
+                if ((id->flags & IFF_BROADCAST) &&
+                    ioctl(e->sd, SIOCGIFBRDADDR, (char *)&ifi) >= 0) {                  
+                    sa = (struct sockaddr_in *)&ifi.ifr_broadaddr;
+                    inet_ntop(AF_INET, &sa->sin_addr, id->badr, 64);
+                }
+                ce->data  = id;
+            }                  
+        }
+        sight_arr_free(i4a);
+    }
     /* Now add IPV6 entries */
     if ((i6a = sight_arr_rload(PROC_INET6_FILE)) != NULL) {
         for (i = 0; i < i6a->siz; i++) {
             cache_entry_t  *ce;
+            struct ifreq ifi;
             int al, plen, scope, dads, ifidx;
-            char name[20];
+            char ias[64];
+            char las[128] = "";
             struct in6_addr in6;
-
             al = sscanf(i6a->arr.ca[i],
-                        "%08X%08X%08X%08X %02x %02x %02x %02x %20s",
-                        &in6.s6_addr32[0], &in6.s6_addr32[1],
-                        &in6.s6_addr32[2], &in6.s6_addr32[3],
-                        &ifidx, &plen, &scope, &dads, &name);
-
-            ce = cache_add(e->ifc, name);
-            if (!ce->data) {
-                net_ifc_data_t *id;
+                        "%32s %02x %02x %02x %02x %16s",
+                        ias, &ifidx, &plen, &scope, &dads, ifi.ifr_name);
+            sight_hex2bin(ias, in6.s6_addr, 16);
+            sight_inet_ntop6(in6.s6_addr, las, 64);
+            ce = cache_add(e->ifc, ifi.ifr_name);
+            if (plen) {
+                char buf[32];
+                sprintf(buf, "/%d", plen);
+                strcat(las, buf);
+            }
+            if (!(id = (net_ifc_data_t *)ce->data)) {
                 if (!(id = (net_ifc_data_t *)sight_calloc(_E,
                                                           sizeof(net_ifc_data_t),
                                                           THROW_FMARK))) {
                     sight_arr_free(i6a);
                     goto cleanup;
                 }
-                id->type = AF_INET6;
-                ce->data = id;
-            }                        
+                strcpy(id->ip6a, las);
+                if (ioctl(e->sd, SIOCGIFHWADDR, (char *)&ifi) >= 0) {
+                    make_mac(ifi.ifr_hwaddr.sa_data, las);
+                    strcpy(id->maca, las);
+                }
+                id->type  = AF_INET6;
+                id->index = ifidx;
+                id->flags = IFF_UP;
+                ce->data  = id;
+            }
+            else {
+                strcpy(id->ip6a, las);
+            }      
         }
         sight_arr_free(i6a);
     }
@@ -279,6 +424,9 @@
 {
     net_adapter_enum_t *e = J2P(handle, net_adapter_enum_t *);
     net_ifc_data_t *id;
+    jobject addr;
+    jobjectArray aarr;
+    jint len, idx;
 
     UNREFERENCED_O;
     if (!e || e->idx > e->ifc->siz)
@@ -287,6 +435,69 @@
     SET_IFIELD_S(0000, thiz, e->ifc->list[e->idx]->key);
     /* TODO: Figure out the Description */
     SET_IFIELD_S(0002, thiz, e->ifc->list[e->idx]->key);
+    
+    if (id->maca[0]) {
+        addr = sight_new_netaddr_class(_E, _O);
+        if (!addr || (*_E)->ExceptionCheck(_E))
+            return;
+        sight_netaddr_set_addr(_E, addr, id->maca);
+        sight_netaddr_set_family(_E, addr, AF_HARDWARE);
+        SET_IFIELD_O(0003, thiz, addr);
+        (*_E)->DeleteLocalRef(_E, addr);
+    }
+    /* Set adapter type */
+    if (id->flags & IFF_LOOPBACK) {
+        CALL_METHOD1(0000, thiz, IF_TYPE_SOFTWARE_LOOPBACK);
+    }
+    else if (id->flags & IFF_POINTOPOINT) {
+        CALL_METHOD1(0000, thiz, IF_TYPE_PPP);
+    }
+    else {
+        CALL_METHOD1(0000, thiz, IF_TYPE_ETHERNET_CSMACD);
+    }
+    /* Set adapter status */
+    if (id->flags & IFF_UP) {
+        CALL_METHOD1(0001, thiz, SIGHT_IFO_UP);
+    } 
+    else {
+        CALL_METHOD1(0001, thiz, SIGHT_IFO_DOWN);
+    }
+    /* Set IP addresses */
+    len = 0;
+    if (id->ip4a[0])
+        len++;
+    if (id->ip6a[0])
+        len++;
+    if (len) {
+        idx = 0;
+        aarr = sight_new_netaddr_array(_E, _O, len);
+        if (!aarr || (*_E)->ExceptionCheck(_E))
+            goto cleanup;
+        if (id->ip4a[0]) {
+            addr = sight_new_netaddr_class(_E, _O);
+            if (!addr || (*_E)->ExceptionCheck(_E))
+                return;
+            sight_netaddr_set_addr(_E, addr, id->ip4a);
+            sight_netaddr_set_family(_E, addr, AF_INET);
+            if (id->mask[0])
+                sight_netaddr_set_mask(_E, addr, id->mask);
+            (*_E)->SetObjectArrayElement(_E, aarr, idx++, addr);
+            (*_E)->DeleteLocalRef(_E, addr);            
+        }
+        if (id->ip6a[0]) {
+            addr = sight_new_netaddr_class(_E, _O);
+            if (!addr || (*_E)->ExceptionCheck(_E))
+                return;
+            sight_netaddr_set_addr(_E, addr, id->ip6a);
+            sight_netaddr_set_family(_E, addr, AF_INET6);
+            (*_E)->SetObjectArrayElement(_E, aarr, idx++, addr);
+            (*_E)->DeleteLocalRef(_E, addr);        
+        }
+        SET_IFIELD_O(0006, thiz, aarr);
+        (*_E)->DeleteLocalRef(_E, aarr);
+    }
+
+cleanup:    
     e->idx++;
 }
 




More information about the jbossnative-commits mailing list