Using PHP to Perform DNS Lookups

Posted by Nessa | Posted in ,,, | Posted on June 30, 2010

16

PHP has a couple DNS functions you can use to perform record lookups.

Most of us are familiar with the two basic ones – gethostbyname() and gethostbyaddr(), both of which perform a single function – returning a hostname or IP address. Here’s an example of both:

<?php

$ip = gethostbyname("v-nessa.net");
$host = gethostbyaddr("69.174.114.71");

echo "v-nessa.net has the IP $ip, which reverses to $host";
?>

The above will return:

v-nessa.net has the IP 69.174.114.71, which has a PTR of server.v-nessa.net

Similarly to gethostbyname, there’s gethostbynamel which is useful for hostnames with multiple A records:

$ips = gethostbynamel("test.v-nessa.net");
foreach ($ips as $ip => $value){
echo $value . "\n";
}

Will return:

69.174.114.71
69.174.115.243

A more advanced function is dns_get_record, which can pull any valid record for a hostname or IP.  Think about the dig command you use in Unix to find DNS records:

nessa@nessa-desktop:~$ dig +short v-nessa.net A
69.174.114.71

The dns_get_record function works in a similar way, and can obtain the following DNS record types:

DNS_A, DNS_CNAME, DNS_HINFO, DNS_MX, DNS_NS, DNS_PTR, DNS_SOA, DNS_TXT, DNS_AAAA, DNS_SRV, DNS_NAPTR, DNS_A6, DNS_ALL or DNS_ANY.

The following will give you a similar result:

$recs = dns_get_record("v-nessa.net", DNS_A);
print_r($recs);

Will return:

Array
(
[0] => Array
(
[host] => v-nessa.net
[type] => A
[ip] => 69.174.114.71
[class] => IN
[ttl] => 13728
)
)

If you want to obtain multiple DNS types, you can do so by separating the record types with a plus sign:

$recs = dns_get_record("v-nessa.net", DNS_A + DNS_MX);

Will return:

Array
(
[0] => Array
(
[host] => v-nessa.net
[type] => A
[ip] => 69.174.114.71
[class] => IN
[ttl] => 13736
)

[1] => Array
(
[host] => v-nessa.net
[type] => MX
[pri] => 0
[target] => v-nessa.net
[class] => IN
[ttl] => 14145
)

)

You’ll notice that the output is a double array, so to call individual values you can do either of the following:

// will return the IP for array 0 ( A record)

echo $recs[0]['ip'];

// will return results for common records

foreach ($recs as $type => $value){
echo $value[ip] . "\n";
}

Similar to the example above, you can use the DNS_ALL type to show any records available for the hostname, and use a minus sign to exclude certain record types. For example, the below code will return all DNS results for v-nessa.net, but exclude NS records:

$recs = dns_get_record("v-nessa.net", DNS_ALL - DNS_NS );

foreach ($recs as $type => $value){
echo $value[type] . "\n";
}

The following records were returned:

A
SOA
MX
TXT

Here’s a more practical example – a simple PHP DNS lookup script. Say you have a form on your site that allows a user to type in a hostname and select a type of record: A, MX, NS, and TXT. The passed form values are $host and $type, and the below script will accept the variables and output the results according to the record type:

HTML Form:

<form action="dns.php" method="POST">
Hostname: <input type="text" name="host" />
Type: <select name="type">
<option value="a">A</option>
<option value="mx">MX</option>
<option value="ns">NS</option>
<option value="txt">TXT</option> </select>
</form>

PHP Script (dns.php):

<?php

if(!empty($_POST['host']) && !empty($_POST['type'])){

    // Grab variable from form and define valid types

    $host = $_POST['host'];
    $type = strtoupper($_POST['type');
    $validtypes=array("A","MX","NS","TXT");

    // Check that dns type is defined or allowed

    if(!defined("DNS_" . $type) or !in_array($type,$validtypes)){
       echo "Invalid DNS Type!";
    }else{

       $type = constant("DNS_" . $type);
       $rec = dns_get_record($host, $type);

       // Set result types - can be modified by using available elements from $rec array

       switch($type){
             case DNS_A:
                    $recvals=array("Hostname" => "host","Type" => "type", "IP" => "ip");
                    break;
             case DNS_MX:
                    $recvals=array("Hostname" => "host","Type" => "type", "Target" => "target", "Priority" => "pri");
                    break;
             case DNS_NS:
                    $recvals=array("Hostname" => "host","Type" => "type", "Target" => "target");
                    break;
             case DNS_TXT:
                    $recvals=array("Hostname" => "host","Type" => "type", "Record" => "txt");
                    break;
        }

      // Output results

      foreach ($rec as $arr => $num){
             foreach ($recvals as $title => $value){
                    echo $title . " : " . $num[$value] . "\n";
             }
      }

    }
} else {

     echo "Either hostname or record type is missing";
}

It’s of course easy to modify the above code accordingly, and I’m sure there may be better ways to do this. Feel free to post your own code snippets or comments.

Be Sociable, Share!

Comments (16)

Thanks for sharing that, I had no idea PHP could do that. Granted, I mostly know CSS and HTML. But now I do see why PHP has taken over in web programming.

I love this personally and use it for blacklist checking, if only it also allowed for a built in count of how long the function took to run. I could find which BL’s were slow and drop them off, as long as they weren’t one of the big ones.

Thanks for sharing

Nessa thanks bro.

Hi Vanessa,
That’s good – but I can’t seem to find a way to specify the global server in NAPTR dns lookup, only the host.

Any ideas anyone?

It doesn’t use DNSSEC, and when using the DNS_ALL switch it doesn’t display DNSKEY records.

Hi, in regards this post, is it possible to run a nslookup from php using dns servers that are not in the /etc/resolv?

Blacklist status check for the given IP at the available DNSBL’s [DNS Blacklists]

Kindly help me in doing the above coding

please

Thanks for your post of DNS Commands in PHP. Can you help me write DNS Reports for the given domain.
This will be usefull for me if you share your throughts.

you ever check your out put . lol

$ips = gethostbynamel(“test.v-nessa.net”);
foreach ($ips as $ip => $value){
echo $value . “\n”;
}

is not a valid array for foreach

I was looking to query A records to implement in our domain auctions portal and thanks a lot. I think your article will help me.

i need a php script to do DNS for an ip

That very nice script dude..
Thank you..

Nice, thx for sharing

I want some help for dns servers any one there?

Post a comment