[2413] in Kerberos_V5_Development

home help back first fref pref prev next nref lref last post

Re: Finding out interface addresses under Windows 95/NT

daemon@ATHENA.MIT.EDU (Theodore Y. Ts'o)
Fri Jul 4 00:16:56 1997

Date: Fri, 4 Jul 1997 00:16:07 -0400
From: "Theodore Y. Ts'o" <tytso@MIT.EDU>
To: Ken Hornstein <kenh@cmf.nrl.navy.mil>
Cc: krbdev@MIT.EDU
In-Reply-To: Ken Hornstein's message of Wed, 02 Jul 1997 23:02:18 -0400,
	<199707030302.XAA25981@ginger.cmf.nrl.navy.mil>

   Date: Wed, 02 Jul 1997 23:02:18 -0400
   From: Ken Hornstein <kenh@cmf.nrl.navy.mil>

   However, the root of the problem is that the version of krb5_os_localaddr()
   used for the win32 stuff (and for the Mac as well) uses DNS to determine
   the local IP address, and this is broken for many machines.  This also
   fails miserably for machines that come in via dialups with dynamic IP
   addresses assigned (because on those machines, the hostname doesn't exist
   in DNS 99% of the time).

The problem is that there's no stack-independent, portable way using
Winsock to find get this information directly.  Here's a patch which
uses a second method for trying to find the local IP address, although
we've heard some rumors that it might not work on some versions of Win32
networking stacks.   Let me know if this helps!

						- Ted

Index: ChangeLog
===================================================================
RCS file: /mit/krbdev/.cvsroot/src/lib/crypto/os/ChangeLog,v
retrieving revision 5.34
diff -u -r5.34 ChangeLog
--- ChangeLog	1997/02/23 07:28:37	5.34
+++ ChangeLog	1997/07/04 04:13:28
@@ -1,3 +1,9 @@
+Fri Jul  4 00:13:02 1997  Theodore Y. Ts'o  <tytso@mit.edu>
+
+	* c_localaddr.c (local_addr_fallback_kludge): Added Winsock
+	 	kludge for finding your local IP address.  May not work
+	 	for all stacks, so we use it as a fallback.
+	
 Sat Feb 22 18:54:53 1997  Richard Basch  <basch@lehman.com>
 
 	* Makefile.in: Use some of the new library list build rules in
Index: c_localaddr.c
===================================================================
RCS file: /mit/krbdev/.cvsroot/src/lib/crypto/os/c_localaddr.c,v
retrieving revision 5.8
diff -u -r5.8 c_localaddr.c
--- c_localaddr.c	1996/06/12 04:13:41	5.8
+++ c_localaddr.c	1997/07/04 04:12:59
@@ -241,10 +241,55 @@
 
 #else /* Windows/Mac version */
 
+/*
+ * Hold on to your lunch!  Backup kludge method of obtaining your
+ * local IP address, courtesy of Windows Socket Network Programming,
+ * by Robert Quinn
+ */
+#if defined(_MSDOS) || !defined(_WIN32)
+static struct hostent *local_addr_fallback_kludge()
+{
+	static struct hostent	host;
+	static SOCKADDR_IN	addr;
+	static char *		ip_ptrs[2];
+	SOCKET			sock;
+	int			size = sizeof(SOCKADDR);
+	int			err;
+
+	sock = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sock == INVALID_SOCKET)
+		return NULL;
+
+	/* connect to arbitrary port and address (NOT loopback) */
+	addr.sin_family = AF_INET;
+	addr.sin_port = htons(IPPORT_ECHO);
+	addr.sin_addr.s_addr = inet_addr("204.137.220.51");
+
+	err = connect(sock, (LPSOCKADDR) &addr, sizeof(SOCKADDR));
+	if (err == SOCKET_ERROR)
+		return NULL;
+
+	err = getsockname(sock, (LPSOCKADDR) &addr, (int FAR *) size);
+	if (err == SOCKET_ERROR)
+		return NULL;
+
+	closesocket(sock);
+
+	host.h_name = 0;
+	host.h_aliases = 0;
+	host.h_addrtype = AF_INET;
+	host.h_length = 4;
+	host.h_addr_list = ip_ptrs;
+	ip_ptrs[0] = (char *) &addr.sin_addr.s_addr;
+	ip_ptrs[1] = NULL;
+
+	return &host;
+}
+#endif
+
 /* No ioctls in winsock so we just assume there is only one networking 
  * card per machine, so gethostent is good enough. 
  */
-
 krb5_error_code
 krb5_crypto_os_localaddr (krb5_address ***addr) {
     char host[64];                              /* Name of local machine */
@@ -258,15 +303,23 @@
 #ifdef HAVE_MACSOCK_H
     hostrec = getmyipaddr();
 #else /* HAVE_MACSOCK_H */
+    err = 0;
+    
     if (gethostname (host, sizeof(host))) {
         err = WSAGetLastError();
-        return err;
     }
 
-    hostrec = gethostbyname (host);
-    if (hostrec == NULL) {
-        err = WSAGetLastError();
-        return err;
+    if (!err) {
+	    hostrec = gethostbyname (host);
+	    if (hostrec == NULL) {
+		    err = WSAGetLastError();
+	    }
+    }
+
+    if (err) {
+	    hostrec = local_addr_fallback_kludge();
+	    if (!hostrec)
+		    return err;
     }
 #endif /* HAVE_MACSOCK_H */
 


home help back first fref pref prev next nref lref last post