1<?php 2/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 3 4/** 5 * DNS Library for handling lookups and updates. 6 * 7 * PHP Version 5 8 * 9 * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 16 * * Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 19 * * Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in 21 * the documentation and/or other materials provided with the 22 * distribution. 23 * 24 * * Neither the name of Mike Pultz nor the names of his contributors 25 * may be used to endorse or promote products derived from this 26 * software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 31 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 32 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 34 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 36 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 38 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39 * POSSIBILITY OF SUCH DAMAGE. 40 * 41 * @category Networking 42 * @package Net_DNS2 43 * @author Mike Pultz <mike@mikepultz.com> 44 * @copyright 2010 Mike Pultz <mike@mikepultz.com> 45 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 46 * @version SVN: $Id$ 47 * @link http://pear.php.net/package/Net_DNS2 48 * @since File available since Release 0.6.0 49 * 50 */ 51 52 53/** 54 * DNS Packet Header class 55 * 56 * This class handles parsing and constructing DNS Packet Headers as defined 57 * by section 4.1.1 of RFC1035. 58 * 59 * DNS header format - RFC1035 section 4.1.1 60 * DNS header format - RFC4035 section 3.2 61 * 62 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 63 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 64 * | ID | 65 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 66 * |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE | 67 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 68 * | QDCOUNT | 69 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 70 * | ANCOUNT | 71 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 72 * | NSCOUNT | 73 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 74 * | ARCOUNT | 75 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 76 * 77 * @category Networking 78 * @package Net_DNS2 79 * @author Mike Pultz <mike@mikepultz.com> 80 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 81 * @link http://pear.php.net/package/Net_DNS2 82 * 83 */ 84class Net_DNS2_Header 85{ 86 public $id; // 16 bit - identifier 87 public $qr; // 1 bit - 0 = query, 1 = response 88 public $opcode; // 4 bit - op code 89 public $aa; // 1 bit - Authoritative Answer 90 public $tc; // 1 bit - TrunCation 91 public $rd; // 1 bit - Recursion Desired 92 public $ra; // 1 bit - Recursion Available 93 public $z; // 1 bit - Reserved 94 public $ad; // 1 bit - Authentic Data (RFC4035) 95 public $cd; // 1 bit - Checking Disabled (RFC4035) 96 public $rcode; // 4 bit - Response code 97 public $qdcount; // 16 bit - entries in the question section 98 public $ancount; // 16 bit - resource records in the answer section 99 public $nscount; // 16 bit - name server rr in the authority records section 100 public $arcount; // 16 bit - rr's in the additional records section 101 102 /** 103 * Constructor - builds a new Net_DNS2_Header object 104 * 105 * @param mixed &$packet either a Net_DNS2_Packet object or null 106 * 107 * @throws Net_DNS2_Exception 108 * @access public 109 * 110 */ 111 public function __construct(Net_DNS2_Packet &$packet = null) 112 { 113 if (!is_null($packet)) { 114 115 $this->set($packet); 116 } else { 117 118 $this->id = $this->nextPacketId(); 119 $this->qr = Net_DNS2_Lookups::QR_QUERY; 120 $this->opcode = Net_DNS2_Lookups::OPCODE_QUERY; 121 $this->aa = 0; 122 $this->tc = 0; 123 $this->rd = 1; 124 $this->ra = 0; 125 $this->z = 0; 126 $this->ad = 0; 127 $this->cd = 0; 128 $this->rcode = Net_DNS2_Lookups::RCODE_NOERROR; 129 $this->qdcount = 1; 130 $this->ancount = 0; 131 $this->nscount = 0; 132 $this->arcount = 0; 133 } 134 } 135 136 /** 137 * returns the next available packet id 138 * 139 * @return integer 140 * @access public 141 * 142 */ 143 public function nextPacketId() 144 { 145 if (++Net_DNS2_Lookups::$next_packet_id > 65535) { 146 147 Net_DNS2_Lookups::$next_packet_id = 1; 148 } 149 150 return Net_DNS2_Lookups::$next_packet_id; 151 } 152 153 /** 154 * magic __toString() method to return the header as a string 155 * 156 * @return string 157 * @access public 158 * 159 */ 160 public function __toString() 161 { 162 $output = ";;\n;; Header:\n"; 163 164 $output .= ";;\t id = " . $this->id . "\n"; 165 $output .= ";;\t qr = " . $this->qr . "\n"; 166 $output .= ";;\t opcode = " . $this->opcode . "\n"; 167 $output .= ";;\t aa = " . $this->aa . "\n"; 168 $output .= ";;\t tc = " . $this->tc . "\n"; 169 $output .= ";;\t rd = " . $this->rd . "\n"; 170 $output .= ";;\t ra = " . $this->ra . "\n"; 171 $output .= ";;\t z = " . $this->z . "\n"; 172 $output .= ";;\t ad = " . $this->ad . "\n"; 173 $output .= ";;\t cd = " . $this->cd . "\n"; 174 $output .= ";;\t rcode = " . $this->rcode . "\n"; 175 $output .= ";;\t qdcount = " . $this->qdcount . "\n"; 176 $output .= ";;\t ancount = " . $this->ancount . "\n"; 177 $output .= ";;\t nscount = " . $this->nscount . "\n"; 178 $output .= ";;\t arcount = " . $this->arcount . "\n"; 179 180 return $output; 181 } 182 183 /** 184 * constructs a Net_DNS2_Header from a Net_DNS2_Packet object 185 * 186 * @param Net_DNS2_Packet &$packet Object 187 * 188 * @return boolean 189 * @throws Net_DNS2_Exception 190 * @access public 191 * 192 */ 193 public function set(Net_DNS2_Packet &$packet) 194 { 195 // 196 // the header must be at least 12 bytes long. 197 // 198 if ($packet->rdlength < Net_DNS2_Lookups::DNS_HEADER_SIZE) { 199 200 throw new Net_DNS2_Exception( 201 'invalid header data provided; to small', 202 Net_DNS2_Lookups::E_HEADER_INVALID 203 ); 204 } 205 206 $offset = 0; 207 208 // 209 // parse the values 210 // 211 $this->id = ord($packet->rdata[$offset]) << 8 | 212 ord($packet->rdata[++$offset]); 213 214 ++$offset; 215 $this->qr = (ord($packet->rdata[$offset]) >> 7) & 0x1; 216 $this->opcode = (ord($packet->rdata[$offset]) >> 3) & 0xf; 217 $this->aa = (ord($packet->rdata[$offset]) >> 2) & 0x1; 218 $this->tc = (ord($packet->rdata[$offset]) >> 1) & 0x1; 219 $this->rd = ord($packet->rdata[$offset]) & 0x1; 220 221 ++$offset; 222 $this->ra = (ord($packet->rdata[$offset]) >> 7) & 0x1; 223 $this->z = (ord($packet->rdata[$offset]) >> 6) & 0x1; 224 $this->ad = (ord($packet->rdata[$offset]) >> 5) & 0x1; 225 $this->cd = (ord($packet->rdata[$offset]) >> 4) & 0x1; 226 $this->rcode = ord($packet->rdata[$offset]) & 0xf; 227 228 $this->qdcount = ord($packet->rdata[++$offset]) << 8 | 229 ord($packet->rdata[++$offset]); 230 $this->ancount = ord($packet->rdata[++$offset]) << 8 | 231 ord($packet->rdata[++$offset]); 232 $this->nscount = ord($packet->rdata[++$offset]) << 8 | 233 ord($packet->rdata[++$offset]); 234 $this->arcount = ord($packet->rdata[++$offset]) << 8 | 235 ord($packet->rdata[++$offset]); 236 237 // 238 // increment the internal offset 239 // 240 $packet->offset += Net_DNS2_Lookups::DNS_HEADER_SIZE; 241 242 return true; 243 } 244 245 /** 246 * returns a binary packed DNS Header 247 * 248 * @param Net_DNS2_Packet &$packet Object 249 * 250 * @return string 251 * @access public 252 * 253 */ 254 public function get(Net_DNS2_Packet &$packet) 255 { 256 $packet->offset += Net_DNS2_Lookups::DNS_HEADER_SIZE; 257 258 return pack('n', $this->id) . 259 chr( 260 ($this->qr << 7) | ($this->opcode << 3) | 261 ($this->aa << 2) | ($this->tc << 1) | ($this->rd) 262 ) . 263 chr( 264 ($this->ra << 7) | ($this->ad << 5) | ($this->cd << 4) | $this->rcode 265 ) . 266 pack('n4', $this->qdcount, $this->ancount, $this->nscount, $this->arcount); 267 } 268} 269 270/* 271 * Local variables: 272 * tab-width: 4 273 * c-basic-offset: 4 274 * c-hanging-comment-ender-p: nil 275 * End: 276 */ 277?> 278