240/4

Vince Fuller vaf at cisco.com
Thu Oct 18 23:51:46 UTC 2007


On Thu, Oct 18, 2007 at 11:00:42PM +0100, michael.dillon at bt.com wrote:
> 
> > why on earth would you want to go and hack this stuff together,  
> > knowing that it WILL NEVER WORK
> 
> Because I have read reports from people whose technical expertise I
> trust. They modified the TCP/IP code of Linux and FreeBSD and were able
> to freely use 240/4 address space to communicate between machines. This
> means that IT WILL WORK.
> 
> The reports stated that the code patch was simple because it involved
> simply removing a line of code that disallowed 240/4 addresses.

Actually, to do the job right, you have to change a handful of conditionals
in about five different files in the Linxux kernel: in.h (really just
cleanup to remove unused macros), devinet.c, fib_frontend.c, ipconfig.c,
and route.c.

Attached are the diffs for a 2.6 kernel (implemented and tested on an Ubuntu
7.04 system) and for a 2.4 kernel (implemented and tested on a Linksys
WRT45GL running OpenWRT whiterussian 0.9).

As mentioned in an earlier message, Mac OSX, at least the version that came
with a Powerbook G4 that I have, will accept a 240/4 address without any
modifications - I used it to test the Linux patches. There does appear to be
a one line change needed to FreeBSD and/or OSX for it to act as a router.

Have fun.

	--Vince
-------------- next part --------------
diff -c 2.6-orig/devinet.c 2.6/devinet.c
*** 2.6-orig/devinet.c	2007-09-20 15:32:16.000000000 -0700
--- 2.6/devinet.c	2007-09-19 11:29:32.000000000 -0700
***************
*** 1,3 ****
--- 1,6 ----
+ /*27-Aug-07 22:27:25, Edit by vaf */
+ /* use /24 default netmask for "class-E" space */
+ 
  /*
   *	NET3	IP device support routines.
   *
***************
*** 594,599 ****
--- 597,604 ----
  			rc = 16;
  		else if (IN_CLASSC(haddr))
  			rc = 24;
+ 		else if (IN_CLASSE(haddr))
+ 			rc = 24;
  	}
  
    	return rc;
diff -c 2.6-orig/fib_frontend.c 2.6/fib_frontend.c
*** 2.6-orig/fib_frontend.c	2007-09-20 15:32:16.000000000 -0700
--- 2.6/fib_frontend.c	2007-09-19 11:29:30.000000000 -0700
***************
*** 1,3 ****
--- 1,6 ----
+ /*16-Aug-07 16:26:55, Edit by vaf */
+ /* replace check for "BADCLASS" with explicit check for INADDR_BROADCAST */
+ 
  /*
   * INET		An implementation of the TCP/IP protocol suite for the LINUX
   *		operating system.  INET is implemented using the  BSD Socket
***************
*** 152,158 ****
  	struct fib_result	res;
  	unsigned ret = RTN_BROADCAST;
  
! 	if (ZERONET(addr) || BADCLASS(addr))
  		return RTN_BROADCAST;
  	if (MULTICAST(addr))
  		return RTN_MULTICAST;
--- 155,161 ----
  	struct fib_result	res;
  	unsigned ret = RTN_BROADCAST;
  
! 	if (ZERONET(addr) || addr == INADDR_BROADCAST)
  		return RTN_BROADCAST;
  	if (MULTICAST(addr))
  		return RTN_MULTICAST;
diff -c 2.6-orig/in.h 2.6/in.h
*** 2.6-orig/in.h	2007-09-20 15:33:11.000000000 -0700
--- 2.6/in.h	2007-09-19 11:29:32.000000000 -0700
***************
*** 1,3 ****
--- 1,5 ----
+ /*27-Aug-07 22:26:39, Edit by vaf */
+ /* add macros for "class-E"; remove those for BADCLASS and EXPERIMENTAL */
  /*
   * INET		An implementation of the TCP/IP protocol suite for the LINUX
   *		operating system.  INET is implemented using the  BSD Socket
***************
*** 215,222 ****
--- 217,232 ----
  #define	IN_MULTICAST(a)		IN_CLASSD(a)
  #define IN_MULTICAST_NET	0xF0000000
  
+ #define IN_CLASSE(a)		((((long int) (a)) & 0xf0000000) == 0xf0000000)
+ #define	IN_CLASSE_NET		0xffffff00
+ #define	IN_CLASSE_NSHIFT	8
+ #define	IN_CLASSE_HOST		(0xffffffff & ~IN_CLASSE_NET)
+ 
+ /* 
+  * these are no longer used
  #define	IN_EXPERIMENTAL(a)	((((long int) (a)) & 0xf0000000) == 0xf0000000)
  #define	IN_BADCLASS(a)		IN_EXPERIMENTAL((a))
+ */
  
  /* Address to accept any incoming messages. */
  #define	INADDR_ANY		((unsigned long int) 0x00000000)
