summaryrefslogtreecommitdiff
path: root/socket-info
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2013-04-23 18:59:15 +0200
committerPeter Wu <lekensteyn@gmail.com>2013-04-23 18:59:15 +0200
commitaf38cb02a9ca95b20056bc92e73fe72a45d1f523 (patch)
tree41628cac3a02d2c4dcf4ff6ecbb1fb8c5378db20 /socket-info
downloadscripts-af38cb02a9ca95b20056bc92e73fe72a45d1f523.tar.gz
Initial checkin.
Diffstat (limited to 'socket-info')
-rwxr-xr-xsocket-info84
1 files changed, 84 insertions, 0 deletions
diff --git a/socket-info b/socket-info
new file mode 100755
index 0000000..5c066ea
--- /dev/null
+++ b/socket-info
@@ -0,0 +1,84 @@
+#!/bin/bash
+# Prints information about a file descriptor socket
+# Author: Peter Wu <lekensteyn@gmail.com>
+# Date: 2013-02-06
+
+rootcmd=sudo
+
+sockno=$1
+pipeno=
+
+sockfd=$(readlink "$1")
+if [[ $sockfd =~ ^socket:\[[0-9]+\]$ ]]; then
+ sockno=${sockfd#socket:[}
+ sockno=${sockno%]}
+fi
+
+# not a socket but a pipe
+if [[ $sockfd =~ ^pipe:\[[0-9]+\]$ ]]; then
+ pipeno=${sockfd#pipe:[}
+ pipeno=${pipeno%]}
+ find /proc/[0-9]*/fd -lname "pipe:\\[$pipeno\\]" -ls 2>/dev/null | \
+ awk -F/ '{
+ pid=$3;
+ print "";
+ print;
+ system("ps huwwp " pid);
+ }'
+ exit
+fi
+
+if ! [[ $sockno =~ ^[0-9]+$ ]]; then
+ echo "Numeric socket number required" >&2
+ exit 1
+fi
+
+# expects: $prot $sockno
+# arg1: field index for inode
+find_by_inode() {
+ </proc/net/$prot awk "{if (\$$1 == $sockno)print}"
+}
+
+# arg1: inode of one socket endpoint
+find_other_sock() {
+ local addr=$1
+ local vmlinux=/usr/src/linux-$(uname -r)/vmlinux
+ local file
+
+ for file in "$vmlinux" /proc/kcore; do
+ if [ ! -e "$file" ]; then
+ echo "$file: not found" >&2
+ return 1
+ fi
+ done
+
+ $rootcmd gdb -q "$vmlinux" /proc/kcore \
+ -ex "p ((struct unix_sock*)0x$addr)->peer" -ex q \
+ | grep -Po '\(struct sock \*\) 0x\K[0-9a-f]+'
+}
+
+line=
+for prot in udp tcp; do
+ line=$(find_by_inode 10)
+ [ -z "$line" ] || break
+done
+
+if [ -z "$line" ]; then
+ prot=unix
+ line=$(find_by_inode 7)
+ addr=$(cut -d: -f1 <<<"$line")
+ find_by_inode 7
+ if [[ $addr =~ ^[0-9a-f]+$ ]]; then
+ addr2=$(find_other_sock $addr)
+ line2=$(grep "^$addr2:" /proc/net/$prot)
+ [ -z "$line2" ] || line="$line"$'\n'"$line2"
+ fi
+fi
+
+if [ -n "$line" ]; then
+ (head -1 /proc/net/$prot;
+ echo "$line") | column -t
+ exit 0
+fi
+
+echo "No info found for $sockno [$sockfd]"