<?php
/**
 * This class helps getting the DNS information of any site with an
 * help of a dns server, and re-directs it self to the name server
 * of the specific web site and gets more information
 * 
 * @author G.Kamalakar (gKodes)
 * @package gKodes Networking
 * @name gDNS
 * @version 0.4 RC 1
 * @example example.php
 * @lastUpdated Feb,10 2008
 */

/**
 * Definations for record output sorting.
 * This defines to generate as the old format of output, which was generated in 0.3
 */
define'GDNS_SORT_OLD'3021 );
/**
 * Definations for record output sorting.
 * This defines to generate similar output as php's dns_get_record.
 */
define'GDNS_SORT_PHP'3022 );

class 
gDNS {

    
/**
     * @access pivate
     * @var array
     */

     
private $qtypes = array( 'A' => 1'NS' => 2'ND' => 3'NF' => 4'CNAME' => 5'SOA' => 6,
         
'MB' => 7'MG' => 8'MR' => 9'NULL' => 10'WKS' => 11'PTR' => 12'HINFO' => 13,
         
'MINFO' => 14'MX' => 15'TXT' => 16'RP' => 17'SIG' => 24'KEY' => 25'LOC' => 29,
         
'NXT' => 30'AAAA' => 28'SRV' => 33'NAPTR' => 35'CERT' => 37'A6' => 38'AXFR' => 252,
         
'IXFR' => 251'*' => 255'ANY' => 255 );


    
/**
     * @access pivate
     * @var array
     */
     
private $qclass = array( 'IN' => 1'CS' => 2'CH' => 3'HS' => 4'*' => 255 );

    
/**
     * Contains all the log's
     * 
     * @access public
     * @var array
     */
     
public $t_log '';

    
/**
     * @access pivate
     * @var array
     */
     
private $_responsers = array();

    
/**
     * @access pivate
     * @var array
     */
     
private $_dnsip '192.33.4.12';

    
/**
     * @access pivate
     * @var array
     */
     
private $dnsip_v6 '2001:0503:a83e:0000:0000:0000:0002:0030';

    
/**
     * @access pivate
     * @var string
     */
     
private $datagram;

    
/**
     * @access pivate
     * @var bool
     */
     
private $is_ipv6 false;

    
/**
     * Contains the current processed domain name, Usefull when CNAME is present.
     * 
     * @access public
     * @var array
     */
     
public $cur_domain '';

    
/**
     * @access pivate
     * @var bool
     */
     
private $cname_rider false;


    
/**
      * Constructor function for gDNS
      * 
      * $ipv6 is a bool that specfies to use IPv6, if enabled the class would only use IPv6
      * ip addresses only.
      * $cname is a boolean specfies , to re-direct if a CNAME is found.
      * $def_dns is the default DNS server the querys are sent to,  this may be a domain name
      * or IP address of a DNS server.
     *
      * @access public
      * @param bool $ipv6
      * @param bool $cname
      * @param string $def_dns
      * @return gDNS
     */
    
function gDNS$ipv6 false$cname false$def_dns '' ) {
        
$this->cname_rider $cname;
        if( 
strlen($def_dns) > ) {
            if( 
$ipv6 ) {
                
$this->dnsip_v6 $def_dns;
                } else{
                
$this->dnsip $def_dns;
            }
        }
        
$this->is_ipv6 $ipv6;
    }

    
/**
     * Query for an DNS record
     * 
     * $domain is the domain name for which you want to get the DNS records for.
     * $type is the type of DNS records you want for example : NS => Name Server , MX => Mail Exchange
     * $auth is a boolean sepecfing that you want the request for the Authoritative DNS server of
     * the specfic domain name.
     * $class is the class in which you what the records for example : IN => Internet
     * $server is the dns server you want to use for the current query, this may be a domain name
     * or IP address of a DNS server.
     *
     * @access public
     * @param string $domain
     * @param string $type
     * @param bool $auth
     * @param string $class
     * @param string $server
     * @return bool
     */
    
public function query$domain$type '*' $auth true $class 'IN'$server null$longquery=false ) {
        
$response $this->packetBuilder$domain$type$class$server, array( 'opc' => 0'longquery'=>$longquery ) );
         if ( 
$response && is_array$response ) && count$response ) == ) {
            
/* loop for Authoritative Answer response.  */
            
while ( is_array$response ) && $auth && !$response['Header']["AA"]
                 && 
$response['Request'] != $domain ) {
                     
$server $this->getDnsServer$response['Records'] );
                    