diff -c 2.6-orig/ipconfig.c 2.6/ipconfig.c
*** 2.6-orig/ipconfig.c	2007-09-20 15:32:16.000000000 -0700
--- 2.6/ipconfig.c	2007-09-19 11:29:31.000000000 -0700
***************
*** 1,3 ****
--- 1,5 ----
+ /*28-Aug-07 10:21:56, Edit by vaf */
+ /* add default net mask for "class-E" */
  /*
   *  $Id: ipconfig.c,v 1.46 2002/02/01 22:01:04 davem Exp $
   *
***************
*** 379,384 ****
--- 381,388 ----
  			ic_netmask = htonl(IN_CLASSB_NET);
  		else if (IN_CLASSC(ntohl(ic_myaddr)))
  			ic_netmask = htonl(IN_CLASSC_NET);
+ 		else if (IN_CLASSE(ntohl(ic_myaddr)))
+ 			ic_netmask = htonl(IN_CLASSE_NET);
  		else {
  			printk(KERN_ERR "IP-Config: Unable to guess netmask for address %u.%u.%u.%u\n",
  				NIPQUAD(ic_myaddr));
diff -c 2.6-orig/route.c 2.6/route.c
*** 2.6-orig/route.c	2007-09-20 15:32:16.000000000 -0700
--- 2.6/route.c	2007-09-19 11:29:31.000000000 -0700
***************
*** 1,3 ****
--- 1,5 ----
+ /*16-Aug-07 16:25:26, Edit by vaf */
+ /* remove checks for BADCLASS to allow "class-E" source/destination addresses */
  /*
   * INET		An implementation of the TCP/IP protocol suite for the LINUX
   *		operating system.  INET is implemented using the  BSD Socket
***************
*** 1140,1146 ****
  		return;
  
  	if (new_gw == old_gw || !IN_DEV_RX_REDIRECTS(in_dev)
! 	    || MULTICAST(new_gw) || BADCLASS(new_gw) || ZERONET(new_gw))
  		goto reject_redirect;
  
  	if (!IN_DEV_SHARED_MEDIA(in_dev)) {
--- 1142,1148 ----
  		return;
  
  	if (new_gw == old_gw || !IN_DEV_RX_REDIRECTS(in_dev)
! 	    || MULTICAST(new_gw) || new_gw == INADDR_BROADCAST || ZERONET(new_gw))
  		goto reject_redirect;
  
  	if (!IN_DEV_SHARED_MEDIA(in_dev)) {
***************
*** 1617,1623 ****
  	if (in_dev == NULL)
  		return -EINVAL;
  
! 	if (MULTICAST(saddr) || BADCLASS(saddr) || LOOPBACK(saddr) ||
  	    skb->protocol != htons(ETH_P_IP))
  		goto e_inval;
  
--- 1619,1625 ----
  	if (in_dev == NULL)
  		return -EINVAL;
  
! 	if (MULTICAST(saddr) || saddr == INADDR_BROADCAST || LOOPBACK(saddr) ||
  	    skb->protocol != htons(ETH_P_IP))
  		goto e_inval;
  
***************
*** 1935,1941 ****
  	   by fib_lookup.
  	 */
  
