IPv6 support for to_native and from_native, and support
[cascardo/gnio.git] / gnio / gsocketaddress.c
1 /* GNIO - GLib Network Layer of GIO
2  *
3  * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Authors: Christian Kellner <gicmo@gnome.org>
21  *          Samuel Cormier-Iijima <sciyoshi@gmail.com>
22  */
23
24 #include <config.h>
25 #include <glib.h>
26
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29
30 #include "gsocketaddress.h"
31 #include "ginetsocketaddress.h"
32 #include "ginet4address.h"
33 #include "ginet6address.h"
34
35 G_DEFINE_ABSTRACT_TYPE (GSocketAddress, g_socket_address, G_TYPE_INITIALLY_UNOWNED);
36
37 static void
38 g_socket_address_class_init (GSocketAddressClass *klass)
39 {
40
41 }
42
43 static void
44 g_socket_address_init (GSocketAddress *address)
45 {
46
47 }
48
49 gssize
50 g_socket_address_native_size (GSocketAddress *address)
51 {
52   g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), -1);
53
54   return G_SOCKET_ADDRESS_GET_CLASS (address)->native_size (address);
55 }
56
57 gboolean
58 g_socket_address_to_native (GSocketAddress *address, gpointer dest)
59 {
60   g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE);
61
62   return G_SOCKET_ADDRESS_GET_CLASS (address)->to_native (address, dest);
63 }
64
65 GSocketAddress *
66 g_socket_address_from_native (gpointer native, gsize len)
67 {
68   gshort family;
69
70   if (len < sizeof (gshort))
71     return NULL;
72
73   family = ((struct sockaddr *) native)->sa_family;
74
75   if (family == AF_UNSPEC)
76     return NULL;
77
78   if (family == AF_INET)
79     {
80       struct sockaddr_in *addr = (struct sockaddr_in *) native;
81
82       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)));
83     }
84
85   if (family == AF_INET6)
86     {
87       struct sockaddr_in6 *addr = (struct sockaddr_in6 *) native;
88
89       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)));
90     }
91
92   // TODO: handle AF_UNIX
93
94   return NULL;
95 }