mkhosts and multiple addresses per host

Steven M. Schultz sms at wlv.imsd.contel.com
Fri Oct 6 09:05:13 AEST 1989


Subject: mkhosts and multiple addresses per host
Index:	etc/mkhosts.c 2.10BSD

Description:
	The /etc/mkhosts program does not correctly handle the
	case where a host has more than one address - only the
	first is returned when a gethostbyaddr() is performed.

Repeat-By:
	Do a gethostbyname() on a host with multiple addresses, print the
	addresses returned in h_addr_list, note there will be only one.

Fix:
	Apply the patches below to mkhosts.c and gethnamadr.c, replace
	gethnamadr.o in libc.a and libc_p.a, recompile mkhosts.c and
	install in /etc.

	The changes below to /etc/mkhosts program and the gethnamadr.c
	module of the C library will cause the array h_addr_list
	to be filled in with up to 10 addresses for a host.  The
	order that the entries are in the text file being scanned
	IS preserved.

	The new dbm files ARE COMPATIBLE with old binaries, the old
	programs will continue to only be returned a single address.
	Programs relinked with the new library module will receive
	the list of addresses for a host.

	There are two patch files, the first is applied to 
	/usr/src/lib/libc/net/hosttable/gethnamadr.c, the 
	second to /usr/src/etc/mkhosts.c.  A test program x.c
	is included to use in testing the new hosts database.

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	patch1
#	patch2
#	x.c
# This archive created: Thu Oct  5 18:47:25 1989
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'patch1'
then
	echo shar: "will not over-write existing file 'patch1'"
else
sed 's/^X//' << \SHAR_EOF > 'patch1'
X*** gethnamadr.old	Tue Aug 23 14:45:14 1988
X--- gethnamadr.c	Thu Oct  5 17:18:17 1989
X***************
X*** 16,26 ****
X  #include <ctype.h>
X  
X  #define	MAXALIASES	35
X  
X  static struct hostent host;
X  static char *host_aliases[MAXALIASES];
X! static char hostbuf[256+1];
X! static char *host_addrs[2];
X  
X  int h_errno;
X  
X--- 16,26 ----
X  #include <ctype.h>
X  
X  #define	MAXALIASES	35
X+ #define	MAXADDRS	10
X  
X  static struct hostent host;
X  static char *host_aliases[MAXALIASES];
X! static char *host_addrs[MAXADDRS];
X  
X  int h_errno;
X  
X***************
X*** 35,41 ****
X  fetchhost(key)
X  	datum key;
X  {
X!         register char *cp, *tp, **ap;
X  	int naliases;
X  
X          if (key.dptr == 0)
X--- 35,42 ----
X  fetchhost(key)
X  	datum key;
X  {
X!         register char *cp, **ap;
X! 	register int naddrs;
X  	int naliases;
X  
X          if (key.dptr == 0)
X***************
X*** 44,57 ****
X  	if (key.dptr == 0)
X                  return ((struct hostent *)NULL);
X          cp = key.dptr;
X! 	tp = hostbuf;
X! 	host.h_name = tp;
X! 	while (*tp++ = *cp++)
X  		;
X  	bcopy(cp, (char *)&naliases, sizeof(int)); cp += sizeof (int);
X  	for (ap = host_aliases; naliases > 0; naliases--) {
X! 		*ap++ = tp;
X! 		while (*tp++ = *cp++)
X  			;
X  	}
X  	*ap = (char *)NULL;
X--- 45,57 ----
X  	if (key.dptr == 0)
X                  return ((struct hostent *)NULL);
X          cp = key.dptr;
X! 	host.h_name = cp;
X! 	while (*cp++)
X  		;
X  	bcopy(cp, (char *)&naliases, sizeof(int)); cp += sizeof (int);
X  	for (ap = host_aliases; naliases > 0; naliases--) {
X! 		*ap++ = cp;
X! 		while (*cp++)
X  			;
X  	}
X  	*ap = (char *)NULL;
X***************
X*** 61,68 ****
X  	bcopy(cp, (char *)&host.h_length, sizeof (int));
X  	cp += sizeof (int);
X  	host.h_addr_list = host_addrs;
X! 	host.h_addr = tp;
X! 	bcopy(cp, tp, host.h_length);
X          return (&host);
X  }
X  
X--- 61,74 ----
X  	bcopy(cp, (char *)&host.h_length, sizeof (int));
X  	cp += sizeof (int);
X  	host.h_addr_list = host_addrs;
X! 	naddrs = (key.dsize - (cp - key.dptr)) / host.h_length;
X! 	if (naddrs > MAXADDRS)
X! 		naddrs = MAXADDRS;
X! 	for (ap = host_addrs; naddrs; naddrs--) {
X! 		*ap++ = cp;
X! 		cp += host.h_length;
X! 	}
X! 	*ap = (char *)NULL;
X          return (&host);
X  }
X  
SHAR_EOF
fi
if test -f 'patch2'
then
	echo shar: "will not over-write existing file 'patch2'"