! 	if (MULTICAST(saddr) || BADCLASS(saddr) || LOOPBACK(saddr))
  		goto martian_source;
  
  	if (daddr == htonl(0xFFFFFFFF) || (saddr == 0 && daddr == 0))
--- 1937,1943 ----
  	   by fib_lookup.
  	 */
  
! 	if (MULTICAST(saddr) || saddr == INADDR_BROADCAST || LOOPBACK(saddr))
  		goto martian_source;
  
  	if (daddr == htonl(0xFFFFFFFF) || (saddr == 0 && daddr == 0))
***************
*** 1947,1953 ****
  	if (ZERONET(saddr))
  		goto martian_source;
  
! 	if (BADCLASS(daddr) || ZERONET(daddr) || LOOPBACK(daddr))
  		goto martian_destination;
  
  	/*
--- 1949,1955 ----
  	if (ZERONET(saddr))
  		goto martian_source;
  
! 	if (ZERONET(daddr) || LOOPBACK(daddr))
  		goto martian_destination;
  
  	/*
***************
*** 2171,2177 ****
  		res->type = RTN_BROADCAST;
  	else if (MULTICAST(fl->fl4_dst))
  		res->type = RTN_MULTICAST;
! 	else if (BADCLASS(fl->fl4_dst) || ZERONET(fl->fl4_dst))
  		return -EINVAL;
  
  	if (dev_out->flags & IFF_LOOPBACK)
--- 2173,2179 ----
  		res->type = RTN_BROADCAST;
  	else if (MULTICAST(fl->fl4_dst))
  		res->type = RTN_MULTICAST;
! 	else if (ZERONET(fl->fl4_dst))
  		return -EINVAL;
  
  	if (dev_out->flags & IFF_LOOPBACK)
***************
*** 2391,2397 ****
  	if (oldflp->fl4_src) {
  		err = -EINVAL;
  		if (MULTICAST(oldflp->fl4_src) ||
! 		    BADCLASS(oldflp->fl4_src) ||
  		    ZERONET(oldflp->fl4_src))
  			goto out;
  
--- 2393,2399 ----
  	if (oldflp->fl4_src) {
  		err = -EINVAL;
  		if (MULTICAST(oldflp->fl4_src) ||
! 		    oldflp->fl4_src == INADDR_BROADCAST ||
  		    ZERONET(oldflp->fl4_src))
  			goto out;
  
-------------- next part --------------
diff -c openwrt-orig/devinet.c openwrt/devinet.c
*** openwrt-orig/devinet.c	2007-09-20 14:38:59.000000000 -0700
--- openwrt/devinet.c	2007-09-20 14:39:01.000000000 -0700
***************
*** 1,3 ****
--- 1,5 ----
+ /*19-Sep-07 16:31:37, Edit by vaf */
+ /* treat "class-E" same as "class-C" in inet_abc_len */
  /*
   *	NET3	IP device support routines.
   *
***************
*** 448,453 ****
--- 450,457 ----
    		return 16;
    	if (IN_CLASSC(addr)) 
    		return 24;
+   	if (IN_CLASSE(addr)) 
+   		return 24;
  
  	/*
  	 *	Something else, probably a multicast. 
diff -c openwrt-orig/fib_frontend.c openwrt/fib_frontend.c
*** openwrt-orig/fib_frontend.c	2007-09-20 14:39:00.000000000 -0700
--- openwrt/fib_frontend.c	2007-09-20 14:38:59.000000000 -0700
***************
*** 1,3 ****
--- 1,7 ----
+ /*19-Sep-07 16:33:43, Edit by vaf */
+ /* replace check for "BADCLASS" with explicit check for INADDR_BROADCAST */
+ 
+ 
  /*
   * INET		An implementation of the TCP/IP protocol suite for the LINUX
   *		operating system.  INET is implemented using the  BSD Socket
***************
*** 174,180 ****
  	struct fib_result	res;
  	unsigned ret = RTN_BROADCAST;
  
! 	if (ZERONET(addr) || BADCLASS(addr))
  		return RTN_BROADCAST;
  	if (MULTICAST(addr))
  		return RTN_MULTICAST;
--- 178,184 ----
  	struct fib_result	res;
  	unsigned ret = RTN_BROADCAST;
  
! 	if (ZERONET(addr) || addr == INADDR_BROADCAST)
  		return RTN_BROADCAST;
  	if (MULTICAST(addr))
  		return RTN_MULTICAST;
diff -c openwrt-orig/in.h openwrt/in.h
*** openwrt-orig/in.h	2007-09-20 14:39:00.000000000 -0700
--- openwrt/in.h	2007-09-20 14:39:01.000000000 -0700
***************
*** 1,3 ****
--- 1,7 ----
+ /*19-Sep-07 16:28:59, Edit by vaf */
+ /* support for "class-E"; no more IN_BADCLASS or IN_EXPERIMENTAL */
+ 
+ 
  /*
   * INET		An implementation of the TCP/IP protocol suite for the LINUX
   *		operating system.  INET is implemented using the  BSD Socket
***************
*** 209,216 ****
--- 213,228 ----
  #define	IN_MULTICAST(a)		IN_CLASSD(a)
  #define IN_MULTICAST_NET	0xF0000000
  
+ #define IN_CLASSE(a)		((((long int) (a)) & 0xf0000000) == 0xf0000000)
+ #define	IN_CLASSE_NET		0xffffff00
+ #define	IN_CLASSE_NSHIFT	8
+ #define	IN_CLASSE_HOST		(0xffffffff & ~IN_CLASSE_NET)
+ 
+ /* 
+  * these are no longer used
  #define	IN_EXPERIMENTAL(a)	((((long int) (a)) & 0xf0000000) == 0xf0000000)
  #define	IN_BADCLASS(a)		IN_EXPERIMENTAL((a))
+ */
  
  /* Address to accept any incoming messages. */
  #define	INADDR_ANY		((unsigned long int) 0x00000000)
