Index: AUTHORS
===================================================================
RCS file: /cvs/gnome/gnome-netstatus/AUTHORS,v
retrieving revision 1.3
diff -u -p -r1.3 AUTHORS
--- a/AUTHORS	10 Jun 2003 12:36:27 -0000	1.3
+++ b/AUTHORS	12 May 2004 13:14:27 -0000
@@ -1,3 +1,7 @@
 Mark McLoughlin  <mark@skynet.ie>
 Erwann Chenede  <erwann.chenede@sun.com>
 Calum Benson  <calum.benson@sun.com>
+
+Contributors:
+Grahame Bowland <grahame@angrygoats.net>
+Davyd Madeley <davyd@ucc.asn.au>
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-netstatus/ChangeLog,v
retrieving revision 1.124
diff -u -p -r1.124 ChangeLog
--- a/ChangeLog	9 May 2004 23:24:35 -0000	1.124
+++ b/ChangeLog	12 May 2004 13:14:30 -0000
@@ -1,3 +1,11 @@
+2004-05-12  Davyd Madeley <davyd@ucc.asn.au>
+
+	* src/gnome-netstatus.glade:
+	* src/netstatus-dialog.c:
+	* src/netstatus-iface.c:
+	* src/netstatus-iface.h:
+	- Add IPv6 support to the netstatus dialog.
+
 2004-05-10  Laszlo Peter  <laca@sun.com>
 
 	* src/netstatus-iface.c: include socket.h to fix build on Solaris
Index: TODO
===================================================================
RCS file: /cvs/gnome/gnome-netstatus/TODO,v
retrieving revision 1.2
diff -u -p -r1.2 TODO
--- a/TODO	10 Jun 2003 14:47:33 -0000	1.2
+++ b/TODO	12 May 2004 13:14:30 -0000
@@ -4,8 +4,6 @@
   if there are any other Network Monitors running and pick
   an interface other than the ones already displayed.
 
-- Implement IPv6 support
-
 - This is totally linux specific at the moment. Need to:
     * Add other implementations for netstatus-sydeps.c on
       systems without /proc/net/dev. In
Index: src/gnome-netstatus.glade
===================================================================
RCS file: /cvs/gnome/gnome-netstatus/src/gnome-netstatus.glade,v
retrieving revision 1.14
diff -u -p -r1.14 gnome-netstatus.glade
--- a/src/gnome-netstatus.glade	17 Mar 2004 23:41:08 -0000	1.14
+++ b/src/gnome-netstatus.glade	12 May 2004 13:14:35 -0000
@@ -1024,7 +1024,7 @@
 		      </child>
 
 		      <child>
-			<widget class="GtkTable" id="table5">
+			<widget class="GtkTable" id="inet6_table">
 			  <property name="visible">True</property>
 			  <property name="n_rows">2</property>
 			  <property name="n_columns">2</property>
@@ -1033,7 +1033,7 @@
 			  <property name="column_spacing">12</property>
 
 			  <child>
-			    <widget class="GtkLabel" id="label39">
+			    <widget class="GtkLabel" id="inet6_addr_title">
 			      <property name="visible">True</property>
 			      <property name="label" translatable="yes">Address:</property>
 			      <property name="use_underline">False</property>
@@ -1057,7 +1057,7 @@
 			  </child>
 
 			  <child>
-			    <widget class="GtkLabel" id="label40">
+			    <widget class="GtkLabel" id="inet6_scope_title">
 			      <property name="visible">True</property>
 			      <property name="label" translatable="yes">Scope:</property>
 			      <property name="use_underline">False</property>
Index: src/netstatus-dialog.c
===================================================================
RCS file: /cvs/gnome/gnome-netstatus/src/netstatus-dialog.c,v
retrieving revision 1.24
diff -u -p -r1.24 netstatus-dialog.c
--- a/src/netstatus-dialog.c	7 Apr 2004 11:44:47 -0000	1.24
+++ b/src/netstatus-dialog.c	12 May 2004 13:14:37 -0000
@@ -78,6 +78,13 @@ typedef struct
   GtkWidget      *inet4_mask;
   GtkWidget      *inet4_mask_title;
 
