Newer
Older
NetAddr-IP / Lite / Util / README
@Michael Robinton Michael Robinton on 21 Oct 2014 19 KB Import of MIKER/NetAddr-IP-4.049 from CPAN.
  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_ntoa
  10. ipv6_n2x
  11. ipv6_n2d
  12. inet_any2n
  13. hasbits
  14. isIPv4
  15. isNewIPv4
  16. isAnyIPv4
  17. inet_n2dx
  18. inet_n2ad
  19. inet_pton
  20. inet_ntop
  21. inet_4map6
  22. ipv4to6
  23. mask4to6
  24. ipanyto6
  25. maskanyto6
  26. ipv6to4
  27. packzeros
  28. shiftleft
  29. addconst
  30. add128
  31. sub128
  32. notcontiguous
  33. bin2bcd
  34. bcd2bin
  35. mode
  36. AF_INET
  37. AF_INET6
  38. naip_gethostbyname
  39. );
  40.  
  41. use NetAddr::IP::Util qw(:all :inet :ipv4 :ipv6 :math)
  42.  
  43. :inet => inet_aton, inet_ntoa, ipv6_aton
  44. ipv6_ntoa, ipv6_n2x, ipv6_n2d,
  45. inet_any2n, inet_n2dx, inet_n2ad,
  46. inet_pton, inet_ntop, inet_4map6,
  47. ipv4to6, mask4to6, ipanyto6, packzeros
  48. maskanyto6, ipv6to4, naip_gethostbyname
  49.  
  50. :ipv4 => inet_aton, inet_ntoa
  51.  
  52. :ipv6 => ipv6_aton, ipv6_ntoa, ipv6_n2x,
  53. ipv6_n2d, inet_any2n, inet_n2dx,
  54. inet_n2ad, inet_pton, inet_ntop,
  55. inet_4map6, ipv4to6, mask4to6,
  56. ipanyto6, maskanyto6, ipv6to4,
  57. packzeros, naip_gethostbyname
  58.  
  59. :math => hasbits, isIPv4, isNewIPv4, isAnyIPv4,
  60. addconst, add128, sub128, notcontiguous,
  61. bin2bcd, bcd2bin, shiftleft
  62.  
  63. $dotquad = inet_ntoa($netaddr);
  64. $netaddr = inet_aton($dotquad);
  65. $ipv6naddr = ipv6_aton($ipv6_text);
  66. $ipv6_text = ipvt_ntoa($ipv6naddr);
  67. $hex_text = ipv6_n2x($ipv6naddr);
  68. $dec_text = ipv6_n2d($ipv6naddr);
  69. $hex_text = packzeros($hex_text);
  70. $ipv6naddr = inet_any2n($dotquad or $ipv6_text);
  71. $ipv6naddr = inet_4map6($netaddr or $ipv6naddr);
  72. $rv = hasbits($bits128);
  73. $rv = isIPv4($bits128);
  74. $rv = isNewIPv4($bits128);
  75. $rv = isAnyIPv4($bits128);
  76. $dotquad or $hex_text = inet_n2dx($ipv6naddr);
  77. $dotquad or $dec_text = inet_n2ad($ipv6naddr);
  78. $netaddr = inet_pton($AF_family,$hex_text);
  79. $hex_text = inet_ntop($AF_family,$netaddr);
  80. $ipv6naddr = ipv4to6($netaddr);
  81. $ipv6naddr = mask4to6($netaddr);
  82. $ipv6naddr = ipanyto6($netaddr);
  83. $ipv6naddr = maskanyto6($netaddr);
  84. $netaddr = ipv6to4($pv6naddr);
  85. $bitsX2 = shiftleft($bits128,$n);
  86. $carry = addconst($ipv6naddr,$signed_32con);
  87. ($carry,$ipv6naddr)=addconst($ipv6naddr,$signed_32con);
  88. $carry = add128($ipv6naddr1,$ipv6naddr2);
  89. ($carry,$ipv6naddr)=add128($ipv6naddr1,$ipv6naddr2);
  90. $carry = sub128($ipv6naddr1,$ipv6naddr2);
  91. ($carry,$ipv6naddr)=sub128($ipv6naddr1,$ipv6naddr2);
  92. ($spurious,$cidr) = notcontiguous($mask128);
  93. $bcdtext = bin2bcd($bits128);
  94. $bits128 = bcd2bin($bcdtxt);
  95. $modetext = mode;
  96. ($name,$aliases,$addrtype,$length,@addrs)=naip_gethostbyname(NAME);
  97. $trueif = havegethostbyname2();
  98.  
  99. NetAddr::IP::Util::lower();
  100. NetAddr::IP::Util::upper();
  101.  
  102. INSTALLATION
  103. Un-tar the distribution in an appropriate directory and type:
  104.  
  105. perl Makefile.PL
  106. make
  107. make test
  108. make install
  109.  
  110. NetAddr::IP::Util installs by default with its primary functions
  111. compiled using Perl's XS extensions to build a 'C' library. If you do
  112. not have a 'C' complier available or would like the slower Pure Perl
  113. version for some other reason, then type:
  114.  
  115. perl Makefile.PL -noxs
  116. make
  117. make test
  118. make install
  119.  
  120. DESCRIPTION
  121. NetAddr::IP::Util provides a suite of tools for manipulating and
  122. converting IPv4 and IPv6 addresses into 128 bit string context and back
  123. to text. The strings can be manipulated with Perl's logical operators:
  124.  
  125. and &
  126. or |
  127. xor ^
  128. ~ compliment
  129.  
  130. in the same manner as 'vec' strings.
  131.  
  132. The IPv6 functions support all rfc1884 formats.
  133.  
  134. i.e. x:x:x:x:x:x:x:x:x
  135. x:x:x:x:x:x:x:d.d.d.d
  136. ::x:x:x
  137. ::x:d.d.d.d
  138. and so on...
  139.  
  140. * $dotquad = inet_ntoa($netaddr);
  141. Convert a packed IPv4 network address to a dot-quad IP address.
  142.  
  143. input: packed network address
  144. returns: IP address i.e. 10.4.12.123
  145.  
  146. * $netaddr = inet_aton($dotquad);
  147. Convert a dot-quad IP address into an IPv4 packed network address.
  148.  
  149. input: IP address i.e. 192.5.16.32
  150. returns: packed network address
  151.  
  152. * $ipv6addr = ipv6_aton($ipv6_text);
  153. Takes an IPv6 address of the form described in rfc1884 and returns a
  154. 128 bit binary RDATA string.
  155.  
  156. input: ipv6 text
  157. returns: 128 bit RDATA string
  158.  
  159. * $ipv6_text = ipv6_ntoa($ipv6naddr);
  160. Convert a 128 bit binary IPv6 address to compressed rfc 1884 text
  161. representation.
  162.  
  163. input: 128 bit RDATA string
  164. returns: ipv6 text
  165.  
  166. * $hex_text = ipv6_n2x($ipv6addr);
  167. Takes an IPv6 RDATA string and returns an 8 segment IPv6 hex address
  168.  
  169. input: 128 bit RDATA string
  170. returns: x:x:x:x:x:x:x:x
  171.  
  172. * $dec_text = ipv6_n2d($ipv6addr);
  173. Takes an IPv6 RDATA string and returns a mixed hex - decimal IPv6
  174. address with the 6 uppermost chunks in hex and the lower 32 bits in
  175. dot-quad representation.
  176.  
  177. input: 128 bit RDATA string
  178. returns: x:x:x:x:x:x:d.d.d.d
  179.  
  180. * $ipv6naddr = inet_any2n($dotquad or $ipv6_text);
  181. This function converts a text IPv4 or IPv6 address in text format in
  182. any standard notation into a 128 bit IPv6 string address. It
  183. prefixes any dot-quad address (if found) with '::' and passes it to
  184. ipv6_aton.
  185.  
  186. input: dot-quad or rfc1844 address
  187. returns: 128 bit IPv6 string
  188.  
  189. * $rv = hasbits($bits128);
  190. This function returns true if there are one's present in the 128 bit
  191. string and false if all the bits are zero.
  192.  
  193. i.e. if (hasbits($bits128)) {
  194. &do_something;
  195. }
  196.  
  197. or if (hasbits($bits128 & $mask128) {
  198. &do_something;
  199. }
  200.  
  201. This allows the implementation of logical functions of the form of:
  202.  
  203. if ($bits128 & $mask128) {
  204. ...
  205.  
  206. input: 128 bit IPv6 string
  207. returns: true if any bits are present
  208.  
  209. * $ipv6naddr = inet_4map6($netaddr or $ipv6naddr
  210. This function returns an ipV6 network address with the first 80 bits
  211. set to zero and the next 16 bits set to one, while the last 32 bits
  212. are filled with the ipV4 address.
  213.  
  214. input: ipV4 netaddr
  215. or ipV6 netaddr
  216. returns: ipV6 netaddr
  217.  
  218. returns: undef on error
  219.  
  220. An ipV6 network address must be in one of the two compatible ipV4
  221. mapped address spaces. i.e.
  222.  
  223. ::ffff::d.d.d.d or ::d.d.d.d
  224.  
  225. * $rv = isIPv4($bits128);
  226. This function returns true if there are no on bits present in the
  227. IPv6 portion of the 128 bit string and false otherwise.
  228.  
  229. i.e. the address must be of the form - ::d.d.d.d
  230.  
  231. Note: this is an old and deprecated ipV4 compatible ipV6 address
  232.  
  233. * $rv = isNewIPv4($bits128);
  234. This function return true if the IPv6 128 bit string is of the form
  235.  
  236. ::ffff::d.d.d.d
  237.  
  238. * $rv = isAnyIPv4($bits128);
  239. This function return true if the IPv6 bit string is of the form
  240.  
  241. ::d.d.d.d or ::ffff::d.d.d.d
  242.  
  243. * $dotquad or $hex_text = inet_n2dx($ipv6naddr);
  244. This function does the right thing and returns the text for either a
  245. dot-quad IPv4 or a hex notation IPv6 address.
  246.  
  247. input: 128 bit IPv6 string
  248. returns: ddd.ddd.ddd.ddd
  249. or x:x:x:x:x:x:x:x
  250.  
  251. * $dotquad or $dec_text = inet_n2ad($ipv6naddr);
  252. This function does the right thing and returns the text for either a
  253. dot-quad IPv4 or a hex::decimal notation IPv6 address.
  254.  
  255. input: 128 bit IPv6 string
  256. returns: ddd.ddd.ddd.ddd
  257. or x:x:x:x:x:x:ddd.ddd.ddd.dd
  258.  
  259. * $netaddr = inet_pton($AF_family,$hex_text);
  260. This function takes an IP address in IPv4 or IPv6 text format and
  261. converts it into binary format. The type of IP address conversion is
  262. controlled by the FAMILY argument.
  263.  
  264. * $hex_text = inet_ntop($AF_family,$netaddr);
  265. This function takes and IP address in binary format and converts it
  266. into text format. The type of IP address conversion is controlled by
  267. the FAMILY argument.
  268.  
  269. NOTE: inet_ntop ALWAYS returns lowercase characters.
  270.  
  271. * $hex_text = packzeros($hex_text);
  272. This function optimizes and rfc 1884 IPv6 hex address to reduce the
  273. number of long strings of zero bits as specified in rfc 1884, 2.2
  274. (2) by substituting :: for the first occurence of the longest string
  275. of zeros in the address.
  276.  
  277. * $ipv6naddr = ipv4to6($netaddr);
  278. Convert an ipv4 network address into an IPv6 network address.
  279.  
  280. input: 32 bit network address
  281. returns: 128 bit network address
  282.  
  283. * $ipv6naddr = mask4to6($netaddr);
  284. Convert an ipv4 network address/mask into an ipv6 network mask.
  285.  
  286. input: 32 bit network/mask address
  287. returns: 128 bit network/mask address
  288.  
  289. NOTE: returns the high 96 bits as one's
  290.  
  291. * $ipv6naddr = ipanyto6($netaddr);
  292. Similar to ipv4to6 except that this function takes either an IPv4 or
  293. IPv6 input and always returns a 128 bit IPv6 network address.
  294.  
  295. input: 32 or 128 bit network address
  296. returns: 128 bit network address
  297.  
  298. * $ipv6naddr = maskanyto6($netaddr);
  299. Similar to mask4to6 except that this function takes either an IPv4
  300. or IPv6 netmask and always returns a 128 bit IPv6 netmask.
  301.  
  302. input: 32 or 128 bit network mask
  303. returns: 128 bit network mask
  304.  
  305. * $netaddr = ipv6to4($pv6naddr);
  306. Truncate the upper 96 bits of a 128 bit address and return the lower
  307. 32 bits. Returns an IPv4 address as returned by inet_aton.
  308.  
  309. input: 128 bit network address
  310. returns: 32 bit inet_aton network address
  311.  
  312. * $bitsXn = shiftleft($bits128,$n);
  313. input: 128 bit string variable,
  314. number of shifts [optional]
  315. returns: bits X n shifts
  316.  
  317. NOTE: a single shift is performed
  318. if $n is not specified
  319.  
  320. * addconst($ipv6naddr,$signed_32con);
  321. Add a signed constant to a 128 bit string variable.
  322.  
  323. input: 128 bit IPv6 string,
  324. signed 32 bit integer
  325. returns: scalar carry
  326. array (carry, result)
  327.  
  328. * add128($ipv6naddr1,$ipv6naddr2);
  329. Add two 128 bit string variables.
  330.  
  331. input: 128 bit string var1,
  332. 128 bit string var2
  333. returns: scalar carry
  334. array (carry, result)
  335.  
  336. * sub128($ipv6naddr1,$ipv6naddr2);
  337. Subtract two 128 bit string variables.
  338.  
  339. input: 128 bit string var1,
  340. 128 bit string var2
  341. returns: scalar carry
  342. array (carry, result)
  343.  
  344. Note: The carry from this operation is the result of adding the
  345. one's complement of ARG2 +1 to the ARG1. It is logically NOT borrow.
  346.  
  347. i.e. if ARG1 >= ARG2 then carry = 1
  348. or if ARG1 < ARG2 then carry = 0
  349.  
  350. * ($spurious,$cidr) = notcontiguous($mask128);
  351. This function counts the bit positions remaining in the mask when
  352. the rightmost '0's are removed.
  353.  
  354. input: 128 bit netmask
  355. returns true if there are spurious
  356. zero bits remaining in the
  357. mask, false if the mask is
  358. contiguous one's,
  359. 128 bit cidr number
  360.  
  361. * $bcdtext = bin2bcd($bits128);
  362. Convert a 128 bit binary string into binary coded decimal text
  363. digits.
  364.  
  365. input: 128 bit string variable
  366. returns: string of bcd text digits
  367.  
  368. * $bits128 = bcd2bin($bcdtxt);
  369. Convert a bcd text string to 128 bit string variable
  370.  
  371. input: string of bcd text digits
  372. returns: 128 bit string variable
  373.  
  374. * $modetext = mode;
  375. Returns the operating mode of this module.
  376.  
  377. input: none
  378. returns: "Pure Perl"
  379. or "CC XS"
  380.  
  381. * ($name,$aliases,$addrtype,$length,@addrs)=naip_gethostbyname(NAME);
  382. Replacement for Perl's gethostbyname if Socket6 is available
  383.  
  384. In ARRAY context, returns a list of five elements, the hostname or
  385. NAME, a space seperated list of C_NAMES, AF family, length of the
  386. address structure, and an array of one or more netaddr's
  387.  
  388. In SCALAR context, returns the first netaddr.
  389.  
  390. This function ALWAYS returns an IPv6 address, even on IPv4 only
  391. systems. IPv4 addresses are mapped into IPv6 space in the form:
  392.  
  393. ::FFFF:FFFF:d.d.d.d
  394.  
  395. This is NOT the expected result from Perl's gethostbyname2. It is
  396. instead equivalent to:
  397.  
  398. On an IPv4 only system:
  399. $ipv6naddr = ipv4to6 scalar ( gethostbyname( name ));
  400.  
  401. On a system with Socket6 and a working gethostbyname2:
  402. $ipv6naddr = gethostbyname2( name, AF_INET6 );
  403. and if that fails, the IPv4 conversion above.
  404.  
  405. For a gethostbyname2 emulator that behave like Socket6, see: the
  406. Net::DNS::Dig manpage
  407.  
  408. * $trueif = havegethostbyname2();
  409. This function returns TRUE if Socket6 has a functioning
  410. gethostbyname2, otherwise it returns FALSE. See the comments above
  411. about the behavior of naip_gethostbyname.
  412.  
  413. * NetAddr::IP::Util::lower();
  414. Return IPv6 strings in lowercase.
  415.  
  416. * NetAddr::IP::Util::upper();
  417. Return IPv6 strings in uppercase. This is the default.
  418.  
  419. EXAMPLES
  420. # convert any textual IP address into a 128 bit vector
  421. #
  422. sub text2vec {
  423. my($anyIP,$anyMask) = @_;
  424.  
  425. # not IPv4 bit mask
  426. my $notiv4 = ipv6_aton('FFFF:FFFF:FFFF:FFFF:FFFF:FFFF::');
  427.  
  428. my $vecip = inet_any2n($anyIP);
  429. my $mask = inet_any2n($anyMask);
  430.  
  431. # extend mask bits for IPv4
  432. my $bits = 128; # default
  433. unless (hasbits($mask & $notiv4)) {
  434. $mask |= $notiv4;
  435. $bits = 32;
  436. }
  437. return ($vecip, $mask, $bits);
  438. }
  439.  
  440. ... alternate implementation, a little faster
  441.  
  442. sub text2vec {
  443. my($anyIP,$anyMask) = @_;
  444.  
  445. # not IPv4 bit mask
  446. my $notiv4 = ipv6_aton('FFFF:FFFF:FFFF:FFFF:FFFF:FFFF::');
  447.  
  448. my $vecip = inet_any2n($anyIP);
  449. my $mask = inet_any2n($anyMask);
  450.  
  451. # extend mask bits for IPv4
  452. my $bits = 128; # default
  453. if (isIPv4($mask)) {
  454. $mask |= $notiv4;
  455. $bits = 32;
  456. }
  457. return ($vecip, $mask, $bits);
  458. }
  459.  
  460. ... elsewhere
  461. $nip = {
  462. addr => $vecip,
  463. mask => $mask,
  464. bits => $bits,
  465. };
  466.  
  467. # return network and broadcast addresses from IP and Mask
  468. #
  469. sub netbroad {
  470. my($nip) = shift;
  471. my $notmask = ~ $nip->{mask};
  472. my $bcast = $nip->{addr} | $notmask;
  473. my $network = $nip->{addr} & $nip->{mask};
  474. return ($network, $broadcast);
  475. }
  476.  
  477. # check if address is within a network
  478. #
  479. sub within {
  480. my($nip,$net) = @_;
  481. my $addr = $nip->{addr}
  482. my($nw,$bc) = netbroad($net);
  483. # arg1 >= arg2, sub128 returns true
  484. return (sub128($addr,$nw) && sub128($bc,$addr))
  485. ? 1 : 0;
  486. }
  487.  
  488. # truely hard way to do $ip++
  489. # add a constant, wrapping at netblock boundaries
  490. # to subtract the constant, negate it before calling
  491. # 'addwrap' since 'addconst' will extend the sign bits
  492. #
  493. sub addwrap {
  494. my($nip,$const) = @_;
  495. my $addr = $nip->{addr};
  496. my $mask = $nip->{mask};
  497. my $bits = $nip->{bits};
  498. my $notmask = ~ $mask;
  499. my $hibits = $addr & $mask;
  500. $addr = addconst($addr,$const);
  501. my $wraponly = $addr & $notmask;
  502. my $newip = {
  503. addr => $hibits | $wraponly,
  504. mask => $mask,
  505. bits => $bits,
  506. };
  507. # bless $newip as appropriate
  508. return $newip;
  509. }
  510.  
  511. # something more useful
  512. # increment a /24 net to the NEXT net at the boundry
  513.  
  514. my $nextnet = 256; # for /24
  515. LOOP:
  516. while (...continuing) {
  517. your code....
  518. ...
  519. my $lastip = $ip-copy();
  520. $ip++;
  521. if ($ip < $lastip) { # host part wrapped?
  522. # discard carry
  523. (undef, $ip->{addr} = addconst($ip->{addr}, $nextnet);
  524. }
  525. next LOOP;
  526. }
  527.  
  528. EXPORT_OK
  529. inet_aton
  530. inet_ntoa
  531. ipv6_aton
  532. ipv6_ntoa
  533. ipv6_n2x
  534. ipv6_n2d
  535. inet_any2n
  536. hasbits
  537. isIPv4
  538. isNewIPv4
  539. isAnyIPv4
  540. inet_n2dx
  541. inet_n2ad
  542. inet_pton
  543. inet_ntop
  544. inet_4map6
  545. ipv4to6
  546. mask4to6
  547. ipanyto6
  548. maskanyto6
  549. ipv6to4
  550. packzeros
  551. shiftleft
  552. addconst
  553. add128
  554. sub128
  555. notcontiguous
  556. bin2bcd
  557. bcd2bin
  558. mode
  559. naip_gethostbyname
  560. havegethostbyname2
  561.  
  562. AUTHOR
  563. Michael Robinton <michael@bizsystems.com>
  564.  
  565. COPYRIGHT
  566. Copyright 2003 - 2011, Michael Robinton <michael@bizsystems.com>
  567.  
  568. All rights reserved.
  569.  
  570. This program is free software; you can redistribute it and/or modify it
  571. under the terms of either:
  572.  
  573. a) the GNU General Public License as published by the Free
  574. Software Foundation; either version 2, or (at your option) any
  575. later version, or
  576.  
  577. b) the "Artistic License" which comes with this distribution.
  578.  
  579. This program is distributed in the hope that it will be useful, but
  580. WITHOUT ANY WARRANTY; without even the implied warranty of
  581. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the GNU
  582. General Public License or the Artistic License for more details.
  583.  
  584. You should have received a copy of the Artistic License with this
  585. distribution, in the file named "Artistic". If not, I'll be glad to
  586. provide one.
  587.  
  588. You should also have received a copy of the GNU General Public License
  589. along with this program in the file named "Copying". If not, write to
  590. the
  591.  
  592. Free Software Foundation, Inc.
  593. 59 Temple Place, Suite 330
  594. Boston, MA 02111-1307, USA
  595.  
  596. or visit their web page on the internet at:
  597.  
  598. http://www.gnu.org/copyleft/gpl.html.
  599.  
  600. AUTHOR
  601. Michael Robinton <michael@bizsystems.com>
  602.  
  603. SEE ALSO
  604. NetAddr::IP(3), NetAddr::IP::Lite(3), NetAddr::IP::InetBase(3)
  605.