Subject: misc/1404: network code in sys/lib/libsa fails on little-endian machines
To: None <gnats-bugs@NetBSD.ORG>
From: Matthias Drochner <drochner@zelux6.zel.kfa-juelich.de>
List: netbsd-bugs
Date: 08/24/1995 23:55:23
>Number:         1404
>Category:       misc
>Synopsis:       network code in sys/lib/libsa fails on little-endian machines
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    misc-bug-people (Misc Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Aug 24 18:20:02 1995
>Last-Modified:
>Originator:     Matthias Drochner
>Organization:
drochner@zelux6.zel.kfa-juelich.de
>Release:        current
>Environment:
	NetBSD-current on i368
System: NetBSD zelz19 1.0 NetBSD 1.0 (MIST) #3: Mon May 22 19:24:05 MET
DST 1995     dro
chner@zelz19:/usr/src/sys/arch/i386/compile/MIST i386

Machine: i386
>Description:
	The network code in sys/lib/libsa is not working on little-endian
	Machines in general and i386 in particular. There are some ntohl etc.
	in the code, but it appears untested.
>How-To-Repeat:
	Make a driver for a PC ethernet card, build a bootloader and watch
	the packets on the net...
>Fix:
	I made a version which works on i386, diffs attached below.
	I did a little bit more than a simple bug fix. To make the code
	more understandable I introduced simple rules:
	-All network addresses, submasks and port numbers are stored
	 in network byte order and only converted for input/output
	 (when assigned from constants or user input, when displayed on
	 screen).
	-Network addresses are stored as "struct in_addr".

	Some little changes which are contained in my diffs:
	-sendrecv in net.c gives up after a given number of tries
	 (to allow sequential probing of bootp and rarp or fallback
	 to default actions)
	-in bootparam.c: replaced use of portmapper function "callit"
	 by direct call to bootparam. Makes encapsulation code
	 and subsequent retrieving of server address unneccesary.
	 replace broadcast (didn't work on my ULTRIX server) by directed call
	 (implicitly assumes, that the inaddr is known (rarp!); I think that
	 is reasonable)
	-some bugfixes in error handling (if(unsigned<0)...)
	-first steps to make things more consistent
	 (bootp returns a value which could indicate success, global
	 variables for pathes etc. moved from lib into main program,
	 statics to avoid namespace pollution)
	 Aim was to remove cross-dependencies between logical
	 independend modules. (eg char *hostname can be set by bootp as well
	 as bootparam, defining it in one of them in inadequate)
	-very simple change: #include <lib/libkern/libkern.h> converted to
	 #include "../libkern/libkern.h", to make it compile in user-land
	 
	In this pr I send only a part of the changes I consider
	useful, the patches here touch the 2 using ports (from a
	glance) only minimal (the main programs would have to define
	the mentioned global variables).
	
	Some further changes I'd propose:
	-remove publically visible byte swapping of udp header members
	 in net.c (for consistency, according to the rules above)
	-reduce global variables to a minimum, use eg dynamically
	 allocated strings for boot pathes and store them in the
	 devdata member of open_file.
	-perhaps: allow choosing of filesystem to use (Background:
	 I implemented a tftp-filesystem (I will contribute later)
	 and want to choose between nfs and tftp.). Could be done
	 by flags in the devdata member, set by devopen, checked by all
	 fs_opens, but this is ugly.
	 We should put a name or at least a flag into fs_ops.
	 (Otherwise, I really take pains to keep the code compact!)
	-replace most "long"s by "int" or, even better, by something
	 like i32_t to become 64bit-clean.

	more comments:
	-exec.c seems broken, at least on i386 (I did not try)
	-When ethernet packets < 60 are expected, they have to be treated
	 specially, because the real packet could overflow the buffer.
	 Should ether.c handle this?
	-globals.c is contra-productive from the namespace point-of-view
	-netif.c seems a little bit over-designed for this purpose
	 (nobody uses it), but netif.h is needed
	-open.c returns 0 for raw devices. Bug or do I miss something?
	-some things belong seperated. eg sendrecv from udp code in net.c
	 or nulldev from open in open.c, to make the linker only include
	 _really_ used code.

	Here are, finally, the diffs:

diff -C 1 libsa/arp.c libsa.new/arp.c
*** libsa/arp.c	Fri Aug  4 08:54:42 1995
--- libsa.new/arp.c	Fri Aug 18 14:42:44 1995
***************
*** 58,60 ****
  static struct arp_list {
! 	n_long	addr;
  	u_char	ea[6];
--- 58,60 ----
  static struct arp_list {
! 	struct in_addr addr;
  	u_char	ea[6];
***************
*** 73,75 ****
  	register struct iodesc *d;
! 	n_long addr;
  {
--- 73,75 ----
  	register struct iodesc *d;
! 	struct in_addr addr;
  {
***************
*** 99,101 ****
  	for (i = 0, al = arp_list; i < arp_num; ++i, ++al)
! 		if (addr == al->addr)
  			return (al->ea);
--- 99,101 ----
  	for (i = 0, al = arp_list; i < arp_num; ++i, ++al)
! 		if (addr.s_addr == al->addr.s_addr)
  			return (al->ea);
diff -C 1 libsa/bootp.c libsa.new/bootp.c
*** libsa/bootp.c	Tue Apr 25 12:21:27 1995
--- libsa.new/bootp.c	Wed Aug 23 20:58:47 1995
***************
*** 52,54 ****
  
! static n_long	nmask, smask;
  
--- 52,54 ----
  
! static struct in_addr nmask, smask;
  
***************
*** 66,68 ****
  /* Fetch required bootp infomation */
! void
  bootp(sock)
--- 66,68 ----
  /* Fetch required bootp infomation */
! int
  bootp(sock)
***************
*** 103,107 ****
  	bp->bp_hlen = 6;
! 	bp->bp_xid = d->xid;
  	MACPY(d->myea, bp->bp_chaddr);
! 	bzero(bp->bp_file, sizeof(bp->bp_file));
  	bcopy(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048));
--- 103,107 ----
  	bp->bp_hlen = 6;
! 	bp->bp_xid = htonl(d->xid);
  	MACPY(d->myea, bp->bp_chaddr);
! 	strncpy(bp->bp_file, bootpfilename, sizeof(bp->bp_file));
  	bcopy(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048));
***************
*** 109,113 ****
  	d->myip = myip;
! 	d->myport = IPPORT_BOOTPC;
! 	d->destip = INADDR_BROADCAST;
! 	d->destport = IPPORT_BOOTPS;
  
--- 109,113 ----
  	d->myip = myip;
! 	d->myport = htons(IPPORT_BOOTPC);
! 	d->destip.s_addr = INADDR_BROADCAST;
! 	d->destport = htons(IPPORT_BOOTPS);
  
***************
*** 119,120 ****
--- 119,121 ----
  	++d->xid;
+ 	return(1);
  }
***************
*** 166,168 ****
  	bp = (struct bootp *)pkt;
- 	NTOHL(bp->bp_xid);
  
--- 167,168 ----
***************
*** 173,175 ****
  #endif
! 	if (bp->bp_xid != d->xid) {
  #ifdef BOOTP_DEBUG
--- 173,175 ----
  #endif
! 	if (ntohl(bp->bp_xid) != d->xid) {
  #ifdef BOOTP_DEBUG
***************
*** 177,179 ****
  			printf("bootprecv: expected xid 0x%x, got 0x%x\n",
! 			    d->xid, bp->bp_xid);
  		}
--- 177,179 ----
  			printf("bootprecv: expected xid 0x%x, got 0x%x\n",
! 			    d->xid, ntohl(bp->bp_xid));
  		}
***************
*** 189,191 ****
  	/* Pick up our ip address (and natural netmask) */
! 	myip = d->myip = ntohl(bp->bp_yiaddr.s_addr);
  #ifdef BOOTP_DEBUG
--- 189,191 ----
  	/* Pick up our ip address (and natural netmask) */
! 	myip = d->myip = bp->bp_yiaddr;
  #ifdef BOOTP_DEBUG
***************
*** 194,201 ****
  #endif
! 	if (IN_CLASSA(d->myip))
! 		nmask = IN_CLASSA_NET;
! 	else if (IN_CLASSB(d->myip))
! 		nmask = IN_CLASSB_NET;
  	else
! 		nmask = IN_CLASSC_NET;
  #ifdef BOOTP_DEBUG
--- 194,201 ----
  #endif
! 	if (IN_CLASSA(ntohl(d->myip.s_addr)))
! 		nmask.s_addr = htonl(IN_CLASSA_NET);
! 	else if (IN_CLASSB(ntohl(d->myip.s_addr)))
! 		nmask.s_addr = htonl(IN_CLASSB_NET);
  	else
! 		nmask.s_addr = htonl(IN_CLASSC_NET);
  #ifdef BOOTP_DEBUG
***************
*** 207,212 ****
  	if (bp->bp_siaddr.s_addr != 0)
! 		rootip = ntohl(bp->bp_siaddr.s_addr);
  	if (bp->bp_file[0] != '\0') {
! 		strncpy(bootfile, (char *)bp->bp_file, sizeof(bootfile));
! 		bootfile[sizeof(bootfile) - 1] = '\0';
  	}
--- 207,212 ----
  	if (bp->bp_siaddr.s_addr != 0)
! 		rootip = bp->bp_siaddr;
  	if (bp->bp_file[0] != '\0') {
! 		strncpy(bootpfilename, (char *)bp->bp_file, sizeof(bootpfilename));
! 		bootpfilename[sizeof(bootpfilename) - 1] = '\0';
  	}
***************
*** 222,224 ****
  	/* Check subnet mask against net mask; toss if bogus */
! 	if ((nmask & smask) != nmask) {
  #ifdef BOOTP_DEBUG
--- 222,224 ----
  	/* Check subnet mask against net mask; toss if bogus */
! 	if ((nmask.s_addr & smask.s_addr) != nmask.s_addr) {
  #ifdef BOOTP_DEBUG
***************
*** 227,229 ****
  #endif
! 		smask = 0;
  	}
--- 227,229 ----
  #endif
! 		smask.s_addr = 0;
  	}
***************
*** 232,234 ****
  	mask = nmask;
! 	if (smask)
  		mask = smask;
--- 232,234 ----
  	mask = nmask;
! 	if (smask.s_addr)
  		mask = smask;
***************
*** 246,248 ****
  	}
! 
  	if (!SAMENET(d->myip, swapip, mask)) {
--- 246,248 ----
  	}
! /*
  	if (!SAMENET(d->myip, swapip, mask)) {
***************
*** 253,255 ****
  	}
! 
  	/* Toss gateway if on a different net */
--- 253,255 ----
  	}
! */
  	/* Toss gateway if on a different net */
***************
*** 260,262 ****
  #endif
! 		gateip = 0;
  	}
