-3

The Linux/Windows can get DNS address from the router

I need to write a local dns proxy and how can I get the DNS server addresses like the OS does, are there any Perl or Python modules can do this?

Update

The question should be clear, I need some thing to simulate the interface start and the protocol talking with local router, I can not take a tcpdump before a interface starts. Not sure if there is an sample trace file on internet. Possiblely it's not IP protocol which I am not familiar with.

Update2

dns

As I use local DNS proxy server, the TCP configuration is like showing in picture

If I query Net::DNS::Resolver, I get result: 127.0.0.1 which is not what I needed

Boying
  • 1,404
  • 13
  • 20

3 Answers3

3

Really long, formatted comment supporting Steffen's answer.

TLDR: Steffen is correct (+1 BTW). Net::DNS::Resolver should get you the information you need.

Example:

#!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;

Tested on Windows & OS X.


If you are serous in your quest for the rope to hang yourself, the protocol you're asking about is DHCP (Dynamic Host Configuration Protocol).

Using DHCP like your OS does, is not a mere "Query" for DNS servers, but a request for a (new/renewed) lease of an IP Address. The fact that things like Gateway, Time Servers & DNS Servers are included are also important, but secondary. If done incorrectly, you may either screw up the relationship between your OS and the DHCP server or convince your DHCP server that your program is another (false) machine on the network for which it should maintain lease information.

tjd
  • 4,064
  • 1
  • 24
  • 34
  • Unfortunately I need to simulate the OS behavior, as the DNS is configured as 127.0.0.1 which is not the real local DNS – Boying Dec 29 '15 at 03:10
  • @Boying, Most folks would have captured the "Good" DNS data before manually overriding it, but to each his own. If you don't want to temporarily undo your change & save it in a config file, you could always use Google's DNS (8.8.8.8) or OpenDNS, either of which could be a better idea than that of your ISP. If all else fails, you still have the option of lying to your DHCP server. – tjd Dec 29 '15 at 14:33
  • Unfortunately I'm in China, so these DNS are not stable and some times I'm in company's network, it's another DNS for intranetwork – Boying Dec 29 '15 at 15:00
  • Tnanks for the help! See my answer. – Boying Dec 29 '15 at 15:09
2

gethostbyname uses the resolver function of the underlying OS library. If you want to have more direct access to the DNS packets use Net::DNS::Resolver.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Net::DNS::Resolver requires a known DNS server, the question is how to know the DNS servername – Boying Dec 28 '15 at 16:01
  • 2
    @Boying: Net::DNS::Resolver tries to use the usual settings of the system if no explicit server is given, see https://metacpan.org/pod/Net::DNS::Resolver#new – Steffen Ullrich Dec 28 '15 at 18:31
  • @Boying: there are not really any changes necessary to my response. You've configured 127.0.0.1 as the local DNS server and thus this is what you get, same as the OS gets. If you want to get the DNS yourself from DHCP but would not like the OS to get the DNS from DHCP than you would need to handle all DHCP yourself. – Steffen Ullrich Dec 29 '15 at 07:06
  • Hi Steffen, so the question is if there any suitable modules handles all DHCP messages? Or I have to lean the protocol and use Net::Packet::Layer2 to process it? – Boying Dec 29 '15 at 09:12
  • @Boying: There are [modules to handle DHCP packets](https://www.google.com/search?q=perl+dhcp) but you still need to capture the packets first using [Net::Pcap](https://metacpan.org/pod/Net::Pcap) or similar depending on the OS. – Steffen Ullrich Dec 29 '15 at 10:13
  • Thanks for the help!!! I findout how to do that, see the answer added by me. It's actually UDP not layer2 stuff, piece of cake:) – Boying Dec 29 '15 at 15:09
0

inspired by Steffen Ullrich I got the issue resolved, by managed taking a DHCP trace and simulated by Net::DHCP::Packet, fortunately it's simple UDP protocol

DHCP

You need to findout IP/Mac/GW address before using the script

#!/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();
}

Execution result:

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

We can see

DHO_DOMAIN_NAME_SERVERS(6) = 192.168.1.1

Is the DNS server address

Boying
  • 1,404
  • 13
  • 20
  • After this, one is forced to wonder if your computer and your DHCP Server still agree on when your lease expires. – tjd Jan 20 '16 at 16:49
  • I tcpdumped the interface when I set/unset manual DNS, this behaviour is allowed on Windows, and then simulated the behaviour by perl. I don't think it's affecting existing ip/gw and related leases time. – Boying Jan 20 '16 at 17:28