问题
I want to debug TCP/IP interactions for a program I'm enhancing. I don't have root access (so no tcpdump etc), but the app runs under my own id. I could use e.g. strace to intercept the system calls, but are there alternatives worth recommending over that? If so, why - what do they offer? Command line prefered (no X server installed on my PC right now :-(), but curious about GUIs too.
Ideally, it would say something like:
app listening on port <portA> app listening on port <portB> client connection #1 accepted on listening port <portA> to local port <portC> from remote <hostX:portXA> app sent #1 <number> bytes "<data dump...>" app received from client #1 <number> bytes "<data dump...>" client #1 closed connection
Would scratch one together myself, but too many wheels to reinvent as is....
Thanks in advance.
UPDATE: both paulrubel and ypnos have made very helpful suggestions... (wish I could accept both answers, as they're distinct and equally good). Code implementing Paul's suggested LD_PRELOAD interception follows:
// TCP comms trace library
// as per http://www.jayconrod.com/cgi/view_post.py?23
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <dlfcn.h>
typedef ssize_t (*Recv)(int s, void* buf, size_t len, int flags);
ssize_t recv(int s, void* buf, size_t len, int flags)
{
static Recv real = NULL;
if (!real)
real = (Recv)dlsym(RTLD_NEXT, "recv");
fprintf(stderr, "> recv(s '%d', buf %p, len %lld, flags %d)...\n",
s, buf, len, flags);
ssize_t result = real(s, buf, len, flags);
fprintf(stderr, "< recv(s '%d', buf %p, len %lld, flags %d) return %lld\n",
s, buf, len, flags, result);
return result;
}
typedef ssize_t (*Send)(int s, const void* buf, size_t len, int flags);
ssize_t send(int s, const void* buf, size_t len, int flags)
{
static Send real = NULL;
if (!real)
real = (Send)dlsym(RTLD_NEXT, "send");
fprintf(stderr, "> send(s '%d', buf %p, len %lld, flags %d)...\n",
s, buf, len, flags);
ssize_t result = real(s, buf, len, flags);
fprintf(stderr, "< recv(s '%d', buf %p, len %lld, flags %d) return %lld\n",
s, buf, len, flags, result);
return result;
}
typedef int (*Connect)(int s, const struct sockaddr* serv_addr, socklen_t addrlen);
int connect(int s, const struct sockaddr* serv_addr, socklen_t addrlen)
{
static Connect real = NULL;
if (!real)
real = (Connect)dlsym(RTLD_NEXT, "connect");
fprintf(stderr, "> connect(s %d, sockaddr %p, addrlen %d)\n",
s, (void*)serv_addr, addrlen);
int result = real(s, serv_addr, addrlen);
fprintf(stderr, "< connect(s %d, sockaddr %p, addrlen %d) return %d\n",
s, (void*)serv_addr, addrlen, result);
return result;
}
typedef int (*Accept)(int s, const struct sockaddr* serv_addr, socklen_t* addrlen);
int accept(int s, struct sockaddr* serv_addr, socklen_t* addrlen)
{
static Accept real = NULL;
if (!real)
real = (Accept)dlsym(RTLD_NEXT, "accept");
fprintf(stderr, "> accept(s %d, sockaddr %p, addrlen %p)\n",
s, (void*)serv_addr, addrlen);
int result = real(s, serv_addr, addrlen);
fprintf(stderr, "< accept(s %d, sockaddr %p, addrlen %p -> %d) return %d\n",
s, (void*)serv_addr, addrlen, *addrlen, result);
return result;
}
回答1:
There is no way to intercept socket connections even if you're running on the same user id as the victim program.
What you need to do is
Let your own program print socket numbers etc.
Let your program connect to another program that in fact tunnels the connection to the real destination. There you can dump all the data sent/received.
回答2:
One idea, and it may be a bit of sledgehammer to swat a fly solution, is to use library interpositioning. You basically wrap a system call, connect and sendto seem like a good starting point for you, and log the parameters seen before passing off the data to the real call.
来源:https://stackoverflow.com/questions/3573830/good-linux-tcp-ip-monitoring-tools-that-dont-need-root-access