Subject: Re: firmware update for Blue & White PowerMac G3
To: Matt Thomas <matt@3am-software.com>
From: Doug Ambrisko <ambrisko@whistle.com>
List: port-macppc
Date: 05/07/1999 15:00:02
Matt Thomas writes:
| At 07:43 PM 5/6/99 , Erik E. Fair wrote:
| >http://asu.info.apple.com/swupdates.nsf/artnum/n11361?OpenDocument
| 
| Doesn't seem to fix the problem that I can't net boot via
| dhcpd.  bootpd works fine.

The issue is that open firmware in the Mac's (atleast iMac which we have)
requires valid non-zero UDP checksums in the reply packet otherwise they
are ignored.

The checksum code in dhcpd was ifdef'd out and didn't work I have a 
working patch here for dhcp-2.0b1pl6 to make it work.  Since the iMac has
been taken away I don't know if newer dhcpd versions work.

BTW the iMac just silently doesn't work without this fix.  bootpd works
since the BSD stack does the UDP checksum calculation.  If you disable
it in the BSD stack (my server machine run FreeBSD and there you can
do a sysctl to turn it off) then bootpd also fails to work.

Doug A.

diff -r -c dhcp-2.0b1pl6/common/alloc.c dhcp-2.0b1pl6.good/common/alloc.c
*** dhcp-2.0b1pl6/common/alloc.c	Fri May  9 00:56:13 1997
--- dhcp-2.0b1pl6.good/common/alloc.c	Fri Feb  5 17:40:28 1999
***************
*** 57,63 ****
  	VOIDPTR foo = (VOIDPTR)malloc (size);
  	if (!foo)
  		warn ("No memory for %s.", name);
! 	memset (foo, 0, size);
  	return foo;
  }
  
--- 57,64 ----
  	VOIDPTR foo = (VOIDPTR)malloc (size);
  	if (!foo)
  		warn ("No memory for %s.", name);
! 	else
! 		memset (foo, 0, size);
  	return foo;
  }
  
Only in dhcp-2.0b1pl6.good/common: alloc.c.orig
diff -r -c dhcp-2.0b1pl6/common/dispatch.c dhcp-2.0b1pl6.good/common/dispatch.c
*** dhcp-2.0b1pl6/common/dispatch.c	Thu Jun 25 14:11:28 1998
--- dhcp-2.0b1pl6.good/common/dispatch.c	Fri Feb  5 17:42:12 1999
***************
*** 116,126 ****
  	for (i = 0; i < ic.ifc_len;) {
  		struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
  #ifdef HAVE_SA_LEN
! 		if (ifp -> ifr_addr.sa_len)
! 			i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
! 		else
! #endif
  			i += sizeof *ifp;
  
  #ifdef ALIAS_NAMES_PERMUTED
  		if ((s = strrchr (ifp -> ifr_name, ':'))) {
--- 116,127 ----
  	for (i = 0; i < ic.ifc_len;) {
  		struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
  #ifdef HAVE_SA_LEN
! 		i += (sizeof ifp -> ifr_name) +
! 		   ((ifp->ifr_addr.sa_len < sizeof(ifp->ifr_addr)) ?
! 		    sizeof(ifp->ifr_addr) : ifp->ifr_addr.sa_len);
! #else
  			i += sizeof *ifp;
+ #endif
  
  #ifdef ALIAS_NAMES_PERMUTED
  		if ((s = strrchr (ifp -> ifr_name, ':'))) {
Only in dhcp-2.0b1pl6.good/common: libdhcp.a
diff -r -c dhcp-2.0b1pl6/common/packet.c dhcp-2.0b1pl6.good/common/packet.c
*** dhcp-2.0b1pl6/common/packet.c	Fri Jun 26 11:20:44 1998
--- dhcp-2.0b1pl6.good/common/packet.c	Fri Feb  5 17:42:27 1999
***************
*** 194,200 ****
  	/* Compute UDP checksums, including the ``pseudo-header'', the UDP
  	   header and the data. */
  
! #if 0
  	udp.uh_sum =
  		wrapsum (checksum ((unsigned char *)&udp, sizeof udp,
  				   checksum (data, len, 
--- 194,200 ----
  	/* Compute UDP checksums, including the ``pseudo-header'', the UDP
  	   header and the data. */
  
! #if 1
  	udp.uh_sum =
  		wrapsum (checksum ((unsigned char *)&udp, sizeof udp,
  				   checksum (data, len, 
diff -r -c dhcp-2.0b1pl6/includes/cf/freebsd.h dhcp-2.0b1pl6.good/includes/cf/freebsd.h
*** dhcp-2.0b1pl6/includes/cf/freebsd.h	Fri May  9 01:18:37 1997
--- dhcp-2.0b1pl6.good/includes/cf/freebsd.h	Fri Feb  5 17:42:58 1999
***************
*** 53,59 ****
  
  #include <net/if.h>
  #include <net/if_dl.h>
! #define INADDR_LOOPBACK	((u_int32_t)0x7f000001)
  
  /* Varargs stuff... */
  #include <stdarg.h>
--- 53,60 ----
  
  #include <net/if.h>
  #include <net/if_dl.h>
! #include <net/if_arp.h>
! /*#define INADDR_LOOPBACK     ((u_int32_t)0x7f000001)*/
  
  /* Varargs stuff... */
  #include <stdarg.h>