当前位置: 首页 > 面试题库 >

如何在Linux中通过特定接口发送多播数据包

申屠黎昕
2023-03-14
问题内容

尝试了所有可能的方法后,找不到解决该问题的方法。我有一台具有两个接口eth0和eth2的机器。我希望所有ff38:40:2001:dead:beef:cafe
:: // 96数据包都在eth2上传输。我尝试了以下所有操作,但在执行ping6 ff38:40:2001:dead:beef:cafe ::
1时,数据包始终在eth0上进行。我尝试过但没有奏效的事情(即,数据包在eth0上仍然熄灭)。

$> route add --inet6 ff38:40:2001:dead:beef:cafe::/96 gw 2003::100 dev eth2
$> route add --inet6 ff38:40:2001:dead:beef:cafe::/96 dev eth2
$> route add --inet6 ff38:40:2001:dead:beef:cafe::/96 metric 1 gw 2003::100 dev eth2

我的路由表是

[root@dev ~]# route --inet6  |grep eth0
fe80::/64                                   *                                       U     256    0        0 eth0
ff00::/8                                    *                                       U     256    0        0 eth0

[root@dev ~]# route --inet6  |grep eth2
2003::/64                                   *                                       U     256    68       0 eth2
fe80::/64                                   *                                       U     256    0        0 eth2
ff38:40:2001:dead:beef:cafe::/96            2003::100                               UG    1      0        0 eth2
*/0                                         fe80::c671:feff:fe14:e482               UGDA  1024   0        0 eth2
ff00::/8                                    *                                       U     256    0        0 eth2

但是,ping6 ff38:40:2001:dead:beef:cafe ::
1-我eth2正常工作。此外,我仅在Linux机器上看到此问题(MAC很好)。

[root@dev ~]# ping6 ff38:40:2001:dead:beef:cafe::1 -I eth2
PING ff38:40:2001:dead:beef:cafe::1(ff38:40:2001:dead:beef:cafe:0:1) from cal eth2: 56 data bytes
64 bytes from 2012::1: icmp_seq=0 ttl=253 time=19.1 ms
64 bytes from 2012::1: icmp_seq=1 ttl=253 time=2.16 ms
64 bytes from 2012::1: icmp_seq=2 ttl=253 time=2.14 ms
64 bytes from 2012::1: icmp_seq=3 ttl=253 time=2.26 ms
64 bytes from 2012::1: icmp_seq=4 ttl=253 time=2.08 ms
64 bytes from 2012::1: icmp_seq=5 ttl=253 time=2.15 ms

root@dev ~]# uname -a
Linux 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:39 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux

可能是因为eth0有一个ff00 :: / 8的事实。我如何推翻那条路线。我也无法删除ff00 :: / 8路由。


问题答案:

我并不完全相信我的解决方案是正确的,但是我至少可以对所发生的事情有更多的了解。

背景

Linux实际上有多个路由表,并且以特定的优先级顺序一次搜索一个路由表,直到找到具有匹配路由的表。您可以选择根据源地址或协议搜索某些路由表。参见ip- rule(8)手册页。

麻烦的是“本地”路由表,它的优先级为0,可能是最高的。内核自动填充“本地”表,其中包含“显而易见的”接口和广播路由。对于Linux下的IPv6,这显然包括整个多播块。

问题

我将使用 iproute2 工具,而不是更传统的工具route,因为它将向我展示我需要知道的所有信息。

在我的Linux机器上:

$ ip -6 route show table local
local ::1 via :: dev lo  proto none  metric 0 
local fe80::213:a9ff:fe91:5bcb via :: dev lo  proto none  metric 0 
local fe80::250:b6ff:fe44:37d1 via :: dev lo  proto none  metric 0 
ff00::/8 dev eth0  metric 256 
ff00::/8 dev eth1  metric 256

$ ip -6 route show table main
fe80::/64 dev eth0  proto kernel  metric 256 
fe80::/64 dev eth1  proto kernel  metric 256 
ff15::/16 dev eth1  metric 1024
ff00::/8 dev eth1  metric 1024

$ ip -6 rule show
0:      from all lookup local 
32766:  from all lookup main

…而且我的ff15 :: 1(5 == site-local,> link-
local)的多播数据包最终到达eth0,因为“本地”路由表首先匹配并覆盖了“主”表,即使“主”表具有更具体的路由。在较大的策略路由方案中,此替代行为是正确的,但是将ff00
:: / 8自动添加到本地表的选择对我来说是个问题。

我的解决方案

我没有足够的经验来知道这是否是一个好主意,但是:

# ip -6 route add ff15::/16 dev eth1 table local

现在我的ff15 :: 1数据包通过eth1路由。

这与本地表的语义有些一致,因为它直接通过设备进行路由。感觉并不完全正确(考虑自动管理和“您不必看这张表”),但这是我找到的最佳解决方案。



 类似资料:
  • 我一直在用c做一些套接字编程,我想让我的程序的用户指定要从中发送和接收数据包的接口。套接字(7) 的 linux 手册页说, 你可以设置套接字选项SO_BINDTODEVICE将套接字绑定到一个特定的设备, 比如 “eth0”。我还想到,在调用 bind() 时,您通常会向它传递一个sockaddr_in结构,并将 sin_addr.s_addr 属性设置为 INADDR_ANY 以指示套接字绑定

  • 问题内容: 我有两个可以同时访问互联网的网络接口(WiFi和以太网)。假设我的界面是(以太网)和(wifi)。我需要特定的请求才能通过接口,其他需要通过。 就像是: 我正在使用,但是我可以使用或如果没有任何方法可以使用它。 问题答案: 我找到了使用的方法。这就像一个魅力。 我让问题悬而未决,希望有人可以使用给出答案。

  • 在我的应用程序中,如果多个用户使用相同的WiFi连接而不使用TCP,我希望通过WiFi将文件发送给多个用户。如何获取连接到指定wify的用户列表。我试过样品,但什么也没得到。

  • 是否可以使用邻居缓存中的链接地址从udp客户端节点向邻居发送自定义数据包?我正在寻找一种避免发送icmpv6数据包的方法,因为它将到达根目录,然后根目录将其发送到目标目录。我看到Contiki启用了mesh拓扑,所以应该可以直接向邻居发送数据包,而无需将数据包转发给父级。我将非常感谢您在这方面的任何帮助!

  • 我有一个数组类型的。我必须在python中通过流/TCP套接字发送它。然后我必须在接收端接收相同的阵列。

  • 问题内容: 我真的很困惑如何通过套接字发送图像数据类型。请帮我。我已经搜寻了如何将Image数据类型转换为char [],但结果为0。 问题答案: 您可以使用以下方法将其转换为(source): 然后,您可以使用ImageIO.write()方法写入结果。