PHP Doku:: Prüft DNS-Einträge auf Übereinstimmung mit einem gegebenen Internet-Host-Namen oder einer IP-Adresse - function.checkdnsrr.html

Verlauf / Chronik / History: (1) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzSonstige DiensteNetworkNetzwerk-Funktionencheckdnsrr

Ein Service von Reinhard Neidl - Webprogrammierung.

Netzwerk-Funktionen

<<Netzwerk-Funktionen

closelog>>

checkdnsrr

(PHP 4, PHP 5)

checkdnsrrPrüft DNS-Einträge auf Übereinstimmung mit einem gegebenen Internet-Host-Namen oder einer IP-Adresse

Beschreibung

bool checkdnsrr ( string $host [, string $type = "MX" ] )

Durchsucht den DNS (Domain-Name-Service) nach Daten des Typs type, die zum übergebenen host gehören.

Parameter-Liste

host

host kann entweder eine durch Punkte getrennte IP-Adresse oder der Hostname sein.

type

type kann einer der folgenden Werte sein: A, MX, NS, SOA, PTR, CNAME, AAAA, A6, SRV, NAPTR, TXT oder ANY.

Rückgabewerte

Gibt TRUE zurück, wenn mindestens ein Datensatz gefunden wurde. Wurde kein Datensatz gefunden oder trat ein Fehler auf, wird FALSE zurückgegeben.

Changelog

Version Beschreibung
5.3.0 Die Funktion ist nun auch auf Windowsplattformen verfügbar.
5.2.4 TXT type hinzugefügt.
5.0.0 AAAA type hinzugefügt.

Anmerkungen

Hinweis:

Wenn unter Windows Kompatibilität zu Versionen ohne Implementierung dieser Funktion gegeben sein muss, verwenden Sie die » PEAR-Klasse » Net_DNS.

Siehe auch

  • dns_get_record() - Fetch DNS Resource Records associated with a hostname
  • getmxrr() - Ermittelt die zu einem Internet-Hostnamen passenden MX-Records
  • gethostbyaddr() - Ermittelt den zur angegebenen IP-Adresse passenden Internet-Hostnamen
  • gethostbyname() - Ermittelt die zum angegebenen Internet-Hostnamen passende IPv4-Adresse
  • gethostbynamel() - Ermittelt eine Liste von IPv4-Adressen passend zum angegebenen Internet-Hostnamen
  • the named(8) manual page


20 BenutzerBeiträge:
- Beiträge aktualisieren...
Anonymous
15.07.2009 18:07
It appears that if you're checking DNS records for a host that uses a Round-Robin DNS technique for load distribution, then you cannot use this function with the "type" parameter set to "ANY".

<?php

//This will not work
if(checkdnsrr("round-robin-example.com"),"ALL")){
     return
true;
}else{
     return
false;
}

//But every value other than "ANY" will work
if(checkdnsrr("round-robin-example.com"),"A")){
     return
true;
}else{
     return
false;
}

?>
php [spat] hm2k.org
19.01.2009 21:12
After successfully handling getmxrr() correctly, I decided to have a bash at this, here's the result:

<?php

