|
|
@ -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 <limit> Set concurrent connection limit (default: 128)\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, " -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 <limit> Set concurrent connection limit (default: 128)\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, " -i, --imei <imei list> 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) |
|
|
|