Net_DNS
[ class tree: Net_DNS ] [ index: Net_DNS ] [ all elements ]

Source for file Resolver.php

Documentation is available at Resolver.php

  1. <?php
  2. /*
  3.  *  License Information:
  4.  *
  5.  *    Net_DNS:  A resolver library for PHP
  6.  *    Copyright (c) 2002-2003 Eric Kilfoil eric@ypass.net
  7.  *
  8.  *    This library is free software; you can redistribute it and/or
  9.  *    modify it under the terms of the GNU Lesser General Public
  10.  *    License as published by the Free Software Foundation; either
  11.  *    version 2.1 of the License, or (at your option) any later version.
  12.  *
  13.  *    This library is distributed in the hope that it will be useful,
  14.  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  *    Lesser General Public License for more details.
  17.  *
  18.  *    You should have received a copy of the GNU Lesser General Public
  19.  *    License along with this library; if not, write to the Free Software
  20.  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21.  */
  22.  
  23.  
  24. /* Net_DNS_Resolver object definition {{{ */
  25. /**
  26.  * A DNS Resolver library
  27.  *
  28.  * Resolver library.  Builds a DNS query packet, sends the packet to the
  29.  * server and parses the reponse.
  30.  *
  31.  * @package Net_DNS
  32.  */
  33. {
  34.     /* class variable definitions {{{ */
  35.     /**
  36.      * An array of all nameservers to query
  37.      *
  38.      * @var array $nameservers 
  39.      * @access public
  40.      */
  41.     var $nameservers;
  42.     /**
  43.      * The UDP port to use for the query (default = 53)
  44.      *
  45.      * @var integer $port 
  46.      * @access public
  47.      */
  48.     var $port;
  49.     /**
  50.      * The domain in which the resolver client host resides.
  51.      *
  52.      * @var string $domain 
  53.      * @access public
  54.      */
  55.     var $domain;
  56.     /**
  57.      * The searchlist to apply to unqualified hosts
  58.      *
  59.      * An array of strings containg domains to apply to unqualified hosts
  60.      * passed to the resolver.
  61.      *
  62.      * @var array $searchlist 
  63.      * @access public
  64.      */
  65.     var $searchlist;
  66.     /**
  67.      * The number of seconds between retransmission of unaswered queries
  68.      *
  69.      * @var integer $retrans 
  70.      * @access public
  71.      */
  72.     var $retrans;
  73.     /**
  74.      * The number of times unanswered requests should be retried
  75.      *
  76.      * @var integer $retry 
  77.      * @access public
  78.      */
  79.     var $retry;
  80.     /**
  81.      * Whether or not to use TCP (Virtual Circuits) instead of UDP
  82.      *
  83.      * If set to 0, UDP will be used unless TCP is required.  TCP is
  84.      * required for questions or responses greater than 512 bytes.
  85.      *
  86.      * @var boolean $usevc 
  87.      * @access public
  88.      */
  89.     var $usevc;
  90.     /**
  91.      * Unknown
  92.      */
  93.     var $stayopen;
  94.     /**
  95.      * Ignore TC (truncated) bit
  96.      *
  97.      * If the server responds with the TC bit set on a response, and $igntc
  98.      * is set to 0, the resolver will automatically retransmit the request
  99.      * using virtual circuits (TCP).
  100.      *
  101.      * @access public
  102.      * @var boolean $igntc 
  103.      */
  104.     var $igntc;
  105.     /**
  106.      * Recursion Desired
  107.      *
  108.      * Sets the value of the RD (recursion desired) bit in the header. If
  109.      * the RD bit is set to 0, the server will not perform recursion on the
  110.      * request.
  111.      *
  112.      * @var boolean $recurse 
  113.      * @access public
  114.      */
  115.     var $recurse;
  116.     /**
  117.      * Unknown
  118.      */
  119.     var $defnames;
  120.     /**
  121.      * Unknown
  122.      */
  123.     var $dnsrch;
  124.     /**
  125.      * Contains the value of the last error returned by the resolver.
  126.      *
  127.      * @var string $errorstring 
  128.      * @access public
  129.      */
  130.     var $errorstring;
  131.     /**
  132.      * The origin of the packet.
  133.      *
  134.      * This contains a string containing the IP address of the name server
  135.      * from which the answer was given.
  136.      *
  137.      * @var string $answerfrom 
  138.      * @access public
  139.      */
  140.     var $answerfrom;
  141.     /**
  142.      * The size of the answer packet.
  143.      *
  144.      * This contains a integer containing the size of the DNS packet the
  145.      * server responded with.
  146.      *
  147.      * @var string $answersize 
  148.      * @access public
  149.      */
  150.     var $answersize;
  151.     /**
  152.      * The number of seconds after which a TCP connection should timeout
  153.      *
  154.      * @var integer $tcp_timeout 
  155.      * @access public
  156.      */
  157.     var $tcp_timeout;
  158.     /**
  159.      * The location of the system resolv.conf file.
  160.      *
  161.      * @var string $resolv_conf 
  162.      */
  163.     var $resolv_conf = '/etc/resolv.conf';
  164.     /**
  165.      * The name of the user defined resolv.conf
  166.      *
  167.      * The resolver will attempt to look in both the current directory as
  168.      * well as the user's home directory for a user defined resolver
  169.      * configuration file
  170.      *
  171.      * @var string $dotfile 
  172.      * @see Net_DNS_Resolver::$confpath
  173.      */
  174.     var $dotfile = '.resolv.conf';
  175.     /**
  176.      * A array of directories to search for the user's resolver config
  177.      *
  178.      * @var string $confpath 
  179.      * @see Net_DNS_Resolver::$dotfile
  180.      */
  181.     var $confpath;
  182.     /**
  183.      * debugging flag
  184.      *
  185.      * If set to true (non-zero), debugging code will be displayed as the
  186.      * resolver makes the request.
  187.      *
  188.      * @var boolean $debug; 
  189.      * @access public
  190.      */
  191.     var $debug;
  192.     /**
  193.      * use the (currently) experimental PHP socket library
  194.      *
  195.      * If set to true (non-zero), the Resolver will attempt to use the
  196.      * much more effecient PHP sockets extension (if available).
  197.      *
  198.      * @var boolean $useEnhancedSockets; 
  199.      * @access public
  200.      */
  201.     var $useEnhancedSockets = true;
  202.     /**
  203.      * An array of sockets connected to a name servers
  204.      *
  205.      * @var array $sockets 
  206.      * @access private
  207.      */
  208.     var $sockets;
  209.     /**
  210.      * axfr tcp socket
  211.      *
  212.      * Used to store a PHP socket resource for a connection to a server
  213.      *
  214.      * @var resource $_axfr_sock; 
  215.      * @access private
  216.      */
  217.     var $_axfr_sock;
  218.     /**
  219.      * axfr resource record list
  220.      *
  221.      * Used to store a resource record list from a zone transfer
  222.      *
  223.      * @var resource $_axfr_rr; 
  224.      * @access private
  225.      */
  226.     var $_axfr_rr;
  227.     /**
  228.      * axfr soa count
  229.      *
  230.      * Used to store the number of soa records received from a zone transfer
  231.      *
  232.      * @var resource $_axfr_soa_count; 
  233.      * @access private
  234.      */
  235.     var $_axfr_soa_count;
  236.  
  237.  
  238.     /* }}} */
  239.     /* class constructor - Net_DNS_Resolver() {{{ */
  240.     /**
  241.      * Initializes the Resolver Object
  242.      * 
  243.      * @return Net_DNS_Resolver 
  244.      */
  245.     function Net_DNS_Resolver($defaults = array())
  246.     {
  247.         $mydefaults = array(
  248.                 'nameservers' => array(),
  249.                 'port'        => '53',
  250.                 'domain'      => '',
  251.                 'searchlist'  => array(),
  252.                 'retrans'     => 5,
  253.                 'retry'       => 4,
  254.                 'usevc'       => 0,
  255.                 'stayopen'    => 0,
  256.                 'igntc'       => 0,
  257.                 'recurse'     => 1,
  258.                 'defnames'    => 1,
  259.                 'dnsrch'      => 1,
  260.                 'debug'       => 0,
  261.                 'errorstring' => 'unknown error or no error',
  262.                 'answerfrom'  => '',
  263.                 'answersize'  => 0,
  264.                 'tcp_timeout' => 120
  265.                 );
  266.         foreach ($mydefaults as $k => $v{
  267.             $this->{$k= isset($defaults[$k]$defaults[$k$v;
  268.         }
  269.         $this->confpath[0= getenv('HOME');
  270.         $this->confpath[1'.';
  271.         $this->res_init();
  272.     }
  273.  
  274.     /* }}} */
  275.     /* Net_DNS_Resolver::res_init() {{{ */
  276.     /**
  277.      * Initalizes the resolver library
  278.      *
  279.      * res_init() searches for resolver library configuration files and
  280.      * initializes the various properties of the resolver object.
  281.      *
  282.      * @see Net_DNS_Resolver::$resolv_conf, Net_DNS_Resolver::$dotfile,
  283.      *       Net_DNS_Resolver::$confpath, Net_DNS_Resolver::$searchlist,
  284.      *       Net_DNS_Resolver::$domain, Net_DNS_Resolver::$nameservers
  285.      * @access public
  286.      */
  287.     function res_init()
  288.     {
  289.         $err error_reporting(0);
  290.         if (file_exists($this->resolv_conf&& is_readable($this->resolv_conf)) {
  291.             $this->read_config($this->resolv_conf);
  292.         }
  293.  
  294.         foreach ($this->confpath as $dir{
  295.             $file $dir.DIRECTORY_SEPARATOR.$this->dotfile;
  296.             if (file_exists($file&& is_readable($file)) {
  297.                 $this->read_config($file);
  298.             }
  299.         }
  300.  
  301.         $this->read_env();
  302.  
  303.         if (!strlen($this->domain&& sizeof($this->searchlist)) {
  304.             $this->domain = $this->searchlist[0];
  305.         else if (sizeof($this->searchlist&& strlen($this->domain)) {
  306.             $this->searchlist = array($this->domain);
  307.         }
  308.         error_reporting($err);
  309.     }
  310.  
  311.     /* }}} */
  312.     /* Net_DNS_Resolver::read_config {{{ */
  313.     /**
  314.      * Reads and parses a resolver configuration file
  315.      *
  316.      * @param string $file The name of the file to open and parse
  317.      */
  318.     function read_config($file)
  319.     {
  320.         if (($f fopen($file'r'))) {
  321.             $this->error = "can't open $file";
  322.         }
  323.  
  324.         while (feof($f)) {
  325.             $line chop(fgets($f10240));
  326.             $line ereg_replace('(.*)[;#].*''\\1'$line);
  327.             if (ereg("^[ \t]*$"$line$regs)) {
  328.                 continue;
  329.             }
  330.             ereg("^[ \t]*([^ \t]+)[ \t]+([^ \t]+)"$line$regs);
  331.             $option $regs[1];
  332.             $value $regs[2];
  333.  
  334.             switch ($option{
  335.                 case 'domain':
  336.                     $this->domain = $regs[2];
  337.                     break;
  338.                 case 'search':
  339.                     $this->searchlist[count($this->searchlist)$regs[2];
  340.                     break;
  341.                 case 'nameserver':
  342.                     foreach (split(' '$regs[2]as $ns{
  343.                         $this->nameservers[count($this->nameservers)$ns;
  344.                     }
  345.                     break;
  346.             }
  347.         }
  348.         fclose($f);
  349.     }
  350.  
  351.     /* }}} */
  352.     /* Net_DNS_Resolver::read_env() {{{ */
  353.     /**
  354.      * Examines the environment for resolver config information
  355.      */
  356.     function read_env()
  357.     {
  358.         if (getenv('RES_NAMESERVERS')) {
  359.             $this->nameservers = split(' 'getenv('RES_NAMESERVERS'));
  360.         }
  361.  
  362.         if (getenv('RES_SEARCHLIST')) {
  363.             $this->searchlist = split(' 'getenv('RES_SEARCHLIST'));
  364.         }
  365.  
  366.         if (getenv('LOCALDOMAIN')) {
  367.             $this->domain = getenv('LOCALDOMAIN');
  368.         }
  369.  
  370.         if (getenv('RES_OPTIONS')) {
  371.             $env split(' 'getenv('RES_OPTIONS'));
  372.             foreach ($env as $opt{
  373.                 list($name$valsplit(':'$opt);
  374.                 if ($val == ''{
  375.                     $val = 1;
  376.                 }
  377.                 $this->{$name$val;
  378.             }
  379.         }
  380.     }
  381.  
  382.     /* }}} */
  383.     /* Net_DNS_Resolver::string() {{{ */
  384.     /**
  385.      * Builds a string containing the current state of the resolver
  386.      *
  387.      * Builds formatted string containing the state of the resolver library suited
  388.      * for display.
  389.      *
  390.      * @access public
  391.      */
  392.     function string()
  393.     {
  394.         $state  ";; Net_DNS_Resolver state:\n";
  395.         $state .= ';;  domain       = ' $this->domain . "\n";
  396.         $state .= ';;  searchlist   = ' implode(' '$this->searchlist"\n";
  397.         $state .= ';;  nameservers  = ' implode(' '$this->nameservers"\n";
  398.         $state .= ';;  port         = ' $this->port . "\n";
  399.         $state .= ';;  tcp_timeout  = ';
  400.         $state .= ($this->tcp_timeout ? $this->tcp_timeout : 'indefinite'"\n";
  401.         $state .= ';;  retrans  = ' $this->retrans . '  ';
  402.         $state .= 'retry    = ' $this->retry . "\n";
  403.         $state .= ';;  usevc    = ' $this->usevc . '  ';
  404.         $state .= 'stayopen = ' $this->stayopen . '    ';
  405.         $state .= 'igntc = ' $this->igntc . "\n";
  406.         $state .= ';;  defnames = ' $this->defnames . '  ';
  407.         $state .= 'dnsrch   = ' $this->dnsrch . "\n";
  408.         $state .= ';;  recurse  = ' $this->recurse . '  ';
  409.         $state .= 'debug    = ' $this->debug . "\n";
  410.         return $state;
  411.     }
  412.  
  413.     /* }}} */
  414.     /* Net_DNS_Resolver::nextid() {{{ */
  415.     /**
  416.      * Returns the next request Id to be used for the DNS packet header
  417.      */
  418.     function nextid()
  419.     {
  420.         if ($GLOBALS['_Net_DNS_packet_id']++ > 65535{
  421.             $GLOBALS['_Net_DNS_packet_id']= 1;
  422.         }
  423.         return $GLOBALS['_Net_DNS_packet_id'];
  424.     }
  425.     /* }}} */
  426.     /* Net_DNS_Resolver::nameservers() {{{ */
  427.     /**
  428.      * Gets or sets the nameservers to be queried.
  429.      *
  430.      * Returns the current nameservers if an array of new nameservers is not
  431.      * given as the argument OR sets the nameservers to the given nameservers.
  432.      *
  433.      * Nameservers not specified by ip address must be able to be resolved by
  434.      * the default settings of a new Net_DNS_Resolver.
  435.      *
  436.      * @access public
  437.      */
  438.     function nameservers($nsa = array())
  439.     {
  440.         $defres = new Net_DNS_Resolver();
  441.  
  442.         if (is_array($nsa)) {
  443.             $a = array();
  444.             foreach ($nsa as $ns{
  445.                 if (preg_match('/^(\d+(:?\.\d+){0,3})$/'$ns)) {
  446.                     $a[($ns == 0'0.0.0.0' $ns;
  447.                 else {
  448.                     $names = array();
  449.                     if (!preg_match('/\./'$ns)) {
  450.                         if (!empty($defres->searchlist)) {
  451.                             foreach ($defres->searchlist as $suffix{
  452.                                 $names[$ns .'.' $suffix;
  453.                             }
  454.                         elseif (!empty($defres->domain)) {
  455.                             $names[$ns .'.'$defres->domain;
  456.                         }
  457.                     else {
  458.                         $names[$ns;
  459.                     }
  460.                     $packet $defres->search($ns);
  461.                     if (is_object($packet)) {
  462.                         $addresses $this->cname_addr($names$packet);
  463.                         foreach ($addresses as $b{
  464.                             $a[$b;
  465.                         }
  466.                         $a array_unique($a);
  467.                     }
  468.                 }
  469.             }
  470.             if (count($a)) {
  471.                 $this->nameservers = $a;
  472.             }
  473.         }
  474.         return $this->nameservers;
  475.     }
  476.  
  477.     /* }}} */
  478.     /* not tested -- Net_DNS_Resolver::cname_addr() {{{ */
  479.     function cname_addr($names$packet)
  480.     {
  481.         $addr = array();
  482.         //my $oct2 = '(?:2[0-4]\d|25[0-5]|[0-1]?\d\d|\d)';
  483.         foreach ($packet->answer as $rr{
  484.             if (in_array($rr->name$names)) {
  485.                 if ($rr->type == 'CNAME'{
  486.                     $names[$rr->cname;
  487.                 elseif ($rr->type == 'A'{
  488.                     // Run a basic taint check.
  489.                     //next RR unless $rr->address =~ m/^($oct2\.$oct2\.$oct2\.$oct2)$/o;
  490.  
  491.                     $addr[$rr->address;
  492.                 }
  493.             }
  494.         }
  495.         return $addr;
  496.     }
  497.  
  498.     /* }}} */
  499.     /* Net_DNS_Resolver::search() {{{ */
  500.     /**
  501.      * Searches nameservers for an answer
  502.      *
  503.      * Goes through the search list and attempts to resolve name based on
  504.      * the information in the search list.
  505.      *
  506.      * @param string $name The name (LHS) of a resource record to query.
  507.      * @param string $type The type of record to query.
  508.      * @param string $class The class of record to query.
  509.      * @return mixed    an object of type Net_DNS_Packet on success,
  510.      *                   or false on failure.
  511.      * @see Net_DNS::typesbyname(), Net_DNS::classesbyname()
  512.      * @access public
  513.      */
  514.     function search($name$type 'A'$class 'IN')
  515.     {
  516.         /*
  517.          * If the name looks like an IP address then do an appropriate
  518.          * PTR query.
  519.          */
  520.         if (preg_match('/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/'$name$regs)) {
  521.             $name $regs[4].'.'.$regs[3].'.'.$regs[2].'.'.$regs[1].'.in-addr.arpa.';
  522.             $type 'PTR';
  523.         }
  524.  
  525.         /*
  526.          * If the name contains at least one dot then try it as is first.
  527.          */
  528.         if (strstr($name'.')) {
  529.             if ($this->debug{
  530.                 echo ";; search($name$type$class)\n";
  531.             }
  532.             $ans $this->query($name$type$class);
  533.             if (is_object($ans&& ($ans->header->ancount > 0)) {
  534.                 return $ans;
  535.             }
  536.         }
  537.  
  538.         /*
  539.          * If the name does not end in a dot then apply the search list.
  540.          */
  541.         $domain '';
  542.         if ((preg_match('/\.$/'$name)) && $this->dnsrch{
  543.             foreach ($this->searchlist as $domain{
  544.                 $newname = "$name.$domain";
  545.                 if ($this->debug{
  546.                     echo ";; search($newname$type$class)\n";
  547.                 }
  548.                 $ans $this->query($newname$type$class);
  549.                 if (is_object($ans&& ($ans->header->ancount > 0)) {
  550.                     return $ans;
  551.                 }
  552.             }
  553.         }
  554.  
  555.         /*
  556.          * Finally, if the name has no dots then try it as is.
  557.          */
  558.         if (strpos($name'.'=== false{
  559.             if ($this->debug{
  560.                 echo ";; search($name$type$class)\n";
  561.             }
  562.             $ans $this->query($name.'.'$type$class);
  563.             if (is_object($ans&& ($ans->header->ancount > 0)) {
  564.                 return $ans;
  565.             }
  566.         }
  567.  
  568.         /*
  569.          * No answer was found.
  570.          */
  571.         return false;
  572.     }
  573.  
  574.     /* }}} */
  575.     /* Net_DNS_Resolver::rawQuery() {{{ */
  576.     /**
  577.      * Queries nameservers for an answer
  578.      *
  579.      * Queries the nameservers listed in the resolver configuration for an
  580.      * answer to a question packet.
  581.      *
  582.      * @param string $name The name (LHS) of a resource record to query.
  583.      * @param string $type The type of record to query.
  584.      * @param string $class The class of record to query.
  585.      * @return mixed an object of type Net_DNS_Packet, regardless of whether the packet
  586.      *                has an answer or not
  587.      * @see Net_DNS::typesbyname(), Net_DNS::classesbyname()
  588.      * @access public
  589.      */
  590.     function rawQuery($name$type 'A'$class 'IN')
  591.     {
  592.         /*
  593.          * If the name does not contain any dots then append the default domain.
  594.          */
  595.         if ((strchr($name'.'< 0&& $this->defnames{
  596.             $name .= '.' $this->domain;
  597.         }
  598.  
  599.         /*
  600.          * If the name looks like an IP address then do an appropriate
  601.          * PTR query.
  602.          */
  603.         if (preg_match('/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/'$name$regs)) {
  604.             $name $regs[4].'.'.$regs[3].'.'.$regs[2].'.'.$regs[1].'.in-addr.arpa.';
  605.             $type 'PTR';
  606.         }
  607.  
  608.         if ($this->debug{
  609.             echo ";; query($name$type$class)\n";
  610.         }
  611.         $packet = new Net_DNS_Packet($this->debug);
  612.         $packet->buildQuestion($name$type$class);
  613.         $packet->header->rd = $this->recurse;
  614.         $ans $this->send($packet);
  615.         return $ans;
  616.     }
  617.  
  618.     /* }}} */
  619.     /* Net_DNS_Resolver::query() {{{ */
  620.     /**
  621.      * Queries nameservers for an answer
  622.      *
  623.      * Queries the nameservers listed in the resolver configuration for an
  624.      * answer to a question packet.
  625.      *
  626.      * @param string $name The name (LHS) of a resource record to query.
  627.      * @param string $type The type of record to query.
  628.      * @param string $class The class of record to query.
  629.      * @return mixed    an object of type Net_DNS_Packet on success,
  630.      *                   or false on failure.
  631.      * @see Net_DNS::typesbyname(), Net_DNS::classesbyname()
  632.      * @access public
  633.      */
  634.     function query($name$type 'A'$class 'IN')
  635.     {
  636.         $ans $this->rawQuery($name$type$class);
  637.         if (is_object($ans&& $ans->header->ancount > 0{
  638.             return $ans;
  639.         }
  640.         return false;
  641.     }
  642.  
  643.     /* }}} */
  644.     /* Net_DNS_Resolver::send($packetORname, $qtype = '', $qclass = '') {{{ */
  645.     /**
  646.      * Sends a packet to a nameserver
  647.      *
  648.      * Determines the appropriate communication method (UDP or TCP) and
  649.      * sends a DNS packet to a nameserver.  Use of the this function
  650.      * directly  is discouraged. $packetORname should always be a properly
  651.      * formatted binary DNS packet.  However, it is possible to send a
  652.      * query here and bypass Net_DNS_Resolver::query()
  653.      *
  654.      * @param string $packetORname      A binary DNS packet stream or a
  655.      *                                   hostname to query
  656.      * @param string $qtype     This should not be used
  657.      * @param string $qclass    This should not be used
  658.      * @return object Net_DNS_Packet    An answer packet object
  659.      */
  660.     function send($packetORname$qtype ''$qclass '')
  661.     {
  662.         $packet $this->make_query_packet($packetORname$qtype$qclass);
  663.         $packet_data $packet->data();
  664.  
  665.         if ($this->usevc != 0 || strlen($packet_data > 512)) {
  666.             $ans $this->send_tcp($packet$packet_data);
  667.         else {
  668.             $ans $this->send_udp($packet$packet_data);
  669.  
  670.             if ($ans && $ans->header->tc && $this->igntc != 0{
  671.                 if ($this->debug{
  672.                     echo ";;\n;; packet truncated: retrying using TCP\n";
  673.                 }
  674.                 $ans $this->send_tcp($packet$packet_data);
  675.             }
  676.         }
  677.         return $ans;
  678.     }
  679.  
  680.     /* }}} */
  681.     /* Net_DNS_Resolver::printhex($packet_data) {{{ */
  682.     /**
  683.      * Prints packet data as hex code.
  684.      */
  685.     function printhex($data)
  686.     {
  687.         $data '  ' $data;
  688.         $start = 0;
  689.         while ($start strlen($data)) {
  690.             printf(';; %03d: '$start);
  691.             for ($ctr $start$ctr $start+16; $ctr++{
  692.                 if ($ctr strlen($data)) {
  693.                     printf('%02x 'ord($data[$ctr]));
  694.                 else {
  695.                     echo '   ';
  696.                 }
  697.             }
  698.             echo '   ';
  699.             for ($ctr $start$ctr $start+16; $ctr++{
  700.                 if (ord($data[$ctr]< 32 || ord($data[$ctr]> 127{
  701.                     echo '.';
  702.                 else {
  703.                     echo $data[$ctr];
  704.                 }
  705.             }
  706.             echo "\n";
  707.             $start += 16;
  708.         }
  709.     }
  710.     /* }}} */
  711.     /* Net_DNS_Resolver::send_tcp($packet, $packet_data) {{{ */
  712.     /**
  713.      * Sends a packet via TCP to the list of name servers.
  714.      *
  715.      * @param string $packet    A packet object to send to the NS list
  716.      * @param string $packet_data   The data in the packet as returned by
  717.      *                               the Net_DNS_Packet::data() method
  718.      * @return object Net_DNS_Packet Returns an answer packet object
  719.      * @see Net_DNS_Resolver::send_udp(), Net_DNS_Resolver::send()
  720.      */
  721.     function send_tcp($packet$packet_data)
  722.     {
  723.         if (count($this->nameservers)) {
  724.             $this->errorstring = 'no nameservers';
  725.             if ($this->debug{
  726.                 echo ";; ERROR: send_tcp: no nameservers\n";
  727.             }
  728.             return null;
  729.         }
  730.         $timeout $this->tcp_timeout;
  731.  
  732.         foreach ($this->nameservers as $ns{
  733.             $dstport $this->port;
  734.             if ($this->debug{
  735.                 echo ";; send_tcp($ns:$dstport)\n";
  736.             }
  737.             $sock_key = "$ns:$dstport";
  738.             if (isset($this->sockets[$sock_key]&& is_resource($this->sockets[$sock_key])) {
  739.                 $sock &$this->sockets[$sock_key];
  740.             else {
  741.                 if (($sock @fsockopen($ns$dstport$errno,
  742.                                 $errstr$timeout))) {
  743.                     $this->errorstring = 'connection failed';
  744.                     if ($this->debug{
  745.                         echo ";; ERROR: send_tcp: connection failed: $errstr\n";
  746.                     }
  747.                     continue;
  748.                 }
  749.                 $this->sockets[$sock_key$sock;
  750.                 unset($sock);
  751.                 $sock &$this->sockets[$sock_key];
  752.             }
  753.             $lenmsg pack('n'strlen($packet_data));
  754.             if ($this->debug{
  755.                 echo ';; sending ' strlen($packet_data" bytes\n";
  756.             }
  757.  
  758.             if (($sent fwrite($sock$lenmsg)) == -1{
  759.                 $this->errorstring = 'length send failed';
  760.                 if ($this->debug{
  761.                     echo ";; ERROR: send_tcp: length send failed\n";
  762.                 }
  763.                 continue;
  764.             }
  765.  
  766.             if (($sent fwrite($sock$packet_data)) == -1{
  767.                 $this->errorstring = 'packet send failed';
  768.                 if ($this->debug{
  769.                     echo ";; ERROR: send_tcp: packet data send failed\n";
  770.                 }
  771.             }
  772.  
  773.             socket_set_timeout($sock$timeout);
  774.             $buf fread($sock2);
  775.             $e socket_get_status($sock);
  776.             /* If $buf is empty, we want to supress errors
  777.                long enough to reach the continue; down the line */
  778.             $len @unpack('nint'$buf);
  779.             $len @$len['int'];
  780.             if (!$len{
  781.                 continue;
  782.             }
  783.             $buf fread($sock$len);
  784.             $actual strlen($buf);
  785.             $this->answerfrom = $ns;
  786.             $this->answersize = $len;
  787.             if ($this->debug{
  788.                 echo ";; received $actual bytes\n";
  789.             }
  790.             if ($actual != $len{
  791.                 $this->errorstring = "expected $len bytes, received $buf";
  792.                 if ($this->debug{
  793.                     echo ';; send_tcp: ' $this->errorstring;
  794.                 }
  795.                 continue;
  796.             }
  797.  
  798.             $ans = new Net_DNS_Packet($this->debug);
  799.             if (is_null($ans->parse($buf))) {
  800.                 continue;
  801.             }
  802.             $this->errorstring = $ans->header->rcode;
  803.             $ans->answerfrom = $this->answerfrom;
  804.             $ans->answersize = $this->answersize;
  805.             return $ans;
  806.         }
  807.     }
  808.  
  809.     /* }}} */
  810.     /* Net_DNS_Resolver::send_udp_no_sock_lib($packet, $packet_data) {{{ */
  811.     /**
  812.      * Sends a packet via UDP to the list of name servers.
  813.      *
  814.      * This function sends a packet to a nameserver.  It is called by
  815.      * send_udp if the sockets PHP extension is not compiled into PHP.
  816.      *
  817.      * @param string $packet    A packet object to send to the NS list
  818.      * @param string $packet_data   The data in the packet as returned by
  819.      *                               the Net_DNS_Packet::data() method
  820.      * @return object Net_DNS_Packet Returns an answer packet object
  821.      * @see Net_DNS_Resolver::send_tcp(), Net_DNS_Resolver::send(),
  822.      *       Net_DNS_Resolver::send_udp(), Net_DNS_Resolver::send_udp_with_sock_lib()
  823.      */
  824.     function send_udp_no_sock_lib($packet$packet_data)
  825.     {
  826.         $retrans $this->retrans;
  827.         $timeout $retrans;
  828.  
  829.         /*
  830.          * PHP doesn't have excellent socket support as of this writing.
  831.          * This needs to be rewritten when PHP POSIX socket support is
  832.          * complete.
  833.          * Obviously, this code is MUCH different than the PERL implementation
  834.          */
  835.  
  836.         $w error_reporting(0);
  837.         $ctr = 0;
  838.         // Create a socket handle for each nameserver
  839.         foreach ($this->nameservers as $nameserver{
  840.             if ($sock[$ctr++fsockopen("udp://$nameserver"$this->port)) {
  841.                 $peerhost[$ctr-1$nameserver;
  842.                 $peerport[$ctr-1$this->port;
  843.                 socket_set_blocking($sockfalse);
  844.             else {
  845.                 $ctr--;
  846.             }
  847.         }
  848.         error_reporting($w);
  849.  
  850.         if ($ctr == 0{
  851.             $this->errorstring = 'no nameservers';
  852.             return null;
  853.         }
  854.  
  855.         for ($i = 0; $i $this->retry$i++$retrans *= 2,
  856.                 $timeout = (int) ($retrans (count($ns)+1))) {
  857.             if ($timeout < 1{
  858.                 $timeout = 1;
  859.             }
  860.  
  861.             foreach ($sock as $k => $s{
  862.                 if ($this->debug{
  863.                     echo ';; send_udp(' $peerhost[$k':' $peerport[$k'): sending ' strlen($packet_data" bytes\n";
  864.                 }
  865.  
  866.                 if (fwrite($s$packet_data)) {
  867.                     if ($this->debug{
  868.                         echo ";; send error\n";
  869.                     }
  870.                 }
  871.  
  872.                 /*
  873.                  *  Here's where it get's really nasty.  We don't have a select()
  874.                  *  function here, so we have to poll for a response... UGH!
  875.                  */
  876.  
  877.                 $timetoTO  time(+ (double)microtime($timeout;
  878.  
  879.                 /*
  880.                  * let's sleep for a few hundred microseconds to let the
  881.                  * data come in from the network...
  882.                  */
  883.                 usleep(500);
  884.                 $buf '';
  885.                 while (strlen($buf&& $timetoTO (time(+
  886.                             (double)microtime())) {
  887.                     socket_set_blocking($sfalse);
  888.                     if ($buf fread($s512)) {
  889.                         $this->answerfrom = $peerhost[$k];
  890.                         $this->answersize = strlen($buf);
  891.                         if ($this->debug{
  892.                             echo ';; answer from ' $peerhost[$k':' .
  893.                                 $peerport[$k.  ': ' strlen($buf" bytes\n";
  894.                         }
  895.                         $ans = new Net_DNS_Packet($this->debug);
  896.                         if ($ans->parse($buf)) {
  897.                             if ($ans->header->qr != '1'{
  898.                                 continue;
  899.                             }
  900.                             if ($ans->header->id != $packet->header->id{
  901.                                 continue;
  902.                             }
  903.                             $this->errorstring = $ans->header->rcode;
  904.                             $ans->answerfrom = $this->answerfrom;
  905.                             $ans->answersize = $this->answersize;
  906.                             return $ans;
  907.                         }
  908.                     }
  909.                     // Sleep another 1/100th of a second... this sucks...
  910.                     usleep(1000);
  911.                 }
  912.  
  913.                 $this->errorstring = 'query timed out';
  914.                 return null;
  915.             }
  916.         }
  917.     }
  918.  
  919.     /* }}} */
  920.     /* Net_DNS_Resolver::send_udp_with_sock_lib($packet, $packet_data) {{{ */
  921.     /**
  922.      * Sends a packet via UDP to the list of name servers.
  923.      *
  924.      * This function sends a packet to a nameserver.  It is called by
  925.      * send_udp if the sockets PHP extension is compiled into PHP.
  926.      *
  927.      * @param string $packet    A packet object to send to the NS list
  928.      * @param string $packet_data   The data in the packet as returned by
  929.      *                               the Net_DNS_Packet::data() method
  930.      * @return object Net_DNS_Packet Returns an answer packet object
  931.      * @see Net_DNS_Resolver::send_tcp(), Net_DNS_Resolver::send(),
  932.      *       Net_DNS_Resolver::send_udp(), Net_DNS_Resolver::send_udp_no_sock_lib()
  933.      */
  934.     function send_udp_with_sock_lib($packet$packet_data)
  935.     {
  936.         $retrans $this->retrans;
  937.         $timeout $retrans;
  938.  
  939.         //$w = error_reporting(0);
  940.         $ctr = 0;
  941.         // Create a socket handle for each nameserver
  942.         foreach ($this->nameservers as $nameserver{
  943.             if ((($sock[$ctr++socket_create(AF_INETSOCK_DGRAMSOL_UDP))) &&
  944.                   socket_connect($sock[$ctr-1]$nameserver$this->port))
  945.             {
  946.                 $peerhost[$ctr-1$nameserver;
  947.                 $peerport[$ctr-1$this->port;
  948.                 socket_set_nonblock($sock[$ctr-1]);
  949.             else {
  950.                 $ctr--;
  951.             }
  952.         }
  953.         //error_reporting($w);
  954.  
  955.         if ($ctr == 0{
  956.             $this->errorstring = 'no nameservers';
  957.             return null;
  958.         }
  959.         // Try each nameserver up to $this->retry times
  960.         for ($i = 0; $i $this->retry$i++{
  961.             if ($i != 0{
  962.                 // Set the timeout for each retry based on the number of
  963.                 // nameservers there is a connected socket for.
  964.                 $retrans *= 2;
  965.                 $timeout = (int) ($retrans $ctr);
  966.             }
  967.             // Make sure the timeout is at least 1 second
  968.             if ($timeout < 1{
  969.                 $timeout = 1;
  970.             }
  971.  
  972.             // Try each nameserver
  973.             foreach ($sock as $k => $s{
  974.                 if ($this->debug{
  975.                     echo "\n;; send_udp(" $peerhost[$k':' $peerport[$k'): sending ' strlen($packet_data" bytes\n";
  976.                 }
  977.  
  978.                 if (socket_write($s$packet_data)) {
  979.                     if ($this->debug{
  980.                         echo ";; send error\n";
  981.                     }
  982.                 }
  983.  
  984.                 $set = array($s);
  985.                 if ($this->debug{
  986.                     echo ";; timeout set to $timeout seconds\n";
  987.                 }
  988.                 $changed socket_select($set$w = null$e = null$timeout);
  989.                 if ($changed{
  990.                     // Test to see if the connection was refused.  Linux servers will send
  991.                     // an ICMP message which will cause the client's next system call to
  992.                     // return ECONNREFUSED if the server is not listening on the ip:port queried
  993.                     if (socket_get_option($sSOL_SOCKETSO_ERROR== SOCKET_ECONNREFUSED{
  994.                         // Unix socket connection was refused
  995.                         if ($this->debug{
  996.                             echo ';; connection to ' $peerhost[$k':' $peerport[$k" was refused\n";
  997.                         }
  998.                         // Try the next server.
  999.                         continue;
  1000.                     }
  1001.  
  1002.                     // Read the response
  1003.                     $buf @socket_read($s512);
  1004.                     if ($buf === false{
  1005.                         // No data could be read from socket
  1006.                         if ($this->debug{
  1007.                             echo ';; no data could be read from ' $peerhost[$k':' $peerport[$k"\n";
  1008.                             echo ';; socket_error: ' socket_strerror(socket_last_error()) "\n";
  1009.                         }
  1010.                         // Reset the non-specific socket error status
  1011.                         socket_clear_error();
  1012.                         // Try the next server.
  1013.                         continue;
  1014.                     }
  1015.  
  1016.                     $this->answerfrom = $peerhost[$k];
  1017.                     $this->answersize = strlen($buf);
  1018.                     if ($this->debug{
  1019.                         echo ';; answer from ' $peerhost[$k':' .
  1020.                             $peerport[$k.  ': ' strlen($buf" bytes\n";
  1021.                     }
  1022.                     $ans = new Net_DNS_Packet($this->debug);
  1023.                     if ($ans->parse($buf)) {
  1024.                         if ($ans->header->qr != '1'{
  1025.                             // Ignore packet if it is not a response
  1026.                             continue;
  1027.                         elseif ($ans->header->id != $packet->header->id{
  1028.                             // Ignore packet if the response id does not match the query id
  1029.                             continue;
  1030.                         else {
  1031.                             // Return the DNS response packet
  1032.                             $this->errorstring = $ans->header->rcode;
  1033.                             $ans->answerfrom = $this->answerfrom;
  1034.                             $ans->answersize = $this->answersize;
  1035.                             return $ans;
  1036.                         }
  1037.                     }
  1038.                 elseif ($this->debug{
  1039.                     echo ";; query to "$peerhost[$k':' $peerport[$k" timed out\n";
  1040.                 }
  1041.             }
  1042.         }
  1043.         $this->errorstring = 'query timed out';
  1044.         return null;
  1045.     }
  1046.  
  1047.     /* }}} */
  1048.     /* Net_DNS_Resolver::send_udp($packet, $packet_data) {{{ */
  1049.     /**
  1050.      * Sends a packet via UDP to the list of name servers.
  1051.      *
  1052.      * This function sends a packet to a nameserver.  send_udp calls
  1053.      * either Net_DNS_Resolver::send_udp_no_sock_lib() or
  1054.      * Net_DNS_Resolver::send_udp_with_sock_lib() depending on whether or
  1055.      * not the sockets extension is compiled into PHP.  Note that using the
  1056.      * sockets extension is MUCH more efficient.
  1057.      *
  1058.      * @param object Net_DNS_Packet $packet A packet object to send to the NS list
  1059.      * @param string $packet_data   The data in the packet as returned by
  1060.      *                               the Net_DNS_Packet::data() method
  1061.      * @return object Net_DNS_Packet Returns an answer packet object
  1062.      * @see Net_DNS_Resolver::send_tcp(), Net_DNS_Resolver::send(),
  1063.      *       Net_DNS_Resolver::send_udp(), Net_DNS_Resolver::send_udp_no_sock_lib()
  1064.      */
  1065.     function send_udp($packet$packet_data)
  1066.     {
  1067.         if (extension_loaded('sockets'&& $this->useEnhancedSockets{
  1068.             if ($this->debug{
  1069.                 echo "\n;; using extended PHP sockets\n";
  1070.             }
  1071.             return $this->send_udp_with_sock_lib($packet$packet_data);
  1072.         else {
  1073.             if ($this->debug{
  1074.                 echo "\n;; using simple sockets\n";
  1075.             }
  1076.             return $this->send_udp_no_sock_lib($packet$packet_data);
  1077.         }
  1078.     }
  1079.  
  1080.     /* }}} */
  1081.     /* Net_DNS_Resolver::make_query_packet($packetORname, $type = '', $class = '') {{{ */
  1082.     /**
  1083.      * Unknown
  1084.      */
  1085.     function make_query_packet($packetORname$type ''$class '')
  1086.     {
  1087.         if (is_object($packetORname&& strcasecmp(get_class($packetORname)'net_dns_packet'== 0{
  1088.             $packet $packetORname;
  1089.         else {
  1090.             $name $packetORname;
  1091.             if ($type == ''{
  1092.                 $type 'A';
  1093.             }
  1094.             if ($class == ''{
  1095.                 $class 'IN';
  1096.             }
  1097.  
  1098.             /*
  1099.              * If the name looks like an IP address then do an appropriate
  1100.              * PTR query.
  1101.              */
  1102.             if (preg_match('/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/'$name$regs)) {
  1103.                 $name $regs[4].'.'.$regs[3].'.'.$regs[2].'.'.$regs[1].'.in-addr.arpa.';
  1104.                 $type 'PTR';
  1105.             }
  1106.  
  1107.             if ($this->debug{
  1108.                 echo ";; query($name$type$class)\n";
  1109.             }
  1110.             $packet = new Net_DNS_Packet($this->debug);
  1111.             $packet->buildQuestion($name$type$class);
  1112.         }
  1113.  
  1114.         $packet->header->rd = $this->recurse;
  1115.         return $packet;
  1116.     }
  1117.  
  1118.     /* }}} */
  1119.     /* Net_DNS_Resolver::axfr_old($dname, $class = 'IN') {{{ */
  1120.     /**
  1121.      * Performs an AXFR query (zone transfer) (OLD BUGGY STYLE)
  1122.      *
  1123.      * This is deprecated and should not be used!
  1124.      *
  1125.      * @param string $dname The domain (zone) to transfer
  1126.      * @param string $class The class in which to look for the zone.
  1127.      * @return object Net_DNS_Packet 
  1128.      * @access public
  1129.      */
  1130.     function axfr_old($dname$class 'IN')
  1131.     {
  1132.         return $this->axfr($dname$classtrue);
  1133.     }
  1134.     /* }}} */
  1135.     /* Net_DNS_Resolver::axfr($dname, $class = 'IN', $old = false) {{{ */
  1136.     /**
  1137.      * Performs an AXFR query (zone transfer)
  1138.      *
  1139.      * Requests a zone transfer from the nameservers. Note that zone
  1140.      * transfers will ALWAYS use TCP regardless of the setting of the
  1141.      * Net_DNS_Resolver::$usevc flag.  If $old is set to true, Net_DNS requires
  1142.      * a nameserver that supports the many-answers style transfer format.  Large
  1143.      * zone transfers will not function properly.  Setting $old to true is _NOT_
  1144.      * recommended and should only be used for backwards compatibility.
  1145.      *
  1146.      * @param string $dname The domain (zone) to transfer
  1147.      * @param string $class The class in which to look for the zone.
  1148.      * @param boolean $old Requires 'old' style many-answer format to function.
  1149.                            Used for backwards compatibility only.
  1150.      * @return object Net_DNS_Packet 
  1151.      * @access public
  1152.      */
  1153.     function axfr($dname$class 'IN'$old = false)
  1154.     {
  1155.         if ($old{
  1156.             if ($this->debug{
  1157.                 echo ";; axfr_start($dname$class)\n";
  1158.             }
  1159.             if (count($this->nameservers)) {
  1160.                 $this->errorstring = 'no nameservers';
  1161.                 if ($this->debug{
  1162.                     echo ";; ERROR: no nameservers\n";
  1163.                 }
  1164.                 return null;
  1165.             }
  1166.             $packet $this->make_query_packet($dname'AXFR'$class);
  1167.             $packet_data $packet->data();
  1168.             $ans $this->send_tcp($packet$packet_data);
  1169.             return $ans;
  1170.         else {
  1171.             if ($this->axfr_start($dname$class=== null{
  1172.                 return null;
  1173.             }
  1174.             $ret = array();
  1175.             while (($ans $this->axfr_next()) !== null{
  1176.                 if ($ans === null{
  1177.                     return null;
  1178.                 }
  1179.                 array_push($ret$ans);
  1180.             }
  1181.             return $ret;
  1182.         }
  1183.     }
  1184.  
  1185.     /* }}} */
  1186.     /* Net_DNS_Resolver::axfr_start($dname, $class = 'IN') {{{ */
  1187.     /**
  1188.      * Sends a packet via TCP to the list of name servers.
  1189.      *
  1190.      * @param string $packet    A packet object to send to the NS list
  1191.      * @param string $packet_data   The data in the packet as returned by
  1192.      *                               the Net_DNS_Packet::data() method
  1193.      * @return object Net_DNS_Packet Returns an answer packet object
  1194.      * @see Net_DNS_Resolver::send_tcp()
  1195.      */
  1196.     function axfr_start($dname$class 'IN')
  1197.     {
  1198.         if ($this->debug{
  1199.             echo ";; axfr_start($dname$class)\n";
  1200.         }
  1201.  
  1202.         if (count($this->nameservers)) {
  1203.             $this->errorstring = "no nameservers";
  1204.             if ($this->debug{
  1205.                 echo ";; ERROR: axfr_start: no nameservers\n";
  1206.             }
  1207.             return null;
  1208.         }
  1209.         $packet $this->make_query_packet($dname"AXFR"$class);
  1210.         $packet_data $packet->data();
  1211.  
  1212.         $timeout $this->tcp_timeout;
  1213.  
  1214.         foreach ($this->nameservers as $ns{
  1215.             $dstport $this->port;
  1216.             if ($this->debug{
  1217.                 echo ";; axfr_start($ns:$dstport)\n";
  1218.             }
  1219.             $sock_key = "$ns:$dstport";
  1220.             if (is_resource($this->sockets[$sock_key])) {
  1221.                 $sock &$this->sockets[$sock_key];
  1222.             else {
  1223.                 if (($sock fsockopen($ns$dstport$errno,
  1224.                                 $errstr$timeout))) {
  1225.                     $this->errorstring = "connection failed";
  1226.                     if ($this->debug{
  1227.                         echo ";; ERROR: axfr_start: connection failed: $errstr\n";
  1228.                     }
  1229.                     continue;
  1230.                 }
  1231.                 $this->sockets[$sock_key$sock;
  1232.                 unset($sock);
  1233.                 $sock &$this->sockets[$sock_key];
  1234.             }
  1235.             $lenmsg pack("n"strlen($packet_data));
  1236.             if ($this->debug{
  1237.                 echo ";; sending " strlen($packet_data" bytes\n";
  1238.             }
  1239.  
  1240.             if (($sent fwrite($sock$lenmsg)) == -1{
  1241.                 $this->errorstring = "length send failed";
  1242.                 if ($this->debug{
  1243.                     echo ";; ERROR: axfr_start: length send failed\n";
  1244.                 }
  1245.                 continue;
  1246.             }
  1247.  
  1248.             if (($sent fwrite($sock$packet_data)) == -1{
  1249.                 $this->errorstring = "packet send failed";
  1250.                 if ($this->debug{
  1251.                     echo ";; ERROR: axfr_start: packet data send failed\n";
  1252.                 }
  1253.             }
  1254.  
  1255.             socket_set_timeout($sock$timeout);
  1256.  
  1257.             $this->_axfr_sock = $sock;
  1258.             $this->_axfr_rr = array();
  1259.             $this->_axfr_soa_count = 0;
  1260.             return $sock;
  1261.         }
  1262.     }
  1263.  
  1264.     /* }}} */
  1265.     /* Net_DNS_Resolver::axfr_next() {{{ */
  1266.     /**
  1267.      * Requests the next RR from a existing transfer started with axfr_start
  1268.      *
  1269.      * @return object Net_DNS_RR Returns a Net_DNS_RR object of the next RR
  1270.      *                            from a zone transfer.
  1271.      * @see Net_DNS_Resolver::send_tcp()
  1272.      */
  1273.     function axfr_next()
  1274.     {
  1275.         if (count($this->_axfr_rr)) {
  1276.             if (isset($this->_axfr_sock|| is_resource($this->_axfr_sock)) {
  1277.                 $this->errorstring = 'no zone transfer in progress';
  1278.                 return null;
  1279.             }
  1280.             $timeout $this->tcp_timeout;
  1281.             $buf $this->read_tcp($this->_axfr_sock2$this->debug);
  1282.             if (strlen($buf)) {
  1283.                 $this->errorstring = 'truncated zone transfer';
  1284.                 return null;
  1285.             }
  1286.             $len unpack('n1len'$buf);
  1287.             $len $len['len'];
  1288.             if ($len{
  1289.                 $this->errorstring = 'truncated zone transfer';
  1290.                 return null;
  1291.             }
  1292.             $buf $this->read_tcp($this->_axfr_sock$len$this->debug);
  1293.             if ($this->debug{
  1294.                 echo ';; received ' strlen($buf"bytes\n";
  1295.             }
  1296.             if (strlen($buf!= $len{
  1297.                 $this->errorstring = 'expected ' $len ' bytes, received ' strlen($buf);
  1298.                 if ($this->debug{
  1299.                     echo ';; ' $err "\n";
  1300.                 }
  1301.                 return null;
  1302.             }
  1303.             $ans = new Net_DNS_Packet($this->debug);
  1304.             if ($ans->parse($buf)) {
  1305.                 if ($this->errorstring{
  1306.                     $this->errorstring = 'unknown error during packet parsing';
  1307.                 }
  1308.                 return null;
  1309.             }
  1310.             if ($ans->header->ancount < 1{
  1311.                 $this->errorstring = 'truncated zone transfer';
  1312.                 return null;
  1313.             }
  1314.             if ($ans->header->rcode != 'NOERROR'{
  1315.                 $this->errorstring = 'errorcode ' $ans->header->rcode . ' returned';
  1316.                 return null;
  1317.             }
  1318.             foreach ($ans->answer as $rr{
  1319.                 if ($rr->type == 'SOA'{
  1320.                     if (++$this->_axfr_soa_count < 2{
  1321.                         array_push($this->_axfr_rr$rr);
  1322.                     }
  1323.                 else {
  1324.                     array_push($this->_axfr_rr$rr);
  1325.                 }
  1326.             }
  1327.             if ($this->_axfr_soa_count >= 2{
  1328.                 unset($this->_axfr_sock);
  1329.             }
  1330.         }
  1331.         $rr array_shift($this->_axfr_rr);
  1332.         return $rr;
  1333.     }
  1334.  
  1335.     /* }}} */
  1336.     /* Net_DNS_Resolver::read_tcp() {{{ */
  1337.     /**
  1338.      * Unknown - not ported yet
  1339.      */
  1340.     function read_tcp($sock$nbytes$debug = 0)
  1341.     {
  1342.         $buf '';
  1343.         while (strlen($buf$nbytes{
  1344.             $nread $nbytes strlen($buf);
  1345.             $read_buf '';
  1346.             if ($debug{
  1347.                 echo ";; read_tcp: expecting $nread bytes\n";
  1348.             }
  1349.             $read_buf fread($sock$nread);
  1350.             if (strlen($read_buf)) {
  1351.                 if ($debug{
  1352.                     echo ";; ERROR: read_tcp: fread failed\n";
  1353.                 }
  1354.                 break;
  1355.             }
  1356.             if ($debug{
  1357.                 echo ';; read_tcp: received ' strlen($read_buf" bytes\n";
  1358.             }
  1359.             if (!strlen($read_buf)) {
  1360.                 break;
  1361.             }
  1362.  
  1363.             $buf .= $read_buf;
  1364.         }
  1365.         return $buf;
  1366.     }
  1367.     /* }}} */
  1368. }
  1369. /* }}} */
  1370. /* VIM settings {{{
  1371.  * Local variables:
  1372.  * tab-width: 4
  1373.  * c-basic-offset: 4
  1374.  * soft-stop-width: 4
  1375.  * c indent on
  1376.  * expandtab on
  1377.  * End:
  1378.  * vim600: sw=4 ts=4 sts=4 cindent fdm=marker et
  1379.  * vim<600: sw=4 ts=4
  1380.  * }}} */
  1381. ?>

Documentation generated on Mon, 11 Mar 2019 14:35:57 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.