Created
October 10, 2012 22:25
-
-
Save duncansmart/3868893 to your computer and use it in GitHub Desktop.
GetMXRecords in C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.ComponentModel; | |
| using System.Linq; | |
| using System.Runtime.InteropServices; | |
| using System.Diagnostics; | |
| public class MailUtil | |
| { | |
| #region DLL Imports | |
| [DllImport("dnsapi", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] | |
| static extern int DnsQuery_W([MarshalAs(UnmanagedType.LPWStr)]string pszName, DnsRecordType wType, QueryOptions options, int aipServers, ref IntPtr ppQueryResults, int pReserved); | |
| [DllImport("dnsapi", CharSet = CharSet.Auto, SetLastError = true)] | |
| static extern void DnsRecordListFree(IntPtr pRecordList, int FreeType); | |
| enum QueryOptions | |
| { | |
| DNS_QUERY_STANDARD = 0, | |
| DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE = 1, | |
| DNS_QUERY_USE_TCP_ONLY = 2, | |
| DNS_QUERY_NO_RECURSION = 4, | |
| 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_WIRE_QUERY = 0x10, | |
| DNS_QUERY_RESERVED = -16777216, | |
| DNS_QUERY_RETURN_MESSAGE = 0x200, | |
| DNS_QUERY_TREAT_AS_FQDN = 0x1000, | |
| DNS_QUERY_WIRE_ONLY = 0x100 | |
| } | |
| enum DnsRecordType : short | |
| { | |
| DNS_TYPE_A = 1, | |
| DNS_TYPE_NS = 2, | |
| DNS_TYPE_CNAME = 5, | |
| DNS_TYPE_SOA = 6, | |
| DNS_TYPE_PTR = 12, | |
| DNS_TYPE_HINFO = 13, | |
| DNS_TYPE_MX = 15, | |
| DNS_TYPE_TXT = 16, | |
| DNS_TYPE_AAAA = 28 | |
| } | |
| [StructLayout(LayoutKind.Sequential)] | |
| struct MXRecord | |
| { | |
| public IntPtr pNext; | |
| public IntPtr pName; | |
| public DnsRecordType wType; | |
| public short wDataLength; | |
| public int flags; | |
| public int dwTtl; | |
| public int dwReserved; | |
| public IntPtr pNameExchange; | |
| public short wPreference; | |
| public short Pad; | |
| } | |
| #endregion | |
| public static List<string> GetMXRecords(string domain) | |
| { | |
| IntPtr ppResults = IntPtr.Zero; | |
| MXRecord mxRecord; | |
| var results = new List<Tuple<short, string>>(); | |
| int error = DnsQuery_W(domain, DnsRecordType.DNS_TYPE_MX, QueryOptions.DNS_QUERY_STANDARD, 0, ref ppResults, 0); | |
| if (error != 0) | |
| throw new Win32Exception(error); | |
| for (var pRecord = ppResults; pRecord != IntPtr.Zero; pRecord = mxRecord.pNext) | |
| { | |
| mxRecord = (MXRecord)Marshal.PtrToStructure(pRecord, typeof(MXRecord)); | |
| if (mxRecord.wType == DnsRecordType.DNS_TYPE_MX) | |
| { | |
| string name = Marshal.PtrToStringAuto(mxRecord.pNameExchange); | |
| results.Add(new Tuple<short, string>(mxRecord.wPreference, name)); | |
| } | |
| } | |
| DnsRecordListFree(ppResults, 0); | |
| return results | |
| .OrderBy(x => x.Item1) | |
| .Select(x => x.Item2) | |
| .ToList(); | |
| } | |
| static void Test() | |
| { | |
| var domains = "gmail.com yahoo.com hotmail.com".Split(' '); | |
| foreach (string domain in domains) | |
| foreach (var mx in GetMXRecords(domain)) | |
| Debug.WriteLine(mx); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment