Net::IP::Identifier - Identify IPs that fall within collections of network blocks


version 0.111


 use Net::IP::Identifier;
 use Net::IP::Identifier ( qw( Microsoft Google ) );


Net::IP::Identifier identifies IP addresses or netblocks that lie within a select group of pre-identified netblocks. This package contains a collection of identified entities (in the Plugins directory). These are either large, well known entities (i.e: Google and Microsoft) or they are owners of netblocks that have produced a lot of SPAM that arrived at my server.



This module is a modulino, meaning it may be used as a module or as a script. The run method is called when there is no caller and it is used as a script. run parses the command line arguments and calls new() to create the object. If a filename is specified, that file is read as the input, otherwise the command line is used.

Input (from a file or the command line) is scanned for things that look like IP (v4 or v6) addresses or blocks. For each matching item, the Net::IP::Identifer object's identify method is called on it (see below). If a match is found, the entity is printed, otherwise the original IP is printed.




    echo | /path/to/perl5/Net/IP/ 

prints 'Google'.

For command line help, run:

    /path/to/perl5/Net/IP/ --help
new( [ options ] )

Creates a new Net::IP::Identifier object. The following options are available, and are also available as accessors:

parents => boolean

A format modifier. See identify below.

cidr => boolean

A format modifier. See identify below.

joiners => ( [ IPv4_string, IPv6_string ] )

Returns a reference to an array of two strings to use when 'join'ing pieces. The default is [ ':', '.' ] which uses ':' on IPv4 addresses and '.' on IPv6 addresses.

entities ( [ @modules ] )

Returns the list of Plugin objects currently in use.

If @modules is defined, it should be an array of names of the Plugin objects to 'require' (they will replace the current list):

    $identifier->entities( qw(
    ) );

If no plugin modules are loaded, and @modules is not defined, the import list (defined at 'use' time) is loaded. If there is no import list, all available modules found in Net::IP::Identifier::Plugins are 'required' and matched against. Loading a reference to an empty array:

    $identifier->entities( [] );

also loads all available plugins.

modules may be passed as a reference to an array:

    $identifier->entities ( \@modules );

Plugins can also be loaded selectively at 'use' time (see SYNOPSIS).

identify( IP )

Try to identify IP with an entity. IP may be a Net::IP or Net::IP::Identifier::Net object or any of the string formats acceptable to Net::IP->new() or Net::IP::Identifier::Net->new().

If the IP cannot be identified with an entity, undef is returned.

If the IP belongs to an included identity (see PLUGINS), the return value is modified by the format flags.

When all modifiers are false, the return value is the name of the entity (e.g: 'Yahoo').

When cidr is true, the Net::IP::Identifier::Net object of the matching netblock is appended to the result.

When parents is true, any parent (and grandparent, etc) entities are prepended to the result.

Flags may be used concurrently.

In scalar context, a string is return where the pieces are joined using joiner. In array context, the array of pieces is returned.

join ( @parts )

Gets the joiners, then scans @parts looking for objects which can identify themselves as IPv4 vs. IPv6. Uses the appropriate element of joiners, and returns a 'join'ed string.


During construction of the binary tree, there may be netblocks that overlap with existing netblocks. This function checks the tree for overlaps. It returns an array where each element represents an overlap. Each overlap is an array of Net::IP::Identifier::Binode objects, the first one being the parent of the overlap, and subsequent entries in the array being the overlapping children.

When used as a modulino, the overlaps command line argument runs this method and prints the result.


Net::IP::Identifier uses the Module::Pluggable module to support plugins. See entities for details on controlling which Plugins are loaded.

Plugins uploaded to CPAN should be well known entities, or entities with wide netblocks. Let's not congest CPAN with a multitude of class C netblocks.

Entities with child netblocks can name them in a children subroutine. If you want to add a netblock as a child, you'll need to arrange with the parent's CPAN owner to add it. This relationship is independant of the network hierarchy, and is currently ignored by Net::IP::Identifier.

Plugins must satisfy the Net::IP::Identifier_Role (see Role::Tiny). Supplying the entity name and setting the list of netblocks in ips in the new method is sufficient. See the existing Plugins for examples.

Test your plugin by running with the overlaps flag. overlaps causes overlapping netblocks to be reported. Overlaps are not necessarily an error and there may be overlaps caused by modules other than your new Plugin.


The check_plugin script in the extra directory checks the IP addresses and blocks in your plugin source code. It can also be used on raw data such as a page from Hurricane Electric (thanks to Hurricane Electric for providing this information from their BGP Toolkit):[search]=baidu&commit=Search

Copy and paste the entire page into a file, then run:

    extra/check_plugin filename

The first part of the output is diagnostic output while running 'jwhois' commands. jwhois may fail to complete on some addresses. Sometimes re-running check_plugin resolves the issue. If not, remove that line from the file and verify that address 'by hand', perhaps using a web-based WHOIS such as

check_plugin builds a binary tree of the IP addresses and creates a list of the IP addresses and blocks, printing diagnostic information as it goes. You can invoke -v and -vv for extra levels of verbosity. Then check_plugin prints a line: 'Result:' followed by output suitable for inclusion in the Plugin module's $self->ips() declaration (in its new method).

You must provide a regular expression for matching the entity. check_plugin expects to find that entity somewhere within the WHOIS output (if not found, that net will not be included in the Results list). The regular expression is extracted from the last name in a 'package' declaration, from the file name, or from the text following '_ENTITY_REGEX_' on any line. The entity matching is done caselessly.

You can run, for example:

    extra/check_plugin [ -v | -vv ] lib/Net/IP/Identifier/Plugin/

to get a feeling for how it should look.


Net::IP::Identifier::Plugins::Google (and other plugins in this directory)


Reid Augustin <>


This software is copyright (c) 2014 by Reid Augustin.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.