I am working on a PDP-10 emulator (see https://github.com/Rhialto/klh10 ). The operating system installed inside it may want to communicate with the outside world via IPv4 (which was just gaining use when those machines were popular). For this purpose, the emulator opens a packet filter (or alternatively, a tap device) on the host machine.
Suppose you're on a local network, 10.0.0.x. The emulated OS may use an IPv4 address of, say, 10.0.0.51.
In order for other hosts on the same network to be able to communicate with the virtual host, they send ARP requests for 10.0.0.51. I want the Unix kernel to answer these requests for me with a sensible ethernet address (which is called proxy-ARP).
To make the Unix do this, the emulator does (the equivalent of) "arp -s 10.0.0.51 01:23:45:56:78:9A pub", where the ethernet address of the host OS is used.
On other Unixen than Linux, this has the desired effect. If I attempt to telnet, or ping, to 10.0.0.51 I see the ARP requests go out for the emulated host, and replies come back:
23:13:42.391941 ARP, Request who-has 10.0.0.51 tell 10.0.0.16, length 46 23:13:42.391954 ARP, Reply 10.0.0.51 is-at f6:2b:a4:a0:76:b0 (oui Unknown), length 28
However, on Linux (I have Ubuntu 15.10), this does not work. The entry does show up in the ARP table with "arp -a", although in a weird way:
? (10.0.0.51) at <from_interface> PERM PUB on eth0
I have tried a few seemingly related sysctls to try to enable the proxy ARPing, such as
net.ipv4.conf.all.proxy_arp = 1 net.ipv4.conf.default.proxy_arp = 1 net.ipv4.conf.eth0.proxy_arp = 1
net.ipv4.ip_forward = 1
but none of this helps. What am I missing?
I can test this just using the arp command on the Linux box, a tcpdump for observation, and another box to initiate ARP requests. When I get it to work, I can install any necessary extra setup steps into the emulator.
EDIT: here is a simple scenario to try, if you have 2 machines on the same network, one of which is Linux:
- On the Linux box, do
sudo arp -s 10.0.0.51 01:23:45:56:78:9A pub. You may need to substitute a different IP address if you're using a different local network; the address should not exist but fit inside your network.
192.168.0.51could be a possibility. Also, I noticed that Ubuntu refused to accept random ethernet addresses, so you may need to substitute an ethernet address of the eth0 interface.
- On the same or other box,
sudo tcpdump -i eth0 arp. This will show all ARP requests and replies on the network.
- On some other box, which may be a different operating system altogether, do
ping 10.0.0.51(or the address you used, of course). Expected result: the running tcpdump command should show ARP Requests and ARP Replies. If it doesn't, I would like to know what setting is needed to make it happen. And if this is Ubuntu-specific perhaps. The
pingwill ultimately fail (no host by that IP address is available) but that is immaterial in this test. If it says
ping: sendto: Host is downit means it knows there is no ARP Reply.