[comp.protocols.tcp-ip] Comer/Shein whois server example won't work on Sparcstation

levy@mtcchi.uucp (2656-Daniel R. Levy(0000000)0000) (12/20/90)

I tried to run the whois server example by Barry Shein in Douglas Comer's
_Internetworking_With_TCP/IP_ on a Sparcstation running SunOS 4.0.3...  bind()
fails with EADDRNOTAVAIL even though the program was run with uid=euid=0.
(Killing inetd, guessing that it might somehow be interfering, did not help.
It did run fine on two SVR2 machines, an Amdahl and a 3B2.  I do not have any
other 4BSD machines for testing.) Below is a listing of the program (with some
debug print statements thrown in) and then the output I get when running it on
the Sparcstation.  Can anyone please assist... thanks much in advance.

-------------------------------------------------------------------------------
/* whoisserver.c - main */

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pwd.h>

#define BACKLOG		5
#define MAXHOSTNAME	32

main(argc,argv)
char **argv;
{
	int s, t;
	int i;
	struct sockaddr_in sa, isa;
	struct hostent *hp;
	char *myname;
	struct servent *sp;
	char localhost[MAXHOSTNAME+1];

	myname = argv[0];

	if ((sp = getservbyname("whois","tcp")) == NULL) {
		fprintf(stderr,"%s: No whois service on this host\n",myname);
		exit(1);
	}

	printf("service name: %s\n",sp->s_name);
	for (i=0; sp->s_aliases[i]; i++) printf("alias name %d: %s\n",i,
						sp->s_aliases[i]);
	printf("port: %d\n", sp->s_port);
	printf("protocol: %s\n", sp->s_proto);

	gethostname(localhost,MAXHOSTNAME);
	if ((hp = gethostbyname(localhost)) == NULL) {
		fprintf(stderr,"%s: cannot get local host info?\n",myname);
		exit(1);
	}

	printf("host name: %s\n",hp->h_name);
	for (i=0; hp->h_aliases[i]; i++) printf("alias name %d: %s\n",i,
						hp->h_aliases[i]);
	printf("address type: %d [AF_INET=%d]\n",hp->h_addrtype,AF_INET);
	printf("h_length = %d\n",hp->h_length);
	for (i=0; hp->h_addr_list[i]; i++) printf("address %d: %d.%d.%d.%d\n",
		i,
		(unsigned char)(hp->h_addr_list[i])[0],
		(unsigned char)(hp->h_addr_list[i])[1],
		(unsigned char)(hp->h_addr_list[i])[2],
		(unsigned char)(hp->h_addr_list[i])[3]);

	sa.sin_port = sp->s_port;
	bcopy((char *)hp->h_addr,(char *)&sa.sin_addr,hp->h_length);
	sa.sin_family = hp->h_addrtype;

	if ((s = socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) {
		perror("socket");
		exit(1);
	}

	if (bind(s,&sa,sizeof sa) < 0) {
		perror("bind");
		exit(1);
	}

	listen(s,BACKLOG);

	while(1) {
		i = sizeof isa;
		if ((t = accept(s,&isa,&i)) < 0) {
			perror("accept");
			exit(1);
		}
		whois(t);
		close(t);
	}
}

whois(sock)
{
	struct passwd *p;
	char buf[BUFSIZ+1];
	int i;

	if ((i = read(sock,buf,BUFSIZ)) <= 0)
		return;
	buf[i] = '\0';

	if ((p = getpwnam(buf)) == NULL)
		strcpy(buf,"User not found\n");
	else
		sprintf(buf,"%s: %s\n",p->pw_name,p->pw_gecos);
	write(sock,buf,strlen(buf));
	return;
}
-------------------------------------------------------------------------------
Attempt to run program:

ihckpo$ id
uid=0(root) gid=1(daemon) groups=1(daemon)
ihckpo$ ./whoisserver
service name: whois
alias name 0: nicname
port: 43
protocol: tcp
host name: ihckpo
alias name 0: skpo
address type: 2 [AF_INET=2]
h_length = 4
address 0: 135.1.13.44
bind: Can't assign requested address
ihckpo$ ps -axwwu
USER       PID %CPU %MEM   SZ  RSS TT STAT START  TIME COMMAND
root         0  0.0  0.0    0    0 ?  D    Dec 16  0:05 swapper
root         1  0.0  0.1   52   16 ?  I    Dec 16  0:03 /sbin/init -
root         2  0.0  0.0    0    0 ?  D    Dec 16  0:00 pagedaemon
levy      6229  0.0  0.0   44    0 p0 IW   20:54   0:00 /bin/ksh
root        98  0.0  0.0  104    0 ?  IW   Dec 16  0:01 /usr/lib/sendmail -bd -q1h
bin         49  0.0  0.5   32   84 ?  I    Dec 16  0:04 ypbind
root        46  0.0  0.0   40    0 ?  IW   Dec 16  0:03 portmap
levy      6171  0.0  0.0   44    0 co IW   19:04   0:00 -ksh (nksh)
root        52  0.0  0.0   36    0 co IW   Dec 16  0:00 keyserv
root        56  0.0  0.0   36    0 ?  IW   Dec 16  0:00 rpc.ypupdated
root        74  0.0  0.0   16    0 ?  I    Dec 16  0:00  (biod)
root        73  0.0  0.0   16    0 ?  I    Dec 16  0:00  (biod)
root        75  0.0  0.0   16    0 ?  I    Dec 16  0:00  (biod)
root        76  0.0  0.0   16    0 ?  I    Dec 16  0:00  (biod)
root        89  0.0  0.0   64    0 ?  IW   Dec 16  0:06 syslogd
root       132  0.0  0.0   12    0 ?  IW   Dec 16  0:05 /usr/bin/screenblank -d 900 -e 1.0
levy      6227  0.0  0.0  232    0 co IW   20:54   0:05 sunview
root       106  0.0  0.0   24    0 ?  I    Dec 16  0:01  (nfsd)
root       107  0.0  0.0   72    0 ?  IW   Dec 16  0:02 rpc.mountd -n
root       134  0.0  0.4   92   56 ?  S    Dec 16  0:17 automount /auto auto.master
root       112  0.0  0.0   24    0 ?  I    Dec 16  0:00  (nfsd)
root       113  0.0  0.0   24    0 ?  I    Dec 16  0:00  (nfsd)
root       114  0.0  0.0   24    0 ?  I    Dec 16  0:00  (nfsd)
root       115  0.0  0.0   24    0 ?  I    Dec 16  0:01  (nfsd)
root       116  0.0  0.0   24    0 ?  I    Dec 16  0:01  (nfsd)
root       117  0.0  0.0   24    0 ?  I    Dec 16  0:01  (nfsd)
root       118  0.0  0.0   24    0 ?  I    Dec 16  0:01  (nfsd)
root       119  0.0  0.0   60    0 co IW   Dec 16  0:00 rpc.lockd
root       146  0.0  0.1   12    8 ?  S    Dec 16  6:43 update
root       123  0.0  0.0   48    0 co IW   Dec 16  0:00 rpc.statd
levy      6234  0.0  0.8  372  124 co S    20:54   0:06 mailtool -Wp 0 0 -Ws 1152 900 -WP 1088 0 -Wi -i 30
root       150  0.0  0.0   76    0 ?  IW   Dec 16  0:24 cron
levy      6629  0.0  0.2   48   28 p3 S    22:27   0:02 ihcgf
root       169  0.0  0.0   52    0 ?  IW   Dec 16  0:00 /usr/lib/lpd -L /var/spool/lpd/err.log
levy      3041  0.0  0.0   40    0 co IW   Dec 18  0:01 selection_svc
root      1386  0.0  0.0   48    0 ?  IW   Dec 17  0:00 rpc.rquotad
levy      6238  0.0  0.0  104    0 p2 IW   20:54   0:00 shelltool -Wp 260 192 -Ws 650 567 -WP 832 0 -Wi -Wg
levy      6237  0.0  1.9  100  284 co S    20:54   0:02 clock -Wp 942 853 -Ws 210 47 -WP 1088 825 -Wi -f -r -d amy -s -Wg
root      6565  0.0  0.0   32    0 ?  IW   22:19   0:00 - Auto-baud ttyb (getty)
levy      6239  0.0  0.0   44    0 p2 IW   20:54   0:00 /bin/ksh
levy      6242  0.0  0.0   52    0 p3 IW   20:54   0:01 /bin/ksh
levy      6244  0.0  2.7  128  412 p4 S    20:54   0:28 shelltool -Wp 387 318 -Ws 650 567 -WP 960 0 -Wi -Wg
levy      6228  0.0  0.0  144    0 p0 IW   20:54   0:01 cmdtool -Wp 0 0 -Ws 670 71 -WP 0 0 -Wl << CONSOLE >> -WL console -C
levy      6241  0.0  4.1  128  628 p3 S    20:54   0:47 shelltool -Wp 321 256 -Ws 650 567 -WP 896 0 -Wi -Wg
levy      6245  0.0  0.0   52    0 p4 IW   20:54   0:04 /bin/ksh
levy      6232  0.0  0.0   44    0 p1 IW   20:54   0:01 /bin/ksh
levy      6248  0.0  1.5  100  232 co S    20:54   0:03 perfmeter -Wp 1024 0 -Ws 64 48 -WP 1024 0 -Wi -Wg
root      6249  0.0  0.6   36   88 ?  S    20:54   0:00 rpc.rstatd
levy      6235  0.0  0.0  104    0 co IW   20:54   0:04 Mail -N -B -f /tmp/MTda06234
levy      6567  0.0  0.0   48    0 p2 IW   22:19   0:00 ttbcad
root      6662  0.0  2.0  128  312 p4 R    22:41   0:00 ps -axwwu
root      6600  0.0  1.2   60  184 p4 S    22:25   0:01 ksh
levy      6566  0.0  0.0   48    0 p2 IW   22:19   0:00 ttbcad
levy      6231  0.0  0.0  120    0 p1 IW   20:54   0:59 shelltool -Wp 195 128 -Ws 650 567 -WP 768 0 -Wg
root      6616  0.0  0.4   44   64 ?  I    22:26   0:01 /usr/etc/inetd
levy      6628  0.0  0.2   48   24 p3 S    22:27   0:00 ihcgf

-------------------------------------------------------------------------------
-- 
* Daniel R. Levy *  uunet!tellab5!mtcchi!levy *                             |
* These views are live; they are not Memorex' *                           --+--
Praise the Lord, Praise the Lord, let the earth hear His voice;             |
Praise the Lord, Praise the Lord, let the people rejoice.  [F. Crosby]      |

levy@mtcchi.uucp (2656-Daniel R. Levy(0000000)0000) (12/22/90)

I wrote

>I tried to run the whois server example by Barry Shein in Douglas Comer's
>_Internetworking_With_TCP/IP_ on a Sparcstation running SunOS 4.0.3...  bind()
>fails with EADDRNOTAVAIL even though the program was run with uid=euid=0.
>(Killing inetd, guessing that it might somehow be interfering, did not help.
>It did run fine on two SVR2 machines, an Amdahl and a 3B2.  I do not have any
>other 4BSD machines for testing.) Below is a listing of the program (with some
>debug print statements thrown in) and then the output I get when running it on
>the Sparcstation.  Can anyone please assist... thanks much in advance.

>main(argc,argv)
>char **argv;
>{
	...
>	struct sockaddr_in sa;
>	struct hostent *hp;
>	int s;
	...
>	sa.sin_port = sp->s_port;
>	bcopy((char *)hp->h_addr,(char *)&sa.sin_addr,hp->h_length);
>	sa.sin_family = hp->h_addrtype;
>
>	if ((s = socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) {
>		perror("socket");
>		exit(1);
>	}
>
>	if (bind(s,&sa,sizeof sa) < 0) {
>		perror("bind");
>		exit(1);
>	}
	...
>}

A public thanks to Stuart Levy at the University of Minnesota, who pointed out
the problem:  a struct sockaddr_in has a char sin_zero[8] member which is
supposed to be zeroed; but if a struct sockaddr_in variable is declared auto,
this member is, of course, not guaranteed to be zeroed.  Either declaring sa to
be static or bzero()ing it fixes the problem.  As an experienced C programmer,
I feel kind of sheepish about not catching this sooner, though I could possibly
be excused in that I was not yet familiar with the structures involved....
-- 
* Daniel R. Levy *  uunet!tellab5!mtcchi!levy *                             |
* These views are live; they are not Memorex' *                           --+--
Praise the Lord, Praise the Lord, let the earth hear His voice;             |
Praise the Lord, Praise the Lord, let the people rejoice.  [F. Crosby]      |