[2413] in Kerberos_V5_Development
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 */