--- 260,262 ----
  #endif
! 		gateip.s_addr = 0;
  	}
***************
*** 283,288 ****
  	if (vp->v_smask.s_addr != 0) {
! 		smask = ntohl(vp->v_smask.s_addr);
  	}
  	if (vp->v_dgate.s_addr != 0) {
! 		gateip = ntohl(vp->v_dgate.s_addr);
  	}
--- 283,288 ----
  	if (vp->v_smask.s_addr != 0) {
! 		smask = vp->v_smask;
  	}
  	if (vp->v_dgate.s_addr != 0) {
! 		gateip = vp->v_dgate;
  	}
***************
*** 316,318 ****
  			bcopy(cp, &smask, sizeof(smask));
- 			smask = ntohl(smask);
  		}
--- 316,317 ----
***************
*** 320,326 ****
  			bcopy(cp, &gateip, sizeof(gateip));
- 			gateip = ntohl(gateip);
  		}
  		if (tag == TAG_SWAPSERVER) {
  			bcopy(cp, &swapip, sizeof(swapip));
- 			swapip = ntohl(swapip);
  		}
--- 319,324 ----
  			bcopy(cp, &gateip, sizeof(gateip));
  		}
+ /*
  		if (tag == TAG_SWAPSERVER) {
  			bcopy(cp, &swapip, sizeof(swapip));
  		}
***************
*** 328,331 ****
  			bcopy(cp, &nameip, sizeof(nameip));
- 			nameip = ntohl(nameip);
  		}
  		if (tag == TAG_ROOTPATH) {
--- 326,329 ----
  			bcopy(cp, &nameip, sizeof(nameip));
  		}
+ */
  		if (tag == TAG_ROOTPATH) {
diff -C 1 libsa/bootparam.c libsa.new/bootparam.c
*** libsa/bootparam.c	Wed Jun 28 09:13:11 1995
--- libsa.new/bootparam.c	Wed Aug 23 10:57:44 1995
***************
*** 54,58 ****
  
! n_long  bp_server_addr;	/* net order */
! n_short bp_server_port;	/* net order */
  
  int hostnamelen;
--- 54,59 ----
  
! static struct in_addr bp_server_addr;
! static n_short bp_server_port;	/* net order */
  
+ /*
  int hostnamelen;
***************
*** 62,63 ****
--- 63,65 ----
  char domainname[FNAME_SIZE];
+ */
  
***************
*** 80,83 ****
  
! int xdr_inaddr_encode __P((void **p, n_long ia));
! int xdr_inaddr_decode __P((void **p, n_long *ia));
  
--- 82,85 ----
  
! int xdr_inaddr_encode __P((void **p, struct in_addr ia));
! int xdr_inaddr_decode __P((void **p, struct in_addr *ia));
  
***************
*** 108,113 ****
  	struct args {
! 		u_int32_t prog;
  		u_int32_t vers;
  		u_int32_t proc;
! 		u_int32_t arglen;
  		struct xdr_inaddr xina;
--- 110,115 ----
  	struct args {
! /*		u_int32_t prog;
  		u_int32_t vers;
  		u_int32_t proc;
! 		u_int32_t arglen; */
  		struct xdr_inaddr xina;
***************
*** 115,119 ****
  	struct repl {
- 		u_int32_t port;
- 		u_int32_t encap_len;
- 		/* encapsulated data here */
  		n_long  capsule[64];
--- 117,118 ----
***************
*** 146,151 ****
  	 */
! 	args->prog = htonl(BOOTPARAM_PROG);
  	args->vers = htonl(BOOTPARAM_VERS);
  	args->proc = htonl(BOOTPARAM_WHOAMI);
! 	args->arglen = htonl(sizeof(struct xdr_inaddr));
  	send_tail = &args->xina;
--- 145,150 ----
  	 */
! /*	args->prog = htonl(BOOTPARAM_PROG);
  	args->vers = htonl(BOOTPARAM_VERS);
  	args->proc = htonl(BOOTPARAM_WHOAMI);
! 	args->arglen = htonl(sizeof(struct xdr_inaddr));*/
  	send_tail = &args->xina;
***************
*** 160,165 ****
  	d->myport = htons(--rpc_port);
! 	d->destip = htonl(INADDR_BROADCAST);	/* XXX: subnet bcast? */
  	/* rpc_call will set d->destport */
  
! 	len = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_CALLIT,
  				  args, send_tail - (void*)args,
--- 159,168 ----
  	d->myport = htons(--rpc_port);
! 	/* d->destip.s_addr = INADDR_BROADCAST;	 XXX: subnet bcast? */
! 	d->destip = rootip;
  	/* rpc_call will set d->destport */
  
! /*	len = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_CALLIT,
! 				  args, send_tail - (void*)args,
! 				  repl, sizeof(*repl));*/
! 	len = rpc_call(d, BOOTPARAM_PROG, BOOTPARAM_VERS, BOOTPARAM_WHOAMI,
  				  args, send_tail - (void*)args,
***************
*** 171,193 ****
  
- 	/* Save bootparam server address (from IP header). */
- 	rpc_fromaddr(repl, &bp_server_addr, &bp_server_port);
- 
- 	/*
- 	 * Note that bp_server_port is now 111 due to the
- 	 * indirect call (using PMAPPROC_CALLIT), so get the
- 	 * actual port number from the reply data.
- 	 */
- 	bp_server_port = repl->port;
- 
- #ifdef	RPC_DEBUG
- 	printf("bp_whoami: server at %s:%d\n",
- 		   intoa(bp_server_addr), ntohs(bp_server_port));
- #endif
- 
- 	/* We have just done a portmap call, so cache the portnum. */
- 	rpc_pmap_putcache(bp_server_addr,
- 			  BOOTPARAM_PROG,
- 			  BOOTPARAM_VERS,
- 			  (int)bp_server_port);
- 
  	/*
--- 174,175 ----
***************
*** 195,201 ****
  	 */
- 	x = ntohl(repl->encap_len);
- 	if (len < x) {
- 		printf("bp_whoami: short reply, %d < %d\n", len, x);
- 		return(-1);
- 	}
  	recv_head = repl->capsule;
--- 177,178 ----
***************
*** 245,247 ****
  	char *pathname;
! 	n_long *serv_addr;
  {
--- 222,224 ----
  	char *pathname;
! 	struct in_addr *serv_addr;
  {
***************
*** 291,293 ****
  	d->myport = htons(--rpc_port);
- 	d->destip   = bp_server_addr;
  	/* rpc_call will set d->destport */
--- 268,269 ----
***************
*** 400,402 ****
  	void **pkt;
! 	n_long ia;		/* host order */
  {
--- 376,378 ----
  	void **pkt;
! 	struct in_addr ia;		/* network order */
  {
***************
*** 413,421 ****
  	xi->atype = htonl(1);
! 	uia.l = htonl(ia);
  	cp = uia.c;
  	ip = xi->addr;
! 	*ip++ = *cp++;
! 	*ip++ = *cp++;
! 	*ip++ = *cp++;
! 	*ip++ = *cp++;
  
--- 389,397 ----
  	xi->atype = htonl(1);
! 	uia.l = ia.s_addr;
  	cp = uia.c;
  	ip = xi->addr;
! 	*ip++ = htonl((int)*cp++);
! 	*ip++ = htonl((int)*cp++);
! 	*ip++ = htonl((int)*cp++);
! 	*ip++ = htonl((int)*cp++);
  
***************
*** 427,429 ****
  	void **pkt;
! 	n_long *ia;		/* host order */
  {
--- 403,405 ----
  	void **pkt;
! 	struct in_addr *ia;		/* network order */
  {
***************
*** 450,456 ****
  	ip = xi->addr;
! 	*cp++ = *ip++;
! 	*cp++ = *ip++;
! 	*cp++ = *ip++;
! 	*cp++ = *ip++;
! 	*ia = ntohl(uia.l);
  
--- 426,432 ----
  	ip = xi->addr;
! 	*cp++ = ntohl(*ip++);
! 	*cp++ = ntohl(*ip++);
! 	*cp++ = ntohl(*ip++);
! 	*cp++ = ntohl(*ip++);
! 	ia->s_addr = uia.l;
  
diff -C 1 libsa/bootparam.h libsa.new/bootparam.h
*** libsa/bootparam.h	Wed Jun 28 09:13:11 1995
--- libsa.new/bootparam.h	Fri Aug 18 14:51:48 1995
***************
*** 2,4 ****
  int bp_whoami(int sock);
! int bp_getfile(int sock, char *key, n_long *addrp, char *path);
  
--- 2,4 ----
  int bp_whoami(int sock);
! int bp_getfile(int sock, char *key, struct in_addr *addrp, char *path);
  
diff -C 1 libsa/globals.c libsa.new/globals.c
*** libsa/globals.c	Mon Nov 21 23:47:12 1994
--- libsa.new/globals.c	Fri Aug 18 12:13:32 1995
***************
*** 23,28 ****
  char	ifname[IFNAME_SIZE];		/* name of interface (e.g. "le0") */
! n_long	nameip;				/* DNS server ip address */
! n_long	rootip;				/* root ip address */
! n_long	swapip;				/* swap ip address */
! n_long	gateip;				/* swap ip address */
! n_long	mask = 0xffffff00;		/* subnet or net mask */
--- 23,29 ----
  char	ifname[IFNAME_SIZE];		/* name of interface (e.g. "le0") */
! struct in_addr myip;
! struct in_addr nameip;			/* DNS server ip address */
! struct in_addr rootip;			/* root ip address */
! struct in_addr swapip;			/* swap ip address */
! struct in_addr gateip;			/* gateway ip address */
! struct in_addr mask;			/* subnet or net mask */
diff -C 1 libsa/iodesc.h libsa.new/iodesc.h
*** libsa/iodesc.h	Mon Nov 21 23:47:13 1994
--- libsa.new/iodesc.h	Fri Aug 18 12:59:10 1995
***************
*** 44,47 ****
  struct iodesc {
! 	n_long	destip;			/* destination ip address */
! 	n_long	myip;			/* my ip address */
  	u_short	destport;		/* destination port */
--- 44,47 ----
  struct iodesc {
! 	struct in_addr	destip;			/* destination ip address */
! 	struct in_addr	myip;			/* my ip address */
  	u_short	destport;		/* destination port */
diff -C 1 libsa/net.c libsa.new/net.c
*** libsa/net.c	Mon Feb 20 12:21:42 1995
--- libsa.new/net.c	Wed Aug 23 21:23:21 1995
***************
*** 58,62 ****
  #include "net.h"
! #include "netif.h"
  
! n_long	myip;
  
--- 58,62 ----
  #include "net.h"
! /* #include "netif.h" */
  
! u_char bcea[6] = BA;
  
***************
*** 81,85 ****
  			printf("saddr: %s:%d",
! 				intoa(d->myip), d->myport);
  			printf(" daddr: %s:%d\n",
! 				intoa(d->destip), d->destport);
  		}
--- 81,85 ----
  			printf("saddr: %s:%d",
! 				intoa(d->myip), ntohs(d->myport));
  			printf(" daddr: %s:%d\n",
! 				intoa(d->destip), ntohs(d->destport));
  		}
***************
*** 99,106 ****
  	ip->ip_ttl = IP_TTL;			/* char */
! 	ip->ip_src.s_addr = htonl(d->myip);
! 	ip->ip_dst.s_addr = htonl(d->destip);
  	ip->ip_sum = in_cksum(ip, sizeof(*ip));	 /* short, but special */
  
! 	uh->uh_sport = htons(d->myport);
! 	uh->uh_dport = htons(d->destport);
  	uh->uh_ulen = htons(len - sizeof(*ip));
--- 99,106 ----
  	ip->ip_ttl = IP_TTL;			/* char */
! 	ip->ip_src = d->myip;
! 	ip->ip_dst = d->destip;
  	ip->ip_sum = in_cksum(ip, sizeof(*ip));	 /* short, but special */
  
! 	uh->uh_sport = d->myport;
! 	uh->uh_dport = d->destport;
  	uh->uh_ulen = htons(len - sizeof(*ip));
***************
*** 118,124 ****
  	if (ip->ip_dst.s_addr == INADDR_BROADCAST || ip->ip_src.s_addr == 0 ||
! 	    mask == 0 || SAMENET(ip->ip_src.s_addr, ip->ip_dst.s_addr, mask))
! 		ea = arpwhohas(d, ip->ip_dst.s_addr);
  	else
! 		ea = arpwhohas(d, htonl(gateip));
! 
  	cc = sendether(d, ip, len, ea, ETHERTYPE_IP);
--- 118,123 ----
  	if (ip->ip_dst.s_addr == INADDR_BROADCAST || ip->ip_src.s_addr == 0 ||
! 	    mask.s_addr == 0 || SAMENET(ip->ip_src, ip->ip_dst, mask))
! 		ea = arpwhohas(d, ip->ip_dst);
  	else
! 		ea = arpwhohas(d, gateip);
  	cc = sendether(d, ip, len, ea, ETHERTYPE_IP);
***************
*** 172,174 ****
  		if (debug)
! 			printf("readudp: not IP. ether_type=%x\n", eh->ether_type);
  #endif
--- 171,173 ----
  		if (debug)
! 			printf("readudp: not IP. ether_type=%x\n", ntohs(eh->ether_type));
  #endif
***************
*** 205,207 ****
  	}
! 	if (d->myip && ntohl(ip->ip_dst.s_addr) != d->myip) {
  #ifdef NET_DEBUG
--- 204,206 ----
  	}
! 	if (d->myip.s_addr && ip->ip_dst.s_addr != d->myip.s_addr) {
  #ifdef NET_DEBUG
***************
*** 209,211 ****
  			printf("readudp: bad saddr %s != ", intoa(d->myip));
! 			printf("%s\n", intoa(ntohl(ip->ip_dst.s_addr)));
  		}
--- 208,210 ----
  			printf("readudp: bad saddr %s != ", intoa(d->myip));
! 			printf("%s\n", intoa(ip->ip_dst));
  		}
***************
*** 221,223 ****
  	}
! 	if (ntohs(uh->uh_dport) != d->myport) {
  #ifdef NET_DEBUG
--- 220,222 ----
  	}
! 	if (uh->uh_dport != d->myport) {
  #ifdef NET_DEBUG
***************
*** 295,301 ****
  	register time_t t, tmo, tlast, tleft;
! 
! #ifdef NET_DEBUG
! 	if (debug)
! 		printf("sendrecv: called\n");
! #endif
  
--- 294,296 ----
  	register time_t t, tmo, tlast, tleft;
! 	int maxtries;
  
***************
*** 304,307 ****
--- 299,309 ----
  	t = getsecs();
+ 	maxtries = MAXTRIES;
  	for (;;) {
  		if (tleft <= 0) {
+ 
+ 		  if(--maxtries<0){
+ 		    errno = EIO;
+ 		    return(-1);
+ 		  }
+ 
  			cc = (*sproc)(d, sbuf, ssize);
***************
*** 334,336 ****
  intoa(addr)
! 	n_long addr;
  {
--- 336,338 ----
  intoa(addr)
! 	struct in_addr addr;
  {
***************
*** 340,341 ****
--- 342,344 ----
  	static char buf[17];	/* strlen(".255.255.255.255") + 1 */
+ 	u_int a=ntohl(addr.s_addr);
  
***************
*** 346,348 ****
  	do {
! 		byte = addr & 0xff;
  		*--cp = byte % 10 + '0';
--- 349,351 ----
  	do {
! 		byte = a & 0xff;
  		*--cp = byte % 10 + '0';
***************
*** 356,358 ****
  		*--cp = '.';
! 		addr >>= 8;
  	} while (--n > 0);
--- 359,361 ----
  		*--cp = '.';
! 		a >>= 8;
  	} while (--n > 0);
diff -C 1 libsa/net.h libsa.new/net.h
*** libsa/net.h	Wed Jun 28 09:13:12 1995
--- libsa.new/net.h	Wed Aug 23 14:40:42 1995
***************
*** 45,47 ****
  /* Returns true if n_long's on the same net */
! #define	SAMENET(a1, a2, m) ((a1 & m) == (a2 & m))
  
--- 45,47 ----
  /* Returns true if n_long's on the same net */
! #define	SAMENET(a1, a2, m) ((a1.s_addr & m.s_addr) == (a2.s_addr & m.s_addr))
  
***************
*** 49,52 ****
  
! #define MAXTMO 20	/* seconds */
! #define MINTMO 2	/* seconds */
  
--- 49,53 ----
  
! #define MAXTMO 10	/* seconds */
! #define MINTMO 1	/* seconds */
! #define MAXTRIES 5
  
***************
*** 69,80 ****
  extern	char bootfile[FNAME_SIZE];
  extern	char hostname[FNAME_SIZE];
  extern	char domainname[FNAME_SIZE];
  extern	char ifname[IFNAME_SIZE];
  
! extern	n_long myip;
! extern	n_long rootip;
! extern	n_long swapip;
! extern	n_long gateip;
! extern	n_long nameip;
! extern	n_long mask;
  
--- 70,84 ----
  extern	char bootfile[FNAME_SIZE];
+ extern	char bootpfilename[FNAME_SIZE];
  extern	char hostname[FNAME_SIZE];
+ extern int hostnamelen;
  extern	char domainname[FNAME_SIZE];
+ extern int domainnamelen;
  extern	char ifname[IFNAME_SIZE];
  
! extern struct in_addr myip;
! extern struct in_addr rootip;
! extern struct in_addr swapip;
! extern struct in_addr gateip;
! extern struct in_addr nameip;
! extern struct in_addr mask;
  
***************
*** 86,88 ****
  
! u_char	*arpwhohas __P((struct iodesc *, n_long));
  
--- 90,92 ----
  
! u_char	*arpwhohas __P((struct iodesc *, struct in_addr));
  
***************
*** 100,102 ****
  int	in_cksum __P((void *, int));
! char	*intoa __P((n_long));			/* similar to inet_ntoa */
  
--- 104,106 ----
  int	in_cksum __P((void *, int));
! char	*intoa __P((struct in_addr));			/* similar to inet_ntoa */
  
diff -C 1 libsa/nfs.c libsa.new/nfs.c
*** libsa/nfs.c	Mon Jul  3 09:01:07 1995
--- libsa.new/nfs.c	Tue Aug 22 20:48:03 1995
***************
*** 268,270 ****
  	int sock;
! 	n_long ip;
  	char *path;
--- 268,270 ----
  	int sock;
! 	struct in_addr ip;
  	char *path;
diff -C 1 libsa/open.c libsa.new/open.c
*** libsa/open.c	Tue Apr 25 12:21:29 1995
--- libsa.new/open.c	Sat Aug 19 22:06:21 1995
***************
*** 104,106 ****
  		f->f_flags |= F_RAW;
! 		return (0);
  	}
--- 104,106 ----
  		f->f_flags |= F_RAW;
! 		return (0); /* fd ?????????????? */
  	}
diff -C 1 libsa/rarp.c libsa.new/rarp.c
*** libsa/rarp.c	Wed Jun 28 09:13:13 1995
--- libsa.new/rarp.c	Wed Aug 23 17:23:52 1995
***************
*** 60,62 ****
   */
! n_long
  rarp_getipaddress(sock)
--- 60,62 ----
   */
! int
  rarp_getipaddress(sock)
***************
*** 104,106 ****
  
! 	if (sendrecv(d,
  	    rarpsend, &wbuf.data, sizeof(wbuf.data),
--- 104,106 ----
  
! 	if ((int)sendrecv(d,
  	    rarpsend, &wbuf.data, sizeof(wbuf.data),
***************
*** 108,113 ****
  		printf("No response for RARP request\n");
! 		return(INADDR_ANY);
  	}
  
! 	return (myip);
  }
--- 108,113 ----
  		printf("No response for RARP request\n");
! 		return(0);
  	}
  
! 	return (1);
  }
diff -C 1 libsa/rpc.c libsa.new/rpc.c
*** libsa/rpc.c	Mon Jul  3 09:01:07 1995
--- libsa.new/rpc.c	Wed Aug 23 21:31:13 1995
***************
*** 102,106 ****
  /* Local forwards */
  static	size_t recvrpc __P((struct iodesc *, void *, size_t, time_t));
  
! int rpc_xid;
  int rpc_port = 0x400;	/* predecrement */
--- 102,107 ----
  /* Local forwards */
+ static int rpc_getport __P((struct iodesc *d, n_long prog, n_long vers));
  static	size_t recvrpc __P((struct iodesc *, void *, size_t, time_t));
  
! static int rpc_xid;
  int rpc_port = 0x400;	/* predecrement */
***************
*** 127,128 ****
--- 128,130 ----
  	n_long x;
+ 	int p;
  
***************
*** 131,136 ****
  		printf("rpc_call: prog=0x%x vers=%d proc=%d\n",
! 			   prog, vers, proc);
  #endif
  
! 	d->destport = rpc_getport(d, prog, vers);
  
--- 133,140 ----
  		printf("rpc_call: prog=0x%x vers=%d proc=%d\n",
! 		       prog, vers, proc);
  #endif
  
! 	if((p = rpc_getport(d, prog, vers)) == -1)
! 	  return(-1);
! 	d->destport = htons((short)ntohl(p));
  
***************
*** 184,189 ****
  	    recvrpc, recv_head, (recv_tail - recv_head));
! #ifdef RPC_DEBUG
! 	if (debug)
! 		printf("callrpc: cc=%d rlen=%d\n", cc, rlen);
! #endif
  	if (cc <= sizeof(*reply))
--- 188,190 ----
  	    recvrpc, recv_head, (recv_tail - recv_head));
! 
  	if (cc <= sizeof(*reply))
***************
*** 238,240 ****
  	len = readudp(d, pkt, len, tleft);
! 	if (len <= (4 * 4))
  		goto bad;
--- 239,241 ----
  	len = readudp(d, pkt, len, tleft);
! 	if ((len <= (4 * 4))||(len==(size_t)-1))
  		goto bad;
***************
*** 279,281 ****
  void
! rpc_fromaddr(void *pkt, n_long *addr, u_short *port)
  {
--- 280,282 ----
  void
! rpc_fromaddr(void *pkt, struct in_addr *addr, u_short *port)
  {
***************
*** 295,297 ****
  	hhdr = ((struct hackhdr *)pkt) - 1;
! 	*addr = hhdr->ip_src;
  	*port = hhdr->uh_sport;
--- 296,298 ----
  	hhdr = ((struct hackhdr *)pkt) - 1;
! 	addr->s_addr = hhdr->ip_src;
  	*port = hhdr->uh_sport;
***************
*** 307,312 ****
  struct pmap_list {
! 	u_long	addr;		/* server, net order */
  	u_long	prog;		/* host order */
  	u_long	vers;		/* host order */
! 	u_short	port;		/* net order */
  	u_short _pad;
--- 308,313 ----
  struct pmap_list {
! 	struct in_addr addr;		/* server, net order */
  	u_long	prog;		/* host order */
  	u_long	vers;		/* host order */
! 	u_int	port;		/* net order */
  	u_short _pad;
***************
*** 315,319 ****
  /* return port number in net order */
! int
  rpc_pmap_getcache(addr, prog, vers)
! 	u_long	addr;	/* server, net order */
  	u_long	prog;	/* host order */
--- 316,320 ----
  /* return port number in net order */
! static int
  rpc_pmap_getcache(addr, prog, vers)
! 	struct in_addr addr;	/* server, net order */
  	u_long	prog;	/* host order */
***************
*** 324,327 ****
  	for (pl = rpc_pmap_list; pl < &rpc_pmap_list[rpc_pmap_num]; pl++)
! 		if (pl->addr == addr &&	pl->prog == prog &&	pl->vers == vers)
! 			return ((int) pl->port);
  	return (-1);
--- 325,328 ----
  	for (pl = rpc_pmap_list; pl < &rpc_pmap_list[rpc_pmap_num]; pl++)
! 		if (pl->addr.s_addr == addr.s_addr &&	pl->prog == prog &&	pl->vers == vers)
! 			return (pl->port);
  	return (-1);
***************
*** 329,336 ****
  
  void
  rpc_pmap_putcache(addr, prog, vers, port)
! 	n_long	addr;	/* net order */
  	n_long	prog;	/* host order */
  	n_long	vers;	/* host order */
! 	int port;		/* net order */
  {
--- 330,340 ----
  
+ /*
+ static
+ */
  void
  rpc_pmap_putcache(addr, prog, vers, port)
! 	struct in_addr addr;	/* net order */
  	n_long	prog;	/* host order */
  	n_long	vers;	/* host order */
! 	u_int port;		/* net order */
  {
***************
*** 362,364 ****
   */
! int
  rpc_getport(d, prog, vers)
--- 366,368 ----
   */
! static int
  rpc_getport(d, prog, vers)
***************
*** 395,397 ****
  	if (prog == PMAPPROG)
! 		return PMAPPORT;
  
--- 399,401 ----
  	if (prog == PMAPPROG)
! 		return htonl(PMAPPORT);
  
***************
*** 399,401 ****
  	port = rpc_pmap_getcache(d->destip, prog, vers);
! 	if (port >= 0)
  		return (port);
--- 403,405 ----
  	port = rpc_pmap_getcache(d->destip, prog, vers);
! 	if (port != -1)
  		return (port);
***************
*** 415,417 ****
  	}
! 	port = (u_short)res->port;
  
--- 419,421 ----
  	}
! 	port = res->port;
  
diff -C 1 libsa/rpc.h libsa.new/rpc.h
*** libsa/rpc.h	Wed Jun 28 09:13:13 1995
--- libsa.new/rpc.h	Fri Aug 18 18:18:19 1995
***************
*** 53,60 ****
  	    void *sdata, size_t slen, void *rdata, size_t rlen));
! int 	rpc_getport __P((struct iodesc *d, n_long prog, n_long vers));
! void	rpc_fromaddr(void *pkt, n_long *addr, u_short *port);
! void	rpc_pmap_putcache __P((n_long addr, n_long pr, n_long v, int port));
  
! extern int rpc_xid; 	/* increment before call */
! extern int rpc_port;	/* decrement before bind */
  
--- 53,57 ----
  	    void *sdata, size_t slen, void *rdata, size_t rlen));
! void	rpc_fromaddr(void *pkt, struct in_addr *addr, u_short *port);
  
! extern int rpc_port;
  
diff -C 1 libsa/ufs.c libsa.new/ufs.c
*** libsa/ufs.c	Wed Feb 22 12:26:19 1995
--- libsa.new/ufs.c	Wed Aug 23 13:31:11 1995
***************
*** 74,76 ****
  #include <ufs/ufs/dir.h>
! #include <lib/libkern/libkern.h>
  
--- 74,76 ----
  #include <ufs/ufs/dir.h>
! #include "../libkern/libkern.h"

>Audit-Trail:
>Unformatted:
SEND-PR: -*- send-pr -*-
SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as
SEND-PR: will all comments (text enclosed in `<' and `>').
SEND-PR: 
SEND-PR: Please consult the send-pr man page `send-pr(1)' or the Texinfo
SEND-PR: manual if you are not sure how to fill out a problem report.
SEND-PR:
SEND-PR: Choose from the following categories:
SEND-PR:
SEND-PR: bin        kern       lib        misc       port-amiga 
SEND-PR: port-hp300 port-i386  port-m68k  port-mac   port-pc532 
SEND-PR: port-pmax  port-sparc port-sun3  
SEND-PR:
To: gnats-bugs@NetBSD.ORG
Subject: 
From: drochner@zelux6.zel.kfa-juelich.de
Reply-To: drochner@zelux6.zel.kfa-juelich.de