IPv6 support for to_native and from_native, and support
[cascardo/gnio.git] / gnio / gsocketaddress.c
index 88b4700..2421108 100644 (file)
 #include <config.h>
 #include <glib.h>
 
+#include <sys/socket.h>
+#include <netinet/in.h>
+
 #include "gsocketaddress.h"
+#include "ginetsocketaddress.h"
+#include "ginet4address.h"
+#include "ginet6address.h"
 
-G_DEFINE_ABSTRACT_TYPE (GSocketAddress, g_socket_address, G_TYPE_OBJECT);
+G_DEFINE_ABSTRACT_TYPE (GSocketAddress, g_socket_address, G_TYPE_INITIALLY_UNOWNED);
 
 static void
 g_socket_address_class_init (GSocketAddressClass *klass)
 {
-  GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
+
 }
 
 static void
@@ -39,3 +45,51 @@ g_socket_address_init (GSocketAddress *address)
 {
 
 }
+
+gssize
+g_socket_address_native_size (GSocketAddress *address)
+{
+  g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), -1);
+
+  return G_SOCKET_ADDRESS_GET_CLASS (address)->native_size (address);
+}
+
+gboolean
+g_socket_address_to_native (GSocketAddress *address, gpointer dest)
+{
+  g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE);
+
+  return G_SOCKET_ADDRESS_GET_CLASS (address)->to_native (address, dest);
+}
+
+GSocketAddress *
+g_socket_address_from_native (gpointer native, gsize len)
+{
+  gshort family;
+
+  if (len < sizeof (gshort))
+    return NULL;
+
+  family = ((struct sockaddr *) native)->sa_family;
+
+  if (family == AF_UNSPEC)
+    return NULL;
+
+  if (family == AF_INET)
+    {
+      struct sockaddr_in *addr = (struct sockaddr_in *) native;
+
+      return G_SOCKET_ADDRESS (g_inet_socket_address_new (G_INET_ADDRESS (g_inet4_address_from_bytes ((guint8 *) &(addr->sin_addr))), g_ntohs (addr->sin_port)));
+    }
+
+  if (family == AF_INET6)
+    {
+      struct sockaddr_in6 *addr = (struct sockaddr_in6 *) native;
+
+      return G_SOCKET_ADDRESS (g_inet_socket_address_new (G_INET_ADDRESS (g_inet6_address_from_bytes ((guint8 *) &(addr->sin6_addr))), g_ntohs (addr->sin6_port)));
+    }
+
+  // TODO: handle AF_UNIX
+
+  return NULL;
+}