Exemple #1
0
    /**
     * returns the rdata portion of the DNS packet
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
     *                                 compressed names
     *
     * @return mixed                   either returns a binary packed
     *                                 string or null on failure
     * @access protected
     *
     */
    protected function rrGet(Net_DNS2_Packet &$packet)
    {
        if (strlen($this->mboxdname) > 0) {

            return $packet->compress($this->mboxdname, $packet->offset) .
                $packet->compress($this->txtdname, $packet->offset);
        }

        return null;
    }
Exemple #2
0
 /**
  * returns the rdata portion of the DNS packet
  *
  * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
  *                                 compressed names
  *
  * @return mixed                   either returns a binary packed
  *                                 string or null on failure
  * @access protected
  *
  */
 protected function rrGet(Net_DNS2_Packet &$packet)
 {
     if (strlen($this->intermediatehost) > 0) {
         $data = pack('n', $this->preference);
         $packet->offset += 2;
         $data .= $packet->compress($this->intermediatehost, $packet->offset);
         return $data;
     }
     return null;
 }
Exemple #3
0
 /**
  * parses the rdata of the Net_DNS2_Packet object
  *
  * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
  *
  * @return boolean
  * @access protected
  *
  */
 protected function rrSet(Net_DNS2_Packet &$packet)
 {
     if ($this->rdlength > 0) {
         //
         // unpack
         //
         $x = unpack('ntc/Calgorithm/Clabels/Norigttl/Nsigexp/Nsigincep/nkeytag', $this->rdata);
         $this->typecovered = Net_DNS2_Lookups::$rr_types_by_id[$x['tc']];
         $this->algorithm = $x['algorithm'];
         $this->labels = $x['labels'];
         $this->origttl = $x['origttl'];
         //
         // the dates are in GM time
         //
         $this->sigexp = gmdate('YmdHis', $x['sigexp']);
         $this->sigincep = gmdate('YmdHis', $x['sigincep']);
         //
         // get the keytag
         //
         $this->keytag = $x['keytag'];
         //
         // get teh signers name and signature
         //
         $offset = $packet->offset + 18;
         $sigoffset = $offset;
         $this->signname = strtolower(Net_DNS2_Packet::expand($packet, $sigoffset));
         $this->signature = base64_encode(substr($this->rdata, 18 + ($sigoffset - $offset)));
         return true;
     }
     return false;
 }
Exemple #4
0
 /**
  * parses a binary packet, and returns the appropriate Net_DNS2_RR object,
  * based on the RR type of the binary content.
  *
  * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet used for
  *                                 decompressing names
  *
  * @return mixed                   returns a new Net_DNS2_RR_* object for
  *                                 the given RR
  * @throws Net_DNS2_Exception
  * @access public
  *
  */
 public static function parse(Net_DNS2_Packet &$packet)
 {
     $object = array();
     //
     // expand the name
     //
     $object['name'] = $packet->expand($packet, $packet->offset);
     if (is_null($object['name'])) {
         throw new Net_DNS2_Exception('failed to parse resource record: failed to expand name.', Net_DNS2_Lookups::E_PARSE_ERROR);
     }
     if ($packet->rdlength < $packet->offset + 10) {
         throw new Net_DNS2_Exception('failed to parse resource record: packet too small.', Net_DNS2_Lookups::E_PARSE_ERROR);
     }
     //
     // unpack the RR details
     //
     $object['type'] = ord($packet->rdata[$packet->offset++]) << 8 | ord($packet->rdata[$packet->offset++]);
     $object['class'] = ord($packet->rdata[$packet->offset++]) << 8 | ord($packet->rdata[$packet->offset++]);
     $object['ttl'] = ord($packet->rdata[$packet->offset++]) << 24 | ord($packet->rdata[$packet->offset++]) << 16 | ord($packet->rdata[$packet->offset++]) << 8 | ord($packet->rdata[$packet->offset++]);
     $object['rdlength'] = ord($packet->rdata[$packet->offset++]) << 8 | ord($packet->rdata[$packet->offset++]);
     if ($packet->rdlength < $packet->offset + $object['rdlength']) {
         return null;
     }
     //
     // lookup the class to use
     //
     $o = null;
     $class = Net_DNS2_Lookups::$rr_types_id_to_class[$object['type']];
     if (isset($class)) {
         $o = new $class($packet, $object);
         if ($o) {
             $packet->offset += $object['rdlength'];
         }
     } else {
         throw new Net_DNS2_Exception('un-implemented resource record type: ' . $object['type'], Net_DNS2_Lookups::E_RR_INVALID);
     }
     return $o;
 }
Exemple #5
0
 /**
  * returns the rdata portion of the DNS packet
  *
  * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
  *                                 compressed names
  *
  * @return mixed                   either returns a binary packed
  *                                 string or null on failure
  * @access protected
  *
  */
 protected function rrGet(Net_DNS2_Packet &$packet)
 {
     if (strlen($this->mname) > 0) {
         $data = $packet->compress($this->mname, $packet->offset);
         $data .= $packet->compress($this->rname, $packet->offset);
         $data .= pack('N5', $this->serial, $this->refresh, $this->retry, $this->expire, $this->minimum);
         $packet->offset += 20;
         return $data;
     }
     return null;
 }
