CSDN博客

img 2066

DNS Client Utility

发表于2004/10/5 20:54:00  1484人阅读

DNS Client Utility
By Jaimon Mathew

DNS Client utility This is a cut down version of the DNS client, which can be used to retrieve the MX (mail exchange) record for any Internet address from a DNS server. You can use this MX record to send e-mails directly without the need for any mail server as a host. The library can be compiled to a DLL file. One test program is also given to show all the mail exchanger records for any particular address. More information on DNS can be found from these RFCs. Rfc1034(http://www.ietf.org/rfc/rfc1034.txt) and rfc1035(http://www.ietf.org/rfc/rfc1035.txt). Once you got the MX record, you can directly opens its SMTP port, and can issue the SMTP commands. You may get more than one record for some sites. In that case do a sorting based on the preference. The lowest value is the most preferred address. (With a small change it can work on Beta 1 also)

Source code for DnsLite.cs

Source code for test.cs

The compile strings for both .cs files is included in the .cs files.

Here is a sample session, which is sending mail to a hotmail account directly.

1)  Test hotmail.com
    This will return all the MX records for hotmail.com
2)  Do telnet to one of the address got from the program (to port 25)
    telnet mc1.law5.hotmail.com 25
3)  Issue the following SMTP commands.

    HELO jaimonmathew
    MAIL FROM: god@heaven.org
    RCPT TO: jaimonmathew@hotmail.com
    DATA
    From: god@heaven.org
    Subject: Just another message from God
    
    First Line
    Second ....
    
    Last Line
    .
    QUIT






/**

	@author Jaimon Mathew

	csc.exe /t:exe /r:System.DLL /r:DnsLib.dll /D:DEBUG=1 /debug+ /out:"Test.exe" "Test.cs"
*/

using System;
using System.Collections;
using DnsLib;

public class Test {

	//usage test <internet address>
	//example : test hotmail.com

	public static void Main(string[] s) {

		try {

			ArrayList dnsServers = new ArrayList();

			//name/ip of the dnsservers
			dnsServers.Add("158.152.1.58");

			DnsLite dl = new DnsLite();
			dl.setDnsServers(dnsServers);

			ArrayList results;

			results = dl.getMXRecords(s[0]);

			for(int i=0;i<results.Count;i++) {

				MXRecord mx = (MXRecord)results[i];
				Console.WriteLine(i + " : " + mx);
			}

			results = null;
		}catch(Exception e) {

			Console.WriteLine("Caught exception : " + e);
		}

	}
}




/**

	@author Jaimon Mathew

	csc /target:library /out:DnsLib.dll /D:DEBUG=1 /debug+ DnsLite.cs

*/

using System;
using System.Net;
using System.IO;
using System.Text;
using System.Net.Sockets;
using System.Collections;

namespace DnsLib {

	public class MXRecord {

		public int preference = -1;
		public string exchange = null;

		public override string ToString() {

			return "Preference : " + preference + " Exchange : " + exchange;
		}

	}

	public class DnsLite {

		private byte[] data;
		private int position, id, length;
		private string name;
		private ArrayList dnsServers;

		private static int DNS_PORT = 53;

		Encoding ASCII = Encoding.ASCII;

		public DnsLite() {

			id = DateTime.Now.Millisecond * 60;
			dnsServers = new ArrayList();

		}

		public void setDnsServers(ArrayList dnsServers) {

			this.dnsServers = dnsServers;

		}
		public ArrayList getMXRecords(string host) {

			ArrayList mxRecords = null;

			for(int i=0; i < dnsServers.Count; i++) {

				try {

					mxRecords = getMXRecords(host,(string)dnsServers[i]);
					break;

				}catch(IOException) {
					continue;
				}

			}

			return mxRecords;
		}

  		private int getNewId() {

			//return a new id
    		return ++id;
  		}

		public ArrayList getMXRecords(string host,string serverAddress) {

			//opening the UDP socket at DNS server
			//use UDPClient, if you are still with Beta1
			UdpClient dnsClient = new UdpClient(serverAddress, DNS_PORT);

			//preparing the DNS query packet.
			makeQuery(getNewId(),host);

			//send the data packet
			dnsClient.Send(data,data.Length);

			IPEndPoint endpoint = null;
			//receive the data packet from DNS server
			data = dnsClient.Receive(ref endpoint);

    		length = data.Length;

    		//un pack the byte array & makes an array of MXRecord objects.
    		return makeResponse();

		}

