Ayer recordé viejos buenos tiempos de phpclasses, y vi un DNServer escrito en Python!, y me dio envidia que haya en Python y no en PHP!. Entonces no dormí hasta terminar un servidor de DNS en php. Y ahí presento el código fuente. Es Public Domain, significa que el código es gratis y libre, y a diferencia del GNU puede formar parte de un programa propietario.
Yesterday I was remembering old times in phpclasses, and I saw a DNServer written in Python!, so I had much envies because that is in Python and not in PHP. So i didn’t sleep until finish a DNS server in php. Here is the source code. This is public domain, this mean that the code is free (as in freedom) and free(priceless). And could be part of a Proprietary software.
<?
class DNServer
{
var $func;
var $socket;
var $types;
/*
** Function Constructor.
** The argument is the name of a function that became
** a callback function. See the example
*/
function DNServer($callback)
{
set_time_limit(0);
$this->func = $callback;
$this->types = array(
“A” => 1,
“NS” => 2,
“CNAME” => 5,
“SOA” => 6,
“WKS” => 11,
“PTR” => 12,
“HINFO” => 13,
“MX” => 15,
“TXT” => 16,
“RP” => 17,
“SIG” => 24,
“KEY” => 25,
“LOC” => 29,
“NXT” => 30,
“AAAA” => 28,
“CERT” => 37,
“A6″ => 38,
“AXFR” => 252,
“IXFR” => 251,
“*” => 255
);
$this->Begin();
}
function Begin()
{
$this->socket = socket_create(AF_INET,SOCK_DGRAM, SOL_UDP);
if ($this->socket < 0)
{
printf(“Error in line %d”, __LINE__ - 3);
exit();
}
if (socket_bind($this->socket, NULL, “53″) == false)
{
printf(“Error in line %d”,__LINE__-2);
exit();
}
/*
* Server Loop
*/
while(1)
{
$len = socket_recvfrom($this->socket, $buf, 1024*4, 0, $ip, $port);
if ($len > 0)
{
$this->HandleQuery($buf,$ip,$port);
}
}
}
function HandleQuery($buf,$clientip,$clientport)
{
$dominio=“”;
$tmp = substr($buf,12);
$e=strlen($tmp);
for($i=0; $i < $e; $i++)
{
$len = ord($tmp[$i]);
if ($len==0)
break;
$dominio .= substr($tmp,$i+1, $len).“.”;
$i += $len;
}
$i++;$i++; /* move two char */
/* Saving the domain name as queried*/
print $DomainAsQueried;
$querytype = array_search((string)ord($tmp[$i]), $this->types ) ;
$dominio = substr($dominio,0,strlen($dominio)-1);
$callback = $this->func;
$ips = $callback($dominio, $querytype);
$answ = $buf[0].$buf[1].chr(129).chr(128).$buf[4].$buf[5].$buf[4].$buf[5];
$answ .= chr(0).chr(0).chr(0).chr(0);
$answ .= $tmp;
$answ .= chr(192).chr(12);
$answ .= chr(0).chr(1).chr(0).chr(1).chr(0).chr(0).chr(0).chr(60).chr(0).chr(4);
$answ .= $this->TransformIP($ips);
if (socket_sendto($this->socket,$answ, strlen($answ), 0,$clientip, $clientport) === false)
printf(“Error in socket\n”);
}
function TransformIP($ip)
{
$nip=“”;
foreach(explode(“.”,$ip) as $pip)
$nip.=chr($pip);
return $nip;
}
}
/* Ej: */
function dnshandler($dominio,$tipo)
{
return “64.64.64.64″;
}
$dns = new DNServer(“dnshandler”);
?>