Exemple #6
0
 /**
  * parses the rdata of the Net_DNS2_Packet object
  *
  * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
  *
  * @return boolean
  * @access protected
  *
  */
 protected function rrSet(Net_DNS2_Packet &$packet)
 {
     if ($this->rdlength > 0) {
         //
         // parse off the precedence, gateway type and algorithm
         //
         $x = unpack('Cprecedence/Cgateway_type/Calgorithm', $this->rdata);
         $this->precedence = $x['precedence'];
         $this->gateway_type = $x['gateway_type'];
         $this->algorithm = $x['algorithm'];
         $offset = 3;
         //
         // extract the gatway based on the type
         //
         switch ($this->gateway_type) {
             case self::GATEWAY_TYPE_NONE:
                 $this->gateway = '';
                 break;
             case self::GATEWAY_TYPE_IPV4:
                 $this->gateway = inet_ntop(substr($this->rdata, $offset, 4));
                 $offset += 4;
                 break;
             case self::GATEWAY_TYPE_IPV6:
                 $ip = unpack('n8', substr($this->rdata, $offset, 16));
                 if (count($ip) == 8) {
                     $this->gateway = vsprintf('%x:%x:%x:%x:%x:%x:%x:%x', $ip);
                     $offset += 16;
                 } else {
                     return false;
                 }
                 break;
             case self::GATEWAY_TYPE_DOMAIN:
                 $doffset = $offset + $packet->offset;
                 $this->gateway = Net_DNS2_Packet::expand($packet, $doffset);
                 $offset = $doffset - $packet->offset;
                 break;
             default:
                 return false;
         }
         //
         // extract the key
         //
         switch ($this->algorithm) {
             case self::ALGORITHM_NONE:
                 $this->key = '';
                 break;
             case self::ALGORITHM_DSA:
             case self::ALGORITHM_RSA:
                 $this->key = base64_encode(substr($this->rdata, $offset));
                 break;
             default:
                 return false;
         }
         return true;
     }
     return false;
 }
Exemple #7
0
    /**
     * returns the rdata portion of the DNS packet
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
     *                                 compressed names
     *
     * @return mixed                   either returns a binary packed
     *                                 string or null on failure
     * @access protected
     *
     */
    protected function rrGet(Net_DNS2_Packet &$packet)
    {
        if ( (isset($this->order)) && (strlen($this->services) > 0) ) {
            
            $data = pack('nn', $this->order, $this->preference);

            $data .= chr(strlen($this->flags)) . $this->flags;
            $data .= chr(strlen($this->services)) . $this->services;
            $data .= chr(strlen($this->regexp)) . $this->regexp;

            $packet->offset += strlen($data);

            $data .= $packet->compress($this->replacement, $packet->offset);

            return $data;
        }

        return null;
    }
Exemple #8
0
    /**
     * returns the rdata portion of the DNS packet
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
     *                                 compressed names
     *
     * @return mixed                   either returns a binary packed
     *                                 string or null on failure
     * @access protected
     *
     */
    protected function rrGet(Net_DNS2_Packet &$packet)
    {
        if (strlen($this->next_domain_name) > 0) {

            $data = $packet->compress($this->next_domain_name, $packet->offset);
            $bitmap = Net_DNS2_BitMap::arrayToBitMap($this->type_bit_maps);
    
            $packet->offset += strlen($bitmap);

            return $data . $bitmap;
        }

        return null;
    }
Exemple #9
0
    /**
     * parses the rdata of the Net_DNS2_Packet object
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
     *
     * @return boolean
     * @access protected
     *
     */
    protected function rrSet(Net_DNS2_Packet &$packet)
    {
        if ($this->rdlength > 0) {
            
            $length = $packet->offset + $this->rdlength;
            $offset = $packet->offset;

            while ($length > $offset) {

                $this->text[] = Net_DNS2_Packet::label($packet, $offset);
            }

            return true;
        }

        return false;
    }
Exemple #10
0
 /**
  * parses the rdata of the Net_DNS2_Packet object
  *
  * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
  *
  * @return boolean
  * @access protected
  *
  */
 protected function rrSet(Net_DNS2_Packet &$packet)
 {
     if ($this->rdlength > 0) {
         //
         // parse the preference
         //
         $x = unpack('npreference', $this->rdata);
         $this->preference = $x['preference'];
         //
         // get the exchange entry server)
         //
         $offset = $packet->offset + 2;
         $this->exchange = Net_DNS2_Packet::label($packet, $offset);
         return true;
     }
     return false;
 }
