File Coverage

blib/lib/Parse/Netstat/linux.pm
Criterion Covered Total %
statement 34 35 97.1
branch 10 14 71.4
condition 12 15 80.0
subroutine 6 6 100.0
pod 1 1 100.0
total 63 71 88.7


line stmt bran cond sub pod time code
1             package Parse::Netstat::linux;
2              
3             our $DATE = '2017-02-09'; # DATE
4             our $VERSION = '0.13'; # VERSION
5              
6 1     1   24 use 5.010001;
  1         2  
7 1     1   4 use strict;
  1         1  
  1         21  
8 1     1   4 use warnings;
  1         0  
  1         24  
9              
10 1     1   3 use Exporter;
  1         1  
  1         270  
11             our @ISA = qw(Exporter);
12             our @EXPORT_OK = qw(parse_netstat);
13              
14             our %SPEC;
15              
16             $SPEC{parse_netstat} = {
17             v => 1.1,
18             summary => 'Parse the output of Linux "netstat" command',
19             description => <<'_',
20              
21             Netstat can be called with `-n` (show raw IP addresses and port numbers instead
22             of hostnames or port names) or without. It can be called with `-a` (show all
23             listening and non-listening socket) option or without. And can be called with
24             `-p` (show PID/program names) or without.
25              
26             _
27             args => {
28             output => {
29             summary => 'Output of netstat command',
30             schema => 'str*',
31             req => 1,
32             },
33             tcp => {
34             summary => 'Whether to parse TCP (and TCP6) connections',
35             schema => [bool => default => 1],
36             },
37             udp => {
38             summary => 'Whether to parse UDP (and UDP6) connections',
39             schema => [bool => default => 1],
40             },
41             unix => {
42             summary => 'Whether to parse Unix socket connections',
43             schema => [bool => default => 1],
44             },
45             },
46             };
47             sub parse_netstat {
48 4     4 1 7 my %args = @_;
49 4 50       8 my $output = $args{output} or return [400, "Please specify output"];
50 4   50     9 my $tcp = $args{tcp} // 1;
51 4   50     4 my $udp = $args{udp} // 1;
52 4   50     6 my $unix = $args{unix} // 1;
53              
54 4         3 my $in_unix;
55             my $in_unix_header;
56 0         0 my @conns;
57 4         3 my $i = 0;
58 4         58 for my $line (split /^/, $output) {
59 84         42 $i++;
60 84         53 my %k;
61 84 100 100     339 if ($line =~ /^tcp/ && $tcp) {
    100 100        
    100 100        
62             #Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
63             #tcp 0 0 0.0.0.0:8898 0.0.0.0:* LISTEN 5566/daemon2.pl [pa
64 30 50       149 $line =~ m!^(?Ptcp[46]?) \s+ (?P\d+) \s+ (?P\d+)\s+
65             (?P\S+?):(?P\w+)\s+
66             (?P\S+?):(?P\w+|\*)\s+
67             (?P\S+) (?: \s+ (?:
68             (?P\d+)/(?P.+?) |
69             -
70             ))? \s*$!x
71             or return [400, "Can't parse tcp line (#$i): $line"];
72 1     1   449 %k = %+;
  1         359  
  1         259  
  30         455  
73             } elsif ($line =~ /^udp/ && $udp) {
74             #udp 0 0 0.0.0.0:631 0.0.0.0:* 2769/cupsd
75 12 50       55 $line =~ m!^(?Pudp[46]?) \s+ (?P\d+) \s+ (?P\d+) \s+
76             (?P\S+?):(?P\w+|\*)\s+
77             (?P\S+?):(?P\w+|\*)
78             (?: \s+
79             (?P\S+)?
80             (?: \s+ (?:
81             (?P\d+)/(?P.+?) |
82             -
83             ))?
84             )? \s*$!x
85             or return [400, "Can't parse udp line (#$i): $line"];
86 12         164 %k = %+;
87             } elsif ($line =~ /^unix/ && $unix) {
88             #Proto RefCnt Flags Type State I-Node PID/Program name Path
89             # unix 2 [ ACC ] STREAM LISTENING 650654 30463/gconfd-2 /tmp/orbit-t1/linc-76ff-0-3fc1dd3f2f2
90 9 50       65 $line =~ m!^(?Punix) \s+ (?P\d+) \s+
91             \[\s*(?P\S*)\s*\] \s+ (?P\S+) \s+
92             (?P\S+|\s+) \s+ (?P\d+) \s+
93             (?: (?: (?P\d+)/(?P.+?) | - ) \s+)?
94             (?P.*?)\s*$!x
95             or return [400, "Can't parse unix line (#$i): $line"];
96 9         115 %k = %+;
97             } else {
98 33         28 next;
99             }
100 51         150 push @conns, \%k;
101             }
102              
103 4         27 [200, "OK", {active_conns => \@conns}];
104             }
105              
106             1;
107             # ABSTRACT: Parse the output of Linux "netstat" command
108              
109             __END__