[gssdp/wip/ipv6: 40/43] wip: Add pktinfo handling for ipv6
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gssdp/wip/ipv6: 40/43] wip: Add pktinfo handling for ipv6
- Date: Mon, 29 Oct 2018 21:55:00 +0000 (UTC)
commit c9519ea4eb964af0bad39c97980e1f039bedc11e
Author: Jens Georg <mail jensge org>
Date: Thu Feb 18 10:47:36 2016 +0100
wip: Add pktinfo handling for ipv6
Signed-off-by: Jens Georg <mail jensge org>
libgssdp/Makefile.am | 4 +-
libgssdp/gssdp-pktinfo6-message.c | 226 ++++++++++++++++++++++++++++++++++++++
libgssdp/gssdp-pktinfo6-message.h | 45 ++++++++
libgssdp/gssdp-socket-functions.c | 9 ++
libgssdp/meson.build | 1 +
5 files changed, 284 insertions(+), 1 deletion(-)
---
diff --git a/libgssdp/Makefile.am b/libgssdp/Makefile.am
index 60a28ab..926c2cb 100644
--- a/libgssdp/Makefile.am
+++ b/libgssdp/Makefile.am
@@ -50,7 +50,9 @@ libgssdp_1_0_la_SOURCES = $(introspection_sources) \
if HAVE_PKTINFO
libgssdp_1_0_la_SOURCES += gssdp-pktinfo-message.c \
- gssdp-pktinfo-message.h
+ gssdp-pktinfo-message.h \
+ gssdp-pktinfo6-message.c \
+ gssdp-pktinfo6-message.h
endif
libgssdp_1_0_la_LIBADD = $(LIBGSSDP_LIBS)
diff --git a/libgssdp/gssdp-pktinfo6-message.c b/libgssdp/gssdp-pktinfo6-message.c
new file mode 100644
index 0000000..470a998
--- /dev/null
+++ b/libgssdp/gssdp-pktinfo6-message.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2014 Jens Georg.
+ *
+ * Author: Jens Georg <mail jensge org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netinet/ip.h>
+
+#include "gssdp-pktinfo6-message.h"
+
+typedef struct _GSSDPPktinfo6MessagePrivate GSSDPPktinfo6MessagePrivate;
+struct _GSSDPPktinfo6MessagePrivate
+{
+ GInetAddress *iface_addr;
+ gint index;
+};
+
+struct _GSSDPPktinfo6Message {
+ GSocketControlMessage parent_instance;
+
+ GSSDPPktinfo6MessagePrivate *priv;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GSSDPPktinfo6Message,
+ gssdp_pktinfo6_message,
+ G_TYPE_SOCKET_CONTROL_MESSAGE)
+
+enum {
+ PROP_0,
+ PROP_IFACE_ADDR,
+ PROP_INDEX
+};
+
+static gsize
+gssdp_pktinfo6_message_get_size (GSocketControlMessage *msg)
+{
+ return sizeof (struct in6_pktinfo);
+}
+
+static int
+gssdp_pktinfo6_message_get_level (GSocketControlMessage *msg)
+{
+ return IPPROTO_IPV6;
+}
+
+static int
+gssdp_pktinfo6_message_get_msg_type (GSocketControlMessage *msg)
+{
+ return IPV6_PKTINFO;
+}
+
+static void
+gssdp_pktinfo6_message_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GSSDPPktinfo6Message *self;
+
+ self = GSSDP_PKTINFO6_MESSAGE (object);
+ switch (property_id)
+ {
+ case PROP_IFACE_ADDR:
+ g_value_set_object (value, self->priv->iface_addr);
+ break;
+ case PROP_INDEX:
+ g_value_set_int (value, self->priv->index);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gssdp_pktinfo6_message_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GSSDPPktinfo6Message *self;
+
+ self = GSSDP_PKTINFO6_MESSAGE (object);
+ switch (property_id)
+ {
+ case PROP_IFACE_ADDR:
+ self->priv->iface_addr = g_value_get_object (value);
+ break;
+ case PROP_INDEX:
+ self->priv->index = g_value_get_int (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gssdp_pktinfo6_dispose (GObject *object)
+{
+ GSSDPPktinfo6Message *self = GSSDP_PKTINFO6_MESSAGE (object);
+
+ g_clear_object (&self->priv->iface_addr);
+}
+
+static GSocketControlMessage *
+gssdp_pktinfo6_message_deserialize (int level,
+ int type,
+ gsize size,
+ gpointer data)
+{
+ GSocketControlMessage *message;
+ GInetAddress *addr;
+ struct in6_pktinfo *info = (struct in6_pktinfo *) data;
+ const guint8 *bytes;
+
+ if (level != IPPROTO_IPV6 || type != IPV6_PKTINFO)
+ return NULL;
+
+ bytes = (const guint8 *)&(info->ipi6_addr);
+ addr = g_inet_address_new_from_bytes (bytes, G_SOCKET_FAMILY_IPV6);
+
+ message = gssdp_pktinfo6_message_new (addr, info->ipi6_ifindex);
+
+ return message;
+}
+
+static void
+gssdp_pktinfo6_message_init (GSSDPPktinfo6Message *self)
+{
+ self->priv = gssdp_pktinfo6_message_get_instance_private (self);
+}
+
+static void
+gssdp_pktinfo6_message_class_init (GSSDPPktinfo6MessageClass *klass)
+{
+ GSocketControlMessageClass *scm_class =
+ G_SOCKET_CONTROL_MESSAGE_CLASS (klass);
+
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GSSDPPktinfo6MessagePrivate));
+
+ scm_class->get_size = gssdp_pktinfo6_message_get_size;
+ scm_class->get_level = gssdp_pktinfo6_message_get_level;
+ scm_class->get_type = gssdp_pktinfo6_message_get_msg_type;
+ scm_class->deserialize = gssdp_pktinfo6_message_deserialize;
+
+ object_class->get_property = gssdp_pktinfo6_message_get_property;
+ object_class->set_property = gssdp_pktinfo6_message_set_property;
+ object_class->dispose = gssdp_pktinfo6_dispose;
+
+ g_object_class_install_property
+ (object_class,
+ PROP_IFACE_ADDR,
+ g_param_spec_object ("iface-address",
+ "iface-address",
+ "IP v4 Address of the interface this packet was received on",
+ G_TYPE_INET_ADDRESS,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_INDEX,
+ g_param_spec_int ("index",
+ "index",
+ "Network interface index",
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+}
+
+GSocketControlMessage *
+gssdp_pktinfo6_message_new (GInetAddress *addr, gint ifindex)
+{
+ GSSDPPktinfo6Message *msg;
+
+ msg = GSSDP_PKTINFO6_MESSAGE (
+ g_object_new (GSSDP_TYPE_PKTINFO6_MESSAGE,
+ "iface-address", addr,
+ "index", ifindex,
+ NULL));
+
+ return G_SOCKET_CONTROL_MESSAGE (msg);
+}
+
+gint
+gssdp_pktinfo6_message_get_ifindex (GSSDPPktinfo6Message *message)
+{
+ g_return_val_if_fail (GSSDP_IS_PKTINFO6_MESSAGE (message), -1);
+
+ return message->priv->index;
+}
+
+GInetAddress *
+gssdp_pktinfo6_message_get_local_addr (GSSDPPktinfo6Message *message)
+{
+ g_return_val_if_fail (GSSDP_IS_PKTINFO6_MESSAGE (message), NULL);
+
+ return message->priv->iface_addr;
+}
+
diff --git a/libgssdp/gssdp-pktinfo6-message.h b/libgssdp/gssdp-pktinfo6-message.h
new file mode 100644
index 0000000..7143404
--- /dev/null
+++ b/libgssdp/gssdp-pktinfo6-message.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 Jens Georg <mail jensge org>
+ *
+ * Author: Jens Georg <mail jensge org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef GSSDP_PKTINFO6_MESSAGE_H
+#define GSSDP_PKTINFO6_MESSAGE_H
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define GSSDP_TYPE_PKTINFO6_MESSAGE (gssdp_pktinfo6_message_get_type())
+G_DECLARE_FINAL_TYPE (GSSDPPktinfo6Message,
+ gssdp_pktinfo6_message,
+ GSSDP,
+ PKTINFO6_MESSAGE,
+ GSocketControlMessage)
+
+G_GNUC_INTERNAL GSocketControlMessage *
+gssdp_pktinfo6_message_new (GInetAddress *addr, gint ifindex);
+
+G_GNUC_INTERNAL gint
+gssdp_pktinfo6_message_get_ifindex (GSSDPPktinfo6Message *message);
+
+G_GNUC_INTERNAL GInetAddress *
+gssdp_pktinfo6_message_get_local_addr (GSSDPPktinfo6Message *message);
+
+#endif /* GSSDP_PKTINFO6_MESSAGE_H */
diff --git a/libgssdp/gssdp-socket-functions.c b/libgssdp/gssdp-socket-functions.c
index 70b3566..f93dd5b 100644
--- a/libgssdp/gssdp-socket-functions.c
+++ b/libgssdp/gssdp-socket-functions.c
@@ -39,6 +39,7 @@
#include "gssdp-error.h"
#include "gssdp-socket-functions.h"
#include "gssdp-pktinfo-message.h"
+#include "gssdp-pktinfo6-message.h"
static char*
gssdp_socket_error_message (int error) {
@@ -154,6 +155,14 @@ gssdp_socket_enable_info (GSocket *socket,
/* Register the type so g_socket_control_message_deserialize() will
* find it */
g_object_unref (g_object_new (GSSDP_TYPE_PKTINFO_MESSAGE, NULL));
+ g_object_unref (g_object_new (GSSDP_TYPE_PKTINFO6_MESSAGE, NULL));
+
+ gssdp_socket_option_set (socket,
+ IPPROTO_IPV6,
+ IPV6_RECVPKTINFO,
+ (char *)&enable,
+ sizeof (enable),
+ error);
return gssdp_socket_option_set (socket,
IPPROTO_IP,
diff --git a/libgssdp/meson.build b/libgssdp/meson.build
index 72cbd24..9a53c82 100644
--- a/libgssdp/meson.build
+++ b/libgssdp/meson.build
@@ -25,6 +25,7 @@ sources = files(
if pktinfo_available
sources += 'gssdp-pktinfo-message.c'
+ sources += 'gssdp-pktinfo6-message.c'
endif
libgssdp = library('gssdp-1.0', sources + marshall,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]