Exemple #11
0
 /**
  * sends a standard Net_DNS2_Packet_Request packet
  *
  * @param Net_DNS2_Packet $request a Net_DNS2_Packet_Request object
  * @param boolean         $use_tcp true/false if the function should
  *                                 use TCP for the request
  *
  * @return mixed returns a Net_DNS2_Packet_Response object, or false on error
  * @throws Net_DNS2_Exception
  * @access protected
  *
  */
 protected function sendPacket(Net_DNS2_Packet $request, $use_tcp)
 {
     //
     // get the data from the packet
     //
     $data = $request->get();
     if (strlen($data) < Net_DNS2_Lookups::DNS_HEADER_SIZE) {
         throw new Net_DNS2_Exception('invalid or empty packet for sending!', Net_DNS2_Lookups::E_PACKET_INVALID, null, $request);
     }
     reset($this->nameservers);
     //
     // randomize the name server list if it's asked for
     //
     if ($this->ns_random == true) {
         shuffle($this->nameservers);
     }
     //
     // loop so we can handle server errors
     //
     $response = null;
     $ns = '';
     $socket_type = null;
     $tcp_fallback = false;
     while (1) {
         //
         // grab the next DNS server
         //
         if ($tcp_fallback == false) {
             $ns = each($this->nameservers);
             if ($ns === false) {
                 throw new Net_DNS2_Exception('every name server provided has failed: ' . $this->_last_socket_error, Net_DNS2_Lookups::E_NS_FAILED);
             }
             $ns = $ns[1];
         }
         //
         // if the use TCP flag (force TCP) is set, or the packet is bigger
         // than 512 bytes, use TCP for sending the packet
         //
         if ($use_tcp == true || strlen($data) > Net_DNS2_Lookups::DNS_MAX_UDP_SIZE || $tcp_fallback == true) {
             $tcp_fallback = false;
             $socket_type = Net_DNS2_Socket::SOCK_STREAM;
             //
             // create the socket object
             //
             if (!isset($this->sock['tcp'][$ns]) || !$this->sock['tcp'][$ns] instanceof Net_DNS2_Socket) {
                 if ($this->sockets_enabled === true) {
                     $this->sock['tcp'][$ns] = new Net_DNS2_Socket_Sockets(Net_DNS2_Socket::SOCK_STREAM, $ns, $this->dns_port, $this->timeout);
                 } else {
                     $this->sock['tcp'][$ns] = new Net_DNS2_Socket_Streams(Net_DNS2_Socket::SOCK_STREAM, $ns, $this->dns_port, $this->timeout);
                 }
             }
             //
             // if a local IP address / port is set, then add it
             //
             if (strlen($this->local_host) > 0) {
                 $this->sock['tcp'][$ns]->bindAddress($this->local_host, $this->local_port);
             }
             //
             // open it; if it fails, continue in the while loop
             //
             if ($this->sock['tcp'][$ns]->open() === false) {
                 $this->_last_socket_error = $this->sock['tcp'][$ns]->last_error;
                 continue;
             }
             //
             // write the data to the socket; if it fails, continue on
             // the while loop
             //
             if ($this->sock['tcp'][$ns]->write($data) === false) {
                 $this->_last_socket_error = $this->sock['tcp'][$ns]->last_error;
                 continue;
             }
             //
             // read the content, using select to wait for a response
             //
             $size = 0;
             $result = null;
             //
             // handle zone transfer requests differently than other requests.
             //
             if ($request->question[0]->qtype == 'AXFR') {
                 $soa_count = 0;
                 while (1) {
                     //
                     // read the data off the socket
                     //
                     $result = $this->sock['tcp'][$ns]->read($size);
                     if ($result === false || $size < Net_DNS2_Lookups::DNS_HEADER_SIZE) {
                         $this->_last_socket_error = $this->sock['tcp'][$ns]->last_error;
                         break;
                     }
                     //
                     // parse the first chunk as a packet
                     //
                     $chunk = new Net_DNS2_Packet_Response($result, $size);
                     //
                     // if this is the first packet, then clone it directly, then
                     // go through it to see if there are two SOA records
                     // (indicating that it's the only packet)
                     //
                     if (is_null($response) == true) {
                         $response = clone $chunk;
                         //
                         // look for a failed response; if the zone transfer
                         // failed, then we don't need to do anything else at this
                         // point, and we should just break out.
                         //
                         if ($response->header->rcode != Net_DNS2_Lookups::RCODE_NOERROR) {
                             break;
                         }
                         //
                         // go through each answer
                         //
                         foreach ($response->answer as $index => $rr) {
                             //
                             // count the SOA records
                             //
                             if ($rr->type == 'SOA') {
                                 $soa_count++;
                             }
                         }
                         //
                         // if we have 2 or more SOA records, then we're done;
                         // otherwise continue out so we read the rest of the
                         // packets off the socket
                         //
                         if ($soa_count >= 2) {
                             break;
                         } else {
                             continue;
                         }
                     } else {
                         //
                         // go through all these answers, and look for SOA records
                         //
                         foreach ($chunk->answer as $index => $rr) {
                             //
                             // count the number of SOA records we find
                             //
                             if ($rr->type == 'SOA') {
                                 $soa_count++;
                             }
                             //
                             // add the records to a single response object
                             //
                             $response->answer[] = $rr;
                         }
                         //
                         // if we've found the second SOA record, we're done
                         //
                         if ($soa_count >= 2) {
                             break;
                         }
                     }
                 }
             } else {
                 $result = $this->sock['tcp'][$ns]->read($size);
                 if ($result === false || $size < Net_DNS2_Lookups::DNS_HEADER_SIZE) {
                     $this->_last_socket_error = $this->sock['tcp'][$ns]->last_error;
                     continue;
                 }
                 //
                 // create the packet object
                 //
                 $response = new Net_DNS2_Packet_Response($result, $size);
             }
             break;
         } else {
             $socket_type = Net_DNS2_Socket::SOCK_DGRAM;
             //
             // create the socket object
             //
             if (!isset($this->sock['udp'][$ns]) || !$this->sock['udp'][$ns] instanceof Net_DNS2_Socket) {
                 if ($this->sockets_enabled === true) {
                     $this->sock['udp'][$ns] = new Net_DNS2_Socket_Sockets(Net_DNS2_Socket::SOCK_DGRAM, $ns, $this->dns_port, $this->timeout);
                 } else {
                     $this->sock['udp'][$ns] = new Net_DNS2_Socket_Streams(Net_DNS2_Socket::SOCK_DGRAM, $ns, $this->dns_port, $this->timeout);
                 }
             }
             //
             // if a local IP address / port is set, then add it
             //
             if (strlen($this->local_host) > 0) {
                 $this->sock['udp'][$ns]->bindAddress($this->local_host, $this->local_port);
             }
             //
             // open it
             //
             if ($this->sock['udp'][$ns]->open() === false) {
                 $this->_last_socket_error = $this->sock['udp'][$ns]->last_error;
                 continue;
             }
             //
             // write the data to the socket
             //
             if ($this->sock['udp'][$ns]->write($data) === false) {
                 $this->_last_socket_error = $this->sock['udp'][$ns]->last_error;
                 continue;
             }
             //
             // read the content, using select to wait for a response
             //
             $size = 0;
             $result = $this->sock['udp'][$ns]->read($size);
             if ($result === false || $size < Net_DNS2_Lookups::DNS_HEADER_SIZE) {
                 $this->_last_socket_error = $this->sock['udp'][$ns]->last_error;
                 continue;
             }
             //
             // create the packet object
             //
             $response = new Net_DNS2_Packet_Response($result, $size);
             if (is_null($response)) {
                 throw new Net_DNS2_Exception('empty response object', Net_DNS2_Lookups::E_NS_FAILED, null, $request);
             }
             //
             // check the packet header for a trucated bit; if it was truncated,
             // then re-send the request as TCP.
             //
             if ($response->header->tc == 1) {
                 $tcp_fallback = true;
                 continue;
             }
             break;
         }
     }
     //
     // if $response is null, then we didn't even try once; which shouldn't
     // actually ever happen
     //
     if (is_null($response)) {
         throw new Net_DNS2_Exception('empty response object', Net_DNS2_Lookups::E_NS_FAILED, null, $request);
     }
     //
     // add the name server that the response came from to the response object,
     // and the socket type that was used.
     //
     $response->answer_from = $ns;
     $response->answer_socket_type = $socket_type;
     //
     // make sure header id's match between the request and response
     //
     if ($request->header->id != $response->header->id) {
         throw new Net_DNS2_Exception('invalid header: the request and response id do not match.', Net_DNS2_Lookups::E_HEADER_INVALID, null, $request, $response);
     }
     //
     // make sure the response is actually a response
     //
     // 0 = query, 1 = response
     //
     if ($response->header->qr != Net_DNS2_Lookups::QR_RESPONSE) {
         throw new Net_DNS2_Exception('invalid header: the response provided is not a response packet.', Net_DNS2_Lookups::E_HEADER_INVALID, null, $request, $response);
     }
     //
     // make sure the response code in the header is ok
     //
     if ($response->header->rcode != Net_DNS2_Lookups::RCODE_NOERROR) {
         throw new Net_DNS2_Exception('DNS request failed: ' . Net_DNS2_Lookups::$result_code_messages[$response->header->rcode], $response->header->rcode, null, $request, $response);
     }
     return $response;
 }
