Как связать сетевое соединение с PID без использования lsof или netstat? - PullRequest
9 голосов
/ 08 мая 2009

Есть ли способ привязать сетевое соединение к PID (ID процесса) без разветвления для lsof или netstat?

В настоящее время lsof используется для опроса, какие соединения принадлежат какому процессу. Однако lsof или netstat могут быть довольно дорогими на занятом хосте и хотели бы избежать необходимости использовать эти инструменты.

Есть ли место, похожее на / proc / $ pid, где можно найти эту информацию? Я знаю, что такое сетевые подключения, изучив / proc / net, но не могу понять, как связать это с pid. В / proc / $ pid, похоже, нет никакой сетевой информации.

Целевыми хостами являются Linux 2.4 и Solaris 8-10. Если возможно, решение на Perl, но я готов сделать C / C ++.

дополнительные примечания:

Я хотел бы подчеркнуть, что цель здесь - привязать сетевое соединение к PID. Получение того или другого является тривиальным, но сложить их вдвоем по низкой цене кажется трудным. Спасибо за ответы до сих пор!

Ответы [ 6 ]

8 голосов
/ 08 мая 2009

Я не знаю, как часто вам нужно опрашивать или что вы имеете в виду под "дорогими", но с правильными опциями netstat и lsof работают намного быстрее, чем в конфигурации по умолчанию.
Примеры:

netstat -ltn

показывает только l istens t cp сокетов и пропускает (медленное) n разрешение ame, которое включено по умолчанию.

lsof -b -n -i4tcp:80

пропускает все операции блокировки b , разрешение n ame и ограничивает выбор сокетами IPv4 tcp на порту 80.

6 голосов
/ 23 мая 2009

В Solaris вы можете использовать pfiles(1) для этого:

# ps -fp 308 
     UID   PID  PPID   C    STIME TTY         TIME CMD
    root   308   255   0 22:44:07 ?           0:00 /usr/lib/ssh/sshd
# pfiles 308 | egrep 'S_IFSOCK|sockname: '
   6: S_IFSOCK mode:0666 dev:326,0 ino:3255 uid:0 gid:0 size:0
        sockname: AF_INET 192.168.1.30  port: 22

Для Linux это более сложно (ужасно):

# pgrep sshd
3155
# ls -l /proc/3155/fd | fgrep socket
lrwx------ 1 root root 64 May 22 23:04 3 -> socket:[7529]
# fgrep 7529 /proc/3155/net/tcp 
   6: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7529 1 f5baa8a0 300 0 0 2 -1            

00000000:0016 - это 0.0.0.0:22. Вот эквивалентный вывод из netstat -a:

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
1 голос
/ 08 мая 2009

Самое простое, что нужно сделать, это

strace -f netstat -na

В Linux (я не знаю о Solaris). Это даст вам журнал всех системных вызовов. Это много выходных, некоторые из которых будут актуальны. Посмотрите на файлы в файловой системе / proc, которые она открывает. Это должно привести вас к тому, как netstat это делает. Непристойно, ltrace позволит вам сделать то же самое через библиотеку c. В данном случае это не полезно для вас, но может быть полезно и в других обстоятельствах.

Если из этого не ясно, посмотрите на источник.

1 голос
/ 08 мая 2009

Для Linux взгляните на каталог /proc/net (например, cat /proc/net/tcp перечисляет ваши соединения TCP). Не уверен насчет Соляриса.

Дополнительная информация здесь .

Я полагаю, что netstat в основном использует ту же самую информацию, поэтому я не знаю, сможете ли вы ускорить ее в целом. Обязательно попробуйте флаги netstat '-an', чтобы НЕ разрешать IP-адреса в реальном времени для имен хостов (поскольку это может занять много времени из-за запросов DNS).

1 голос
/ 08 мая 2009

Почему бы вам не взглянуть на исходный код netstat и посмотреть, как он получает информацию? Это открытый исходный код.

0 голосов
/ 30 октября 2010

Посмотрите на эти ответы, в которых подробно рассматриваются доступные варианты:

...