$this->t_log[] = "Request redirected to $server for records of $domain";
                 
$response $this->packetBuilder$domain$type$class$server, array('opc'=>0) );
            }
            if( 
$this->cname_rider && ( $new_domain $this->CnameReDir($response['Records']) ) ) {
                
$server $this->getDnsServer$response['Records'] );
                    
$this->clearRecords($domain);
                    
$this->cur_domain $new_domain;
                return 
$this->Query($new_domain$type$auth$class$server);
            }
            if ( 
is_array$response ) ) {
                
$this->_responsers[$domain] = $response;
                
$this->cur_domain $domain;
                return 
true;
                }
            }
        
$this->t_log[] = 'Failed to get DNS Records.';
        return 
false;
    }

    
/**
     * Used to build request packed and get the response.
     *
     * @access private
     * @param string $domain
     * @param specfies $type
     * @param specfies $class
     * @param specfies $server
     * @param array $flags
     * @return bool|array
     */
    
private function packetBuilder$domain$type '*'$class 'IN'$server null$flags = array()) {
         if ( 
strlen$domain ) > && $this->isValidDomain$domain ) ) {
            
$response = array();
             
$id chrrand1255 ) ) . chrrand1255 ) );
             
#$id = chr( hexdec(0) ) . chr( hexdec(29) );  // used by DIG
             #$id = chr( 00 ) . chr( 23 ) . chr( 48) . chr( 23 ) ; // used by dig in TCP mode

             
$this->recivedPack null;
             
$query $id chr( ( ( $flags['opc'] << ) | ) ) . chr) . chr) . chr) .
             
chr) . chr) . chr) . chr) . chr) . chr(($flags['longquery']==true)?1:0);
             foreach( 
explode'.'$domain ) as $uri ) {
                
$query .= chrstrlen$uri ) ) . $uri;
             }
            
$query .= chr(0).chr(0).chr$this->qtypes[$type] ).chr(0).chr$this->qclass[$class] );

            if (
$flags['longquery']==true)// for long querys lig DIG +bufsize=4000
             
foreach(explode(' ''00 00 29 0f a0 00 00 00 00 00 00') AS $o)
              
$query .= chr(hexdec($o));

            
$server $this->getDnsServer$server );
             if ( 
$server === false ) {
                return 
false;
                 }
            
$this->t_log[] = "Requesting $server for records of $domain";
             
$dns_server fsockopen'udp://' $server53 );
             
stream_set_timeout$dns_server10 );
             if ( 
$dns_server ) {
                
fwrite$dns_server$query );
                 if ( ( 
$recivedPack = @fread$dns_server) ) !== false ) {
                    
$str_info stream_get_meta_data$dns_server );
                     if ( 
$str_info['unread_bytes'] > && !$str_info['timed_out'] ) {
                        
$recivedPack .= fread$dns_server$str_info['unread_bytes'] );
                         
// file_put_contents("packet.dunp", $recivedPack);
                        
$response $this->responseParser$recivedPacktrue );
                         }else if ( 
$str_info['timed_out'] ) {
                        
$this->t_log[] = 'Connection timed out.';
                         return 
false;
                         }
                    }
                 
$str_info stream_get_meta_data$dns_server );
                 
fclose$dns_server );
                 return 
$response;
                 } else  {
                  
$this->t_log[] = 'Failed to establish connection with the Server.';
                 }
            }else {
            
$this->t_log[] = 'Invalid Domain Name.';
             }
        return 
false;
    }
    
    
/**
     * Process the responce header
     *
     * @access private 
     * @return array 
     */
    
private function Header_processor$packet ) {
         
$head sprintf'%08d'decbinord($packet{2}) ) ) .
                                          
sprintf'%08d'decbinord($packet{3}) ) );
         
$info = array( 
             
'ID' => substr$this->recivedPack0),
             
'QR' => ( bool )$head{0},
             
'OPCODE' => bindecsubstr$head1) ),
             
'AA' => ( bool )$head{5},
             
'TC' => ( bool )$head{6},
             
'RD' => ( bool )$head{7},
             
'RA' => ( bool )$head{8},
             
'Z' => bindecsubstr$head9) ),
             
'RCODE' => bindecsubstr$head, -1) ),
             
'QDCOUNT' => $this->bit8to16substr$packet4) ),
             
