Busybox, netstat, нет -p
У меня очень старый (не спрашиваю почему) BusyBox (BusyBox v1.01 (2008.12.19-21: 31 + 0000) Встроенная оболочка (ясень)) на моем DreamBox. Я хотел бы выяснить, какой процесс открыл какое соединение, используя netstat. Но я обнаружил, что netstat BusyBox не содержит опцию -p. Какие еще есть возможности, чтобы узнать, какой процесс открыл (и использует) соответствующий сокет?
5 ответов
Вы можете найти эквивалентную информацию в несколько более уродливой форме (она же шестнадцатеричная) в /proc/net/tcp
, Там вы можете найти индекс соединения, который вы можете найти под /proc/$pid/fd/
,
Например:
$ cat /proc/net/tcp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 6115 1 f5adc4c0 300 0 0 2 -1
...
(В обычном netstat, но не в busybox netstat, -e
Опция также дает вам эту дополнительную информацию.)
а также
$ sudo ls -l /proc/2560/fd
...
lrwx------ 1 root root 64 7 jan 22.50 3 -> socket:[6115]
Вам нужен root-доступ для второго шага.
Не так удобно, как -p
Вариант, очевидно, но работает в безвыходном положении. Может быть в сценарии, если это необходимо.
Это может не помочь, если у вас нет возможности восстановить Busybox, но если это кому-нибудь поможет...
Busybox имеет опцию конфигурации для поддержки -p
переключатель Busyboxnetstat
, См вариант CONFIG_FEATURE_NETSTAT_PRG
, выбранный в параметрах меню busybox через Сетевые утилиты → netstat → Включить вывод PID/ имени программы.
Если у вас есть или можете получить ss
на вашем устройстве он также может показать PID:
ss -ltp # for TCP
ss -lup # for UDP
Вот полный awk-скрипт для этого. Это некрасиво, но это работает.
{ cat /proc/net/tcp; lsof; } | awk -vMACH=$(uname -m) 'BEGIN { if (MACH == "i686") { M=-2; B=7; } else { M=2; B=1 } } function addr(a) { if (a) { return sprintf("%d.%d.%d.%d:%d", "0x" substr(a, M*0+B, 2), "0x" substr(a, M*1+B, 2), "0x" substr(a, M*2+B, 2), "0x" substr(a, M*3+B, 2), "0x" substr(a, 10, 4)); } } substr($0,5,1)==":" { sock[$10]=$0; next } $3~/socket:/ { if (match($3, /[0-9]+/) == 0) { exit; } l = sock[substr($3, RSTART, RLENGTH)]; print $0 " " addr(substr(l, 7, 13)) " " addr(substr(l, 21, 13)) }'
Небольшой вариант, который может быть проще для некоторых:
- Определите интересный протокол и порт из netstat или другого источника.
- Преобразовать порт в шестнадцатеричный: echo | awk '{ printf "%x\n", $1 }'
- компакт-диск /proc/net
- grep -i <шестнадцатеричный_порт> {upd|tcp} | awk '{ printf "local: %s inode: %s", $2, $10 }' Если вы получаете несколько строк, найдите ту, которая имеет соответствующий hex_port во второй половине "локальной" строки.
- ls -al /proc//fd/ 2>/dev/null | grep
Это должно вернуть строку, похожую на:lrwx------ 1 root root 64 22 мая 20:02 /proc/1148/fd/26 -> сокет:[4520]
Сообщаю вам, что у PID 1148 открыт сокет на индексном дескрипторе 4520.
Пример. Поиск процесса SSDP на Philips Hue Bridge V2.x:
root@Philips-hue:/proc# netstat -an | grep 1900
udp 2176 0 0.0.0.0:1900 0.0.0.0:*
root@Philips-hue:/proc# echo 1900 | awk '{ printf "%x\n", $1 }'
76c
root@Philips-hue:/proc# grep -i 76c /proc/net/udp | awk '{ printf "local: %s ino
de: %s\n", $2, $10 }'
local: 00000000:076C inode: 4520
root@Philips-hue:/proc# ls -al /proc/*/fd/* 2>/dev/null | grep 4520
lrwx------ 1 root root 64 May 22 20:02 /proc/1148/fd/26 -> socket:[4520]
Итак, мы определили процесс PID=1148 как прослушиватель:
root@Philips-hue:/proc# ps w | grep 1148
1148 root 64016 S /usr/sbin/ipbridge -p /home/ipbridge/var -z /dev/ttyZigbee -u /etc/channel/channel-config -h /home -e ecb
1696 root 1284 S grep 1148
Итак, теперь я знаю, что демон ipbridge управляет прослушивателем SSDP, а также многими другими вещами, которыми он управляет на Hue Bridge.