Get SPF records from a Domain

前端 未结 7 1324
面向向阳花
面向向阳花 2021-02-14 01:20

What are the ways to Check SPF records on a domain?

There is a website where i can do it manually using - http://www.mxtoolbox.com/SuperTool.aspx

How can i do it

7条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-02-14 01:47

    Even though .NET has a lot of support for networking including doing host name to address mapping it lacks a general way to query DNS.

    However, you can use P/Invoke to call the DnsQuery function directly. The API is somewhat cumbersome but it is not impossible to create the correct P/Invoke signature for your requirement.

    A SPF record is stored as a TXT record in DNS. The corresponding structure you will have to work with is the DNS_TXT_DATA structure. If you can find an example of querying a MX record you can reuse the code and use DNS_TYPE_TEXT for the query type and unmarshal the data to a DNS_TXT_DATA structure.

    Or you could just use this code:

    using System.ComponentModel;
    using System.Runtime.InteropServices;
    
    public String DnsGetTxtRecord(String name) {
      const Int16 DNS_TYPE_TEXT = 0x0010;
      const Int32 DNS_QUERY_STANDARD = 0x00000000;
      const Int32 DNS_ERROR_RCODE_NAME_ERROR = 9003;
      const Int32 DNS_INFO_NO_RECORDS = 9501;
      var queryResultsSet = IntPtr.Zero;
      try {
        var dnsStatus = DnsQuery(
          name,
          DNS_TYPE_TEXT,
          DNS_QUERY_STANDARD,
          IntPtr.Zero,
          ref queryResultsSet,
          IntPtr.Zero
        );
        if (dnsStatus == DNS_ERROR_RCODE_NAME_ERROR || dnsStatus == DNS_INFO_NO_RECORDS)
          return null;
        if (dnsStatus != 0)
          throw new Win32Exception(dnsStatus);
        DnsRecordTxt dnsRecord;
        for (var pointer = queryResultsSet; pointer != IntPtr.Zero; pointer = dnsRecord.pNext) {
          dnsRecord = (DnsRecordTxt) Marshal.PtrToStructure(pointer, typeof(DnsRecordTxt));
          if (dnsRecord.wType == DNS_TYPE_TEXT) {
            var lines = new List();
            var stringArrayPointer = pointer
              + Marshal.OffsetOf(typeof(DnsRecordTxt), "pStringArray").ToInt32();
            for (var i = 0; i < dnsRecord.dwStringCount; ++i) {
              var stringPointer = (IntPtr) Marshal.PtrToStructure(stringArrayPointer, typeof(IntPtr));
              lines.Add(Marshal.PtrToStringUni(stringPointer));
              stringArrayPointer += IntPtr.Size;
            }
            return String.Join(Environment.NewLine, lines);
          }
        }
        return null;
      }
      finally {
        const Int32 DnsFreeRecordList = 1;
        if (queryResultsSet != IntPtr.Zero)
          DnsRecordListFree(queryResultsSet, DnsFreeRecordList);
      }
    }
    
    [DllImport("Dnsapi.dll", EntryPoint = "DnsQuery_W", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
    static extern Int32 DnsQuery(String lpstrName, Int16 wType, Int32 options, IntPtr pExtra, ref IntPtr ppQueryResultsSet, IntPtr pReserved);
    
    [DllImport("Dnsapi.dll")]
    static extern void DnsRecordListFree(IntPtr pRecordList, Int32 freeType);
    
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    struct DnsRecordTxt {
      public IntPtr pNext;
      public String pName;
      public Int16 wType;
      public Int16 wDataLength;
      public Int32 flags;
      public Int32 dwTtl;
      public Int32 dwReserved;
      public Int32 dwStringCount;
      public String pStringArray;
    }
    

提交回复
热议问题