subnetting on Suns

11 Aug 86 09:08:38 EDT

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
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: - used by 4.2 - used by 4.2 if you install subnets - used by 4.3, I think - used by 4.3 with subnets turned on, I think - 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 The standards documents, and I think 4.3, all do imply
that the subnet number should be included in the broadcast address. 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 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
type broadcast address without source. A patch to use
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


        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);


        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 SUBNETHOST 0x000000ff

This archive was generated by hypermail 2.0b3 on Thu Mar 09 2000 - 14:36:35 GMT