[3988] in RedHat Linux List

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

Fix for broken talk (patch)

daemon@ATHENA.MIT.EDU (William E. Roadcap)
Mon Nov 11 22:47:53 1996

Date: Mon, 11 Nov 1996 22:44:03 -0500 (EST)
From: "William E. Roadcap" <roadcapw@cfw.com>
To: redhat-list@redhat.com
Resent-From: redhat-list@redhat.com
Reply-To: redhat-list@redhat.com

For those of you experiencing a problem with talk in 4.0, here is a patch
that corrected the problem for me.  You will need to install the SRPMS for
NetKit-B and recompile talk of course.

In the NetKit-B source tree, I found a Linux specific patch for talk that
wasn't applied by RedHat.  Maybe they had a good reason, I don't know. 
Anyhow, it didn't apply right off, so I had to doctor it a bit.  This is a
POST doctoring diff.

I'd like to stress that this is NOT my code, but a new diff based on an
existing patch in the NetKit-B source tree.

Hope this helps someone.

....................................[snip]............................

--- ./get_addrs.c.orig	Mon Nov 11 22:31:47 1996
+++ ./get_addrs.c	Mon Nov 11 22:33:31 1996
@@ -48,11 +48,33 @@
 #include "talk.h"
 #include "talk_ctl.h"
 
+/*
+ * Hah.  BSD folks may have thought too simple on this one.
+ * If you are a multihomed host, this program will miserably fail,
+ * as it will use the IP address of "hostname" as the source of the
+ * messages, not the address of the interface over which the packet
+ * will be routed.
+ *
+ * With Linux NET-2E, a possible solution is to perform an UDP CONNECT
+ * operation on a socket, so the kernel sets the correct source address
+ * of the socket's packets.  Then we do a getsockname on that socket,
+ * and voila... we have the correct source address!
+ *
+ * Note that this only works with NET-2E BETA-4 and newer kernels.
+ */
 void
 get_addrs(char *my_machine_name, char *his_machine_name)
 {
 	struct hostent *hp;
 	struct servent *sp;
+#ifdef __linux__
+       struct sockaddr_in sin;
+       struct sockaddr_in foo;
+       int sock, i;
+
+       /* If socket fails, code will see it. */
+       sock = socket(AF_INET, SOCK_DGRAM, 0);
+#endif
 
 	msg.pid = htonl(getpid());
 	/* look up the address of the local host */
@@ -85,6 +107,24 @@
 		exit(-1);
 	}
 	daemon_port = sp->s_port;
+#ifdef __linux__
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = his_machine_addr.s_addr;
+	sin.sin_port = sp->s_port;
+
+	/* Now here is the trick.  We connect to the other side. */
+	if ((sock >= 0) &&
+	    (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) == 0)) {
+		/* Bingo.  Now fetch the address. */
+		foo = sin;
+		i = sizeof(foo);
+		if (getsockname(sock, (struct sockaddr *) &foo, &i) == 0) {
+			my_machine_addr = foo.sin_addr;
+		}
+	}
+	/* Loose the socket. */
+	(void) close(sock);
+#endif
 #ifdef	BAD_LINUX_HACK
 	/* now some hacking to get my own address correctly routed */
 	{

__
William E. Roadcap                            mailto:roadcapw@cfw.com
TITUS Software                                   ftp://titus.cfw.com/pub
Waynesboro, Va (USA)                            http://www.cfw.com/~roadcapw



--
  PLEASE read the Red Hat FAQ, Tips, Errata and the MAILING LIST ARCHIVES!
  ________________________________________________________________________
  http://www.redhat.com/RedHat-FAQ   http://www.redhat.com/RedHat-Errata
  http://www.redhat.com/RedHat-Tips  http://www.redhat.com/mailing-lists
  ------------------------------------------------------------------------
To unsubscribe: mail -s unsubscribe redhat-list-request@redhat.com < /dev/null


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