Added IMEI filtering and command line argument to strip Iridium SBD header

when writing files
This commit is contained in:
Christopher Ramey 2016-03-24 00:31:11 +00:00 committed by cdramey
parent 155ab39bf2
commit dbc6c8f7e2
2 changed files with 66 additions and 16 deletions

View File

@ -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) void shutdown_handler(int sig)
{ {
@ -61,22 +61,26 @@ void shutdown_handler(int sig)
static void print_help() static void print_help()
{ {
fprintf(stdout, "usage: %s [-d] [-l limit] [-p port] [-b addr] directory\n", exec_name); 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, " -d, --nodaemon Do not detach and daemonize\n");
fprintf(stdout, " -l, --limit <limit> Set concurrent connection limit (default: 128)\n"); fprintf(stdout, " -l, --limit <limit> Set concurrent connection limit (default: 128)\n");
fprintf(stdout, " -p, --port <port> Port to listen on (default: 10800)\n"); fprintf(stdout, " -p, --port <port> Port to listen on (default: 10800)\n");
fprintf(stdout, " -b, --bind <address> Address to bind to (default: 0.0.0.0)\n"); fprintf(stdout, " -b, --bind <address> Address to bind to (default: 0.0.0.0)\n");
fprintf(stdout, " -h, --help Print this message and exit\n"); fprintf(stdout, " -i, --imei <imei list> Comma separated list of IMEIs to allow (default: all)\n");
fprintf(stdout, " -v, --version Print version and exit\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[]) int main(int argc, char* argv[])
{ {
const struct option longopts[] = { const struct option longopts[] = {
{ "imei", required_argument, NULL, 'i' },
{ "limit", required_argument, NULL, 'l' }, { "limit", required_argument, NULL, 'l' },
{ "nodaemon", required_argument, NULL, 'd' }, { "nodaemon", required_argument, NULL, 'd' },
{ "port", required_argument, NULL, 'p' }, { "port", required_argument, NULL, 'p' },
{ "bind", required_argument, NULL, 'b' }, { "bind", required_argument, NULL, 'b' },
{ "strip", no_argument, NULL, 's' },
{ "version", no_argument, NULL, 'v' }, { "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' }, { "help", no_argument, NULL, 'h' },
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
@ -90,6 +94,11 @@ int main(int argc, char* argv[])
struct connection** conns = NULL; struct connection** conns = NULL;
struct pollfd* fds = 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){ if((exec_name = basename(argv[0])) == NULL){
fprintf(stderr, "%s: cannot get basename - %s\n", fprintf(stderr, "%s: cannot get basename - %s\n",
exec_name, strerror(errno) exec_name, strerror(errno)
@ -97,7 +106,7 @@ int main(int argc, char* argv[])
goto shutdown_error; 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){ switch(ch){
case 'd': case 'd':
daemonize = 0; daemonize = 0;
@ -111,6 +120,22 @@ int main(int argc, char* argv[])
goto shutdown_error; goto shutdown_error;
} }
break; 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': case 'p':
port = (int)strtol(optarg, NULL, 10); 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 // Convert and add three bytes for the SBD header
ssize_t expected = (ssize_t)htons(sbd_sz) + 3; ssize_t expected = (ssize_t)htons(sbd_sz) + 3;
// Iridium SBD format check. Is the protocol byte in place? int ok = 1;
// Is the reported size the same as the actual size written // Is the reported size the same as the actual size
// in bytes? If so, write it out. // written in bytes?
if(expected == conns[i-1]->len && conns[i-1]->buff[0] == 1){ if(expected != conns[i-1]->len) ok = 0;
write_connection(conns[i - 1]);
// 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]); 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 // Build a filename for the file we're writing based
// on the time and the source IP address // on the time and the source IP address
@ -473,8 +518,13 @@ static int write_connection(struct connection *conn)
return 1; return 1;
} }
unsigned char *buff = (strip ? (conn->buff + 3) : conn->buff);
ssize_t len = (strip ? (conn->len - 3) : conn->len);
// Write out the buffer // Write out the buffer
if(write(ofd, conn->buff, conn->len) == -1){ if(write(ofd, buff, len) == -1){
if(daemonize){ if(daemonize){
syslog(LOG_ERR, "write error on %s - %s", syslog(LOG_ERR, "write error on %s - %s",
fnbuff, strerror(errno) fnbuff, strerror(errno)

View File

@ -1 +1 @@
#define VERSION "1.0.1" #define VERSION "1.1"