从Linux内核v4.2-rc5开始,不可能使用libpcap使用的接口直接捕获。libpcap使用特定于Linux的AF_PACKET
(别名PF_PACKET
)域,该域仅允许您捕获通过“ netdevice ”(例如以太网接口)传输的数据的数据。
没有用于从AF_UNIX
套接字捕获的内核接口。标准以太网捕获具有带有源/目标的以太网头,等等。Unix套接字没有这样的伪头,并且链接层头类型注册表没有列出与此相关的任何内容。
对数据的基本入口点unix_stream_recvmsg
,并unix_stream_sendmsg
为SOCK_STREAM
(SOCK_DGRAM
和SOCK_SEQPACKET
有类似命名的功能)。数据sk->sk_receive_queue
在unix_stream_sendmsg
函数中和缓冲区中缓冲,没有代码最终导致调用该tpacket_rcv
函数进行数据包捕获。有关包捕获内部的一般细节,请参见osgx在SO上的分析。
回到有关AF_UNIX
套接字监视的原始问题,如果您主要对应用程序数据感兴趣,则可以选择以下方法:
- 被动(也适用于已经运行的进程):
strace
在执行I / O的可能的系统调用上使用和捕获。有很多人,read
,pread64
,readv
,preadv
,recvmsg
以及更多...查看@斯特凡Chazelas例如为xterm
。这种方法的缺点是,您首先必须找到文件描述符,然后仍然可能错过系统调用。使用strace可以将-e trace=file
它们用于大多数(pread
仅由覆盖-e trace=desc
,但大多数程序可能不用于Unix套接字)。
- 打破/修改
unix_stream_recvmsg
,unix_stream_sendmsg
(或unix_dgram_*
或者unix_seqpacket_*
)在内核和输出的数据,某处。您可以使用SystemTap设置此类跟踪点,这是一个监视传出消息的示例。需要内核支持和调试符号的可用性。
有效(仅适用于新流程):
使用还写入文件的代理。您可以自己编写一个快速多路复用器,也可以破解类似的东西,它也会输出一个pcap(请注意限制,例如AF_UNIX
可以传递文件描述符,AF_INET
但不能):
# fake TCP server connects to real Unix socket
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CONNECT:some.sock
# start packet capture on said port
tcpdump -i lo -f 'tcp port 6000'
# clients connect to this Unix socket
socat UNIX-LISTEN:fake.sock,fork TCP-CONNECT:127.0.0.1:6000
- 使用专用的应用程序代理。对于X11,有xscope(git,manual)。
CONFIG_UNIX_DIAG
不幸的是,建议的选项在这里也无济于事,它只能用于收集统计信息,而不能获取流经的实时数据(请参阅linux / unix_diag.h)。
不幸的是,对于产生pcap的Unix域套接字,目前还没有完美的跟踪器(据我所知)。理想情况下,将存在一个libpcap格式,该格式的标头包含源/目标PID(如果可用),后跟可选的附加数据(凭证,文件描述符),最后是数据。缺乏这一点,最好的办法就是系统调用跟踪。
其他信息(供感兴趣的读者使用)是一些回溯记录(通过GDB在unix_stream_*
和上中断rbreak packet.c:.
,在QEMU中的Linux和在主线Linux 4.2-rc5上的socat所获得):
# echo foo | socat - UNIX-LISTEN:/foo &
# echo bar | socat - UNIX-CONNECT:/foo
unix_stream_sendmsg at net/unix/af_unix.c:1638
sock_sendmsg_nosec at net/socket.c:610
sock_sendmsg at net/socket.c:620
sock_write_iter at net/socket.c:819
new_sync_write at fs/read_write.c:478
__vfs_write at fs/read_write.c:491
vfs_write at fs/read_write.c:538
SYSC_write at fs/read_write.c:585
SyS_write at fs/read_write.c:577
entry_SYSCALL_64_fastpath at arch/x86/entry/entry_64.S:186
unix_stream_recvmsg at net/unix/af_unix.c:2210
sock_recvmsg_nosec at net/socket.c:712
sock_recvmsg at net/socket.c:720
sock_read_iter at net/socket.c:797
new_sync_read at fs/read_write.c:422
__vfs_read at fs/read_write.c:434
vfs_read at fs/read_write.c:454
SYSC_read at fs/read_write.c:569
SyS_read at fs/read_write.c:562
# tcpdump -i lo &
# echo foo | socat - TCP-LISTEN:1337 &
# echo bar | socat - TCP-CONNECT:127.0.0.1:1337
tpacket_rcv at net/packet/af_packet.c:1962
dev_queue_xmit_nit at net/core/dev.c:1862
xmit_one at net/core/dev.c:2679
dev_hard_start_xmit at net/core/dev.c:2699
__dev_queue_xmit at net/core/dev.c:3104
dev_queue_xmit_sk at net/core/dev.c:3138
dev_queue_xmit at netdevice.h:2190
neigh_hh_output at include/net/neighbour.h:467
dst_neigh_output at include/net/dst.h:401
ip_finish_output2 at net/ipv4/ip_output.c:210
ip_finish_output at net/ipv4/ip_output.c:284
ip_output at net/ipv4/ip_output.c:356
dst_output_sk at include/net/dst.h:440
ip_local_out_sk at net/ipv4/ip_output.c:119
ip_local_out at include/net/ip.h:119
ip_queue_xmit at net/ipv4/ip_output.c:454
tcp_transmit_skb at net/ipv4/tcp_output.c:1039
tcp_write_xmit at net/ipv4/tcp_output.c:2128
__tcp_push_pending_frames at net/ipv4/tcp_output.c:2303
tcp_push at net/ipv4/tcp.c:689
tcp_sendmsg at net/ipv4/tcp.c:1276
inet_sendmsg at net/ipv4/af_inet.c:733
sock_sendmsg_nosec at net/socket.c:610
sock_sendmsg at net/socket.c:620
sock_write_iter at net/socket.c:819
new_sync_write at fs/read_write.c:478
__vfs_write at fs/read_write.c:491
vfs_write at fs/read_write.c:538
SYSC_write at fs/read_write.c:585
SyS_write at fs/read_write.c:577
entry_SYSCALL_64_fastpath at arch/x86/entry/entry_64.S:186
tpacket_rcv at net/packet/af_packet.c:1962
dev_queue_xmit_nit at net/core/dev.c:1862
xmit_one at net/core/dev.c:2679
dev_hard_start_xmit at net/core/dev.c:2699
__dev_queue_xmit at net/core/dev.c:3104
dev_queue_xmit_sk at net/core/dev.c:3138
dev_queue_xmit at netdevice.h:2190
neigh_hh_output at include/net/neighbour.h:467
dst_neigh_output at include/net/dst.h:401
ip_finish_output2 at net/ipv4/ip_output.c:210
ip_finish_output at net/ipv4/ip_output.c:284
ip_output at net/ipv4/ip_output.c:356
dst_output_sk at include/net/dst.h:440
ip_local_out_sk at net/ipv4/ip_output.c:119
ip_local_out at include/net/ip.h:119
ip_queue_xmit at net/ipv4/ip_output.c:454
tcp_transmit_skb at net/ipv4/tcp_output.c:1039
tcp_send_ack at net/ipv4/tcp_output.c:3375
__tcp_ack_snd_check at net/ipv4/tcp_input.c:4901
tcp_ack_snd_check at net/ipv4/tcp_input.c:4914
tcp_rcv_state_process at net/ipv4/tcp_input.c:5937
tcp_v4_do_rcv at net/ipv4/tcp_ipv4.c:1423
tcp_v4_rcv at net/ipv4/tcp_ipv4.c:1633
ip_local_deliver_finish at net/ipv4/ip_input.c:216
ip_local_deliver at net/ipv4/ip_input.c:256
dst_input at include/net/dst.h:450
ip_rcv_finish at net/ipv4/ip_input.c:367
ip_rcv at net/ipv4/ip_input.c:455
__netif_receive_skb_core at net/core/dev.c:3892
__netif_receive_skb at net/core/dev.c:3927
process_backlog at net/core/dev.c:4504
napi_poll at net/core/dev.c:4743
net_rx_action at net/core/dev.c:4808
__do_softirq at kernel/softirq.c:273
do_softirq_own_stack at arch/x86/entry/entry_64.S:970