Exemple #12
0
 /**
  * sends a standard Net_DNS2_Packet_Request packet
  *
  * @param Net_DNS2_Packet $request a Net_DNS2_Packet_Request object
  * @param boolean         $use_tcp true/false if the function should
  *                                 use TCP for the request
  *
  * @return mixed returns a Net_DNS2_Packet_Response object, or false on error
  * @throws Net_DNS2_Exception
  * @access protected
  *
  */
 protected function sendPacket(Net_DNS2_Packet $request, $use_tcp)
 {
     //
     // get the data from the packet
     //
     $data = $request->get();
     if (strlen($data) < Net_DNS2_Lookups::DNS_HEADER_SIZE) {
         throw new Net_DNS2_Exception('invalid or empty packet for sending!', Net_DNS2_Lookups::E_PACKET_INVALID, null, $request);
     }
     reset($this->nameservers);
     //
     // randomize the name server list if it's asked for
     //
     if ($this->ns_random == true) {
         shuffle($this->nameservers);
     }
     //
     // loop so we can handle server errors
     //
     $response = null;
     $ns = '';
     while (1) {
         //
         // grab the next DNS server
         //
         $ns = each($this->nameservers);
         if ($ns === false) {
             if (is_null($this->last_exception) == false) {
                 throw $this->last_exception;
             } else {
                 throw new Net_DNS2_Exception('every name server provided has failed', Net_DNS2_Lookups::E_NS_FAILED);
             }
         }
         $ns = $ns[1];
         //
         // if the use TCP flag (force TCP) is set, or the packet is bigger than our
         // max allowed UDP size- which is either 512, or if this is DNSSEC request,
         // then whatever the configured dnssec_payload_size is.
         //
         $max_udp_size = Net_DNS2_Lookups::DNS_MAX_UDP_SIZE;
         if ($this->dnssec == true) {
             $max_udp_size = $this->dnssec_payload_size;
         }
         if ($use_tcp == true || strlen($data) > $max_udp_size) {
             try {
                 $response = $this->sendTCPRequest($ns, $data, $request->question[0]->qtype == 'AXFR' ? true : false);
             } catch (Net_DNS2_Exception $e) {
                 $this->last_exception = $e;
                 $this->last_exception_list[$ns] = $e;
                 continue;
             }
             //
             // otherwise, send it using UDP
             //
         } else {
             try {
                 $response = $this->sendUDPRequest($ns, $data);
                 //
                 // check the packet header for a trucated bit; if it was truncated,
                 // then re-send the request as TCP.
                 //
                 if ($response->header->tc == 1) {
                     $response = $this->sendTCPRequest($ns, $data);
                 }
             } catch (Net_DNS2_Exception $e) {
                 $this->last_exception = $e;
                 $this->last_exception_list[$ns] = $e;
                 continue;
             }
         }
         //
         // make sure header id's match between the request and response
         //
         if ($request->header->id != $response->header->id) {
             $this->last_exception = new Net_DNS2_Exception('invalid header: the request and response id do not match.', Net_DNS2_Lookups::E_HEADER_INVALID, null, $request, $response);
             $this->last_exception_list[$ns] = $this->last_exception;
             continue;
         }
         //
         // make sure the response is actually a response
         //
         // 0 = query, 1 = response
         //
         if ($response->header->qr != Net_DNS2_Lookups::QR_RESPONSE) {
             $this->last_exception = new Net_DNS2_Exception('invalid header: the response provided is not a response packet.', Net_DNS2_Lookups::E_HEADER_INVALID, null, $request, $response);
             $this->last_exception_list[$ns] = $this->last_exception;
             continue;
         }
         //
         // make sure the response code in the header is ok
         //
         if ($response->header->rcode != Net_DNS2_Lookups::RCODE_NOERROR) {
             $this->last_exception = new Net_DNS2_Exception('DNS request failed: ' . Net_DNS2_Lookups::$result_code_messages[$response->header->rcode], $response->header->rcode, null, $request, $response);
             $this->last_exception_list[$ns] = $this->last_exception;
             continue;
         }
         break;
     }
     return $response;
 }
