From dbc6c8f7e263f13fa9503645ac5e6313169be469 Mon Sep 17 00:00:00 2001 From: Christopher Ramey Date: Thu, 24 Mar 2016 00:31:11 +0000 Subject: [PATCH] Added IMEI filtering and command line argument to strip Iridium SBD header when writing files --- src/wstationd.c | 80 +++++++++++++++++++++++++++++++++++++++---------- src/wstationd.h | 2 +- 2 files changed, 66 insertions(+), 16 deletions(-) diff --git a/src/wstationd.c b/src/wstationd.c index 8af9074..87cf96b 100644 --- a/src/wstationd.c +++ b/src/wstationd.c @@ -51,7 +51,7 @@ struct connection }; -static int write_connection(struct connection *); +static int write_connection(struct connection *, int strip); void shutdown_handler(int sig) { @@ -61,22 +61,26 @@ void shutdown_handler(int sig) static void print_help() { fprintf(stdout, "usage: %s [-d] [-l limit] [-p port] [-b addr] directory\n", exec_name); - fprintf(stdout, " -d, --nodaemon Do not detach and daemonize\n"); - fprintf(stdout, " -l, --limit Set concurrent connection limit (default: 128)\n"); - fprintf(stdout, " -p, --port Port to listen on (default: 10800)\n"); - fprintf(stdout, " -b, --bind
Address to bind to (default: 0.0.0.0)\n"); - fprintf(stdout, " -h, --help Print this message and exit\n"); - fprintf(stdout, " -v, --version Print version and exit\n"); + fprintf(stdout, " -d, --nodaemon Do not detach and daemonize\n"); + fprintf(stdout, " -l, --limit Set concurrent connection limit (default: 128)\n"); + fprintf(stdout, " -p, --port Port to listen on (default: 10800)\n"); + fprintf(stdout, " -b, --bind
Address to bind to (default: 0.0.0.0)\n"); + fprintf(stdout, " -i, --imei Comma separated list of IMEIs to allow (default: all)\n"); + fprintf(stdout, " -s, --strip Strip Iridium SBD header when writing files\n"); + fprintf(stdout, " -h, --help Print this message and exit\n"); + fprintf(stdout, " -v, --version Print version and exit\n"); } int main(int argc, char* argv[]) { const struct option longopts[] = { + { "imei", required_argument, NULL, 'i' }, { "limit", required_argument, NULL, 'l' }, { "nodaemon", required_argument, NULL, 'd' }, { "port", required_argument, NULL, 'p' }, { "bind", required_argument, NULL, 'b' }, + { "strip", no_argument, NULL, 's' }, { "version", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 } @@ -90,6 +94,11 @@ int main(int argc, char* argv[]) struct connection** conns = NULL; struct pollfd* fds = NULL; + char *imei_list = NULL; + size_t imei_list_sz = 0; + + int strip = 0; + if((exec_name = basename(argv[0])) == NULL){ fprintf(stderr, "%s: cannot get basename - %s\n", exec_name, strerror(errno) @@ -97,7 +106,7 @@ int main(int argc, char* argv[]) goto shutdown_error; } - for(int ch; (ch = getopt_long(argc, argv, "l:b:p:dvh0", longopts, NULL)) != -1;){ + for(int ch; (ch = getopt_long(argc, argv, "i:l:b:p:dsvh0", longopts, NULL)) != -1;){ switch(ch){ case 'd': daemonize = 0; @@ -111,6 +120,22 @@ int main(int argc, char* argv[]) goto shutdown_error; } break; + + case 'i': + imei_list = argv[optind-1]; + imei_list_sz = strlen(imei_list); + + // If the user provides the word "all" as the only imei entry, + // remove the filter. + if(imei_list_sz == 3 && memcmp(imei_list, "all", 3) == 0){ + imei_list_sz = 0; + imei_list = NULL; + } + break; + + case 's': + strip = 1; + break; case 'p': port = (int)strtol(optarg, NULL, 10); @@ -299,12 +324,32 @@ int main(int argc, char* argv[]) // Convert and add three bytes for the SBD header ssize_t expected = (ssize_t)htons(sbd_sz) + 3; - // Iridium SBD format check. Is the protocol byte in place? - // Is the reported size the same as the actual size written - // in bytes? If so, write it out. - if(expected == conns[i-1]->len && conns[i-1]->buff[0] == 1){ - write_connection(conns[i - 1]); + int ok = 1; + // Is the reported size the same as the actual size + // written in bytes? + if(expected != conns[i-1]->len) ok = 0; + + // Is the protocol byte in place? + if(ok && conns[i-1]->buff[0] != 1) ok = 0; + + // Do we have an IMEI list? + if(imei_list_sz != 0 && conns[i-1]->len > 25){ + // If so, check IMEI against list + if(memmem(imei_list, imei_list_sz, (conns[i-1]->buff + 10), 15) == NULL){ + if(daemonize){ + syslog(LOG_NOTICE, "IMEI rejected: %.*s", + 15, (conns[i-1]->buff + 10) + ); + } else { + fprintf(stderr, "%s: IMEI rejected: %.*s\n", + exec_name, 15, (conns[i-1]->buff + 10) + ); + } + ok = 0; + } } + + if(ok) write_connection(conns[i - 1], strip); } free(conns[i - 1]); @@ -444,7 +489,7 @@ int main(int argc, char* argv[]) } -static int write_connection(struct connection *conn) +static int write_connection(struct connection *conn, int strip) { // Build a filename for the file we're writing based // on the time and the source IP address @@ -473,8 +518,13 @@ static int write_connection(struct connection *conn) return 1; } + + unsigned char *buff = (strip ? (conn->buff + 3) : conn->buff); + ssize_t len = (strip ? (conn->len - 3) : conn->len); + + // Write out the buffer - if(write(ofd, conn->buff, conn->len) == -1){ + if(write(ofd, buff, len) == -1){ if(daemonize){ syslog(LOG_ERR, "write error on %s - %s", fnbuff, strerror(errno) diff --git a/src/wstationd.h b/src/wstationd.h index 380630a..1fc901b 100644 --- a/src/wstationd.h +++ b/src/wstationd.h @@ -1 +1 @@ -#define VERSION "1.0.1" +#define VERSION "1.1"