'ANCOUNT' => $this->bit8to16substr$packet6) ),
             
'NSCOUNT' => $this->bit8to16substr$packet8) ),
             
'ARCOUNT' => $this->bit8to16substr$packet10) )
             );
        return 
$info;
    }
    
    
/**
     * Returns the lable at the specfic position sepcfide.
     *
     * @access private 
     * @param int $loc
     * @param string $packet 
     */
    
private function GetLable( &$loc ) {
        unset(
$lable);
        
$lable = array();
        
$loc_c $loc;
         if ( 
is_string$this->datagram ) && strlen$this->datagram ) > ) {
            while ( 
ord$this->datagram $loc }) != ) {
                if ( ( ( 
ord$this->datagram $loc }) ^ 192 ) <= 63 ) ) {


                    
$ploc $this->bit8to16( ( chr( ( ord$this->datagram{$loc}) ^ 192 ) ) . $this->datagram$loc }) ); 
                     
$loc += 2;
                     return 
array_merge$lable$this->GetLable$ploc ) );
                } else {
                    
$a substr$this->datagram$loc 1ord$this->datagram{$loc}) );
                    
$lable[] = $a
                    
$loc += ord$this->datagram{$loc}) + 1;
                    }
                }
            if ( 
count$lable ) > ) {
                
$this->labels[$loc_c] = $lable;
                 }
            }
        return 
$lable;
    }

    
/**
     * Processes the response from the DNS server.
     *
     * @access private
     * @param string $packet
     * @return array
     */
    
private function responseParser$packet ) {
        
$i 12;
        
$this->datagram $packet;
        
$this->labels = array();
        
$header $this->Header_processor$packet );
        
$res_info = array( 
            
'Header'  => $header,
            
'Records' => array()
        );
         if ( 
$header['RCODE'] == 0
             
&& ( $header['ANCOUNT'] > || $header['ARCOUNT'] > || $header['NSCOUNT'] > ) ) {
            
$res_info['Request'] = $this->readQuestion$i );
             
$len strlen$packet );
             for ( ; 
$i $len$i += 10 ) {
                
$domain $this->GetLable$i );
                 
$type $this->bit8to16substr$packet$i ) );
                 
$class $this->bit8to16substr$packet$i ) );
                 
$ttl $this->bit16to32substr$packet$i ) );
                 
$rdlength $this->bit8to16substr$packet$i ) );
                 
$rdata substr$packet$i 10$rdlength );
                 
$record = array( 
                     
'Domain' => implode'.'$domain ),
                     
'Type'   => array_search$type $this->qtypes ),
                     
'Class'  => array_search$class$this->qclass ),
                     
'Ttl'    => $ttl,
                     
'Record' => $this->RData$type$i 10$i 10 $rdlength$rdata  )
                     );
                 
$i += strlen$rdata );
                 
$res_info['Records'][] = $record;
                 }
            return 
$res_info;
             }else {
            
$this->t_log[] = 'There might be a problum in the request data, or the server had'.
                             
' responded with zero records as response.';
        }
        return 
false;
    }

    
/**
     * Returns the full response with Header, Request and Records (in GDNS_SORT_PHP format) of the
     * specfied domain.
     *
     * @access public
     * @param string $domain
     * @return array
     */
    
public function getResponse$domain ) {
        if ( 
array_key_exists$domain$this->_responsers ) ) {
            return 
$this->_responsers[$domain];
        }
        return 
false;
    }

    
/**
     * Returns the response records of the specfied domain.
     *
     * @access public
     * @param string $domain
     * @param int $sort_id
     * @return array
     */
    
public function getRecords$domain$sort_id GDNS_SORT_OLD ) {
         if ( !
array_key_exists$domain$this->_responsers ) ) {
            return 
false;
             }
        if ( 
$sort_id == GDNS_SORT_PHP ) {
            return 
$this->_responsers[$domain]['Records'];
        } else if ( 
$sort_id == GDNS_SORT_OLD ) {
            
$records = array();
             foreach ( 
$this->_responsers[$domain]['Records'] as $record )
              if (!empty(
$record['Domain'])) // bugfix for extralong parameter
              
{
                if ( !
key_exists$record['Domain'], $records ) ) {
                    
$records[$record['Domain']] = array();
                     }
                if ( !
key_exists$record['Class'], $records[$record['Domain']] ) ) {
                    
$records[$record['Domain']][$record['Class']] = array();
                     }
                if ( !
key_exists$record['Type'], $records[$record['Domain']][$record['Class']] ) ) {
                    
$records[$record['Domain']][$record['Class']][$record['Type']] = array();
                     }
                
