Snooping on sockets/file descriptors
Hi, Is it possible for an application (say "snoop", with sufficient privileges) to monitor data on any socket/file descriptor in the system? Here's an example: suppose we have a browser and it creates a tcp socket to connect to a URL. Whenever the browser issues a read() and data is pushed to user space, I want "snoop" to get notified and made available a copy of the same data that the browser read. ptrace can be used to do it, but then there are several ways the app can read data. It could use read(), or recv() or recvmsg(). Is there a better way to deal with this complexity? It's like the action of "tee" on any socket/file descriptor in the system. -- Vimal
On Thu, Mar 31, 2011 at 10:29 PM, Vimal <j.vimal@gmail.com> wrote:
Hi,
Is it possible for an application (say "snoop", with sufficient privileges) to monitor data on any socket/file descriptor in the system?
Here's an example: suppose we have a browser and it creates a tcp socket to connect to a URL. Whenever the browser issues a read() and data is pushed to user space, I want "snoop" to get notified and made available a copy of the same data that the browser read.
ptrace can be used to do it, but then there are several ways the app can read data. It could use read(), or recv() or recvmsg(). Is there a better way to deal with this complexity?
It's like the action of "tee" on any socket/file descriptor in the system.
How about tcpdump? thanks, Daniel.
Hi Daniel,
How about tcpdump?
Thanks for the suggestion. tcpdump is good, but it doesn't solve all problems. There are a few reasons: * TCP packets could arrive out of order * The data needn't belong to a valid TCP connection * The app could just discard data (close/flush/etc) In short, there is a lot of state and complex logic which act on the packets before it is seen by the application. Given the complexity (such as wide variations in TCP implementation), I am not sure if reimplementing them is a good idea, even if it's possible. Thanks, -- Vimal
On Fri, Apr 1, 2011 at 03:04, Vimal <j.vimal@gmail.com> wrote:
Hi Daniel,
How about tcpdump?
Thanks for the suggestion.
tcpdump is good, but it doesn't solve all problems. There are a few reasons:
* TCP packets could arrive out of order * The data needn't belong to a valid TCP connection * The app could just discard data (close/flush/etc)
In short, there is a lot of state and complex logic which act on the packets before it is seen by the application.
then, something like dtrace or systemtap? IMO you're looking for kinda combo of kernel mode + user land "sniffer"... the user land sniffer, in it's very simple form, is by using LD_PRELOAD ... -- regards, Mulyadi Santosa Freelance Linux trainer and consultant blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com
then, something like dtrace or systemtap? IMO you're looking for kinda combo of kernel mode + user land "sniffer"... the user land sniffer, in it's very simple form, is by using LD_PRELOAD ...
dtrace seems fine and is similar to ptrace. But then, one would have to enumerate all possible syscalls that the application can issue to read data. For e.g., it could use read(), recvfrom(), recvmsg(), or even syscall(syscall#, args...) I wonder if LD_PRELOAD can be done on a program without shutting it down. ptrace fits the bill here, except for the above problem. Thanks! -- Vimal
On Fri, Apr 1, 2011 at 9:23 AM, Vimal <j.vimal@gmail.com> wrote:
then, something like dtrace or systemtap? IMO you're looking for kinda combo of kernel mode + user land "sniffer"... the user land sniffer, in it's very simple form, is by using LD_PRELOAD ...
dtrace seems fine and is similar to ptrace. But then, one would have to enumerate all possible syscalls that the application can issue to read data. For e.g., it could use read(), recvfrom(), recvmsg(), or even syscall(syscall#, args...)
I wonder if LD_PRELOAD can be done on a program without shutting it down. ptrace fits the bill here, except for the above problem.
If you want to do it in the kernel, you can write a loadable kernel module to register netfilter hooks and obtain the socket buffers (sk_buff). Look at this blog entry: http://fcns.eu/2010/02/netfilter-hooks/ Hope it helps. Regards, ----------------------------------------- Javier Martínez Canillas (+34) 682 39 81 69 PhD Student in High Performance Computing Computer Architecture and Operating System Department (CAOS) Universitat Autònoma de Barcelona Barcelona, Spain
Hi Javier,
If you want to do it in the kernel, you can write a loadable kernel module to register netfilter hooks and obtain the socket buffers (sk_buff).
Thanks. If you see my earlier posts, I didn't want netfilter/pcap because they give me access to packets. I would like access to the stream of data that is read by the application using read()/recvmsg()/etc syscalls. @all: thanks for the help; I think I've figured out how to do it. I manually traced the system call to see which one would be called ultimately, for read on a socket. It turns out that skb_copy_datagram_iovec(..) is called ultimately (fn defn: http://lxr.free-electrons.com/source/net/ipv4/tcp.c#L1668). I could hook onto this function using kprobes and get the data that is read. Thanks! -- Vimal
On 03/31/11 15:29, Vimal wrote:
Is it possible for an application (say "snoop", with sufficient privileges) to monitor data on any socket/file descriptor in the system? "snoop" it is :)
http://sourceforge.net/projects/snoop/
Here's an example: suppose we have a browser and it creates a tcp socket to connect to a URL. Whenever the browser issues a read() and data is pushed to user space, I want "snoop" to get notified and made available a copy of the same data that the browser read.
For this particular scenario snoop may not be the best choice: while it can attach on-the-fly when opening local files (inotify trigger), socket FDs must be picked manually after they've been opened (/proc/<pid>/fd/...) - so unless your connection is long-lived, this is going to be tricky. -- Florin
participants (5)
-
Daniel Baluta -
Florin Malita -
Javier Martinez Canillas -
Mulyadi Santosa -
Vimal