+  GtkWidget	 *inet6_frame;
+  GtkWidget	 *inet6_table;
+  GtkWidget	 *inet6_addr;
+  GtkWidget	 *inet6_addr_title;
+  GtkWidget	 *inet6_scope;
+  GtkWidget	 *inet6_scope_title;
+
   GtkWidget      *dev_frame;
   GtkWidget      *dev_type;
   GtkWidget      *dev_addr;
@@ -204,6 +211,50 @@ netstatus_dialog_update_signal_strength 
 }
 
 static void
+netstatus_dialog_update_inet6_support (NetstatusDialogData *data)
+{
+	char *addr = NULL;
+	char *scope = NULL;
+
+	if (netstatus_iface_get_inet6_details (data->iface, &addr, &scope))
+	{
+		gtk_widget_show (data->inet6_frame);
+
+		/* Address */
+		if (addr)
+		{
+			gtk_table_set_row_spacing (GTK_TABLE (data->inet6_table), 0, 6);
+			gtk_label_set_text (GTK_LABEL(data->inet6_addr), addr);
+			gtk_widget_show (data->inet6_addr);
+			gtk_widget_show (data->inet6_addr_title);
+		} else {
+			gtk_table_set_row_spacing (GTK_TABLE (data->inet6_table), 0, 0);
+			gtk_widget_hide (data->inet6_addr);
+			gtk_widget_hide (data->inet6_addr_title);
+		}
+
+		/* Scope */
+		if (scope)
+		{
+			gtk_table_set_row_spacing (GTK_TABLE (data->inet6_table), 1, 6);
+			gtk_label_set_text (GTK_LABEL(data->inet6_scope), scope);
+			gtk_widget_show (data->inet6_scope);
+			gtk_widget_show (data->inet6_scope_title);
+		} else {
+			gtk_table_set_row_spacing (GTK_TABLE (data->inet6_table), 1, 0);
+			gtk_widget_hide (data->inet6_scope);
+			gtk_widget_hide (data->inet6_scope_title);
+		}
+
+		g_free (addr);
+		g_free (scope);
+
+	} else {
+		gtk_widget_hide (data->inet6_frame);
+	}
+}
+
+static void
 netstatus_dialog_update_inet4_support (NetstatusDialogData *data)
 {
   char *addr = NULL;
@@ -322,6 +373,7 @@ netstatus_dialog_iface_state_changed (Ne
   netstatus_dialog_update_activity (data);
   
   netstatus_dialog_update_inet4_support (data);
+  netstatus_dialog_update_inet6_support (data);
   netstatus_dialog_update_device_support (data);
 }
 
@@ -640,6 +692,20 @@ netstatus_dialog_setup_signal_strength_d
 }
 
 static void
