3. How Proxy ARP with subnetting works

The Proxy ARP is actually only used to get packets from network 1 to network 0. To get packets back the other way, the normal IP routing functionality is employed.

In my case, network 1 has an 8-bit subnet mask (255.255.255.0). I have chosen the subnet mask for network 0 to be 4-bit (255.255.255.240), allowing 14 IP nodes on network 0 (2 ^ 4 = 16, less two for the all zeros and all ones cases). Note that any size of subnet mask up to, but not including, the size of the mask of the other network is allowable here (eg. 2, 3, 4, 5, 6 or 7 bits in this case - for one bit, just use normal Proxy ARP!)

All the IP numbers for network 0 (16 in total) appear in network 1 as a subset. Note that it is very important, in this case, not to allow any machine connected directly to network 1 to have an IP number in this range! In my case, I have "reserved" the IP numbers of network 1 ending in 64 .. 79 for network 0. In this case, the IP numbers ending in 64 and 79 can't actually be used by nodes - 79 is the broadcast address for network 0.

Machine A is allocated two IP numbers, one within the network 0 range for it's real Ethernet interface (eth0) and the other within the network 1 range, but outside of the network 0 range, for the wireless Ethernet interface (eth1).

Say machine C (on network 1) wants to send a packet to machine B (on network 0). Because the IP number of machine B makes it look to machine C as though it is on the same physical network, machine C will use the Address Resolution Protocol (ARP) to send a broadcast message on network 1 requesting the machine with the IP number of machine B to respond with it's hardware (Ethernet or MAC layer) address. Machine B won't see this request, as it isn't actually on network 1, but machine A, on both networks, will see it.

The first bit of magic now happens as the Linux kernel arp code on machine A, with a properly configured Proxy ARP with subnetting entry, determines that the ARP request has come in on the network 1 interface (eth1) and that the IP number being ARP'd for is in the subnet range for network 0. Machine A then sends it's own hardware (Ethernet) address back to machine C as an ARP response packet.

Machine C then updates it's ARP cache with an entry for machine B, but with the hardware (Ethernet) address of machine A (in this case, the wireless Ethernet interface). Machine C can now send the packet for machine B to this hardware (Ethernet) address, and machine A receives it.

Machine A notices that the destination IP number in the packet is that of machine B, not itself. Machine A's Linux kernel IP routing code attempts to forward the packet to machine B by looking at it's routing tables to determine which interface contains the network number for machine B. However, the IP number for machine B is valid for both the network 0 interface (eth0), and for the network 1 interface (eth1).

At this point, something else clever happens. Because the subnet mask for the network 0 interface has more 1 bits (it is more specific) than the subnet mask for the network 1 interface, the Linux kernel routing code will match the IP number for machine B to the network 0 interface, and not keep looking for the potential match with the network 1 interface (the one the packet came in on).

Now machine A needs to find out the "real" hardware (Ethernet) address for machine B (assuming that it doesn't already have it in the ARP cache). Machine A uses an ARP request, but this time the Linux kernel arp code notes that the request isn't coming from the network 1 interface (eth1), and so doesn't respond with the Proxy address of eth1. Instead, it sends the ARP request on the network 0 interface (eth0), where machine B will see it and respond with it's own (real) hardware (Ethernet) address. Now machine A can send the packet (from machine C) onto machine B.

Machine B gets the packet from machine C (via machine A) and then wants to send back a response. This time, machine B notices that machine C in on a different subnet (machine B's subnet mask of 255.255.255.240 excludes all machines not in the network 0 IP address range). Machine B is setup with a "default" route to machine A's network 0 IP number and sends the packet to machine A. This time, machine A's Linux kernel routing code determines the destination IP number (of machine C) as being on network 1 and sends the packet onto machine C via Ethernet interface eth1.

Similar (less complicated) things occur for packets originating from and destined to machine A from other machines on either of the two networks.

Similarly, it should be obvious that if another machine (D) on network 0 ARP's for machine B, machine A will receive the ARP request on it's network 0 interface (eth0) and won't respond to the request as it is set up to only Proxy on it's network 1 interface (eth1).

Note also that all of machines B and C (and D) are not required to do anything unusual, IP-wise. In my case, there is a mixture of Suns, Macs and PC/Windoze 95 machines on network 0 all connecting through Linux machine A to the rest of the world.

Finally, note that once the hardware (Ethernet) addresses are discovered by each of machines A, B, C (and D), they are placed in the ARP cache and subsequent packet transfers occur without the ARP overhead. The ARP caches normally expire entries after 5 minutes of non-activity.