Oops, I sent the last message without including the patch. Here we go again: In case you haven't noticed, ytalk (and ntalk) doesn't behave nicely when there are multiple network interfaces. The connection request packet has to contain the IP address to reply to, and ytalk guess this by looking at the hostname. This doesn't always work -- for example, if the hostname is bound to a loopback device or to, say, the ethernet device and you want to talk over ppp. The most convienant thing would be for ytalk to check how the packets get routed to the destination machine to figure out the right source address to use, but this appears to be tricky to do in a portable fashion. So, I did the simplest thing and added a new -I option (just like the -i option for traceroute) which takes a net interface name as the argument. You can also set this in the ytalkrc. This patch should be applied against the source in ytalk-3.0.3-2.src.rpm in the redhat 5.0 distribution after applying both patches included in that rpm. I haven't gotten around to doing the same to ntalk. diff -crN ytalk-3.0.3-8bit/Imakefile ytalk-3.0.3-8bit.new/Imakefile *** ytalk-3.0.3-8bit/Imakefile Wed Mar 25 13:42:59 1998 --- ytalk-3.0.3-8bit.new/Imakefile Wed Mar 25 13:04:40 1998 *************** *** 62,67 **** --- 62,72 ---- EBCDEFS = -DEIGHT_BIT_CLEAN + # If you system has sys/sockio.h, set this. Needed for solaris, not needed + # for linux. + + # SYSIODEFS = -DHAVE_SYS_SOCKIO_H + # # If you have (or want) a system-wide .ytalkrc file, uncomment the # next line and set it to the correct pathname. The backslashes must *************** *** 85,98 **** ## Past this point, you shouldn't need to modify anything ## ############################################################ LIB = -lncurses -ltermcap $(SLIBS) $(XLIB) ! DEFINES = -DUSE_X11 -I/usr/include/ncurses $(DEBCFLAGS) $(TDEFS) $(BDEFS) $(RCDEF) $(VDEFS) \ $(PDEFS) $(EBCDEFS) -O LDFLAGS = $(LDOPTIONS) OBJ = main.o term.o user.o fd.o comm.o menu.o socket.o rc.o exec.o cwin.o \ ! xwin.o PRG = ytalk ! all: $(PRG) ytalk.cat $(PRG): $(OBJ) $(CC) $(LDFLAGS) -o $(PRG) $(OBJ) $(LIB) --- 90,103 ---- ## Past this point, you shouldn't need to modify anything ## ############################################################ LIB = -lncurses -ltermcap $(SLIBS) $(XLIB) ! DEFINES = -DUSE_X11 -I/usr/include/ncurses $(DEBCFLAGS) $(TDEFS) $(BDEFS) $(RCDEF) $(VDEFS) $(SYSIODEFS) \ $(PDEFS) $(EBCDEFS) -O LDFLAGS = $(LDOPTIONS) OBJ = main.o term.o user.o fd.o comm.o menu.o socket.o rc.o exec.o cwin.o \ ! xwin.o ifaddrlist.o PRG = ytalk ! all:: $(PRG) ytalk.cat $(PRG): $(OBJ) $(CC) $(LDFLAGS) -o $(PRG) $(OBJ) $(LIB) diff -crN ytalk-3.0.3-8bit/header.h ytalk-3.0.3-8bit.new/header.h *** ytalk-3.0.3-8bit/header.h Wed Mar 25 13:42:55 1998 --- ytalk-3.0.3-8bit.new/header.h Wed Mar 25 13:56:48 1998 *************** *** 237,242 **** --- 237,243 ---- extern char *sys_errlist[]; /* system errors */ #endif + extern char *net_iface; /* my source net iface */ extern yuser *me; /* just lil' ol' me */ extern yuser *user_list; /* full list of invited/connected users */ extern yuser *connect_list; /* list of connected users */ *************** *** 304,310 **** extern void set_cooked_term (); /* term.c */ extern int term_does_asides(); /* term.c */ ! extern void init_user (); /* user.c */ extern yuser *new_user ( /* name, host, tty */ ); /* user.c */ extern void free_user ( /* yuser */ ); /* user.c */ extern yuser *find_user ( /* name, host_addr, pid */ ); /* user.c */ --- 305,311 ---- extern void set_cooked_term (); /* term.c */ extern int term_does_asides(); /* term.c */ ! extern void init_user ( ); /* user.c */ extern yuser *new_user ( /* name, host, tty */ ); /* user.c */ extern void free_user ( /* yuser */ ); /* user.c */ extern yuser *find_user ( /* name, host_addr, pid */ ); /* user.c */ diff -crN ytalk-3.0.3-8bit/ifaddrlist.c ytalk-3.0.3-8bit.new/ifaddrlist.c *** ytalk-3.0.3-8bit/ifaddrlist.c Wed Dec 31 17:00:00 1969 --- ytalk-3.0.3-8bit.new/ifaddrlist.c Wed Mar 25 13:00:22 1998 *************** *** 0 **** --- 1,200 ---- + /* This file is taken from the traceroute 1.4a5 sources with minor changes. + -- [EMAIL PROTECTED] */ + + /* + * Copyright (c) 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef lint + static const char rcsid[] = + "@(#) $Header: ifaddrlist.c,v 1.2 97/04/22 13:31:05 leres Exp $ (LBL)"; + #endif + + #include <sys/param.h> + #include <sys/file.h> + #include <sys/ioctl.h> + #include <sys/socket.h> + #ifdef HAVE_SYS_SOCKIO_H + #include <sys/sockio.h> + #endif + #include <sys/time.h> /* concession to AIX */ + + #if __STDC__ + struct mbuf; + struct rtentry; + #endif + + #include <net/if.h> + #include <netinet/in.h> + + #include <ctype.h> + #include <errno.h> + #include <memory.h> + #include <stdio.h> + #include <stdlib.h> + #include <string.h> + #include <unistd.h> + + #ifdef HAVE_OS_PROTO_H + #include "os-proto.h" + #endif + + #include "ifaddrlist.h" + + + /* Not all systems have IFF_LOOPBACK */ + #ifdef IFF_LOOPBACK + #define ISLOOPBACK(p) ((p)->ifr_flags & IFF_LOOPBACK) + #else + #define ISLOOPBACK(p) (strcmp((p)->ifr_name, "lo0") == 0) + #endif + + #define MAX_IPADDR 32 + + /* A replacement for strdup() that cuts down on malloc() overhead */ + char * + savestr(register const char *str) + { + register u_int size; + register char *p; + static char *strptr = NULL; + static u_int strsize = 0; + + size = strlen(str) + 1; + if (size > strsize) { + strsize = 1024; + if (strsize < size) + strsize = size; + strptr = (char *)malloc(strsize); + if (strptr == NULL) { + fprintf(stderr, "savestr: malloc\n"); + exit(1); + } + } + (void)strcpy(strptr, str); + p = strptr; + strptr += size; + strsize -= size; + return (p); + } + + /* + * Return the interface list + */ + int + ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf) + { + register int fd, nipaddr; + #ifdef HAVE_SOCKADDR_SA_LEN + register int n; + #endif + register struct ifreq *ifrp, *ifend, *ifnext, *mp; + register struct sockaddr_in *sin; + register struct ifaddrlist *al; + struct ifconf ifc; + struct ifreq ibuf[MAX_IPADDR], ifr; + char device[sizeof(ifr.ifr_name) + 1]; + static struct ifaddrlist ifaddrlist[MAX_IPADDR]; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + (void)sprintf(errbuf, "socket: %s", strerror(errno)); + return (-1); + } + ifc.ifc_len = sizeof(ibuf); + ifc.ifc_buf = (caddr_t)ibuf; + + if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 || + ifc.ifc_len < sizeof(struct ifreq)) { + (void)sprintf(errbuf, "SIOCGIFCONF: %s", strerror(errno)); + (void)close(fd); + return (-1); + } + ifrp = ibuf; + ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len); + + al = ifaddrlist; + mp = NULL; + nipaddr = 0; + for (; ifrp < ifend; ifrp = ifnext) { + #ifdef HAVE_SOCKADDR_SA_LEN + n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name); + if (n < sizeof(*ifrp)) + ifnext = ifrp + 1; + else + ifnext = (struct ifreq *)((char *)ifrp + n); + if (ifrp->ifr_addr.sa_family != AF_INET) + continue; + #else + ifnext = ifrp + 1; + #endif + /* + * Need a template to preserve address info that is + * used below to locate the next entry. (Otherwise, + * SIOCGIFFLAGS stomps over it because the requests + * are returned in a union.) + */ + strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name)); + if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { + if (errno == ENXIO) + continue; + (void)sprintf(errbuf, "SIOCGIFFLAGS: %.*s: %s", + (int)sizeof(ifr.ifr_name), ifr.ifr_name, + strerror(errno)); + (void)close(fd); + return (-1); + } + + /* Must be up and not the loopback */ + if ((ifr.ifr_flags & IFF_UP) == 0 || ISLOOPBACK(&ifr)) + continue; + + (void)strncpy(device, ifr.ifr_name, sizeof(ifr.ifr_name)); + device[sizeof(device) - 1] = '\0'; + if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { + (void)sprintf(errbuf, "SIOCGIFADDR: %s: %s", + device, strerror(errno)); + (void)close(fd); + return (-1); + } + + sin = (struct sockaddr_in *)&ifr.ifr_addr; + al->addr = sin->sin_addr; + al->device = savestr(device); + ++al; + ++nipaddr; + } + (void)close(fd); + + *ipaddrp = ifaddrlist; + return (nipaddr); + } diff -crN ytalk-3.0.3-8bit/ifaddrlist.h ytalk-3.0.3-8bit.new/ifaddrlist.h *** ytalk-3.0.3-8bit/ifaddrlist.h Wed Dec 31 17:00:00 1969 --- ytalk-3.0.3-8bit.new/ifaddrlist.h Wed Mar 25 13:00:22 1998 *************** *** 0 **** --- 1,35 ---- + /* This file is taken from the traceroute 1.4a5 sources with minor changes. + -- [EMAIL PROTECTED] */ + + /* + * Copyright (c) 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: traceroute.h,v 1.1 97/01/04 19:33:33 leres Locked $ (LBL) + */ + + #include <sys/types.h> + #include <netinet/in.h> + + struct ifaddrlist { + struct in_addr addr; + char *device; + }; + + int ifaddrlist(struct ifaddrlist **, char *); diff -crN ytalk-3.0.3-8bit/main.c ytalk-3.0.3-8bit.new/main.c *** ytalk-3.0.3-8bit/main.c Mon Nov 11 09:25:00 1996 --- ytalk-3.0.3-8bit.new/main.c Wed Mar 25 13:54:53 1998 *************** *** 134,140 **** int argc; char **argv; { ! int xflg = 0, sflg = 0, yflg = 0, iflg = 0; char *prog; /* check for a 64-bit mis-compile */ --- 134,140 ---- int argc; char **argv; { ! int xflg = 0, sflg = 0, yflg = 0, iflg = 0, Iflg = 0; char *prog; /* check for a 64-bit mis-compile */ *************** *** 193,198 **** --- 193,203 ---- sflg++; /* immediately start a shell */ argv++, argc--; } + else if (strcmp(*argv, "-I") == 0) { + Iflg++; + net_iface = argv[1]; + argv += 2, argc -= 2; + } else argc = 0; /* force a Usage error */ } *************** *** 204,209 **** --- 209,215 ---- fprintf(stderr, "Usage: %s [options] user[@host][#tty]...\n\ Options: -i -- no auto-invite port\n\ + -I iface -- use network interface iface\n\ -x -- do not use the X interface\n\ -Y -- require caps on all y/n answers\n\ -s -- start a shell\n", prog); *************** *** 225,232 **** errno = 0; init_fd(); - init_user(); read_ytalkrc(); if(xflg) def_flags &= ~FL_XWIN; if(yflg) --- 231,238 ---- errno = 0; init_fd(); read_ytalkrc(); + init_user(net_iface); if(xflg) def_flags &= ~FL_XWIN; if(yflg) diff -crN ytalk-3.0.3-8bit/rc.c ytalk-3.0.3-8bit.new/rc.c *** ytalk-3.0.3-8bit/rc.c Mon Nov 11 09:25:20 1996 --- ytalk-3.0.3-8bit.new/rc.c Wed Mar 25 13:59:50 1998 *************** *** 165,170 **** --- 165,175 ---- } readdress_host(arg1, arg2, arg3); } + else if (strcmp (w, "iface") == 0) + { + if (net_iface == NULL) + net_iface = strdup (get_word (&ptr)); + } else if(strcmp(w, "set") == 0 || strcmp(w, "turn") == 0) { arg1 = get_word(&ptr); diff -crN ytalk-3.0.3-8bit/user.c ytalk-3.0.3-8bit.new/user.c *** ytalk-3.0.3-8bit/user.c Thu Feb 1 17:46:37 1996 --- ytalk-3.0.3-8bit.new/user.c Wed Mar 25 13:55:02 1998 *************** *** 18,27 **** --- 18,29 ---- #include "header.h" #include "menu.h" + #include "ifaddrlist.h" #include <pwd.h> extern char *getlogin(); + char *net_iface = NULL; /* my source net iface */ yuser *me; /* my user information */ yuser *user_list; /* list of invited/connected users */ yuser *connect_list; /* list of connected users */ *************** *** 158,169 **** bail(YTE_ERROR); } ! /* get my hostname */ ! ! if(gethostname(my_host, 100) < 0) ! { show_error("init_user: gethostname() failed"); bail(YTE_ERROR); } /* get my user record */ --- 160,200 ---- bail(YTE_ERROR); } ! if (net_iface == NULL) { ! /* get my hostname */ ! ! if(gethostname(my_host, 100) < 0) ! { show_error("init_user: gethostname() failed"); bail(YTE_ERROR); + } + } + else { + struct ifaddrlist *al; + int i, n, found = 0; + char errbuf[132]; + + n = ifaddrlist(&al, errbuf); + if (n < 0) { + show_error ("init_user: error resolving network interface"); + bail (YTE_ERROR); + } + if (n == 0) { + show_error ("init_user: no network interfaces found"); + bail (YTE_ERROR); + } + for (i = 0; i < n; i++) { + if (!strcmp (al[i].device, net_iface)) { + strncpy (my_host, inet_ntoa (al[i].addr), sizeof (my_host)); + found = 1; + break; + } + } + if (!found) { + show_error ("init_user: couldn't find requested " + "network interface"); + bail (YTE_ERROR); + } } /* get my user record */ diff -crN ytalk-3.0.3-8bit/ytalk.1 ytalk-3.0.3-8bit.new/ytalk.1 *** ytalk-3.0.3-8bit/ytalk.1 Mon Nov 11 09:28:30 1996 --- ytalk-3.0.3-8bit.new/ytalk.1 Wed Mar 25 14:07:02 1998 *************** *** 12,18 **** .SH NAME ytalk - A multi-user chat program. .SH SYNOPSIS ! ytalk [-x] [-s] [-Y] [-i] username... .SH DESCRIPTION .I YTalk V3.0 Patch Level 2 .PP --- 12,18 ---- .SH NAME ytalk - A multi-user chat program. .SH SYNOPSIS ! ytalk [-x] [-s] [-Y] [-i] [-I iface] username... .SH DESCRIPTION .I YTalk V3.0 Patch Level 2 .PP *************** *** 47,52 **** --- 47,56 ---- The -i option disables the auto-invite port (meaning you won't see "talk to [EMAIL PROTECTED]", but your talk daemon will beep you instead). .PP + The -I option specifies the network interface to obtain the source IP + address for outgoing packets. This is normally only useful for a multi-homed + host. + .PP The -Y option requires a capital Y or N as an answer to any yes/no question. .PP *************** *** 242,247 **** --- 246,273 ---- For example, one could enable word-wrap with the line: .sp turn word-wrap on + .Sh "SETTING SOURCE INTERFACE" + When ytalk sends a connection request message to the server, it needs to + include a reply IP address. Usually, it can correctly determine this address + from the hostname. However, on machines with multiple network interfaces, this + will not always work. In this case, ytalk needs to be told the correct + network interface to use. The syntax of the iface command is: + .sp + iface + .I interface + .PP + The + .I interface + argument should be one of the network interfaces listed by the ifconfig + program. For example, setting: + .sp + iface ppp0 + .PP + tells ytalk to use the IP address bound to the first ppp device, and: + .sp + iface eth0 + .PP + tells ytalk to use the the IP address bound to the first ethernet device. .Sh "SETTING RE-ADDRESS MODES" The purpose of readdressing is to allow Ytalk connections across point-to-point network gateways where the local machines know themselves -- PLEASE read the Red Hat FAQ, Tips, Errata and the MAILING LIST ARCHIVES! http://www.redhat.com/RedHat-FAQ /RedHat-Errata /RedHat-Tips /mailing-lists To unsubscribe: mail [EMAIL PROTECTED] with "unsubscribe" as the Subject.