summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--sock_events.c50
-rw-r--r--utils.c129
-rw-r--r--utils.h12
4 files changed, 125 insertions, 67 deletions
diff --git a/Makefile b/Makefile
index 4ff2901..9978e73 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,5 @@
LIB_SRCS = utils.c sock_events.c libc_overrides.c
+CFLAGS = -Wall
default: libudtrace.so
diff --git a/sock_events.c b/sock_events.c
index 523f45a..9340d7d 100644
--- a/sock_events.c
+++ b/sock_events.c
@@ -14,6 +14,7 @@
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
+#include <sys/un.h>
#include <unistd.h>
#ifdef __ANDROID__
@@ -25,13 +26,6 @@
#define IS_OUT true
#define IS_IN false
-static void trace_data(int fd, bool is_out, const char *fn, const uint8_t *data, unsigned int len)
-{
- if (!data || !len)
- return;
- fprintf(stderr, "%d %s %c %s\n", fd, fn, is_out ? 'W' : 'R', udtrace_hexdump(data, len, ""));
-}
-
static void trace_iov(int fd, bool is_out, const char *fn, int ret,
const struct iovec *iovec, int iovec_count)
{
@@ -46,7 +40,7 @@ static void trace_iov(int fd, bool is_out, const char *fn, int ret,
if (remain < vec->iov_len)
written_len = remain;
- trace_data(fd, is_out, fn, vec->iov_base, written_len);
+ udtrace_data(fd, is_out, fn, vec->iov_base, written_len);
remain -= written_len;
}
@@ -60,16 +54,26 @@ void sock_ev_socket(int fd, int domain, int type, int protocol)
{
if (domain != AF_UNIX)
return;
- add_fd(fd);
+ udtrace_add_fd(fd);
}
void sock_ev_bind(int fd, int ret, int err, const struct sockaddr *addr, socklen_t len)
{
+ const struct sockaddr_un *sun = (const struct sockaddr_un *) addr;
+ if (ret < 0)
+ return;
+ LOG("bind(%d, \"%s\")\n", fd, sun->sun_path);
+ udtrace_fd_set_path(fd, sun->sun_path);
}
void sock_ev_connect(int fd, int ret, int err, const struct sockaddr *addr,
socklen_t len)
{
+ const struct sockaddr_un *sun = (const struct sockaddr_un *) addr;
+ if (ret < 0)
+ return;
+ LOG("connect(%d, \"%s\")\n", fd, sun->sun_path);
+ udtrace_fd_set_path(fd, sun->sun_path);
}
void sock_ev_listen(int fd, int ret, int err, int backlog)
@@ -81,7 +85,7 @@ void sock_ev_accept(int fd, int ret, int err, struct sockaddr *addr,
{
if (ret < 0)
return;
- add_fd(ret);
+ udtrace_add_fd(ret);
}
void sock_ev_accept4(int fd, int ret, int err, struct sockaddr *addr,
@@ -89,7 +93,7 @@ void sock_ev_accept4(int fd, int ret, int err, struct sockaddr *addr,
{
if (ret < 0)
return;
- add_fd(ret);
+ udtrace_add_fd(ret);
}
void sock_ev_send(int fd, int ret, int err, const void *buf, size_t bytes,
@@ -97,14 +101,14 @@ void sock_ev_send(int fd, int ret, int err, const void *buf, size_t bytes,
{
if (ret <= 0)
return;
- trace_data(fd, IS_OUT, "send", buf, ret);
+ udtrace_data(fd, IS_OUT, "send", buf, ret);
}
void sock_ev_recv(int fd, int ret, int err, void *buf, size_t bytes, int flags)
{
if (ret <= 0)
return;
- trace_data(fd, IS_IN, "recv", buf, ret);
+ udtrace_data(fd, IS_IN, "recv", buf, ret);
}
void sock_ev_sendto(int fd, int ret, int err, const void *buf, size_t bytes,
@@ -112,7 +116,7 @@ void sock_ev_sendto(int fd, int ret, int err, const void *buf, size_t bytes,
{
if (ret <= 0)
return;
- trace_data(fd, IS_OUT, "sendto", buf, ret);
+ udtrace_data(fd, IS_OUT, "sendto", buf, ret);
}
void sock_ev_recvfrom(int fd, int ret, int err, void *buf, size_t bytes,
@@ -120,7 +124,7 @@ void sock_ev_recvfrom(int fd, int ret, int err, void *buf, size_t bytes,
{
if (ret <= 0)
return;
- trace_data(fd, IS_IN, "recvfrom", buf, ret);
+ udtrace_data(fd, IS_IN, "recvfrom", buf, ret);
}
void sock_ev_sendmsg(int fd, int ret, int err, const struct msghdr *msg,
@@ -168,40 +172,40 @@ void sock_ev_write(int fd, int ret, int err, const void *buf, size_t bytes)
{
if (ret <= 0)
return;
- trace_data(fd, IS_OUT, "write", buf, ret);
+ udtrace_data(fd, IS_OUT, "write", buf, ret);
}
void sock_ev_read(int fd, int ret, int err, void *buf, size_t bytes)
{
if (ret <= 0)
return;
- trace_data(fd, IS_IN, "read", buf, ret);
+ udtrace_data(fd, IS_IN, "read", buf, ret);
}
void sock_ev_close(int fd, int ret, int err)
{
- del_fd(fd);
+ udtrace_del_fd(fd);
}
void sock_ev_dup(int fd, int ret, int err)
{
if (ret >= 0)
- add_fd(ret);
+ udtrace_add_fd(ret);
}
void sock_ev_dup2(int fd, int ret, int err, int newfd)
{
if (ret >= 0) {
- del_fd(newfd);
- add_fd(ret);
+ udtrace_del_fd(newfd);
+ udtrace_add_fd(ret);
}
}
void sock_ev_dup3(int fd, int ret, int err, int newfd, int flags)
{
if (ret >= 0) {
- del_fd(newfd);
- add_fd(ret);
+ udtrace_del_fd(newfd);
+ udtrace_add_fd(ret);
}
}
diff --git a/utils.c b/utils.c
index 0c763bc..55499af 100644
--- a/utils.c
+++ b/utils.c
@@ -3,36 +3,77 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <string.h>
#include "utils.h"
#define MAX_UNIX_FDS 32
-#define LOG(fmt, args ...) \
- fprintf(stderr, ">>> UDTRACE: " fmt, ## args)
-
/***********************************************************************
* Utility functions
***********************************************************************/
-static int unix_fds[MAX_UNIX_FDS];
+/* taken from libosmocore */
+static char hexd_buff[4096];
+static const char hex_chars[] = "0123456789abcdef";
+static char *hexdump(const unsigned char *buf, int len, char *delim)
+{
+ int i;
+ char *cur = hexd_buff;
-__attribute__ ((constructor)) static void udtrace_init(void) {
+ 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;
+}
+
+typedef void (*udtrace_dissector)(int fd, bool is_out, const char *fn, const uint8_t *data, unsigned int len);
+
+static void default_dissector(int fd, bool is_out, const char *fn, const uint8_t *data, unsigned int len)
+{
+ fprintf(stderr, "%d %s %c %s\n", fd, fn, is_out ? 'W' : 'R', hexdump(data, len, ""));
+}
+
+struct sock_state {
+ int fd;
+ const char *path;
+ udtrace_dissector dissector;
+};
+
+static struct sock_state unix_fds[MAX_UNIX_FDS];
+
+__attribute__ ((constructor)) static void udtrace_init(void)
+{
int i;
LOG("Unix Domain Socket Trace initialized\n");
for (i = 0; i < ARRAY_SIZE(unix_fds); i++) {
- unix_fds[i] = -1;
+ unix_fds[i] = (struct sock_state) { -1, NULL, NULL };
}
}
/* add a file descriptor from the list of to-be-traced ones */
-void add_fd(int fd)
+void udtrace_add_fd(int fd)
{
int i;
for (i = 0; i < ARRAY_SIZE(unix_fds); i++) {
- if (unix_fds[i] == -1) {
+ if (unix_fds[i].fd == -1) {
LOG("Adding FD %d\n", fd);
- unix_fds[i] = fd;
+ unix_fds[i].fd = fd;
return;
}
}
@@ -40,56 +81,62 @@ void add_fd(int fd)
}
/* delete a file descriptor from the list of to-be-traced ones */
-void del_fd(int fd)
+void udtrace_del_fd(int fd)
{
int i;
for (i = 0; i < ARRAY_SIZE(unix_fds); i++) {
- if (unix_fds[i] == fd) {
+ if (unix_fds[i].fd == fd) {
LOG("Removing FD %d\n", fd);
- unix_fds[i] = -1;
+ free((void *) unix_fds[i].path);
+ unix_fds[i] = (struct sock_state) { -1, NULL, NULL };
return;
}
}
LOG("Couldn't delete UNIX FD %d (no such FD)\n", fd);
}
-/* is the given file descriptor part of the to-be-traced unix domain fd's? */
-bool is_unix_socket(int fd)
+static void udtrace_resolve_dissector(struct sock_state *ss)
+{
+ /* FIXME: actual useful dissectors resovled by path */
+ ss->dissector = &default_dissector;
+}
+
+/* set the path of a given fd */
+void udtrace_fd_set_path(int fd, const char *path)
{
int i;
for (i = 0; i < ARRAY_SIZE(unix_fds); i++) {
- if (unix_fds[i] == fd)
- return true;
+ if (unix_fds[i].fd == fd) {
+ unix_fds[i].path = strdup(path);
+ udtrace_resolve_dissector(&unix_fds[i]);
+ return;
+ }
}
- return false;
}
-
-/* taken from libosmocore */
-static char hexd_buff[4096];
-static const char hex_chars[] = "0123456789abcdef";
-char *udtrace_hexdump(const unsigned char *buf, int len, char *delim)
+const struct sock_state *udtrace_sstate_by_fd(int fd)
{
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];
+ for (i = 0; i < ARRAY_SIZE(unix_fds); i++) {
+ if (unix_fds[i].fd == fd)
+ return &unix_fds[i];
+ }
+ return NULL;
+}
- while (len_remain > 1 && *delimp) {
- *cur++ = *delimp++;
- len_remain--;
- }
+/* is the given file descriptor part of the to-be-traced unix domain fd's? */
+bool is_unix_socket(int fd)
+{
+ if (udtrace_sstate_by_fd(fd))
+ return true;
+ else
+ return false;
+}
- *cur = 0;
- }
- hexd_buff[sizeof(hexd_buff)-1] = 0;
- return hexd_buff;
+void udtrace_data(int fd, bool is_out, const char *fn, const uint8_t *data, unsigned int len)
+{
+ const struct sock_state *ss = udtrace_sstate_by_fd(fd);
+ if (!data || !len || !ss)
+ return;
+ ss->dissector(fd, is_out, fn, data, len);
}
diff --git a/utils.h b/utils.h
index 8148518..f1f52f4 100644
--- a/utils.h
+++ b/utils.h
@@ -3,13 +3,19 @@
/*! Determine number of elements in an array of static size */
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#define LOG(fmt, args ...) \
+ fprintf(stderr, ">>> UDTRACE: " fmt, ## args)
+
/* add a file descriptor from the list of to-be-traced ones */
-void add_fd(int fd);
+void udtrace_add_fd(int fd);
/* delete a file descriptor from the list of to-be-traced ones */
-void del_fd(int fd);
+void udtrace_del_fd(int fd);
+
+/* set the path of a given fd */
+void udtrace_fd_set_path(int fd, const char *path);
/* is the given file descriptor part of the to-be-traced unix domain fd's? */
bool is_unix_socket(int fd);
-char *udtrace_hexdump(const unsigned char *buf, int len, char *delim);
+void udtrace_data(int fd, bool is_out, const char *fn, const uint8_t *data, unsigned int len);
personal git repositories of Harald Welte. Your mileage may vary