.NET库中是否有任何内置方法可以返回给定域的所有MX记录?我看到你如何获得CNAMES,但不是MX记录.
更新2018/5/23:
查看MichaC对具有.NET标准支持的新库的回答.
原答案:
Alexander Reinert 的ARSoft.Tools.Net库似乎做得很好.
它可以从NuGet获得:
PM> Install-Package ARSoft.Tools.Net
导入命名空间:
using ARSoft.Tools.Net.Dns;
然后进行同步查找就像这样简单:
var resolver = new DnsStubResolver(); var records = resolver.Resolve("gmail.com", RecordType.Mx); foreach (var record in records) { Console.WriteLine(record.ExchangeDomainName?.ToString()); }
这给了我们输出:
gmail-smtp-in.l.google.com. alt1.gmail-smtp-in.l.google.com. alt2.gmail-smtp-in.l.google.com. alt3.gmail-smtp-in.l.google.com. alt4.gmail-smtp-in.l.google.com.
在引擎盖下,看起来像库构造发送到解析器所需的UDP(或TCP)数据包,就像您期望的那样.该库甚至具有逻辑(调用DnsClient.Default
)以发现要查询的DNS服务器.
完整的文档可以在这里找到.
刚刚浏览了我自己的库,因为.net core/xplat支持没什么... https://github.com/MichaCo/DnsClient.NET
它工作得非常好,dig
如果你愿意,它会给你提供日志消息.
简单易用
var lookup = new LookupClient(); var result = await lookup.QueryAsync("google.com", QueryType.ANY);
并适用于在任何端口,多个服务器等上运行的自定义服务器......
另请参阅DnsClient网站了解更多详情
我花了一整天时间弄清楚如何发送/接收DNS请求并想出了这个.它是一个完整的通用处理程 你只需要设置dns服务器并传入'd',例如.my.website.com?d=itmanx.com
<%@ WebHandler Language="C#" Class="Handler" %> using System; using System.Web; using System.Text; using System.Net; using System.Net.Sockets; using System.Collections.Generic; public class Handler : IHttpHandler { string dns = "dc1"; //change to your dns string qtype = "15"; //A=1 MX=15 string domain = ""; int[] resp; public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; try { if (context.Request["t"] != null) qtype = context.Request["t"]; if (context.Request["d"] != null) domain = context.Request["d"]; if (string.IsNullOrEmpty(domain)) throw new Exception("Add ?d=to url or post data"); Do(context); } catch (Exception ex) { string msg = ex.Message; if (msg == "1") msg = "Malformed packet"; else if (msg == "5") msg = "Refused"; else if (msg == "131") msg = "No such name"; context.Response.Write("Error: " + msg); } } public void Do(HttpContext context) { UdpClient udpc = new UdpClient(dns, 53); // SEND REQUEST-------------------- List list = new List (); list.AddRange(new byte[] { 88, 89, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }); string[] tmp = domain.Split('.'); foreach (string s in tmp) { list.Add(Convert.ToByte(s.Length)); char[] chars = s.ToCharArray(); foreach (char c in chars) list.Add(Convert.ToByte(Convert.ToInt32(c))); } list.AddRange(new byte[] { 0, 0, Convert.ToByte(qtype), 0, 1 }); byte[] req = new byte[list.Count]; for (int i = 0; i < list.Count; i++) { req[i] = list[i]; } udpc.Send(req, req.Length); // RECEIVE RESPONSE-------------- IPEndPoint ep = null; byte[] recv = udpc.Receive(ref ep); udpc.Close(); resp = new int[recv.Length]; for (int i = 0; i < resp.Length; i++) resp[i] = Convert.ToInt32(recv[i]); int status = resp[3]; if (status != 128) throw new Exception(string.Format("{0}", status)); int answers = resp[7]; if (answers == 0) throw new Exception("No results"); int pos = domain.Length + 18; if (qtype == "15") // MX record { while (answers > 0) { int preference = resp[pos + 13]; pos += 14; //offset string str = GetMXRecord(pos, out pos); context.Response.Write(string.Format("{0}: {1}\n", preference, str)); answers--; } } else if (qtype == "1") // A record { while (answers > 0) { pos += 11; //offset string str = GetARecord(ref pos); context.Response.Write(string.Format("{0}\n", str)); answers--; } } } //------------------------------------------------------ private string GetARecord(ref int start) { StringBuilder sb = new StringBuilder(); int len = resp[start]; for (int i = start; i < start + len; i++) { if (sb.Length > 0) sb.Append("."); sb.Append(resp[i + 1]); } start += len + 1; return sb.ToString(); } private string GetMXRecord(int start, out int pos) { StringBuilder sb = new StringBuilder(); int len = resp[start]; while (len > 0) { if (len != 192) { if (sb.Length > 0) sb.Append("."); for (int i = start; i < start + len; i++) sb.Append(Convert.ToChar(resp[i + 1])); start += len + 1; len = resp[start]; } if (len == 192) { int newpos = resp[start + 1]; if (sb.Length > 0) sb.Append("."); sb.Append(GetMXRecord(newpos, out newpos)); start++; break; } } pos = start + 1; return sb.ToString(); } //------------------------------------------------------ public bool IsReusable { get { return false; } } }