PageRenderTime 43ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/www/devel/upgrade/upms_server/lib/pear/Net/IPv4.php

https://github.com/orchestra-io/sample-openx
PHP | 458 lines | 209 code | 40 blank | 209 comment | 46 complexity | d71c06a7ed832b90ac7dad930fd2446f MD5 | raw file
  1. <?php
  2. /**
  3. * Class to provide IPv4 calculations
  4. *
  5. * PHP versions 4 and 5
  6. *
  7. * LICENSE: This source file is subject to version 3.01 of the PHP license
  8. * that is available through the world-wide-web at the following URI:
  9. * http://www.php.net/license/3_01.txt. If you did not receive a copy of
  10. * the PHP License and are unable to obtain it through the web, please
  11. * send a note to license@php.net so we can mail you a copy immediately.
  12. *
  13. * @category Net
  14. * @package Net_IPv4
  15. * @author Eric Kilfoil <edk@ypass.net>
  16. * @author Marco Kaiser <bate@php.net>
  17. * @author Florian Anderiasch <fa@php.net>
  18. * @copyright 1997-2005 The PHP Group
  19. * @license http://www.php.net/license/3_01.txt PHP License 3.01
  20. * @version CVS: $Id: IPv4.php 18922 2008-04-16 08:56:47Z monique.szpak@openx.org $
  21. * @link http://pear.php.net/package/Net_IPv4
  22. */
  23. require_once 'PEAR.php';
  24. // {{{ GLOBALS
  25. /**
  26. * Map of bitmasks to subnets
  27. *
  28. * This array contains every valid netmask. The index of the dot quad
  29. * netmask value is the corresponding CIDR notation (bitmask).
  30. *
  31. * @global array $GLOBALS['Net_IPv4_Netmask_Map']
  32. */
  33. $GLOBALS['Net_IPv4_Netmask_Map'] = array(
  34. 0 => "0.0.0.0",
  35. 1 => "128.0.0.0",
  36. 2 => "192.0.0.0",
  37. 3 => "224.0.0.0",
  38. 4 => "240.0.0.0",
  39. 5 => "248.0.0.0",
  40. 6 => "252.0.0.0",
  41. 7 => "254.0.0.0",
  42. 8 => "255.0.0.0",
  43. 9 => "255.128.0.0",
  44. 10 => "255.192.0.0",
  45. 11 => "255.224.0.0",
  46. 12 => "255.240.0.0",
  47. 13 => "255.248.0.0",
  48. 14 => "255.252.0.0",
  49. 15 => "255.254.0.0",
  50. 16 => "255.255.0.0",
  51. 17 => "255.255.128.0",
  52. 18 => "255.255.192.0",
  53. 19 => "255.255.224.0",
  54. 20 => "255.255.240.0",
  55. 21 => "255.255.248.0",
  56. 22 => "255.255.252.0",
  57. 23 => "255.255.254.0",
  58. 24 => "255.255.255.0",
  59. 25 => "255.255.255.128",
  60. 26 => "255.255.255.192",
  61. 27 => "255.255.255.224",
  62. 28 => "255.255.255.240",
  63. 29 => "255.255.255.248",
  64. 30 => "255.255.255.252",
  65. 31 => "255.255.255.254",
  66. 32 => "255.255.255.255"
  67. );
  68. // }}}
  69. // {{{ Net_IPv4
  70. /**
  71. * Class to provide IPv4 calculations
  72. *
  73. * Provides methods for validating IP addresses, calculating netmasks,
  74. * broadcast addresses, network addresses, conversion routines, etc.
  75. *
  76. * @category Net
  77. * @package Net_IPv4
  78. * @author Eric Kilfoil <edk@ypass.net>
  79. * @author Marco Kaiser <bate@php.net>
  80. * @author Florian Anderiasch <fa@php.net>
  81. * @copyright 1997-2005 The PHP Group
  82. * @license http://www.php.net/license/3_01.txt PHP License 3.01
  83. * @version CVS: 1.3.0
  84. * @link http://pear.php.net/package/Net_IPv4
  85. * @access public
  86. */
  87. class Net_IPv4
  88. {
  89. // {{{ properties
  90. var $ip = "";
  91. var $bitmask = false;
  92. var $netmask = "";
  93. var $network = "";
  94. var $broadcast = "";
  95. var $long = 0;
  96. // }}}
  97. // {{{ validateIP()
  98. /**
  99. * Validate the syntax of the given IP adress
  100. *
  101. * Using the PHP long2ip() and ip2long() functions, convert the IP
  102. * address from a string to a long and back. If the original still
  103. * matches the converted IP address, it's a valid address. This
  104. * function does not allow for IP addresses to be formatted as long
  105. * integers.
  106. *
  107. * @param string $ip IP address in the format x.x.x.x
  108. * @return bool true if syntax is valid, otherwise false
  109. */
  110. function validateIP($ip)
  111. {
  112. if ($ip == long2ip(ip2long($ip))) {
  113. return true;
  114. } else {
  115. return false;
  116. }
  117. }
  118. // }}}
  119. // {{{ check_ip()
  120. /**
  121. * Validate the syntax of the given IP address (compatibility)
  122. *
  123. * This function is identical to Net_IPv4::validateIP(). It is included
  124. * merely for compatibility reasons.
  125. *
  126. * @param string $ip IP address
  127. * @return bool true if syntax is valid, otherwise false
  128. */
  129. function check_ip($ip)
  130. {
  131. return $this->validateIP($ip);
  132. }
  133. // }}}
  134. // {{{ validateNetmask()
  135. /**
  136. * Validate the syntax of a four octet netmask
  137. *
  138. * There are 33 valid netmask values. This function will compare the
  139. * string passed as $netmask to the predefined 33 values and return
  140. * true or false. This is most likely much faster than performing the
  141. * calculation to determine the validity of the netmask.
  142. *
  143. * @param string $netmask Netmask
  144. * @return bool true if syntax is valid, otherwise false
  145. */
  146. function validateNetmask($netmask)
  147. {
  148. if (! in_array($netmask, $GLOBALS['Net_IPv4_Netmask_Map'])) {
  149. return false;
  150. }
  151. return true;
  152. }
  153. // }}}
  154. // {{{ parseAddress()
  155. /**
  156. * Parse a formatted IP address
  157. *
  158. * Given a network qualified IP address, attempt to parse out the parts
  159. * and calculate qualities of the address.
  160. *
  161. * The following formats are possible:
  162. *
  163. * [dot quad ip]/[ bitmask ]
  164. * [dot quad ip]/[ dot quad netmask ]
  165. * [dot quad ip]/[ hex string netmask ]
  166. *
  167. * The first would be [IP Address]/[BitMask]:
  168. * 192.168.0.0/16
  169. *
  170. * The second would be [IP Address] [Subnet Mask in dot quad notation]:
  171. * 192.168.0.0/255.255.0.0
  172. *
  173. * The third would be [IP Address] [Subnet Mask as Hex string]
  174. * 192.168.0.0/ffff0000
  175. *
  176. * Usage:
  177. *
  178. * $cidr = '192.168.0.50/16';
  179. * $net = Net_IPv4::parseAddress($cidr);
  180. * echo $net->network; // 192.168.0.0
  181. * echo $net->ip; // 192.168.0.50
  182. * echo $net->broadcast; // 192.168.255.255
  183. * echo $net->bitmask; // 16
  184. * echo $net->long; // 3232235520 (long/double version of 192.168.0.50)
  185. * echo $net->netmask; // 255.255.0.0
  186. *
  187. * @param string $ip IP address netmask combination
  188. * @return object true if syntax is valid, otherwise false
  189. */
  190. function parseAddress($address)
  191. {
  192. $myself = new Net_IPv4;
  193. if (strchr($address, "/")) {
  194. $parts = explode("/", $address);
  195. if (! $myself->validateIP($parts[0])) {
  196. return PEAR::raiseError("invalid IP address");
  197. }
  198. $myself->ip = $parts[0];
  199. // Check the style of netmask that was entered
  200. /*
  201. * a hexadecimal string was entered
  202. */
  203. if (eregi("^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$", $parts[1], $regs)) {
  204. // hexadecimal string
  205. $myself->netmask = hexdec($regs[1]) . "." . hexdec($regs[2]) . "." .
  206. hexdec($regs[3]) . "." . hexdec($regs[4]);
  207. /*
  208. * a standard dot quad netmask was entered.
  209. */
  210. } else if (strchr($parts[1], ".")) {
  211. if (! $myself->validateNetmask($parts[1])) {
  212. return PEAR::raiseError("invalid netmask value");
  213. }
  214. $myself->netmask = $parts[1];
  215. /*
  216. * a CIDR bitmask type was entered
  217. */
  218. } else if ($parts[1] >= 0 && $parts[1] <= 32) {
  219. // bitmask was entered
  220. $myself->bitmask = $parts[1];
  221. /*
  222. * Some unknown format of netmask was entered
  223. */
  224. } else {
  225. return PEAR::raiseError("invalid netmask value");
  226. }
  227. $myself->calculate();
  228. return $myself;
  229. } else if ($myself->validateIP($address)) {
  230. $myself->ip = $address;
  231. return $myself;
  232. } else {
  233. return PEAR::raiseError("invalid IP address");
  234. }
  235. }
  236. // }}}
  237. // {{{ calculate()
  238. /**
  239. * Calculates network information based on an IP address and netmask.
  240. *
  241. * Fully populates the object properties based on the IP address and
  242. * netmask/bitmask properties. Once these two fields are populated,
  243. * calculate() will perform calculations to determine the network and
  244. * broadcast address of the network.
  245. *
  246. * @return mixed true if no errors occured, otherwise PEAR_Error object
  247. */
  248. function calculate()
  249. {
  250. $validNM = $GLOBALS['Net_IPv4_Netmask_Map'];
  251. if (! is_a($this, "net_ipv4")) {
  252. $myself = new Net_IPv4;
  253. return PEAR::raiseError("cannot calculate on uninstantiated Net_IPv4 class");
  254. }
  255. /* Find out if we were given an ip address in dot quad notation or
  256. * a network long ip address. Whichever was given, populate the
  257. * other field
  258. */
  259. if (strlen($this->ip)) {
  260. if (! $this->validateIP($this->ip)) {
  261. return PEAR::raiseError("invalid IP address");
  262. }
  263. $this->long = $this->ip2double($this->ip);
  264. } else if (is_numeric($this->long)) {
  265. $this->ip = long2ip($this->long);
  266. } else {
  267. return PEAR::raiseError("ip address not specified");
  268. }
  269. /*
  270. * Check to see if we were supplied with a bitmask or a netmask.
  271. * Populate the other field as needed.
  272. */
  273. if (strlen($this->bitmask)) {
  274. $this->netmask = $validNM[$this->bitmask];
  275. } else if (strlen($this->netmask)) {
  276. $validNM_rev = array_flip($validNM);
  277. $this->bitmask = $validNM_rev[$this->netmask];
  278. } else {
  279. return PEAR::raiseError("netmask or bitmask are required for calculation");
  280. }
  281. $this->network = long2ip(ip2long($this->ip) & ip2long($this->netmask));
  282. $this->broadcast = long2ip(ip2long($this->ip) |
  283. (ip2long($this->netmask) ^ ip2long("255.255.255.255")));
  284. return true;
  285. }
  286. // }}}
  287. // {{{ getNetmask()
  288. function getNetmask($length)
  289. {
  290. if (! PEAR::isError($ipobj = Net_IPv4::parseAddress("0.0.0.0/" . $length))) {
  291. $mask = $ipobj->netmask;
  292. unset($ipobj);
  293. return $mask;
  294. }
  295. return false;
  296. }
  297. // }}}
  298. // {{{ getNetLength()
  299. function getNetLength($netmask)
  300. {
  301. if (! PEAR::isError($ipobj = Net_IPv4::parseAddress("0.0.0.0/" . $netmask))) {
  302. $bitmask = $ipobj->bitmask;
  303. unset($ipobj);
  304. return $bitmask;
  305. }
  306. return false;
  307. }
  308. // }}}
  309. // {{{ getSubnet()
  310. function getSubnet($ip, $netmask)
  311. {
  312. if (! PEAR::isError($ipobj = Net_IPv4::parseAddress($ip . "/" . $netmask))) {
  313. $net = $ipobj->network;
  314. unset($ipobj);
  315. return $net;
  316. }
  317. return false;
  318. }
  319. // }}}
  320. // {{{ inSameSubnet()
  321. function inSameSubnet($ip1, $ip2)
  322. {
  323. if (! is_object($ip1) || strcasecmp(get_class($ip1), 'net_ipv4') <> 0) {
  324. $ipobj1 = Net_IPv4::parseAddress($ip1);
  325. if (PEAR::isError($ipobj)) {
  326. return PEAR::raiseError("IP addresses must be an understood format or a Net_IPv4 object");
  327. }
  328. }
  329. if (! is_object($ip2) || strcasecmp(get_class($ip2), 'net_ipv4') <> 0) {
  330. $ipobj2 = Net_IPv4::parseAddress($ip2);
  331. if (PEAR::isError($ipobj)) {
  332. return PEAR::raiseError("IP addresses must be an understood format or a Net_IPv4 object");
  333. }
  334. }
  335. if ($ipobj1->network == $ipobj2->network &&
  336. $ipobj1->bitmask == $ipobj2->bitmask) {
  337. return true;
  338. }
  339. return false;
  340. }
  341. // }}}
  342. // {{{ atoh()
  343. /**
  344. * Converts a dot-quad formatted IP address into a hexadecimal string
  345. * @param string $addr IP-adress in dot-quad format
  346. * @return mixed false if invalid IP and hexadecimal representation as string if valid
  347. */
  348. function atoh($addr)
  349. {
  350. if (! Net_IPv4::validateIP($addr)) {
  351. return false;
  352. }
  353. $ap = explode(".", $addr);
  354. return sprintf("%02x%02x%02x%02x", $ap[0], $ap[1], $ap[2], $ap[3]);
  355. }
  356. // }}}
  357. // {{{ htoa()
  358. /**
  359. * Converts a hexadecimal string into a dot-quad formatted IP address
  360. * @param string $addr IP-adress in hexadecimal format
  361. * @return mixed false if invalid IP and dot-quad formatted IP as string if valid
  362. */
  363. function htoa($addr)
  364. {
  365. if (eregi("^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$",
  366. $addr, $regs)) {
  367. return hexdec($regs[1]) . "." . hexdec($regs[2]) . "." .
  368. hexdec($regs[3]) . "." . hexdec($regs[4]);
  369. }
  370. return false;
  371. }
  372. // }}}
  373. // {{{ ip2double()
  374. /**
  375. * Converts an IP address to a PHP double. Better than ip2long because
  376. * a long in PHP is a signed integer.
  377. * @param string $ip dot-quad formatted IP adress
  378. * @return float IP adress as double - positive value unlike ip2long
  379. */
  380. function ip2double($ip)
  381. {
  382. return (double)(sprintf("%u", ip2long($ip)));
  383. }
  384. // }}}
  385. // {{{ ipInNetwork()
  386. /**
  387. * Determines whether or not the supplied IP is within the supplied network.
  388. *
  389. * This function determines whether an IP address is within a network.
  390. * The IP address ($ip) must be supplied in dot-quad format, and the
  391. * network ($network) may be either a string containing a CIDR
  392. * formatted network definition, or a Net_IPv4 object.
  393. *
  394. * @param string $ip A dot quad representation of an IP address
  395. * @param string $network A string representing the network in CIDR format or a Net_IPv4 object.
  396. * @return bool true if the IP address exists within the network
  397. */
  398. function ipInNetwork($ip, $network)
  399. {
  400. if (! is_object($network) || strcasecmp(get_class($network), 'net_ipv4') <> 0) {
  401. $network = Net_IPv4::parseAddress($network);
  402. }
  403. $net = Net_IPv4::ip2double($network->network);
  404. $bcast = Net_IPv4::ip2double($network->broadcast);
  405. $ip = Net_IPv4::ip2double($ip);
  406. unset($network);
  407. if ($ip >= $net && $ip <= $bcast) {
  408. return true;
  409. }
  410. return false;
  411. }
  412. // }}}
  413. }
  414. // }}}
  415. /*
  416. * vim: sts=4 ts=4 sw=4 cindent fdm=marker
  417. */
  418. ?>