* Ben Woods (woodsb02@gmail.com)
*/
-#include <config.h>
+#include "config.h"
-#include <mono/metadata/object.h>
-#include <mono/metadata/mono-route.h>
+#if HOST_DARWIN || HOST_BSD
-#if defined(HOST_DARWIN) || defined(HOST_BSD)
+#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <stdlib.h>
#include <string.h>
-extern MonoBoolean ves_icall_System_Net_NetworkInformation_MacOsIPInterfaceProperties_ParseRouteInfo_internal(MonoString *iface, MonoArray **gw_addr_list)
+#if HOST_IOS || HOST_WATCHOS || HOST_TVOS
+// The iOS SDK does not provide the net/route.h header but using the Darwin version works fine.
+#include "../../support/ios/net/route.h"
+#else
+#include <net/route.h>
+#endif
+
+static in_addr_t
+gateway_from_rtm (struct rt_msghdr *rtm);
+
+#include "object.h"
+#include "icall-decl.h"
+
+MonoBoolean
+ves_icall_System_Net_NetworkInformation_MacOsIPInterfaceProperties_ParseRouteInfo_internal (MonoStringHandle iface_handle, MonoArrayHandleOut gw_addr_list_handle, MonoError *error)
{
- ERROR_DECL (error);
+ MonoString *iface = MONO_HANDLE_RAW (iface_handle);
+ MONO_HANDLE_ASSIGN_RAW (gw_addr_list_handle, NULL);
+
size_t needed;
in_addr_t in;
- int mib[6];
- int num_gws=0, gwnum=0;
+ int mib [6];
+ int num_gws = 0, gwnum = 0;
unsigned int ifindex = 0;
- char *buf, *next, *lim, *ifacename;
+ char *buf = NULL;
+ char *next, *lim;
+ char *ifacename = NULL;
struct rt_msghdr *rtm;
-
+ MonoArray *gw_addr_list = NULL;
+ MonoStringHandle addr_string_handle = NULL_HANDLE_INIT; // FIXME probably overkill
MonoDomain *domain = mono_domain_get ();
+ MonoBoolean result = FALSE;
ifacename = mono_string_to_utf8_checked_internal (iface, error);
- if (mono_error_set_pending_exception (error))
- return FALSE;
+ goto_if_nok (error, fail);
- if ((ifindex = if_nametoindex(ifacename)) == 0)
- return FALSE;
- g_free(ifacename);
+ if ((ifindex = if_nametoindex (ifacename)) == 0)
+ goto fail;
// MIB array defining data to read from sysctl
- mib[0] = CTL_NET; // Networking
- mib[1] = PF_ROUTE; // Routing messages
- mib[2] = 0; // Protocol number (always zero)
- mib[3] = AF_INET; // Address family (IPv4)
- mib[4] = NET_RT_DUMP; // Dump routing table
- mib[5] = 0; //
+ mib [0] = CTL_NET; // Networking
+ mib [1] = PF_ROUTE; // Routing messages
+ mib [2] = 0; // Protocol number (always zero)
+ mib [3] = AF_INET; // Address family (IPv4)
+ mib [4] = NET_RT_DUMP; // Dump routing table
+ mib [5] = 0; //
// First sysctl call with oldp set to NULL to determine size of available data
if (sysctl(mib, G_N_ELEMENTS(mib), NULL, &needed, NULL, 0) < 0)
- return FALSE;
+ goto fail;
// Allocate suffcient memory for available data based on the previous sysctl call
if ((buf = g_malloc (needed)) == NULL)
- return FALSE;
+ goto fail;
// Second sysctl call to retrieve data into appropriately sized buffer
- if (sysctl(mib, G_N_ELEMENTS(mib), buf, &needed, NULL, 0) < 0) {
- g_free (buf);
- return FALSE;
- }
+ if (sysctl (mib, G_N_ELEMENTS (mib), buf, &needed, NULL, 0) < 0)
+ goto fail;
lim = buf + needed;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
- if (rtm->rtm_version != RTM_VERSION)
- continue;
- if (rtm->rtm_index != ifindex)
- continue;
- if((in = gateway_from_rtm(rtm)) == 0)
+ if (rtm->rtm_version != RTM_VERSION
+ || rtm->rtm_index != ifindex
+ || (in = gateway_from_rtm (rtm)) == 0)
continue;
num_gws++;
}
- *gw_addr_list = mono_array_new_checked (domain, mono_get_string_class (), num_gws, error);
+ gw_addr_list = mono_array_new_checked (domain, mono_get_string_class (), num_gws, error);
goto_if_nok (error, leave);
+ MONO_HANDLE_ASSIGN_RAW (gw_addr_list_handle, gw_addr_list);
+
+ addr_string_handle = MONO_HANDLE_NEW (MonoString, NULL); // FIXME probably overkill
+
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
- if (rtm->rtm_version != RTM_VERSION)
- continue;
- if (rtm->rtm_index != ifindex)
- continue;
- if ((in = gateway_from_rtm(rtm)) == 0)
+ if (rtm->rtm_version != RTM_VERSION
+ || rtm->rtm_index != ifindex
+ || (in = gateway_from_rtm (rtm)) == 0)
continue;
MonoString *addr_string;
int len;
ptr = (char *) ∈
- len = snprintf(addr, sizeof(addr), "%u.%u.%u.%u",
+ len = snprintf(addr, sizeof (addr), "%u.%u.%u.%u",
(unsigned char) ptr [0],
(unsigned char) ptr [1],
(unsigned char) ptr [2],
(unsigned char) ptr [3]);
- if ((len >= sizeof(addr)) || (len < 0))
+ if (len >= sizeof (addr) || len < 0)
// snprintf output truncated
continue;
addr_string = mono_string_new_checked (domain, addr, error);
goto_if_nok (error, leave);
- mono_array_setref_internal (*gw_addr_list, gwnum, addr_string);
+ MONO_HANDLE_ASSIGN_RAW (addr_string_handle, addr_string); // FIXME probably overkill
+ mono_array_setref_internal (gw_addr_list, gwnum, addr_string);
gwnum++;
}
leave:
+ result = is_ok (error);
+fail:
+ g_free (ifacename);
g_free (buf);
- return is_ok (error);
+ return result;
}
-in_addr_t gateway_from_rtm(struct rt_msghdr *rtm)
+static in_addr_t
+gateway_from_rtm(struct rt_msghdr *rtm)
{
struct sockaddr *gw;
unsigned int l;
return 0;
}
-#else
-
-MonoBoolean
-ves_icall_System_Net_NetworkInformation_MacOsIPInterfaceProperties_ParseRouteInfo_internal(MonoString *iface, MonoArray **gw_addr_list)
-{
- g_assert_not_reached ();
- return FALSE;
-}
+#endif
-#endif /* #if defined(HOST_DARWIN) || defined(HOST_BSD) */
+extern const char mono_route_empty_file_no_warning;
+extern const char mono_route_empty_file_no_warning = 0;