File Coverage

blib/lib/Parse/CPinfo.pm
Criterion Covered Total %
statement 107 117 91.4
branch 28 32 87.5
condition 1 3 33.3
subroutine 14 15 93.3
pod 7 7 100.0
total 157 174 90.2


line stmt bran cond sub pod time code
1             package Parse::CPinfo;
2              
3 2     2   42201 use 5.006_001;
  2         8  
  2         67  
4 2     2   9 use strict;
  2         5  
  2         58  
5 2     2   9 no warnings;
  2         14  
  2         66  
6 2     2   8 use base qw/Exporter/;
  2         3  
  2         174  
7 2     2   10 use Carp;
  2         2  
  2         126  
8 2     2   1560 use IO::File;
  2         20292  
  2         2642  
9             require Exporter;
10              
11             our $VERSION = '0.882';
12              
13             # extracted from Regexp::Common
14             my $re_mac =
15             '(?:(?:[0-9a-fA-F]{1,2}):(?:[0-9a-fA-F]{1,2}):(?:[0-9a-fA-F]{1,2}):(?:[0-9a-fA-F]{1,2}):(?:[0-9a-fA-F]{1,2}):(?:[0-9a-fA-F]{1,2}))';
16             my $re_net_ipv4 =
17             '(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))';
18              
19             sub new {
20 2     2 1 490 my $class = shift;
21 2         4 my $self = {};
22 2         5 bless $self, $class;
23 2         7 return $self;
24             }
25              
26             sub readfile {
27 2     2 1 10 my $self = shift;
28 2         4 my $filename = shift;
29              
30             # keep copy of filename in object
31 2         10 $self->{'_filename'} = $filename;
32 2         17 my $fh = new IO::File($filename, 'r');
33 2 100       211 if (!defined($fh)) {
34 1         175 croak "Unable to open $filename for reading";
35             }
36              
37             # ensure we are in binary mode as some system (win32 for example)
38             # will assume we are handling text otherwise.
39 1         6 binmode $fh, ':raw';
40              
41 1         6484 my @lines = <$fh>;
42 1         1485 chomp @lines;
43 1         3 my $linenumber = 0;
44 1         6 while ($linenumber < $#lines) {
45 459         406 $linenumber++;
46 459 100       1205 if ($lines[$linenumber] =~ m/^\={46}$/o) {
47 18         18 $linenumber++;
48 18         29 my $section = $lines[$linenumber];
49 18         25 $linenumber++;
50              
51 18         27 foreach (0 .. $linenumber) {
52 1801         1695 $linenumber++;
53 1801 100       2909 if ($lines[$linenumber] !~ m/^\={46}$/o) {
54 1786         2222 $lines[$linenumber] =~ s/\r\n//g;
55 1786         1920 $lines[$linenumber] =~ s/\r//g;
56 1786         1893 $lines[$linenumber] =~ s/\n//g;
57 1786         6924 $self->{'config'}->{$section} = $self->{'config'}->{$section} . "$lines[$linenumber]\n";
58             }
59             else {
60 15         16 $linenumber--;
61 15         47 last;
62             }
63             }
64             }
65             }
66 1         20 $self->_parseinterfacelist();
67 1         221 return 1;
68             }
69              
70             sub _parseinterfacelist {
71 1     1   4 my $self = shift;
72 1         6 my $ifconfigtext = $self->{'config'}->{'IP Interfaces'};
73 1 50       6 if (!$ifconfigtext) {
74 0         0 return;
75             }
76 1         28 my @s = split /\n/, $ifconfigtext;
77 1         5 my ($int);
78 1         4 foreach my $line (@s) {
79 20         57 chomp $line;
80 20 100       74 if ($line =~ m/^(\w+)\s+/o) {
81 3         8 my $match = $1;
82 3 100       10 if ($match !~ m/ifconfig/o) {
83 2         5 $int = $1;
84 2         10 $self->{'interface'}->{$int}->{'name'} = $int;
85             }
86             }
87 20 100       62 if ($line =~ m/Link encap:(\w+)\s+/io) {
88 2         7 $self->{'interface'}->{$int}->{'encap'} = $1;
89             }
90 20 100       158 if ($line =~ m/HWaddr ($re_mac)/io) {
91 1         3 $self->{'interface'}->{$int}->{'hwaddr'} = $1;
92             }
93 20 100       166 if ($line =~ m/inet addr:($re_net_ipv4)/io) {
94 2         8 $self->{'interface'}->{$int}->{'inetaddr'} = $1;
95             }
96 20 100       116 if ($line =~ m/bcast:($re_net_ipv4)/io) {
97 1         5 $self->{'interface'}->{$int}->{'broadcast'} = $1;
98             }
99 20 100       108 if ($line =~ m/mask:($re_net_ipv4)/io) {
100 2         7 $self->{'interface'}->{$int}->{'mask'} = $1;
101 2         10 $self->{'interface'}->{$int}->{'masklength'} = $self->_ipv4_msk2cidr($self->{'interface'}->{$int}->{'mask'});
102             }
103 20 100       75 if ($line =~ m/MTU:(\d+)/io) {
104 2         10 $self->{'interface'}->{$int}->{'mtu'} = $1;
105             }
106             }
107 1         7 return 1;
108             }
109              
110             sub _ipv4_msk2cidr {
111 2     2   4 my $self = shift;
112 2         2 my $mask = shift;
113 2         11 ($mask) = $mask =~ m/(\d+\.\d+\.\d+\.\d+)/o;
114              
115 2 50       8 if (! defined($mask)) {
116 0         0 return undef;
117             }
118              
119 2         8 for (split /\./, $mask) {
120 8 50 33     39 if ($_ < 0 or $_ > 255) {
121 0         0 return undef;
122             }
123             }
124 2         8 my @bytes = split /\./, $mask;
125              
126 2         3 my $cidr = 0;
127 2         5 for (@bytes) {
128 8         22 my $bits = unpack("B*", pack("C", $_));
129 8         19 $cidr += $bits =~ tr /1/1/;
130             }
131 2         9 return $cidr;
132             }
133              
134             sub getInterfaceList {
135 1     1 1 363 my $self = shift;
136 1         2 return keys %{$self->{'interface'}};
  1         5  
137             }
138              
139             sub getInterfaceInfo {
140 2     2 1 1485 my $self = shift;
141 2         3 my $interface = shift;
142 2         8 return $self->{'interface'}{$interface};
143             }
144              
145             sub getSectionList {
146 0     0 1 0 my $self = shift;
147 0         0 my @r;
148 0         0 foreach my $section (sort keys %{$self->{config}}) {
  0         0  
149 0         0 push @r, $section;
150             }
151 0         0 return @r;
152             }
153              
154             sub getSection {
155 1     1 1 1 my $self = shift;
156 1         2 my $query = shift;
157 1         7 my $section = $self->{'config'}->{$query};
158 1         112 return $section;
159             }
160              
161             sub getHostname {
162 1     1 1 951 my $self = shift;
163 1         5 my @section = split(/\n/, $self->getSection('System Information'));
164 1         18 my $hostname;
165 1         4 foreach my $linenumber (0 .. $#section) {
166 14 100       32 if ($section[$linenumber] =~ m/Issuing 'hostname'/i) {
167 1         2 $hostname = $section[$linenumber + 2];
168 1         3 chomp $hostname;
169 1         2 last;
170             }
171             }
172 1 50       4 if (defined($hostname)) {
173 1         39 return $hostname;
174             }
175             else {
176 0           return undef;
177             }
178             }
179              
180             1;
181             __END__