Author: mladen.turk(a)jboss.com
Date: 2007-09-19 04:51:27 -0400 (Wed, 19 Sep 2007)
New Revision: 1031
Modified:
trunk/sight/native/os/linux/netadapter.c
Log:
Add support for IPV4 routes/gateways
Modified: trunk/sight/native/os/linux/netadapter.c
===================================================================
--- trunk/sight/native/os/linux/netadapter.c 2007-09-14 08:57:26 UTC (rev 1030)
+++ trunk/sight/native/os/linux/netadapter.c 2007-09-19 08:51:27 UTC (rev 1031)
@@ -32,9 +32,9 @@
#include <net/if.h>
#include <net/if_arp.h>
+#include <net/route.h>
#include <sys/ioctl.h>
-
/*
* Network adapter implementation
*/
@@ -142,8 +142,10 @@
sight_unload_class(_E, &_clazzn);
}
-#define PROC_INET6_FILE "/proc/net/if_inet6"
-#define PROC_NET_DEV "/proc/net/dev"
+#define PROC_INET6_FILE "/proc/net/if_inet6"
+#define PROC_NET_DEV "/proc/net/dev"
+#define PROC_NET_ROUTE4 "/proc/net/route"
+#define PROC_NET_ROUTE6 "/proc/net/ipv6_route"
typedef struct net_ifc_addr_t {
char ip4a[64];
@@ -151,6 +153,7 @@
char mask[64];
char badr[64];
int virt;
+ int route;
} net_ifc_addr_t;
typedef struct net_ifc_data_t {
@@ -241,7 +244,7 @@
}
}
-net_ifc_data_t *new_ifc_data(JNIEnv *_E, const char *name,
+net_ifc_data_t *new_ifc_addr(JNIEnv *_E, const char *name,
net_ifc_addr_t **ca)
{
net_ifc_data_t *id;
@@ -287,6 +290,54 @@
return ca;
}
+static int get_ipv4_route(JNIEnv *_E, const char *name,
+ net_ifc_data_t *id)
+{
+ sight_arr_t *i4r;
+ net_ifc_addr_t *ca;
+ int i;
+
+ if (!id)
+ return 0; /* No rec, nothing to do */
+ if ((i4r = sight_arr_rload(PROC_NET_ROUTE4)) != NULL) {
+ for (i = 1; i < i4r->siz; i++) {
+ char iface[16], nname[64];
+ char gatea[128], neta[128], maska[128];
+ struct in_addr ipg, ipn, ipm;
+ int al, iflags, metric, refcnt, use, mss, window, irtt;
+
+ al = sscanf(i4r->arr[i],
+ "%16s %128s %128s %X %d %d %d %128s %d %d %d",
+ iface, neta, gatea, &iflags, &refcnt, &use,
&metric,
+ maska, &mss, &window, &irtt);
+ if (al < 10 || !(iflags & RTF_GATEWAY))
+ continue;
+ if (strcmp(iface, name))
+ continue;
+ sprintf(nname, "%s.r4.%d", name, i);
+ /* TODO: Deal with RTF_HOST flags */
+ if (!(ca = get_ifc_addr(_E, nname, id))) {
+ sight_arr_free(i4r);
+ return 1;
+ }
+ if (ca->route)
+ continue;
+ ca->route = 1;
+
+ if (sscanf(gatea, "%X", &ipg.s_addr) != 1)
+ continue;
+ if (sscanf(neta, "%X", &ipn.s_addr) != 1)
+ continue;
+ if (sscanf(maska, "%X", &ipm.s_addr) != 1)
+ continue;
+ inet_ntop(AF_INET, &ipg, ca->ip4a, 64);
+ inet_ntop(AF_INET, &ipm, ca->mask, 64);
+ }
+ }
+ sight_arr_free(i4r);
+ return 0;
+}
+
SIGHT_EXPORT_DECLARE(jlong, NetworkAdapter, enum0)(SIGHT_STDARGS,
jlong pool)
{
@@ -352,7 +403,7 @@
if (!(id = (net_ifc_data_t *)ce->data)) {
net_ifc_addr_t *ca;
- if (!(id = new_ifc_data(_E, ifr->ifr_name, &ca))) {
+ if (!(id = new_ifc_addr(_E, ifr->ifr_name, &ca))) {
free(ifc.ifc_buf);
goto cleanup;
}
@@ -373,7 +424,7 @@
strcpy(ca->ip4a, las);
do_ifrec(id, ca, e->sd, ifr->ifr_name);
}
-
+ get_ipv4_route(_E, ifr->ifr_name, id);
}
free(ifc.ifc_buf);
@@ -389,13 +440,14 @@
if (!(id = (net_ifc_data_t *)ce->data)) {
net_ifc_addr_t *ca;
- if (!(id = new_ifc_data(_E, i4a->arr[i], &ca))) {
+ if (!(id = new_ifc_addr(_E, i4a->arr[i], &ca))) {
sight_arr_free(i4a);
goto cleanup;
}
ce->data = id;
id->type = AF_INET;
do_ifrec(id, ca, e->sd, i4a->arr[i]);
+ get_ipv4_route(_E, i4a->arr[i], id);
}
}
sight_arr_free(i4a);
@@ -425,7 +477,7 @@
if (!(id = (net_ifc_data_t *)ce->data)) {
net_ifc_addr_t *ca;
- if (!(id = new_ifc_data(_E, ifi.ifr_name, &ca))) {
+ if (!(id = new_ifc_addr(_E, ifi.ifr_name, &ca))) {
sight_arr_free(i6a);
goto cleanup;
}
@@ -472,8 +524,10 @@
UNREFERENCED_O;
if (!e)
return 0;
- else
+ else {
+ e->idx = 0;
return e->ifc->siz;
+ }
}
SIGHT_EXPORT_DECLARE(void, NetworkAdapter, enum2)(SIGHT_STDARGS,
@@ -485,7 +539,7 @@
net_ifc_addr_t *ca;
jobject addr;
jobjectArray aarr;
- jint len, idx = 0;
+ jint len, idx;
int i;
UNREFERENCED_O;
@@ -528,8 +582,11 @@
}
/* Set IP addresses */
len = 0;
+ idx = 0;
for (i = 0; i < id->addr->siz; i++) {
ca = (net_ifc_addr_t *)id->addr->list[i]->data;
+ if (ca->route)
+ continue;
if (ca->ip4a[0])
len++;
if (ca->ip6a[0])
@@ -542,6 +599,8 @@
for (i = 0; i < id->addr->siz; i++) {
ca = (net_ifc_addr_t *)id->addr->list[i]->data;
+ if (ca->route)
+ continue;
if (ca->ip4a[0]) {
addr = sight_new_netaddr_class(_E, _O);
if (!addr || (*_E)->ExceptionCheck(_E))
@@ -566,6 +625,47 @@
SET_IFIELD_O(0006, thiz, aarr);
(*_E)->DeleteLocalRef(_E, aarr);
}
+ /* Set Gateway addresses */
+ len = 0;
+ idx = 0;
+ for (i = 0; i < id->addr->siz; i++) {
+ ca = (net_ifc_addr_t *)id->addr->list[i]->data;
+ if (!ca->route)
+ continue;
+ if (ca->ip4a[0])
+ len++;
+ else if (ca->ip6a[0])
+ len++;
+ }
+ if (len) {
+ aarr = sight_new_netaddr_array(_E, _O, len);
+ if (!aarr || (*_E)->ExceptionCheck(_E))
+ goto cleanup;
+ for (i = 0; i < id->addr->siz; i++) {
+ ca = (net_ifc_addr_t *)id->addr->list[i]->data;
+
+ if (!ca->route)
+ continue;
+ addr = sight_new_netaddr_class(_E, _O);
+ if (!addr || (*_E)->ExceptionCheck(_E))
+ return;
+ if (ca->ip4a[0]) {
+ 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);
+ }
+ else if (ca->ip6a[0]) {
+ 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);
+ }
+ SET_IFIELD_O(0008, thiz, aarr);
+ (*_E)->DeleteLocalRef(_E, aarr);
+ }
+
SET_IFIELD_I(0009, thiz, id->mtu);
cleanup: