File Coverage

lib/App/Tel/HostRange.pm
Criterion Covered Total %
statement 12 30 40.0
branch 1 12 8.3
condition 0 11 0.0
subroutine 4 5 80.0
pod 1 1 100.0
total 18 59 30.5


line stmt bran cond sub pod time code
1             package App::Tel::HostRange;
2              
3 7     7   20183 use strict;
  7         15  
  7         154  
4 7     7   32 use warnings;
  7         10  
  7         167  
5 7     7   768 use Module::Load;
  7         970  
  7         71  
6              
7             require Exporter;
8             our @ISA = qw(Exporter);
9             our @EXPORT = qw();
10             our @EXPORT_OK = qw ( check_hostrange );
11             our $_have_netaddr; # can't set a default because this happens after the BEGIN block
12              
13             # needed because CPAN won't index undef since it's a lower version number
14             our $VERSION = '0.201503';
15              
16             BEGIN {
17 7 50   7   925 if (eval { Module::Load::load NetAddr::IP; 1; }) {
  7         22  
  0         0  
18 0         0 $_have_netaddr=1;
19             } else {
20 7         6272 $_have_netaddr=0;
21             }
22             }
23              
24             =head1 NAME
25              
26             App::Tel::HostRange - Support for HostRanges
27              
28             =head1 SYNOPSIS
29              
30             if (check_hostrange($_, $host));
31              
32             Searches an IPv4 or IPv6 range to see if it contains a particular IP address.
33             Returns true if the host is contained in the range, false if it is not.
34              
35             =head1 AUTHOR
36              
37             Robert Drake, C<< <rdrake at cpan.org> >>
38              
39             =head1 COPYRIGHT & LICENSE
40              
41             Copyright 2015 Robert Drake, all rights reserved.
42              
43             This program is free software; you can redistribute it and/or modify it
44             under the same terms as Perl itself.
45              
46             =cut
47              
48             =head2 check_hostrange
49              
50             if (check_hostrange($rangelist, $host));
51              
52             Searches an IPv4 or IPv6 range to see if it contains a particular IP address.
53             Returns true if the host is contained in the range, false if it is not.
54              
55             This does no validation, leaving it all up to NetAddr:IP and the calling
56             function.
57              
58             This should support the following types of ranges:
59              
60             # 192.168.13.17-192.168.32.128
61             # 192.168.13.17-22
62             # fe80::1-fe80::256
63             # 192.168.13.0/24
64             # fe80::/64
65             # 192.168.13.17-192.168.32.128,172.16.0.2-172.16.0.13,172.28.0.0/24
66              
67             =cut
68              
69             sub check_hostrange {
70 0     0 1   my ($rangelist, $host) = @_;
71 0 0         return 0 if (!$_have_netaddr);
72 0   0       $host = NetAddr::IP->new($host) || return 0;
73              
74 0           for(split(/,/,$rangelist)) {
75             # if it's a cidr pass it into NetAddr::IP directly
76 0 0         if ($_ =~ qr#/#) {
77 0   0       my $range = NetAddr::IP->new($_) || return 0;
78 0 0         return 1 if ($range->contains($host));
79             } else {
80 0           my ($host1, $host2) = split(/-/);
81 0   0       $host1 = NetAddr::IP->new($host1) || return 0;
82             # if they only supplied the last octet
83 0 0         if ($host2 =~ /^[\da-f]+$/i) {
84 0           my $tmp = $host1->addr;
85             # drop the last octet
86 0           $tmp =~ s/([:\.])[\da-f]+$/$1/;
87 0           $host2 = $tmp . $host2;
88             }
89 0   0       $host2 = NetAddr::IP->new($host2) || return 0;
90 0 0 0       return 1 if ($host >= $host1 && $host <= $host2);
91             }
92             }
93 0           return 0;
94             }
95              
96             1;