Exemple #13
0
 /**
  * sends a standard Net_DNS2_Packet_Request packet
  *
  * @param Net_DNS2_Packet $request a Net_DNS2_Packet_Request object
  * @param boolean         $use_tcp true/false if the function should
  *                                 use TCP for the request
  *
  * @return mixed returns a Net_DNS2_Packet_Response object, or false on error
  * @throws Net_DNS2_Exception
  * @access protected
  *
  */
 protected function sendPacket(Net_DNS2_Packet $request, $use_tcp)
 {
     //
     // get the data from the packet
     //
     $data = $request->get();
     if (strlen($data) < Net_DNS2_Lookups::DNS_HEADER_SIZE) {
         throw new Net_DNS2_Exception('invalid or empty packet for sending!', Net_DNS2_Lookups::E_PACKET_INVALID);
     }
     reset($this->nameservers);
     //
     // randomize the name server list if it's asked for
     //
     if ($this->ns_random == true) {
         shuffle($this->nameservers);
     }
     //
     // loop so we can handle server errors
     //
     $response = null;
     $ns = '';
     $tcp_fallback = false;
     while (1) {
         //
         // grab the next DNS server
         //
         if ($tcp_fallback == false) {
             $ns = each($this->nameservers);
             if ($ns === false) {
                 throw new Net_DNS2_Exception('every name server provided has failed: ' . $this->_last_socket_error, Net_DNS2_Lookups::E_NS_FAILED);
             }
             $ns = $ns[1];
         }
         //
         // if the use TCP flag (force TCP) is set, or the packet is bigger
         // than 512 bytes, use TCP for sending the packet
         //
         if ($use_tcp == true || strlen($data) > Net_DNS2_Lookups::DNS_MAX_UDP_SIZE || $tcp_fallback == true) {
             $tcp_fallback = false;
             //
             // create the socket object
             //
             if (!isset($this->sock['tcp'][$ns]) || !$this->sock['tcp'][$ns] instanceof Net_DNS2_Socket) {
                 if ($this->sockets_enabled === true) {
                     $this->sock['tcp'][$ns] = new Net_DNS2_Socket_Sockets(SOCK_STREAM, $ns, $this->dns_port, $this->timeout);
                 } else {
                     $this->sock['tcp'][$ns] = new Net_DNS2_Socket_Streams(SOCK_STREAM, $ns, $this->dns_port, $this->timeout);
                 }
             }
             //
             // if a local IP address / port is set, then add it
             //
             if (strlen($this->local_host) > 0) {
                 $this->sock['tcp'][$ns]->bindAddress($this->local_host, $this->local_port);
             }
             //
             // open it; if it fails, continue in the while loop
             //
             if ($this->sock['tcp'][$ns]->open() === false) {
                 $this->_last_socket_error = $this->sock['tcp'][$ns]->last_error;
                 continue;
             }
             //
             // write the data to the socket; if it fails, continue on
             // the while loop
             //
             if ($this->sock['tcp'][$ns]->write($data) === false) {
                 $this->_last_socket_error = $this->sock['tcp'][$ns]->last_error;
                 continue;
             }
             //
             // read the content, using select to wait for a response
             //
             $size = 0;
             $result = $this->sock['tcp'][$ns]->read($size);
             if ($result === false || $size < Net_DNS2_Lookups::DNS_HEADER_SIZE) {
                 $this->_last_socket_error = $this->sock['tcp'][$ns]->last_error;
                 continue;
             }
             //
             // create the packet object
             //
             $response = new Net_DNS2_Packet_Response($result, $size);
             break;
         } else {
             //
             // create the socket object
             //
             if (!isset($this->sock['udp'][$ns]) || !$this->sock['udp'][$ns] instanceof Net_DNS2_Socket) {
                 if ($this->sockets_enabled === true) {
                     $this->sock['udp'][$ns] = new Net_DNS2_Socket_Sockets(SOCK_DGRAM, $ns, $this->dns_port, $this->timeout);
                 } else {
                     $this->sock['udp'][$ns] = new Net_DNS2_Socket_Streams(SOCK_DGRAM, $ns, $this->dns_port, $this->timeout);
                 }
             }
             //
             // if a local IP address / port is set, then add it
             //
             if (strlen($this->local_host) > 0) {
                 $this->sock['udp'][$ns]->bindAddress($this->local_host, $this->local_port);
             }
             //
             // open it
             //
             if ($this->sock['udp'][$ns]->open() === false) {
                 $this->_last_socket_error = $this->sock['udp'][$ns]->last_error;
                 continue;
             }
             //
             // write the data to the socket
             //
             if ($this->sock['udp'][$ns]->write($data) === false) {
                 $this->_last_socket_error = $this->sock['udp'][$ns]->last_error;
                 continue;
             }
             //
             // read the content, using select to wait for a response
             //
             $size = 0;
             $result = $this->sock['udp'][$ns]->read($size);
             if ($result === false || $size < Net_DNS2_Lookups::DNS_HEADER_SIZE) {
                 $this->_last_socket_error = $this->sock['udp'][$ns]->last_error;
                 continue;
             }
             //
             // create the packet object
             //
             $response = new Net_DNS2_Packet_Response($result, $size);
             //
             // check the packet header for a trucated bit; if it was truncated,
             // then re-send the request as TCP.
             //
             if ($response->header->tc == 1) {
                 $tcp_fallback = true;
                 continue;
             }
             break;
         }
     }
     if (is_null($response)) {
         return false;
     }
     //
     // make sure header id's match between the request and response
     //
     if ($request->header->id != $response->header->id) {
         throw new Net_DNS2_Exception('invalid header: the request and response id do not match.', Net_DNS2_Lookups::E_HEADER_INVALID);
     }
     //
     // make sure the response is actually a response
     //
     // 0 = query, 1 = response
     //
     if ($response->header->qr != Net_DNS2_Lookups::QR_RESPONSE) {
         throw new Net_DNS2_Exception('invalid header: the response provided is not a response packet.', Net_DNS2_Lookups::E_HEADER_INVALID);
     }
     //
     // make sure the response code in the header is ok
     //
     if ($response->header->rcode != Net_DNS2_Lookups::RCODE_NOERROR) {
         throw new Net_DNS2_Exception('DNS request failed: ' . Net_DNS2_Lookups::$result_code_messages[$response->header->rcode], $response->header->rcode);
     }
     return $response;
 }
