[runtime] Remove unused MONO_ARCH_SAVE_REGS declarations.
[mono.git] / mono / metadata / socket-io.c
index 0b75405bd0acd42aca213b10a011e745d1ecc636..eef60ab9139906aae2da5759b2a6b12fd21a0604 100644 (file)
 #include <ws2tcpip.h>
 #else
 #include <sys/socket.h>
+#ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
+#endif
 #include <netinet/in.h>
 #include <netinet/tcp.h>
+#ifdef HAVE_NETDB_H
 #include <netdb.h>
+#endif
 #include <arpa/inet.h>
 #endif
 #ifdef HAVE_UNISTD_H
@@ -53,6 +57,7 @@
 #include <mono/metadata/domain-internals.h>
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/mono-memory-model.h>
+#include <mono/utils/networking.h>
 
 #include <time.h>
 #ifdef HAVE_SYS_TIME_H
 
 #include "mono/io-layer/socket-wrappers.h"
 
-#if defined(HOST_WIN32)
-/* This is a kludge to make this file build under cygwin:
- * w32api/ws2tcpip.h has definitions for some AF_INET6 values and
- * prototypes for some but not all required functions (notably
- * inet_ntop() is missing), but the libws2_32 library is missing the
- * actual implementations of these functions.
- */
-#undef AF_INET6
-#endif
-
 #define LOGDEBUG(...)  
 /* define LOGDEBUG(...) g_message(__VA_ARGS__)  */
 