else
sed 's/^X//' << \SHAR_EOF > 'patch2'
X*** mkhosts.c.old	Sun Feb 15 23:51:18 1987
X--- mkhosts.c	Thu Oct  5 17:17:40 1989
X***************
X*** 11,17 ****
X  #endif not lint
X  
X  #ifndef lint
X! static char sccsid[] = "@(#)mkhosts.c	5.1 (Berkeley) 5/28/85";
X  #endif not lint
X  
X  #include <sys/file.h>
X--- 11,18 ----
X  #endif not lint
X  
X  #ifndef lint
X! /* static char sccsid[] = "@(#)mkhosts.c	5.1 (Berkeley) 5/28/85"; */
X! static char sccsid[] = "@(#)mkhosts.c	1.1 (2.10BSD) 10/04/89";
X  #endif not lint
X  
X  #include <sys/file.h>
X***************
X*** 26,35 ****
X  {
X  	DBM *dp;
X  	register struct hostent *hp;
X  	datum key, content;
X  	register char *cp, *tp, **sp;
X  	register int *nap;
X! 	int naliases;
X  	int verbose = 0, entries = 0, maxlen = 0, error = 0;
X  	char tempname[BUFSIZ], newname[BUFSIZ];
X  
X--- 27,37 ----
X  {
X  	DBM *dp;
X  	register struct hostent *hp;
X+ 	struct hostent *hp2;
X  	datum key, content;
X  	register char *cp, *tp, **sp;
X  	register int *nap;
X! 	int naliases, naddrs;
X  	int verbose = 0, entries = 0, maxlen = 0, error = 0;
X  	char tempname[BUFSIZ], newname[BUFSIZ];
X  
X***************
X*** 63,68 ****
X--- 65,77 ----
X  			;
X  		nap = (int *)cp;
X  		cp += sizeof (int);
X+ 		key.dptr = hp->h_name;
X+ 		key.dsize = strlen(hp->h_name);
X+ 		hp2 = (struct hostent *)fetchhost(dp, key);
X+ 		if (hp2) {
X+ 			merge(hp, hp2);
X+ 			hp = hp2;
X+ 		}
X  		naliases = 0;
X  		for (sp = hp->h_aliases; *sp; sp++) {
X  			tp = *sp;
X***************
X*** 75,89 ****
X  		cp += sizeof (int);
X  		bcopy((char *)&hp->h_length, cp, sizeof (int));
X  		cp += sizeof (int);
X! 		bcopy(hp->h_addr, cp, hp->h_length);
X! 		cp += hp->h_length;
X  		content.dptr = buf;
X  		content.dsize = cp - buf;
X  		if (verbose)
X! 			printf("store %s, %d aliases\n", hp->h_name, naliases);
X! 		key.dptr = hp->h_name;
X! 		key.dsize = strlen(hp->h_name);
X! 		if (dbm_store(dp, key, content, DBM_INSERT) < 0) {
X  			perror(hp->h_name);
X  			goto err;
X  		}
X--- 84,99 ----
X  		cp += sizeof (int);
X  		bcopy((char *)&hp->h_length, cp, sizeof (int));
X  		cp += sizeof (int);
X! 		for (naddrs = 0, sp = hp->h_addr_list; *sp; sp++) {
X! 			bcopy(*sp, cp, hp->h_length);
X! 			cp += hp->h_length;
X! 			naddrs++;
X! 		}
X  		content.dptr = buf;
X  		content.dsize = cp - buf;
X  		if (verbose)
X! 			printf("store %s, %d aliases %d addresses\n", hp->h_name, naliases, naddrs);
X! 		if (dbm_store(dp, key, content, DBM_REPLACE) < 0) {
X  			perror(hp->h_name);
X  			goto err;
X  		}
X***************
X*** 90,105 ****
X  		for (sp = hp->h_aliases; *sp; sp++) {
X  			key.dptr = *sp;
X  			key.dsize = strlen(*sp);
X! 			if (dbm_store(dp, key, content, DBM_INSERT) < 0) {
X  				perror(*sp);
X  				goto err;
X  			}
X  		}
X! 		key.dptr = hp->h_addr;
X! 		key.dsize = hp->h_length;
X! 		if (dbm_store(dp, key, content, DBM_INSERT) < 0) {
X! 			perror("dbm_store host address");
X! 			goto err;
X  		}
X  		entries++;
X  		if (cp - buf > maxlen)
X--- 100,117 ----
X  		for (sp = hp->h_aliases; *sp; sp++) {
X  			key.dptr = *sp;
X  			key.dsize = strlen(*sp);
X! 			if (dbm_store(dp, key, content, DBM_REPLACE) < 0) {
X  				perror(*sp);
X  				goto err;
X  			}
X  		}
X! 		for (sp = hp->h_addr_list; *sp; sp++) {
X! 			key.dptr = *sp;
X! 			key.dsize = hp->h_length;
X! 			if (dbm_store(dp, key, content, DBM_REPLACE) < 0) {
X! 				perror("dbm_store host address");
X! 				goto err;
X! 			}
X  		}
X  		entries++;
X  		if (cp - buf > maxlen)
X***************
X*** 128,131 ****
X--- 140,233 ----
X  	sprintf(tempname, "%s.new.dir", argv[1]);
X  	unlink(tempname);
X  	exit(1);
X+ }
X+ 
X+ /* following code lifted from libc/net/hosttable/gethnamadr.c */
X+ 
X+ #define	MAXALIASES	35
X+ #define	MAXADDRS	10
X+ 
X+ static	struct	hostent	host2;
X+ static	char	*hstaliases[MAXALIASES];
X+ static	char	*hstaddrs[MAXADDRS];
X+ static	char	buf2[BUFSIZ];
X+ 
X+ static struct hostent *
X+ fetchhost(dp, key)
X+ 	DBM	*dp;
X+ 	datum key;
X+ {
X+         register char *cp, **ap;
X+ 	register int naddrs;
X+ 	int naliases;
X+ 
X+ 	key = dbm_fetch(dp, key);
X+ 	if (key.dptr == 0)
X+                 return ((struct hostent *)NULL);
X+ 	bcopy(key.dptr, buf2, key.dsize);
X+         cp = buf2;
X+ 	host2.h_name = cp;
X+ 	while (*cp++)
X+ 		;
X+ 	bcopy(cp, (char *)&naliases, sizeof(int));
X+ 	cp += sizeof (int);
X+ 	for (ap = hstaliases; naliases > 0; naliases--) {
X+ 		*ap++ = cp;
X+ 		while (*cp++)
X+ 			;
X+ 	}
X+ 	*ap = (char *)NULL;
X+ 	host2.h_aliases = hstaliases;
X+ 	bcopy(cp, (char *)&host2.h_addrtype, sizeof (int));
X+ 	cp += sizeof (int);
X+ 	bcopy(cp, (char *)&host2.h_length, sizeof (int));
X+ 	cp += sizeof (int);
X+ 	host2.h_addr_list = hstaddrs;
X+ 	naddrs = (key.dsize - (cp - buf2)) / host2.h_length;
X+ 	if (naddrs > MAXADDRS)
X+ 		naddrs = MAXADDRS;
X+ 	for (ap = hstaddrs; naddrs; naddrs--) {
X+ 		*ap++ = cp;
X+ 		cp += host2.h_length;
X+ 	}
X+ 	*ap = (char *)NULL;
X+         return (&host2);
X+ }
X+ 
X+ merge(hp2, hp)
X+ 	struct	hostent	*hp2, *hp;
X+ {
X+ register char	**sp, **sp2;
X+ 	char	**endalias, **endadr, **hp2ali, **hp2adr;
X+ 	long	l;
X+ 
X+ 	hp2ali = &hp2->h_aliases[0];
X+ 	hp2adr = &hp2->h_addr_list[0];
X+ 
X+ 	for (sp = hp->h_addr_list; *sp; sp++)
X+ 		;
X+ 	endadr = sp;
X+ 	for (sp = hp->h_aliases; *sp; sp++)
X+ 		;
X+ 	endalias = sp;
X+ 	for (sp = hp->h_aliases; *sp && *hp2ali; sp++) {
X+ 		for (sp2 = hp2ali; *sp2; sp2++) {
X+ 			if (!strcmp(*sp2, *sp))
X+ 				break;
X+ 		}
X+ 		if (*sp2 == (char *)NULL) {
X+ 			*endalias++ = *hp2ali++;
X+ 			*endalias = (char *)NULL;
X+ 		}
X+ 	}
X+ 	for (sp = hp->h_addr_list; *sp && *hp2adr; sp++) {
X+ 		for (sp2 = hp2adr; *sp2; sp2++) {
X+ 			if (!bcmp(*sp2, *sp, hp->h_length))
X+ 				break;
X+ 		}
X+ 		if (*sp2 == (char *)NULL) {
X+ 			*endadr++ = *hp2adr++;
X+ 			*endadr = (char *)NULL;
X+ 		}
X+ 	}
X  }
SHAR_EOF
fi
if test -f 'x.c'
then
	echo shar: "will not over-write existing file 'x.c'"
else
sed 's/^X//' << \SHAR_EOF > 'x.c'
X#include	<stdio.h>
X#include	<netdb.h>
X#include	<sysexits.h>
X#include	<sys/types.h>
X#include	<sys/socket.h>
X
X	struct	hostent	*hp;
X	long	l, addr[10], *lp;
X
Xmain(argc, argv)
X	int	argc;
X	char	**argv;
X	{
X
X	if	(argc != 2)
X		{
X		fputs("Usage: program hostname\n", stderr);
X		exit(EX_USAGE);
X		}
X	hp = gethostbyname(argv[1]);
X	if	(!hp)
X		{
X		printf("no such host %s\n", argv[1]);
X		exit(EX_NOHOST);
X		}
X	lp = addr;
X	while	(hp->h_addr_list[0])
X		{
X		bcopy(hp->h_addr_list[0], &l, sizeof (long));
X		bcopy(&l, lp++, sizeof (long));
X		printf("%s Address: %s\n", argv[1], inet_ntoa(l));
X		hp->h_addr_list++;
X		}
X	while	(hp->h_aliases[0])
X		{
X		printf("%s Alias: %s\n", argv[1], hp->h_aliases[0]);
X		hp->h_aliases++;
X		}
X	printf("Doing gethostbyaddr\n");
X	for	(lp = addr; *lp; lp++)
X		{
X		hp = gethostbyaddr(lp, sizeof (long), AF_INET);
X		if	(!hp)
X			{
X			printf("gethostbyaddr(0x%lx) failed\n", *lp);
X			continue;
X			}
X		while	(hp->h_addr_list[0])
X			{
X			bcopy(hp->h_addr_list[0], &l, sizeof (long));
X			printf("%s Address: %s\n", argv[1], inet_ntoa(l));
X			hp->h_addr_list++;
X			}
X		while	(hp->h_aliases[0])
X			{
X			printf("%s Alias: %s\n", argv[1], hp->h_aliases[0]);
X			hp->h_aliases++;
X			}
X		}
X	}
SHAR_EOF
fi
exit 0
#	End of shell archive



More information about the Comp.bugs.2bsd mailing list