$records[$record['Domain']][$record['Class']][$record['Type']][] = array( 
                    
'TTL' => $record['Ttl'],
                     
'Responce' => $record['Record']
                     );
             }
            return 
$records;
        }
        return 
false;
    }
    
    
/**
     * Process RR record Data.
     *
     * @access private 
     * @param string $type 
     * @param string $data 
     * @return mixed 
     */
    
private function RData$type$ind$len$rdata  ) {
        
$return null;
        switch ( 
$type ) {
        case 
1:/* A */
             
$return = array();
             for( ; 
$ind $len$ind++ ) {
                
$return[] = ord$this->datagram{$ind});
                 };
             
$return implode'.'$return );
             break;
         case 
2:/* NS */
         
case 3:/* MD */
         
case 4:/* MF */
         
case 5:/* CNAME */
             
$return implode'.'$this->GetLable$ind ) );
             break;
         case 
6:/* SOA */
             
$return = array();
             
$return['MNAME'] = implode'.', ( $this->GetLable$ind ) ) );
             
$return['RNAME'] = $this->toMail( ( $this->GetLable$ind ) ) );
             
$return['SERIAL'] = $this->bit16to32substr$this->datagram$ind) );
             
$return['REFRESH'] = $this->bit16to32substr$this->datagram$ind 4) );
             
$return['RETRY'] = $this->bit16to32substr$this->datagram$ind 8) );
             
$return['EXPIRE'] = $this->bit16to32substr$this->datagram$ind 12) );
             
$return['MINIMUM'] = $this->bit16to32substr$this->datagram$ind 16) );
             break;
         case 
7:/* MB */
         
case 8:/* MG */
         
case 9:/* MR */
             
$return $this->toMail( ( $this->GetLable$ind ) ) );
             break;
         case 
10:/* NULL */
             
$return '';
             break;
         case 
11:/* WKS */
             
$return = array( 
                
'address' => $this->RData1$ind),
                
'protocall' => ord$this->datagram {
                        
$ind 5}
                    ),
                 
'bitmap' => substr$this->datagram$ind 6$len - ( $ind ) )
                 );
             break;
         case 
12:/* PTR */
             
$return implode'.', ( $this->GetLable$ind ) ) );
             break;
         case 
13:/* HINFO */
             
$i $this->GetLable$ind );
             
$return = array( 
                
'cpu' => $i[0],
                 
'os' => $i[1]
                 );
             break;
         case 
14:/* MINFO */
             
$return = array( 
                
'RMAILBX' => $this->toMail$this->GetLable$ind ) ),
                 
'EMAILBX' => $this->toMailsubstr$this->datagram$ind$len $ind ) )
                 );
             break;
         case 
15:/* MX */
             
$ind += 2;
             
$return = array( 
                
'prefrence' => $this->bit8to16$this->datagram {
                        
$ind-2}
                    . 
$this->datagram {
                        
$ind-1}
                    ),
                 
'domain' => implode'.'$this->GetLable$ind ) )
                 );
             break;
         case 
16:/* TXT */ 
          
$i 0
          while(
$i<strlen($rdata))
          {
           
$length ordsubstr$rdata$i1) );

               if (
$length==0)
                
$return[] = '';
               else
            
$return[] = substr($rdata, ($i+1), $length);

           
$i += $length+1;
          }
             break;
         case 
17:/* RP */
             
$return $return = array( 
                
'mbox' => $this->toMail$this->GetLable$ind ) ),
                
'txtdname' => implode'.'$this->GetLable$ind ) )
                );
             break;
         case 
28:/* AAAA */
             
$return = array();
             for( ; 
$ind $len$ind += ) {
                
$return[] = sprintf'%02s'dechexord$this->datagram{$ind}) ) )
                             . 
sprintf'%02s'dechexord$this->datagram {$ind 1}) ) );
                 };
             
$return implode':'$return );
             break;
         case 
29:/* LOC rfc1876 */
             
$lat sprintf'%u'$this->bit16to32substr$this->datagram$ind 4) ) );
             
$lon sprintf'%u'$this->bit16to32substr$this->datagram$ind 8) ) );
             