Exemple #14
0
 /**
  * returns a binary packed Net_DNS2_Question object
  *
  * @param Net_DNS2_Packet &$packet the Net_DNS2_Packet object this question is
  *                                 part of. This needs to be passed in so that
  *                                 the compressed qname value can be packed in
  *                                 with the names of the other parts of the
  *                                 packet.
  *
  * @return string
  * @throws Net_DNS2_Exception
  * @access public
  *
  */
 public function get(Net_DNS2_Packet &$packet)
 {
     //
     // validate the type and class
     //
     $type = Net_DNS2_Lookups::$rr_types_by_name[$this->qtype];
     $class = Net_DNS2_Lookups::$classes_by_name[$this->qclass];
     if (!isset($type) || !isset($class)) {
         throw new Net_DNS2_Exception('invalid question section: invalid type (' . $this->qtype . ') or class (' . $this->qclass . ') specified.', Net_DNS2_Lookups::E_QUESTION_INVALID);
     }
     $data = $packet->compress($this->qname, $packet->offset);
     $data .= chr($type << 8) . chr($type) . chr($class << 8) . chr($class);
     $packet->offset += 4;
     return $data;
 }
Exemple #15
0
    /**
     * parses the rdata of the Net_DNS2_Packet object
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
     *
     * @return boolean
     * @access protected
     *
     */
    protected function rrSet(Net_DNS2_Packet &$packet)
    {
        if ($this->rdlength > 0) {

            $this->isdnaddress = Net_DNS2_Packet::label($packet, $packet->offset);

            //
            // look for a SA (sub address) - it's optional
            //
            if ( (strlen($this->isdnaddress) + 1) < $this->rdlength) {

                $this->sa = Net_DNS2_Packet::label($packet, $packet->offset);
            } else {
            
                $this->sa = '';
            }

            return true;
        }

        return false;
    }
