3

I am using this c# librabry for nslookup to find nameservers of domains.Here is my c# code

public async System.Threading.Tasks.Task<List<NS>> RunCmd(params string[] domains)
    {


        List<NS> NSL = new List<NS>();
        var lookup = new LookupClient();
        lookup.EnableAuditTrail = true;
        foreach (var item in domains)
        {
            var result = await lookup.QueryAsync(item, QueryType.NS);
            // rootDomain = result.AllRecords.FirstOrDefault().DomainName.Value;
            var nameServer = result.AuditTrail;
            var record = Regex.Match(nameServer.ToString(), @"ns\d"+ "."+ item).Value;
            NSL.Add(new NS { domainName=item,nameServers= record});


        }

        var workbook = new XLWorkbook();
        workbook.AddWorksheet("sheetName");
        var ws = workbook.Worksheet("sheetName");

        int row = 1;
        foreach (var item in NSL)
        {
            ws.Cell("A" + row.ToString()).Value = item.domainName.ToString();
            ws.Cell("B" + row.ToString()).Value = item.nameServers.ToString();
            row++;
        }
        string folderPath = "D:\\";
        workbook.SaveAs(folderPath+"nameServer.xlsx");


        return NSL;

    }

So i pass an array of domains for which i need to know the nameservers and return them in a list also write them to an excel file in my local directory.I can't get the nameservers from the response (var nameServer) directly so i am using regex to split the nameservers from the string.So according to my current regex i am able to get the nameservers if they are ns1 and ns2 if they are anything other than this like ns1262 or ns2636 i just get an empty string from the regex.

Here are two different sample response that i get in the variable nameServer

; (2 server found)
;; Got answer:
;; ->>HEADER<<- opcode: Query, status: No Error, id: 29412
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
mobilecellvideo.com.                IN  NS

;; ANSWER SECTION:
mobilecellvideo.com.            66306   IN  NS  ns2.mobilecellvideo.com.
mobilecellvideo.com.            66306   IN  NS  ns1.mobilecellvideo.com.

;; Query time: 132 msec
;; SERVER: 106.51.113.3#53
;; WHEN: Mon, 13 Mar 2017 02:55:38 GMT
;; MSG SIZE  rcvd: 73

and for the below response when i try to match the above regex i only get an empty string

; (2 server found)
;; Got answer:
;; ->>HEADER<<- opcode: Query, status: No Error, id: 29414
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
networkwonder.com.                  IN  NS

;; ANSWER SECTION:
networkwonder.com.              300     IN  NS  ns2626.ztomy.com.
networkwonder.com.              300     IN  NS  ns1626.ztomy.com.

;; Query time: 436 msec
;; SERVER: 106.51.113.3#53
;; WHEN: Mon, 13 Mar 2017 03:09:01 GMT
;; MSG SIZE  rcvd: 83

Any help would be really appreciated

Thanks in advance !

Melvin
  • 877
  • 3
  • 11
  • 27

2 Answers2

4

There is absolutely no need to try to extract information from the result.AuditTrail property via regex again. AuditTrail is just for logging information! All the data you want is already in the result and the DnsClient.NET library gives you strongly typed results for everything.

This is all you get back in the result. A list of Answers, Authorities, etc...

DnsQueryResponse is is the actualy DNS result you should work with. Depending on the question you ask, relevant data might be in Answers, Additionals or Authorities.

Your mistake was (looking at commented code), that you tried to check DomainName string on all records to find your NS names, but that's not where to find them ;) DomainName is used for anything, the query mostly. Each record has its own fields to store record specific data, so does NsRecord.

So, the following example gives you ns records and the ns names you want

var lookup = new LookupClient();
var result = await lookup.QueryAsync("google.com", QueryType.NS);

foreach(var nsRecord in result.Answers.NsRecords())
{
    Console.WriteLine(nsRecord.NSDName);
}

This will print something like

ns4.google.com. ns1.google.com. ns3.google.com. ns2.google.com.

Hope that helps

MichaC
  • 13,104
  • 2
  • 44
  • 56
0

You need to change your regex expression from

var record = Regex.Match(nameServer.ToString(), @"ns\d"+ "."+ item).Value;

to:

var record = Regex.Match(nameServer.ToString(), @"ns\d+"+ "."+ item).Value;

When you add a plus symbol to \d, you are looking for one or unlimited digits.

You can use Regex101 for checking your regular expressions.

Update

I am a bit surprised that this solution didn't help you, so I tried to fix your code.

In my example, the input was google.es, so in the following code: foreach (var item in domains), item=="google.es" and the DNS answer was:

; (2 server found)
;; Got answer:
;; ->>HEADER<<- opcode: Query, status: No Error, id: 10049
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
google.es.                          IN  NS

;; ANSWER SECTION:
google.es.                      86399   IN  NS  ns2.google.com.
google.es.                      86399   IN  NS  ns3.google.com.
google.es.                      86399   IN  NS  ns4.google.com.
google.es.                      86399   IN  NS  ns1.google.com.

;; Query time: 74 msec
;; SERVER: 8.8.8.8#53
;; WHEN: Mon, 13 Mar 2017 20:54:34 GMT
;; MSG SIZE  rcvd: 120

The regular expression was ns\d+.google.es. As you can see, the error was in the regular expression because you are using the item to build the regular expression and your domain to check can be other domain for DNS (here I ask for google.es however the DNS use google.com)

If you would like to use regex, you can use the following ns\d+.+, the result is the following: enter image description here

I hope this can help you.

ganchito55
  • 3,559
  • 4
  • 25
  • 46