PageRenderTime 43ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/includes/net/dns2/packet.php

https://bitbucket.org/speedealing/speedealing
PHP | 449 lines | 173 code | 72 blank | 204 comment | 20 complexity | 9e0dce6a637c5bf038a10afbce320357 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1, GPL-3.0, MIT
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * DNS Library for handling lookups and updates.
  5. *
  6. * PHP Version 5
  7. *
  8. * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
  9. * All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. *
  15. * * Redistributions of source code must retain the above copyright
  16. * notice, this list of conditions and the following disclaimer.
  17. *
  18. * * Redistributions in binary form must reproduce the above copyright
  19. * notice, this list of conditions and the following disclaimer in
  20. * the documentation and/or other materials provided with the
  21. * distribution.
  22. *
  23. * * Neither the name of Mike Pultz nor the names of his contributors
  24. * may be used to endorse or promote products derived from this
  25. * software without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  28. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  29. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  30. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  31. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  32. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  33. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  34. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  35. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  37. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. * @category Networking
  41. * @package Net_DNS2
  42. * @author Mike Pultz <mike@mikepultz.com>
  43. * @copyright 2010 Mike Pultz <mike@mikepultz.com>
  44. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  45. * @version SVN: $Id: Packet.php 179 2012-11-23 05:49:01Z mike.pultz $
  46. * @link http://pear.php.net/package/Net_DNS2
  47. * @since File available since Release 0.6.0
  48. *
  49. * This file contains code based off the Net::DNS Perl module by
  50. * Michael Fuhr.
  51. *
  52. * This is the copyright notice from the PERL Net::DNS module:
  53. *
  54. * Copyright (c) 1997-2000 Michael Fuhr. All rights reserved. This
  55. * program is free software; you can redistribute it and/or modify it
  56. * under the same terms as Perl itself.
  57. *
  58. */
  59. /**
  60. * This is the base class that holds a standard DNS packet.
  61. *
  62. * The Net_DNS2_Packet_Request and Net_DNS2_Packet_Response classes extend this
  63. * class.
  64. *
  65. * @category Networking
  66. * @package Net_DNS2
  67. * @author Mike Pultz <mike@mikepultz.com>
  68. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  69. * @link http://pear.php.net/package/Net_DNS2
  70. * @see Net_DNS2_Packet_Request, Net_DNS2_Packet_Response
  71. *
  72. */
  73. class Net_DNS2_Packet
  74. {
  75. /*
  76. * the full binary data and length for this packet
  77. */
  78. public $rdata;
  79. public $rdlength;
  80. /*
  81. * the offset pointer used when building/parsing packets
  82. */
  83. public $offset = 0;
  84. /*
  85. * Net_DNS2_Header object with the DNS packet header
  86. */
  87. public $header;
  88. /*
  89. * array of Net_DNS2_Question objects
  90. *
  91. * used as "zone" for updates per RFC2136
  92. *
  93. */
  94. public $question = array();
  95. /*
  96. * array of Net_DNS2_RR Objects for Answers
  97. *
  98. * used as "prerequisite" for updates per RFC2136
  99. *
  100. */
  101. public $answer = array();
  102. /*
  103. * array of Net_DNS2_RR Objects for Authority
  104. *
  105. * used as "update" for updates per RFC2136
  106. *
  107. */
  108. public $authority = array();
  109. /*
  110. * array of Net_DNS2_RR Objects for Addtitional
  111. */
  112. public $additional = array();
  113. /*
  114. * array of compressed labeles
  115. */
  116. private $_compressed = array();
  117. /**
  118. * magic __toString() method to return the Net_DNS2_Packet as a string
  119. *
  120. * @return string
  121. * @access public
  122. *
  123. */
  124. public function __toString()
  125. {
  126. $output = $this->header->__toString();
  127. foreach ($this->question as $x) {
  128. $output .= $x->__toString() . "\n";
  129. }
  130. foreach ($this->answer as $x) {
  131. $output .= $x->__toString() . "\n";
  132. }
  133. foreach ($this->authority as $x) {
  134. $output .= $x->__toString() . "\n";
  135. }
  136. foreach ($this->additional as $x) {
  137. $output .= $x->__toString() . "\n";
  138. }
  139. return $output;
  140. }
  141. /**
  142. * returns a full binary DNS packet
  143. *
  144. * @return string
  145. * @throws Net_DNS2_Exception
  146. * @access public
  147. *
  148. */
  149. public function get()
  150. {
  151. $data = $this->header->get($this);
  152. foreach ($this->question as $x) {
  153. $data .= $x->get($this);
  154. }
  155. foreach ($this->answer as $x) {
  156. $data .= $x->get($this);
  157. }
  158. foreach ($this->authority as $x) {
  159. $data .= $x->get($this);
  160. }
  161. foreach ($this->additional as $x) {
  162. $data .= $x->get($this);
  163. }
  164. return $data;
  165. }
  166. /**
  167. * applies a standard DNS name compression on the given name/offset
  168. *
  169. * This logic was based on the Net::DNS::Packet::dn_comp() function
  170. * by Michanel Fuhr
  171. *
  172. * @param string $name the name to be compressed
  173. * @param integer &$offset the offset into the given packet object
  174. *
  175. * @return string
  176. * @access public
  177. *
  178. */
  179. public function compress($name, &$offset)
  180. {
  181. $names = explode('.', $name);
  182. $compname = '';
  183. while (!empty($names)) {
  184. $dname = join('.', $names);
  185. if (isset($this->_compressed[$dname])) {
  186. $compname .= pack('n', 0xc000 | $this->_compressed[$dname]);
  187. $offset += 2;
  188. break;
  189. }
  190. $this->_compressed[$dname] = $offset;
  191. $first = array_shift($names);
  192. $length = strlen($first);
  193. if ($length <= 0) {
  194. continue;
  195. }
  196. //
  197. // truncate see RFC1035 2.3.1
  198. //
  199. if ($length > 63) {
  200. $length = 63;
  201. $first = substr($first, 0, $length);
  202. }
  203. $compname .= pack('Ca*', $length, $first);
  204. $offset += $length + 1;
  205. }
  206. if (empty($names)) {
  207. $compname .= pack('C', 0);
  208. $offset++;
  209. }
  210. return $compname;
  211. }
  212. /**
  213. * applies a standard DNS name compression on the given name/offset
  214. *
  215. * This logic was based on the Net::DNS::Packet::dn_comp() function
  216. * by Michanel Fuhr
  217. *
  218. * @param string $name the name to be compressed
  219. *
  220. * @return string
  221. * @access public
  222. *
  223. */
  224. public static function pack($name)
  225. {
  226. $offset = 0;
  227. $names = explode('.', $name);
  228. $compname = '';
  229. while (!empty($names)) {
  230. $first = array_shift($names);
  231. $length = strlen($first);
  232. $compname .= pack('Ca*', $length, $first);
  233. $offset += $length + 1;
  234. }
  235. $compname .= "\0";
  236. $offset++;
  237. return $compname;
  238. }
  239. /**
  240. * expands the domain name stored at a given offset in a DNS Packet
  241. *
  242. * This logic was based on the Net::DNS::Packet::dn_expand() function
  243. * by Michanel Fuhr
  244. *
  245. * @param Net_DNS2_Packet &$packet the DNS packet to look in for the domain name
  246. * @param integer &$offset the offset into the given packet object
  247. *
  248. * @return mixed either the domain name or null if it's not found.
  249. * @access public
  250. *
  251. */
  252. public static function expand(Net_DNS2_Packet &$packet, &$offset)
  253. {
  254. $name = '';
  255. while (1) {
  256. if ($packet->rdlength < ($offset + 1)) {
  257. return null;
  258. }
  259. $xlen = ord($packet->rdata[$offset]);
  260. if ($xlen == 0) {
  261. ++$offset;
  262. break;
  263. } else if (($xlen & 0xc0) == 0xc0) {
  264. if ($packet->rdlength < ($offset + 2)) {
  265. return null;
  266. }
  267. $ptr = ord($packet->rdata[$offset]) << 8 |
  268. ord($packet->rdata[$offset+1]);
  269. $ptr = $ptr & 0x3fff;
  270. $name2 = Net_DNS2_Packet::expand($packet, $ptr);
  271. if (is_null($name2)) {
  272. return null;
  273. }
  274. $name .= $name2;
  275. $offset += 2;
  276. break;
  277. } else {
  278. ++$offset;
  279. if ($packet->rdlength < ($offset + $xlen)) {
  280. return null;
  281. }
  282. $elem = '';
  283. $elem = substr($packet->rdata, $offset, $xlen);
  284. $name .= $elem . '.';
  285. $offset += $xlen;
  286. }
  287. }
  288. return trim($name, '.');
  289. }
  290. /**
  291. * parses a domain label from a DNS Packet at the given offset
  292. *
  293. * @param Net_DNS2_Packet &$packet the DNS packet to look in for the domain name
  294. * @param integer &$offset the offset into the given packet object
  295. *
  296. * @return mixed either the domain name or null if it's not found.
  297. * @access public
  298. *
  299. */
  300. public static function label(Net_DNS2_Packet &$packet, &$offset)
  301. {
  302. $name = '';
  303. if ($packet->rdlength < ($offset + 1)) {
  304. return null;
  305. }
  306. $xlen = ord($packet->rdata[$offset]);
  307. ++$offset;
  308. if (($xlen + $offset) > $packet->rdlength) {
  309. $name = substr($packet->rdata, $offset);
  310. $offset = $packet->rdlength;
  311. } else {
  312. $name = substr($packet->rdata, $offset, $xlen);
  313. $offset += $xlen;
  314. }
  315. return $name;
  316. }
  317. /**
  318. * copies the contents of the given packet, to the local packet object. this
  319. * function intentionally ignores some of the packet data.
  320. *
  321. * @param Net_DNS2_Packet $packet the DNS packet to copy the data from
  322. *
  323. * @return boolean
  324. * @access public
  325. *
  326. */
  327. public function copy(Net_DNS2_Packet $packet)
  328. {
  329. $this->header = $packet->header;
  330. $this->question = $packet->question;
  331. $this->answer = $packet->answer;
  332. $this->authority = $packet->authority;
  333. $this->additional = $packet->additional;
  334. return true;
  335. }
  336. /**
  337. * resets the values in the current packet object
  338. *
  339. * @return boolean
  340. * @access public
  341. *
  342. */
  343. public function reset()
  344. {
  345. $this->header->id = $this->header->nextPacketId();
  346. $this->rdata = '';
  347. $this->rdlength = 0;
  348. $this->offset = 0;
  349. $this->answer = array();
  350. $this->authority = array();
  351. $this->additional = array();
  352. $this->_compressed = array();
  353. return true;
  354. }
  355. /**
  356. * formats an IPv6 IP address in the preferred format
  357. *
  358. * @param string $address The IPv6 IP address to format
  359. *
  360. * @return string The IPv6 IP address formatted in the new format
  361. * @access public
  362. * @deprecated function deprecated in 1.1.3
  363. *
  364. */
  365. public static function formatIPv6($address)
  366. {
  367. return Net_DNS2::expandIPv6($address);
  368. }
  369. }
  370. /*
  371. * Local variables:
  372. * tab-width: 4
  373. * c-basic-offset: 4
  374. * c-hanging-comment-ender-p: nil
  375. * End:
  376. */
  377. ?>