为什么我可以通过部分IP地址访问服务器?

wie*_*oma 10 linux networking ip ping telnet

在我的网络中,我有一个 IP 地址为 10.0.0.15 的服务器。偶然地,我发现命令:ping 10.0.15导致

64 bytes from 10.0.0.15: icmp_seq=1 ttl=64 time=9.09 ms
Run Code Online (Sandbox Code Playgroud)

...所以正确的服务器响应 ping。即使我尝试:ping 10.15我也得到了可比较的结果。此外,到部分地址的 telnet 也按预期工作。但是,SSH 失败。为什么发送到部分地址的数据包会到达正确的服务器?

thr*_*rig 18

根据inet_aton(3)功能文档,这是一种允许的形式:

DESCRIPTION
       inet_aton() converts the Internet host address cp from  the  IPv4  num?
       bers-and-dots  notation  into  binary  form (in network byte order) and
       stores it in the structure that inp  points  to.   inet_aton()  returns
       nonzero  if the address is valid, zero if not.  The address supplied in
       cp can have one of the following forms:

       a.b.c.d   Each of the four  numeric  parts  specifies  a  byte  of  the
                 address;  the  bytes  are  assigned in left-to-right order to
                 produce the binary address.

       a.b.c     Parts a and b specify the  first  two  bytes  of  the  binary
                 address.   Part  c  is  interpreted  as  a  16-bit value that
                 defines the rightmost two bytes of the binary address.   This
                 notation  is  suitable for specifying (outmoded) Class B net?
                 work addresses.

       a.b       Part a specifies the first byte of the binary address.   Part
                 b is interpreted as a 24-bit value that defines the rightmost
                 three bytes of the binary address.  This notation is suitable
                 for specifying (outmoded) Class C network addresses.

       a         The  value  a is interpreted as a 32-bit value that is stored
                 directly into the binary address without any byte  rearrange?
                 ment.
Run Code Online (Sandbox Code Playgroud)

例如

$ perl -MSocket=inet_aton,inet_ntoa -E 'say inet_ntoa(inet_aton("10.0.15"))'
10.0.0.15
$ perl -MSocket=inet_aton,inet_ntoa -E 'say inet_ntoa(inet_aton("10.15"))'
10.0.0.15
$ 
Run Code Online (Sandbox Code Playgroud)

然而,现在最好使用getaddrinfoinet_ntop调用 IPv6 支持。“B 类”的东西在 1994 年左右成为遗产,现在我们有了 CIDR 和/24......

嘿,你也可以给它一个大的旧整数(但请不要)

$ perl -MSocket=inet_aton,inet_ntoa -E 'say inet_ntoa(inet_aton("2130706433"))'
127.0.0.1
$ getent hosts 2130706433
127.0.0.1       2130706433
$ ssh 2130706433
The authenticity of host '2130706433 (127.0.0.1)' can't be established.
...
Run Code Online (Sandbox Code Playgroud)

(这可能无法移植到其他 unix;尤其是 OpenBSD 无法解析 2130706433...)