add a LD_PRELOAD wrapper to trace client <-> qmuxd communications
This commit is contained in:
parent
bd82bb4fef
commit
377d3cf830
|
@ -0,0 +1,13 @@
|
|||
CFLAGS=-fPIC -Wall
|
||||
LDFLAGS=-shared -ldl
|
||||
|
||||
all: qmuxd_wrapper.so
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $^
|
||||
|
||||
qmuxd_wrapper.so: qmuxd_wrapper.o
|
||||
$(CC) $(LDFLAGS) -o $@ $^
|
||||
|
||||
clean:
|
||||
@rm -f qmuxd_wrapper.so *.o
|
|
@ -0,0 +1,127 @@
|
|||
#define _GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
static char hexd_buff[4096];
|
||||
static const char hex_chars[] = "0123456789abcdef";
|
||||
|
||||
static char *_osmo_hexdump(const unsigned char *buf, int len, char *delim)
|
||||
{
|
||||
int i;
|
||||
char *cur = hexd_buff;
|
||||
|
||||
hexd_buff[0] = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
const char *delimp = delim;
|
||||
int len_remain = sizeof(hexd_buff) - (cur - hexd_buff);
|
||||
if (len_remain < 3)
|
||||
break;
|
||||
|
||||
*cur++ = hex_chars[buf[i] >> 4];
|
||||
*cur++ = hex_chars[buf[i] & 0xf];
|
||||
|
||||
while (len_remain > 1 && *delimp) {
|
||||
*cur++ = *delimp++;
|
||||
len_remain--;
|
||||
}
|
||||
|
||||
*cur = 0;
|
||||
}
|
||||
hexd_buff[sizeof(hexd_buff)-1] = 0;
|
||||
return hexd_buff;
|
||||
}
|
||||
|
||||
static char *osmo_hexdump(const unsigned char *buf, int len)
|
||||
{
|
||||
return _osmo_hexdump(buf, len, " ");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Function pointers to hold the value of the glibc functions */
|
||||
static ssize_t (*real_write)(int fd, const void *buf, size_t count);
|
||||
static ssize_t (*real_read)(int fd, void *buf, size_t count);
|
||||
static int (*real_connect)(int fd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
static ssize_t (*real_send)(int sockfd, const void *buf, size_t len, int flags);
|
||||
static ssize_t (*real_recv)(int sockfd, void *buf, size_t len, int flags);
|
||||
static int (*real_close)(int fd);
|
||||
|
||||
static int trace_fds[16]= { -1, };
|
||||
static int num_trace_fds = 0;
|
||||
|
||||
static void dump_qmuxd(int fd, int to_qmux, const void *buf, size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_trace_fds; i++) {
|
||||
if (trace_fds[i] == fd)
|
||||
printf("%s_qmuxd(%u, %04x): %s\n", to_qmux ? "to" : "from", fd, len, osmo_hexdump(buf, len));
|
||||
}
|
||||
}
|
||||
|
||||
/* wrapping write function call */
|
||||
ssize_t write(int fd, const void *buf, size_t count)
|
||||
{
|
||||
dump_qmuxd(fd, 1, buf, count);
|
||||
|
||||
real_write = dlsym(RTLD_NEXT, "write");
|
||||
return real_write(fd, buf, count);
|
||||
}
|
||||
|
||||
ssize_t read(int fd, void *buf, size_t count)
|
||||
{
|
||||
dump_qmuxd(fd, 0, buf, count);
|
||||
|
||||
real_read = dlsym(RTLD_NEXT, "read");
|
||||
return real_read(fd, buf, count);
|
||||
}
|
||||
|
||||
ssize_t send(int fd, const void *buf, size_t count, int flags)
|
||||
{
|
||||
dump_qmuxd(fd, 1, buf, count);
|
||||
|
||||
real_send = dlsym(RTLD_NEXT, "send");
|
||||
return real_send(fd, buf, count, flags);
|
||||
}
|
||||
|
||||
ssize_t recv(int fd, void *buf, size_t len, int flags)
|
||||
{
|
||||
dump_qmuxd(fd, 0, buf, len);
|
||||
|
||||
real_recv = dlsym(RTLD_NEXT, "recv");
|
||||
return real_recv(fd, buf, len, flags);
|
||||
}
|
||||
|
||||
int connect(int fd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
if (addr->sa_family == AF_UNIX) {
|
||||
struct sockaddr_un *sun = (struct sockaddr_un *)addr;
|
||||
if (!strcmp(sun->sun_path, "/var/qmux_connect_socket")) {
|
||||
printf("Found socketfd to qmuxd: %d\n", fd);
|
||||
trace_fds[num_trace_fds++] = fd;
|
||||
}
|
||||
}
|
||||
|
||||
real_connect = dlsym(RTLD_NEXT, "connect");
|
||||
return real_connect(fd, addr, addrlen);
|
||||
}
|
||||
|
||||
int close(int fd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_trace_fds; i++) {
|
||||
if (trace_fds[i] == fd) {
|
||||
printf("Closed socketfd to qmuxd: %d\n", fd);
|
||||
trace_fds[i] = -1;
|
||||
}
|
||||
}
|
||||
real_close = dlsym(RTLD_NEXT, "close");
|
||||
return real_close(fd);
|
||||
}
|
Loading…
Reference in New Issue