Added IMEI filtering and command line argument to strip Iridium SBD header
when writing files
This commit is contained in:
		@ -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)
 | 
			
		||||
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
#define VERSION "1.0.1"
 | 
			
		||||
#define VERSION "1.1"
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user