From 75e95789179b2efac88fd0f8d6555722695e3f94 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 26 Mar 2018 18:21:03 +0200 Subject: prepare for different payload dissectors --- utils.c | 129 +++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 88 insertions(+), 41 deletions(-) (limited to 'utils.c') diff --git a/utils.c b/utils.c index 0c763bc..55499af 100644 --- a/utils.c +++ b/utils.c @@ -3,36 +3,77 @@ #include #include #include +#include #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); } -- cgit v1.2.3