PrePAN

Sign in to PrePAN

Net-NameGoesHere Sane APIs for single IP addresses and subnets

Good

Synopsis

use Net::NameGoesHere::IPAddress;

my $ip = Net::NameGoesHere::IPAddress->new( address => '1.2.3.4' );
print $ip->as_string;
print $ip->as_integer;
print $ip->as_bit_string;

my $next = $ip->next_ip();
my $prev = $ip->previous_ip();

if ( $ip < $next ) { .. }

my @ips = sort ( $next, $prev, $ip );

# All the same operations work with IPv6 as with IPv4
my $ip = Net::NameGoesHere::IPAddress->new( address => 'ffff::a:1234' );

my $ip = Net::NameGoesHere::IPAddress->new_from_integer(
    integer => 0,
    version => 4,
);

use bigint;
my $ip = Net::NameGoesHere::IPAddress->new_from_integer(
    integer => 2**128 - 1,
    version => 6,
);

use Net::NameGoesHere::Subnet;

my $net = MM::Net::Subnet->new( subnet => '1.1.1.0/28' );
print $net->as_string;
print $net->netmask; # 28

# first & last include network & broadcast addresses
my $first_ip = $net->first(); # 1.1.1.0
my $last_ip = $net->last(); # 1.1.1.15

my $iter = $net->iterator();
while ( my $ip = $iter->() ) { ... }

my $net = MM::Net::Subnet->new( subnet => '1.1.1.4/32' );
print $net->max_netmask; # 30

# IPv4 and IPv6 subnets work exactly the same way
my $net = MM::Net::Subnet->new( subnet => 'ffff:ff00::/105' );

my @subnets = MM::Net::Subnet->range_as_subnets( '1.1.1.1', '1.1.1.32' );
print $_->as_string, "\n" for @subnets;
# 1.1.1.1/32
# 1.1.1.2/31
# 1.1.1.4/30
# 1.1.1.8/29
# 1.1.1.16/28
# 1.1.1.32/32

# Removes reserved subnets like 10.0.0.0/8 as part of the splitting process
my @subnets = MM::Net::Subnet->range_as_subnets( '1.1.1.0', '255.255.255.255' );

Description

This is a distro we created in-house to make it easier to work with IP addresses and subnets. There was no single module or distro that did everything we wanted.

The code in question is in the top-level lib and t dirs of the linked repo.

Right now this is a wrapper around the NetAddr-IP module, but in the future it's possible we'd write out own code from scratch (yay, tests). Our API smooths over a lot of crazy rough edges in NetAddr::IP and makes sure everything "just works" for IPv4 and IPv6.

What we really need is a name for this distro.

It covers both single address and subnets, and the existing modules on CPAN have used up basically every good name.

I was thinking of something like Net::Sweet or Net::Sane but I'm open to something better.

Comments

Can you explain more which methods you are missing in NetAddr::IP?
I'd prefer to extend it instead of creating another module, the author responds quickly to feature requests.
What I've been missing in it is a IPv4 and IPv6 only class so I can be sure that an object is one or the other.
Also NetAddr::IP is XS for speed with a pure-perl fallback if needed.
This class currently wraps NetAddr::IP so speed isn't a huge issue.

What's missing is separate classes for addresses vs subnets, a sane iterator (first/last, nth), and a generally less quirky API.

See the synopsis for examples.
So add them to NetAddr::IP instead of creating yet another module.
Net::Works
@abraxxa, I'm not sure there's a place for all this stuff in NetAddr::IP, which is why I created these wrappers. Some of what I want is to just backwards incompatible, so either there'd have to be two iterator APIs or there's be a breaking change.
I looked at the NetAddr::IP docs again regarding the iterator.
Do you mean the various split and hostenum methods? I personally don't see a problem in adding another iterator API, but ask the author what his view on this is.
I rarely use an iterator, most of the time I need to know if one network or address is included in some other network.

Regarding the naming I don't like 'Subnet', it should just be 'Network', 0.0.0.0/0 is a network but not a subnet.
And if the whole module is about IP it should be 'Address' instead of 'IPAddress'.
Net::IP::Address and Net::IP::Network are my suggested names if you really want to create a new module.
Sugar subclasses would be Net::IP::Address::v4, ::v6 and Net::IP::Network::v4 and ::v6.
None of your IP addresses ever have network masks? You never need limits on your next and previous IP addresses? While some parts of your API are nice(r than NetAddr::IP) I'm not sure that something this specific to your needs has any real advantage over NetAddr::IP. If the NetAddr::IP API cannot be improved sufficiently for your needs I would rather see a more complete reimplementation/wrapper that doesn't only provide reduced functionality.

Please sign up to post a review.