如何通过 Python 或 Perl 查询网关的 DNS 地址

How to query gateway for DNS adress by Python or Perl

Linux/Windows可以从路由器获取DNS地址

我需要编写一个本地 DNS 代理,我怎样才能像 OS 那样获取 DNS 服务器地址,是否有任何 Perl 或 Python 模块可以做到这一点?

更新

问题应该很清楚了,我需要一些东西来模拟接口启动和与本地路由器通信的协议,我不能在接口启动之前进行 tcpdump。不确定互联网上是否有示例跟踪文件。可能不是我不熟悉的IP协议

更新2

由于我使用的是本地DNS代理服务器,TCP配置如图所示

如果我查询 Net::DNS::Resolver,我得到结果:127.0.0.1 这不是我需要的

gethostbyname 使用底层 OS 库的解析器函数。如果您想更直接地访问 DNS 数据包,请使用 Net::DNS::Resolver.

非常长的格式化评论支持 Steffen 的回答。

TLDR:Steffen 是正确的(+1 顺便说一句)。 Net::DNS::Resolver 应该可以为您提供所需的信息。

示例:

#!perl
use strict;
use warnings;

use Net::DNS::Resolver;

#configure a resolver object using your OS's current config.
my $resolver = Net::DNS::Resolver->new;

print join "\n", $resolver->nameservers;

在 Windows & OS X 上测试。


如果你真的想找绳子上吊,你问的协议是 DHCP(动态主机配置协议)。

像您的 OS 那样使用 DHCP,不仅仅是 "Query" DNS 服务器,而是请求 (new/renewed) 租约 的 IP 地址。包括网关、时间服务器和 DNS 服务器之类的东西也很重要,但次要。如果操作不当,您可能会搞砸 OS 和 DHCP 服务器之间的关系,或者让您的 DHCP 服务器相信您的程序是网络上的另一台(假)机器,它应该维护租用信息。

灵感来自 Steffen Ullrich 我通过 Net::DHCP::Packet 管理获取 DHCP 跟踪并模拟来解决问题,幸运的是它是简单的 UDP 协议

使用脚本前需要先找到IP/Mac/GW地址

#!/usr/bin/perl

use strict;
use warnings;
use IO::Socket::INET;
use Net::DHCP::Packet;
use Net::DHCP::Constants;
srand();

# creat DHCP Packet
my $discover = Net::DHCP::Packet->new(
    Xid                     => int(rand(0xFFFFFFFF)),    # random xid
    Flags                   => 0x0000,                   
    DHO_DHCP_MESSAGE_TYPE() => DHCPREQUEST(),
);
$discover->ciaddr('192.168.1.5');
$discover->chaddr('5cc5d43ca078');

my $handle = IO::Socket::INET->new(
    Proto     => 'udp',
    ReuseAddr => 1,
    PeerPort  => '67',
    LocalPort => '68',
    PeerAddr  => '192.168.1.1'
) or die "socket: $@";

$handle->send($discover->serialize());
my $newmsg;
if ($handle->recv($newmsg, 1024)) {
    my $packet = Net::DHCP::Packet->new($newmsg);
    print STDERR $packet->toString();
}

执行结果:

op = BOOTREPLY
htype = HTYPE_ETHER
hlen = 6
hops = 0
xid = eaba416c
secs = 0
flags = 0
ciaddr = 192.168.1.5
yiaddr = 192.168.1.5
siaddr = 0.0.0.0
giaddr = 0.0.0.0
chaddr = 5cc5d43ca078
sname =
file =
Options :
 DHO_DHCP_MESSAGE_TYPE(53) = DHCPACK
 DHO_SUBNET_MASK(1) = 255.255.255.0
 DHO_ROUTERS(3) = 192.168.1.1
 DHO_DOMAIN_NAME_SERVERS(6) = 192.168.1.1
 DHO_DHCP_SERVER_IDENTIFIER(54) = 192.168.1.1
 DHO_DHCP_LEASE_TIME(51) = 86400
 DHO_VI_VENDOR_SPECIFIC_INFOMATION(125) = \x00\x00\x00\x00\x14\x02\x06HGW-CT\x0A\x02\x00\x00\x0B\x02\x00U\x0D\x02\x00.
padding [247] = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

我们可以看到

DHO_DOMAIN_NAME_SERVERS(6) = 192.168.1.1

是DNS服务器地址