[sugar] [PATCH] Trac #34: IPv6 support for _get_local_ip_address.

Chris Ball cjb
Sun Sep 10 14:53:27 EDT 2006


Hi,

The sugar function _get_local_ip_address attempts to find the local IP
address by using the SIOCGIFADDR ioctl on the network interface.  This
will always provide an IPv4 address, regardless of which protocol is in
use; this patch modifies _get_local_ip_address to take protocol into
account, using SIOCGIFADDR for IPv4 and /proc/net/if_inet6 for IPv6.

The patch fixes the following error when sharing an activity over IPv6:

sugar-presence-service (6429): Level 10 - resolved service 'cjb [38a0b98587c1d8fb1ad29722a4f14f1f00f4e7b5]' type '_olpc_model._tcp' domain 'local' to fe80::213:d3ff:fe4e:5cb6:29989
sugar-presence-service (6429): Level 40 - Service source and buddy address doesn
't match: fe80::213:d3ff:fe4e:5cb6 None
sugar-presence-service (6429): Level 40 - Traceback (most recent call last):

  File "/home/cjb/cvs/sugar-jhbuild/build/share/sugar/shell/PresenceService/Pres
enceService.py", line 466, in _resolve_service_reply_cb
    self._handle_new_activity_service(service)
  File "/home/cjb/cvs/sugar-jhbuild/build/share/sugar/shell/PresenceService/PresenceService.py", line 410, in _handle_new_activity_service
    activity.add_service(service)
  File "/home/cjb/cvs/sugar-jhbuild/build/share/sugar/shell/PresenceService/Activity.py", line 146, in add_service
    buddies = self.get_joined_buddies()
  File "/home/cjb/cvs/sugar-jhbuild/build/share/sugar/shell/PresenceService/Activity.py", line 129, in get_joined_buddies
    if not owner in buddies and owner.is_valid():
AttributeError: 'NoneType' object has no attribute 'is_valid'

This is my first sugar patch, so please feel free to ask questions or
give feedback.  As mentioned in <http://dev.laptop.org/ticket/34>,
there may be more work needed to have sugar fully working under IPv6.

Thanks,

- Chris.

-------------- next part --------------
diff --git a/shell/PresenceService/PresenceService.py b/shell/PresenceService/PresenceService.py
index 56b54a3..27af5c6 100644
--- a/shell/PresenceService/PresenceService.py
+++ b/shell/PresenceService/PresenceService.py
@@ -8,22 +8,44 @@ from sugar import env
 from sugar import util
 
 
-def _get_local_ip_address(ifname):
+def _get_local_ip_address(ifname, protocol):
 	"""Call Linux specific bits to retrieve our own IP address."""
 	import socket
 	import sys
 	import fcntl
+	import struct
 
 	addr = None
-	SIOCGIFADDR = 0x8915
-	sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-	try:
-		ifreq = (ifname + '\0'*32)[:32]
-		result = fcntl.ioctl(sockfd.fileno(), SIOCGIFADDR, ifreq)
-		addr = socket.inet_ntoa(result[20:24])
-	except IOError, exc:
-		print "Error getting IP address: %s" % exc
-	sockfd.close()
+
+	if protocol == 0: # IPv4
+		SIOCGIFADDR = 0x8915
+		sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+		try:
+			ifreq = (ifname + '\0'*32)[:32]
+			result = fcntl.ioctl(sockfd.fileno(), SIOCGIFADDR, ifreq)
+			addr = socket.inet_ntoa(result[20:24])
+		except IOError, exc:
+			print "Error getting IPv4 address: %s" % exc
+		sockfd.close()
+	elif protocol == 1: # IPv6 
+		# Using an ioctl to get the current IP address only works for 
+		# IPv4; for IPv6, we use /proc/net/if_inet6. 
+		try:
+			f = open("/proc/net/if_inet6","r")
+		except IOError, exc:
+			print "Error getting IPv6 address: %s" % exc
+		for line in f.readlines():
+			# addr, index, plen, scope, flags, ifname
+			v6_list = line.split()
+			v6_ip = struct.unpack('4s4s4s4s4s4s4s4s', (v6_list[0]))
+			if v6_list[5] == ifname:
+				addr = ':'.join(v6_ip)
+			# Convert addr to a compressed address
+			addr = socket.inet_ntop(socket.AF_INET6, socket.inet_pton(socket.AF_INET6, addr))
+	else:
+		raise ValueError("Protocol not supported: %d" % protocol)
+	if not addr:
+		raise NotFoundError("IP address for interface %s not found" % ifname)	
 	return addr
 
 
@@ -497,7 +519,7 @@ class PresenceService(object):
 		if interface not in self._local_addrs.keys():
 			ifname = self._mdns_service.GetNetworkInterfaceNameByIndex(interface)
 			if ifname:
-				addr = _get_local_ip_address(ifname)
+				addr = _get_local_ip_address(ifname, protocol)
 				if addr:
 					self._local_addrs[interface] = addr
 
-------------- next part --------------
-- 
Chris Ball   <cjb at mrao.cam.ac.uk>    <http://blog.printf.net/>


More information about the Sugar-devel mailing list