Last active
August 31, 2024 11:32
-
-
Save jkstill/5095725 to your computer and use it in GitHub Desktop.
decode entries in /proc/net/tcp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Decoding the data in /proc/net/tcp: | |
Linux 5.x /proc/net/tcp | |
Linux 6.x /proc/PID/net/tcp | |
Given a socket: | |
$ ls -l /proc/24784/fd/11 | |
lrwx------ 1 jkstill dba 64 Dec 4 16:22 /proc/24784/fd/11 -> socket:[15907701] | |
Find the address | |
$ head -1 /proc/24784/net/tcp; grep 15907701 /proc/24784/net/tcp | |
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode | |
46: 010310AC:9C4C 030310AC:1770 01 0100000150:00000000 01:00000019 00000000 1000 0 54165785 4 cd1e6040 25 4 27 3 -1 | |
46: 010310AC:9C4C 030310AC:1770 01 | |
| | | | | |--> connection state | |
| | | | |------> remote TCP port number | |
| | | |-------------> remote IPv4 address | |
| | |--------------------> local TCP port number | |
| |---------------------------> local IPv4 address | |
|----------------------------------> number of entry | |
00000150:00000000 01:00000019 00000000 | |
| | | | |--> number of unrecovered RTO timeouts | |
| | | |----------> number of jiffies until timer expires | |
| | |----------------> timer_active (see below) | |
| |----------------------> receive-queue | |
|-------------------------------> transmit-queue | |
1000 0 54165785 4 cd1e6040 25 4 27 3 -1 | |
| | | | | | | | | |--> slow start size threshold, | |
| | | | | | | | | or -1 if the treshold | |
| | | | | | | | | is >= 0xFFFF | |
| | | | | | | | |----> sending congestion window | |
| | | | | | | |-------> (ack.quick<<1)|ack.pingpong | |
| | | | | | |---------> Predicted tick of soft clock | |
| | | | | | (delayed ACK control data) | |
| | | | | |------------> retransmit timeout | |
| | | | |------------------> location of socket in memory | |
| | | |-----------------------> socket reference count | |
| | |-----------------------------> inode | |
| |----------------------------------> unanswered 0-window probes | |
|---------------------------------------------> uid | |
timer_active: | |
0 no timer is pending | |
1 retransmit-timer is pending | |
2 another timer (e.g. delayed ack or keepalive) is pending | |
3 this is a socket in TIME_WAIT state. Not all field will contain data. | |
4 zero window probe timer is pending | |
========================================== | |
Perl script to decode the address | |
#!/usr/bin/perl | |
my $hexip=$ARGV[0]; | |
my $hexport=$ARGV[1]; | |
print "hex: $hexip\n"; | |
my @ip = map hex($_), ( $hexip =~ m/../g ); | |
my $ip = join('.',reverse(@ip)); | |
my $port = hex($hexport); | |
print "IP: $ip PORT: $port\n"; | |
========================================== | |
$ hexip.pl 030310AC 1770 | |
hex: 030310AC | |
IP: 172.16.3.3 PORT: 6000 | |
cool.
@semeion Please check for connection state. For Listening state is 0x0A. Please check for enums in file https://elixir.bootlin.com/linux/v4.14.42/source/include/net/tcp_states.h.
@AmitIITR here is a derived script to parse the full output from /proc/net/tcp and print each line in readable format:
#!/usr/bin/perl
#
# ref https://elixir.bootlin.com/linux/v4.14.42/source/include/net/tcp_states.h
@tcpstates = (
"DUMMY",
"TCP_ESTABLISHED", #1
"TCP_SYN_SENT", #2
"TCP_SYN_RECV", #3
"TCP_FIN_WAIT1", #4
"TCP_FIN_WAIT2", #5
"TCP_TIME_WAIT", #6
"TCP_CLOSE", #7
"TCP_CLOSE_WAIT", #8
"TCP_LAST_ACK", #9
"TCP_LISTEN", #10
"TCP_CLOSING", #11
"TCP_NEW_SYN_RECV", #12
"TCP_MAX_STATES," #13
);
sub ipport() {
$_[0] =~ m/([0-9A-F]+):([0-9A-F]+)/;
$hexip = $1; $hexport = $2;
my @ip = map hex($_), ( $hexip =~ m/../g );
my $ip = join('.',reverse(@ip));
my $port = hex($hexport);
return ($ip . ":" . $port);
}
while ($line = <>) {
if ($line =~ /(^[ ]*[0-9]+: )([0-9A-F:]+) ([0-9A-F:]+) ([0-9A-F]+)(.*)/) {
$head = $1;
$loc = $2;
$rem = $3;
$stat = $4;
$tail = $5;
if (hex($stat) == 0) {
print STDERR "hex($stat) is 0\n";
}
push @output, sprintf("%s%-21s %-21s %s %s\n", $head, &ipport($loc), &ipport($rem), $tcpstates[hex($stat)]);
}
}
foreach $line (@output) {
print $line;
}
Nice script!
@AmitIITR here is a derived script to parse the full output from /proc/net/tcp and print each line in readable format:
#!/usr/bin/perl # # ref https://elixir.bootlin.com/linux/v4.14.42/source/include/net/tcp_states.h @tcpstates = ( "DUMMY", "TCP_ESTABLISHED", #1 "TCP_SYN_SENT", #2 "TCP_SYN_RECV", #3 "TCP_FIN_WAIT1", #4 "TCP_FIN_WAIT2", #5 "TCP_TIME_WAIT", #6 "TCP_CLOSE", #7 "TCP_CLOSE_WAIT", #8 "TCP_LAST_ACK", #9 "TCP_LISTEN", #10 "TCP_CLOSING", #11 "TCP_NEW_SYN_RECV", #12 "TCP_MAX_STATES," #13 ); sub ipport() { $_[0] =~ m/([0-9A-F]+):([0-9A-F]+)/; $hexip = $1; $hexport = $2; my @ip = map hex($_), ( $hexip =~ m/../g ); my $ip = join('.',reverse(@ip)); my $port = hex($hexport); return ($ip . ":" . $port); } while ($line = <>) { if ($line =~ /(^[ ]*[0-9]+: )([0-9A-F:]+) ([0-9A-F:]+) ([0-9A-F]+)(.*)/) { $head = $1; $loc = $2; $rem = $3; $stat = $4; $tail = $5; if (hex($stat) == 0) { print STDERR "hex($stat) is 0\n"; } push @output, sprintf("%s%-21s %-21s %s %s\n", $head, &ipport($loc), &ipport($rem), $tcpstates[hex($stat)]); } } foreach $line (@output) { print $line; }
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice info, btw, how to know if a connection is incomming or outgoing?