4. 设置使用子网的 Proxy ARP

我在一台 Linux 内核版本 2.0.30 的机器上设置了使用子网的 Proxy ARP,但我被告知该代码可以追溯到 1.2.x 时代的某些内核版本。

首先需要注意的是,ARP 代码分为两个部分:内核内部发送和接收 ARP 请求和响应并更新 ARP 缓存等的部分;另一部分是 arp(8) 命令,超级用户可以使用该命令手动修改 ARP 缓存,任何人都可以使用它来检查缓存。

我遇到的第一个问题是我的 Slackware 3.1 发行版附带的 arp(8) 命令非常旧(1994 年代!!!),并且根本无法与内核 arp 代码正确通信(主要是通过它为 “arp -a” 提供的奇怪输出证明的)。

“net-tools-1.33a” 软件包中的 arp(8) 命令可以从多个地方获得,包括(来自README它附带的文件)ftp.linux.org.uk:/pub/linux/Networking/base/ 可以正常工作,并且包含新的手册页,这些手册页比旧的 arp(8) 手册页更好地解释了内容。

有了功能完善的 arp(8) 命令,我所做的所有更改都在/etc/rc.d/rc.inet1脚本(对于 Slackware - 对于其他发行版可能不同)。首先,我们需要更改 eth0 的广播地址、网络号和子网掩码

NETMASK=255.255.255.240 # for a 4-bit host part
NETWORK=x.y.z.64        # our new network number (replace x.y.z with your net)
BROADCAST=x.y.z.79      # in my case

然后需要添加一行来配置第二个以太网端口(在可能需要加载驱动程序代码的任何模块加载之后)

/sbin/ifconfig eth1 (name on net 1) broadcast (x.y.z.255) netmask 255.255.255.0

然后我们为新接口添加路由

/sbin/route add -net (x.y.z.0) netmask 255.255.255.0

而且您可能需要将默认网关更改为网络 1 的网关。

此时,添加 Proxy ARP 条目是合适的

/sbin/arp -i eth1 -Ds ${NETWORK} eth1 netmask ${NETMASK} pub

这指示 ARP 为网络 ${NETWORK} 在缓存中添加一个静态条目 (s)。-D 告诉 ARP 使用与接口 eth1 (第二个 eth1) 相同的硬件地址,从而省去了我们查找 eth1 的硬件地址并将其硬编码的麻烦。“netmask” 选项告诉 ARP 我们要使用子网(即,代理所有 (IP 地址) & ${NETMASK} == ${NETWORK} & ${NETMASK})。“pub” 选项告诉 ARP 发布此 ARP 条目,即,它是一个代理条目,因此代表这些 IP 地址进行响应。“-i eth1” 选项告诉 ARP 仅响应从接口 eth1 进入的请求。

希望在此时,当机器重启后,网络 0 上的所有机器都将显示在网络 1 上。您可以检查使用子网的 Proxy ARP 条目是否已在机器 A 上正确安装。在我的机器上(名称已更改以保护无辜者)它是

bash$ /sbin/arp -an
Address                 HWtype  HWaddress           Flags Mask            Iface
x.y.z.1                 ether   00:00:0C:13:6F:17   C     *               eth1
x.y.z.65                ether   00:40:05:49:77:01   C     *               eth0
x.y.z.67                ether   08:00:20:0B:79:47   C     *               eth0
x.y.z.5                 ether   00:00:3B:80:18:E5   C     *               eth1
x.y.z.64                ether   00:40:96:20:CD:D2   CMP   255.255.255.240 eth1

或者,您可以检查/proc/net/arp文件,例如使用 cat(1)。

最后一行是子网的代理条目。“CMP” 标志表明这是一个静态(手动输入)条目,并且将被发布。该条目仅会回复 eth1 上的 ARP 请求,其中请求的 IP 地址在掩码后与网络号(也掩码)匹配。请注意,arp(8) 已自动确定 eth1 的硬件地址,并将其插入为要使用的地址(-Ds 选项)。

同样,检查路由表是否已正确设置可能是明智的。这是我的路由表(同样,名称已更改以保护无辜者)

#/bin/netstat -rn
Kernel routing table
Destination     Gateway         Genmask         Flags Metric Ref Use    Iface
x.y.z.64        0.0.0.0         255.255.255.240 U     0      0       71 eth0
x.y.z.0         0.0.0.0         255.255.255.0   U     0      0      389 eth1
127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        7 lo
0.0.0.0         x.y.z.1         0.0.0.0         UG    1      0      573 eth1

或者,您可以检查/proc/net/route文件,例如使用 cat(1)。

请注意,第一个条目是第二个条目的真子集,但路由表已按子网掩码顺序对它们进行排序,因此将先检查 eth0 条目,然后再检查 eth1 条目。