2009-05-08 2 views
9

Gibt es eine Möglichkeit, eine Netzwerkverbindung an eine PID (Prozess-ID) zu binden, ohne auf lsof oder netstat zu verzichten?Wie bindet man eine Netzwerkverbindung an eine PID, ohne lsof oder netstat zu verwenden?

Momentan wird lsof verwendet, um abzufragen, welche Verbindungen zu welcher Prozess-ID gehören. Allerdings kann lsof oder netstat auf einem ausgelasteten Host ziemlich teuer sein und würde es vermeiden wollen, auf diese Tools zu verzichten.

Gibt es einen ähnlichen Ort wie/proc/$ pid, wo man nach diesen Informationen suchen kann? Ich weiß, was die Netzwerkverbindungen sind, indem ich/proc/net untersuche, kann aber nicht herausfinden, wie man das an eine PID bindet. In/proc/$ pid gibt es keine Netzwerkinformationen.

Die Zielhosts sind Linux 2.4 und Solaris 8 bis 10. Wenn möglich, eine Lösung in Perl, aber bin bereit, C/C++ zu tun.

zusätzliche Hinweise:

Ich mag das Ziel hier betonen, ist eine Netzwerkverbindung zu einer PID zu binden. Das eine oder das andere zu bekommen ist trivial, aber es scheint schwierig zu sein, die beiden in einer billigen Weise zusammenzubringen. Danke für die Antworten bis jetzt!

Antwort

1

Warum guckst du nicht den Quellcode von netstat und sehen, wie es die Informationen bekommen? Es ist Open Source.

+1

ich netstat blickte eine Weile zurück. Ich bin mir ziemlich sicher, dass es sich einfach durchpflügt und einen Cache von Verbindungen baut. Ich glaube nicht, dass da Magie im Gange ist. – Duck

+0

@Duck keine Magie benötigt :-) Und es ist immer noch eine gute Referenz auf den Code kopieren, als er darauf hingewiesen, nicht netstat in einem Kind-Prozess ausführen möchten. – lothar

1

Für Linux, werfen Sie einen Blick auf das Verzeichnis (zum Beispiel, cat /proc/net/tcp listet Ihre TCP-Verbindungen). Ich bin mir nicht sicher über Solaris.

Einige weitere Informationen here.

Ich denke netstat verwendet im Grunde genau diese Informationen, so dass ich nicht weiß, ob Sie in der Lage sein werden, eine Menge zu beschleunigen. Stellen Sie sicher, dass Sie die netstat '-an'-Flags verwenden, um IP-Adressen NICHT zu Hostnamen in Echtzeit aufzulösen (da dies aufgrund von DNS-Abfragen viel Zeit in Anspruch nehmen kann).

+0

Wir fanden eine Runde um herauszufinden, die PID durch Betrachten von/proc/net/tcp. Von "tcp", erhalten Sie die UID und den Sockel. Dann traverse die/proc/*, wo der Besitzer uid ist und die 'fd' enthält den gleichen Sockel. Dies funktioniert leider nicht in Solaris. Auch ich hatte auf eine Lösung gehofft, bei der eine Suche durch das Dateisystem/proc nicht notwendig war. –

1

Die einfachste Sache zu tun ist,

strace -f netstat -na 

Unter Linux (ich weiß nicht, über Solaris). Dadurch erhalten Sie ein Protokoll aller getätigten Systemaufrufe. Es ist eine Menge Output, von denen einige relevant sein werden. Sehen Sie sich die Dateien im/proc-Dateisystem an, das geöffnet wird. Dies sollte Sie dazu bringen, wie netstat es macht. Indecently, ltrace ermöglicht es Ihnen, das gleiche durch die c-Bibliothek zu tun. In diesem Fall nicht nützlich für Sie, aber unter anderen Umständen kann es nützlich sein.

Wenn es nicht klar ist, dann sehen Sie sich die Quelle an.

8

Ich weiß nicht, wie oft Sie abfragen müssen, oder was Sie mit "teuer" meinen, aber mit den richtigen Optionen sowohl netstat als auch lsof laufen viel schneller als in der Standardkonfiguration. Beispiele
:

netstat -ltn 

zeigt nur l istening t cp Buchsen und lässt die (langsame) n ame Auflösung, die standardmäßig aktiviert ist.

lsof -b -n -i4tcp:80 

lässt alle b Sperroperationen, n ame Auflösung und schränkt die Auswahl an IPv4 TCP-Sockets auf Port 80

+1

Auf Linux 'netstat -tnp' gibt mir was ich will. Das 'P' gibt mir das Pid und tatsächlich ist es ziemlich schnell. Aber ich hatte gehofft zu vermeiden, dass ich auf Netstat verzichten musste, um diese Informationen zu bekommen. Gleiches gilt für "lsof", wo ich es sehr schnell zum Laufen gebracht habe, aber nicht aufgab. –

6

Unter Solaris können Sie pfiles(1), dies zu tun:

# 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 

Für Linux ist dies komplexer (schaurig):

# 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 ist 0.0.0.0:22. Hier ist der äquivalente Ausgang von netstat -a:

tcp  0  0 0.0.0.0:22    0.0.0.0:*    LISTEN 
Verwandte Themen