"A", // RFC 1035 (Address Record; IPv4) 2 => "NS", // RFC 1035 (Name Server) 5 => "CNAME", // RFC 1035 (Canonical Name/Alias) 6 => "SOA", // RFC 1035 (Start of Authority) 12 => "PTR", // RFC 1035 (Pointer/address) 15 => "MX", // RFC 1035 (Mail eXchanger) 16 => "TXT", // RFC 1035 (Text Record) 17 => "RP", // RFC 1183 (Responsible Person) 18 => "AFSDB", // RFC 1183 (AFS Database) 24 => "SIG", // RFC 2535 25 => "KEY", // RFC 2535, RFC 2930 28 => "AAAA", // RFC 3596 (Address Record; IPv6) 29 => "LOC", // RFC 1876 (Geographic Location) 33 => "SRV", // RFC 2782 (Service Locator) 35 => "NAPTR", // RFC 3403 (Naming Authority Pointer) 36 => "KX", // RFC 2230 (Key eXchanger) 37 => "CERT", // RFC 4398 (Certificate Record; used by PGP) 39 => "DNAME", // RFC 2672 (Delegation Name) 41 => "OPT", // RFC 6891 (EDNS: Option) 43 => "DS", // RFC 4034 (DNSSEC: Delegation Signer) 44 => "SSHFP", // RFC 4255 (SSH Public Key Fingerprint) 45 => "IPSECKEY", // RFC 4025 (IPSEC Key) 46 => "RRSIG", // RFC 4034 (DNSSEC: Signature) 47 => "NSEC", // RFC 4034 (DNSSEC: Next-secure Record) 48 => "DNSKEY", // RFC 4034 (DNSSEC: DNS Key Record) 49 => "DHCID", // RFC 4701 (DHCP Identifier) 50 => "NSEC3", // RFC 5155 (DNSSEC: NSEC Record v3) 51 => "NSEC3PARAM", // RFC 5155 (DNSSEC: NSEC3 Parameters) 52 => "TLSA", // RFC 6698 (TLSA certificate association) 55 => "HIP", // RFC 5205 (Host Identity Protocol) 99 => "SPF", // RFC 4408 (SPF: Sender Policy Framework; anti-spam) 249 => "TKEY", // RFC 2930 (Secret Key) 250 => "TSIG", // RFC 2845 (Transaction Signature) 251 => "IXFR", // RFC 1995 (Incremental Zone Transfer) 252 => "AXFR", // RFC 1035 (Authoritative Zone Transfer) 255 => "ANY", // RFC 1035 (Pseudo Record) 32768 => "TA", // No RFC (DNSSEC: Trusted Authorities) 32769 => "DLV" // RFC 4431 (DNSSEC: Lookaside Validation) ); /************************************************ _dnsreadreply(): Receive and decode a DNS result. DO NOT CALL THIS FUNCTION DIRECTLY. This is called by the various dnsquery functions. ************************************************/ function _dnsreadreply($sock,$timeout) { global $DNSType; $Result=false; // Receive data into $Data $r=array($sock); $w=$e=NULL; $Result=false; if (socket_select($r,$w,$e,$timeout,0)) /* $timeout seconds to respond! */ { // Receive no more than 255 bytes if (socket_recv($sock,$Data,255,0)) { $DataLen=strlen($Data); if ($DataLen < 12) { return(false); } // Minimum DNS result is 12 bytes $Result=array(); $Result['ID'] = ord($Data[0])*256 + ord($Data[1]); $Result['Flags'] = ord($Data[2])*256 + ord($Data[3]); $Result['Query'] = ord($Data[4])*256 + ord($Data[5]); $Result['Answer'] = ord($Data[6])*256 + ord($Data[7]); $Result['Authoritative'] = ord($Data[8])*256 + ord($Data[9]); $Result['Additional'] = ord($Data[10])*256 + ord($Data[11]); $rlen=12; /* Skip queries (simple DNS client: I know what I asked!) */ for($c=0; $c < $Result['Query']; $c++) { $Name=''; if (ord($Data[$rlen])==0xc0) { $rlen+=2; break; } while($rlen+4 < $DataLen) { $len=ord($Data[$rlen]); if ($len==0) { $rlen++; break; } $rlen += $len+1; } } if ($c) { $rlen+=4; } /* 4 = type and class */ /* Store answers in $Result array */ for($c=0; $c < $Result['Answer']; $c++) { if ($rlen+4 > $DataLen) break; /* First comes the name. Every segment is null terminated. */ $Name=''; if (ord($Data[$rlen])==0xc0) { /* Length 0xc0 is special: pointer to previous string */ $slen=ord($Data[$rlen+1]); $rlen+=2; while($slen < $DataLen) { $len=ord($Data[$slen]); if ($len==0) { $slen++; break; } if ($slen+$len > $DataLen) { break; } $Name .= substr($Data,$Data+$slen+1,$len) . "."; $slen += $len+1; } } elseif ($rlen < 64) /* DNS limits name segments to 63 bytes each */ { /* Non-special; length of string is provided */ while($rlen < $DataLen) { $len=ord($Data[$rlen]); if ($len==0) { $rlen++; break; } if ($rlen+$len > $DataLen) { break; } $Name .= substr($Data,$Data+$rlen+1,$len) . "."; $rlen += $len+1; } } else { return(false); /* bad length */ } /* Store the name */ if (!isset($Result['Name'])) { $Result['Name'] = $Name; } /* Type of request */ if ($rlen+2 <= $DataLen) { $Type=ord($Data[$rlen])*256 + ord($Data[$rlen+1]); $rlen+=2; if (isset($DNSType[$Type])) { $Type=$DNSType[$Type]; } } /* Class type id (usually 0x0001 == 'IN') */ $rlen+=2; /* skip class */ /* For DNS caching: time to live (TTL) */ if ($rlen+4 <= $DataLen) { $Result['TTL'] =ord($Data[$rlen])<<24; $Result['TTL']|=ord($Data[$rlen+1])<<16; $Result['TTL']|=ord($Data[$rlen+2])<<8; $Result['TTL']|=ord($Data[$rlen+3]); $rlen+=4; } /* Finally: decode the payload */ $PayloadLen=0; if ($rlen+2 <= $DataLen) { $PayloadLen=ord($Data[$rlen])*256 + ord($Data[$rlen+1]); $rlen+=2; } if (($rlen+$PayloadLen <= $DataLen) && !isset($Result[$Type])) { /* Store payload in $Result[$Type] */ $Result[$Type]=substr($Data,$rlen,$PayloadLen); $rlen+=$PayloadLen; /* Any special decoding */ if ($Type=='A') { $Result[$Type] = inet_ntop($Result[$Type]); } elseif ($Type=='AAAA') { $Result[$Type] = inet_ntop($Result[$Type]); } /* TXT begins with a 1-byte length */ elseif ($Type=='TXT') { $Result[$Type] = substr($Result[$Type],1,ord($Result[$Type][0])); } } } /* Ignore authentication and additional responses */ } // if reading DNS reply } // if reading data return($Result); } /* _dnsreadreply() */ /************************************************ dnsqueryhostname(): Perform a basic DNS query. Returns: false if fail, otherwise array of results. ************************************************/ function dnsqueryhostname($server,$qhostname,$port=53,$timeout=2) { /* Idiot check: Prevent timeout of 0 to hang forever. */ $timeout=intval($timeout); if ($timeout <= 0) { $timeout=2; } // echo "Asking server $server on port $port for hostname $qhostname\n"; /* Create the DNS query: $q is DNS query packet */ $q=''; $q .= chr(mt_rand(0,255)) . chr(mt_rand(0,255)); /* ID */ $q .= chr(0x01) . chr(0x00); /* flags: query, permit recursion */ $q .= chr(0x00) . chr(0x01); /* qcount=0x0001 (one question) */ $q .= chr(0x00) . chr(0x00); /* acount=0x0000 (zero answers) */ $q .= chr(0x00) . chr(0x00); /* aacount=0x0000 (zero authorities) */ $q .= chr(0x00) . chr(0x00); /* adcount=0x0000 (zero additional) */ $qlen=12; /* Add in the hostname */ if (substr($qhostname,-1)!='.') { $qhostname .= "."; } $hostpart=explode(".",$qhostname); foreach($hostpart as $h) { $hlen = strlen($h); $q .= chr($hlen) . $h; $qlen+=$hlen+1; } $q .= chr(0x00) . chr(0x01); /* Type "A" (want IPv4 result) */ $q .= chr(0x00) . chr(0x01); /* Class "IN" */ $qlen += 4; // Submit query $sock = socket_create(AF_INET,SOCK_DGRAM,0); /* create UDP socket*/ if (!$sock) return(false); if (!socket_sendto($sock,$q,$qlen,0,$server,$port)) { return(false); } $Result=_dnsreadreply($sock,$timeout); // read reply socket_close($sock); return($Result); } /* dnsqueryhostname() */ // Debug code // Debug: Test against my private DNS:BL server; should return Private address //echo "DNS:BL Test:\n"; print_r(dnsqueryhostname("127.0.0.1","1.2.3.10.","15353")); // Debug: Test against real DNS server; should return my network info //echo "DNS Test:\n"; print_r(dnsqueryhostname("8.8.8.8","hackerfactor.com.")); ?>