Author: mladen.turk(a)jboss.com
Date: 2007-09-14 03:54:55 -0400 (Fri, 14 Sep 2007)
New Revision: 1028
Modified:
trunk/sight/native/os/linux/netadapter.c
Log:
Fix virtual adapters
Modified: trunk/sight/native/os/linux/netadapter.c
===================================================================
--- trunk/sight/native/os/linux/netadapter.c 2007-09-13 10:32:37 UTC (rev 1027)
+++ trunk/sight/native/os/linux/netadapter.c 2007-09-14 07:54:55 UTC (rev 1028)
@@ -145,20 +145,20 @@
#define PROC_INET6_FILE "/proc/net/if_inet6"
#define PROC_NET_DEV "/proc/net/dev"
+typedef struct net_ifc_addr_t {
+ char ip4a[64];
+ char ip6a[64];
+ char mask[64];
+ char badr[64];
+} net_ifc_addr_t;
+
typedef struct net_ifc_data_t {
int type;
int index;
int flags;
int mtu;
- char ip4a[64];
- char ip6a[64];
char maca[64];
- char mask[64];
- char badr[64];
- char p4ds[64];
- char s4ds[64];
- char p6ds[64];
- char s6ds[64];
+ cache_table_t *addr;
} net_ifc_data_t;
typedef struct net_adapter_enum_t {
@@ -172,6 +172,7 @@
{
net_ifc_data_t *d = (net_ifc_data_t *)data;
if (d) {
+ cache_free(d->addr, NULL);
free(d);
}
}
@@ -204,7 +205,8 @@
*sp++ = '\0';
}
-static void do_ifrec(net_ifc_data_t *id, int sd, const char *name)
+static void do_ifrec(net_ifc_data_t *id, net_ifc_addr_t *ca,
+ int sd, const char *name)
{
struct ifreq ifi;
struct sockaddr_in *sa;
@@ -220,24 +222,70 @@
if (!ioctl(sd, SIOCGIFFLAGS, (char *)&ifi))
id->flags = ifi.ifr_flags;
/* Can we have IPV4 without MAC address ? */
- if (!ioctl(sd, SIOCGIFHWADDR, (char *)&ifi))
+
+ if (!id->maca[0] && !ioctl(sd, SIOCGIFHWADDR, (char *)&ifi))
make_mac(ifi.ifr_hwaddr.sa_data, id->maca);
if (!ioctl(sd, SIOCGIFNETMASK, (char *)&ifi)) {
sa = (struct sockaddr_in *)&ifi.ifr_netmask;
- inet_ntop(AF_INET, &sa->sin_addr, id->mask, 64);
+ inet_ntop(AF_INET, &sa->sin_addr, ca->mask, 64);
}
if ((id->flags & IFF_BROADCAST) &&
!ioctl(sd, SIOCGIFBRDADDR, (char *)&ifi)) {
sa = (struct sockaddr_in *)&ifi.ifr_broadaddr;
- inet_ntop(AF_INET, &sa->sin_addr, id->badr, 64);
+ inet_ntop(AF_INET, &sa->sin_addr, ca->badr, 64);
}
if (!ioctl(sd, SIOCGIFMTU, (char *)&ifi))
id->mtu = ifi.ifr_mtu;
}
+net_ifc_data_t *new_ifc_data(JNIEnv *_E, const char *name,
+ net_ifc_addr_t **ca)
+{
+ net_ifc_data_t *id;
+ cache_entry_t *ie;
+ if (!(id = (net_ifc_data_t *)sight_calloc(_E,
+ sizeof(net_ifc_data_t),
+ THROW_FMARK))) {
+ return NULL;
+ }
+ if (!(id->addr = cache_new(16))) {
+ throwAprMemoryException(_E, THROW_FMARK,
+ apr_get_os_error());
+ free(id);
+ return NULL;
+ }
+ ie = cache_add(id->addr, name);
+ if (!(*ca = (net_ifc_addr_t *)sight_calloc(_E,
+ sizeof(net_ifc_addr_t),
+ THROW_FMARK))) {
+ cache_free(id->addr, NULL);
+ return NULL;
+ }
+ ie->data = *ca;
+ return id;
+}
+
+net_ifc_addr_t *get_ifc_addr(JNIEnv *_E, const char *name,
+ net_ifc_data_t *id)
+{
+ cache_entry_t *ie;
+ net_ifc_addr_t *ca;
+
+ ie = cache_add(id->addr, name);
+ if (ie->data)
+ return ie->data;
+ if (!(ca = (net_ifc_addr_t *)sight_calloc(_E,
+ sizeof(net_ifc_addr_t),
+ THROW_FMARK))) {
+ return NULL;
+ }
+ ie->data = ca;
+ return ca;
+}
+
SIGHT_EXPORT_DECLARE(jlong, NetworkAdapter, enum0)(SIGHT_STDARGS,
jlong pool)
{
@@ -284,26 +332,41 @@
ifr = ifc.ifc_req;
for (i = 0; i < ifc.ifc_len; i += sizeof(struct ifreq), ifr++) {
cache_entry_t *ce;
- char las[128] = "";
+ char *p, las[128] = "";
+ char pname[IF_NAMESIZE];
struct sockaddr_in *sa;
sa = (struct sockaddr_in *)&ifr->ifr_addr;
inet_ntop(AF_INET, &sa->sin_addr, las, 64);
- ce = cache_add(e->ifc, ifr->ifr_name);
+ strcpy(pname, ifr->ifr_name);
+ if ((p = strchr(pname, ':'))) {
+ /* This is an virtual adapter.
+ * Remove everything after colon
+ */
+ *p = '\0';
+ }
+ ce = cache_add(e->ifc, pname);
if (!(id = (net_ifc_data_t *)ce->data)) {
- if (!(id = (net_ifc_data_t *)sight_calloc(_E,
- sizeof(net_ifc_data_t),
- THROW_FMARK))) {
+ net_ifc_addr_t *ca;
+
+ if (!(id = new_ifc_data(_E, ifr->ifr_name, &ca))) {
free(ifc.ifc_buf);
goto cleanup;
}
- do_ifrec(id, e->sd, ifr->ifr_name);
- strcpy(id->ip4a, las);
+ ce->data = id;
id->type = AF_INET;
- ce->data = id;
+ strcpy(ca->ip4a, las);
+ do_ifrec(id, ca, e->sd, ifr->ifr_name);
}
else {
- strcpy(id->ip4a, las);
+ net_ifc_addr_t *ca;
+
+ if (!(ca = get_ifc_addr(_E, ifr->ifr_name, id))) {
+ free(ifc.ifc_buf);
+ goto cleanup;
+ }
+ strcpy(ca->ip4a, las);
+ do_ifrec(id, ca, e->sd, ifr->ifr_name);
}
}
@@ -319,15 +382,15 @@
*pname = '\0';
ce = cache_add(e->ifc, i4a->arr.ca[i]);
if (!(id = (net_ifc_data_t *)ce->data)) {
- if (!(id = (net_ifc_data_t *)sight_calloc(_E,
- sizeof(net_ifc_data_t),
- THROW_FMARK))) {
+ net_ifc_addr_t *ca;
+
+ if (!(id = new_ifc_data(_E, i4a->arr.ca[i], &ca))) {
sight_arr_free(i4a);
goto cleanup;
}
- do_ifrec(id, e->sd, i4a->arr.ca[i]);
- id->type = AF_INET;
- ce->data = id;
+ ce->data = id;
+ id->type = AF_INET;
+ do_ifrec(id, ca, e->sd, i4a->arr.ca[i]);
}
}
sight_arr_free(i4a);
@@ -355,13 +418,15 @@
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))) {
+ net_ifc_addr_t *ca;
+
+ if (!(id = new_ifc_data(_E, ifi.ifr_name, &ca))) {
sight_arr_free(i6a);
goto cleanup;
}
- strcpy(id->ip6a, las);
+ ce->data = id;
+ strcpy(ca->ip6a, las);
+
if (!ioctl(e->sd, SIOCGIFHWADDR, (char *)&ifi)) {
make_mac(ifi.ifr_hwaddr.sa_data, las);
strcpy(id->maca, las);
@@ -371,10 +436,15 @@
id->type = AF_INET6;
id->index = ifidx;
id->flags = IFF_UP;
- ce->data = id;
}
else {
- strcpy(id->ip6a, las);
+ net_ifc_addr_t *ca;
+
+ if (!(ca = get_ifc_addr(_E, ifr->ifr_name, id))) {
+ sight_arr_free(i6a);
+ goto cleanup;
+ }
+ strcpy(ca->ip6a, las);
}
}
sight_arr_free(i6a);
@@ -407,9 +477,11 @@
{
net_adapter_enum_t *e = J2P(handle, net_adapter_enum_t *);
net_ifc_data_t *id;
+ net_ifc_addr_t *ca;
jobject addr;
jobjectArray aarr;
- jint len, idx;
+ jint len, idx = 0;
+ int i;
UNREFERENCED_O;
if (!e || e->idx > e->ifc->siz)
@@ -451,35 +523,41 @@
}
/* Set IP addresses */
len = 0;
- if (id->ip4a[0])
- len++;
- if (id->ip6a[0])
- len++;
+ for (i = 0; i < id->addr->siz; i++) {
+ ca = (net_ifc_addr_t *)id->addr->list[i]->data;
+ if (ca->ip4a[0])
+ len++;
+ if (ca->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);
+ for (i = 0; i < id->addr->siz; i++) {
+ ca = (net_ifc_addr_t *)id->addr->list[i]->data;
+
+ if (ca->ip4a[0]) {
+ addr = sight_new_netaddr_class(_E, _O);
+ if (!addr || (*_E)->ExceptionCheck(_E))
+ return;
+ sight_netaddr_set_addr(_E, addr, ca->ip4a);
+ sight_netaddr_set_family(_E, addr, AF_INET);
+ if (ca->mask[0])
+ sight_netaddr_set_mask(_E, addr, ca->mask);
+ (*_E)->SetObjectArrayElement(_E, aarr, idx++, addr);
+ (*_E)->DeleteLocalRef(_E, addr);
+ }
+ if (ca->ip6a[0]) {
+ addr = sight_new_netaddr_class(_E, _O);
+ if (!addr || (*_E)->ExceptionCheck(_E))
+ return;
+ sight_netaddr_set_addr(_E, addr, ca->ip6a);
+ sight_netaddr_set_family(_E, addr, AF_INET6);
+ (*_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);
}