我正在开展一个项目,试图开发一种用于单向数据传输的数据二极管,我希望使用 socat 进行一些测量。作为第一步,我想使用 socat 通过以太网电缆将数据从一个 NIC 发送到同一台 PC 上的另一个 NIC。我正在运行 Ubuntu 22.04。我手动配置了每个 NIC 的 IP 地址,然后使用以太网电缆将它们连接在一起。最后,我添加了一个手动 arp 条目:
$ sudo arp -s 10.0.1.1 48:21:0b:3e:76:ce -i enp89s0
$ arp -a
story-NUC11 (10.0.1.1) at 48:21:0b:3e:76:ce [ether] PERM on enp89s0
...
每个 NIC 的详细信息:
NIC 1: enp88s0
inet 10.0.1.1
netmask 255.255.255.0
ether 48:21:0b:3e:76:ce
NIC 2: enp89s0
inet 10.0.1.2
netmask 255.255.255.0
ether 48:21:0b:3e:4f:df
我认为将数据从 NIC 2 传输到 NIC 1 就像运行这些 socat 命令一样简单:
# To receive on NIC 1
socat -u UDP-RECV:1234,bind=10.0.1.1,so-bindtodevice=enp88s0 -
# To send to NIC 1 using NIC 2
socat -u - UDP:10.0.1.1:1234,so-bindtodevice=enp89s0
然而,没有这样的运气。接收命令从未回显任何输出。
当我使用 Wireshark(编辑:和 tcpdump)监听 enp88s0(NIC 1)时,我看到了 NIC 2 正在发送的 UDP 数据包。我还使用 tcpdump 观察了环回接口,但没有看到任何数据包通过环回传输。由于数据是通过以太网电缆传输的,这表明我的接收命令不正确。但是,我尝试了许多排列,我的接收命令从未回显任何内容。有什么想法吗?
编辑:将 IP 切换至 10.0.1.X 子网。
答案1
该命令看起来不错;在 enp88s0 上执行 tcpdump/wireshark 时,您可能会检查 MAC 地址,只是为了确保数据包使用了线路。
尝试不带绑定的接收器(因此只能使用 so-bindtodevice),反之亦然!
答案2
我不确定为什么 socat 在这种情况下不起作用,但我确实找到了一种使用网络命名空间的解决方案,基于此解决方案。
对于我的单向用例:
# Create a sender namespace
sudo ip netns add sender
# Move link into sender namespace
sudo ip link set enp89s0 netns sender
# Set the ip for the link
sudo ip netns exec sender ip addr add dev enp89s0 10.0.1.2/24
# Bring the link up
sudo ip netns exec sender ip link set dev enp89s0 up
# Where should outbound traffic go? To 10.0.1.1.
# Destination IPs must be on the same subnet as this interface's IP.
sudo ip netns exec sender route add default gw 10.0.1.1
# Add manual ARP entry
sudo ip netns exec sender arp -s 10.0.1.1 48:21:0b:3e:76:ce -i enp89s0
然后,我只需在网络命名空间中运行发送方,接收方就可以毫无问题地接收数据:
sudo ip netns exec sender socat -u - UDP:10.0.1.1:1234,so-bindtodevice=enp89s0
事实上,使用命名空间时甚至不需要显式绑定到接口。因此,使用以下命令即可:
# Receiver
socat -u UDP-RECV:1234 -
# Sender
sudo ip netns exec sender socat -u - UDP:10.0.1.1:1234
网络命名空间才是正确方法!