File Coverage

lib/App/Tel/HostRange.pm
Criterion Covered Total %
statement 14 32 43.7
branch 2 16 6.2
condition 0 11 0.0
subroutine 5 5 100.0
pod 1 1 100.0
total 22 65 32.3


line stmt bran cond sub pod time code
1             package App::Tel::HostRange;
2              
3 8     8   47854 use strict;
  8         11  
  8         182  
4 8     8   24 use warnings;
  8         10  
  8         159  
5 8     8   440 use Module::Load;
  8         783  
  8         38  
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             # uncoverable branch false
18 8 50   8   798 if (eval { Module::Load::load NetAddr::IP; 1; }) {
  8         30  
  0         0  
19 0         0 $_have_netaddr=1;
20             } else {
21 8         4737 $_have_netaddr=0;
22             }
23             }
24              
25             =head1 NAME
26              
27             App::Tel::HostRange - Support for HostRanges
28              
29             =head1 SYNOPSIS
30              
31             if (check_hostrange($_, $host));
32              
33             Searches an IPv4 or IPv6 range to see if it contains a particular IP address.
34             Returns true if the host is contained in the range, false if it is not.
35              
36             =head1 AUTHOR
37              
38             Robert Drake, C<< >>
39              
40             =head1 COPYRIGHT & LICENSE
41              
42             Copyright 2015 Robert Drake, all rights reserved.
43              
44             This program is free software; you can redistribute it and/or modify it
45             under the same terms as Perl itself.
46              
47             =cut
48              
49             =head2 check_hostrange
50              
51             if (check_hostrange($rangelist, $host));
52              
53             Searches an IPv4 or IPv6 range to see if it contains a particular IP address.
54             Returns true if the host is contained in the range, false if it is not.
55              
56             This does no validation, leaving it all up to NetAddr:IP and the calling
57             function.
58              
59             This should support the following types of ranges:
60              
61             # 1. 192.168.13.17-192.168.32.128
62             # 2. 192.168.13.17-22
63             # 3. fe80::1-fe80::256
64             # 4. 192.168.13.0/24
65             # 5. fe80::/64
66             # 6. 192.168.13.17-192.168.32.128,172.16.0.2-172.16.0.13,172.28.0.0/24
67             # 7. 192.168.13.12
68              
69              
70             =cut
71              
72             sub check_hostrange {
73 1     1 1 2 my ($rangelist, $host) = @_;
74 1 50       34 return 0 if (!$_have_netaddr);
75 0   0       $host = NetAddr::IP->new($host) || return 0;
76              
77 0           for(split(/,/,$rangelist)) {
78             # if it's a cidr pass it into NetAddr::IP directly
79 0 0         if ($_ =~ qr#/#) {
80 0   0       my $range = NetAddr::IP->new($_) || return 0;
81 0 0         return 1 if ($range->contains($host));
82             } else {
83 0           my ($host1, $host2) = split(/-/);
84 0   0       $host1 = NetAddr::IP->new($host1) || return 0;
85             # if it's a single IP, like #7
86 0 0         if (!defined($host2)) {
87 0 0         return $host == $host1 ? 1 : 0;
88             }
89             # if they only supplied the last octet like #2
90 0 0         if ($host2 =~ /^[\da-f]+$/i) {
91 0           my $tmp = $host1->addr;
92             # drop the last octet
93 0           $tmp =~ s/([:\.])[\da-f]+$/$1/;
94 0           $host2 = $tmp . $host2;
95             }
96 0   0       $host2 = NetAddr::IP->new($host2) || return 0;
97 0 0 0       return 1 if ($host >= $host1 && $host <= $host2);
98             }
99             }
100 0           return 0;
101             }
102              
103             1;