// checkdnsrr() support for Windows by HM2K <php [spat] hm2k.org>
function win_checkdnsrr($host, $type='MX') {
    if (
strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') { return; }
    if (empty(
$host)) { return; }
   
$types=array('A', 'MX', 'NS', 'SOA', 'PTR', 'CNAME', 'AAAA', 'A6', 'SRV', 'NAPTR', 'TXT', 'ANY');
    if (!
in_array($type,$types)) {
       
user_error("checkdnsrr() Type '$type' not supported", E_USER_WARNING);
        return;
    }
    @
exec('nslookup -type='.$type.' '.escapeshellcmd($host), $output);
    foreach(
$output as $line){
        if (
preg_match('/^'.$host.'/',$line)) { return true; }
    }
}

// Define
if (!function_exists('checkdnsrr')) {
    function
checkdnsrr($host, $type='MX') {
        return
win_checkdnsrr($host, $type);
    }
}

/* example */

echo "<pre>";
$domains=array('example.com','php.net');
foreach (
$domains as $domain) {
   
$result=checkdnsrr($domain);
    echo
$domain.':';
    echo
$result?"true\n":"false\n";
}

?>
Anonymous
20.08.2008 0:08
These Windows checkdnsrr() replacement functions in the comments are handy, but none of them appear to be escaping the input data before they call the nslookup.exe program via the shell. Thus, if the hostname being passed to the replacement functions is something unexpected like, say, "microsoft.com; cd \; deltree *.*", the exec() function will happily execute all of those malicious user specified commands.

The solution would be to properly validate input data, only allowing characters that could be found in a hostname according to the proper RFCs.
loaded67 at hotmail dot com
22.04.2008 18:27
A php5.2 SPL implementation substitute for win platforms.

<?php
if(!function_exists('checkdnsrr')){
    function
checkdnsrr($host, $type=''){
        if(!empty(
$host)){
           
$type = (empty($type)) ? 'MX' $type;
           
exec('nslookup -type='.$type.' '.escapeshellcmd($host), $result);
           
$it = new ArrayIterator($result);
            foreach(new
RegexIterator($it, '~^'.$host.'~', RegexIterator::GET_MATCH) as $result){
                if(
$result){
                    return
true;
                }               
            }
        }
        return
false;
    }
}
?>
jon at webignition dot net
30.05.2007 18:42
With many email address validity functions listed here, it's worth mentioning that the boolean output of an email address validity function should never be treated as definitive with respect to displaying errors and restricting what the user of a web app can do.

In more simple terms, if a user-supplied email address fails a validity check, don't tell the user the email address they entered is invalid and force them to enter something different.

Use such email validity checks as guidelines only, word errors to state that the email address might be invalid, ask the user to check and always always give the user the option of bypassing the validity check - it's really infuriating to be told your email address is invalid when you know for sure this is not the case!
developer at sysco dot ch
15.05.2007 18:05
Here is a simple and fully compatible implementation of checkdnsrr() for Windows.

If you include these lines at the beginning of your code, you do not need to change anything else in the code in order to work!

if(!function_exists('checkdnsrr'))
{
    function checkdnsrr($hostName, $recType = '')
    {
     if(!empty($hostName)) {
       if( $recType == '' ) $recType = "MX";
       exec("nslookup -type=$recType $hostName", $result);
       // check each line to find the one that starts with the host
       // name. If it exists then the function succeeded.
       foreach ($result as $line) {
         if(eregi("^$hostName",$line)) {
           return true;
         }
       }
       // otherwise there was no mail handler for the domain
       return false;
     }
     return false;
    }
}
reportingsjr at gmail dot com
28.04.2007 3:05
Here is a modification to the note below:
    function check_email($email) {
        if(preg_match('/^\w[-.\w]*@(\w[-._\w]*\.[a-zA-Z]{2,}.*)$/', $email, $matches))
        {
            if(function_exists('checkdnsrr'))
            {
                if(checkdnsrr($matches[1] . '.', 'MX')) return true;
                if(checkdnsrr($matches[1] . '.', 'A')) return true;
            }else{
                if(!empty($hostName))
                {
                    if( $recType == '' ) $recType = "MX";
                    exec("nslookup -type=$recType $hostName", $result);
                    foreach ($result as $line)
                    {
                        if(eregi("^$hostName",$line))
                        {
                            return true;
                        }
                    }
                    return false;
                }
                return false;
            }
        }
        return false;
    }
This makes it compatible with windows and will make sure it actually checks the domain.
Check DNSBL - WIN also
12.01.2007 1:41
<?php
/*
* Check DNSBL - WIN also - DD
*/
function blacklisted($ip) {
   
$dnsbl_lists = array("bl.spamcop.net", "list.dsbl.org", "sbl.spamhaus.org");
    if (
$ip && preg_match('/^([0-9]{1, 3})\.([0-9]{1, 3})\.([0-9]{1, 3})\.([0-9]{1, 3})/', $ip)) {
       
$reverse_ip = implode(".", array_reverse(explode(".", $ip)));
       
$on_win = substr(PHP_OS, 0, 3) == "WIN" ? 1 : 0;
        foreach (
$dnsbl_lists as $dnsbl_list){
            if (
function_exists("checkdnsrr")) {
                if (
checkdnsrr($reverse_ip . "." . $dnsbl_list . ".", "A")) {
                    return
$reverse_ip . "." . $dnsbl_list;
                }
            } else if (
$on_win == 1) {
               
$lookup = "";
                @
exec("nslookup -type=A " . $reverse_ip . "." . $dnsbl_list . ".", $lookup);
                foreach (
$lookup as $line) {
                    if (
strstr($line, $dnsbl_list)) {
                        return
$reverse_ip . "." . $dnsbl_list;
                    }
                }
            }
        }
    }
    return
false;
}
?>

12.12.2006 1:06
<?php
function check_dnsbl($ip)
{
   
$dnsbl_check=array("bl.spamcop.net","list.dsbl.org",
"sbl.spamhaus.org",'xbl.spamhaus.org');
    if(
$ip){
       
$rip=implode('.',array_reverse(explode(".",$ip)));
        foreach(
$dnsbl_check as $val){
            if(
checkdnsrr($rip.'.'.$val.'.','A'))
                return
$rip.'.'.$val;
        }
    }
    return
false;
}
?>
satmd
28.01.2006 17:29
fox dot 69 at gmx dot net: I wonder where you got this code from. I have written this piece of code half a year ago and released it WITH a copyright header that is missing now! Anyways... this code is to be considered licenced "as-is", however it'd be nice to keep the authors note (This is something about reputation, you see?). Thanks.

(Much) more recent version of it:
<?php
function is_blacklisted($ip) {
  
// written by satmd, do what you want with it, but keep the author please
  
$result=Array();
  
$dnsbl_check=array("bl.spamcop.net",
                      
"list.dsbl.org",
                      
"sbl.spamhaus.org");
   if (
$ip) {
      
$quads=explode(".",$ip);
      
$rip=$quads[3].".".$quads[2].".".$quads[1].".".$quads[0];
       for (
$i=0; $i<count($dnsbl_check); $i++) {
           if (
checkdnsrr($rip.".".$dnsbl_check[$i].".","A")) {
             
$result[]=Array($dnsbl_check[$i],$rip.".".$dnsbl_check[$i]);
           }
         }
      return
$result;
   }
}
?>

Beware that this code's signature differs from the original! I also removed osirusoft as its results are not useful anyways (false positives!). Please make sure that you have nscd or a caching dns server running as this code is prone to (d)dos! Only use it in places where it is necessary (when data is to be modified), e.g. the script processing uploads/posts/replies in a blog.
tabascopete78 at yahoo dot com
18.08.2005 9:30
I was using file_get_contents on a set of URLs. Some of them URLs were invalid (the structure of it was ok but the DNS hosts couldn't resolve them) and I kept getting an annoying warning that I wanted to handle correctly. I wanted to check the DNS somehow but the existing check dns function in php doesn't have one for windows and the one a person supplied here does not work 100% of the time. (The reg exp is wrong.)

Instead use gethostbyname to try to resolve a host. This won't throw any warnings, you just need to check the output and it's all handled gracefully. You'll get the same warnings with fopen and fsockopen.

The only minor drawback is that on invalid hosts it takes a couple seconds to figure it out.
Plasma
18.06.2005 10:43
In response to fox dot 69 at gmx dot net's dnsbl function:

<?php
function is_blacklisted($ip) {
  
$dnsbl_check=array("bl.spamcop.net",
                      
"relays.osirusoft.com",
                      
"list.dsbl.org",
                      
"sbl.spamhaus.org");
   if (
$ip) {
      
$quads=explode(".",$ip);
      
$rip=$quads[3].".".$quads[2].".".$quads[1].".".$quads[0];
       for (
$i=0; $i<count($dnsbl_check); $i++) {
           if (
checkdnsrr($rip.".".$dnsbl_check[$i] . '.',"A")) {
              
$listed.=$dnsbl_check[$i]." ";
           }
         }
       if (
$listed) { return $listed; } else { return FALSE; }
   }
}
?>

Add a . after the $dnsbl_check[$i] so that it returns a valid response, I found this was not working (always returned the A record) when I didnt specify the . at the end:

           if (checkdnsrr($rip.".".$dnsbl_check[$i] . '.',"A")) {
Sven
7.02.2005 14:46
Note to Patrick's regular expression (from 14-Dec-2004):

Don't use it as it will not recognize every valid email address, because valid domain names do not pass the regex.

For example: test--domain.com is a perfectly valid domain, but won't be recognized as such.

If you have to use a regular expression as a first filter, then either use the complete complex form based on RFC2822, or stick to the most basic regex like this:

".+@.+\..+."

Explanation: The username in front of the @ can include every known character in the world - it has to be escaped somehow, but dealing with this is a mess.

The shortest possible domain name is 1 character long, not 2 or 3 (although many registries impose such arbitrary rules on domain names). Try www.x.org if you don't believe this. :)

Only the top level domain consists of at least 2 characters (country code tld), but there should be no upper limit. Many had to learn the hard way as .info became available. And .museum. Maybe there will be .solarsystem someday.

So the shortest possible email address consists of 6 characters: "a@b.cd".

I do not use more specific character classes for the domain names because we have international domain names, which opens up the whole unicode range as valid characters. Converting these into useable dns domain names is a different task, best left to appropriate librarys such as PEAR's Net_IDNA.

Rule of thumb: Don't assume too much. If a string doesn't contain an "@"-sign and a dot after that, then it surely is no email address, and no further checking needs to take place. Everything else should go one step further.
Patrick
14.12.2004 4:53
This is a little code example that will validate an email address in two ways:
- first the general syntax of the string is checked with a regular expression
- then the domain substring (after the '@') is checked using the 'checkdnsrr' function

<?php

function validate_email($email){

  
$exp = "^[a-z\'0-9]+([._-][a-z\'0-9]+)*@([a-z0-9]+([._-][a-z0-9]+))+$";

   if(
eregi($exp,$email)){

      if(
checkdnsrr(array_pop(explode("@",$email)),"MX")){
        return
true;
      }else{
        return
false;
      }

   }else{

      return
false;

   }   
}

?>
dave146 at burtonsys dot com
21.06.2004 8:46
The .museum TLD is weird.  All undefined second-level domains resolve to 195.7.77.20 (a/k/a index.museum).  So checkdnsrr() doesn't tell you anything at all about second-level domains under .museum.

-Dave

Editors note:

This applies to all TLDs that have a wildcard covering all non-existant domains. This may at some point in the future include .com or .net and does already cover other domains. If you are unsure just try a couple of random domains that can't possibly exist. If they both resolve to the same IP address and checkdnserr() returns false, you may have to check the IP.
picaune at hotmail dot com
1.02.2004 3:58
On Windows NT machines (inc. 2000, XP, 2003, .net, Longhorn) you can emulate this function by spoonfeeding the nslookup proglet.

After spitting out some info on which DNS server it's using, the daemon presents a "> " prompt. At this point if you enter a domain name a list of A records will be returned from the default name server. The sixth line of output has "Address: " followed by the IPv4 address in dotted-quad notation. You may enter "set type=" followed by the IP type. Currently the only supported IP class is IN (Internet); the others are no longer supported. You can exit by entering "exit".

You may perform a one-shot lookup by passing the domain name as a command line argument; in this case nslookup will automatically perform an A lookup on the default name server and exit. The IPv4 address is on the last line with non-whitespace.

Additional information and options can be obtained by running nslookup and then searching for "?".
fox dot 69 at gmx dot net
1.05.2003 22:40
maybe usefull, a blacklist (DNSBL) check function:

<?php
function is_blacklisted($ip) {
   
$dnsbl_check=array("bl.spamcop.net",
                      
"relays.osirusoft.com",
                      
"list.dsbl.org",
                      
"sbl.spamhaus.org");
    if (
$ip) {
      
$quads=explode(".",$ip);
       
$rip=$quads[3].".".$quads[2].".".$quads[1].".".$quads[0];
        for (
$i=0; $i<count($dnsbl_check); $i++) {
            if (
checkdnsrr($rip.".".$dnsbl_check[$i],"A")) {
               
$listed.=$dnsbl_check[$i]." ";
            }
         }
       if (
$listed) { return $listed; } else { return FALSE; }
    }
}
?>
kriek at jonkriek dot com
26.03.2003 2:08
The checkdnsrr function is not implemented on the Windows platform. The way to get around this problem is to write your own version of checkdnsrr. Example: myCheckDNSRR

<?php
function myCheckDNSRR($hostName, $recType = '')
{
 if(!empty(
$hostName)) {
   if(
$recType == '' ) $recType = "MX";
  
exec("nslookup -type=$recType $hostName", $result);
  
// check each line to find the one that starts with the host
   // name. If it exists then the function succeeded.
  
foreach ($result as $line) {
     if(
eregi("^$hostName",$line)) {
       return
true;
     }
   }
  
// otherwise there was no mail handler for the domain
  
return false;
 }
 return
false;
}
?>
Note that the type parameter is optional, and if you don't supply it then the type defaults to "MX" (which means Mail Exchange). If any records are found, the function returns TRUE. Otherwise, it returns FALSE.

23.07.2002 15:45
<?php
/******************************************************

These functions can be used on WindowsNT to replace
their built-in counterparts that do not work as
expected.

checkdnsrr_winNT() works just the same, returning true
or false

getmxrr_winNT() returns true or false and provides a
list of MX hosts in order of preference.

*******************************************************/

function checkdnsrr_winNT( $host, $type = '' )
{

    if( !empty(
$host ) )
    {

       
# Set Default Type:
       
if( $type == '' ) $type = "MX";

        @
exec( "nslookup -type=$type $host", $output );

        while( list(
$k, $line ) = each( $output ) )
        {

           
# Valid records begin with host name:
           
if( eregi( "^$host", $line ) )
            {
               
# record found:
               
return true;
            }

        }

        return
false;

    }

}

function
getmxrr_winNT( $hostname, &$mxhosts )
{

    if( !
is_array( $mxhosts ) ) $mxhosts = array();

    if( !empty(
$hostname ) )
    {

        @
exec( "nslookup -type=MX $hostname", $output, $ret );

        while( list(
$k, $line ) = each( $output ) )
        {

           
# Valid records begin with hostname:
           
if( ereg( "^$hostname\tMX preference = ([0-9]+), mail exchanger = (.*)$", $line, $parts ) )
            {

               
$mxhosts[ $parts[1] ] = $parts[2];

            }

        }

        if(
count( $mxhosts ) )
        {

           
reset( $mxhosts );

           
ksort( $mxhosts );

           
$i = 0;

            while( list(
$pref, $host ) = each( $mxhosts ) )
            {
               
$mxhosts2[$i] = $host;
               
$i++;
            }

           
$mxhosts = $mxhosts2;

            return
true;

        }
        else
        {

            return
false;

        }

    }

}

if (
getmxrr_winNT( "microsoft.com", $hosts ) )
{
echo
count($hosts)."<br>";
for (
$i=0; $i<=count($hosts); $i++){
echo
$hosts[$i];}
}
?>
alex at xela dot co dot uk
1.03.2002 14:36
Hi,

Interesting thing I've discovered regarding checkdnsrr. When querying a domain's status using the command, always append a dot to the end of the domain you are querying. I.e.

<?php
checkdnsrr
($domain.'.')
?>

The dot is sometimes necessary if you are searching for a fully qualified domain which has the same name as a host on your local domain.. ie :-

You want to search for "our.info"
and you happen to have a node on your domain called :

our.info.ourdomain.com

If your DNS server is told to check 'ourdomain.com' before any other you will get a positive result when in fact our.info might not exist.

For this reason adding the dot enforces the root. Of course the dot does not alter results that were OK anyway.

Hope that helps some poor confused people :o)

Alex.



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)