$return = array( 
                
'size' => sprintf'%01.2fm'$this->Loc_8_4$this->datagram{$ind 1}) / 100 ),
                
'horiz_pre' => sprintf'%01.2fm'$this->Loc_8_4$this->datagram {$ind 2}) / 100 ),
                
'vert_pre' => sprintf'%01.2fm'$this->Loc_8_4$this->datagram {$ind 3}) / 100 ),
                
'latitude' => implode':'$this->Loc_dms$lat ) ) . ' '
                                                         
. ( ( $lat pow231 ) )? 'N' 'S' ),
                
'longitude' => implode':'$this->Loc_dms$lon ) ) . ' '
                                                         
. ( ( $lon pow231 ) )? 'E' 'W' ),
                
'altitude' => sprintf'%01.2fm',
                     ( ( 
$this->bit16to32substr$this->datagram12) )-10000000 ) / 100 ) )
                );
             break;
         case 
33:/* SRV rfc2782 */
             
$return = array( 
                
'priority' => $this->bit8to16substr$this->datagram$ind) ),
                
'weight' => $this->bit8to16substr$this->datagram$ind 4) ),
                
'port' => $this->bit8to16substr$this->datagram$ind 6) ),
                
'target' => implode'.'substr$this->datagram$ind 7$len-) )
                 );
             break;
         case 
35:/* NAPTR */
             
             
$string substr$this->datagram$ind$len-$ind );
             
$maxLangth strlen($string);
             
             
$return = array();
             
$return[] = ord(substr($string11));
             
$return[] = ord(substr($string31));
             
             
$i 4;
                  
             
$length ordsubstr$string$i1) );
             
             if (
$length==&& $i<($maxLangth-1))
             {
               
$tmp = array();

               
$i 7;  
               while(
$i<strlen($string))   
               {
                
$length ordsubstr$string$i1) );
              
                if (
$length==0)
                 break;
                                             
                
$tmp[] = substr($string, ($i+1), $length);
                
$i += $length+1;  
               }

              
$return[] = $tmp;     
              
             } else {

              while(
$i<strlen($string))   
              {
               
$length ordsubstr$string$i1) );
              
               if (
$length==0)
                break;
                                             
               
$return[] = substr($string, ($i+1), $length);
               
$i += $length+1;  
              }

             }
                          
                      
             break;
         default:
             
$return substr$this->datagram$ind$len-$ind );
             }
        return 
$return;
    }

    
/**
     * Used for convertion the lable array to an valid mail id.
     *
     * @access private
     * @param array $domain
     * @return string
     */
    
private function toMail$domain ) {
         
$mail $domain[0] . '@';
         unset( 
$domain[0] );
         return 
$mail implode'.'$domain );
    }

    
/**
     * Additional function to process LOC record
     *
     * @access private
     * @param int $raw_sec
     * @return array
     */
    
private function Loc_dms$raw_sec ) {
         
$abs absabs$raw_sec ) - pow231 ) );
         
$deg = ( int ) ( $abs / ( 60 60 1000 ) );
         
$abs -= $deg * ( 60 60 1000 );
         
$min = ( int ) ( $abs / ( 60 1000 ) );
         
$abs -= $min * ( 60 1000 );
         
$sec = ( int ) ( $abs 1000 );
         
$abs -= $sec 1000;
         
$msec $abs;
         return array( 
            
'dec' => $deg,
            
'min' => $min,
            
'sec' => $sec '.' sprintf'%03d'$msec )
       );
    }

    
/**
     * Additional function to process LOC record
     *
     * @access private
     * @param string $data
     * @return float
     */
    
private function Loc_8_4$data ) {
         
$size decbinord$data ) );
         return ( 
bindecsubstr$size0strlen$size )-) ) * 
                                                        
pow10bindecsubstr$size, -) ) ) );
    }

    
/**
     * Reads the Question Session from the response data.
     *
     * @access privae
     * @param string $loc
     * @return array
     */
    
private function readQuestion( &$loc ) {
    
$qu = array( 
        
'QNAME' => implode'.'$this->GetLable$loc ) ),
        
'QTYPE' => array_search$this->bit8to16substr$this->datagram$loc ) )
                                                                                , 
$this->qtypes ),
        
'QCLASS' => array_search$this->bit8to16substr$this->datagram$loc ) )
                                                                                , 
$this->qclass )
            );
            
$loc += 5;
        return 
$qu;
    }

    