diff -c openwrt-orig/ipconfig.c openwrt/ipconfig.c
*** openwrt-orig/ipconfig.c	2007-09-20 14:39:00.000000000 -0700
--- openwrt/ipconfig.c	2007-09-20 14:39:00.000000000 -0700
***************
*** 1,3 ****
--- 1,5 ----
+ /*19-Sep-07 16:35:44, Edit by vaf */
+ /* add default net mask for "class-E" */
  /*
   *  $Id: ipconfig.c,v 1.43.2.1 2001/12/13 10:39:53 davem Exp $
   *
***************
*** 366,371 ****
--- 368,375 ----
  			ic_netmask = htonl(IN_CLASSB_NET);
  		else if (IN_CLASSC(ntohl(ic_myaddr)))
  			ic_netmask = htonl(IN_CLASSC_NET);
+ 		else if (IN_CLASSE(ntohl(ic_myaddr)))
+ 			ic_netmask = htonl(IN_CLASSE_NET);
  		else {
  			printk(KERN_ERR "IP-Config: Unable to guess netmask for address %u.%u.%u.%u\n",
  				NIPQUAD(ic_myaddr));
diff -c openwrt-orig/route.c openwrt/route.c
*** openwrt-orig/route.c	2007-09-20 14:39:01.000000000 -0700
--- openwrt/route.c	2007-09-20 14:39:01.000000000 -0700
***************
*** 1,3 ****
--- 1,5 ----
+ /*19-Sep-07 16:42:52, Edit by vaf */
+ /* remove checks for BADCLASS to allow "class-E" addresses */
  /*
   * INET		An implementation of the TCP/IP protocol suite for the LINUX
   *		operating system.  INET is implemented using the  BSD Socket
***************
*** 853,859 ****
  		return;
  
  	if (new_gw == old_gw || !IN_DEV_RX_REDIRECTS(in_dev)
! 	    || MULTICAST(new_gw) || BADCLASS(new_gw) || ZERONET(new_gw))
  		goto reject_redirect;
  
  	if (!IN_DEV_SHARED_MEDIA(in_dev)) {
--- 855,861 ----
  		return;
  
  	if (new_gw == old_gw || !IN_DEV_RX_REDIRECTS(in_dev)
! 	    || MULTICAST(new_gw) || new_gw == INADDR_BROADCAST || ZERONET(new_gw))
  		goto reject_redirect;
  
  	if (!IN_DEV_SHARED_MEDIA(in_dev)) {
***************
*** 1316,1322 ****
  	if (in_dev == NULL)
  		return -EINVAL;
  
! 	if (MULTICAST(saddr) || BADCLASS(saddr) || LOOPBACK(saddr) ||
  	    skb->protocol != htons(ETH_P_IP))
  		goto e_inval;
  
--- 1318,1324 ----
  	if (in_dev == NULL)
  		return -EINVAL;
  
! 	if (MULTICAST(saddr) || saddr == INADDR_BROADCAST || LOOPBACK(saddr) ||
  	    skb->protocol != htons(ETH_P_IP))
  		goto e_inval;
  
***************
*** 1430,1436 ****
  	   by fib_lookup.
  	 */
  
