[3988] in RedHat Linux List
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