-/* 
- * Some older versions of libc provide IPV6 support without defining the AI_ADDRCONFIG
- * flag for getaddrinfo.
- */
-#ifndef AI_ADDRCONFIG
-#define AI_ADDRCONFIG 0
-#endif
-
-#if defined(__APPLE__) || defined(__FreeBSD__)
-/*
- * We remove this until we have a Darwin implementation
- * that can walk the result of struct ifconf.  The current
- * implementation only works for Linux
- */
-#undef HAVE_SIOCGIFCONF
-#endif
-
 static gint32 convert_family(MonoAddressFamily mono_family)
 {
        gint32 family=-1;
@@ -177,10 +155,9 @@ static gint32 convert_family(MonoAddressFamily mono_family)
                break;
                
        case AddressFamily_InterNetworkV6:
-#ifdef AF_INET6
                family=AF_INET6;
-#endif
                break;
+
        case AddressFamily_Irda:
 #ifdef AF_IRDA 
                family=AF_IRDA;
@@ -232,11 +209,9 @@ static MonoAddressFamily convert_to_mono_family(guint16 af_family)
                family=AddressFamily_AppleTalk;
                break;
                
-#ifdef AF_INET6
        case AF_INET6:
                family=AddressFamily_InterNetworkV6;
                break;
-#endif
                
 #ifdef AF_IRDA 
        case AF_IRDA:
@@ -464,24 +439,7 @@ static gint32 convert_sockopt_level_and_name(MonoSocketOptionLevel mono_level,
                break;
                
        case SocketOptionLevel_IP:
-#ifdef HAVE_SOL_IP
-               *system_level = SOL_IP;
-#else
-               if (1) {
-                       static int cached = 0;
-                       static int proto;
-                       
-                       if (!cached) {
-                               struct protoent *pent;
-                               
-                               pent = getprotobyname ("IP");
-                               proto = pent ? pent->p_proto : 0 /* 0 a good default value?? */;
-                               cached = 1;
-                       }
-                       
-                       *system_level = proto;
-               }
-#endif /* HAVE_SOL_IP */
+               *system_level = mono_networking_get_ip_protocol ();
                
                switch(mono_name) {
                case SocketOptionName_IPOptions:
@@ -548,26 +506,8 @@ static gint32 convert_sockopt_level_and_name(MonoSocketOptionLevel mono_level,
                }
                break;
 
-#ifdef AF_INET6
        case SocketOptionLevel_IPv6:
-#ifdef HAVE_SOL_IPV6
-               *system_level = SOL_IPV6;
-#else
-               if (1) {
-                       static int cached = 0;
-                       static int proto;
-
-                       if (!cached) {
-                               struct protoent *pent;
-
-                               pent = getprotobyname ("IPV6");
-                               proto = pent ? pent->p_proto : 41 /* 41 a good default value?? */;
-                               cached = 1;
-                       }
-
-                       *system_level = proto;
-               }
-#endif /* HAVE_SOL_IPV6 */
+               *system_level = mono_networking_get_ipv6_protocol ();
 
                switch(mono_name) {
                case SocketOptionName_IpTimeToLive:
@@ -611,27 +551,9 @@ static gint32 convert_sockopt_level_and_name(MonoSocketOptionLevel mono_level,
                }
 
                break;  /* SocketOptionLevel_IPv6 */
-#endif
                
        case SocketOptionLevel_Tcp:
-#ifdef HAVE_SOL_TCP
-               *system_level = SOL_TCP;
-#else
-               if (1) {
-                       static int cached = 0;
-                       static int proto;
-                       
-                       if (!cached) {
-                               struct protoent *pent;
-                               
-                               pent = getprotobyname ("TCP");
-                               proto = pent ? pent->p_proto : 6 /* is 6 a good default value?? */;
-                               cached = 1;
-                       }
-                       
-                       *system_level = proto;
-               }
-#endif /* HAVE_SOL_TCP */
+       *system_level = mono_networking_get_tcp_protocol ();
                
                switch(mono_name) {
                case SocketOptionName_NoDelay:
@@ -697,7 +619,6 @@ static MonoImage *get_socket_assembly (void)
        return domain->socket_assembly;
 }
 
-#ifdef AF_INET6
 static gint32 get_family_hint(void)
 {
        MonoDomain *domain = mono_domain_get ();
@@ -736,7 +657,6 @@ static gint32 get_family_hint(void)
                return PF_UNSPEC;
        }
 }
-#endif
 
 gpointer ves_icall_System_Net_Sockets_Socket_Socket_internal(MonoObject *this, gint32 family, gint32 type, gint32 proto, gint32 *error)
 {
@@ -745,8 +665,6 @@ gpointer ves_icall_System_Net_Sockets_Socket_Socket_internal(MonoObject *this, g
        gint32 sock_proto;
        gint32 sock_type;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        sock_family=convert_family(family);
@@ -775,16 +693,6 @@ gpointer ves_icall_System_Net_Sockets_Socket_Socket_internal(MonoObject *this, g
                return(NULL);
        }
 
-       if (sock_family == AF_INET && sock_type == SOCK_DGRAM) {
-               return (GUINT_TO_POINTER (sock));
-       }
-
-#ifdef AF_INET6
-       if (sock_family == AF_INET6 && sock_type == SOCK_DGRAM) {
-               return (GUINT_TO_POINTER (sock));
-       }
-#endif
-
        return(GUINT_TO_POINTER (sock));
 }
 
@@ -794,8 +702,6 @@ gpointer ves_icall_System_Net_Sockets_Socket_Socket_internal(MonoObject *this, g
 void ves_icall_System_Net_Sockets_Socket_Close_internal(SOCKET sock,
                                                        gint32 *error)
 {
-       MONO_ARCH_SAVE_REGS;
-
        LOGDEBUG (g_message ("%s: closing 0x%x", __func__, sock));
 
        *error = 0;
@@ -808,8 +714,6 @@ void ves_icall_System_Net_Sockets_Socket_Close_internal(SOCKET sock,
 
 gint32 ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal(void)
 {
-       MONO_ARCH_SAVE_REGS;
-
        LOGDEBUG (g_message("%s: returning %d", __func__, WSAGetLastError()));
 
        return(WSAGetLastError());
@@ -821,8 +725,6 @@ gint32 ves_icall_System_Net_Sockets_Socket_Available_internal(SOCKET sock,
        int ret;
        int amount;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
 
        /* FIXME: this might require amount to be unsigned long. */
@@ -841,8 +743,6 @@ void ves_icall_System_Net_Sockets_Socket_Blocking_internal(SOCKET sock,
 {
        int ret;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
 
        /*
@@ -863,8 +763,6 @@ gpointer ves_icall_System_Net_Sockets_Socket_Accept_internal(SOCKET sock,
 {
        SOCKET newsock;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
 #ifdef HOST_WIN32
        {
@@ -890,8 +788,6 @@ void ves_icall_System_Net_Sockets_Socket_Listen_internal(SOCKET sock,
 {
        int ret;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        ret = _wapi_listen (sock, backlog);
@@ -900,7 +796,6 @@ void ves_icall_System_Net_Sockets_Socket_Listen_internal(SOCKET sock,
        }
 }
 
-#ifdef AF_INET6
 // Check whether it's ::ffff::0:0.
 static gboolean
 is_ipv4_mapped_any (const struct in6_addr *addr)
@@ -919,7 +814,6 @@ is_ipv4_mapped_any (const struct in6_addr *addr)
        }
        return TRUE;
 }
-#endif
 
 static MonoObject *create_object_from_sockaddr(struct sockaddr *saddr,
                                               int sa_size, gint32 *error)
@@ -982,7 +876,6 @@ static MonoObject *create_object_from_sockaddr(struct sockaddr *saddr,
                mono_field_set_value (sockaddr_obj, domain->sockaddr_data_field, data);
 
                return(sockaddr_obj);
-#ifdef AF_INET6
        } else if (saddr->sa_family == AF_INET6) {
                struct sockaddr_in6 *sa_in=(struct sockaddr_in6 *)saddr;
                int i;
@@ -1019,7 +912,6 @@ static MonoObject *create_object_from_sockaddr(struct sockaddr *saddr,
                mono_field_set_value (sockaddr_obj, domain->sockaddr_data_field, data);
 
                return(sockaddr_obj);
-#endif
 #ifdef HAVE_SYS_UN_H
        } else if (saddr->sa_family == AF_UNIX) {
                int i;
@@ -1046,10 +938,8 @@ get_sockaddr_size (int family)
        size = 0;
        if (family == AF_INET) {
                size = sizeof (struct sockaddr_in);
-#ifdef AF_INET6
        } else if (family == AF_INET6) {
                size = sizeof (struct sockaddr_in6);
-#endif
 #ifdef HAVE_SYS_UN_H
        } else if (family == AF_UNIX) {
                size = sizeof (struct sockaddr_un);
@@ -1065,8 +955,6 @@ extern MonoObject *ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal(SO
        int ret;
        MonoObject *result;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        salen = get_sockaddr_size (convert_family (af));
@@ -1099,8 +987,6 @@ extern MonoObject *ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal(S
        int ret;
        MonoObject *result;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        salen = get_sockaddr_size (convert_family (af));
@@ -1177,8 +1063,6 @@ static struct sockaddr *create_sockaddr_from_object(MonoObject *saddr_obj,
 
                *sa_size = sizeof(struct sockaddr_in);
                return((struct sockaddr *)sa);
-
-#ifdef AF_INET6
        } else if (family == AF_INET6) {
                struct sockaddr_in6 *sa;
                int i;
@@ -1207,7 +1091,6 @@ static struct sockaddr *create_sockaddr_from_object(MonoObject *saddr_obj,
 
                *sa_size = sizeof(struct sockaddr_in6);
                return((struct sockaddr *)sa);
-#endif
 #ifdef HAVE_SYS_UN_H
        } else if (family == AF_UNIX) {
                struct sockaddr_un *sock_un;
@@ -1244,8 +1127,6 @@ extern void ves_icall_System_Net_Sockets_Socket_Bind_internal(SOCKET sock, MonoO
        socklen_t sa_size;
        int ret;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        sa=create_sockaddr_from_object(sockaddr, &sa_size, error);
@@ -1278,9 +1159,6 @@ ves_icall_System_Net_Sockets_Socket_Poll_internal (SOCKET sock, gint mode,
        int ret;
        time_t start;
        
-
-       MONO_ARCH_SAVE_REGS;
-       
        pfds = g_new0 (mono_pollfd, 1);
        pfds[0].fd = GPOINTER_TO_INT (sock);
        pfds[0].events = (mode == SelectModeRead) ? MONO_POLLIN :
@@ -1350,8 +1228,6 @@ extern void ves_icall_System_Net_Sockets_Socket_Connect_internal(SOCKET sock, Mo
        socklen_t sa_size;
        int ret;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        sa=create_sockaddr_from_object(sockaddr, &sa_size, error);
@@ -1393,8 +1269,6 @@ extern void ves_icall_System_Net_Sockets_Socket_Disconnect_internal(SOCKET sock,
        LPFN_TRANSMITFILE _wapi_transmitfile = NULL;
        gboolean bret;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        LOGDEBUG (g_message("%s: disconnecting from socket %p (reuse %d)", __func__, sock, reuse));
@@ -1453,8 +1327,6 @@ gint32 ves_icall_System_Net_Sockets_Socket_Receive_internal(SOCKET sock, MonoArr
        gint32 alen;
        int recvflags=0;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        alen = mono_array_length (buffer);
@@ -1496,8 +1368,6 @@ gint32 ves_icall_System_Net_Sockets_Socket_Receive_array_internal(SOCKET sock, M
        WSABUF *wsabufs;
        DWORD recvflags = 0;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        wsabufs = mono_array_addr (buffers, WSABUF, 0);
@@ -1527,8 +1397,6 @@ gint32 ves_icall_System_Net_Sockets_Socket_RecvFrom_internal(SOCKET sock, MonoAr
        struct sockaddr *sa;
        socklen_t sa_size;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        alen = mono_array_length (buffer);
@@ -1577,8 +1445,6 @@ gint32 ves_icall_System_Net_Sockets_Socket_Send_internal(SOCKET sock, MonoArray
        gint32 alen;
        int sendflags=0;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        alen = mono_array_length (buffer);
@@ -1614,8 +1480,6 @@ gint32 ves_icall_System_Net_Sockets_Socket_Send_array_internal(SOCKET sock, Mono
        WSABUF *wsabufs;
        DWORD sendflags = 0;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        wsabufs = mono_array_addr (buffers, WSABUF, 0);
@@ -1645,8 +1509,6 @@ gint32 ves_icall_System_Net_Sockets_Socket_SendTo_internal(SOCKET sock, MonoArra
        struct sockaddr *sa;
        socklen_t sa_size;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        alen = mono_array_length (buffer);
@@ -1707,8 +1569,6 @@ void ves_icall_System_Net_Sockets_Socket_Select_internal(MonoArray **sockets, gi
        time_t start;
        uintptr_t socks_size;
        
-       MONO_ARCH_SAVE_REGS;
-
        /* *sockets -> READ, null, WRITE, null, ERROR, null */
        count = mono_array_length (*sockets);
        nfds = count - 3; /* NULL separators */
@@ -1846,8 +1706,6 @@ void ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal(SOCKET soc
        MonoClass *obj_class;
        MonoClassField *field;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
 #if !defined(SO_EXCLUSIVEADDRUSE) && defined(SO_REUSEADDR)
@@ -1985,8 +1843,6 @@ void ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal(SOCKET soc
        guchar *buf;
        socklen_t valsize;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        ret=convert_sockopt_level_and_name(level, name, &system_level,
@@ -2024,7 +1880,6 @@ static struct in_addr ipaddress_to_struct_in_addr(MonoObject *ipaddr)
        return(inaddr);
 }
 
-#ifdef AF_INET6
 static struct in6_addr ipaddress_to_struct_in6_addr(MonoObject *ipaddr)
 {
        struct in6_addr in6addr;
@@ -2048,7 +1903,6 @@ static struct in6_addr ipaddress_to_struct_in6_addr(MonoObject *ipaddr)
 #endif
        return(in6addr);
 }
-#endif /* AF_INET6 */
 #endif
 
 #if defined(__APPLE__) || defined(__FreeBSD__)
@@ -2097,34 +1951,13 @@ void ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal(SOCKET sock, g
        int system_level = 0;
        int system_name = 0;
        int ret;
-#ifdef AF_INET6
        int sol_ip;
        int sol_ipv6;
 
        *error = 0;
-       
-#ifdef HAVE_SOL_IPV6
-       sol_ipv6 = SOL_IPV6;
-#else
-       {
-               struct protoent *pent;
-               pent = getprotobyname ("ipv6");
-               sol_ipv6 = (pent != NULL) ? pent->p_proto : 41;
-       }
-#endif
 
-#ifdef HAVE_SOL_IP
-       sol_ip = SOL_IP;
-#else
-       {
-               struct protoent *pent;
-               pent = getprotobyname ("ip");
-               sol_ip = (pent != NULL) ? pent->p_proto : 0;
-       }
-#endif
-#endif /* AF_INET6 */
-
-       MONO_ARCH_SAVE_REGS;
+       sol_ipv6 = mono_networking_get_ipv6_protocol ();
+       sol_ip = mono_networking_get_ip_protocol ();
 
        ret=convert_sockopt_level_and_name(level, name, &system_level,
                                           &system_name);
@@ -2170,7 +2003,6 @@ void ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal(SOCKET sock, g
                {
                        MonoObject *address = NULL;
 
-#ifdef AF_INET6
                        if(system_level == sol_ipv6) {
                                struct ipv6_mreq mreq6;
 
@@ -2205,9 +2037,7 @@ void ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal(SOCKET sock, g
                                ret = _wapi_setsockopt (sock, system_level,
                                                        system_name, &mreq6,
                                                        sizeof (mreq6));
-                       } else if(system_level == sol_ip)
-#endif /* AF_INET6 */
-                       {
+                       } else if(system_level == sol_ip) {
 #ifdef HAVE_STRUCT_IP_MREQN
                                struct ip_mreqn mreq = {{0}};
 #else
@@ -2325,8 +2155,6 @@ void ves_icall_System_Net_Sockets_Socket_Shutdown_internal(SOCKET sock,
 {
        int ret;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        /* Currently, the values for how (recv=0, send=1, both=2) match
@@ -2348,8 +2176,6 @@ ves_icall_System_Net_Sockets_Socket_WSAIoctl (SOCKET sock, gint32 code,
        gint i_len, o_len;
        gint ret;
 
-       MONO_ARCH_SAVE_REGS;
-
        *error = 0;
        
        if ((guint32)code == FIONBIO) {
@@ -2382,501 +2208,14 @@ ves_icall_System_Net_Sockets_Socket_WSAIoctl (SOCKET sock, gint32 code,
        return (gint) output_bytes;
 }
 
-#ifdef HAVE_SIOCGIFCONF
-static gboolean
-is_loopback (int family, void *ad)
-{
-       char *ptr = (char *) ad;
-
-       if (family == AF_INET) {
-               return (ptr [0] == 127);
-       }
-#ifdef AF_INET6
-       else {
-               return (IN6_IS_ADDR_LOOPBACK ((struct in6_addr *) ptr));
-       }
-#endif
-       return FALSE;
-}
-
-static void *
-get_local_ips (int family, int *nips)
-{
-       int addr_size, offset, fd, i, count;
-       int max_ifaces = 50; /* 50 interfaces should be enough... */
-       struct ifconf ifc;
-       struct ifreq *ifr;
-       struct ifreq iflags;
-       char *result, *tmp_ptr;
-       gboolean ignore_loopback = FALSE;
-
-       *nips = 0;
-       if (family == AF_INET) {
-               addr_size = sizeof (struct in_addr);
-               offset = G_STRUCT_OFFSET (struct sockaddr_in, sin_addr);
-#ifdef AF_INET6
-       } else if (family == AF_INET6) {
-               addr_size = sizeof (struct in6_addr);
-               offset = G_STRUCT_OFFSET (struct sockaddr_in6, sin6_addr);
-#endif
-       } else {
-               return NULL;
-       }
-
-       fd = socket (family, SOCK_STREAM, 0);
-
-       ifc.ifc_len = max_ifaces * sizeof (struct ifreq);
-       ifc.ifc_buf = g_malloc (ifc.ifc_len);
-       if (ioctl (fd, SIOCGIFCONF, &ifc) < 0) {
-               close (fd);
-               g_free (ifc.ifc_buf);
-               return NULL;
-       }
-
-       count = ifc.ifc_len / sizeof (struct ifreq);
-       *nips = count;
-       if (count == 0) {
-               g_free (ifc.ifc_buf);
-               close (fd);
-               return NULL;
-       }
-
-       for (i = 0, ifr = ifc.ifc_req; i < *nips; i++, ifr++) {
-               strcpy (iflags.ifr_name, ifr->ifr_name);
-               if (ioctl (fd, SIOCGIFFLAGS, &iflags) < 0) {
-                       continue;
-               }
-
-               if ((iflags.ifr_flags & IFF_UP) == 0) {
-                       ifr->ifr_name [0] = '\0';
-                       continue;
-               }
-
-               if ((iflags.ifr_flags & IFF_LOOPBACK) == 0) {
-                       ignore_loopback = TRUE;
-               }
-       }
-
-       close (fd);
-       result = g_malloc (addr_size * count);
-       tmp_ptr = result;
-       for (i = 0, ifr = ifc.ifc_req; i < count; i++, ifr++) {
-               if (ifr->ifr_name [0] == '\0') {
-                       (*nips)--;
-                       continue;
-               }
-
-               if (ignore_loopback && is_loopback (family, ((char *) &ifr->ifr_addr) + offset)) {
-                       (*nips)--;
-                       continue;
-               }
-
-               memcpy (tmp_ptr, ((char *) &ifr->ifr_addr) + offset, addr_size);
-               tmp_ptr += addr_size;
-       }
-
-       g_free (ifc.ifc_buf);
-       return result;
-}
-#elif defined(HAVE_GETIFADDRS)
-static gboolean
-is_loopback (int family, void *ad)
-{
-       char *ptr = (char *) ad;
-
-       if (family == AF_INET) {
-               return (ptr [0] == 127);
-       }
-#ifdef AF_INET6
-       else {
-               return (IN6_IS_ADDR_LOOPBACK ((struct in6_addr *) ptr));
-       }
-#endif
-       return FALSE;
-}
-
-static void *
-get_local_ips (int family, int *nips)
-{
-       struct ifaddrs *ifap = NULL, *ptr;
-       int addr_size, offset, count, i;
-       char *result, *tmp_ptr;
-
-       *nips = 0;
-       if (family == AF_INET) {
-               addr_size = sizeof (struct in_addr);
-               offset = G_STRUCT_OFFSET (struct sockaddr_in, sin_addr);
-#ifdef AF_INET6
-       } else if (family == AF_INET6) {
-               addr_size = sizeof (struct in6_addr);
-               offset = G_STRUCT_OFFSET (struct sockaddr_in6, sin6_addr);
-#endif
-       } else {
-               return NULL;
-       }
-       
-       if (getifaddrs (&ifap)) {
-               return NULL;
-       }
-       
-       count = 0;
-       for (ptr = ifap; ptr; ptr = ptr->ifa_next) {
-               if (!ptr->ifa_addr)
-                       continue;
-               if (ptr->ifa_addr->sa_family != family)
-                       continue;
-               if (is_loopback (family, ((char *) ptr->ifa_addr) + offset))
-                       continue;
-               count++;
-       }
-               
-       result = g_malloc (addr_size * count);
-       tmp_ptr = result;
-       for (i = 0, ptr = ifap; ptr; ptr = ptr->ifa_next) {
-               if (!ptr->ifa_addr)
-                       continue;
-               if (ptr->ifa_addr->sa_family != family)
-                       continue;
-               if (is_loopback (family, ((char *) ptr->ifa_addr) + offset))
-                       continue;
-                       
-               memcpy (tmp_ptr, ((char *) ptr->ifa_addr) + offset, addr_size);
-               tmp_ptr += addr_size;
-       }
-       
-       freeifaddrs (ifap);
-       *nips = count;
-       return result;
-}
-#else
-static void *
-get_local_ips (int family, int *nips)
-{
-       *nips = 0;
-       return NULL;
-}
-
-#endif /* HAVE_SIOCGIFCONF */
-
-#ifndef AF_INET6
-static gboolean hostent_to_IPHostEntry(struct hostent *he, MonoString **h_name,
-                                      MonoArray **h_aliases,
-                                      MonoArray **h_addr_list,
-                                      gboolean add_local_ips)
-{
-       MonoDomain *domain = mono_domain_get ();
-       int i = 0;
-       struct in_addr *local_in = NULL;
-       int nlocal_in = 0;
-
-       if (he != NULL) {
-               if(he->h_length!=4 || he->h_addrtype!=AF_INET) {
-                       return(FALSE);
-               }
-
-               *h_name=mono_string_new(domain, he->h_name);
-
-               while(he->h_aliases[i]!=NULL) {
-                       i++;
-               }
-               
-               *h_aliases=mono_array_new(domain, mono_get_string_class (), i);
-               i=0;
-               while(he->h_aliases[i]!=NULL) {
-                       MonoString *alias;
-                       
-                       alias=mono_string_new(domain, he->h_aliases[i]);
-                       mono_array_setref (*h_aliases, i, alias);
-                       i++;
-               }
-       } else if (!add_local_ips) {
-               return FALSE;
-       }
-
-       if (add_local_ips) {
-               local_in = (struct in_addr *) get_local_ips (AF_INET, &nlocal_in);
-               if (nlocal_in) {
-                       *h_addr_list = mono_array_new(domain, mono_get_string_class (), nlocal_in);
-                       for (i = 0; i < nlocal_in; i++) {
-                               MonoString *addr_string;
-                               char addr [16], *ptr;
-                               
-                               ptr = (char *) &local_in [i];
-                               g_snprintf(addr, 16, "%u.%u.%u.%u",
-                                        (unsigned char) ptr [0],
-                                        (unsigned char) ptr [1],
-                                        (unsigned char) ptr [2],
-                                        (unsigned char) ptr [3]);
-                               
-                               addr_string = mono_string_new (domain, addr);
-                               mono_array_setref (*h_addr_list, i, addr_string);
-                               i++;
-                       }
-
-                       g_free (local_in);
-               } else if (he == NULL) {
-                       /* If requesting "" and there are no other interfaces up, MS returns 127.0.0.1 */
-                       *h_addr_list = mono_array_new(domain, mono_get_string_class (), 1);
-                       mono_array_setref (*h_addr_list, 0, mono_string_new (domain, "127.0.0.1"));
-                       return TRUE;
-               }
-       }
-       
-       if (nlocal_in == 0 && he != NULL) {
-               i = 0;
-               while (he->h_addr_list[i]!=NULL) {
-                       i++;
-               }
-
-               *h_addr_list=mono_array_new(domain, mono_get_string_class (), i);
-               i=0;
-               while(he->h_addr_list[i]!=NULL) {
-                       MonoString *addr_string;
-                       char addr[16];
-                       
-                       g_snprintf(addr, 16, "%u.%u.%u.%u",
-                                (unsigned char)he->h_addr_list[i][0],
-                                (unsigned char)he->h_addr_list[i][1],
-                                (unsigned char)he->h_addr_list[i][2],
-                                (unsigned char)he->h_addr_list[i][3]);
-                       
-                       addr_string=mono_string_new(domain, addr);
-                       mono_array_setref (*h_addr_list, i, addr_string);
-                       i++;
-               }
-       }
-
-       return(TRUE);
-}
-
-static gboolean ipaddr_to_IPHostEntry(const char *addr, MonoString **h_name,
-                                     MonoArray **h_aliases,
-                                     MonoArray **h_addr_list)
-{
-       MonoDomain *domain = mono_domain_get ();
-
-       *h_name=mono_string_new(domain, addr);
-       *h_aliases=mono_array_new(domain, mono_get_string_class (), 0);
-       *h_addr_list=mono_array_new(domain, mono_get_string_class (), 1);
-       mono_array_setref (*h_addr_list, 0, *h_name);
-
-       return(TRUE);
-}
-#endif
-
-#if defined(AF_INET6) && defined(HAVE_GETHOSTBYNAME2_R)
-static gboolean hostent_to_IPHostEntry2(struct hostent *he1,struct hostent *he2, MonoString **h_name,
-                               MonoArray **h_aliases, MonoArray **h_addr_list, gboolean add_local_ips)
-{
-       MonoDomain *domain = mono_domain_get ();
-       int i, host_count, host_index, family_hint;
-       struct in_addr *local_in = NULL;
-       int nlocal_in = 0;
-       struct in6_addr *local_in6 = NULL;
-       int nlocal_in6 = 0;
-       gboolean from_local = FALSE;
-
-       family_hint = get_family_hint ();
-
-       /*
-        * Check if address length and family are correct
-        */
-       if (he1 != NULL && (he1->h_length!=4 || he1->h_addrtype!=AF_INET)) {
-               return(FALSE);
-       }
-
-       if (he2 != NULL && (he2->h_length!=16 || he2->h_addrtype!=AF_INET6)) {
-               return(FALSE);
-       }
-
-       /*
-        * Get the aliases and host name from he1 or he2 whichever is
-        * not null, if he1 is not null then take aliases from he1
-        */
-       if (he1 != NULL && (family_hint == PF_UNSPEC ||
-                           family_hint == PF_INET)) {
-               *h_name=mono_string_new (domain, he1->h_name);
-
-               i=0;
-               while(he1->h_aliases[i]!=NULL) {
-                       i++;
-               }
-
-               *h_aliases=mono_array_new (domain, mono_get_string_class (),
-                                          i);
-               i=0;
-               while(he1->h_aliases[i]!=NULL) {
-                       MonoString *alias;
-
-                       alias=mono_string_new (domain, he1->h_aliases[i]);
-                       mono_array_setref (*h_aliases, i, alias);
-                       i++;
-               }
-       } else if (he2 != NULL && (family_hint == PF_UNSPEC ||
-                                  family_hint == PF_INET6)) {
-               *h_name=mono_string_new (domain, he2->h_name);
-
-               i=0;
-               while(he2->h_aliases [i] != NULL) {
-                       i++;
-               }
-
-               *h_aliases=mono_array_new (domain, mono_get_string_class (),
-                                          i);
-               i=0;
-               while(he2->h_aliases[i]!=NULL) {
-                       MonoString *alias;
-
-                       alias=mono_string_new (domain, he2->h_aliases[i]);
-                       mono_array_setref (*h_aliases, i, alias);
-                       i++;
-               }
-       } else if (!add_local_ips) {
-               return(FALSE);
-       }
-
-       /*
-        * Count the number of addresses in he1 + he2
-        */
-       host_count = 0;
-       if (he1 != NULL && (family_hint == PF_UNSPEC ||
-                           family_hint == PF_INET)) {
-               i=0;
-               while(he1->h_addr_list[i]!=NULL) {
-                       i++;
-                       host_count++;
-               }
-       }
-
-       if (he2 != NULL && (family_hint == PF_UNSPEC ||
-                           family_hint == PF_INET6)) {
-               i=0;
-               while(he2->h_addr_list[i]!=NULL) {
-                       i++;
-                       host_count++;
-               }
-       }
-
-       /*
-        * Fills the array
-        */
-       host_index = 0;
-       if (add_local_ips) {
-               if (family_hint == PF_UNSPEC || family_hint == PF_INET)
-                       local_in = (struct in_addr *) get_local_ips (AF_INET, &nlocal_in);
-
-               if (family_hint == PF_UNSPEC || family_hint == PF_INET6)
-                       local_in6 = (struct in6_addr *) get_local_ips (AF_INET6, &nlocal_in6);
-
-               if (nlocal_in || nlocal_in6) {
-                       from_local = TRUE;
-                       *h_addr_list = mono_array_new (domain, mono_get_string_class (),
-                                                            nlocal_in + nlocal_in6);
-
-                       if (nlocal_in6) {
-                               int n;
-                               for (n = 0; n < nlocal_in6; n++) {
-                                       MonoString *addr_string;
-                                       const char *ret;
-                                       char addr[48]; /* INET6_ADDRSTRLEN == 46, but IPv6 addresses can be 48 bytes with the trailing NULL */
-
-                                       ret = inet_ntop (AF_INET6, &local_in6 [n], addr, sizeof(addr));
-
-                                       if (ret != NULL) {
-                                               addr_string = mono_string_new (domain, addr);
-                                               mono_array_setref (*h_addr_list, host_index, addr_string);
-                                               host_index++;
-                                       }
-                               }
-                       }
-
-                       if (nlocal_in) {
-                               int n;
-                               for (n = 0; n < nlocal_in; n++) {
-                                       MonoString *addr_string;
-                                       const char *ret;
-                                       char addr[16]; /* INET_ADDRSTRLEN == 16 */
-
-                                       ret = inet_ntop (AF_INET, &local_in [n], addr, sizeof(addr));
-
-                                       if (ret != NULL) {
-                                               addr_string = mono_string_new (domain, addr);
-                                               mono_array_setref (*h_addr_list, host_index, addr_string);
-                                               host_index++;
-                                       }
-                               }
-                       }
-                       g_free (local_in);
-                       g_free (local_in6);
-                       return TRUE;
-               } else if (he1 == NULL && he2 == NULL) {
-                       /* If requesting "" and there are no other interfaces up, MS returns 127.0.0.1 */
-                       *h_addr_list = mono_array_new(domain, mono_get_string_class (), 1);
-                       mono_array_setref (*h_addr_list, 0, mono_string_new (domain, "127.0.0.1"));
-                       g_free (local_in);
-                       g_free (local_in6);
-                       return TRUE;
-               }
-
-               g_free (local_in);
-               g_free (local_in6);
-       }
-
-       *h_addr_list=mono_array_new (domain, mono_get_string_class (), host_count);
-
-       if (he2 != NULL && (family_hint == PF_UNSPEC ||
-                           family_hint == PF_INET6)) {
-               i = 0;
-               while(he2->h_addr_list[i] != NULL) {
-                       MonoString *addr_string;
-                       const char *ret;
-                       char addr[48]; /* INET6_ADDRSTRLEN == 46, but IPv6 addresses can be 48 bytes long with the trailing NULL */
-
-                       ret = inet_ntop (AF_INET6, he2->h_addr_list[i], addr,
-                                        sizeof(addr));
-
-                       if (ret != NULL) {
-                               addr_string = mono_string_new (domain, addr);
-                               mono_array_setref (*h_addr_list, host_index, addr_string);
-                               i++;
-                               host_index++;
-                       }
-               }
-       }
-
-       if (he1 != NULL && (family_hint == PF_UNSPEC ||
-                           family_hint == PF_INET)) {
-               i=0;
-               while(he1->h_addr_list[i] != NULL) {
-                       MonoString *addr_string;
-                       const char *ret;
-                       char addr[16]; /* INET_ADDRSTRLEN == 16 */
-
-                       ret = inet_ntop (AF_INET, he1->h_addr_list[i], addr,
-                                        sizeof(addr));
-
-                       if (ret != NULL) {
-                               addr_string=mono_string_new (domain, addr);
-                               mono_array_setref (*h_addr_list, host_index, addr_string);
-                               i++;
-                               host_index++;
-                       }
-               }
-       }
-
-       return(TRUE);
-}
-#endif
-
-#if defined(AF_INET6)
 static gboolean 
-addrinfo_to_IPHostEntry(struct addrinfo *info, MonoString **h_name,
+addrinfo_to_IPHostEntry(MonoAddressInfo *info, MonoString **h_name,
                                                MonoArray **h_aliases,
                                                MonoArray **h_addr_list,
                                                gboolean add_local_ips)
 {
        gint32 count, i;
-       struct addrinfo *ai = NULL;
+       MonoAddressEntry *ai = NULL;
        struct in_addr *local_in = NULL;
        int nlocal_in = 0;
        struct in6_addr *local_in6 = NULL;
@@ -2888,32 +2227,34 @@ addrinfo_to_IPHostEntry(struct addrinfo *info, MonoString **h_name,
        addr_index = 0;
        *h_aliases=mono_array_new(domain, mono_get_string_class (), 0);
        if (add_local_ips) {
-               local_in = (struct in_addr *) get_local_ips (AF_INET, &nlocal_in);
-               local_in6 = (struct in6_addr *) get_local_ips (AF_INET6, &nlocal_in6);
+               local_in = (struct in_addr *) mono_get_local_interfaces (AF_INET, &nlocal_in);
+               local_in6 = (struct in6_addr *) mono_get_local_interfaces (AF_INET6, &nlocal_in6);
                if (nlocal_in || nlocal_in6) {
+                       char addr [INET6_ADDRSTRLEN];
                        *h_addr_list=mono_array_new(domain, mono_get_string_class (), nlocal_in + nlocal_in6);
                        if (nlocal_in) {
                                MonoString *addr_string;
-                               char addr [16];
                                int i;
 
                                for (i = 0; i < nlocal_in; i++) {
-                                       inet_ntop (AF_INET, &local_in [i], addr, sizeof (addr));
-                                       addr_string = mono_string_new (domain, addr);
-                                       mono_array_setref (*h_addr_list, addr_index, addr_string);
-                                       addr_index++;
+                                       MonoAddress maddr;
+                                       mono_address_init (&maddr, AF_INET, &local_in [i]);
+                                       if (mono_networking_addr_to_str (&maddr, addr, sizeof (addr))) {
+                                               addr_string = mono_string_new (domain, addr);
+                                               mono_array_setref (*h_addr_list, addr_index, addr_string);
+                                               addr_index++;
+                                       }
                                }
                        }
 
                        if (nlocal_in6) {
                                MonoString *addr_string;
-                               const char *ret;
-                               char addr [48];
                                int i;
 
                                for (i = 0; i < nlocal_in6; i++) {
-                                       ret = inet_ntop (AF_INET6, &local_in6 [i], addr, sizeof (addr));
-                                       if (ret != NULL) {
+                                       MonoAddress maddr;
+                                       mono_address_init (&maddr, AF_INET6, &local_in6 [i]);
+                                       if (mono_networking_addr_to_str (&maddr, addr, sizeof (addr))) {
                                                addr_string = mono_string_new (domain, addr);
                                                mono_array_setref (*h_addr_list, addr_index, addr_string);
                                                addr_index++;
@@ -2924,7 +2265,7 @@ addrinfo_to_IPHostEntry(struct addrinfo *info, MonoString **h_name,
                        g_free (local_in);
                        g_free (local_in6);
                        if (info) {
-                               freeaddrinfo (info);
+                               mono_free_address_info (info);
                        }
                        return TRUE;
                }
@@ -2933,8 +2274,8 @@ addrinfo_to_IPHostEntry(struct addrinfo *info, MonoString **h_name,
                g_free (local_in6);
        }
 
-       for (count=0, ai=info; ai!=NULL; ai=ai->ai_next) {
-               if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
+       for (count = 0, ai = info->entries; ai != NULL; ai = ai->next) {
+               if (ai->family != AF_INET && ai->family != AF_INET6)
                        continue;
 
                count++;
@@ -2942,22 +2283,17 @@ addrinfo_to_IPHostEntry(struct addrinfo *info, MonoString **h_name,
 
        *h_addr_list=mono_array_new(domain, mono_get_string_class (), count);
 
-       for (ai=info, i=0; ai!=NULL; ai=ai->ai_next) {
+       for (ai = info->entries, i = 0; ai != NULL; ai = ai->next) {
+               MonoAddress maddr;
                MonoString *addr_string;
-               const char *ret;
-               char buffer [48]; /* Max. size for IPv6 */
+               char buffer [INET6_ADDRSTRLEN]; /* Max. size for IPv6 */
 
-               if((ai->ai_family != PF_INET) && (ai->ai_family != PF_INET6)) {
+               if((ai->family != PF_INET) && (ai->family != PF_INET6)) {
                        continue;
                }
 
-               if(ai->ai_family == PF_INET) {
-                       ret = inet_ntop(ai->ai_family, (void*)&(((struct sockaddr_in*)ai->ai_addr)->sin_addr), buffer, 16);
-               } else {
-                       ret = inet_ntop(ai->ai_family, (void*)&(((struct sockaddr_in6*)ai->ai_addr)->sin6_addr), buffer, 48);
-               }
-
-               if(ret) {
+               mono_address_init (&maddr, ai->family, &ai->address);
+               if(mono_networking_addr_to_str (&maddr, buffer, sizeof (buffer))) {
                        addr_string=mono_string_new(domain, buffer);
                } else {
                        addr_string=mono_string_new(domain, "");
@@ -2967,8 +2303,8 @@ addrinfo_to_IPHostEntry(struct addrinfo *info, MonoString **h_name,
 
                if(!i) {
                        i++;
-                       if (ai->ai_canonname != NULL) {
-                               *h_name=mono_string_new(domain, ai->ai_canonname);
+                       if (ai->canonical_name != NULL) {
+                               *h_name=mono_string_new(domain, ai->canonical_name);
                        } else {
                                *h_name=mono_string_new(domain, buffer);
                        }
@@ -2978,206 +2314,68 @@ addrinfo_to_IPHostEntry(struct addrinfo *info, MonoString **h_name,
        }
 
        if(info) {
-               freeaddrinfo(info);
+               mono_free_address_info (info);
        }
 
        return(TRUE);
 }
+
+static int
+get_addrinfo_family_hint (void)
+{
+       switch (get_family_hint ()) {
+       case PF_UNSPEC: return MONO_HINT_UNSPECIFIED;
+       case PF_INET: return MONO_HINT_IPV4;
+#ifdef PF_INET6
+       case PF_INET6: return MONO_HINT_IPV6;
 #endif
+       default:
+               g_error ("invalid hint");
+               return 0;
+       }
+}
 
-#ifdef AF_INET6
 MonoBoolean ves_icall_System_Net_Dns_GetHostByName_internal(MonoString *host, MonoString **h_name, MonoArray **h_aliases, MonoArray **h_addr_list)
 {
        gboolean add_local_ips = FALSE;
-#ifdef HAVE_SIOCGIFCONF
        gchar this_hostname [256];
-#endif
-#if !defined(HAVE_GETHOSTBYNAME2_R)
-       struct addrinfo *info = NULL, hints;
+       MonoAddressInfo *info = NULL;
        char *hostname;
        
-       MONO_ARCH_SAVE_REGS;
-       
        hostname=mono_string_to_utf8 (host);
        if (*hostname == '\0') {
                add_local_ips = TRUE;
                *h_name = host;
        }
-#ifdef HAVE_SIOCGIFCONF
        if (!add_local_ips && gethostname (this_hostname, sizeof (this_hostname)) != -1) {
                if (!strcmp (hostname, this_hostname)) {
                        add_local_ips = TRUE;
                        *h_name = host;
                }
        }
-#endif
 
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_family = get_family_hint ();
-       hints.ai_socktype = SOCK_STREAM;
-       hints.ai_flags = AI_CANONNAME;
-
-       if (*hostname && getaddrinfo(hostname, NULL, &hints, &info) == -1) {
+       if (*hostname && mono_get_address_info (hostname, 0, MONO_HINT_CANONICAL_NAME | get_addrinfo_family_hint (), &info)) {
                g_free (hostname);
                return(FALSE);
        }
        
        g_free(hostname);
 
-       return(addrinfo_to_IPHostEntry(info, h_name, h_aliases, h_addr_list, add_local_ips));
-#else
-       struct hostent he1,*hp1, he2, *hp2;
-       int buffer_size1, buffer_size2;
-       char *buffer1, *buffer2;
-       int herr;
-       gboolean return_value;
-       char *hostname;
-       
-       MONO_ARCH_SAVE_REGS;
-       
-       hostname=mono_string_to_utf8 (host);
-       if (*hostname == '\0')
-               add_local_ips = TRUE;
-
-#ifdef HAVE_SIOCGIFCONF
-       if (!add_local_ips && gethostname (this_hostname, sizeof (this_hostname)) != -1) {
-               if (!strcmp (hostname, this_hostname))
-                       add_local_ips = TRUE;
-       }
-#endif
-
-       buffer_size1 = 512;
-       buffer_size2 = 512;
-       buffer1 = g_malloc0(buffer_size1);
-       buffer2 = g_malloc0(buffer_size2);
-
-       hp1 = NULL;
-       hp2 = NULL;
-       while (*hostname && gethostbyname2_r(hostname, AF_INET, &he1, buffer1, buffer_size1,
-                               &hp1, &herr) == ERANGE) {
-               buffer_size1 *= 2;
-               buffer1 = g_realloc(buffer1, buffer_size1);
-       }
-
-       if (*hostname && hp1 == NULL)
-       {
-               while (gethostbyname2_r(hostname, AF_INET6, &he2, buffer2,
-                                       buffer_size2, &hp2, &herr) == ERANGE) {
-                       buffer_size2 *= 2;
-                       buffer2 = g_realloc(buffer2, buffer_size2);
-               }
-       }
-
-       return_value = hostent_to_IPHostEntry2(hp1, hp2, h_name, h_aliases,
-                                              h_addr_list, add_local_ips);
-
-       g_free(buffer1);
-       g_free(buffer2);
-       g_free(hostname);
-
-       return(return_value);
-#endif /* HAVE_GETHOSTBYNAME2_R */
+       return (addrinfo_to_IPHostEntry(info, h_name, h_aliases, h_addr_list, add_local_ips));
 }
-#else /* AF_INET6 */
-MonoBoolean ves_icall_System_Net_Dns_GetHostByName_internal(MonoString *host, MonoString **h_name, MonoArray **h_aliases, MonoArray **h_addr_list)
-{
-       struct hostent *he;
-       char *hostname;
-       gboolean add_local_ips = FALSE;
-#ifdef HAVE_SIOCGIFCONF
-       gchar this_hostname [256];
-#endif
-       
-       MONO_ARCH_SAVE_REGS;
-
-       hostname=mono_string_to_utf8(host);
-       if (*hostname == '\0')
-               add_local_ips = TRUE;
-#ifdef HAVE_SIOCGIFCONF
-       if (!add_local_ips && gethostname (this_hostname, sizeof (this_hostname)) != -1) {
-               if (!strcmp (hostname, this_hostname))
-                       add_local_ips = TRUE;
-       }
-#endif
-
-#ifndef HOST_WIN32
-       he = NULL;
-       if (*hostname)
-               he = _wapi_gethostbyname (hostname);
-#else
-       he = _wapi_gethostbyname (hostname);
-#endif
-
-       if (*hostname && he==NULL) {
-               g_free (hostname);
-               return(FALSE);
-       }
-
-       g_free (hostname);
-
-       return(hostent_to_IPHostEntry(he, h_name, h_aliases, h_addr_list, add_local_ips));
-}
-#endif /* AF_INET6 */
-
-#ifndef HAVE_INET_PTON
-static int
-inet_pton (int family, const char *address, void *inaddrp)
-{
-       if (family == AF_INET) {
-#ifdef HAVE_INET_ATON
-               struct in_addr inaddr;
-               
-               if (!inet_aton (address, &inaddr))
-                       return 0;
-               
-               memcpy (inaddrp, &inaddr, sizeof (struct in_addr));
-               return 1;
-#else
-               /* assume the system has inet_addr(), if it doesn't
-                  have that we're pretty much screwed... */
-               guint32 inaddr;
-               
-               if (!strcmp (address, "255.255.255.255")) {
-                       /* special-case hack */
-                       inaddr = 0xffffffff;
-               } else {
-                       inaddr = inet_addr (address);
-#ifndef INADDR_NONE
-#define INADDR_NONE ((in_addr_t) -1)
-#endif
-                       if (inaddr == INADDR_NONE)
-                               return 0;
-               }
-               
-               memcpy (inaddrp, &inaddr, sizeof (guint32));
-               return 1;
-#endif /* HAVE_INET_ATON */
-       }
-       
-       return -1;
-}
-#endif /* !HAVE_INET_PTON */
 
 extern MonoBoolean ves_icall_System_Net_Dns_GetHostByAddr_internal(MonoString *addr, MonoString **h_name, MonoArray **h_aliases, MonoArray **h_addr_list)
 {
        char *address;
-       
-#ifdef AF_INET6
        struct sockaddr_in saddr;
        struct sockaddr_in6 saddr6;
-       struct addrinfo *info = NULL, hints;
+       MonoAddressInfo *info = NULL;
        gint32 family;
        char hostname[NI_MAXHOST] = {0};
        int flags = 0;
-#else
-       struct in_addr inaddr;
-       struct hostent *he;
-       gboolean ret;
-#endif
 
        address = mono_string_to_utf8 (addr);
 
-#ifdef AF_INET6
        if (inet_pton (AF_INET, address, &saddr.sin_addr ) <= 0) {
                /* Maybe an ipv6 address */
                if (inet_pton (AF_INET6, address, &saddr6.sin6_addr) <= 0) {
@@ -3215,32 +2413,10 @@ extern MonoBoolean ves_icall_System_Net_Dns_GetHostByAddr_internal(MonoString *a
                }
        }
 
-       memset (&hints, 0, sizeof(hints));
-       hints.ai_family = get_family_hint ();
-       hints.ai_socktype = SOCK_STREAM;
-       hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
-
-       if( getaddrinfo (hostname, NULL, &hints, &info) == -1 ) {
-               return(FALSE);
-       }
+       if (mono_get_address_info (hostname, 0, get_addrinfo_family_hint () | MONO_HINT_CANONICAL_NAME | MONO_HINT_CONFIGURED_ONLY, &info))
+               return FALSE;
 
        return(addrinfo_to_IPHostEntry (info, h_name, h_aliases, h_addr_list, FALSE));
-#else
-       if (inet_pton (AF_INET, address, &inaddr) <= 0) {
-               g_free (address);
-               return(FALSE);
-       }
-
-       if ((he = gethostbyaddr ((char *) &inaddr, sizeof (inaddr), AF_INET)) == NULL) {
-               ret = ipaddr_to_IPHostEntry (address, h_name, h_aliases, h_addr_list);
-       } else {
-               ret = hostent_to_IPHostEntry (he, h_name, h_aliases,
-                                             h_addr_list, FALSE);
-       }
-
-       g_free (address);
-       return(ret);
-#endif
 }
 
 extern MonoBoolean ves_icall_System_Net_Dns_GetHostName_internal(MonoString **h_name)
@@ -3248,8 +2424,6 @@ extern MonoBoolean ves_icall_System_Net_Dns_GetHostName_internal(MonoString **h_
        gchar hostname[256];
        int ret;
        
-       MONO_ARCH_SAVE_REGS;
-
        ret = gethostname (hostname, sizeof (hostname));
        if(ret==-1) {
                return(FALSE);
@@ -3267,8 +2441,6 @@ ves_icall_System_Net_Sockets_Socket_SendFile (SOCKET sock, MonoString *filename,
        gint32 error;
        TRANSMIT_FILE_BUFFERS buffers;
 
-       MONO_ARCH_SAVE_REGS;
-
        if (filename == NULL)
                return FALSE;
 
@@ -3299,22 +2471,13 @@ ves_icall_System_Net_Sockets_Socket_SendFile (SOCKET sock, MonoString *filename,
 
 void mono_network_init(void)
 {
-       WSADATA wsadata;
-       int err;
-       
-       err=WSAStartup(MAKEWORD(2,0), &wsadata);
-       if(err!=0) {
-               g_error("%s: Couldn't initialise networking", __func__);
-               exit(-1);
-       }
-
-       LOGDEBUG (g_message("%s: Using socket library: %s", __func__, wsadata.szDescription));
-       LOGDEBUG (g_message("%s: Socket system status: %s", __func__, wsadata.szSystemStatus));
+       mono_networking_init ();
 }
 
 void mono_network_cleanup(void)
 {
-       WSACleanup();
+       _wapi_cleanup_networking ();
+       mono_networking_shutdown ();
 }
 
 void