博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C#查询DNS的MX地址的代码

Posted on 2013-01-05 14:27  快乐家++  阅读(593)  评论(0编辑  收藏  举报
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] s = PAB.DnsUtils.DnsMx.GetMXRecords("qq.com");

            foreach (string st in s) Console.WriteLine("Server: {0}", st);

            Console.ReadLine();
        }
    }
}


namespace PAB.DnsUtils
{
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Runtime.InteropServices;

    public class DnsMx
    {
        public DnsMx()
        {
        }

        [DllImport("dnsapi", EntryPoint = "DnsQuery_W", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
        private static extern int DnsQuery([MarshalAs(UnmanagedType.VBByRefStr)]ref string pszName, QueryTypes wType, QueryOptions options, int aipServers, ref IntPtr ppQueryResults, int pReserved);

        [DllImport("dnsapi", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern void DnsRecordListFree(IntPtr pRecordList, int FreeType);

        public static string[] GetMXRecords(string domain)
        {
            IntPtr ptr1 = IntPtr.Zero;
            IntPtr ptr2 = IntPtr.Zero;
            MXRecord recMx;

            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
            {
                throw new NotSupportedException();
            }

            ArrayList list1 = new ArrayList();

            int num1 = DnsMx.DnsQuery(ref domain, QueryTypes.DNS_TYPE_MX, QueryOptions.DNS_QUERY_BYPASS_CACHE, 0, ref ptr1, 0);

            if (num1 != 0) { throw new Win32Exception(num1); }

            for (ptr2 = ptr1; !ptr2.Equals(IntPtr.Zero); ptr2 = recMx.pNext)
            {
                recMx = (MXRecord)Marshal.PtrToStructure(ptr2, typeof(MXRecord));

                if (recMx.wType == 15)
                {
                    string text1 = Marshal.PtrToStringAuto(recMx.pNameExchange);
                    list1.Add(text1);
                }
            }

            DnsMx.DnsRecordListFree(ptr2, 0);

            return (string[])list1.ToArray(typeof(string));
        }

        private enum QueryOptions { DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE = 1, DNS_QUERY_BYPASS_CACHE = 8, DNS_QUERY_DONT_RESET_TTL_VALUES = 0x100000, DNS_QUERY_NO_HOSTS_FILE = 0x40, DNS_QUERY_NO_LOCAL_NAME = 0x20, DNS_QUERY_NO_NETBT = 0x80, DNS_QUERY_NO_RECURSION = 4, DNS_QUERY_NO_WIRE_QUERY = 0x10, DNS_QUERY_RESERVED = -16777216, DNS_QUERY_RETURN_MESSAGE = 0x200, DNS_QUERY_STANDARD = 0, DNS_QUERY_TREAT_AS_FQDN = 0x1000, DNS_QUERY_USE_TCP_ONLY = 2, DNS_QUERY_WIRE_ONLY = 0x100 }

        private enum QueryTypes { DNS_TYPE_MX = 15 }

        [StructLayout(LayoutKind.Sequential)]
        private struct MXRecord
        {
            public IntPtr pNext;
            public string pName;
            public short wType;
            public short wDataLength;
            public int flags;
            public int dwTtl;
            public int dwReserved;
            public IntPtr pNameExchange;
            public short wPreference;
            public short Pad;
        }
    }
}