HEDRICK@RED.RUTGERS.EDU (Charles Hedrick) (08/11/86)
Simple-minded subnetting is very easy to do. It requires slight changes to in.h and in.c. You can use in.c from any 4.2 system. Sun's is not special. In addition, inet_lnaof and inet_netof need to be fixed in a handful of utilities. We did this without sources. Sun claims that they are not doing subnetting because it will break some of the extra-cost networking options, which they get from 3rd parties and don't have source to. I find that hard to believe, since such code should call common kernel routines to do all routing computations. But it wouldn't be the first time programmers wrote code that did something they shouldn't, so I can't judge for sure. Here is a copy of a message I sent to somebody else. Unfortunately, our changes may be a bit too simple-minded. In trying to keep the number of changes to a minimum, I suspect we have missed some utilities. Any utilities that broadcasts may have to be changed. E.g. rwho and routed. We don't use those. Ideally route and netstat should also be changed. If you have source, you can just fix inet_lnaof and inet_netof in the C library and reload everything. (The patches are the same as to in_lnaof and in_netof, shown below.) When you do this, you should also set ipforwarding to 0 on every machine on your net. You can do this in adb: cp /vmunix /vmunix.OLD adb -w /vmunix ipforwarding/W 0 ^D Make sure the /W is upper case. It should say 1 --> 0. The subnet patch may introduce disagreements as to what the broadcast address is. This can cause chaos. Turning off forwarding, except on actual gateways, can make things a lot better. They actual gateways should have some repair work done to in_forward, so that they don't forward packets with bogus broadcast addresses. I suggest throwing away any packet that matches your class B address, and whose low-order byte is 0 or 255. Also any address whose first byte is 127 or 255. But others have done more work on this than I and probably have better filters. You need to decide what you want your broadcast address to be. 4.2 and the Sun kernel use the convention that the broadcast address uses a host number of 0. The newest convention, implemented in 4.3, uses a host number of -1, i.e. 255. The standards were only changed recently, so must vendors have not caught up. Consider our network, which is a class B network, 128.6. On subnet 4, there are the following possible broadcast addresses: 128.6.0.0 - used by 4.2 128.6.4.0 - used by 4.2 if you install subnets 128.6.255.255 - used by 4.3, I think 128.6.4.255 - used by 4.3 with subnets turned on, I think 255.255.255.255 - not used by any, but recognized by Sun and 4.3 When you enable subnets, the subnet number becomes in effect part of your network number. Thus the network number is 128.6.x, not just 128.6. So the broadcast address ends up having the subnet number as part of it. Now, the problem is that the Suns are set up such that every machine on the network, including non-Suns, must agree on the broadcast address. Otherwise there will be chaos and your network will be flooded with spurious packets, causing all of your machines to become unusable. By far the simplest approach is to use a broadcast address of 128.6.4.0. The standards documents, and I think 4.3, all do imply that the subnet number should be included in the broadcast address. 128.6.4.255 would in fact be better, but it is harder to do without source, and is going to cause trouble until everybody updates to the new conventions (possibly including changes to the Sun ROM's). Nevertheless, we decided to use 128.6.0.0. We don't have as much control over the network as I would like, and I was worried that somebody would put up standard (non-subnet) Sun software on some machine without talking to me. Thus it seemed safer to use a subnet address that would be compatible with unmodified software. This patch is possible, but not easy, without source. I believe the following instructions will suffice to allow the 128.6.4.0 type broadcast address without source. A patch to use 128.6.0.0 type broadcast address is a bit more complex. It is easiest to do this patch by using a source version of the module in.c. I am including the change to in.h and in.c. MYSUBNET and possibly the masks in in.h. However if you change the masks, some of the binary patches may not work. Anyway, here is what to do: Use this version of in.c and in.h in building your kernel. I trust you know enough about building it to make this work without more detailed instructions. There are patches to umount and ypbind necessary. If you have source, just make the same patches as in in.c to the library routines inet_netof and inet_lnaof in libc.a, and rebuild umount and ypbind. If you don't, the following will give reasonable approximations. They treat all addresses as class C. Since umount and ypbind should only be seeing packets from a local host, that is a reasonable approximation. This is for version 3.0. change 660e to 602c at the following address sun 3 sun 2 umount 3f5a 3f72 ypbind 3b42 3b42 It is critical to update /etc/umount on *every* client at the same time. There are patches to boot necessary. If you have source, you need to patch in_lnaof and in_broadaddr in the obvious way. If not, then again we have an approximation based on the assumption that boot is only going to deal with local hosts. In /tftpboot, change ndboot.sun[23].pub[01]: sun3 sun2 change 660a to 6024 at 5514 5662 change 6610 to 6650 at 5558 56a6 In /pub/boot, make the corresponding changes, except that the addresses are 90000 (hex) higher. You may have to do installboot, or patch other copies of boot, depending upon your machines and configurations. If you have source, you will need to change in_lnaof and some name like in_isbroadcast. Here are the changes to in.c .... in_netof(in) struct in_addr in; { register u_long i = ntohl(in.s_addr); /* 6 SUBNET hack */ if ((i & SUBNETMASK) == MYSUBNET) return (((i)&SUBNETNET) >> SUBNETSHIFT); /* end SUBNET hack */ if (IN_CLASSA(i)) return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); ... in_lnaof(in) struct in_addr in; { register u_long i = ntohl(in.s_addr); /* 6 SUBNET hack */ if ((i & SUBNETMASK) == MYSUBNET) return ((i)&SUBNETHOST); /* end SUBNET hack */ if (IN_CLASSA(i)) return ((i)&IN_CLASSA_HOST); In in.h, add the following. Use your own net number for MYSUBNET. /* 6 subnet - this implementation hardwires the parameters here * instead of using settable masks, etc., as 4.3 does */ #define MYSUBNET 0x80060000 #define SUBNETMASK 0xffff0000 #define SUBNETNET 0xffffff00 #define SUBNETSHIFT 8 #define SUBNETHOST 0x000000ff -------