NAME

NetAddr::IP::Count - Count addresses in named groups of subnets

VERSION

version 4.080_07

SYNOPSIS

use NetAddr::IP;
use NetAddr::IP::Count;

my $counter = NetAddr::IP::Count->new(
    customers => NetAddr::IP->new('198.51.100.0/24'),
    lab       => [
        NetAddr::IP->new('203.0.113.0/25'),
        NetAddr::IP->new('2001:db8::/32'),
    ],
);
$counter->add( 'customer-a' => NetAddr::IP->new('198.51.100.0/28') );

$counter->count( map { NetAddr::IP->new($_) }
      qw(198.51.100.1 198.51.100.77 2001:db8::1) );
$counter->valcount( NetAddr::IP->new('203.0.113.9'), 5 );

my $totals = $counter->result;
print "$_ $totals->{$_}\n" for sort keys %{$totals};
# customer-a 1
# customers 2
# lab 6

DESCRIPTION

Counts how many addresses fall in each named group of subnets, for example the visits in a web server log from each customer's networks. A group is a name and one or more NetAddr::IP subnets.

Each address counted adds to the total of every group with a subnet that contains it, once per group. Overlapping groups therefore each see the address: in the synopsis, 198.51.100.1 counts for both customers and customer-a. The totals do not depend on the order the groups were added or the addresses were counted, and with overlapping groups they add up to more than the number of addresses counted.

A subnet contains an address when $subnet->contains($address) is true, so an IPv4 address never counts in an IPv6 subnet, and the other way round.

This module has the interface of NetAddr::IP::Count 2.01, by Luis E. Munoz with valcount by Alvaro Carvajal, and replaces it. Where no two groups overlap, the totals are the same. Three things differ:

  • Overlapping groups. Version 2.01 counted an address in one group only, and which group depended on hash order, the order of the addresses and the cache size.

  • Arguments. Anything but a NetAddr::IP object where an address or subnet is expected, or anything but a number where a value is expected, croaks before any total changes. Version 2.01 stopped counting at the first false element of a list.

  • The cache. The cache method keeps its interface, but the size no longer changes how addresses are counted or how fast.

Constructor

NetAddr::IP::Count->new(%groups)

Returns a new counter holding the given groups, each with a total of zero. Each key is a group name, and each value is a NetAddr::IP subnet or a reference to an array of them, as add takes. Croaks on an odd number of arguments or on a subnet that is not a NetAddr::IP object. Called on a counter, it returns a new, empty counter of the same class.

my $counter = NetAddr::IP::Count->new(
    lab => NetAddr::IP->new('203.0.113.0/24') );
print join( ',', keys %{ $counter->result } ), "\n";    # lab

Groups

->add($name, @subnets)
->add($name, \@subnets)

Adds the subnets to the group called $name, creating the group with a total of zero if it is new, and returns the counter. Croaks when $name is undefined or a subnet is not a NetAddr::IP object.

$counter->add( lab => NetAddr::IP->new('2001:db8::/32') );

Counting

->count(@addresses)

Adds one to the total of every group with a subnet that contains each address, once per group, and returns the counter. Croaks, changing no total, when any element is not a NetAddr::IP object.

$counter->count( NetAddr::IP->new('198.51.100.1') );
->valcount($address, $value, ...)

Works as count does, but adds the value paired with each address instead of one. Croaks, changing no total, on an odd number of arguments, an address that is not a NetAddr::IP object, or a value that is not a number.

$counter->valcount( NetAddr::IP->new('203.0.113.9'), 5 );

Results

->result

Returns a new hash reference from each group name to its total, including the groups whose total is zero. Changing that hash does not change the counter.

my $totals = $counter->result;
print $totals->{lab}, "\n";    # 6, after the synopsis
->cache($size)
->cache

Returns the cache size before the call, 5 for a new counter, and sets it to $size when $size is zero or more. The size is kept for compatibility with NetAddr::IP::Count 2.01 and does not affect counting. Croaks when $size is given and is not a number.

my $old = $counter->cache(10);    # 5

SEE ALSO

NetAddr::IP

AUTHORS

  • Dean Hamstead <dean@fragfest.com.au>

  • Luis E. Muñoz <luismunoz@cpan.org>

  • Michael Robinton <michael@bizsystems.com>

COPYRIGHT AND LICENSE

This software is Copyright (c) 2026 by Dean Hamstead, Luis E. Muñoz, Michael Robinton.

This is free software, licensed under:

The MIT (X11) License

The full text of the license can be found in the LICENSE file included with this distribution.