PATCH: Fix and simplify get_netid()



Hi,

The linc2/src/linc-protocols.c:get_netid() function produced nonsense values for ORBNetID="ipaddr" on Mac OS X Leopard. Please see:

   http://bugzilla.gnome.org/show_bug.cgi?id=539510


The patch below fixes this and makes for a simpler get_netid() bu introducing a new helper function. The patch has been tested on Leopard and Ubuntu Gutsy. "make check" is also happy on both platforms. Please forgive me if the patch below is whitespace-messed- up. My current mailer isn't too happy about inserted text...

May I commit? Comments?

Best regards,
  jules




Index: linc2/ChangeLog
===================================================================
--- linc2/ChangeLog	(revision 2073)
+++ linc2/ChangeLog	(working copy)
@@ -1,3 +1,13 @@
+2008-06-21  Jules Colding  <colding 42tools com>
+
+	* src/linc-protocols.c (get_netid): This function
+	failed on Mac OS X for (ORBNetID == "ipaddr"). It is
+	now fixed and simplified greatly by the use of the new
+	function get_first_non_local_ipaddr().
+	(get_first_non_local_ipaddr):  This function will
+	correctly deduce the first non-loopback interface
+	on the host.
+
 ============================== 2.14.13 ===========================

 2008-05-25  Tor Lillqvist  <tml novell com>
Index: linc2/src/linc-protocols.c
===================================================================
--- linc2/src/linc-protocols.c	(revision 2073)
+++ linc2/src/linc-protocols.c	(working copy)
@@ -145,7 +145,49 @@
 #endif
 #define DEFAULT_LINC2_IFNUM (32)

+#ifndef G_OS_WIN32
 static char *
+get_first_non_local_ipaddr(char *buf,
+			   size_t len)
+{
+	int sock;
+	const char *retv;
+	struct if_nameindex *ifname_idx_array;
+	struct if_nameindex *ifname_idx;
+	struct ifreq ifr;
+	struct sockaddr_in sin;
+
+	*buf = '\0';
+
+	sock = socket(AF_INET, SOCK_DGRAM, 0);
+	if (-1 == sock)
+		return;
+
+	ifname_idx_array = if_nameindex();
+ for (ifname_idx = ifname_idx_array; ifname_idx && ifname_idx- >if_name && ifname_idx->if_name[0]; ifname_idx++) {
+		strncpy(ifr.ifr_name, ifname_idx->if_name, IFNAMSIZ);
+		if (!ioctl(sock, SIOCGIFADDR, &ifr)) {
+			memcpy(&sin, &(ifr.ifr_addr), sizeof(struct sockaddr_in));
+			retv = (const char*)inet_ntoa(sin.sin_addr);
+			retv = strcmp("127.0.0.1", retv) ? retv : NULL;
+			if (retv) {
+				strncpy(buf, (const char*)inet_ntoa(sin.sin_addr), len);
+				break;
+			}
+		}
+	}
+
+	if (ifname_idx_array)
+		if_freenameindex(ifname_idx_array);
+
+	if (-1 != sock)
+		close(sock);
+
+	return buf;
+}
+#endif
+
+static char *
 get_netid(LinkNetIdType which,
 	  char *buf,
 	  size_t len)
@@ -161,58 +203,13 @@
 	if ((LINK_NET_ID_IS_IPADDR == which)
 	    || (LINK_NET_ID_IS_CUSTOM == which)) {
 #ifndef G_OS_WIN32
-		struct sockaddr_in *adr = NULL;
-		struct ifreq *my_ifreqs = NULL;
-		struct ifconf my_ifconf = { 0 };
-		int sock = -1;
-		int num = 0;
-		int i = 0;
+		if (fixed_host_net_id)
+			strncpy(buf, fixed_host_net_id, len);
+		else
+			get_first_non_local_ipaddr(buf, len);
+		if ('\0' == *buf)
+			strncpy(buf, "127.0.0.1", len);

-		sock = socket(AF_INET,SOCK_DGRAM,0);
-		if (-1 == sock)
-			goto out;
-#ifdef SIOCGIFNUM
-		i = ioctl(sock, SIOCGIFNUM, &num);
-		if ((0 > i) || !num) {
-			close(sock);
-			goto out;
-		}
-#else
-		num = DEFAULT_LINC2_IFNUM;
-#endif
-		my_ifconf.ifc_len = sizeof(struct ifreq) * num;
-		my_ifconf.ifc_req = (struct ifreq*)malloc(my_ifconf.ifc_len);
-		if (!my_ifconf.ifc_req) {
-			close(sock);
-			goto out;
-		}
-		if (ioctl(sock,SIOCGIFCONF,&my_ifconf) < 0) {
-			close(sock);
-			free(my_ifconf.ifc_req);
-			goto out;
-		}
-		close(sock);
-
-		my_ifreqs = my_ifconf.ifc_req;
- 		for (i = 0; i < num; i++) {
-			adr = (struct sockaddr_in *)&my_ifreqs[i].ifr_ifru.ifru_addr;
-			if (fixed_host_net_id) {
-				if (!strcmp(fixed_host_net_id, inet_ntoa(adr->sin_addr)))
-					break;
-			} else {
-				if (strcmp("127.0.0.1", inet_ntoa(adr->sin_addr)))
-					break;
-			}
-			if (!strcmp("0.0.0.0", inet_ntoa(adr->sin_addr))) {
-				if (i)
-					adr = (struct sockaddr_in *)&my_ifreqs[--i].ifr_ifru.ifru_addr;
-				break;
-			}
-		}
-		strncpy(buf, (const char*)inet_ntoa(adr->sin_addr), len);
-		free(my_ifconf.ifc_req);
-
-		/* will be 127.0.0.1 anyway, if no other address is defined... */
 		return buf;
 #else
 		SOCKET sock;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]