linux - tag - musicbrainz picard debian
¿Cómo puedo saber qué programa está en el otro extremo de un socket local? (8)
Strace me dice que un proceso en mi sistema Linux está hablando en un socket que tiene un descriptor de archivo 10. lsof me dice que este es un socket Unix con inode 11085, y netstat me dice que el Inode 11085 es un socket de corriente y que es conectado.
Dado que este proceso no tiene otros hilos, por lo tanto, debe haber otro proceso en el sistema que esté conectado al otro extremo de este socket. ¿Cómo puedo saber qué es?
Actualizar:
Hay algo de iluminación por parte del autor lsof here . Esencialmente, parece que Linux simplemente no proporciona esta información.
¿ netstat -p
ayuda?
De Manpage:
-p,
--program Show the PID and name of the program to which each socket belongs.
Escribí una tool que utiliza el método gdb para obtener de manera confiable información de pares de socket, no se necesitan símbolos de depuración del kernel.
Para conectar el proceso a un socket dado, pásale el número de inodo:
# socket_peer 11085
3703 thunderbird
Para descubrir todos los procesos a la vez, use netstat_unix
, agrega una columna a la salida de netstat:
# netstat_unix
Proto RefCnt Flags Type State I-Node PID/Program name Peer PID/Program name Path
unix 3 [ ] STREAM CONNECTED 6825 982/Xorg 1497/compiz /tmp/.X11-unix/X0
unix 3 [ ] STREAM CONNECTED 6824 1497/compiz 982/Xorg
unix 3 [ ] SEQPACKET CONNECTED 207142 3770/chromium-brows 17783/UMA-Session-R
unix 3 [ ] STREAM CONNECTED 204903 1523/pulseaudio 3703/thunderbird
unix 3 [ ] STREAM CONNECTED 204902 3703/thunderbird 1523/pulseaudio
unix 3 [ ] STREAM CONNECTED 204666 1523/pulseaudio 3703/thunderbird
...
Pruebe netstat_unix --dump
si necesita una salida que sea fácil de analizar.
Consulte tool para obtener más información.
Para información, el inodo + 1 / -1 hack no es confiable. Funciona la mayor parte del tiempo, pero fallará o (peor) devolverá el conector incorrecto si no tiene suerte.
He observado que:
El inodo del fd
que llamó a connect()
en el lado del cliente, siempre es exactamente uno mayor que el que recibió de la llamada accept()
en el lado del servidor.
Ejemplo de salida de mi programa:
client_fd=4
/proc/4436/fd/4
inode=3072
is socket
node: 3072 socket: /tmp/unix.socket
f0be8960: 00000003 00000000 00000000 0001 03 3072 /tmp/unix.socket
/proc/9293/fd/43
fd:43
inode=3073
is socket
node: 3073 socket:
f0be81e0: 00000003 00000000 00000000 0001 03 3073
La ruta enlazada no se muestra en /proc/net/unix
sin embargo.
YMMV y yo no hemos investigado la mecánica subyacente.
Parece que si estás realmente desesperado, puedes obtener esa información directamente de la memoria del kernel de Linux usando un depurador del kernel. Con la herramienta "crash" de RHEL5:
- obtenga una imagen
vmlinux
sin comprimir (por ejemplo, instalekernel-debuginfo
rpm o extraiga el archivovmlinux
de esa rpm) - ejecutar
crash /path/to/vmlinux
-
net -s 12345
enumera todos los sockets paraPID
12345 - encuentre el socket interesante (tiene que ser de la familia / tipo
UNIX:STREAM
), y anote su valor deSOCK
:-
PID: 12345 TASK: e903d000 CPU: 0 COMMAND: "someapp"
-
FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT
-
36 cadd0240 c8a64040 UNIX:STREAM
-
- ahora tiene la dirección de la
unix_sock struct
para este socket- básicamente,
unix_sock.peer.name
es la estructura de nombre del otro extremo del socket -
p *(*(*((struct unix_sock*)( (struct unix_sock*)0xc8a64040)->peer)).addr).name
con:p *(*(*((struct unix_sock*)( (struct unix_sock*)0xc8a64040)->peer)).addr).name
- básicamente,
Realmente triste que esta información no se exporta directamente al espacio de usuario.
Qué tal esto: grep 11085 /proc/net/unix
. Suponiendo que haya una ruta no vacía presente en la línea con el inodo que le interesa, grep
para esa ruta en /proc/net/unix
para encontrar el inodo para el otro extremo de la conexión, luego use el método @ efficientjelly''s para asignar el otro inodo a un pid
.
Un punto clave aquí es el hecho de que los dos zócalos conectados tendrán cada uno un número de inodo diferente.
Si por alguna razón no tiene suerte con las opciones adecuadas de lsof y netstat, también puede hacer lo siguiente:
find /proc -lname ''*11085*'' 2> /dev/null
lsof | grep 11085
lsof debe ejecutarse como root.
He estado experimentando con lsof en mi sistema Linux y lsof -U
muestra que todos los números en la columna NODE son únicos.
ss -p
le dirá (Siempre que el zócalo no sea propiedad del propio núcleo).