Exemple #16
0
 /**
  * returns the rdata portion of the DNS packet
  *
  * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
  *                                 compressed names
  *
  * @return mixed                   either returns a binary packed
  *                                 string or null on failure
  * @access protected
  *
  */
 protected function rrGet(Net_DNS2_Packet &$packet)
 {
     if (strlen($this->target) > 0) {
         $data = pack('nn', $this->priority, $this->weight);
         $packet->offset += 4;
         $data .= $packet->compress(trim($this->target, '"'), $packet->offset);
         return $data;
     }
     return null;
 }
Exemple #17
0
 /**
  * parses the rdata of the Net_DNS2_Packet object
  *
  * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
  *
  * @return boolean
  * @access protected
  *
  */
 protected function rrSet(Net_DNS2_Packet &$packet)
 {
     if ($this->rdlength > 0) {
         $offset = $packet->offset;
         $this->previous = Net_DNS2_Packet::label($packet, $offset);
         $this->next = Net_DNS2_Packet::label($packet, $offset);
         return true;
     }
     return false;
 }
Exemple #18
0
    /**
     * returns the rdata portion of the DNS packet
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
     *                                 compressed names
     *
     * @return mixed                   either returns a binary packed
     *                                 string or null on failure
     * @access protected
     *
     */
    protected function rrGet(Net_DNS2_Packet &$packet)
    {
        if (strlen($this->algorithm) > 0) {

            //
            // make sure the size values are correct
            //
            $this->key_size     = strlen($this->key_data);
            $this->other_size   = strlen($this->other_data);

            //
            // add the algorithm without compression
            //
            $data = Net_DNS2_Packet::pack($this->algorithm);

            //
            // pack in the inception, expiration, mode, error and key size
            //
            $data .= pack(
                'NNnnn', $this->inception, $this->expiration, 
                $this->mode, 0, $this->key_size
            );

            //
            // if the key_size > 0, then add the key
            //
            if ($this->key_size > 0) {
            
                $data .= $this->key_data;
            }

            //
            // pack in the other size
            //
            $data .= pack('n', $this->other_size);
            if ($this->other_size > 0) {

                $data .= $this->other_data;
            }

            $packet->offset += strlen($data);

            return $data;
        }

        return null;
    }
Exemple #19
0
 /**
  * parses the rdata of the Net_DNS2_Packet object
  *
  * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
  *
  * @return boolean
  * @access protected
  *
  */
 protected function rrSet(Net_DNS2_Packet &$packet)
 {
     if ($this->rdlength > 0) {
         $this->psdnaddress = Net_DNS2_Packet::label($packet, $packet->offset);
         return true;
     }
     return false;
 }
Exemple #20
0
 /**
  * expands the domain name stored at a given offset in a DNS Packet
  *
  * This logic was based on the Net::DNS::Packet::dn_expand() function
  * by Michanel Fuhr
  *
  * @param Net_DNS2_Packet &$packet the DNS packet to look in for the domain name
  * @param integer         &$offset the offset into the given packet object
  *
  * @return mixed either the domain name or null if it's not found.
  * @access public
  *
  */
 public static function expand(Net_DNS2_Packet &$packet, &$offset)
 {
     $name = '';
     while (1) {
         if ($packet->rdlength < $offset + 1) {
             return null;
         }
         $xlen = ord($packet->rdata[$offset]);
         if ($xlen == 0) {
             ++$offset;
             break;
         } else {
             if (($xlen & 0xc0) == 0xc0) {
                 if ($packet->rdlength < $offset + 2) {
                     return null;
                 }
                 $ptr = ord($packet->rdata[$offset]) << 8 | ord($packet->rdata[$offset + 1]);
                 $ptr = $ptr & 0x3fff;
                 $name2 = Net_DNS2_Packet::expand($packet, $ptr);
                 if (is_null($name2)) {
                     return null;
                 }
                 $name .= $name2;
                 $offset += 2;
                 break;
             } else {
                 ++$offset;
                 if ($packet->rdlength < $offset + $xlen) {
                     return null;
                 }
                 $elem = '';
                 $elem = substr($packet->rdata, $offset, $xlen);
                 $name .= $elem . '.';
                 $offset += $xlen;
             }
         }
     }
     return trim($name, '.');
 }