! 	if (MULTICAST(saddr) || BADCLASS(saddr) || LOOPBACK(saddr))
  		goto martian_source;
  
  	if (daddr == 0xFFFFFFFF || (saddr == 0 && daddr == 0))
--- 1432,1438 ----
  	   by fib_lookup.
  	 */
  
! 	if (MULTICAST(saddr) || saddr == INADDR_BROADCAST || LOOPBACK(saddr))
  		goto martian_source;
  
  	if (daddr == 0xFFFFFFFF || (saddr == 0 && daddr == 0))
***************
*** 1442,1448 ****
  	if (ZERONET(saddr))
  		goto martian_source;
  
! 	if (BADCLASS(daddr) || ZERONET(daddr) || LOOPBACK(daddr))
  		goto martian_destination;
  
  	/*
--- 1444,1450 ----
  	if (ZERONET(saddr))
  		goto martian_source;
  
! 	if (ZERONET(daddr) || LOOPBACK(daddr))
  		goto martian_destination;
  
  	/*
***************
*** 1804,1810 ****
  	if (oldkey->src) {
  		err = -EINVAL;
  		if (MULTICAST(oldkey->src) ||
! 		    BADCLASS(oldkey->src) ||
  		    ZERONET(oldkey->src))
  			goto out;
  
--- 1806,1812 ----
  	if (oldkey->src) {
  		err = -EINVAL;
  		if (MULTICAST(oldkey->src) ||
! 		    oldkey->src == INADDR_BROADCAST ||
  		    ZERONET(oldkey->src))
  			goto out;
  
***************
*** 1962,1968 ****
  		res.type = RTN_BROADCAST;
  	else if (MULTICAST(key.dst))
  		res.type = RTN_MULTICAST;
! 	else if (BADCLASS(key.dst) || ZERONET(key.dst))
  		goto e_inval;
  
  	if (dev_out->flags & IFF_LOOPBACK)
--- 1964,1970 ----
  		res.type = RTN_BROADCAST;
  	else if (MULTICAST(key.dst))
  		res.type = RTN_MULTICAST;
! 	else if (ZERONET(key.dst))
  		goto e_inval;
  
  	if (dev_out->flags & IFF_LOOPBACK)


More information about the NANOG mailing list