[root@GFVM4 ~]# hostname
GFVM4
[root@GFVM4 ~]#
[root@GFVM4 ~]#
[root@GFVM4 ~]# getent hosts gfvm4
192.168.122.151 GFVM4
[root@GFVM4 ~]# getent hosts GFVM4
fe80::5054:ff:feac:787 GFVM4
[root@GFVM4 ~]#
[root@GFVM4 ~]#
[root@GFVM4 ~]#
[root@GFVM4 ~]# ifconfig ens5
ens5: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.122.151 netmask 255.255.255.0 broadcast 192.168.122.255
inet6 fe80::5054:ff:feac:787 prefixlen 64 scopeid 0x20<link>
ether 52:54:00:ac:07:87 txqueuelen 1000 (Ethernet)
RX packets 452 bytes 33008 (32.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 204 bytes 26112 (25.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@GFVM4 ~]#
以上是预期的行为吗?
正如您所见,我已设置全部大写的 HOSTNAME GFVM4。
如果我使用相同的名称(全部大写),它将返回 ipv6 地址。如果我使用小写字母的主机名,它将返回 ipv4 地址。
这是正确的行为吗?
将 Fedora21 作为基于 qemu 的 VM 运行。
谢谢
答案1
这不是一个完整的答案,只是想分享我的发现,而且它太长了,无法容纳在评论中......
首先,如果您想回复,getent
您需要在、、等中进行正确的配置。/etc/nsswitch.conf
我/etc/resolv.conf
有/etc/hosts
一个 Fedora 22,它在中有以下几行/etc/nsswitch.conf
。
hosts: files mdns4_minimal [NUTFOUND=return] dns myhostname
getent hosts localhost
和getent hosts LOCALHOST
给出了不同的结果。但是当我改为 之后/etc/nsswitch.conf
,hosts: files
它们给出了相同的结果。
我认为当您有多个来源进行搜索时,他们可能会以不同的方式处理案例并给出不一致的结果。
其次,您可能想尝试getent ahost
。它使用getaddrinfo()
而不是gethostbyname2()
。至少在我的例子中,它给出了更一致的答案。参见man getent
。
第三,我发现阅读源代码很有趣获取客户端并通过 观察跟踪ltrace getent hosts localhost
。您可以在那里看到inet_pton()
和gethostbyname2()
。您还可以通过 跟踪系统调用ltrace -S
,并可以看到打开了哪些文件,例如/etc/hosts
。
以下是 的输出ltrace
。在 AF_INET (2) 之前尝试 AF_INET6 (10)。
[a@localhost ~]$ ltrace getent hosts LOCALHOST
__libc_start_main([ "getent", "hosts", "LOCALHOST" ] <unfinished ...>
mtrace() = <void>
setlocale(LC_ALL, "") = "en_US.UTF-8"
textdomain("libc") = "libc"
argp_parse(0x606440, 3, 0x7ffc1cf8a7c8, 0) = 0
strcmp("hosts", "hosts") = 0
inet_pton(10, 0x7ffc1cf8c67a, 0x7ffc1cf8a680, 0) = 0
inet_pton(2, 0x7ffc1cf8c67a, 0x7ffc1cf8a680, 0x658e2f20) = 0
gethostbyname2(0x7ffc1cf8c67a, 10, 0x7ffc1cf8a680, 0x658e2f20) = 0
gethostbyname2(0x7ffc1cf8c67a, 2, -20, 0x7f166586c8f5) = 0x7f1665b16260
inet_ntop(2, 0xc47000, 0x7ffc1cf8a620, 46) = 0x7ffc1cf8a620
printf("%-15s %s", "127.0.0.1", "localhost.localdomain") = 37
__overflow(0x7f1665b13620, 32, 0, 0x7fffffda) = 32
fputs_unlocked(0xc47041, 0x7f1665b13620, 0x7f1665d36025, 0xfbad2a84) = 1
__overflow(0x7f1665b13620, 10, 0xc47050, 0x74736f686c61636f127.0.0.1 localhost.localdomain localhost
) = 10
+++ exited (status 0) +++
最后,我的建议是 1)控制来源getent
;/etc/nsswitch.conf
或 2)维护自己的数据库/词典。
答案2
只是猜测,但从http://linuxmanpages.net/manpages/fedora21/man1/getent.1.html:
hosts 当没有提供密钥时,使用 sethostent(3)、gethostent(3), 和 endhostent(3) 枚举主机数据库。当 提供一个或多个关键参数,将每个键传递给 gethostbyaddr(3) 或 gethostbyname2(3),取决于 对 inet_pton(3) 的调用是否表明密钥是 是否为 IPv6 或 IPv4 地址,并显示结果。
在http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/usr.bin/getent/getent.c“if (argc == 2)” 表示“% getent hosts”(未提供键),因此执行以下操作:
for (i = 2; i < argc; i++) {
if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0)
he = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6);
else if (inet_pton(AF_INET, argv[i], (void *)addr) > 0)
he = gethostbyaddr(addr, INADDRSZ, AF_INET);
else
he = gethostbyname(argv[i]);
if (he != NULL)
hostsprint(he);
else {
rv = RV_NOTFOUND;
break;
}
}
我不擅长 C 语言,而且我通过快速谷歌搜索找到的唯一来源是 NetBSD,但似乎如果第一个 inet_pton(http://linuxmanpages.net/manpages/fedora21/man3/inet_pton.3.html) 找到 IPv6 的条目,则跳过 IPv4 的第二个函数。此外,乍一看,我没有看到任何强制大小写(这意味着区分大小写似乎不是强制的)。
也就是说,GFVM4 可能有 2 个条目,一个在上,另一个在下。上一个条目可能与 IPv6 地址相关联。
如果您能针对不同情况下的不同条目提供确认或不确认信息,以便确认(或不确认),那就太好了。如果确认,我会说这是 getent 软件的预期行为。