Exemple #21
0
 /**
  * parses the rdata of the Net_DNS2_Packet object
  *
  * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
  *
  * @return boolean
  * @access protected
  *
  */
 protected function rrSet(Net_DNS2_Packet &$packet)
 {
     if ($this->rdlength > 0) {
         $offset = $packet->offset;
         $this->cpu = trim(Net_DNS2_Packet::label($packet, $offset), '"');
         $this->os = trim(Net_DNS2_Packet::label($packet, $offset), '"');
         return true;
     }
     return false;
 }
Exemple #22
0
    /**
     * returns the rdata portion of the DNS packet
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
     *                                 compressed names
     *
     * @return mixed                   either returns a binary packed
     *                                 string or null on failure
     * @access protected
     *
     */
    protected function rrGet(Net_DNS2_Packet &$packet)
    {
        if (strlen($this->map822) > 0) {
            
            $data = pack('n', $this->preference);
            $packet->offset += 2;

            $data .= $packet->compress($this->map822, $packet->offset);
            $data .= $packet->compress($this->mapx400, $packet->offset);

            return $data;
        }

        return null;
    }
Exemple #23
0
 /**
  * returns the rdata portion of the DNS packet
  *
  * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
  *                                 compressed names
  *
  * @return mixed                   either returns a binary packed
  *                                 string or null on failure
  * @access protected
  *
  */
 protected function rrGet(Net_DNS2_Packet &$packet)
 {
     if (strlen($this->key) > 0) {
         //
         // create a new packet for the signature-
         //
         $new_packet = new Net_DNS2_Packet_Request('example.com', 'SOA', 'IN');
         //
         // copy the packet data over
         //
         $new_packet->copy($packet);
         //
         // remove the TSIG object from the additional list
         //
         array_pop($new_packet->additional);
         $new_packet->header->arcount = count($new_packet->additional);
         //
         // copy out the data
         //
         $sig_data = $new_packet->get();
         //
         // add the name without compressing
         //
         $sig_data .= Net_DNS2_Packet::pack($this->name);
         //
         // add the class and TTL
         //
         $sig_data .= pack('nN', Net_DNS2_Lookups::$classes_by_name[$this->class], $this->ttl);
         //
         // add the algorithm name without compression
         //
         $sig_data .= Net_DNS2_Packet::pack(strtolower($this->algorithm));
         //
         // add the rest of the values
         //
         $sig_data .= pack('nNnnn', 0, $this->time_signed, $this->fudge, $this->error, $this->other_length);
         if ($this->other_length > 0) {
             $sig_data .= pack('nN', 0, $this->other_data);
         }
         //
         // sign the data
         //
         $this->mac = $this->_signHMAC($sig_data, base64_decode($this->key), $this->algorithm);
         $this->mac_size = strlen($this->mac);
         //
         // compress the algorithm
         //
         $data = Net_DNS2_Packet::pack(strtolower($this->algorithm));
         //
         // pack the time, fudge and mac size
         //
         $data .= pack('nNnn', 0, $this->time_signed, $this->fudge, $this->mac_size);
         $data .= $this->mac;
         //
         // check the error and other_length
         //
         if ($this->error == Net_DNS2_Lookups::RCODE_BADTIME) {
             $this->other_length = strlen($this->other_data);
             if ($this->other_length != 6) {
                 return null;
             }
         } else {
             $this->other_length = 0;
             $this->other_data = '';
         }
         //
         // pack the id, error and other_length
         //
         $data .= pack('nnn', $packet->header->id, $this->error, $this->other_length);
         if ($this->other_length > 0) {
             $data .= pack('nN', 0, $this->other_data);
         }
         $packet->offset += strlen($data);
         return $data;
     }
     return null;
 }
Exemple #24
0
    /**
     * returns the rdata portion of the DNS packet
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
     *                                 compressed names
     *
     * @return mixed                   either returns a binary packed
     *                                 string or null on failure
     * @access protected
     *
     */
    protected function rrGet(Net_DNS2_Packet &$packet)
    {
        if ( (strlen($this->hit) > 0) && (strlen($this->public_key) > 0) ) {

            //
            // pack the length, algorithm and HIT values
            //
            $data = pack(
                'CCnH*', 
                $this->hit_length, 
                $this->pk_algorithm, 
                $this->pk_length,
                $this->hit                
            );
            
            //
            // add the public key
            //
            $data .= base64_decode($this->public_key);

            //
            // add the offset
            //
            $packet->offset += strlen($data);

            //
            // add each rendezvous server
            //
            foreach ($this->rendezvous_servers as $index => $server) {

                $data .= $packet->compress($server, $packet->offset);
            }

            return $data;
        }

        return null;
    }
Exemple #25
0
 /**
  * returns the rdata portion of the DNS packet
  *
  * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
  *                                 compressed names
  *
  * @return mixed                   either returns a binary packed
  *                                 string or null on failure
  * @access protected
  *
  */
 protected function rrGet(Net_DNS2_Packet &$packet)
 {
     if (strlen($this->hostname) > 0) {
         $data = pack('n', $this->subtype);
         $packet->offset += 2;
         $data .= $packet->compress($this->hostname, $packet->offset);
         return $data;
     }
     return null;
 }