我正在创建的工具使用户能够修改其反向DNS记录。由于这些记录也可以通过外部方法进行修改,因此我必须向用户显示其实际的当前反向DNS记录。
因为gethostbyaddr($ip)
以及dns_get_record(<reversed ip>.in-addr.arpa)
在第一个请求之后返回缓存记录。
基本上我需要直接查询authorative名称服务器(在我的情况下,是一个已知的服务器/ ip),这样缓存在服务器和它使用的非授权名称服务器上都不是问题。
所以实际问题(也是 TL; DR ):如何使用本机PHP方法以最有效的方式查询特定(授权)名称服务器。 (php 5.3 +)
在将此问题标记为重复之前:类似问题的所有现有答案都指向PEAR的NET2类。如果在没有外部类的情况下有更简单的方法可以解决这个问题。通过新方法/类(较新版本的PHP)
答案 0 :(得分:1)
我在gessostbyaddr()的PHP.net文档上找到some code,它似乎与特定的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)
$requestsize=@fwrite($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;
}
?>