# ETHERSPOOF and RAW4ALL unified diff for Mac OS X 10.0.x / Darwin 1.3.x
# by peter bartoli, version 1.4 of 1/21/2002
#
# to install
# 1. unpack and cd to your xnu source tree
# 2. patch -p0 -b [--verbose --suffix=.orig] < ETHERSPOOF+RAW4ALL.patch
# 3. build xnu and install your kernel
#
--- bsd/conf/MASTER.orig	Mon Dec  4 14:13:43 2000
+++ bsd/conf/MASTER	Wed Aug  1 01:00:06 2001
@@ -198,10 +198,14 @@
 options		NATPT				# KAME/IPv6 NAT feature		#<natpt>
 pseudo-device   gif     2		# <gif>
 pseudo-device   dummy   2		# <dummy>
 pseudo-device   faith   1		# <faith>
 
+# custom networking options
+options		ETHERSPOOF			# source address spoofing
+options		RAW4ALL				# raw sockets for all users
+
 makeoptions	LIBDRIVER = "libDriver_kern.o"			# <libdriver>
 makeoptions	LIBOBJC   = "libkobjc.o"			# <kernobjc>
 
 maxusers	64		# <xlarge>
 maxusers	50		# <large>

--- bsd/net/ether_if_module.c.orig	Wed Nov 29 16:46:56 2000
+++ bsd/net/ether_if_module.c	Wed Aug  8 01:21:05 2001
@@ -481,12 +481,25 @@
 
 	eh = mtod(*m, struct ether_header *);
 	(void)memcpy(&eh->ether_type, ether_type,
 		sizeof(eh->ether_type));
  	(void)memcpy(eh->ether_dhost, edst, 6);
+#ifdef ETHERSPOOF
+	if (ndest->sa_family == AF_UNSPEC) {
+	    (void)memcpy((u_char *)eh->ether_shost,
+	       (u_char *)((struct ether_header *)(ndest->sa_data))->ether_shost,
+	           6);
+	}
+	else
+	{
+	    (void)memcpy(eh->ether_shost, ac->ac_enaddr,
+	       sizeof(eh->ether_shost));
+	}
+#else
  	(void)memcpy(eh->ether_shost, ac->ac_enaddr,
 	    sizeof(eh->ether_shost));
+#endif /* ETHERSPOOF */
 
 	return 0;
 }

 
--- bsd/netinet/if_ether.c.orig	Fri Jan 26 14:40:36 2001
+++ bsd/netinet/if_ether.c	Mon Jan  7 16:46:24 2002
@@ -359,10 +359,13 @@
 	ea->arp_hrd = htons(ARPHRD_ETHER);
 	ea->arp_pro = htons(ETHERTYPE_IP);
 	ea->arp_hln = sizeof(ea->arp_sha);	/* hardware address length */
 	ea->arp_pln = sizeof(ea->arp_spa);	/* protocol address length */
 	ea->arp_op = htons(ARPOP_REQUEST);
+#ifdef ETHERSPOOF
+	(void)memcpy(eh->ether_shost, enaddr, sizeof(eh->ether_shost));
+#endif /* ETHERSPOOF */
 	(void)memcpy(ea->arp_sha, enaddr, sizeof(ea->arp_sha));
 	(void)memcpy(ea->arp_spa, sip, sizeof(ea->arp_spa));
 	(void)memcpy(ea->arp_tpa, tip, sizeof(ea->arp_tpa));
 	sa.sa_family = AF_UNSPEC;
 	sa.sa_len = sizeof(sa);
@@ -667,10 +668,13 @@
 	(void)memcpy(ea->arp_spa, &itaddr, sizeof(ea->arp_spa));
 	ea->arp_op = htons(ARPOP_REPLY);
 	ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
 	eh = (struct ether_header *)sa.sa_data;
 	(void)memcpy(eh->ether_dhost, ea->arp_tha, sizeof(eh->ether_dhost));
+#ifdef ETHERSPOOF
+	(void)memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(eh->ether_shost));
+#endif /* ETHERSPOOF */
 	eh->ether_type = htons(ETHERTYPE_ARP);
 	sa.sa_family = AF_UNSPEC;
 	sa.sa_len = sizeof(sa);
 	dlil_output((u_long) ac, m, 0, &sa, 0);
 	return;
