Skip to content

Instantly share code, notes, and snippets.

@duncansmart
Created October 10, 2012 22:25
Show Gist options
  • Select an option

  • Save duncansmart/3868893 to your computer and use it in GitHub Desktop.

Select an option

Save duncansmart/3868893 to your computer and use it in GitHub Desktop.
GetMXRecords in C#
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