Revision history for Perl extension NetAddr::IP

4.080_05  2026-10-15 13:40:32+11:00 Australia/Sydney (TRIAL RELEASE)

    - Fix GH#142: Use Socket's own AF_INET6 where the Socket module has one,
      rather than guess it from the operating system name

    - Fix GH#140: Build the XS by default on macOS when a C compiler works;
      Windows, Cygwin and DOS still default to pure Perl

    - Declare perl 5.014 for the configure phase as well as runtime and test.
      The configure prereqs carried 5.010, the version [MinimumPerl] found in
      lib/ and copied there, and the shipped Makefile.PL opened with use
      5.010. It now opens with use 5.014, passes MIN_PERL_VERSION 5.014
      without a header override, and asks for ExtUtils::MakeMaker 6.5702,
      which perl 5.14 ships as 6.57_05.

    - RT #114495: Document that network() keeps the netmask; addr() gives the
      address alone.

    - Relicense to MIT, agreed by all three copyright holders. The
      distribution was dual-licensed under GPL v2 and the Artistic License.
      Prior releases remain under prior licenses.

4.080_04  2026-10-09 19:50:39+11:00 Australia/Sydney (TRIAL RELEASE)

    - Fix GH#109: The wrap check in the Util EXAMPLES compared addresses as
      strings, so text order stood in for address order. Two snippets stepped
      an address with the overloaded ++ and decided whether the host part had
      wrapped by comparing the string forms before and after. As text
      192.0.2.10 sorts before 192.0.2.9, so the step from .9 to .10 read as a
      wrap, and the real wrap from .11 back to .8 sorted after, so it read as
      no wrap. Both snippets happened to print what the page said: the first
      never wrapped, so its addconst branch never ran, and every address in
      the loop had three digits in the last octet, where text order and
      address order agree.

    - Stepping every aligned subnet of 192.0.2.0/24 from /24 to /31, 255 nets
      and 2048 steps, each net wrapping once, the string test reported 13
      false wraps and missed 6 of the 255 real ones, in 192.0.2.64/26,
      192.0.2.96/27, 192.0.2.96/28, 192.0.2.8/29, 192.0.2.96/29 and
      192.0.2.8/30. Six IPv6 nets in 2001:db8::/32 gave 3 false wraps and no
      missed ones. Comparing the objects got all 2048 IPv4 steps and all 4648
      IPv6 steps right on both builds.

    - Both snippets now take $before = $ip->copy and test $ip < $before, the
      overloaded comparison, which subtracts the two 128 bit addresses and is
      address order for either family. A step inside the net raises the
      address and a wrap drops it to the network address, so the new address
      is the lower one only at a wrap. The first snippet starts at
      192.0.2.127/26 and steps by 64, so it takes the wrap branch and shows
      the addconst list assignment the paragraph above it is about; it prints
      192.0.2.128/26, where the string test prints 192.0.2.64/26. The loop
      starts at 192.0.2.8/30, which passes both failure points, and its output
      follows as result comments. The paragraph between them had called the
      overloaded < the wrong test, when it is the right one, and had said
      comparing string forms is what detects the wrap; the only fault in the
      original test was $ip-copy(), which is not Perl. No code outside the
      examples changes.

    - Fix GH#111: Build XS by default where a compiler works, and delete the
      checkout Makefile.PL. Three edits for GH#101 combined to disable the
      compiler test: $useXS was initialised to 0 rather than left undefined,
      which also made the new "!defined $useXS" test in the Windows rule
      permanently false; the probe condition became "if ($useXS)" rather than
      "unless (defined $useXS)", so it ran only when --xs was given; and a
      successful probe no longer set $useXS = 1. So a plain "perl Makefile.PL"
      wrote the pure Perl Makefile everywhere. That is the command cpan and
      cpanm run, so an install from the next release would have built pure
      Perl even where a compiler works, and the Linux CI job meant to test the
      XS has been testing pure Perl while staying green. The same commit also
      dropped the closing brace of an "if ($useXS)" block, so the checked-out
      Makefile.PL no longer compiled at all.

    - header.pl leaves $useXS undefined until an option or the platform rule
      sets it, runs the probe when neither --xs nor -noxs was given, and sets
      $useXS = 1 when a compiler works. That restores the 4.079 default while
      keeping the GH#101 change that lets --xs override the Windows rule. With
      --xs the probe is skipped and the build is XS, as in 4.079; a broken
      compiler now fails at make instead of falling back to pure Perl, which
      is what asking for the XS explicitly should mean.

    - Each of the four build jobs now checks the mode it got rather than
      passing as whichever build it happened to produce. t/033-util-mode.t
      cannot do this: it derives its expectation from Util_IS->not_pure, so it
      agrees with the build either way. The macOS job asserts Pure Perl, which
      is the point of pinning it down, since it gets there by the accident
      that "darwin" contains "win" and so matches the /win/i platform rule.

    - The checked-out Makefile.PL is deleted rather than repaired. It is
      excluded from the distribution, nothing regenerates it, and it had
      drifted from inc/MakeMaker: it still used the older %makeparms spelling
      instead of @mm_args, and carried a realclean naming xs/config.h,
      xs/config.log and xs/config.status, which GH#101 stopped generating,
      plus a clean override protecting lib/NetAddr/IP/Util.c, which GH#96
      established is not tracked in git. README.md now says so and gives the
      dzil build path.

    - Restoring the XS build exposed a fault in the clean list that the pure
      Perl default had been hiding. make clean did not remove
      lib/NetAddr/IP/Util.o, because ExtUtils::MakeMaker only knows about
      C_FILES and OBJECT when the XS branch fills them in, so the file
      survived a clean, then a later perl Makefile.PL -noxs in the same tree
      copied it into blib as though it were a module, which dragged the
      postamble's xsubpp rule into a pure Perl build where $(XSUBPP) is unset.
      That failed on "-ypemap". The clean list now names Util.c, Util.o and
      Util.c.xsc as well. All three are generated, and in a pure Perl tree
      naming absent files costs nothing.

    - Fix GH#114: The XS build had not compiled since GH#106, so CI never
      noticed: its Linux XS job builds pure Perl, see GH#111. The file carried
      two definitions of _num_arg and two of have128 with no body. It was
      missing _128x10plusbcd, which _bcdn2bin still called, and the unused
      _isipv4. It used k and nv in comp128 and bcd2bin without declaring them,
      and read the packed argument with SvPV rather than SvPVbyte in seven
      functions. Restored GH#106 as filed, tests included: the duplicate is
      gone, have128 keeps its GH#102 unaligned access fix, the missing helpers
      are back, the packed argument is read with SvPVbyte while the digit text
      in bcd2bin and simple_pack stays SvPV, and a count or constant is read
      before a pointer into the address is taken. A fifth defect in the same
      area: a packed address reached through get magic looked undefined.
      _packed_ok runs the magic once and reports whether the value is then
      defined, _packed_bytes reads the bytes without running the magic again
      and through a downgraded copy when the argument is upgraded.
      SvPVbyte_nomg would do this in one call but needs perl 5.31.4, so this
      uses only calls available from 5.9.2.

    - Fix GH#101: Remove the autoconf/configure step. The XS build ran one of
      two autoconf scripts to write xs/config.h, and the C code takes exactly
      two facts from that file: the host byte order and a pair of 32-bit
      integer types. Both have been in perl.h since at least 5.005_03. The
      configure step can go: four files, 31 percent of the compressed tarball,
      about 60 lines of the Makefile.PL header, and the reason the module has
      historically given for building pure Perl on Windows.

    - Fix GH#102: Four helpers in xs/Util.xs read the caller's packed address
      as 32-bit words through a cast of the Perl string buffer. That is
      undefined behaviour in C whenever the buffer is not 4-byte aligned, and
      Perl hands the XSUBs unaligned buffers in ordinary use. A string whose
      leading bytes were removed in place keeps its allocation and moves its
      start. On x86 and arm64 the loads still give the right answer, which is
      why nothing has failed; on hardware that traps misaligned loads, SPARC
      above all, the process dies with SIGBUS. The fix copies the bytes into
      local words with memcpy, which compiles to the same instructions where
      unaligned loads are cheap.

    - Fix GH#7: Document that uppercase is the effective default, not
      lowercase. InetBase said "This module defaults to lowercase", which
      holds only when it is loaded on its own. NetAddr::IP::Util loads it with
      :upper, so every program that uses NetAddr::IP prints uppercase. The
      case setting is process wide and the last import or call wins, so a
      lower() anywhere changes what every object prints. InetBase, IP.pm and
      Lite.pm now say so.

    - Fix GH#12: The :aton packed input is corrupted by lc for bytes 0x41 to
      0x5A. The _xnew() function in Lite.pm ran $ip = lc $ip; before checking
      whether the input was a packed binary address, so bytes 0x41-0x5A (A-Z)
      became 0x61-0x7a (a-z). Fixed by preserving the original input in $raw
      before lowercasing, and using it for the binary IP detection path.

    - Fix GH#21: ipv6_aton accepts a single leading or trailing colon, which
      RFC 4291 section 2.2 does not allow. The pure-Perl build shares this
      code and behaves the same way. Fixed by adding explicit checks for a
      single leading or trailing colon before processing.

    - Final polish: constructor entry cleanup and import tag refinement.

    - Unify the argument names and finish the import tag tables (GH#100, C5
      and C7), the last two items from the structure list.

    - C5 named one concept six ways across the three function pages. For a
      16 byte string there were $ipv6naddr, $ipv6addr, $pv6naddr, $bits128
      and $netaddr. Now $bits128 is the 16 byte string, $ipv6naddr an
      address being converted, and $netaddr a 4 byte one:
      $bits128     52 -> 60 uses, after the sweep
      $ipv6naddr   48 -> 50
      $netaddr     29
      $ipv6addr     8 -> 0
      $pv6naddr     2 -> 0

    - $pv6naddr was a typo for $ipv6naddr, in two places. Checked first that
      every occurrence of both names was POD or POD inside a comment, so no
      code was renamed:
      $ipv6addr in non-POD code   0 lines in each of the three files

    - C7, three pages carried an import tag section and Lite.pm carried none,
      and none of them said what happens when :lower and :upper are both
      given. Verified rather than assumed, in both classes:
      NetAddr::IP          :lower          2001:db8:0:0:0:0:0:1
      NetAddr::IP          :upper          2001:DB8:0:0:0:0:0:1
      NetAddr::IP          :lower :upper   2001:DB8:0:0:0:0:0:1
      NetAddr::IP          :upper :lower   2001:DB8:0:0:0:0:0:1

    - :upper wins either way, because :lower is handled first in import.
      Lite.pm now has an IMPORT TAGS section covering the five tags it
      accepts, each marked process-wide, and the precedence stated. Which is
      the five was measured, since :old_storable and :rfc3021 belong to
      NetAddr::IP alone:
      :old_storable   rejected by Lite
      :rfc3021        rejected by Lite
      :aton           accepted
      :old_nth        accepted
      :nofqdn         accepted

    - Documentation only, no code change.

    - Group the remaining method and function entries (GH#100, C2 and the
      grouped layout). IP.pm was grouped in the previous commit; this does
      the other four.
      Util.pm      34 entries into Text to binary, Binary to text, Case,
                   Family tests, Widening and narrowing, Arithmetic,
                   Decimal strings, Resolver, Build mode
      InetBase.pm  21 entries into Text to binary, Binary to text,
                   Family tests, Address family, Short IPv4 text, Case
      UtilPP.pm    13 entries into Family test and shift, Arithmetic,
                   Widening and narrowing, Decimal strings
      Lite.pm      27 entries into the six groups it has, the same names
                   IP.pm uses where they overlap

    - Each entry block was moved whole and checked to have survived
      verbatim, and both the definition count and the POD item count are
      unchanged in all six modules:
      IP.pm       31 subs, 67 items
      Lite.pm     50 subs, 39 items
      Util.pm      7 subs, 41 items
      InetBase.pm 29 subs, 25 items
      UtilPP.pm   28 subs, 13 items
      Constants.pm 0 subs, 14 items

    - Two things worth recording about how this went.

    - podchecker needs =head2 outside an =over, so each group is its own
      list rather than headings inside one list. It also needs a blank line
      before =back, or the =back is swallowed as ordinary text and the list
      reads as unclosed. That only bit one group, because the group whose
      entries happened to be last in the old order had no trailing blank
      line to inherit. The error pointed at the next =head2, which sent the
      first two attempts looking for an imbalance that was not there; the
      cause only showed up when the block was reproduced in three lines.

    - UtilPP.pm had two =head1 DESCRIPTION sections, one of them a single
      line left over from the step 2 rewrite, and no FUNCTIONS heading at
      all. Both fixed here.

    - C3 finished at the same time: INSTALLATION is now gone from every
      module. It was already gone from Util.pm, InetBase.pm, UtilPP.pm and
      Constants.pm; IP.pm and Lite.pm still had it, so the build steps live
      in README.md alone, and the two pages point at it from DESCRIPTION.
      Nothing linked to the removed sections.

    - Documentation only, no code change.

    - Fix README.md (GH#100, step 4, the last one). It had errors of its own,
      and three of them meant a reader's first attempt at the advanced
      methods died.

    - The four calling conventions in the advanced section were all wrong.
      They were written as functions called on the class name, where the
      arguments land in $_[0] where an object is expected:
      NetAddr::IP->split($base,$bits)
        dies: Can't use string ("NetAddr::IP") as a HASH ref
      NetAddr::IP->rsplit($base,$target)
        dies: Can't use string ("NetAddr::IP") as a HASH ref
      NetAddr::IP->hostenum($ips)
        dies: Can't use string ("NetAddr::IP") as a HASH ref
      NetAddr::IP->compact(@ips)
        dies: Can't use string ("NetAddr::IP") as a HASH ref
      NetAddr::IP->coalesce(@ips)
        returns one value, silently

    - Every one of them is a method on an object:
      $ip->split(26)                     $ip->rsplit(28,29,28,29,26)
      $ip->splitref(26)                  $ip->rsplitref(28,29,28,29,26)
      $ip->hostenum                      $ip->hostenumref
      $ip->compact(@other)               $ip->compactref(\@other)
      $ip->coalesce($masklen,$number,@other)

    - The coalesce case is the nastiest, because it returns rather than
      dying, which is the same silent-wrong-answer shape as GH#39.

    - The examples used 192.168.1.123 and fe80::1. Replaced with the RFC
      5737 and RFC 3849 documentation addresses, so nothing in the README
      points at a range someone might own, and the IPv6 outputs are the real
      ones, which are not what a reader would guess:
      new('2001:db8::1/64')->network    2001:DB8:0:0:0:0:0:0/64
      new('2001:db8::1/64')->broadcast  2001:DB8:0:0:0:FFFF:FFFF:FFFF:FFFF/64

    - InetBase was described as "low-level inet address conversion (mostly
      XS)". It is pure Perl on every host; UtilPP is the pure Perl half and
      Util is the XS one. The module list also said four modules and gave
      no mention of UtilPP or Constants, so all six are now listed, with
      NetAddr::IP::Util_IS noted as generated.

    - is_local was described as "true for 127.x.x.x or ::1", which misses
      the two IPv6 forms the code accepts:
      127.0.0.1=1  ::1=1  ::127.0.0.1=1  ::ffff:127.0.0.1=1

    - The export tag table omitted :old_storable, :aton and :rfc3021. All
      three are added and marked deprecated, and the entry for :rfc3021
      says why it is no longer needed.

    - Added what was missing rather than only fixing: the mask-argument
      trap, the array deref overload and the two croaking operators, the
      comparison order, the /31 and /127 host count, the split croak, a
      worked example showing split and rsplitref actually differing on the
      same plan, and a Functions section for Compact, Coalesce and
      netlimit, which had no home at all.

    - The Authors section listed two of the three, and gave an address for
      Michael Robinton that is not the one in dist.ini. It now matches
      META.json.

    - Documentation only. No module was touched, checked by counting
      definitions before and after: IP.pm 31/31, Lite.pm 50/50, Util.pm
      7/7, InetBase.pm 29/29, UtilPP.pm 28/28, Constants.pm 0/0.

    - Group the IP.pm methods, rewrite its SYNOPSIS, and document netlimit
      (GH#100, step 3 continued). The Methods section was one flat =over of
      forty-eight entries, so a reader looking for how to enumerate hosts
      scanned forty-eight headings. It is now ten =head2 groups, each its
      own =over:
      Constructors           new new6 new_no new_from_aton
                             new_cis new_cis6
      Address and mask       addr mask masklen bits version cidr aton
      Boundaries             network broadcast first last range
      Numeric forms          numeric bigint
      Text forms             short canon full full6 full6m prefix
                             nprefix wildcard
      Containment            contains within is_rfc1918 is_local
      Splitting              split splitref rsplit rsplitref
      Set operations         compact compactref coalesce
      Hosts                  num nth hostenum hostenumref
      Regular expressions    re re6

    - That reorders entries, so each block was moved whole and checked to
      have survived verbatim; 48 of 48 did, and the POD item count is
      unchanged at 63. podchecker needs =head2 outside an =over, so each
      group is its own list rather than one list with headings inside it.

    - The SYNOPSIS was 113 lines: an import list, every signature, the
      case policy, the FQDN note, Storable, Compact, Coalesce and
      netlimit, all of it mixed together. It is now fifteen pasteable lines
      with results in comments, and the material that was not a synopsis
      moved to its own IMPORT TAGS section:
      print $ip->addr, "\n";         # 192.0.2.1
      print $ip->mask, "\n";         # 255.255.255.0
      print $ip->network, "\n";      # 192.0.2.0/24
      print $ip->broadcast, "\n";    # 192.0.2.255/24
      print "$ip\n";                 # 192.0.2.1/24
      my $next = $ip + 5;            # 192.0.2.6/24
      my @halves = $ip->split(25);   # 192.0.2.0/25, 192.0.2.128/25

    - B11, netlimit was documented only inside the SYNOPSIS, which is where
      the code lived too, and it returns the new limit rather than "true on
      success". It has a FUNCTIONS section now, and the values are the
      measured ones:
      netlimit(20)   1048576
      netlimit(16)   65536
      netlimit(24)   16777216
      netlimit(10)   undef, below the default
      netlimit(25)   undef, above the maximum

    - B4 through B7 are documented under the constructor, where the
      abbreviated accepted-forms list is, with the mask-argument trap
      spelled out since it is the one that surprises:
      new('10.1')        10.0.0.1/32
      new('10.1', 8)     10.1.0.0/8
      new('10.1.2')      10.1.0.2/32
      new('10.1.2', 24)  10.1.2.0/24
      new('192.0.2.4-7')         192.0.2.4/30
      new('192.0-3.')            192.0.0.0/14
      new('[2001:db8::1]/64')    2001:DB8:0:0:0:0:0:1/64
      new('[192.0.2.1]/24')      undef
      new('broadcast')       255.255.255.255/32
      new6('broadcast')      undef, IPv4 keywords only
      new('loopback')        127.0.0.1/8, not /32

    - And one correction to what I wrote in the previous commit for this
      step: moving the SYNOPSIS deleted the netlimit sub and its $_netlimit
      default, because the code sat between that heading and INSTALLATION
      and the replacement spanned both. perl -c did not catch it and the
      suite still passed 2535 tests, since nothing calls netlimit. What
      caught it was documenting the function and finding
      NetAddr::IP->can("netlimit") was undef. Restored, in the FUNCTIONS
      section this time. Every edited file was then checked for lost
      definitions:
      IP.pm 31 subs before, 31 after, identical set
      Lite.pm 50/50, Util.pm 7/7, InetBase.pm 29/29,
      UtilPP.pm 28/28, Constants.pm 0/0

    - plus the glob aliases, which also match.

    - Fix NetAddr::IP and NetAddr::IP::Lite (GH#100, step 3). The two pages
      carry the same object API and have drifted, so they go in one commit
      and the merged text is written once.

    - A4, both said splitref "returns undef when bits ... will not fit". It
      croaks:
      NetAddr::IP->new('192.0.2.0/24')->splitref(16);
      `# netmask error: overrange or spurious bits`

    - A6, the IP.pm SYNOPSIS listed inet_any2d and inetanyto6. Neither
      exists; they are inet_any2n and ipanyto6, both of which Util has.

    - A11, both new() entries said 'See "STRINGIFICATION" below.' There is
      no such section on either page.

    - A12, "The first two methods create..." followed by "The third method
      new_no", after six constructors had been listed. new6FFFF was absent
      from IP.pm's list altogether and works through inheritance, so the
      entry now names it and shows the object it makes:
      NetAddr::IP->new6FFFF('192.0.2.1');
      `# 0:0:0:0:0:FFFF:C000:201/128`

    - A13 is Util.pm, A17 is below. A19, IP.pm's DESCRIPTION promised
      NetAddr::IP "will work with older versions of Perl". META.json says
      5.014, so that is now stated.

    - A20 and A22 are the drift between the two pages. IP.pm listed two
      is_local forms where Lite.pm listed four, and Lite.pm's within()
      carried a sentence about comparing addr() that IP.pm lacked. Both are
      merged, verified against the code:
      127.0.0.1        is_local=1
      ::1              is_local=1
      ::127.0.0.1      is_local=1
      ::ffff:127.0.0.1 is_local=1
      ::ffff:10.0.0.1  is_local=0
      128.0.0.1        is_local=0

    - The entries are now byte-identical between the two files, which is
      checkable:
      is_local()  identical    mask()  identical     first()  identical
      within()    identical    bits()  identical     last()   identical

    - A21, Lite.pm carried the numeric() float-comparison warning and IP.pm
      did not. It is on both now, with the hazard shown rather than
      described, because it is silent:
      $x->numeric == $y->numeric   same    for 2001:db8::1 and ::2
      $x == $y                     different
      $x->bigint == $y->bigint     different

    - A23, both new_cis item headings had an unbalanced quote.

    - A25, prefix() was documented as including the broadcast address. The
      range starts at first(), not network():
      192.0.2.4/30  ->  192.0.2.5-7
      192.0.2.0/24  ->  192.0.2.
      192.0.2.0/20  ->  192.0.0-15.
      192.0.2.9/32  ->  192.0.2.9

    - A27, both pages warned that comparing objects of differing CIDR "may
      produce indeterminate - unexpected results". It is deterministic:
      address first, then the mask as a number. The warning was wrong, and
      the real caveat is that the order is not the one most people mean by
      "bigger", so it says that instead and shows the sort order.

    - A28, both listed "a netaddr as returned by 'inet_aton'" among the
      accepted forms without saying it needs the deprecated :aton tag.
      Without it a packed string returns undef, which is now stated. The
      RFC 1884 citations became RFC 4291 s2.2 on both pages.

    - A17, the IP.pm NOTES / BUGS section said in the first person that the
      author lacked the resources to get the configure step working on
      Windows and asked for volunteers. It now states the fact and where it
      comes from, which is that header.pl selects pure Perl when $^O
      matches /win/i, and points at README.md for the build steps.

    - B1 and B2, the @{} overload and the croaking neg and abs, were
      undocumented on both pages:
      scalar @{$ip}   14 for a /28
      -$ip            cannot negate a NetAddr::IP object
      abs $ip         cannot take the absolute value of a NetAddr::IP object

    - B3, the sort order is now given as part of the comparison entry.

    - C4, version history inside method text is gone from nth() and num() on
      both pages. Both entries carry measured output instead:
      /32 nth(0) is the address itself, num 1
      /31 nth(0) is the network address, num 2
      /30 nth(0) is the first host, num 2
      /28 num 14

    - and the C<:old_nth> tag still restores the old behaviour, verified:
      old_nth 192.0.2.0/30  nth 0 undef, 1..3 the hosts, num 3

    - C9, IP.pm's HISTORY section, which said only "See the Changes file",
      is removed and the internal link now points at DEPRECATED.

    - Also fixed in passing: "array contest" for "array context" in IP.pm
      and Lite.pm numeric(), a doubled space in Lite.pm bigint(), and the
      C3.02 version note in compact().

    - POD only, no code change. Still outstanding from this step: the
      =head2 method groups, the SYNOPSIS rewrite, and B4 through B12 for the
      constructor entry, which is where the accepted-forms list lives and is
      long enough to need more than a correction.

    - Fix NetAddr::IP::InetBase and NetAddr::IP::UtilPP (GH#100, step 2,
      continued). The two carry copies of the entries fixed in Util.pm, so
      they go in the same step.

    - A7, the InetBase SYNOPSIS said "use NetAddr::IP::Base qw(...)", and
      the module is NetAddr::IP::InetBase, so the line as printed could not
      run. It was also followed by a NetAddr::IP::Util line pasted from
      Util.pm showing Util's tags, which InetBase does not have. Both are
      gone; the SYNOPSIS is now InetBase's own nineteen names with measured
      output, and its four tags are listed with their real contents,
      recovered by importing each into a scratch package:
      :ipv4   fillIPv4 inet_aton inet_ntoa, three names
      :ipv6   eleven names

    - The old list for :ipv6 was missing four of those.

    - A8, InetBase documented ipv4to6. It is neither defined nor exported
      there; the function belongs to NetAddr::IP::Util, and
      InetBase->can("ipv4to6") is undef. The entry is removed.

    - A9, InetBase said lower() "is the default" and Util.pm said upper()
      "is the default", and both were right about themselves and wrong
      about the reader's program. Measured:
      InetBase alone:          ipv6_n2x = 2001:db8:0:0:0:0:0:1
      after InetBase::upper() ipv6_n2x = 2001:DB8:0:0:0:0:0:1
      Util loaded:             ipv6_n2x = 2001:DB8:0:0:0:0:0:1

    - InetBase defaults to lowercase, and loading Util, Lite or NetAddr::IP
      imports :upper for you, so in practice uppercase is the default for
      nearly every program. There is now one section, THE CASE POLICY, that
      says so once, shows the process-wide behaviour where an unrelated
      package importing :lower changes the output for everyone else, and
      points at GH#7 for the open question of what the policy should be.
      ipv6_ntoa and inet_ntop are called out as always lowercase.

    - Worth recording, since the old entries implied otherwise: neither
      lower nor upper is importable from either module.
      NetAddr::IP::InetBase->can("lower")   undef
      NetAddr::IP::Util->can("lower")       undef

    - They must be called fully qualified, NetAddr::IP::InetBase::upper(),
      and the entries now say so.

    - fillIPv4 was documented as converting "127.1 to the long form
      127.0.0.1", which is right, but nothing said what it does with
      anything else, and it is not what a reader would guess. Measured:
      fillIPv4('192.0.2.1')      192.0.2.1
      fillIPv4('192.0.2')        192.0.0.2
      fillIPv4('192.0')          192.0.0.0
      fillIPv4('10')             0.0.0.10
      fillIPv4('example.com')    example.com, unchanged
      fillIPv4('256.1.1.1')      undef

    - The argument is text, not a packed address, which is the trap: a
      packed string does not match, so it comes back unchanged. It is also
      the BSD inet_aton convention and not RFC 791, which is the note
      table D asks for, and which belongs here rather than on inet_aton.

    - A14, the missing paren in the hasbits example was in this file too,
      at UtilPP.pm:111, so it is fixed in both.

    - A15, the UtilPP EXPORT_OK list ended with "threads", which is not a
      function of that module nor of NetAddr::IP::Util; it never existed.
      Removed, and the list now cross references NetAddr::IP::Util instead
      of being a bare list of eighteen names.

    - A18's rfc1844 typo was here as well as in Util.pm, and the two rfc1884
      citations became RFC 4291 s2.2.

    - UtilPP gets a DESCRIPTION, which it did not have beyond one sentence.
      It explains when the module is selected, that the two implementations
      are meant to be interchangeable and agree down to the error message
      wording, and that README.md carries the build steps, so no page
      discusses building.

    - INSTALLATION is removed from InetBase too, per C3.

    - A new section on InetBase, SOCKET6 SUBSTITUTION, names the three
      symbols that come from Socket6 when it is installed, says the choice
      is made at load time, and points at GH#99 and GH#21 for where the two
      paths disagree.

    - POD only, no code change. The grouped =head2 sections the issue asks
      for across all three function pages, and the table D note about
      inet_aton short forms, are still outstanding.

    - Fix NetAddr::IP::Util (GH#100, step 2 of the POD overhaul). The
      SYNOPSIS was a 118 line import list followed by every signature, a
      table of contents rather than a synopsis; it is now about forty lines
      that a reader can paste, and every value in it is the measured output
      rather than a placeholder. INSTALLATION is removed, per the rules,
      and README.md keeps the build steps. The EXAMPLES section did not
      compile at all and now runs on both builds.

    - The four defects the issue found in the examples, and what each was:
      $addr = addconst($addr,$const)      scalar context stores the
                                          carry, not the sum
      return ($network, $broadcast)       $broadcast never declared,
                                          the local is $bcast
      my $addr = $nip->{addr}             missing semicolon
      my $lastip = $ip-copy()             not Perl; stringification
                                          copies, "$ip"

    - plus an unbalanced paren in (undef, $ip->{addr} = addconst(. The wrap
      is now detected with "$ip" lt $before, since the comparison is on the
      string forms rather than the overloaded operators, and the list
      context form of addconst takes the second element. The loop is shown
      wrapping a /30, so the branch is actually exercised:
      step 3: 192.0.2.252/30   wrapped: 1

    - A1, shiftleft with no count. Util.pm said "a single shift is
      performed if $n is not specified" and UtilPP.pm said it returns the
      input. UtilPP was right and both builds agree:
      shiftleft($bits128) eq $bits128      yes, on XS and pure Perl

    - Both entries now say so, with an example, and note that $n above
      $MAX_SHIFTLEFT croaks.

    - A2, naip_gethostbyname documented IPv4 answers as ::FFFF:FFFF:d.d.d.d,
      which is not an address. The answer for 127.0.0.1 is:
      0:0:0:0:0:FFFF:7F00:1

    - so the form is ::FFFF:d.d.d.d, the RFC 4291 s2.5.5.2 mapped prefix,
      which is what the function actually produces on both builds.

    - A3, three entries wrote ::ffff::d.d.d.d, which has one colon too
      many. Corrected to ::ffff:d.d.d.d, and the isNewIPv4 and isAnyIPv4
      entries now name the prefixes they test, s2.5.5.2 and the union of
      s2.5.5.1 with it.

    - A14, "if (hasbits($bits128 & $mask128) {" was missing its closing
      paren here and in UtilPP.pm.

    - A16, the EXPORT_OK list omitted seven names that are in @EXPORT_OK:
      AF_INET, AF_INET6, bin2bcdn, bcdn2txt, bcdn2bin, simple_pack and
      comp128. All seven are now listed, the last five under a heading that
      says they are exported for the test suite and are not stable API,
      which is what the code comments about comp128 said all along. The
      import tags are now listed with their real contents, measured by
      importing each into a scratch package, which turned up that :ipv6 is
      :inet without the two IPv4 names and nothing else, and that the
      original list for it was missing four.

    - A18, inet_n2ad was documented as returning x:x:x:x:x:x:ddd.ddd.ddd.dd,
      which has a truncated octet. The real form is
      x:x:x:x:x:x:ddd.ddd.ddd.ddd, and inet_n2ad(2001:db8::1) is
      2001:DB8:0:0:0:0:0.0.0.1. Two rfc1844 typos became RFC 4291 s2.2.

    - A24, "=item $ipv6naddr = inet_4map6($netaddr or $ipv6naddr" was
      missing its closing paren in the item heading.

    - B9, the :noSock6 import tag, which forces havegethostbyname2 to
      report false so the resolver fallback can be tested on a host that
      has Socket6, was undocumented. It has its own section now, labelled
      a test hook. C7's point that there is no single place listing the
      tags that change behaviour is partly answered; the case tags live in
      NetAddr::IP::InetBase and are cross referenced.

    - B10, the split between the functions that return undef on bad input
      and the ones that croak on a wrong length, now stated in the
      entries: ipv6_aton, inet_aton and inet_4map6 return undef, while
      hasbits and isIPv4 croak with "Bad arg length ... length is N,
      should be 128". B11's netlimit is a NetAddr::IP function rather than
      one of these, and is left to step 3.

    - The RFC 1884 citations become RFC 4291 s2.2 for the accepted forms
      and RFC 5952 s4 for the output, with packzeros documented against
      s4.2.1, s4.2.2 and s4.2.3 separately and an example for each,
      including that a single zero group is never shortened. Table D's
      note that inet_aton short forms are the BSD convention rather than
      RFC 791 is still outstanding; inet_aton('127.1') is 127.0.0.1 and
      inet_aton('192.168.1') is 192.168.0.1, and inet_aton croaks on
      '0x7f.1', so it belongs with a rewritten inet_aton entry.

    - Five names for one concept were unified to $bits128 for a 16 byte
      string and $ipv6naddr for an address, per C5, though the full sweep
      across all three function pages is part of finishing this step.

    - POD only, no code change. InetBase.pm and UtilPP.pm carry copies of
      several of these entries and are corrected in the commit that
      follows.

    - Fix NetAddr::IP::Constants (GH#100, step 1 of the POD overhaul).
      Unindent the item bodies, which rendered as verbatim blocks under
      pod2text, group the constants by the RFC they come from, and drop the
      claim that importing one "ensures that each constant resolves at
      compile time".

    - That claim is false and the opposite is worth saying plainly, since
      the constants are read in the hot path of the 128 bit arithmetic.
      They are our variables, so an assignment writes through to the
      module's own copy, which is what the rest of the distribution reads:
      use NetAddr::IP::Constants qw($IPV6_BITS);
      print "$IPV6_BITS\n";                             # 128
      $IPV6_BITS = 999;
      print "$IPV6_BITS\n";                             # 999
      print "$NetAddr::IP::Constants::IPV6_BITS\n";     # 999

    - A caller who has already declared a name the import wants is not
      overwritten, because Exporter only installs the alias when the name
      is free, so overriding is reachable and order dependent. InetBase,
      Util and UtilPP each import these and read their own copy, so a
      caller's reassignment changes nothing inside the library. Documented
      as reachable but unsupported rather than as a supported feature.

    - One more correction the issue did not list. $MAX_BCD_DIGITS was
      documented as "40 (i.e. ceil(128 * log10(2)))", and that ceiling is
      39, not 40:
      ceil(128*log10(2)) = 39      decimal digits in 2**128 = 39
      bin2bcd of all ones        = 39 digits, unpadded

    - 40 is right for a different reason. BCD holds one digit per nibble,
      and a packed string has to be a whole number of bytes, so 39 nibbles
      round up to 40, which is the 20 bytes $PACKED_BCD_BYTES holds, and
      simple_pack is what pads to 40 before pack("H40"). The entry now
      gives that reasoning instead of the false equivalence.

    - $IPV4_OFFSET gained the two section numbers it covers, RFC 4291
      s2.5.5.1 for the deprecated compatible prefix and s2.5.5.2 for the
      mapped prefix, since both sit at that offset and the entry had only
      the umbrella citation. Table D's note that inet_aton short forms
      such as 127.1 are the BSD convention and not RFC 791 is left for the
      Util.pm commit that rewrites the function entries.

    - POD only, no code change. Every example run on both builds.

    - Narrow what canon() claims to follow, and document what it does with
      an IPv4 address in the low 32 bits (GH#98). The POD said ipV6 output
      is "as per RFC5952", which overclaims. Sections 4.1 to 4.3 hold:
      leading zeros dropped, the longest run of zero groups shortened to
      ::, the first of two equal runs shortened, lowercase, and canon is
      the lower case of short() on every address tried. Section 5, the
      mixed form for an embedded IPv4 address, is not applied:
      canon ->new('::ffff:192.0.2.1')   ::ffff:c000:201
      canon ->new6FFFF('192.0.2.1')     ::ffff:c000:201
      canon ->new6('1.2.3.4')           ::102:304

    - Deferred to a future decision, GH#98, and this entry takes neither
      path. Mixed notation for the mapped prefix alone is the narrowest
      reading of section 5, the one prefix that is both well known and
      current, and is what Python does; the test is isNewIPv4, which is
      what distinguishes the mapped prefix from the compatible one, since
      isIPv4 is also true of ::1 and its mixed form would be ::0.0.0.1.
      It would change canon for mapped addresses and nothing else, leave
      addr, short, full and stringification in hex since none of them
      claims the RFC, and stop canon and short agreeing for those
      addresses, which the POD would then have to say. Mixed notation for
      the compatible prefix as well would agree with glibc, and therefore
      with ipv6_ntoa where Socket6 binds libc, but it would make canon
      stop agreeing with the ::102:304 that new6 documents, and RFC 4291
      deprecates the form. Either way t/114-canon.t gains the mapped cases
      and keeps ::1 and :: unchanged, and anyone comparing stored canon
      strings of mapped addresses sees a new value, so this belongs in the
      series that already changed re, re6 and new(undef).

    - A comment at canon() records the section 5 omission where it happens
      and points at GH#98.

    - Document that ipv6_ntoa and inet_ntop render an address with an IPv4
      address in the low 32 bits differently depending on Socket6
      (GH#99). inet_ntop is bound to the platform's libc when Socket6 is
      installed and to the module's own _inet_ntop otherwise, and Socket6
      is a recommendation rather than a requirement. Two hosts differing
      only in that one optional module therefore render
      ::ffff:192.0.2.1 as ::ffff:192.0.2.1 and as ::ffff:c000:201. The
      POD said these functions "come from the Socket6 library if it is
      present on this host" without saying what follows from it.

    - The table now in the POD is measured, not reasoned. Over 8,040
      addresses, a structured set plus random ones weighted towards zero
      groups, every disagreement between libc and the fallback fell in the
      mapped prefix ::ffff:0:0/96 or the deprecated compatible prefix
      ::/96, and nowhere else. Zero run compression, which of two equal
      runs is shortened, single zero groups, leading zeros and case agree
      throughout, including on 2001:0:0:1:0:0:0:1, where both shorten the
      second run.

    - Also correct "takes and IP address" to "an" in the inet_ntop entry.

    - POD only. No method of NetAddr::IP or NetAddr::IP::Lite calls either
      function; stringification goes through ipv6_n2x and packzeros, which
      are pure Perl on every host.

    - Deferred to a future decision, GH#99. Two ways out, and this entry
      takes neither. Bind inet_ntop to the module's own implementation
      always, and teach the fallback the mixed form for the mapped prefix.
      That makes the text the same on every host, defined by this module
      rather than by whichever libc is underneath, and stops a libc
      rendering it differently from breaking the suite, which is what GH#33
      was. The cost is that on a host with Socket6 today ::192.0.2.1 comes
      back as ::c000:201, so it moves output for existing callers. Or keep
      libc and teach the fallback to match, which moves nothing today but
      leaves the text defined by the host's libc, leaves the GH#33 class of
      failure in place, and forces the compatible prefix to glibc's
      rendering. That is the opposite of Path B of GH#98, so canon and
      ipv6_ntoa would disagree on ::192.0.2.1 unless GH#98 takes the same
      path. Whichever is chosen, the four tests that pin these functions
      should gain the mapped and compatible cases with one expected value
      each, true with and without Socket6.

    - A comment at the fallback binding in InetBase.pm now records the
      divergence where the choice is made, and points at GH#99 and GH#21.

    - Drop docs/rfc1884.txt (GH#97). The full text of RFC 1884, "IP
      Version 6 Addressing Architecture", December 1995, shipped with
      4.001 in August 2006 and moved to docs/ by 4.004 a fortnight
      later, and nothing has touched it since. It is 37,854 bytes, 3.98%
      of the unpacked distribution, and the only thing under docs/.

    - Nothing read it. No POD links to it, no test opened it, no code
      names the path, and the only reference to docs/ anywhere in the
      tree was the skip line in dist.ini that existed to keep the EOL
      test away from it. The generated t/author-eol.t lists 185 files and
      none under docs/, so removing the file and the skip line leaves
      that test at the same 185 files.

    - RFC 1884 was obsoleted by RFC 2373 in July 1998, which RFC 3513
      replaced in April 2003, which RFC 4291 replaced in February 2006.
      The addressing architecture is RFC 4291, and the text
      representation rules that :lower and canon() follow are RFC 5952
      from August 2010. Shipping the 1995 text beside code that
      implements the 2006 rules invites a reader to take it for the
      reference.

    - The ten mentions of rfc1884 in the POD name the specification, not
      the file, and are unchanged here. They are being replaced with RFC
      4291 and RFC 5952 citations in the POD work.

    - The text remains at https://www.rfc-editor.org/rfc/rfc1884 for
      anyone who wants the history.

    - Give the shipped Makefile.PL a clean and realclean list again
      (GH#96). The checkout Makefile.PL has listed the generated files
      since 4.079, but header.pl has not, so the shipped one has had no
      list at all since the move to MakeMaker::Awesome, and six files
      survived make realclean:
      lib/NetAddr/IP/Util.c, lib/NetAddr/IP/Util_IS.pm, xs/config.h,
      xs/config.log, xs/config.status and xs/localperl.h. Pure Perl left
      Util_IS.pm behind.

    - The stale xs/config.h was the part that mattered. Configure runs
      only when that file is missing, so the next perl Makefile.PL in the
      same tree reused the old results and never probed again, whatever
      had changed in between.

    - Restore the 4.079 split: make clean removes what Makefile.PL
      rewrites on every run, which is Util_IS.pm in both builds and
      localperl.h in the XS build, and make realclean removes the
      configure results. make clean moves the Makefile aside, so
      perl Makefile.PL runs again before the next build and puts those
      three back; the configure results survive until realclean.

    - That required dropping the sub clean override from the footer,
      which kept lib/NetAddr/IP/Util.c out of make clean on the grounds
      that "we need this file tracked in git for CPAN distribution". It
      is no longer tracked in git, and 4.080_03
      does not ship it, so the override was protecting nothing. The file
      is not needed in the tree either: the postamble regenerates it from
      xs/Util.xs through xsubpp, and a make clean followed by
      perl Makefile.PL and make builds and tests clean.

    - The checkout Makefile.PL loses xs/config.h, xs/config.log and
      xs/config.status from its clean list for the same reason, so the
      two copies do not disagree about what a clean build reuses.

    - Verified: XS build then make realclean leaves none of the six;
      pure Perl then make realclean leaves none; after make clean,
      Util.c, Util_IS.pm and localperl.h are gone and the three configure
      results are kept; Util.c comes back on the next make, and the next
      perl Makefile.PL --xs after a realclean probes again. Both builds
      161 files and 2535 tests, all pass.

    - Correct the :nofqdn example in NetAddr::IP's POD (GH#92). The
      FQDN paragraph under new() told the reader to load NetAddr::IP::Lite,
      which works, since the flag lives there and both modules read it, but
      every other tag example on that page imports through NetAddr::IP and
      a reader of the NetAddr::IP page has no reason to load Lite. Both
      forms set the same $NetAddr::IP::Lite::NoFQDN, checked here, and
      t/124-nofqdn.t already covers the tag arriving through NetAddr::IP.
      POD only.

    - Fix LIBS from configure reaching ExtUtils::MakeMaker by the wrong
      name (GH#95). header.pl read xs/config.h and then replaced
      @mm_args[-1], which is depend's hash ref rather than LIBS', so the
      libraries turned depend into an array ref, LIBS stayed empty, and
      EUMM died before writing a Makefile:
          WARNING: depend takes a HASH reference not a ARRAY reference
          Not a HASH reference at ExtUtils/MakeMaker.pm line 837
      Any library configure had to add, which is libnsl or libsocket on
      illumos and older Solaris, was enough to do it. config.h is only
      rewritten when it is missing, so the tree then stayed broken until it
      was deleted by hand. Read the file first and pass the libraries by
      name now.

    - Stop emitting the xs/config.h make rule, and stop referring to $begin
      to do it (GH#93). The rule ran xs/configure, a script this
      distribution has not shipped since 4.069, so it could never succeed;
      it only stayed out of the Makefile by accident, because the footer
      referred to $main::begin, which is the package variable of a
      different thing and is always unset. Every build warned
          Name "main::begin" used only once: possible typo
          Use of uninitialized value $begin in concatenation (.) or string
      and then carried on. No perl makes those fatal. The generated
      Makefile.PL enables warnings with a plain "use warnings", which
      [MakeMaker::Awesome] puts there, so both messages printed, the
      Makefile was written and the suite passed, on every perl in the
      matrix. Only a caller that imposes fatal warnings on the whole
      process, as PERL5OPT=-Mwarnings=FATAL does, turns the first one into
      a build that stops.
      Remove the reference and the warnings go; remove the rule and the
      generated Makefile is byte for byte what it was before, and a
      missing xs/config.h stops the build with make's own
          No rule to make target 'xs/config.h', needed by 'Util.c'
      rather than a failed script. The depend entry still lists it as a
      prerequisite. Makefile.PL itself probes configure.gcc, then
      configure.cc, then falls back to pure Perl before writing anything,
      which a make rule cannot repeat.

    - Re-enable the Windows test job, pure Perl only, so the runner needs
      no C toolchain. It had been disabled long enough that the reason was
      forgotten, and the reason was three separate things stacked on top of
      each other:
          - the job ran under a POSIX shell, where "perl" is the Cygwin perl
            that Git Bash puts on PATH, and it has no ExtUtils::MakeMaker, so
            the installer reported a core module as missing
          - the flavour of make ExtUtils::MakeMaker writes a Makefile in
            depends on the perl, 5.24 saying "dmake-style" and 5.26 saying
            "gmake-style", and neither make works across the matrix
          - the dependency install did not request the develop phase, which
            the author tests in the distribution need
    - It now installs through cpm via the setup action, which also gets all
      five author tests' prerequisites, and asks for gmake explicitly with
      MAKE=gmake so the Makefile flavour does not vary with the perl.

    - The Windows job does not set AUTHOR_TESTING, unlike the others. On
      that platform the setup action installs dependencies into
      local/lib/perl5 inside the project directory, and Test::EOF walks the
      working directory, so the check was reading third-party modules and
      failing on Data::Binary's trailing newlines. Test::EOF takes no file
      list and no finder, so it cannot be pointed elsewhere. The five
      author tests skip themselves without the variable. The four release
      tests do not, and still run; they need the develop phase, which is
      still installed, and they pass on Windows.

    - Skip local/ in the other line-ending check as well, the one built on
      the EOLFiles finder, for the same reason. Both checks walk the tree
      and neither can be given a file list from dist.ini.

    - Verified on Windows, pure Perl, perl 5.24: 160 files and 3676 tests
      with the one failure above, and 2531 with it gone and the author
      tests skipped. t/013-util-binet_pton.t and
      t/025-util-inet_pton.t, which hard-code the output of inet_ntop, both
      pass, so the difference in GH#33 is glibc against BSD and does not
      reach Windows. GH#33 is closed as unreproduced: all forty macOS jobs
      pass, ten perls from 5.24 across four images, with Socket6 built
      into each so libc, not the pure Perl fallback, is under test. The
      tests still assert the rendered string, so a libc rendering these
      three addresses differently would fail them again.

    - Stop the SYNOPSIS of both modules importing behaviour-changing tags
      (GH#91). A SYNOPSIS invites pasting, and both lists pulled in every
      tag the module has. Pasted as written, NetAddr::IP's list warned
      twice, for :aton and :rfc3021, and NetAddr::IP::Lite's warned
      once, for :aton. Under "use warnings FATAL => 'all'" both died at
      compile time, in a program that had only asked for Compact and
      Zeros.

    - Worse, the tags change behaviour for the whole program rather than
      returning something. A paste of the NetAddr::IP list also switched
      on the legacy Storable and nth() behaviour, and its :lower did
      nothing at all, because import() handles :lower before :upper, so
      :upper wins whichever order they appear in.

    - Each list now names functions only. NetAddr::IP points at where
      the tags are documented: :lower, :upper, :old_storable and
      :nofqdn each have a one-line example where they apply, and :aton
      and :rfc3021 are under DEPRECATED. Lite.pm is the smaller module
      and gets no sentence, and its EXPORT_OK drops the tags to match
      NetAddr::IP's, which lists functions only.

    - The tags themselves are unchanged and still import as before; this
      is POD only. No test asserted the SYNOPSIS list, and none needed
      changing.

    - Verified that each list now loads clean under both plain and FATAL
      warnings, that all twelve tags across the two modules still import,
      and podchecker is clean on both files.

4.080_03  2026-09-30 23:07:41+10:00 Australia/Sydney (TRIAL RELEASE)

    - Reformat the test files with perltidy's default profile. Nine of
      them were indented with tabs while the other 140 used spaces, and
      .editorconfig asks for four columns of spaces, so t/ is now
      internally consistent for the first time. Whitespace is the only
      thing that moved, except for four semicolons perltidy deletes by
      default, being ones that are simply empty statements: the one after
      "sub BASE_LEN () { 7 };" in t/043, and one standing before a closing
      brace in each of t/087, t/096 and t/097. None of them changes what
      the code does.

    - Tabs survive in six files, inside comments that use them to line up
      columns in a table of test vectors. perltidy does not rewrite comment
      text, which is the right call, so those stay.

    - Checked by stripping all whitespace from each file before and after,
      which is the only guarantee perltidy actually makes, so those four
      semicolons are the whole of the difference. The suite passes either
      way: 160 files and 2927 tests from dzil test --all, and 160 files
      and 2531 tests in each of the XS and pure Perl built distributions.

    - No .perltidyrc is checked in, so this records the result rather than
      the settings that produced it, and nothing stops the files drifting
      apart again.

    - Name an undefined packed argument in the error, instead of warning
      first and then reporting a length of zero. The guards read their
      argument with length() and then did arithmetic or a comparison on
      the result, so an undef reached an operator first and perl warned
      about a value inside the library, at a line the caller cannot act
      on, before the check that names the function could run:
          inet_ntoa(undef)    Use of uninitialized value in numeric eq
                              (==), at InetBase.pm line 332
                            Bad arg length for ...::inet_ntoa, length is
                            should be 4
          hasbits(undef)      Use of uninitialized value in numeric ne
                              (!=), at UtilPP.pm line 137
                            Bad arg length for ...::hasbits, length is 0,
                            should be 128
      Both halves were wrong. The zero described a length nobody passed,
      and inet_ntoa interpolated an empty string because length(undef) is
      the empty string, so its message named the function and the expected
      width but no length at all. The message now says the length is
      undefined, and nothing warns on the way to it.

    - Fixed in both implementations, which have to agree: NetAddr::IP::Util
      is native by default and falls back to UtilPP, and the XS half got
      there differently. It declares its arguments as SV *, and SvPV
      turned an undefined argument into an empty string with a length of
      zero without complaining, so it reported the same misleading zero
      and perl's "Use of uninitialized value in subroutine entry" warning
      fired from the caller's line. Each XS function now tests SvOK
      before it calls SvPV.

    - inet_ntoa and ipv6_ntoa are pure perl with no XS counterpart, so
      they only needed the guard. ipv6_ntoa was also handing an undefined
      argument to Socket6::inet_ntop, which reported a length of 0 for
      something that had none.

    - A wrong but defined length is still measured and reported as before,
      so "ab" still gives 2 and not undefined.

    - Fix addition and subtraction accepting a constant that is not a
      number (GH#89). The guard compared $const == int($const), and perl
      numifies both sides first, so a string passed as its leading digits
      or as zero:
          - '5abc' added or subtracted 5
          - '0x10' and '0b11' added 0, which reads as no change at all
    - looks_like_number now runs ahead of the guard, and subtraction
      negates only what is a number so the guard sees the original
      otherwise. Hex, binary, 0o and empty strings are rejected. Padded
      and exponent strings, and a Math::BigInt constant, are unaffected.
      The POD in both IP.pm and Lite.pm said only that the constant must
      be an integer, and now says a non-numeric string croaks.

    - Keep the documented behaviour for a missing or zero constant, which
      returns a copy. Nothing tested it before, so the new tests pin it:
      undef and the empty string still return a copy for both operators,
      where subtraction previously died inside the negation and addition
      returned a copy.

    - Fix both SYNOPSIS use lists, which carried their annotations as qw()
      members, so each module tried to import a symbol named DEPRECATED and
      Lite.pm one named ! as well (GH#83)

    - Consolidate the scattered deprecation notes in IP.pm and Lite.pm into a
      DEPRECATED section under EXPORT_OK, and state there that everything
      listed is going in version 5:
          - the promise was only ever attached to a markdown ###### banner in
            a POD verbatim block, and in Lite.pm that sat 58 lines into the
            new_cis6 item body
          - :rfc3021 said only "a future version", and new_cis and new_cis6
            carried no removal version at all
          - :rfc3021, new_cis and new_cis6 are now covered by the promise
    - Each item names its replacement. :old_nth is left out, being a
      compatibility switch that has never been marked deprecated and has no
      replacement.

    - Warn in the deprecated category when :aton, new_cis or new_cis6 is
      used, naming the replacement in the warning (GH#49). None of the three
      warned before, though all were marked deprecated:
          - :aton warns on import in both IP.pm and Lite.pm
          - new_cis and new_cis6 warn on call; they are defined once in
            Lite.pm and reached from IP.pm via AUTOLOAD
    - Behaviour of all three is unchanged, except under use warnings
      FATAL => 'all', where the new warning dies; no warnings 'deprecated'
      silences it. For an import like :aton that silence has to come
      before the use, since the import runs at BEGIN time.

    - Require Math::BigInt 1.99, the last release before perl 5.14 (GH#44)

    - Remove duplicate NAME section from the Constants.pm POD

    - Adjust Constants.pm POD: name each constant with its sigil and
      indent descriptions consistently

    - Convert SEE ALSO sections to L<...> links and drop the (3) suffixes

    - Uniform code formatting across lib/, following UtilPP.pm:
          - 4 spaces per indent level, no tabs
          - space after commas, my (...) rather than my(...)
          - =item rather than =item *
          - else and elsif on their own line, not cuddled to the brace
    - POD is unchanged by the reindent; verbatim examples keep their
      two-space first level.

    - Fix {1,3} regex quantifiers broken by a stray space, which had
      disabled the mixed hex/dot-quad branch of InetBase::ipv6_aton and
      the masklen check in coalesce

    - Write the shipped Makefile.PL source as inc/MakeMaker/header.pl and
      reapply the style pass there, so the tarball no longer ships the
      old use vars, indent and =item * forms (GH#85)

    - Drop AutoLoader from the prerequisites; nothing loads it since GH#70

    - Drop vars from the prerequisites; generated Util_IS.pm now declares
      its version with our $VERSION

    - Remove the Math::BigInt emulation switch from Lite.pm (GH#84):
          - _force_bi_emu and $no_mbi_emu are gone, and _loadMBI always
            runs the require, so bigint() no longer croaks on a host that
            has Math::BigInt installed
          - drop the stale note on the three known Math::BigInt flavors

    - Document the numeric() comparison hazard in the Lite.pm POD: an
      ipV6 value has more digits than a Perl number holds, so ==, <=> and
      sort treat distinct addresses as equal (GH#84)

4.080_02  2026-09-29 17:02:48+10:00 Australia/Sydney (TRIAL RELEASE)

    - Fix re6() to support compressed IPv6 addresses (::) and shortened
      groups (GH#14)

    - Fix bcd2bin/bcdn2bin error messages to show correct function
      name (GH#78)

    - Add :all export tag to NetAddr::IP::Constants (GH#81)

    - Remove broken _bi_fake fallback in bigint(): Math::BigInt now required
      for bigint() support, added to RuntimeRecommends (GH#44)

    - Fix SYNOPSIS in IP.pm and Lite.pm (GH#74 items 3-9):
          - Fix within() example, consolidate my $ip declarations
          - Fix prose indentation, typo "Domanin" -> "Domain"
          - Fix unbalanced parenthesis, fix
            Zeros/Ones/V4mask/V4net description

    - Fix comment in Lite.pm: 0xfffffffe is 2**32 - 2, not 2**32 - 1 (GH#79)

    - Fix module load without resolver: replace inet_aton('255.0.0.0') with
      pack() (GH#69)

    - Fix Storable hooks: install at file scope, :old_storable is
      sticky (GH#8)

    - Re-enable tail-call goto dispatches removed by the dead-code cleanup:
          - IP.pm: splitref/rsplitref -> goto &_splitref
          - UtilPP.pm: addconst/add128/sub128 -> goto &slowadd128
          - UtilPP.pm: bcd2bin -> &_bcdcheck; goto &_bcd2bin
          - UtilPP.pm: bin2bcdn -> goto &_bin2bcdn
          - UtilPP.pm: comp128 restored to return ~ $_[0]

    - Convert @ISA + require Exporter to use parent in all modules

    - Replace use vars with our declarations, consolidate declaration + init

    - Convert tabs to spaces and fix POD indentation in IP.pm and Lite.pm

4.080_01  2026-09-22 09:08:35+10:00 Australia/Sydney (TRIAL RELEASE)

    - Validate masklen and number in coalesce, croak on bad arguments (GH#40)

    - Fix coalesce on subclass objects (GH#38)

    - Fix coalesce to count subnet addresses, not usable hosts (GH#37)

    - new6() returns compatible form for IPv4-only hosts, not mapped
      form (GH#64)

    - Add neg and abs overloads with clear error messages (GH#67)

    - Anchor bracket notation match to reject text outside brackets (GH#68)

    - Fix licence metadata and restore Artistic text (GH#56)

    - new6FFFF returns undef on invalid input instead of unblessed hash
      ref (GH#65)

    - BREAKING: re() on IPv6 objects in IPv4 space no longer emits a broken
      regex (GH#34)

    - BREAKING: re6() now returns a non-capturing group (?:...) (GH#50)

    - new6() now prefers AAAA over A for dual-stack hostnames,
      RT#119858 (GH#32)

    - Deprecate :rfc3021 tag; hostenum/hostenumref return 2 hosts for /31 and
      /127 unconditionally (GH#26)

    - BREAKING: new(undef) returns undef instead of the default route (GH#29)

    - Fix is_local for IPv4 loopback held in IPv6 objects (GH#27)

    - Fix pure-Perl _bcdcheck error messages (GH#23)

    - Remove dead branch in _splitplan, use named loop variable (GH#18)

    - Add BCD boundary input test suite (GH#51)

    - Preserve caller $@ and $SIG{__DIE__} on oversized decimal in
      new() (GH#59)

    - Localize $SIG{__DIE__} in module load eval probes, RT#130949 (GH#30)

    - Fix POD spelling mistakes: complier, alway, netowrk, occurence,
      RT#114239 (GH#47)

    - Prevent re() from matching addresses embedded in longer dotted
      strings (GH#35)

    - Reject cross-family and non-object arguments in within() and
      contains() (GH#28)

    - Remove faulty _splitplan pre-check that rejected valid short
      plans (GH#58)

    - Fix Compact merging v4 with v6 and mutating arguments (GH#15)

    - Fix compactref on subclasses (GH#16)

    - Reject bracket-enclosed IPv4 literals (GH#60)

    - Assert mode() matches Makefile.PL build choice (GH#61)

    - Reject empty string mask in constructor (GH#3)

    - Croak on swapped subtraction constant - object (GH#24)

    - Fix plus() alias for zero and silent no-op outside 32-bit range (GH#25)

    - Detect overflow in decimal integers, return undef in constructor (GH#19)

    - Support [addr]/mask URI bracket notation (GH#2)

    - Fix _splitplan netlimit pre-check and croak (GH#17)

    - Reject non-integer indices in nth() (GH#10)

    - Fix 0b/0x literal parsing using oct() instead of string eval (GH#4)

    - Reject non-ASCII digits in IP parsing

    - Fix version() for large decimal integers, RT#117995 (GH#31)

    - Document coalesce() behavior for equal-length masks (GH#45)

    - Fix bcdn2bin length check to report digits not bytes (GH#53)

    - Make Socket6 an optional recommends, not hard prereq (GH#54)

    - Modernize POD: indirect object syntax and RFC 5737 doc addresses

    - Bump perl requirement to 5.014 and fix Test2 imports (GH#57)

    - Remove Perl 5.10 and 5.12 from CI matrix (GH#57)

    - Consolidate sub-distributions into conventional Dist::Zilla layout

    - Convert all test files to Test2::V1

    - Fix :nofqdn import tag to actually set the flag, RT#111301 (GH#1)

4.079 2016-03-25T16:18:26-07:00

    - correct non-suppression of leading zeros in certain instances of new_no
      use. Thanks to "Mike Bartman (mbartman)" <mbartman@cisco.com> for
      spotting the bug.

    - put in missing code to propagate NetAddr::IP::Lite :nofqdn to IP.pm

4.078 2015-08-17T15:35:28-07:00

    - fix typo in Util.pm 1.53 MakefilePL that cause compiler to not be found
      at all

4.077 2015-08-14T01:17:23-07:00

    - re-numbered because of CPAN upload issue

4.076 2015-08-13T22:44:48-07:00

    - added method is_local() to Lite.pm inspired by Xan Charbonne

    - fix Util Makefile.PL to accomodate bug in Android's sh

    - add method full6m() inspired by abraxxa@cpan.org

    - fix Util/Makefile.PL issue with clang compiler, bug 86831

4.075 2014-06-11T11:41:17-07:00

    - make CPAN happy with new rev number

4.074 2014-06-11T09:36:10-07:00

    - In Lite.pm v1.54, change input filter for resolvable hostnames to allow
      the underscore character
    - Thanks to grankio [...] gmail.com for the heads up on this issue.

4.073 2014-04-05T09:32:11-07:00

    - add documentation about FQDN conversion and an option to disable

4.072 2014-01-27T11:59:58-08:00

    - modify Makefile.PL to bypass missing 'pod2text'

4.071 2013-09-30T13:41:03-07:00

    - add method "canon" by request from <tom.jones@bccx.com>

4.070 2013-09-12T12:54:22-07:00

    - nth documention error fixed. thanks to Anton tobez@tobez.org

    - Lite v1.51, add new6FFFF, RFC4291 compliant ipv4->ipV6 new

4.069 2013-05-25T15:10:45-07:00

    - In Lite.pm v1.50, add =encoding UTF-8
    - In Util.pm v1.50 changed Makefile.PL to check for config.h when building
      for XS with 'gcc', try building with 'cc', and check again. If config.h
      is not found, force Pure Perl mode.

    - Kill XS in winduhs and Darwin, both of which misbehave when compiling
      XS code

4.068 2013-04-03T10:52:24-07:00

    - update Makefile.PL in Util.pm v 1.49 to better detect 'winduhs'

4.067 2013-03-30T12:57:20-07:00

    - Improved diagnostic message for "die" with bad mask for hostenum,
      hostenumref, split, splitref, rsplit, rsplitref
    - Thanks to GENSYM@cpan.org for pointing out the need.

4.066 2012-10-29T13:30:14-07:00

    - update Lite.pm v1.47 to support bracketed IPv6 URI notation as described
      in RFC-3986
    - Thanks to Quanah Gibson-Mount mishikal@yahoo.com

4.065 2012-10-02T12:36:11-07:00

    - correct format for IPv6 embedded IPv4 addresses in InetBase v0.8

4.064 2012-09-25T13:54:47-07:00

    - added support for rfc3021 /31 networks to hostenum

4.063 2012-08-10T11:46:18-07:00

    - Updated GPL v2.0 text and address in all modules

4.062 2012-06-06T12:34:48-07:00

    - documentation updates courtesy of Ben Bullock
      <benkasminbullock@gmail.com>
    - Thank you Ben.

4.061 2012-05-08T16:24:03-07:00

    - fixed bug in Lite v1.44 that returned $ip->num() = 2^128 for 0.0.0.0/0
    - Thanks to Sebastian <debug@test1.org> for spotting it.

4.060 2012-04-06T16:00:02-07:00

    - In Lite.pm v1.43, fix bug #75976, change in behavior introduced in
      v4.050 where an empty string supplied to "new" previously returned
      'undef' and now returns 'default' for ipV4 or ipV6

4.059 2012-03-07T12:50:04-08:00

    - add is_rfc1918 to Lite.pm v1.42

    - documentation updates

4.058 2011-11-11T19:23:11-08:00

    - up rev for documentation update
    - update documentation in InetBase v0.06

4.057 2011-11-11T15:04:20-08:00

    - Lite.pm v1.40 add call to InetBase::fillIPv4 to all uses
      of gethostbyname

    - break out the code in InetBase v0.05 that expands short IPv4 addresses
      into dotquad format to account for broken BSD implementations of
      inet_aton and gethostbyname that do not recognize the short format.
      EXPORT this as sub 'fillIPv4'

    - in Util.pm v1.45, add 'fillIPv4' to calls to gethostbyname to work
      around broken inet_aton and gethostbyname implementations in certain
      BSD implementations

4.056 2011-11-02T19:15:31-07:00

    - bump rev to incorporate improved inet_aton in InetBase v0.04 to overcome
      broken gethostbyname found in NetBSD and OpenBSD

4.055 2011-10-28T11:41:22-07:00

    - in Lite.pm v1.38 patch for bug 71869, issues with Math::BigInt varients

4.054 2011-10-27T12:48:55-07:00

    - In Lite.pm v1.37, remove Calc.pm
    - add detection of early Math::Bigint object structure
    - fix bug 71869 - a failed test routine

4.053 2011-10-26T08:52:34-07:00

    - In Lite.pm v1.36 fix bug #71925. A a sub-varient of #62521 that showed
      up only for short notation for IPv4. i.e. 127/n, 127.0/n, 127.0.0/n but
      not 127.0.0.0/n

4.052 2011-10-25T16:18:38-07:00

    - add test in Lite.pm v1.35 for api-version of Math::BigInt to support
      versions earlier than 1.70, circa Dec 2003.
    - Thanks to Paul Howarth <paul@city-fan.org> for spotting that bug.

4.051 2011-10-24T14:44:53-07:00

    - fix bug 71869 in Lite.pm v1.34 use Math::BigInt::Calc for creating
      BigInt values and fall back to NetAddr::IP::Calc if Math::BigInt is
      not present.

    - remove reference to Config{osname} in InetBase.pm v0.03 (Util 1.43)

4.050 2011-10-22T01:58:57-07:00

    - In Lite/Util/lib/NetAddr/IP/Lite/Util/InetBase.pm v0.02 Socket6 prior to
      version 0.23 does not have AF_INET6 in the EXPORT_OK array, modify
      InetBase.pm v0.2 to work around this.

    - Add support for Math::BigInt to NetAddr::IP::Lite v1.33

4.049 2011-10-15T22:15:10-07:00

    - Updates to Lite.pm, Util.pm, new module InetBase.pm

    - In Lite v1.32 bug68723, add capability to parse input of the form
      ->new6(12345,1). This should have been there but was missing. Thanks to
      Andrei Benea for spotting this.

    - In Util v1.41 add inet_pton, inet_ntop, AF_INET, AF_INET6

    - modify inet_n2dx and inet_n2ad to recognize the new 128 bit IPv4
      format ::FFFF:FFFF:0:0

    - replace isIPv4 with a pure perl version for portablity

    - split the following into NetAddr::IP::InetBase v0.01 to provide better
      long term support for IPv6
          - inet_aton
          - inet_ntoa
          - ipv6_aton
          - ipv6_n2x
          - ipv6_n2d
          - inet_any2n
          - inet_n2dx
          - inet_n2ad
          - inet_ntop
          - inet_pton
          - packzeros
          - isIPv4
          - isNewIPv4
          - isAnyIPv4
          - AF_INET
          - AF_INET6

4.048 2011-10-08T01:33:44-07:00

    - remove debug print statement from Util v1.40

4.047 2011-10-06T23:41:42-07:00

    - really correct missing reference in Util v1.39
    - doc update only in Lite.pm v1.30

4.046 2011-10-06T20:20:33-07:00 DEPRECATED

    - corrected missing reference to inet_4map6 in Util v1.38

4.045 2011-10-06T18:23:04-07:00 DEPRECATED

    - updated NetAddr::IP::Util 1.37
    - addid isAnyIPv4, isNewIPv4, inet_4map6
    - revised naip_gethostbyname to conform to Perl's gethostbyname output

4.044 2011-05-18T14:47:34-07:00

    - added missing support for ->compactref(\@list) which is described in the
      documentation but not implemented.

    - Thanks to Rusty Bourland codebard@gmail.com for spotting this and
      providing both a patch and test code

4.043 2011-04-06T11:31:19-07:00

    - Update documentation on the use of "adding constants to an IP address".

4.042 2011-03-22T15:26:02-07:00

    - Update Lite.pm v1.27 to encompass treatment of /31 and /127
      point-to-point networks as described in RFC 3021

    - NOTE: for /31's and /127's this changes the behavior of the
      following methods:
          first   returns the "network" address
          last    returns the "broadcast" address
          nth     index 0 returns "network" addr instead of undef
          nth     index 1 returns "broadcast" addr instead of undef
          num     returns 2 instead of 0 (zero)

    - "old_nth" behavior is unchanged

    - Thanks to Todd Caine todd.caine@gmail.com for pointing this out.

4.041 2011-03-08T15:18:16-08:00

    - Updated Lite.pm v1.26, "sub num" to support usable IP ranges greater
      than 2**32

    - Thanks to Jan Ploski jan@plosquare.com for finding this bug

4.040 2011-02-19T10:04:00-08:00

    - correction to use of Util.pm package lexicals

    - thanks to mishikal@yahoo.com for spotting the bug and to Mark Martinec
      mark.martinec+ama...@ijs.si for the solution.

4.039 2011-02-16T15:48:03-08:00

    - Correct documentation for 'split' methods

4.038 2010-12-17T17:47:47-08:00

    - Modify subs "new" and "new6" in Lite.pm to accomodate Cisco mask syntax
      that uses space instead of "/" for a separator
    - This eliminates the need for "new_cis" and "newcis6" which are
      now deprecated.

    - Modify LIte/t/v4-cnew.t and add Lite/t/v6-cnew.t to test the above

4.037 2010-11-19T10:48:01-08:00

    - add :upper and :lower to Lite.pm v1.23
    - add comments about rfc5952 requirement for lowercase ipV6 notation in
      Lite.pm v1.23 and IP.pm
    - add test for :lower in Lite.pm v1.23

4.036 2010-11-16T16:28:37-08:00

    - In Util.pm v1.35, naip_gethostbyname modified to return undef instead of
      0 (zero) on failure

    - thanks to Terry Cassidy enaudishaylee@tc17.com for the bug report

    - In Util.pm v1.35, move sub's ipv6_n2d and ipv6_n2x to non-autosplit
      portion of module to eliminate warnings during autosplit of
      "our" variables

    - thanks to Nicholas Bamber <nicholas@periapt.co.uk>
    - Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=517361

    - In Lite.pm v1.22, update new6 to properly classify short ipv4 notation
      i.e. 127/8 with test for ":" rather than match for \d.\d.\d.\d

    - thanks to Steve Huff (SHUFF) * shuff@cpan.org for spotting that bug.

    - In Lite.pm v1.22, update t/v4-new.t for deprecated array syntax in
      perl 5.13
      was:    qw(...stuff...)
      is:     (qw(...stuff...))

    - thanks to Todd Rinaldo <toddr@cpan.org> for reporting this

4.035 2010-10-28T14:26:19-07:00

    - fix bug in Lite v1.21 where new6 improperly assigns the mask value for
      and ipv4 address in 32 bit space instead of 128 bit space

    - Thanks to Mark Martinec and Steve Huff (SHUFF) * shuff@cpan.org for
      spotting and replicating that bug

    - added new_cis and new_cis6 to Lite.pm v1.21 to accomodate Cisco syntax
      that has IP and MASK separated by a space.

    - Updated typo in documentation that left out example print new6 stuff

4.034 2010-10-25T16:22:01-07:00

    - Updated Lite::_xnew v1.20 to properly handle ipV6 notation of the form
      xxxx:xxxx:xxxx:xxxx:xxxx:xxxx, DDD

    - Thanks to Dusty Mabe <Dusty.Mabe@tekelec.com> for spotting this bug

4.033 2010-09-29T10:32:50-07:00

    - Conditionalize import of AF_INET6 in Util.pm NetAddr::IP::UtilPolluted

4.032 2010-09-22T13:39:08-07:00

    - Added overload => 'ne' and '!=' to Lite.pm v1.18

4.031 2010-09-21T19:21:04-07:00

    - Pull Socket6 stuff out of Lite 1.17 and put into NetAddr::IP::Util.pm
      1.33 in its own namespace

4.030 2010-07-20T15:32:23-07:00

    - Resolve named hosts in Lite.pm using gethostbyname, followed by
      gethostbyname6 to determine whether to set ipV6 flag

    - Thanks to Dusty Mabe <Dusty.Mabe@tekelec.com> for spotting this bug

4.029 2010-07-08T18:17:38-07:00

    - In NetAddr::IP::Lite, added support for the sub "new" to resolve host6
      names if the OPTIONAL perl Socket6 module is available

    - Thanks to "Mabe, Dusty" <Dusty.Mabe@tekelec.com> for spotting this and
      suggesting a fix.

4.028 2010-05-12T14:18:20-07:00

    - In /Lite/Util/Util.xs v1.32, changed netswap() to postincrement *a++ =
      to *a and added increment after save to mollify some picky compilers
      that return possible undefined behavior.

    - changed type of _128x10 to 'void'

    - Thanks to David Bolt <dbolt@davjam.org> for the above two patches

4.027 2009-06-09T10:31:11-07:00

    - In NetAddr::IP::Util v1.31, ferret out shell value for Makefile.PL when
      calling ./configure for systems where the 'x' bit gets lost due to bug
      in Archive::Tar

4.026 2009-03-07T16:35:33-08:00

    - make the compiler test check the environment for CC before using Perl's
      default compiler

4.025 2009-03-07T16:15:18-08:00

    - revised compiler test in Makefile.PL for Util v1.29 to accomodate picky
      Solaris "cc"

4.024 2009-01-26T00:27:32-08:00

    - documentation update

4.023 2009-01-16T14:30:40-08:00

    - added the capability to set the CASE of ipV6 text return values to
      either upper or lower. Thanks to Rob Riepel
      <riepel@networking.Stanford.EDU> for developing this improvement and
      providing a comprehensive patch

4.022 2008-12-20T13:05:01-08:00

    - In Util.xs 1.28 set uninitialized "carry" in XS bin2bcd to zero

    - This insidious bug only showed up on 64 bit hosts running perl 5.6.2
    - Thanks to Oliver Paukstadt <pstadt@sourcentral.org> for taking the time
      to do the testing for me on his s390 system.

4.021 2008-12-10T11:09:36-08:00

    - Removed test code that produces a warning about all perl versions,
      OOPS!! instead of just the buggy 5.8.0 - 5.8.5 versions.
    - Thanks to paul@city-fan.org for reporting this.

4.020 2008-12-09T16:25:46-08:00

    - cleaned up various typo's with good patch from Rob Riepel
      <riepel@networking.Stanford.EDU>
    - thanks Rob.

    - revised UtilPP v1.7 to work around perl 5.8.4 failures with certain @_
      operations of goto &sub... see perl bug [ 23429]. Unfortunately,
      perl-5.8.4 is the distribution of choice for many solaris boxes

4.019 2008-11-29T15:15:30-08:00

    - in Lite/Util, add pure perl testing to XS build

4.018 2008-11-28T23:19:01-08:00

    - revised XS code to be full re-entrant, thread safe in Util.xs v1.26
    - removed all traces of mutex locks in Util.xs v1.26
    - removed function 'threads' here an in UtilPP v1.6

4.017 2008-11-23T19:32:59-08:00

    - Extended the capability of 'splitref' to allow splitting of objects into
      multiple pieces with differing CIDR masks. Returned object list can be
      split from bottom to top or from top to bottom depending on which method
      is called
          split, rsplit, splitref, rsplitref

    - Thanks to kashmish <kashmish@gmail.com> for the idea on improving
      functionality of 'split'.

    - Thanks to Rob Riepel <riepel@networking.Stanford.EDU> for a faster and
      more accurate _compV6 function.

    - in UtitPP v1.5 correct documentation error
    - add threads reporting (empty string)

    - in Util v1.25 add threads reporting that returns a comma separated
      string of build headers.

    - added what is hopefully thread safe operation via serialization. Must be
      invoked by "--with-threads"

    - in Lite v1.12 corrected missing Zeros subroutine
    - Zeros and Zero both will work

    - in Lite v1.12 added minus (-) overloading to allow the subtraction of
      two NetAddr::IP objects to get the difference between the
      object->{addr}'s as a numeric value
    - Thanks to Rob Riepel <riepel@networking.Stanford.EDU> for the initial
      code and inspiration for this enhancement

4.016 2008-11-05T18:13:20-08:00

    - in Util/ version 1.24 Clean up Makefile.PL to check actual required link
      libraries against the perl build for consistency

4.015 2008-11-02T10:10:38-08:00

    - in Util v1.23 add missing headers in configure and localconf.h for
      Solaris inet_xton
    - thanks to Karl Bunch <karl@digilink.net> for spotting the bug.

4.014 2008-11-01T15:13:48-08:00

    - in Lite.pm v1.11, add test for characters not allowed by rfc952 before
      the call to gethostbyname in sub new() for those people that insist on
      using deprecated functionality :aton and OS's that fail to notice calls
      to gethostbyname with binary arguments.

4.013 2008-10-22T15:04:49-07:00

    - In Lite.pm v1.10, add new no octal method for improperly formatted
      ipV4 addresses

    - In Util.pm v1.22, eliminated dependence on PL_sawampersand
    - thanks to Mark Martinec <Mark.Martinec@ijs.si> for spotting this and
      submitting a patch.

    - In Util.pm v1.22, force -noxs mode for Win32

    - In Util.pm v1.22, use autoconf to configure 'C' build

4.012 2008-10-16T19:35:33-07:00

    - clear build bug for Win32 in Util.pm v 1.21

4.011 2008-10-06T13:10:00-07:00

4.010 2008-09-27T17:00:28-07:00

    - in NetAddr::IP::Util v0.19 updated test for ENDIANess in siteconf

    - add test in inet_aton to detect overange IP dot quad values missed by
      some broken Socket implementations i.e. 256.1.1.1 would fail to
      return undef

    - NOTE: Versions 4.008 and 4.009 had limited release to tester only and
      were not uploaded to CPAN. All of the v4.008, 4.009 changes are
      incorporated in v4.010

4.009 2008-09-02T19:09:57-07:00

    - In NetAddr::IP::Lite v1.07, in the off chance that NetAddr::IP::Lite
      objects are created and the caller later loads NetAddr::IP and expects
      to use those objects, let the AUTOLOAD routine find and redirect
      NetAddr::IP::Lite method and subroutine calls to NetAddr::IP.

    - updated Lite/t/v4-wnew.t so that non-existent domains are "really"
      not there

4.008 2008-06-07T14:01:55-07:00

    - inherit method "new_from_aton" from NetAddr::IP::Lite
    - add related documentation

    - Inherited methods from Lite.pm updated as follows:

    - comparisons of the form <, >, <=, >=
          10.0.0.0/24 {operator} 10.0.0.0/16
      return now return the comparison of the cidr value when the address
      portion is equal.
    - NOTE: this comparison returns the comparison of the NUMERIC value of the
      CIDR. This produces the counter intuitive result that /24 > /16. There
      is logic to this, really! For proper operation of commands like
      "Compact" and "Coalesce", lists of netaddr objects must sort in
      ascending order. However, this conflicts with the requirement for larger
      netblocks to sort FIRST so as to include smaller ones. This logic
      extends to any requirement for a sort of netaddr objects. It should be
      further noted that the mixing of netaddr objects with varying IP
      addresses and CIDR allocations can lead to unexpected results since the
      comparisons done first on the IP portion and then on the CIDR portion.
      The documentation has been updated appropriately.
    - Thanks to Peter DeVries for spotting this discrepancy

4.007 2007-06-06T16:41:11-04:30

    - Update copyright dates

4.006 2007-06-06T15:58:04-04:30

    - A patch from Michael got rid of $& and $` as reported by Daryl O'Shea
      and documented at
      http://issues.apache.org/SpamAssassin/show_bug.cgi?id=5312

4.004 2006-08-16T16:01:54-07:00

    - update to include/exclude files in corrupted distro

4.003 2006-08-06T10:48:25-07:00

    - correct SYNOPSIS documentation
    - add :old_nth

    - update Lite.pm documentation
    - update Util.pm documentation
    - Imported into distribution CVS tree - Some revision number mismatches
      are to be expected
    - Latin-1 is back
    - Fixed some angle brackets so that they show up in the docs

4.002 2006-08-04T14:14:16-07:00

    - remove unused global variable $isV6

    - update Lite.pm to v1.02
    - $isV6 global converted to a lexical variable within sub "_xnew"
    - $Class global removed and replaced by calls to UNIVERSAL::isa
    - Thanks to julian@mehnle.net for spotting problems related to using the
      Lite.pm with mod_perl

4.001 2006-07-06T14:09:01-07:00

    - various bug fixes courtesy of Luis Munoz: changes to Lite.pm v1.01,
      Util.pm v0.17 see Changes in those distros.
    - update t/v6-re.t, addconst called as a scalar, should be called to
      return the address value ()[1]

4.000 2006-06-19T21:51:10-07:00

    - initial release of version 4.000 which includes full support of ipV6
      addresses and drops the requirement for Math::BigInt and will run on
      older versions of Perl at least back to 5.005_03
