我想发送一个包到另一台机器,但在以太网头有不同的mac地址。为此,我在c中使用原始套接字,并创建自己的以太网头,以便可以根据需要设置源mac。问题是我不确定要在头中填写哪个目的地mac地址。我知道目标机器的IP,但不知道Mac。即使我知道,我也不想硬编码这台Mac电脑。
我看到的一个选择是,我的机器将知道它的arp表中的mac,我可以读取它,得到mac地址并填写它。但是,在发送每个包之前执行此操作是开销。我可以读一次然后继续使用,但是如果有一天目标机器被替换了呢。管理员将为新计算机分配相同的IP地址,但MAC地址将不同。可能当新机器启动时,它会发送一个无偿的arp,而我的机器会更新它的arp表。但我的程序不知道。我的程序会一直用旧的mac发送数据包。
我觉得我错过了一些很基本的东西。思想?
最佳答案
您在这里看到的是每个试图实现网络堆栈的人都面临的相同问题。
你有几个选择:
如果包是一个应答包,那么只需使用from地址的mac地址
如果表中的条目丢失或过时,您可以维护自己的arp表并发送arp请求。解析arp应答并相应地更新表。在没有有效arp表项的情况下发送的数据包必须排队。这是最优雅的,但也是一个非常苛刻的选择。
您只需将数据包发送到本地路由器的mac。它将数据包转发到IP报头中指定的正确主机。如果您的本地路由器使用VRRP、HSRP或GBLP等协议,那么即使您的路由器被替换,MAC地址也始终相同且不变。
您可以从/proc/net/arp
或使用ioctl(SIOCGARP, ...);
读取mac地址,但如果您的主机最近没有尝试与之通信,则您正在查找的ip的条目可能不存在。当然,在读取arp表之前,您可以向该主机发送一个带有sendto();
的虚拟数据包。
如果你更详细地描述你计划做什么,建议可能会更好。
关于c - 查找以太网头的下一跳MAC地址,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51837388/