Newer
Older
NetAddr-IP / Lite / Util / README
  1. NAME
  2. NetAddr::IP::Util -- IPv4/6 and 128 bit number utilities
  3.  
  4. SYNOPSIS
  5. use NetAddr::IP::Util qw(
  6. inet_aton
  7. inet_ntoa
  8. ipv6_aton
  9. ipv6_n2x
  10. ipv6_n2d
  11. inet_any2n
  12. hasbits
  13. isIPv4
  14. inet_n2dx
  15. inet_n2ad
  16. ipv4to6
  17. mask4to6
  18. ipanyto6
  19. maskanyto6
  20. ipv6to4
  21. shiftleft
  22. addconst
  23. add128
  24. sub128
  25. notcontiguous
  26. bin2bcd
  27. bcd2bin
  28. mode
  29. );
  30.  
  31. use NetAddr::IP::Util qw(:all :inet :ipv4 :ipv6 :math)
  32.  
  33. :inet => inet_aton, inet_ntoa, ipv6_aton,
  34. ipv6_n2x, ipv6_n2d, inet_any2n,
  35. inet_n2dx, inet_n2ad, ipv4to6,
  36. mask4to6, ipanyto6, maskanyto6,
  37. ipv6to4
  38.  
  39. :ipv4 => inet_aton, inet_ntoa
  40.  
  41. :ipv6 => ipv6_aton, ipv6_n2x, ipv6_n2d,
  42. inet_any2n, inet_n2dx, inet_n2ad
  43. ipv4to6, mask4to6, ipanyto6,
  44. maskanyto6, ipv6to4
  45.  
  46. :math => hasbits, isIPv4, addconst,
  47. add128, sub128, notcontiguous,
  48. bin2bcd, bcd2bin, shiftleft
  49.  
  50. $dotquad = inet_ntoa($netaddr);
  51. $netaddr = inet_aton($dotquad);
  52. $ipv6naddr = ipv6_aton($ipv6_text);
  53. $hex_text = ipv6_n2x($ipv6naddr);
  54. $dec_text = ipv6_n2d($ipv6naddr);
  55. $ipv6naddr = inet_any2n($dotquad or $ipv6_text);
  56. $rv = hasbits($bits128);
  57. $rv = isIPv4($bits128);
  58. $dotquad or $hex_text = inet_n2dx($ipv6naddr);
  59. $dotquad or $dec_text = inet_n2ad($ipv6naddr);
  60. $ipv6naddr = ipv4to6($netaddr);
  61. $ipv6naddr = mask4to6($netaddr);
  62. $ipv6naddr = ipanyto6($netaddr);
  63. $ipv6naddr = maskanyto6($netaddr);
  64. $netaddr = ipv6to4($pv6naddr);
  65. $bitsX2 = shiftleft($bits128,$n);
  66. $carry = addconst($ipv6naddr,$signed_32con);
  67. ($carry,$ipv6naddr)=addconst($ipv6naddr,$signed_32con);
  68. $carry = add128($ipv6naddr1,$ipv6naddr2);
  69. ($carry,$ipv6naddr)=add128($ipv6naddr1,$ipv6naddr2);
  70. $carry = sub128($ipv6naddr1,$ipv6naddr2);
  71. ($carry,$ipv6naddr)=sub128($ipv6naddr1,$ipv6naddr2);
  72. ($spurious,$cidr) = notcontiguous($mask128);
  73. $bcdtext = bin2bcd($bits128);
  74. $bits128 = bcd2bin($bcdtxt);
  75. $modetext = mode;
  76.  
  77. INSTALLATION
  78. Un-tar the distribution in an appropriate directory and type:
  79.  
  80. perl Makefile.PL
  81. make
  82. make test
  83. make install
  84.  
  85. NetAddr::IP::Util installs by default with its primary functions
  86. compiled using Perl's XS extensions to build a 'C' library. If you do
  87. not have a 'C' complier available or would like the slower Pure Perl
  88. version for some other reason, then type:
  89.  
  90. perl Makefile.PL -noxs
  91. make
  92. make test
  93. make install
  94.  
  95. DESCRIPTION
  96. NetAddr::IP::Util provides a suite of tools for manipulating and
  97. converting IPv4 and IPv6 addresses into 128 bit string context and back
  98. to text. The strings can be manipulated with Perl's logical operators:
  99.  
  100. and &
  101. or |
  102. xor ^
  103.  
  104. in the same manner as 'vec' strings.
  105.  
  106. The IPv6 functions support all rfc1884 formats.
  107.  
  108. i.e. x:x:x:x:x:x:x:x:x
  109. x:x:x:x:x:x:x:d.d.d.d
  110. ::x:x:x
  111. ::x:d.d.d.d
  112. and so on...
  113.  
  114. * $dotquad = inet_ntoa($netaddr);
  115. Convert a packed IPv4 network address to a dot-quad IP address.
  116.  
  117. input: packed network address
  118. returns: IP address i.e. 10.4.12.123
  119.  
  120. * $netaddr = inet_aton($dotquad);
  121. Convert a dot-quad IP address into an IPv4 packed network address.
  122.  
  123. input: IP address i.e. 192.5.16.32
  124. returns: packed network address
  125.  
  126. * $ipv6addr = ipv6_aton($ipv6_text);
  127. Takes an IPv6 address of the form described in rfc1884 and returns a
  128. 128 bit binary RDATA string.
  129.  
  130. input: ipv6 text
  131. returns: 128 bit RDATA string
  132.  
  133. * $hex_text = ipv6_n2x($ipv6addr);
  134. Takes an IPv6 RDATA string and returns an 8 segment IPv6 hex address
  135.  
  136. input: 128 bit RDATA string
  137. returns: x:x:x:x:x:x:x:x
  138.  
  139. * $dec_text = ipv6_n2d($ipv6addr);
  140. Takes an IPv6 RDATA string and returns a mixed hex - decimal IPv6
  141. address with the 6 uppermost chunks in hex and the lower 32 bits in
  142. dot-quad representation.
  143.  
  144. input: 128 bit RDATA string
  145. returns: x:x:x:x:x:x:d.d.d.d
  146.  
  147. * $ipv6naddr = inet_any2n($dotquad or $ipv6_text);
  148. This function converts a text IPv4 or IPv6 address in text format in
  149. any standard notation into a 128 bit IPv6 string address. It
  150. prefixes any dot-quad address (if found) with '::' and passes it to
  151. ipv6_aton.
  152.  
  153. input: dot-quad or rfc1844 address
  154. returns: 128 bit IPv6 string
  155.  
  156. * $rv = hasbits($bits128);
  157. This function returns true if there are one's present in the 128 bit
  158. string and false if all the bits are zero.
  159.  
  160. i.e. if (hasbits($bits128)) {
  161. &do_something;
  162. }
  163.  
  164. or if (hasbits($bits128 & $mask128) {
  165. &do_something;
  166. }
  167.  
  168. This allows the implementation of logical functions of the form of:
  169.  
  170. if ($bits128 & $mask128) {
  171. ...
  172.  
  173. input: 128 bit IPv6 string
  174. returns: true if any bits are present
  175.  
  176. * $rv = isIPv4($bits128);
  177. This function returns true if there are no on bits present in the
  178. IPv6 portion of the 128 bit string and false otherwise.
  179.  
  180. * $dotquad or $hex_text = inet_n2dx($ipv6naddr);
  181. This function does the right thing and returns the text for either a
  182. dot-quad IPv4 or a hex notation IPv6 address.
  183.  
  184. input: 128 bit IPv6 string
  185. returns: ddd.ddd.ddd.ddd
  186. or x:x:x:x:x:x:x:x
  187.  
  188. * $dotquad or $dec_text = inet_n2ad($ipv6naddr);
  189. This function does the right thing and returns the text for either a
  190. dot-quad IPv4 or a hex::decimal notation IPv6 address.
  191.  
  192. input: 128 bit IPv6 string
  193. returns: ddd.ddd.ddd.ddd
  194. or x:x:x:x:x:x:ddd.ddd.ddd.dd
  195.  
  196. * $ipv6naddr = ipv4to6($netaddr);
  197. Convert an ipv4 network address into an ipv6 network address.
  198.  
  199. input: 32 bit network address
  200. returns: 128 bit network address
  201.  
  202. * $ipv6naddr = mask4to6($netaddr);
  203. Convert an ipv4 network address/mask into an ipv6 network mask.
  204.  
  205. input: 32 bit network/mask address
  206. returns: 128 bit network/mask address
  207.  
  208. NOTE: returns the high 96 bits as one's
  209.  
  210. * $ipv6naddr = ipanyto6($netaddr);
  211. Similar to ipv4to6 except that this function takes either an IPv4 or
  212. IPv6 input and always returns a 128 bit IPv6 network address.
  213.  
  214. input: 32 or 128 bit network address
  215. returns: 128 bit network address
  216.  
  217. * $ipv6naddr = maskanyto6($netaddr);
  218. Similar to mask4to6 except that this function takes either an IPv4
  219. or IPv6 netmask and always returns a 128 bit IPv6 netmask.
  220.  
  221. input: 32 or 128 bit network mask
  222. returns: 128 bit network mask
  223.  
  224. * $netaddr = ipv6to4($pv6naddr);
  225. Truncate the upper 96 bits of a 128 bit address and return the lower
  226. 32 bits. Returns an IPv4 address as returned by inet_aton.
  227.  
  228. input: 128 bit network address
  229. returns: 32 bit inet_aton network address
  230.  
  231. * $bitsXn = shiftleft($bits128,$n);
  232. input: 128 bit string variable,
  233. number of shifts [optional]
  234. returns: bits X n shifts
  235.  
  236. NOTE: a single shift is performed
  237. if $n is not specified
  238.  
  239. * addconst($ipv6naddr,$signed_32con);
  240. Add a signed constant to a 128 bit string variable.
  241.  
  242. input: 128 bit IPv6 string,
  243. signed 32 bit integer
  244. returns: scalar carry
  245. array (carry, result)
  246.  
  247. * add128($ipv6naddr1,$ipv6naddr2);
  248. Add two 128 bit string variables.
  249.  
  250. input: 128 bit string var1,
  251. 128 bit string var2
  252. returns: scalar carry
  253. array (carry, result)
  254.  
  255. * sub128($ipv6naddr1,$ipv6naddr2);
  256. Subtract two 128 bit string variables.
  257.  
  258. input: 128 bit string var1,
  259. 128 bit string var2
  260. returns: scalar carry
  261. array (carry, result)
  262. Note: The carry from this operation is the result of adding the
  263. one's complement of ARG2 +1 to the ARG1. It is logically NOT borrow.
  264.  
  265. i.e. if ARG1 >= ARG2 then carry = 1
  266. or if ARG1 < ARG2 then carry = 0
  267.  
  268. * ($spurious,$cidr) = notcontiguous($mask128);
  269. This function counts the bit positions remaining in the mask when
  270. the rightmost '0's are removed.
  271.  
  272. input: 128 bit netmask
  273. returns true if there are spurious
  274. zero bits remaining in the
  275. mask, false if the mask is
  276. contiguous one's,
  277. 128 bit cidr number
  278.  
  279. * $bcdtext = bin2bcd($bits128);
  280. Convert a 128 bit binary string into binary coded decimal text
  281. digits.
  282.  
  283. input: 128 bit string variable
  284. returns: string of bcd text digits
  285.  
  286. * $bits128 = bcd2bin($bcdtxt);
  287. Convert a bcd text string to 128 bit string variable
  288.  
  289. input: string of bcd text digits
  290. returns: 128 bit string variable
  291.  
  292. * $modetext = mode;
  293. Returns the operating mode of this module.
  294.  
  295. input: none
  296. returns: "Pure Perl"
  297. or "CC XS"
  298.  
  299. EXAMPLES
  300. # convert any textual IP address into a 128 bit vector
  301. #
  302. sub text2vec {
  303. my($anyIP,$anyMask) = @_;
  304.  
  305. # not IPv4 bit mask
  306. my $notiv4 = ipv6_aton('FFFF:FFFF:FFFF:FFFF:FFFF:FFFF::');
  307.  
  308. my $vecip = inet_any2n($anyIP);
  309. my $mask = inet_any2n($anyMask);
  310.  
  311. # extend mask bits for IPv4
  312. my $bits = 128; # default
  313. unless (hasbits($mask & $notiv4)) {
  314. $mask |= $notiv4;
  315. $bits = 32;
  316. }
  317. return ($vecip, $mask, $bits);
  318. }
  319.  
  320. ... alternate implementation, a little faster
  321.  
  322. sub text2vec {
  323. my($anyIP,$anyMask) = @_;
  324.  
  325. # not IPv4 bit mask
  326. my $notiv4 = ipv6_aton('FFFF:FFFF:FFFF:FFFF:FFFF:FFFF::');
  327.  
  328. my $vecip = inet_any2n($anyIP);
  329. my $mask = inet_any2n($anyMask);
  330.  
  331. # extend mask bits for IPv4
  332. my $bits = 128; # default
  333. if (isIPv4($mask)) {
  334. $mask |= $notiv4;
  335. $bits = 32;
  336. }
  337. return ($vecip, $mask, $bits);
  338. }
  339.  
  340. ... elsewhere
  341. $nip = {
  342. addr => $vecip,
  343. mask => $mask,
  344. bits => $bits,
  345. };
  346.  
  347. # return network and broadcast addresses from IP and Mask
  348. #
  349. sub netbroad {
  350. my($nip) = shift;
  351. my $notmask = ~ $nip->{mask};
  352. my $bcast = $nip->{addr} | $notmask;
  353. my $network = $nip->{addr} & $nip->{mask};
  354. return ($network, $broadcast);
  355. }
  356.  
  357. # check if address is within a network
  358. #
  359. sub within {
  360. my($nip,$net) = @_;
  361. my $addr = $nip->{addr}
  362. my($nw,$bc) = netbroad($net);
  363. # arg1 >= arg2, sub128 returns true
  364. return (sub128($addr,$nw) && sub128($bc,$addr))
  365. ? 1 : 0;
  366. }
  367.  
  368. # add a constant, wrapping at netblock boundries
  369. # to subtract the constant, negate it before calling
  370. # 'addwrap' since 'addconst' will extend the sign bits
  371. #
  372. sub addwrap {
  373. my($nip,$const) = @_;
  374. my $mask = $nip->{addr};
  375. my $bits = $nip->{bits};
  376. my $notmask = ~ $mask;
  377. my $hibits = $addr & $mask;
  378. my $addr = addconst($addr,$const);
  379. my $wraponly = $addr & $notmask;
  380. my $newip = {
  381. addr => $hibits | $wraponly,
  382. mask => $mask,
  383. bits => $bits,
  384. };
  385. # bless $newip as appropriate
  386. return $newip;
  387. }
  388. EXPORT_OK
  389. inet_aton
  390. inet_ntoa
  391. ipv6_aton
  392. ipv6_n2x
  393. ipv6_n2d
  394. inet_any2n
  395. hasbits
  396. isIPv4
  397. inet_n2dx
  398. inet_n2ad
  399. ipv4to6
  400. mask4to6
  401. ipanyto6
  402. maskanyto6
  403. ipv6to4
  404. shiftleft
  405. addconst
  406. add128
  407. sub128
  408. notcontiguous
  409. bin2bcd
  410. bcd2bin
  411. mode
  412.  
  413. AUTHOR
  414. Michael Robinton <michael@bizsystems.com>
  415.  
  416. ACKNOWLEDGEMENTS
  417. The following functions are used in whole or in part as include files to
  418. Util.xs. The copyright is include in the file.
  419.  
  420. file: function:
  421.  
  422. miniSocket.inc inet_aton, inet_ntoa
  423.  
  424. inet_aton, inet_ntoa are from the perl-5.8.0 release by Larry Wall,
  425. copyright 1989-2002. inet_aton, inet_ntoa code is current through
  426. perl-5.9.3 release. Thank you Larry for making PERL possible for all of
  427. us.
  428.  
  429. COPYRIGHT
  430. Copyright 2003 - 2006, Michael Robinton <michael@bizsystems.com>
  431.  
  432. LICENSE AND WARRANTY
  433.  
  434. This software is (c) Michael Robinton. It can be used under the terms of
  435. the perl artistic license provided that proper credit for the work of
  436. the author is preserved in the form of this copyright notice and license
  437. for this module.
  438.  
  439. No warranty of any kind is expressed or implied, by using it you accept
  440. any and all the liability.
  441.  
  442. AUTHOR
  443. Michael Robinton <michael@bizsystems.com>
  444.