line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Linux::Proc::Net::TCP; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $VERSION = '0.07'; |
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
121651
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
51
|
|
6
|
1
|
|
|
1
|
|
7
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
37
|
|
7
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
6
|
use Carp; |
|
1
|
|
|
|
|
8
|
|
|
1
|
|
|
|
|
106
|
|
9
|
1
|
|
|
1
|
|
5
|
use Scalar::Util; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
834
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
require Linux::Proc::Net::TCP::Base; |
12
|
|
|
|
|
|
|
our @ISA = qw(Linux::Proc::Net::TCP::Base); |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub read { |
15
|
1
|
|
|
1
|
1
|
15
|
my $class = shift; |
16
|
1
|
|
|
|
|
12
|
$class->_read(_proto => 'tcp', @_); |
17
|
|
|
|
|
|
|
} |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub listeners { |
20
|
0
|
|
|
0
|
1
|
|
my $table = shift; |
21
|
0
|
|
|
|
|
|
my @l; |
22
|
0
|
|
|
|
|
|
for (@$table) { |
23
|
0
|
0
|
|
|
|
|
last unless $_->[5] eq '0A'; |
24
|
0
|
|
|
|
|
|
push @l, $_; |
25
|
|
|
|
|
|
|
} |
26
|
0
|
|
|
|
|
|
@l; |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
sub listener_ports { |
30
|
0
|
|
|
0
|
1
|
|
my $table = shift; |
31
|
0
|
|
|
|
|
|
my @p; |
32
|
0
|
|
|
|
|
|
for (sort { $a <=> $b } map $_->local_port, $table->listeners) { |
|
0
|
|
|
|
|
|
|
33
|
0
|
0
|
0
|
|
|
|
push @p, $_ unless (($p[-1] || 0) == $_) |
34
|
|
|
|
|
|
|
} |
35
|
0
|
|
|
|
|
|
@p; |
36
|
|
|
|
|
|
|
} |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
package Linux::Proc::Net::TCP::Entry; |
39
|
|
|
|
|
|
|
our @ISA = qw(Linux::Proc::Net::TCP::Base::Entry); |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
my @st_names = ( undef, |
42
|
|
|
|
|
|
|
qw(ESTABLISHED |
43
|
|
|
|
|
|
|
SYN_SENT |
44
|
|
|
|
|
|
|
SYN_RECV |
45
|
|
|
|
|
|
|
FIN_WAIT1 |
46
|
|
|
|
|
|
|
FIN_WAIT2 |
47
|
|
|
|
|
|
|
TIME_WAIT |
48
|
|
|
|
|
|
|
CLOSE |
49
|
|
|
|
|
|
|
CLOSE_WAIT |
50
|
|
|
|
|
|
|
LAST_ACK |
51
|
|
|
|
|
|
|
LISTEN |
52
|
|
|
|
|
|
|
CLOSING) ); |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub _tcp_st2dual { |
55
|
0
|
|
|
0
|
|
|
my $st = hex shift; |
56
|
0
|
|
|
|
|
|
my $name = $st_names[$st]; |
57
|
0
|
0
|
|
|
|
|
(defined $name ? Scalar::Util::dualvar($st, $name) : $st); |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
0
|
|
|
0
|
|
|
sub st { _tcp_st2dual shift->[ 5] } |
61
|
|
|
|
|
|
|
|
62
|
0
|
|
|
0
|
|
|
sub retransmit_timeout { shift->[16] } |
63
|
0
|
|
|
0
|
|
|
sub predicted_tick { shift->[17] } |
64
|
0
|
|
0
|
0
|
|
|
sub ack_quick { ( shift->[18] || 0 ) >> 1 } |
65
|
0
|
|
0
|
0
|
|
|
sub ack_pingpong { ( shift->[18] || 0 ) & 1 } |
66
|
0
|
|
|
0
|
|
|
sub sending_congestion_window { shift->[19] } |
67
|
0
|
|
|
0
|
|
|
sub slow_start_size_threshold { shift->[20] } |
68
|
0
|
|
|
0
|
|
|
sub _more { shift->[21] } |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
1; |
73
|
|
|
|
|
|
|
__END__ |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=head1 NAME |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
Linux::Proc::Net::TCP - Parser for Linux /proc/net/tcp and /proc/net/tcp6 |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=head1 SYNOPSIS |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
use Linux::Proc::Net::TCP; |
82
|
|
|
|
|
|
|
my $table = Linux::Proc::Net::TCP->read; |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
for my $entry (@$table) { |
85
|
|
|
|
|
|
|
printf("%s:%d --> %s:%d, %s\n", |
86
|
|
|
|
|
|
|
$entry->local_address, $entry->local_port, |
87
|
|
|
|
|
|
|
$entry->rem_address, $entry->rem_port, |
88
|
|
|
|
|
|
|
$entry->st ); |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=head1 DESCRIPTION |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
This module can read and parse the information available from |
94
|
|
|
|
|
|
|
/proc/net/tcp in Linux systems. |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=head1 API |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=head2 The table object |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=over |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=item $table = Linux::Proc::Net::TCP->read |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=item $table = Linux::Proc::Net::TCP->read(%opts) |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
reads C</proc/net/tcp> and C</proc/net/tcp6> and returns an object |
107
|
|
|
|
|
|
|
representing a table of the connections. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
Individual entries in the table can be accessed just dereferencing the |
110
|
|
|
|
|
|
|
returned object. For instance: |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
for my $entry (@$table) { |
113
|
|
|
|
|
|
|
# do something with $entry |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
The table entries are of class C<Linux::Proc::Net::TCP::Entry> |
117
|
|
|
|
|
|
|
described below. |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
This method accepts the following optional arguments: |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=over 4 |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=item ip4 => 0 |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
disables parsing of the file /proc/net/tcp containing state |
126
|
|
|
|
|
|
|
information for TCP over IP4 connections |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
=item ip6 => 0 |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
disables parsing of the file /proc/net/tcp6 containing state |
131
|
|
|
|
|
|
|
information for TCP over IP6 connections |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=item mnt => $procfs_mount_point |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
overrides the default mount point for the procfs at C</proc>. |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=back |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=item $table->listeners |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
returns a list of the entries that are listeners: |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
for my $entry ($table->listeners) { |
144
|
|
|
|
|
|
|
printf "listener: %s:%d\n", $entry->local_address, $entry->local_port; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=item $table->listener_ports |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
returns the list of TCP ports where there are some service listening. |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
This method can be used to find some unused port: |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
my @used_ports = Linux::Proc::Net::TCP->read->listener_ports; |
154
|
|
|
|
|
|
|
my %used_port = map { $_ => 1 } @used_ports; |
155
|
|
|
|
|
|
|
my $port = $start; |
156
|
|
|
|
|
|
|
$port++ while $used_port{$port}; |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=back |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=head2 The entry object |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
The entries in the table are of class |
163
|
|
|
|
|
|
|
C<Linux::Proc::Net::TCP::Entry> and implement the following read only |
164
|
|
|
|
|
|
|
accessors: |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sl local_address local_port rem_address rem_port st tx_queue |
167
|
|
|
|
|
|
|
rx_queue timer tm_when retrnsmt uid timeout inode reference_count |
168
|
|
|
|
|
|
|
memory_address retransmit_timeout predicted_tick ack_quick |
169
|
|
|
|
|
|
|
ack_pingpong sending_congestion_window slow_start_size_threshold |
170
|
|
|
|
|
|
|
ip4 ip6 |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=head1 The /proc/net/tcp documentation |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
This is the documentation about /proc/net/tcp available from the Linux |
175
|
|
|
|
|
|
|
kernel source distribution: |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
This document describes the interfaces /proc/net/tcp and |
178
|
|
|
|
|
|
|
/proc/net/tcp6. Note that these interfaces are deprecated in favor |
179
|
|
|
|
|
|
|
of tcp_diag. |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
These /proc interfaces provide information about currently active TCP |
182
|
|
|
|
|
|
|
connections, and are implemented by tcp4_seq_show() in |
183
|
|
|
|
|
|
|
net/ipv4/tcp_ipv4.c and tcp6_seq_show() in net/ipv6/tcp_ipv6.c, |
184
|
|
|
|
|
|
|
respectively. |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
It will first list all listening TCP sockets, and next list all |
187
|
|
|
|
|
|
|
established TCP connections. A typical entry of /proc/net/tcp would |
188
|
|
|
|
|
|
|
look like this (split up into 3 parts because of the length of the |
189
|
|
|
|
|
|
|
line): |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
46: 010310AC:9C4C 030310AC:1770 01 |
192
|
|
|
|
|
|
|
| | | | | |--> connection state |
193
|
|
|
|
|
|
|
| | | | |------> remote TCP port number |
194
|
|
|
|
|
|
|
| | | |-------------> remote IPv4 address |
195
|
|
|
|
|
|
|
| | |--------------------> local TCP port number |
196
|
|
|
|
|
|
|
| |---------------------------> local IPv4 address |
197
|
|
|
|
|
|
|
|----------------------------------> number of entry |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
00000150:00000000 01:00000019 00000000 |
200
|
|
|
|
|
|
|
| | | | |--> number of unrecovered RTO timeouts |
201
|
|
|
|
|
|
|
| | | |----------> number of jiffies until timer expires |
202
|
|
|
|
|
|
|
| | |----------------> timer_active (see below) |
203
|
|
|
|
|
|
|
| |----------------------> receive-queue |
204
|
|
|
|
|
|
|
|-------------------------------> transmit-queue |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
1000 0 54165785 4 cd1e6040 25 4 27 3 -1 |
207
|
|
|
|
|
|
|
| | | | | | | | | |--> slow start size threshold, |
208
|
|
|
|
|
|
|
| | | | | | | | | or -1 if the threshold |
209
|
|
|
|
|
|
|
| | | | | | | | | is >= 0xFFFF |
210
|
|
|
|
|
|
|
| | | | | | | | |----> sending congestion window |
211
|
|
|
|
|
|
|
| | | | | | | |-------> (ack.quick<<1)|ack.pingpong |
212
|
|
|
|
|
|
|
| | | | | | |---------> Predicted tick of soft clock |
213
|
|
|
|
|
|
|
| | | | | | (delayed ACK control data) |
214
|
|
|
|
|
|
|
| | | | | |------------> retransmit timeout |
215
|
|
|
|
|
|
|
| | | | |------------------> location of socket in memory |
216
|
|
|
|
|
|
|
| | | |-----------------------> socket reference count |
217
|
|
|
|
|
|
|
| | |-----------------------------> inode |
218
|
|
|
|
|
|
|
| |----------------------------------> unanswered 0-window probes |
219
|
|
|
|
|
|
|
|---------------------------------------------> uid |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
timer_active: |
222
|
|
|
|
|
|
|
0 no timer is pending |
223
|
|
|
|
|
|
|
1 retransmit-timer is pending |
224
|
|
|
|
|
|
|
2 another timer (e.g. delayed ack or keepalive) is pending |
225
|
|
|
|
|
|
|
3 this is a socket in TIME_WAIT state. Not all fields will contain |
226
|
|
|
|
|
|
|
data (or even exist) |
227
|
|
|
|
|
|
|
4 zero window probe timer is pending |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
=head1 AUTHOR |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
Salvador FandiE<ntilde>o E<lt>sfandino@yahoo.comE<gt> |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
Copyright (C) 2010, 2012, 2014 by Qindel FormaciE<oacute>n y Servicios S.L. |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
239
|
|
|
|
|
|
|
it under the same terms as Perl itself, either Perl version 5.10.1 or, |
240
|
|
|
|
|
|
|
at your option, any later version of Perl 5 you may have available. |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
=cut |