Difference between revisions of "Unix sockets"
(Created page with " ==Socket status== The kernel exports information about open network sockets. The relevant <code>/proc/net/</code> files for IPv4 are: tcp, udp, and raw. All three files have...") |
(→External links) |
||
| (4 intermediate revisions by the same user not shown) | |||
| Line 2: | Line 2: | ||
==Socket status== | ==Socket status== | ||
| − | The kernel exports information about open network sockets. The relevant <code>/proc/net/</code> files for IPv4 are: tcp, udp, and raw. All three files have identical syntax. The first line provides labels for each of the columns in the output. Each following line represents one open socket. Results from <code> | + | The kernel exports information about open network sockets. The relevant <code>/proc/net/</code> files for IPv4 are: <code>tcp</code>, <code>udp</code>, and <code>raw</code>. All three files have identical syntax. The first line provides labels for each of the columns in the output. Each following line represents one open socket. Results from <code>$(cat /proc/net/tcp)</code> are shown here. |
The data presented in each output column is: | The data presented in each output column is: | ||
| − | ; sl : The number of the line in the output listing. | + | ; <code>sl</code> : The number of the line in the output listing. |
| − | ; local_address : The local IP address and port number for the socket. The IP address is displayed as a little-endian four-byte hexadecimal number; that is, the least significant byte is listed first, so one needs to reverse the order of the bytes to convert it to an IP address. The port number is a simple two-byte hexadecimal number. | + | ; <code>local_address</code> : The local IP address and port number for the socket. The IP address is displayed as a little-endian four-byte hexadecimal number; that is, the least significant byte is listed first, so one needs to reverse the order of the bytes to convert it to an IP address. The port number is a simple two-byte hexadecimal number. |
| − | ; rem_address : The remote IP address and port number for the socket. Encoding is the same as for the local_address. | + | ; <code>rem_address</code> : The remote IP address and port number for the socket. Encoding is the same as for the <code>local_address</code>. |
| − | ; st : The socket status. | + | ; <code>st</code> : The socket status. |
| − | ; tx_queue | + | ; <code>tx_queue / rx_queue</code> : The size of the transmit and receive queues. |
| − | ; tr | + | ; <code>tr / tm->when</code> : The <code>tr</code> field indicates whether a timer is active for this socket. A value of zero indicates the timer is not active. The <code>tm->when</code> field indicates the time remaining (in jiffies) before timeout occurs. |
| − | ; retrnsmt : Unused. | + | ; <code>retrnsmt</code> : Unused. |
| − | ; uid : The ID of the user that owns the socket. This is the same ID found in the /etc/passwd file. | + | ; <code>uid</code> : The ID of the user that owns the socket. This is the same ID found in the <code>/etc/passwd</code> file. |
| − | ; time-out : Unused. | + | ; <code>time-out</code> : Unused. |
| − | ; inode : A cryptic-looking number that identifies the socket to the Linux virtual filesystem. | + | ; <code>inode</code> : A cryptic-looking number that identifies the socket to the Linux virtual filesystem. |
===IP addresses in /proc/net/=== | ===IP addresses in /proc/net/=== | ||
| − | In the files offered by the /proc/net/ directory, IP addresses are often represented as little-endian four-byte hexadecimal numbers. These are easy to convert into the more usual dotted-decimal notation. | + | In the files offered by the <code>/proc/net/</code> directory, IP addresses are often represented as little-endian four-byte hexadecimal numbers. These are easy to convert into the more usual dotted-decimal notation. |
| − | For example, to convert the remote address and port of line 16 of the /proc/net/tcp output shown in this column, one would do the following: | + | For example, to convert the remote address and port of line 16 of the <code>/proc/net/tcp</code> output shown in this column, one would do the following: |
# Take the rem_address field: | # Take the rem_address field: | ||
| Line 37: | Line 37: | ||
$ netstat -planu | awk '/^udp / {print $4}' | $ netstat -planu | awk '/^udp / {print $4}' | ||
| − | * Get the same info via the /proc filesystem: | + | * Get the same info via the <code>/proc</code> filesystem: |
$ for h in $(awk 'NR>1{print $2}' /proc/net/udp); do | $ for h in $(awk 'NR>1{print $2}' /proc/net/udp); do | ||
| Line 45: | Line 45: | ||
$ ip_addr=$(echo 0F01A8C0 | sed -e 's/\(..\)\(..\)\(..\)\(..\)/echo $((0x\4)).$(echo $((0x\3))).$(echo $((0x\2))).$(echo $((0x\1)))/e') | $ ip_addr=$(echo 0F01A8C0 | sed -e 's/\(..\)\(..\)\(..\)\(..\)/echo $((0x\4)).$(echo $((0x\3))).$(echo $((0x\2))).$(echo $((0x\1)))/e') | ||
| − | * Nice, but, let's do this in pure | + | * Nice, but, let's do this in pure [[awk]]: |
$ awk 'NR>1{split($2, addr, ":"); for(i=0;i<4;i++){ | $ awk 'NR>1{split($2, addr, ":"); for(i=0;i<4;i++){ | ||
| Line 58: | Line 58: | ||
rshift(and(ip,0xff000000),24))}' | rshift(and(ip,0xff000000),24))}' | ||
| − | * Final, pure | + | * Final, pure [[awk]]: |
<pre> | <pre> | ||
$ awk 'NR>1 { | $ awk 'NR>1 { | ||
| Line 69: | Line 69: | ||
}' /proc/net/udp | }' /proc/net/udp | ||
</pre> | </pre> | ||
| + | |||
| + | ==See also== | ||
| + | * [[Procfs]] | ||
==External links== | ==External links== | ||
Latest revision as of 22:26, 20 January 2022
Socket status
The kernel exports information about open network sockets. The relevant /proc/net/ files for IPv4 are: tcp, udp, and raw. All three files have identical syntax. The first line provides labels for each of the columns in the output. Each following line represents one open socket. Results from $(cat /proc/net/tcp) are shown here.
The data presented in each output column is:
-
sl - The number of the line in the output listing.
-
local_address - The local IP address and port number for the socket. The IP address is displayed as a little-endian four-byte hexadecimal number; that is, the least significant byte is listed first, so one needs to reverse the order of the bytes to convert it to an IP address. The port number is a simple two-byte hexadecimal number.
-
rem_address - The remote IP address and port number for the socket. Encoding is the same as for the
local_address. -
st - The socket status.
-
tx_queue / rx_queue - The size of the transmit and receive queues.
-
tr / tm->when - The
trfield indicates whether a timer is active for this socket. A value of zero indicates the timer is not active. Thetm->whenfield indicates the time remaining (in jiffies) before timeout occurs. -
retrnsmt - Unused.
-
uid - The ID of the user that owns the socket. This is the same ID found in the
/etc/passwdfile. -
time-out - Unused.
-
inode - A cryptic-looking number that identifies the socket to the Linux virtual filesystem.
IP addresses in /proc/net/
In the files offered by the /proc/net/ directory, IP addresses are often represented as little-endian four-byte hexadecimal numbers. These are easy to convert into the more usual dotted-decimal notation.
For example, to convert the remote address and port of line 16 of the /proc/net/tcp output shown in this column, one would do the following:
- Take the rem_address field:
-
0100007F:0017
-
- Reverse the ordering of the bytes in the IP address part:
-
7F000001:0017
-
- Separate the bytes of the address for readability:
-
7F 00 00 01 : 0017
-
- Perform a simple hexadecimal-to-decimal conversion on each:
-
127 0 0 1 : 23
-
It is a telnet connection to localhost. Simple enough.
- Get a list of local IP addresses and ports listening via UDP:
$ netstat -planu | awk '/^udp / {print $4}'
- Get the same info via the
/procfilesystem:
$ for h in $(awk 'NR>1{print $2}' /proc/net/udp); do
printf "%s:%d\n" $(printf "%d." $(echo ${h%:*}|sed 's/../0x& /g'|tr ' ' '\n'|tac)|sed 's/\.$/\n/') 0x${h#*:};
done
$ ip_addr=$(echo 0F01A8C0 | sed -e 's/\(..\)\(..\)\(..\)\(..\)/echo $((0x\4)).$(echo $((0x\3))).$(echo $((0x\2))).$(echo $((0x\1)))/e')
- Nice, but, let's do this in pure awk:
$ awk 'NR>1{split($2, addr, ":"); for(i=0;i<4;i++){
printf("%d.",strtonum("0x" substr(addr[1],2*i+1,2)))}; print ":" strtonum("0x" addr[2]);}' /proc/net/udp
- Almost. Just need to reverse the dotted decimals.
$ echo 0F01A8C0 | awk '{str = sprintf("0x%s", $0); ip = strtonum(str); \
printf ("%d.%d.%d.%d\t",rshift(and(ip,0x000000ff),00),
rshift(and(ip,0x0000ff00),08),
rshift(and(ip,0x00ff0000),16),
rshift(and(ip,0xff000000),24))}'
- Final, pure awk:
$ awk 'NR>1 {
split($2, a, ":");
patsplit(a[1],h,/.{2}/);
for(i=4;i>0;i--){
h[i]=strtonum("0x" h[i]);
};
printf("%d.%d.%d.%d:%d\n",h[4],h[3],h[2],h[1],strtonum("0x" a[2]));
}' /proc/net/udp
See also
External links
- Exploring the /proc/net/ Directory — where most of the above explanation came from
- http://www.usna.edu/Users/cs/aviv/classes/ic221/s14/lec/22/lec.html
- https://dzone.com/articles/linux-system-mining-python