Google
 

2.03.2008

DnDns - A .NET DNS Client Library (Resolver)

I've been sitting on the source code for a DNS resolver library I wrote for a few years now, wondering what to do with it - and too busy to really think much about it anyway. Finally I've decided to release it on CodePlex under the new BSD License for others to learn from and use.

It was originally done using .NET 1.1 - I've ported it to .NET 2.0 - though there is no real differences between the two versions. It is a fully managed implementation written in C# - I suspect it will run just fine on Mono since there's no specific MS Windows namespaces required...but I haven't had time to try it out yet - if anyone has a chance to try it out, let me know how it goes.

The project on CodePlex is located here:
DnDns - A .NET DNS Client Library

Doing a standard 'nslookup' on www.google.com would be done like this in code:

To do a normal Host (A) lookup:

1 DnsQueryRequest request = new DnsQueryRequest();
2 DnsQueryResponse response =
3 request.Resolve(dnsServer, "www.google.com",
4 NsType.A, NsClass.INET, ProtocolType.Udp);

To lookup Google's gMail MX record for email:


1 DnsQueryRequest request = new DnsQueryRequest();
2 DnsQueryResponse response =
3 request.Resolve(dnsServer, "gmail.com"
4 NsType.MX, NsClass.INET, ProtocolType.Udp);

To get the answer, loop over the response.Answers[] array...you can also inspect all aspects of the DNS record response (headers, answers, additional records, etc.).

Motivation

I enjoy implementing protocols. My first network protocol I implemented was a Quake 2 server browser in Java - you could find Quake servers on the Internet and also check out the score of a game that was in-process from a particular server (very similar to early versions of GameSpy Arcade). After that I was hooked - leaning the internals of how the Internet functions is fascinating to me.

I went on to implement a FTP client, a native SMTP mailer (the main reason being that .NET 1.1 required Outlook/CDONTS installed to handle SMTP which was overkill of a requirement), a Syslog listener for keeping tabs on my Firewalls, FreeBSD Servers, and routers - which I'm also working to release soon as a part of another project I'm working on (stay tuned), and the protocol of this discussion, DNS.

In retrospect, the DNS client was probably the most interesting protocol to implement. It's clear the goal in the DNS protocol was to be very light weight and to utilize very little bandwidth. I enjoyed seeing how these efficiencies were implemented in the protocol back when a bandwidth was not as available as it is today.

It's not simply because they choose originally to use datagrams (UDP) that makes the DNS protocol light weight - though that's part if it - it's how the data is packaged for transmission. If that sort of thing interests you, check out section 4.1.4 titled "Message Compression" in RFC 1035. It is an incredibly simplistic type of compression...to reduce repetition of domain names in the message, they stored pointers throughout the message that point to previous occurrence of the same name so names are never duplicated within a message. It's surprising how little space this seems to save, but I suspect every little bit of savings were important back when the system was originally created.

Below is a list of the RFC's I used to implement the DNS client library (as well as Ethereal which was indispensable of course):

I may be missing a couple - it's been a while since I've reviewed the RFC's for which NSTYPE is in which RFC...of course there are some new features in DNS I'm interested in adding, specifically the DNSSEC record types.

Again, here's the link to the DnDns project on CodePlex:
DnDns - A .NET DNS Client Library

Samples are provided on the CodePlex site. Feedback, problems, and suggestions are welcome.

kick it on DotNetKicks.com

10 comments:

Anonymous said...

Awesome. I wrote just what I needed a few years ago to get MX records because you can't from the default .Net libs. Just MX was a pain in the rear, thanks for taking the time to implement so many!

j. montgomery, CISSP, GNET, GSEC said...

My pleasure!

That's what initially got me started down this road. When real DNS support wasn't provided in .net 1.0 and 1.1 I just figured they'd get to it later....it's suprising Microsoft still hasn't implemented it in 2.0/3.0/3.5.

Perhaps there's not a huge demand...

Anonymous said...

Good article. Do you think one could validate an email address by querying the domain's mx record, would that be a good use case?

Maybe you could point me to the right direction, I need a smtp mailer for .net on w2k...

j. montgomery, CISSP, GNET, GSEC said...

That would certainly validate that the Domain portion of the email was valid -

I have also implemented an SMTP library as well but it's not in any condition to release. There is one out there called OpenSmtp.Net at http://sourceforge.net/projects/opensmtp-net/ - perhaps that will get you there.

scott said...

this is good stuff. i have a need to implement stuff a host name into a dns server, but i don't do the protocols too well. can you point me in some direction that is a bit more language friendly than the rfc's?

thanks

Anonymous said...

Absolutely kick-ass J! I've spent a lot of time getting my head around "talking DNS with C#". I got stuck in a couple of places and your DNS library has enabled me to accelerate my thought process significantly. Quick question - are you planning on supporting zone-transfer requests (unless I missed it in there)?

Thanks J (My C# hero of the month:)

j. montgomery, CISSP, GNET, GSEC said...

Hah, no problem...

Zone Transfers (AXFR) support has not been implemented yet. I've added that feature request to the CodePlex site here:

Add Support for Zone Transfers (AXFR)

I included the appropriate links to the RFC's, etc. I'm not sure when I'll be able to get around to it, feel free to jump in! :)

j. montgomery, CISSP, GNET, GSEC said...

Scott - I'm not sure exactly what you're trying to acomplish. Could you walk me a detailed scenario?

scott said...

sorry for not making myself too clear (long day). what i need to do is get DNS update working. i have an embedded system that supports an ip port. DHCP is working fine on it. i want to get the newly established ip address associated with my chosen host name into the DNS server so that other machines can find the system. for instance, i want to be able to ping "HostName" instead of "10.1.0.1"

thanks,
scott

j. montgomery, CISSP, GNET, GSEC said...

scott - i wondered if Dynamic DNS Updates is what you meant. :)

Currently DnDns doesn't support UPDATE. I've created a workitem to the DnDns portal as a feature request and added links to the two RFC's that apply:

Add Support for Dynamic Updates (DNS UPDATE)

Do you know if you need the OLD style UPDATE (insecure) or the Secure Dynamic updates specified in the newer RFC. I suspect which you'll need will depend on the DNS Server (either a configuration setting or a matter of it supporting the newer secure updates). Certainly the older style dynamic updates will probably be easier to implement...

I've briefly scanned RFC 2136 and it doesn't look too bad to implement on top of the current DnDns infrastructure.

I'm a bit bogged down right now with a few things, but I'd certainly interested in working on it eventually...

You're also welcome to take a stab at it if you feel comfortable with Protocols. :)