summaryrefslogtreecommitdiff
path: root/utils.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2018-03-26 18:21:03 +0200
committerHarald Welte <laforge@gnumonks.org>2018-03-26 18:21:03 +0200
commit75e95789179b2efac88fd0f8d6555722695e3f94 (patch)
tree27e630a8847de500287867f64eecc5951424fe45 /utils.c
parent4bbf70b9f367afab929cb6c2f214475ee09b2403 (diff)
prepare for different payload dissectors
Diffstat (limited to 'utils.c')
-rw-r--r--utils.c129
1 files changed, 88 insertions, 41 deletions
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);
}
personal git repositories of Harald Welte. Your mileage may vary