首先,您传递给名称服务器的名称不是点分隔的,但名称的每个部分都是分开传输的。
其次,您不会将数据转换为十六进制,而是直接发送它们。十六进制(\x01\x01
)就是表示形式。
所以,你会在形式"\x06google\x02nl\x00"
编码您google.nl
,因为每个名称部分是由它的长度之前,最后一个由\x00
意味着空字符串成功 - 这反过来又表示名称的结束链。
所以为了保持变化,你应该把你的域名分割成它的组件,并在它们的每一个之前加上相应的长度字节。
像
function domain2dns($domain)
{
$split = explode(".", $domain);
$target = ""; // cumulate here
foreach ($split as $part) {
// For every $part, prepend one byte denoting its length.
// strlen($part) is its length which is supposed to be put into one character.
$target .= chr(strlen($part)).$part;
}
return $target . "\x00";
}
事做
$domainname = "google.nl";
$dnsdomain = domain2dns($domainname);
$package = "\x01\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00" . $dnsdomain . "\x00\xff\x00\x01";
可能是有用的,所以我的包是: $包= “\ x06google \ x02nl \ X00” 类似的东西? –
@GertKommer不,我只是指它的“名字部分”。它周围的数据包必须正确构建。我想你的'“\ x01 \ x01 ...”'是谨慎选择的,因此是正确的。 – glglgl
@GertKommer根据http://www.firewall.cx/networking-topics/protocols/domain-name-system-dns/160-protocols-dns-query.html,要更详细一些,你的ID是' 0x0101',一个标准查询和一个问题。因此,您的数据包应该是“\ x01 \ x01 \ x01 \ x00 \ x00 \ x01 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00”。“\ x00 \ x00 \ x00 \ x00” x01“'第一部分来自你,第二部分是适当格式的主机名,第三部分是类型和类。 – glglgl