/**
     * Return the NS records from the given record set
     *
     * @access private
     * @param array $records
     * @param bool $ipv6
     * @return array
     */
    
private function getNS$records$ipv6 false ) {
         
$ns = array();
         foreach ( 
$records as $record ) {
            if ( 
$record['Type'] == 'NS' ) {
                
$ns[$record['Record']] = $record['Record'];
                 } else if ( 
array_key_exists$record['Domain'], $ns ) &&
                     ( ( !
$ipv6 && $record['Type'] == 'A' ) || ( $ipv6 && $record['Type'] == 'AAAA' ) ) ) {
                if ( 
$record['Type'] == 'A' ) {
                        
$ns[$record['Domain']] = $record['Record'];
                     }else {
                        
$ns[$record['Domain']] = '[' $record['Record'] . ']';
                     }
                }
            }
        return 
$ns;
    }

    
/**
     * Return a valid DNS server IP.
     *
     * @access private
     * @param string $server
     * @return string
     */
    
private function getDnsServer$server ) {
        if ( 
is_array$server ) ) {
            
$ns $this->getNS$server$this->is_ipv6 );
            if( 
count($ns) > ) {
                
$ns_name array_keys$ns );
                    
$serv_id rand0count$ns )-);
                return ( 
$ns[$ns_name[$serv_id]] === false )? 
                            
$ns_name[$serv_id] : $ns[$ns_name[$serv_id]];
            }
            return 
false;
        }
        if ( 
$server && !$this->isIP$server ) ) {
            
$this->Query$server'A'true );
            
$records $this->getRecords$serverGDNS_SORT_PHP );
            
$this->clearRecords$server );
            if ( 
$records ) {
                
$type = ( ($this->is_ipv6)? 'AAAA' 'A' ) ;
                foreach ( 
$records as $record ) {
                    if ( 
$record['Type'] == $type && $record['Domain'] == $server ) {
                        return 
$record['Record'];
                         }
                    }
                }
                
$this->t_log[] = 'Failed to find a valid ipV'.
                        ( (
$this->is_ipv6)? '6' '4' ).' Supported Name Server';
            return 
false;
             }
        return ( ( 
$server )? $server 
                            ( (
$this->is_ipv6)? '['.$this->dnsip_v6.']' :  $this->_dnsip ) );
    }

    
/**
     * Checks for a CNAME, if found will return the CNAME or else returns false.
     *
     * @access private
     * @return bool|string
     */
    
private function CnameReDir($records) {
        if( 
is_array($records) && count($records) > ) {
        foreach ( 
$records as $record ) {
                if( 
$record['Type'] == 'CNAME' ) {
                        
$this->t_log[] = 'CNAME present, re-directed to ' $record['Record'];
                        
$this->cur_domain $record['Record'];
                    return 
$record['Record'];
                }
            }
        }
        return 
false;
    }

    
/**
     * Removes the records of the specfied domain.
     *
     * @access public
     * @param string $domain
     */
    
public function clearRecords$domain ) {
         unset( 
$this->_responsers[$domain] );
    }

    
/**
     * Validates if the given $ip is a valid IPv4 or IPv6 IP address.
     *
     * @access public
     * @param string $ip
     * @param bool $ip6
     * @return bool
     */
    
public function isIP$ip $ip6 false ) {
         
$ipv4 '/^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$/';
         
$ipv6 '/^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/';
         return ( 
preg_match( ( ( $ip6 )? $ipv6 $ipv4 ) , $ip ) > )? true false;
    }

    
/**
     * Validates if the given $domain is an valid domain.
     *
     * @access public
     * @param string $doamin
     * @return bool
     */
    
public function isValidDomain$doamin ) {
         
$dreg '/^([a-zA-Z0-9\_]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}$/';
         return ( 
preg_match$dreg$doamin ) >= )? true false;
    }
    
    
/**
     * Converts 8bit to 16bit data.
     *
     * @access private 
     * @param array $char 
     * @return int 
     */
    
private function bit8to16$char ) { 
         return ( int ) ( @
ord( @$char{0}) << | @ord( @$char{1}) );
    }
    
    
/**
     * Converts 16bit to 32bit data.
     *
     * @access private 
     * @param array $char 
     * @return double 
     */
    
private function bit16to32$char ) {
         return ( double ) ( 
$this->bit8to16$char{0}. $char{1}) << 16 
                                                 
$this->bit8to16$char{2}. $char{3}) );
    }
}
?>