2014-07-03 119 views
1

我創建的工具使用戶能夠修改其反向DNS記錄。由於這些記錄也可以通過外部方法進行修改,所以我可以向用戶顯示其實際的反向DNS記錄。如何查詢特定的域名服務器(本地php)

因爲它既代表gethostbyaddr($ip)也代表dns_get_record(<reversed ip>.in-addr.arpa)在第一個請求之後返回緩存的記錄。

基本上我需要直接查詢authorative nameserver(在我的情況下,它是一個已知的服務器/ ip),以便緩存不是服務器以及它使用的非授權域名服務器的問題) 。

所以實際的問題(也TL; DR):我如何使用PHP本身的方法是最有效的方式查詢特定的(權威的)名稱服務器。 (php 5.3+)

在將此問題標記爲重複項之前,所有類似問題上的現有答案均指向PEAR的NET2類。這個問題尋求答案,如果有一個更簡單的方法來做到這一點,沒有外部類,即。 (新版本的PHP)

回答

0

我在PHP.net上找到了some code docs for gethostbyaddr(),它似乎與特定的DNS服務器建立udp連接(你給它的IP) ,然後找到特定IP的主機名。已經改變了一點,所以它看起來像你想要的代碼。也許它很有用。

<?php 
echo gethostbyaddr_custom('173.194.32.37','8.8.8.8'); 

function gethostbyaddr_custom($ip, $dns){ 
    // random transaction number (for routers etc to get the reply back) 
    $data = rand(0, 99); 
    // trim it to 2 bytes 
    $data = substr($data, 0, 2); 
    // request header 
    $data .= "\1\0\0\1\0\0\0\0\0\0"; 
    // split IP up 
    $bits = explode(".", $ip); 
    // error checking 
    if (count($bits) != 4) return "ERROR"; 
    // there is probably a better way to do this bit... 
    // loop through each segment 
    for ($x=3; $x>=0; $x--) 
    { 
     // needs a byte to indicate the length of each segment of the request 
     switch (strlen($bits[$x])) 
     { 
      case 1: // 1 byte long segment 
       $data .= "\1"; break; 
      case 2: // 2 byte long segment 
       $data .= "\2"; break; 
      case 3: // 3 byte long segment 
       $data .= "\3"; break; 
      default: // segment is too big, invalid IP 
       return "INVALID"; 
     } 
     // and the segment itself 
     $data .= $bits[$x]; 
    } 
    // and the final bit of the request 
    $data .= "\7in-addr\4arpa\0\0\x0C\0\1"; 
    // create UDP socket 
    $handle = @fsockopen("udp://$dns", 53); 
    // send our request (and store request size so we can cheat later) 
    [email protected]($handle, $data); 

    $response = @fread($handle, 1000); 
    @fclose($handle); 
    if ($response == "") 
     return $ip; 
    // find the response type 
    $type = @unpack("s", substr($response, $requestsize+2)); 
    if ($type[1] == 0x0C00) // answer 
    { 
     // set up our variables 
     $host=""; 
     $len = 0; 
     // set our pointer at the beginning of the hostname 
     // uses the request size from earlier rather than work it out 
     $position=$requestsize+12; 
     // reconstruct hostname 
     do 
     { 
      // get segment size 
      $len = unpack("c", substr($response, $position)); 
      // null terminated string, so length 0 = finished 
      if ($len[1] == 0) 
       // return the hostname, without the trailing . 
       return substr($host, 0, strlen($host) -1); 
      // add segment to our host 
      $host .= substr($response, $position+1, $len[1]) . "."; 
      // move pointer on to the next segment 
      $position += $len[1] + 1; 
     } 
     while ($len != 0); 
     // error - return the hostname we constructed (without the . on the end) 
     return $ip; 
    } 
    return $ip; 
} 
?> 
相關問題