PING命令如何找到所需的网络接口?

huangapple go评论72阅读模式
英文:

How does PING command find the required network interface?

问题

I'm using the ping command pretty often, but now when learning about network interfaces come to misunderstanding of how the desired interface is determined when pinging the required IP. I have the following network interfaces:

$ ifconfig
lo: [...]
      inet 127.0.0.1  netmask 255.0.0.0
      [...]

eth0: [...]
      inet 20.20.20.20  netmask 255.255.255.255
      [...]

virbr0: [...]
        inet 192.168.122.1 netmask 255.255.255.0


 //lots of other interfaces

示例 1.

I decided to run strace ping 8.8.8.8 to understand what we actually have under the hood and what I've noticed the following fragment:

socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 5
connect(5, {sa_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("8.8.8.8")}, 16) = 0
getsockname(5, {sa_family=AF_INET, sin_port=htons(46754), sin_addr=inet_addr("20.20.20.20")}, [16]) = 0
close(5)

The question is how ping understands that 8.8.8.8 can be reached via eth0 which my device has ip address 20.20.20.20?

示例 2.

When pinging my QEMUVM sudo strace -f ping 192.168.122.77 I got

socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 5
connect(5, {sa_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("192.168.122.77")}, 16) = 0
getsockname(5, {sa_family=AF_INET, sin_port=htons(33866), sin_addr=inet_addr("192.168.122.1")}, [16]) = 0
close(5)  

and it was also somehow undertood that the interface virbr0 should be used.

QUESTION:
How is it determined which network interface to use when ping-ing a specific ip address? Maybe I missed some dedicated syscall?

英文:

I'm using the ping command pretty often, but now when learning about network interfaces come to misunderstanding of how the desired interface is determined when pinging the required IP. I have the following network interfaces:

$ ifconfig
lo: [...]
      inet 127.0.0.1  netmask 255.0.0.0
      [...]

eth0: [...]
      inet 20.20.20.20  netmask 255.255.255.255
      [...]

virbr0: [...]
        inet 192.168.122.1 netmask 255.255.255.0


 //lots of other interfaces

Example 1.

I decided to run strace ping 8.8.8.8 to understand what we actually have under the hood and what I've noticed the following fragment:

socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 5
connect(5, {sa_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("8.8.8.8")}, 16) = 0
getsockname(5, {sa_family=AF_INET, sin_port=htons(46754), sin_addr=inet_addr("20.20.20.20")}, [16]) = 0
close(5)

The question is how ping understands that 8.8.8.8 can be reached via eth0 which my device has ip address 20.20.20.20?

Example 2.

When pinging my QEMUVM sudo strace -f ping 192.168.122.77 I got

socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 5
connect(5, {sa_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("192.168.122.77")}, 16) = 0
getsockname(5, {sa_family=AF_INET, sin_port=htons(33866), sin_addr=inet_addr("192.168.122.1")}, [16]) = 0
close(5)  

and it was also somehow undertood that the interface virbr0 should be used.

QUESTION:
How is it determined which network interface to use when ping-ing a specific ip address? Maybe I missed some dedicated syscall?

答案1

得分: 2

这是由操作系统中的路由层处理的。虽然在实践中可能会更加复杂,但基本思想是将目标地址与路由表进行匹配测试,并使用匹配的最具体路由。

例如,任何到127.0.0.0/8的东西都会被明确地路由到“localhost”或通常是lo类型的地址。

最一般的路由是0.0.0.0/0,代表“一切”,并且具有最低的优先级。前往此处的数据包将通过定义的“网关”(也就是您的上游路由器)传递。

中间某处是您的本地网络,如192.168.0.0/24或类似的,或者在某些情况下,根据您的配置,可能有多个本地网络。前往此处的数据包将直接通过匹配的接口发送到目标机器,不需要网关。

请注意,如果您要ping某些网络并希望使用特定的接口,例如有线而不是无线,您可以在使用之前将套接字绑定到特定地址。

由于您的计算机通常至少有两个接口,即localhost和某种其他网络连接,ping程序确实需要选择正确的接口,否则数据包将无法路由。例如,通过无线连接ping127.0.0.1将不起作用,而在环回接口上ping网络地址也没有意义,因为没有设备会响应。

如果您正在编写自己的ping程序,可能需要为localhost的ping划分一个特殊情况并相应地进行绑定。更强大的实现会检查路由表,并选择正确的地址进行发送。许多工具还具有-i类型的接口说明符,用于指定源IP或源接口。

英文:

This is handled by the routing layer in the OS. While it can be trickier in practice, the basic idea is that the target address is tested against the routing table, and the most specific route that matches is used.

For example, anything to 127.0.0.0/8 is routed, explicitly, to "localhost" or often the lo-type address.

The most general route is 0.0.0.0/0 which is "everything" and has the lowest precedence. Packets going here go through the defined "gateway", otherwise known as your upstream router.

Somewhere in the middle is your local network, like 192.168.0.0/24 or something like that, or in some cases multiple local networks depending on your config. Packets going here are sent out the matching interface directly to the destination machine, no gateway is required.

Note that if you're pinging certain networks and want to use a certain interface, like your wired instead of wireless, you can bind your socket to a specific address before using it.

Since your computer usually has at least two interfaces, localhost and some kind of other network connection, ping programs do need to select the correct interface or the packets won't be able to be routed. For example, pinging 127.0.0.1 out your wireless connection will go nowhere, while pinging a network address on the loopback interface is likewise pointless, no device will respond.

If you're writing your own ping, you may want to carve out a special case for localhost pings and bind accordingly. A more robust implementation checks the routing table, and picks the correct address to send from. Many tools also have a -i type interface specifier to specify either the source IP or the source interface.

huangapple
  • 本文由 发表于 2023年5月21日 07:48:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76297769.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定