		//for packing the information to the format accepted by server
		public void makeQuery(int id,String name) {

			data = new byte[512];

			for(int i = 0; i < 512; ++i) {
				data[i] = 0;
    		}

			data[0]	 = (byte) (id >> 8);
			data[1]  = (byte) (id & 0xFF );
			data[2]  = (byte) 1; data[3] = (byte) 0;
			data[4]  = (byte) 0; data[5] = (byte) 1;
			data[6]  = (byte) 0; data[7] = (byte) 0;
	    	data[8]  = (byte) 0; data[9] = (byte) 0;
    		data[10] = (byte) 0; data[11] = (byte) 0;

    		string[] tokens = name.Split(new char[] {'.'});
	  		string label;

  			position = 12;

  			for(int j=0; j<tokens.Length; j++) {

				label = tokens[j];
				data[position++] = (byte) (label.Length & 0xFF);
				byte[] b = ASCII.GetBytes(label);

				for(int k=0; k < b.Length; k++) {
					data[position++] = b[k];
				}

 			}

			data[position++] = (byte) 0 ; data[position++] = (byte) 0;
			data[position++] = (byte) 15; data[position++] = (byte) 0 ;
			data[position++] = (byte) 1 ;

		}

		//for un packing the byte array
		public ArrayList makeResponse() {

			ArrayList mxRecords = new ArrayList();
			MXRecord mxRecord;

			//NOTE: we are ignoring the unnecessary fields.
			//		and takes only the data required to build
			//		MX records.

    		int qCount = ((data[4] & 0xFF) << 8) | (data[5] & 0xFF);
		    if (qCount < 0) {
      			throw new IOException("invalid question count");
    		}

    		int aCount = ((data[6] & 0xFF) << 8) | (data[7] & 0xFF);
	    	if (aCount < 0) {
    			throw new IOException("invalid answer count");
    		}

	    	position=12;

    		for( int i=0;i<qCount; ++i) {
				name = "";
	    		position = proc(position);
	    		position += 4;
			}

    		for (int i = 0; i < aCount; ++i) {

				name = "";
				position = proc(position);

      			position+=10;

				int pref = (data[position++] << 8) | (data[position++] & 0xFF);

				name="";
				position = proc(position);

				mxRecord = new MXRecord();

				mxRecord.preference = pref;
				mxRecord.exchange = name;

				mxRecords.Add(mxRecord);

			}

			return mxRecords;
		}

		private int proc(int position) {

			int len = (data[position++] & 0xFF);

    		if(len == 0) {
      			return position;
    		}

    		int offset;

    		do {
      			if ((len & 0xC0) == 0xC0) {
        			if (position >= length) {
          				return -1;
        			}
	        		offset = ((len & 0x3F) << 8) | (data[position++] & 0xFF);
		        	proc(offset);
	        		return position;
      			} else {
        			if ((position + len) > length) {
          				return -1;
        			}
        			name += ASCII.GetString(data, position, len);
        			position += len;
      			}

      			if (position > length) {
        			return -1;
      			}

				len = data[position++] & 0xFF;

      			if (len != 0) {
	        		name += ".";
      			}
    		}while (len != 0);

	    	return position;
		}
	}
}
http://www.groupsrv.com/dotnet/viewtopic.php?t=72621


If you have more than one network connection (say a dialup connection and a
LAN connection), you'll get a message box for each connection. Usually the
LAN connection is the first, so you only need the first one.

I think you can change this:
Quote:
For Each obj In objs
MsgBox(obj.DHCPServer.ToString)
Next

to:
MsgBox(objs.obj(0).DHCPServer.ToString) 'or (1) depending if 0 zero based.

Tho I haven't tried it. You'll have to play with it to get it right.


"vbsearch" <dfgfdg> wrote in message
news:OdMKd6ioEHA.1992@TK2MSFTNGP09.phx.gbl...
Quote:
I have just realised something:
If my ip is

a.b.c.d

and my computer is connected to the internet from an internal home
network, then the dns will always be

192.168.0.1 if network connection sharing is used
and
a.b.c.1 if real addresses are used.

Would that be the case (most of the time) ?



p.s.
thanks for your code, it works, I got a few blank message boxes
and 192.168.0.1. The only strange one was 255.255.255.255,
i think this one is irrelevant for tcp/ip, isn't it?





"Terry Olsen" <tolsen64@hotmail.com> wrote in message
news:epp2uddoEHA.2784@TK2MSFTNGP14.phx.gbl...
This works...
Dim objs As Object
Dim obj As Object
Dim WMI As Object
WMI = GetObject("WinMgmts:")
objs = WMI.InstancesOf("Win32_NetworkAdapterConfiguration")
For Each obj In objs
MsgBox(obj.DHCPServer.ToString)
Next
End Sub

To see all the different things you can do, look at this link...


http://www.activexperts.com/activmonitor/windowsmanagement/wmi/samples/hw/#Win32_NetworkAdapterConfiguration


"vbsearch" <dfgfdg> wrote in message
news:utgqjIdoEHA.2912@TK2MSFTNGP10.phx.gbl...
When I do something like this

For Each ip As System.Net.IPAddress _
In System.Net.Dns.GetHostByName(strDomain).AddressList
MessageBox.Show(ip.ToString)
Next ip

would it be correct to assume that GetHostByName uses my local DNS
server to perform the translation. If so, is there a way to extract the
i.p.(or host name/address ) of this server, as I need to query it
directly.





0 0

相关博文

我的热门文章

img
取 消
img