+netstatus_dialog_setup_inet6_support (NetstatusDialogData *data,
+				      GladeXML		  *xml)
+{
+	data->inet6_frame	= glade_xml_get_widget (xml, "inet6_frame");
+	data->inet6_table	= glade_xml_get_widget (xml, "inet6_table");
+	data->inet6_addr	= glade_xml_get_widget (xml, "inet6_addr_label");
+	data->inet6_addr_title	= glade_xml_get_widget (xml, "inet6_addr_title");
+	data->inet6_scope	= glade_xml_get_widget (xml, "inet6_scope_label");
+	data->inet6_scope_title	= glade_xml_get_widget (xml, "inet6_scope_title");
+
+	netstatus_dialog_update_inet6_support (data);
+}
+
+static void
 netstatus_dialog_setup_inet4_support (NetstatusDialogData *data,
 				      GladeXML            *xml)
 {
@@ -767,6 +833,7 @@ netstatus_dialog_new (NetstatusIface *if
   netstatus_dialog_setup_activity (data, xml);
   netstatus_dialog_setup_signal_strength_details (data, xml);
   netstatus_dialog_setup_inet4_support (data, xml);
+  netstatus_dialog_setup_inet6_support (data, xml);
   netstatus_dialog_setup_device_support (data, xml);
   netstatus_dialog_setup_configure_button (data, xml);
 
Index: src/netstatus-iface.c
===================================================================
RCS file: /cvs/gnome/gnome-netstatus/src/netstatus-iface.c,v
retrieving revision 1.15
diff -u -p -r1.15 netstatus-iface.c
--- a/src/netstatus-iface.c	9 May 2004 23:24:35 -0000	1.15
+++ b/src/netstatus-iface.c	12 May 2004 13:14:40 -0000
@@ -45,10 +45,18 @@
 #include <errno.h>
 #include <unistd.h>
 #include <string.h>
+#include <stdio.h>
 
 #include "netstatus-sysdeps.h"
 #include "netstatus-enums.h"
 
+/* for IPv6 support */
+#define _PATH_PROCNET_IFINET6	"/proc/net/if_inet6"
+#define IPV6_ADDR_LOOPBACK	0x0010U
+#define IPV6_ADDR_LINKLOCAL	0x0020U
+#define IPV6_ADDR_SITELOCAL	0x0040U
+#define IPV6_ADDR_COMPATv4	0x0080U
+
 #define NETSTATUS_IFACE_POLL_DELAY       500  /* milliseconds between polls */
 #define NETSTATUS_IFACE_POLLS_IN_ERROR   10   /* no. of polls in error before increasing delay */
 #define NETSTATUS_IFACE_ERROR_POLL_DELAY 5000 /* delay to use when in error state */
@@ -680,6 +688,73 @@ netstatus_iface_init_monitor (NetstatusI
 }
 
 gboolean
+netstatus_iface_get_inet6_details (NetstatusIface  *iface,
+				   char		  **addr,
+				   char		  **scope)
+{
+	/*
+	 * This is the only way you currently seem to be able to get
+	 * the IPv6 data in Linux at the moment. Borrowed from ifconfig.
+	 */
+	char addr6[INET6_ADDRSTRLEN];
+	char addr6p[8][5];
+	char devname[20]; /* is there an actual length for devname? */
+	int plen, devscope, if_idx, dad_status;
+	FILE *f;
+	
+	if (addr)
+		*addr = NULL;
+	if (scope)
+		*scope = NULL;
+
+	if (!iface->priv->name)
+		return FALSE;
+
+	if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL)
+	{
+		while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x%20s\n",
+					addr6p[0], addr6p[1], addr6p[2], addr6p[3],
+					addr6p[4], addr6p[5], addr6p[6], addr6p[7],
+					&if_idx, &plen, &devscope, &dad_status, devname) != EOF)
+		{
+			if (!strcmp(devname, iface->priv->name))
+			{
+				sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
+						addr6p[0], addr6p[1], addr6p[2], addr6p[3],
+						addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
+				*addr = g_strdup (addr6);
+				switch (devscope)
+				{
+					case 0:
+						*scope = g_strdup ("Global");
+						break;
+					case IPV6_ADDR_LINKLOCAL:
+						*scope = g_strdup ("Link");
+						break;
+					case IPV6_ADDR_SITELOCAL:
+						*scope = g_strdup ("Site");
+						break;
+					case IPV6_ADDR_COMPATv4:
+						*scope = g_strdup ("Compat");
+						break;
+					case IPV6_ADDR_LOOPBACK:
+						*scope = g_strdup ("Host");
+						break;
+					default:
+						*scope = g_strdup ("Unknown");
+				}
+			}
+		}
+	}
+	fclose (f);
+
+	if (addr && !*addr)
+		return FALSE;
+	else
+		return TRUE;
+}
+
+gboolean
 netstatus_iface_get_inet4_details (NetstatusIface  *iface,
 				   char           **addr,
 				   char           **dest,
@@ -689,6 +764,7 @@ netstatus_iface_get_inet4_details (Netst
   struct ifreq if_req;
   int          fd;
   int          flags;
+  char	ad[INET_ADDRSTRLEN];
 
   if (addr)
     *addr = NULL;
Index: src/netstatus-iface.h
===================================================================
RCS file: /cvs/gnome/gnome-netstatus/src/netstatus-iface.h,v
retrieving revision 1.6
diff -u -p -r1.6 netstatus-iface.h
--- a/src/netstatus-iface.h	17 Mar 2004 23:41:09 -0000	1.6
+++ b/src/netstatus-iface.h	12 May 2004 13:14:40 -0000
@@ -86,6 +86,10 @@ gboolean               netstatus_iface_g
 							      char           **dest,
 							      char           **bcast,
 							      char           **mask);
+gboolean               netstatus_iface_get_inet6_details     (NetstatusIface  *iface,
+		                                              char           **addr,
+							      char           **scope);
+
 gboolean               netstatus_iface_get_device_details    (NetstatusIface  *iface,
 							      const char     **hw_name,
 							      char           **hw_addr);
