aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml1
-rw-r--r--.gitlab-ci.yml1
-rw-r--r--config.h21
-rw-r--r--nDPId-test.c4
-rw-r--r--nDPId.c179
-rw-r--r--nDPIsrvd.c164
-rw-r--r--utils.c40
-rw-r--r--utils.h17
8 files changed, 261 insertions, 166 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index aebd96f22..c746dc15f 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -70,6 +70,7 @@ jobs:
run: |
./build/nDPId-test || test $? -eq 1
./build/nDPId -h || test $? -eq 1
+ ./build/nDPIsrvd -h || test $? -eq 1
- name: Test DIFF
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.ndpid_gcrypt, '-DNDPI_WITH_GCRYPT=OFF')
run: |
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c485efe20..4e2e8fc44 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -53,6 +53,7 @@ build_and_test:
- cd ..
- ./build/nDPId-test || test $? -eq 1
- ./build/nDPId -h || test $? -eq 1
+ - ./build/nDPIsrvd -h || test $? -eq 1
# dameon start/stop test
- NUSER=nobody make -C ./build daemon VERBOSE=1
- NUSER=nobody make -C ./build daemon VERBOSE=1
diff --git a/config.h b/config.h
index afc8d1d20..8d0387634 100644
--- a/config.h
+++ b/config.h
@@ -2,6 +2,7 @@
#define CONFIG_H 1
/* macros shared across multiple executables */
+#define DEFAULT_CHUSER "nobody"
#define COLLECTOR_UNIX_SOCKET "/tmp/ndpid-collector.sock"
#define DISTRIBUTOR_UNIX_SOCKET "/tmp/ndpid-distributor.sock"
#define DISTRIBUTOR_HOST "127.0.0.1"
@@ -23,17 +24,17 @@
#define nDPId_MAX_IDLE_FLOWS_PER_THREAD (nDPId_MAX_FLOWS_PER_THREAD / 32u)
#define nDPId_MAX_READER_THREADS 32u
#define nDPId_ERROR_EVENT_THRESHOLD_N 16u
-#define nDPId_ERROR_EVENT_THRESHOLD_TIME TIME_S_TO_US(10u) /* 10 sec */
-#define nDPId_DAEMON_STATUS_INTERVAL TIME_S_TO_US(600u) /* 600 sec */
+#define nDPId_ERROR_EVENT_THRESHOLD_TIME TIME_S_TO_US(10u) /* 10 sec */
+#define nDPId_DAEMON_STATUS_INTERVAL TIME_S_TO_US(600u) /* 600 sec */
#define nDPId_MEMORY_PROFILING_LOG_INTERVAL TIME_S_TO_US(5u) /* 5 sec */
-#define nDPId_COMPRESSION_SCAN_INTERVAL TIME_S_TO_US(20u) /* 20 sec */
-#define nDPId_COMPRESSION_FLOW_INACTIVITY TIME_S_TO_US(30u) /* 30 sec */
-#define nDPId_FLOW_SCAN_INTERVAL TIME_S_TO_US(10u) /* 10 sec */
-#define nDPId_GENERIC_IDLE_TIME TIME_S_TO_US(600u) /* 600 sec */
-#define nDPId_ICMP_IDLE_TIME TIME_S_TO_US(120u) /* 120 sec */
-#define nDPId_TCP_IDLE_TIME TIME_S_TO_US(7440u) /* 7440 sec */
-#define nDPId_UDP_IDLE_TIME TIME_S_TO_US(180u) /* 180 sec */
-#define nDPId_TCP_POST_END_FLOW_TIME TIME_S_TO_US(120u) /* 120 sec */
+#define nDPId_COMPRESSION_SCAN_INTERVAL TIME_S_TO_US(20u) /* 20 sec */
+#define nDPId_COMPRESSION_FLOW_INACTIVITY TIME_S_TO_US(30u) /* 30 sec */
+#define nDPId_FLOW_SCAN_INTERVAL TIME_S_TO_US(10u) /* 10 sec */
+#define nDPId_GENERIC_IDLE_TIME TIME_S_TO_US(600u) /* 600 sec */
+#define nDPId_ICMP_IDLE_TIME TIME_S_TO_US(120u) /* 120 sec */
+#define nDPId_TCP_IDLE_TIME TIME_S_TO_US(7440u) /* 7440 sec */
+#define nDPId_UDP_IDLE_TIME TIME_S_TO_US(180u) /* 180 sec */
+#define nDPId_TCP_POST_END_FLOW_TIME TIME_S_TO_US(120u) /* 120 sec */
#define nDPId_THREAD_DISTRIBUTION_SEED 0x03dd018b
#define nDPId_PACKETS_PER_FLOW_TO_SEND 15u
#define nDPId_PACKETS_PER_FLOW_TO_PROCESS NDPI_DEFAULT_MAX_NUM_PKTS_PER_FLOW_TO_DISSECT
diff --git a/nDPId-test.c b/nDPId-test.c
index ae28b2b64..b125d5e99 100644
--- a/nDPId-test.c
+++ b/nDPId-test.c
@@ -1141,13 +1141,13 @@ int main(int argc, char ** argv)
nDPId_options.memory_profiling_log_interval = (unsigned long long int)-1;
nDPId_options.reader_thread_count = 1; /* Please do not change this! Generating meaningful pcap diff's relies on a
single reader thread! */
- nDPId_options.instance_alias = strdup("nDPId-test");
+ set_cmdarg(&nDPId_options.instance_alias, "nDPId-test");
if (access(argv[1], R_OK) != 0)
{
logger(1, "%s: pcap file `%s' does not exist or is not readable", argv[0], argv[1]);
return 1;
}
- nDPId_options.pcap_file_or_interface = strdup(argv[1]);
+ set_cmdarg(&nDPId_options.pcap_file_or_interface, argv[1]);
if (validate_options() != 0)
{
return 1;
diff --git a/nDPId.c b/nDPId.c
index 0410d7fb3..ca131bbfd 100644
--- a/nDPId.c
+++ b/nDPId.c
@@ -441,27 +441,27 @@ static MT_VALUE(zlib_compression_bytes, uint64_t) = MT_INIT(0);
static struct
{
/* opts */
- char * pcap_file_or_interface;
+ struct cmdarg pcap_file_or_interface;
+ struct cmdarg bpf_str;
+ struct cmdarg pidfile;
+ struct cmdarg user;
+ struct cmdarg group;
+ struct cmdarg custom_protocols_file;
+ struct cmdarg custom_categories_file;
+ struct cmdarg custom_ja3_file;
+ struct cmdarg custom_sha1_file;
+ struct cmdarg collector_address;
+ struct cmdarg instance_alias;
union nDPId_ip pcap_dev_ip4, pcap_dev_ip6;
union nDPId_ip pcap_dev_netmask4, pcap_dev_netmask6;
union nDPId_ip pcap_dev_subnet4, pcap_dev_subnet6;
uint8_t process_internal_initial_direction;
uint8_t process_external_initial_direction;
- char * bpf_str;
- char pidfile[UNIX_PATH_MAX];
- char * user;
- char * group;
- char * custom_protocols_file;
- char * custom_categories_file;
- char * custom_ja3_file;
- char * custom_sha1_file;
- char collector_address[UNIX_PATH_MAX];
#ifdef ENABLE_ZLIB
uint8_t enable_zlib_compression;
#endif
uint8_t enable_data_analysis;
/* subopts */
- char * instance_alias;
unsigned long long int max_flows_per_thread;
unsigned long long int max_idle_flows_per_thread;
unsigned long long int reader_thread_count;
@@ -484,9 +484,17 @@ static struct
unsigned long long int max_packets_per_flow_to_analyse;
unsigned long long int error_event_threshold_n;
unsigned long long int error_event_threshold_time;
-} nDPId_options = {.pidfile = nDPId_PIDFILE,
- .user = "nobody",
- .collector_address = COLLECTOR_UNIX_SOCKET,
+} nDPId_options = {.pcap_file_or_interface = CMDARG(NULL),
+ .bpf_str = CMDARG(NULL),
+ .pidfile = CMDARG(nDPId_PIDFILE),
+ .user = CMDARG(DEFAULT_CHUSER),
+ .group = CMDARG(NULL),
+ .custom_protocols_file = CMDARG(NULL),
+ .custom_categories_file = CMDARG(NULL),
+ .custom_ja3_file = CMDARG(NULL),
+ .custom_sha1_file = CMDARG(NULL),
+ .collector_address = CMDARG(COLLECTOR_UNIX_SOCKET),
+ .instance_alias = CMDARG(NULL),
.max_flows_per_thread = nDPId_MAX_FLOWS_PER_THREAD / 2,
.max_idle_flows_per_thread = nDPId_MAX_IDLE_FLOWS_PER_THREAD / 2,
.reader_thread_count = nDPId_MAX_READER_THREADS / 2,
@@ -986,7 +994,7 @@ static int get_ip6_address_and_netmask(char const * const ifa_name, size_t ifnam
logger(0,
"%s IPv6 address/prefix netmask subnet: %s/%u %s %s",
- nDPId_options.pcap_file_or_interface,
+ get_cmdarg(&nDPId_options.pcap_file_or_interface),
addr6,
plen,
netmask6,
@@ -1053,7 +1061,7 @@ static int get_ip4_address_and_netmask(char const * const ifa_name, size_t ifnam
void * ssubn = &nDPId_options.pcap_dev_subnet4.v4.ip;
logger(0,
"%s IPv4 address netmask subnet: %s %s %s",
- nDPId_options.pcap_file_or_interface,
+ get_cmdarg(&nDPId_options.pcap_file_or_interface),
inet_ntop(AF_INET, saddr, addr, sizeof(addr)),
inet_ntop(AF_INET, snetm, netm, sizeof(netm)),
inet_ntop(AF_INET, ssubn, subn, sizeof(subn)));
@@ -1236,10 +1244,10 @@ static struct nDPId_workflow * init_workflow(char const * const file_or_device)
return NULL;
}
- if (nDPId_options.bpf_str != NULL)
+ if (is_cmdarg_set(&nDPId_options.bpf_str) != 0)
{
struct bpf_program fp;
- if (pcap_compile(workflow->pcap_handle, &fp, nDPId_options.bpf_str, 1, PCAP_NETMASK_UNKNOWN) != 0)
+ if (pcap_compile(workflow->pcap_handle, &fp, get_cmdarg(&nDPId_options.bpf_str), 1, PCAP_NETMASK_UNKNOWN) != 0)
{
logger_early(1, "pcap_compile: %s", pcap_geterr(workflow->pcap_handle));
free_workflow(&workflow);
@@ -1292,21 +1300,21 @@ static struct nDPId_workflow * init_workflow(char const * const file_or_device)
NDPI_PROTOCOL_BITMASK protos;
NDPI_BITMASK_SET_ALL(protos);
ndpi_set_protocol_detection_bitmask2(workflow->ndpi_struct, &protos);
- if (nDPId_options.custom_protocols_file != NULL)
+ if (is_cmdarg_set(&nDPId_options.custom_protocols_file) != 0)
{
- ndpi_load_protocols_file(workflow->ndpi_struct, nDPId_options.custom_protocols_file);
+ ndpi_load_protocols_file(workflow->ndpi_struct, get_cmdarg(&nDPId_options.custom_protocols_file));
}
- if (nDPId_options.custom_categories_file != NULL)
+ if (is_cmdarg_set(&nDPId_options.custom_categories_file) != 0)
{
- ndpi_load_categories_file(workflow->ndpi_struct, nDPId_options.custom_categories_file, NULL);
+ ndpi_load_categories_file(workflow->ndpi_struct, get_cmdarg(&nDPId_options.custom_categories_file), NULL);
}
- if (nDPId_options.custom_ja3_file != NULL)
+ if (is_cmdarg_set(&nDPId_options.custom_ja3_file) != 0)
{
- ndpi_load_malicious_ja3_file(workflow->ndpi_struct, nDPId_options.custom_ja3_file);
+ ndpi_load_malicious_ja3_file(workflow->ndpi_struct, get_cmdarg(&nDPId_options.custom_ja3_file));
}
- if (nDPId_options.custom_sha1_file != NULL)
+ if (is_cmdarg_set(&nDPId_options.custom_sha1_file) != 0)
{
- ndpi_load_malicious_sha1_file(workflow->ndpi_struct, nDPId_options.custom_sha1_file);
+ ndpi_load_malicious_sha1_file(workflow->ndpi_struct, get_cmdarg(&nDPId_options.custom_sha1_file));
}
ndpi_finalize_initialization(workflow->ndpi_struct);
@@ -1484,28 +1492,30 @@ static int setup_reader_threads(void)
return 1;
}
- if (nDPId_options.pcap_file_or_interface == NULL)
+ if (is_cmdarg_set(&nDPId_options.pcap_file_or_interface) == 0)
{
- nDPId_options.pcap_file_or_interface = get_default_pcapdev(pcap_error_buffer);
- if (nDPId_options.pcap_file_or_interface == NULL)
+ char * const pcapdev = get_default_pcapdev(pcap_error_buffer);
+ set_cmdarg(&nDPId_options.pcap_file_or_interface, pcapdev);
+ free(pcapdev);
+ if (is_cmdarg_set(&nDPId_options.pcap_file_or_interface) == 0)
{
logger_early(1, "pcap_lookupdev: %.*s", (int)PCAP_ERRBUF_SIZE, pcap_error_buffer);
return 1;
}
- logger_early(0, "Capturing packets from default device: %s", nDPId_options.pcap_file_or_interface);
+ logger_early(0, "Capturing packets from default device: %s", get_cmdarg(&nDPId_options.pcap_file_or_interface));
}
errno = 0;
- if (access(nDPId_options.pcap_file_or_interface, R_OK) != 0 && errno == ENOENT)
+ if (access(get_cmdarg(&nDPId_options.pcap_file_or_interface), R_OK) != 0 && errno == ENOENT)
{
errno = 0;
- if (get_ip_netmask_from_pcap_dev(nDPId_options.pcap_file_or_interface) != 0)
+ if (get_ip_netmask_from_pcap_dev(get_cmdarg(&nDPId_options.pcap_file_or_interface)) != 0)
{
if (errno != 0)
{
logger_early(1,
"Could not get netmask for pcap device %s: %s",
- nDPId_options.pcap_file_or_interface,
+ get_cmdarg(&nDPId_options.pcap_file_or_interface),
strerror(errno));
}
return 1;
@@ -1527,7 +1537,7 @@ static int setup_reader_threads(void)
for (unsigned long long int i = 0; i < nDPId_options.reader_thread_count; ++i)
{
- reader_threads[i].workflow = init_workflow(nDPId_options.pcap_file_or_interface);
+ reader_threads[i].workflow = init_workflow(get_cmdarg(&nDPId_options.pcap_file_or_interface));
if (reader_threads[i].workflow == NULL)
{
return 1;
@@ -1981,8 +1991,10 @@ static void jsonize_basic(struct nDPId_reader_thread * const reader_thread, int
ndpi_serialize_string_int32(&workflow->ndpi_serializer, "thread_id", reader_thread->array_index);
}
ndpi_serialize_string_uint32(&workflow->ndpi_serializer, "packet_id", workflow->packets_captured);
- ndpi_serialize_string_string(&workflow->ndpi_serializer, "source", nDPId_options.pcap_file_or_interface);
- ndpi_serialize_string_string(&workflow->ndpi_serializer, "alias", nDPId_options.instance_alias);
+ ndpi_serialize_string_string(&workflow->ndpi_serializer,
+ "source",
+ get_cmdarg(&nDPId_options.pcap_file_or_interface));
+ ndpi_serialize_string_string(&workflow->ndpi_serializer, "alias", get_cmdarg(&nDPId_options.instance_alias));
}
static void jsonize_daemon(struct nDPId_reader_thread * const reader_thread, enum daemon_event event)
@@ -2232,7 +2244,7 @@ static void send_to_collector(struct nDPId_reader_thread * const reader_thread,
"[%8llu, %zu] Reconnected to nDPIsrvd Collector at %s",
workflow->packets_captured,
reader_thread->array_index,
- nDPId_options.collector_address);
+ get_cmdarg(&nDPId_options.collector_address));
jsonize_daemon(reader_thread, DAEMON_EVENT_RECONNECT);
}
}
@@ -2244,7 +2256,7 @@ static void send_to_collector(struct nDPId_reader_thread * const reader_thread,
"[%8llu, %zu] Could not connect to nDPIsrvd Collector at %s, will try again later. Error: %s",
workflow->packets_captured,
reader_thread->array_index,
- nDPId_options.collector_address,
+ get_cmdarg(&nDPId_options.collector_address),
(reader_thread->collector_sock_last_errno != 0
? strerror(reader_thread->collector_sock_last_errno)
: "Internal Error."));
@@ -2275,7 +2287,7 @@ static void send_to_collector(struct nDPId_reader_thread * const reader_thread,
workflow->packets_captured,
reader_thread->array_index,
(collector_address.raw.sa_family == AF_UNIX ? "Connection" : "Datagram"),
- nDPId_options.collector_address);
+ get_cmdarg(&nDPId_options.collector_address));
}
reader_thread->collector_sock_last_errno = saved_errno;
}
@@ -2302,7 +2314,7 @@ static void send_to_collector(struct nDPId_reader_thread * const reader_thread,
"[%8llu, %zu] Send data (blocking I/O) to nDPIsrvd Collector at %s failed: %s",
workflow->packets_captured,
reader_thread->array_index,
- nDPId_options.collector_address,
+ get_cmdarg(&nDPId_options.collector_address),
strerror(saved_errno));
reader_thread->collector_sock_last_errno = saved_errno;
break;
@@ -4476,7 +4488,7 @@ static void * processing_thread(void * const ndpi_thread_arg)
logger(1,
"Thread %zu: Could not connect to nDPIsrvd Collector at %s, will try again later. Error: %s",
reader_thread->array_index,
- nDPId_options.collector_address,
+ get_cmdarg(&nDPId_options.collector_address),
(reader_thread->collector_sock_last_errno != 0 ? strerror(reader_thread->collector_sock_last_errno)
: "Internal Error."));
}
@@ -4516,30 +4528,33 @@ static int start_reader_threads(void)
return 1;
}
- if (daemonize_with_pidfile(nDPId_options.pidfile) != 0)
+ if (daemonize_with_pidfile(get_cmdarg(&nDPId_options.pidfile)) != 0)
{
return 1;
}
errno = 0;
- if (nDPId_options.user != NULL &&
- change_user_group(nDPId_options.user, nDPId_options.group, nDPId_options.pidfile, NULL, NULL) != 0 &&
+ if (change_user_group(get_cmdarg(&nDPId_options.user),
+ get_cmdarg(&nDPId_options.group),
+ get_cmdarg(&nDPId_options.pidfile),
+ NULL,
+ NULL) != 0 &&
errno != EPERM)
{
if (errno != 0)
{
logger(1,
"Change user/group to %s/%s failed: %s",
- (nDPId_options.user != NULL ? nDPId_options.user : "-"),
- (nDPId_options.group != NULL ? nDPId_options.group : "-"),
+ get_cmdarg(&nDPId_options.user),
+ get_cmdarg(&nDPId_options.group),
strerror(errno));
}
else
{
logger(1,
"Change user/group to %s/%s failed.",
- (nDPId_options.user != NULL ? nDPId_options.user : "-"),
- (nDPId_options.group != NULL ? nDPId_options.group : "-"));
+ get_cmdarg(&nDPId_options.user),
+ get_cmdarg(&nDPId_options.group));
}
return 1;
}
@@ -4816,10 +4831,8 @@ static void print_subopt_usage(void)
} while (1);
}
-static int nDPId_parse_options(int argc, char ** argv)
+static void print_usage(char const * const arg0)
{
- int opt;
-
static char const usage[] =
"Usage: %s "
"[-i pcap-file/interface] [-I] [-E] [-B bpf-filter]\n"
@@ -4844,9 +4857,12 @@ static int nDPId_parse_options(int argc, char ** argv)
"\t-l\tLog all messages to stderr.\n"
"\t-L\tLog all messages to a log file.\n"
"\t-c\tPath to a UNIX socket (nDPIsrvd Collector) or a custom UDP endpoint.\n"
- "\t-d\tForking into background after initialization.\n"
+ "\t \tDefault: %s\n"
+ "\t-d\tFork into background after initialization.\n"
"\t-p\tWrite the daemon PID to the given file path.\n"
+ "\t \tDefault: %s\n"
"\t-u\tChange UID to the numeric value of user.\n"
+ "\t \tDefault: %s\n"
"\t-g\tChange GID to the numeric value of group.\n"
"\t-P\tLoad a nDPI custom protocols file.\n"
"\t-C\tLoad a nDPI custom categories file.\n"
@@ -4867,13 +4883,24 @@ static int nDPId_parse_options(int argc, char ** argv)
"\t-o\t(Carefully) Tune some daemon options. See subopts below.\n"
"\t-v\tversion\n"
"\t-h\tthis\n\n";
+ fprintf(stderr,
+ usage,
+ arg0,
+ get_cmdarg(&nDPId_options.collector_address),
+ get_cmdarg(&nDPId_options.pidfile),
+ get_cmdarg(&nDPId_options.user));
+}
+
+static int nDPId_parse_options(int argc, char ** argv)
+{
+ int opt;
while ((opt = getopt(argc, argv, "i:IEB:lL:c:dp:u:g:P:C:J:S:a:Azo:vh")) != -1)
{
switch (opt)
{
case 'i':
- nDPId_options.pcap_file_or_interface = strdup(optarg);
+ set_cmdarg(&nDPId_options.pcap_file_or_interface, optarg);
break;
case 'I':
nDPId_options.process_internal_initial_direction = 1;
@@ -4882,7 +4909,7 @@ static int nDPId_parse_options(int argc, char ** argv)
nDPId_options.process_external_initial_direction = 1;
break;
case 'B':
- nDPId_options.bpf_str = strdup(optarg);
+ set_cmdarg(&nDPId_options.bpf_str, optarg);
break;
case 'l':
enable_console_logger();
@@ -4894,36 +4921,34 @@ static int nDPId_parse_options(int argc, char ** argv)
}
break;
case 'c':
- strncpy(nDPId_options.collector_address, optarg, sizeof(nDPId_options.collector_address) - 1);
- nDPId_options.collector_address[sizeof(nDPId_options.collector_address) - 1] = '\0';
+ set_cmdarg(&nDPId_options.collector_address, optarg);
break;
case 'd':
daemonize_enable();
break;
case 'p':
- strncpy(nDPId_options.pidfile, optarg, sizeof(nDPId_options.pidfile) - 1);
- nDPId_options.pidfile[sizeof(nDPId_options.pidfile) - 1] = '\0';
+ set_cmdarg(&nDPId_options.pidfile, optarg);
break;
case 'u':
- nDPId_options.user = strdup(optarg);
+ set_cmdarg(&nDPId_options.user, optarg);
break;
case 'g':
- nDPId_options.group = strdup(optarg);
+ set_cmdarg(&nDPId_options.group, optarg);
break;
case 'P':
- nDPId_options.custom_protocols_file = strdup(optarg);
+ set_cmdarg(&nDPId_options.custom_protocols_file, optarg);
break;
case 'C':
- nDPId_options.custom_categories_file = strdup(optarg);
+ set_cmdarg(&nDPId_options.custom_categories_file, optarg);
break;
case 'J':
- nDPId_options.custom_ja3_file = strdup(optarg);
+ set_cmdarg(&nDPId_options.custom_ja3_file, optarg);
break;
case 'S':
- nDPId_options.custom_sha1_file = strdup(optarg);
+ set_cmdarg(&nDPId_options.custom_sha1_file, optarg);
break;
case 'a':
- nDPId_options.instance_alias = strdup(optarg);
+ set_cmdarg(&nDPId_options.instance_alias, optarg);
break;
case 'A':
nDPId_options.enable_data_analysis = 1;
@@ -4950,7 +4975,7 @@ static int nDPId_parse_options(int argc, char ** argv)
{
logger_early(1, "Missing value for `%s'", subopt_token[subopt]);
fprintf(stderr, "%s", "\n");
- fprintf(stderr, usage, argv[0]);
+ print_usage(argv[0]);
print_subopt_usage();
return 1;
}
@@ -4958,7 +4983,7 @@ static int nDPId_parse_options(int argc, char ** argv)
{
logger_early(1, "Invalid subopt: %s", value);
fprintf(stderr, "%s", "\n");
- fprintf(stderr, usage, argv[0]);
+ print_usage(argv[0]);
print_subopt_usage();
return 1;
}
@@ -5045,7 +5070,7 @@ static int nDPId_parse_options(int argc, char ** argv)
case 'h':
default:
fprintf(stderr, "%s\n", get_nDPId_version());
- fprintf(stderr, usage, argv[0]);
+ print_usage(argv[0]);
print_subopt_usage();
return 1;
}
@@ -5055,7 +5080,7 @@ static int nDPId_parse_options(int argc, char ** argv)
{
logger_early(1, "%s", "Unexpected argument after options");
fprintf(stderr, "%s", "\n");
- fprintf(stderr, usage, argv[0]);
+ print_usage(argv[0]);
print_subopt_usage();
return 1;
}
@@ -5090,12 +5115,12 @@ static int validate_options(void)
}
}
#endif
- if (nDPIsrvd_setup_address(&collector_address, nDPId_options.collector_address) != 0)
+ if (nDPIsrvd_setup_address(&collector_address, get_cmdarg(&nDPId_options.collector_address)) != 0)
{
retval = 1;
- logger_early(1, "Collector socket invalid address: %s.", nDPId_options.collector_address);
+ logger_early(1, "Collector socket invalid address: %s.", get_cmdarg(&nDPId_options.collector_address));
}
- if (nDPId_options.instance_alias == NULL)
+ if (is_cmdarg_set(&nDPId_options.instance_alias) == 0)
{
char hname[256];
@@ -5107,9 +5132,11 @@ static int validate_options(void)
}
else
{
- nDPId_options.instance_alias = strdup(hname);
- logger_early(1, "No instance alias given, using your hostname '%s'", nDPId_options.instance_alias);
- if (nDPId_options.instance_alias == NULL)
+ set_cmdarg(&nDPId_options.instance_alias, hname);
+ logger_early(1,
+ "No instance alias given, using your hostname '%s'",
+ get_cmdarg(&nDPId_options.instance_alias));
+ if (is_cmdarg_set(&nDPId_options.instance_alias) == 0)
{
retval = 1;
}
@@ -5285,7 +5312,7 @@ int main(int argc, char ** argv)
}
free_reader_threads();
- daemonize_shutdown(nDPId_options.pidfile);
+ daemonize_shutdown(get_cmdarg(&nDPId_options.pidfile));
logger(0, "%s", "Bye.");
shutdown_logging();
diff --git a/nDPIsrvd.c b/nDPIsrvd.c
index eab484e7e..e57e2625a 100644
--- a/nDPIsrvd.c
+++ b/nDPIsrvd.c
@@ -84,19 +84,24 @@ static struct nDPIsrvd_address distributor_in_address = {
static struct
{
- char * pidfile;
- char * collector_un_sockpath;
- char * distributor_un_sockpath;
- char * distributor_in_address;
+ struct cmdarg pidfile;
+ struct cmdarg collector_un_sockpath;
+ struct cmdarg distributor_un_sockpath;
+ struct cmdarg distributor_in_address;
+ struct cmdarg user;
+ struct cmdarg group;
nDPIsrvd_ull max_remote_descriptors;
- char * user;
- char * group;
nDPIsrvd_ull max_write_buffers;
int bufferbloat_fallback_to_blocking;
-} nDPIsrvd_options = {.max_remote_descriptors = nDPIsrvd_MAX_REMOTE_DESCRIPTORS,
+} nDPIsrvd_options = {.pidfile = CMDARG(nDPIsrvd_PIDFILE),
+ .collector_un_sockpath = CMDARG(COLLECTOR_UNIX_SOCKET),
+ .distributor_un_sockpath = CMDARG(DISTRIBUTOR_UNIX_SOCKET),
+ .distributor_in_address = CMDARG(NULL),
+ .user = CMDARG(DEFAULT_CHUSER),
+ .group = CMDARG(NULL),
+ .max_remote_descriptors = nDPIsrvd_MAX_REMOTE_DESCRIPTORS,
.max_write_buffers = nDPIsrvd_MAX_WRITE_BUFFERS,
- .bufferbloat_fallback_to_blocking = 1,
- .user = "nobody"};
+ .bufferbloat_fallback_to_blocking = 1};
static void logger_nDPIsrvd(struct remote_desc const * const remote,
char const * const prefix,
@@ -457,7 +462,7 @@ static int create_listen_sockets(void)
return 1;
}
- if (nDPIsrvd_options.distributor_in_address != NULL)
+ if (is_cmdarg_set(&nDPIsrvd_options.distributor_in_address) != 0)
{
distributor_in_sockfd = socket(distributor_in_address.raw.sa_family, SOCK_STREAM, 0);
if (distributor_in_sockfd < 0)
@@ -487,7 +492,7 @@ static int create_listen_sockets(void)
int written = snprintf(collector_addr.sun_path,
sizeof(collector_addr.sun_path),
"%s",
- nDPIsrvd_options.collector_un_sockpath);
+ get_cmdarg(&nDPIsrvd_options.collector_un_sockpath));
if (written < 0)
{
logger(1, "snprintf failed: %s", strerror(errno));
@@ -497,7 +502,7 @@ static int create_listen_sockets(void)
{
logger(1,
"Collector UNIX socket path too long, current/max: %zu/%zu",
- strlen(nDPIsrvd_options.collector_un_sockpath),
+ strlen(get_cmdarg(&nDPIsrvd_options.collector_un_sockpath)),
sizeof(collector_addr.sun_path) - 1);
return 1;
}
@@ -506,7 +511,7 @@ static int create_listen_sockets(void)
{
logger(1,
"Error binding Collector UNIX socket to `%s': %s",
- nDPIsrvd_options.collector_un_sockpath,
+ get_cmdarg(&nDPIsrvd_options.collector_un_sockpath),
strerror(errno));
return 1;
}
@@ -518,7 +523,7 @@ static int create_listen_sockets(void)
int written = snprintf(distributor_addr.sun_path,
sizeof(distributor_addr.sun_path),
"%s",
- nDPIsrvd_options.distributor_un_sockpath);
+ get_cmdarg(&nDPIsrvd_options.distributor_un_sockpath));
if (written < 0)
{
logger(1, "snprintf failed: %s", strerror(errno));
@@ -528,7 +533,7 @@ static int create_listen_sockets(void)
{
logger(1,
"Distributor UNIX socket path too long, current/max: %zu/%zu",
- strlen(nDPIsrvd_options.distributor_un_sockpath),
+ strlen(get_cmdarg(&nDPIsrvd_options.distributor_un_sockpath)),
sizeof(distributor_addr.sun_path) - 1);
return 2;
}
@@ -537,19 +542,19 @@ static int create_listen_sockets(void)
{
logger(1,
"Error binding Distributor socket to `%s': %s",
- nDPIsrvd_options.distributor_un_sockpath,
+ get_cmdarg(&nDPIsrvd_options.distributor_un_sockpath),
strerror(errno));
return 2;
}
}
- if (nDPIsrvd_options.distributor_in_address != NULL)
+ if (is_cmdarg_set(&nDPIsrvd_options.distributor_in_address) != 0)
{
if (bind(distributor_in_sockfd, &distributor_in_address.raw, distributor_in_address.size) < 0)
{
logger(1,
"Error binding Distributor TCP/IP socket to %s: %s",
- nDPIsrvd_options.distributor_in_address,
+ get_cmdarg(&nDPIsrvd_options.distributor_in_address),
strerror(errno));
return 3;
}
@@ -557,7 +562,7 @@ static int create_listen_sockets(void)
{
logger(1,
"Error listening Distributor TCP/IP socket to %s: %s",
- nDPIsrvd_options.distributor_in_address,
+ get_cmdarg(&nDPIsrvd_options.distributor_in_address),
strerror(errno));
return 3;
}
@@ -565,7 +570,7 @@ static int create_listen_sockets(void)
{
logger(1,
"Error setting Distributor TCP/IP socket %s to non-blocking mode: %s",
- nDPIsrvd_options.distributor_in_address,
+ get_cmdarg(&nDPIsrvd_options.distributor_in_address),
strerror(errno));
return 3;
}
@@ -581,7 +586,7 @@ static int create_listen_sockets(void)
{
logger(1,
"Error setting Collector UNIX socket `%s' to non-blocking mode: %s",
- nDPIsrvd_options.collector_un_sockpath,
+ get_cmdarg(&nDPIsrvd_options.collector_un_sockpath),
strerror(errno));
return 3;
}
@@ -590,7 +595,7 @@ static int create_listen_sockets(void)
{
logger(1,
"Error setting Distributor UNIX socket `%s' to non-blocking mode: %s",
- nDPIsrvd_options.distributor_un_sockpath,
+ get_cmdarg(&nDPIsrvd_options.distributor_un_sockpath),
strerror(errno));
return 3;
}
@@ -800,23 +805,19 @@ static int nDPIsrvd_parse_options(int argc, char ** argv)
}
break;
case 'c':
- free(nDPIsrvd_options.collector_un_sockpath);
- nDPIsrvd_options.collector_un_sockpath = strdup(optarg);
+ set_cmdarg(&nDPIsrvd_options.collector_un_sockpath, optarg);
break;
case 'd':
daemonize_enable();
break;
case 'p':
- free(nDPIsrvd_options.pidfile);
- nDPIsrvd_options.pidfile = strdup(optarg);
+ set_cmdarg(&nDPIsrvd_options.pidfile, optarg);
break;
case 's':
- free(nDPIsrvd_options.distributor_un_sockpath);
- nDPIsrvd_options.distributor_un_sockpath = strdup(optarg);
+ set_cmdarg(&nDPIsrvd_options.distributor_un_sockpath, optarg);
break;
case 'S':
- free(nDPIsrvd_options.distributor_in_address);
- nDPIsrvd_options.distributor_in_address = strdup(optarg);
+ set_cmdarg(&nDPIsrvd_options.distributor_in_address, optarg);
break;
case 'm':
if (str_value_to_ull(optarg, &nDPIsrvd_options.max_remote_descriptors) != CONVERSION_OK)
@@ -826,11 +827,10 @@ static int nDPIsrvd_parse_options(int argc, char ** argv)
}
break;
case 'u':
- nDPIsrvd_options.user = strdup(optarg);
+ set_cmdarg(&nDPIsrvd_options.user, optarg);
break;
case 'g':
- free(nDPIsrvd_options.group);
- nDPIsrvd_options.group = strdup(optarg);
+ set_cmdarg(&nDPIsrvd_options.group, optarg);
break;
case 'C':
if (str_value_to_ull(optarg, &nDPIsrvd_options.max_write_buffers) != CONVERSION_OK)
@@ -853,44 +853,57 @@ static int nDPIsrvd_parse_options(int argc, char ** argv)
"\t[-s path-to-distributor-unix-socket] [-S distributor-host:port]\n"
"\t[-m max-remote-descriptors] [-u user] [-g group]\n"
"\t[-C max-buffered-json-lines] [-D]\n"
- "\t[-v] [-h]\n",
- argv[0]);
+ "\t[-v] [-h]\n\n"
+ "\t-l\tLog all messages to stderr.\n"
+ "\t-L\tLog all messages to a log file.\n"
+ "\t-c\tPath to a listening UNIX socket (nDPIsrvd Collector).\n"
+ "\t \tDefault: %s\n"
+ "\t-d\tFork into background after initialization.\n"
+ "\t-p\tWrite the daemon PID to the given file path.\n"
+ "\t \tDefault: %s\n"
+ "\t-m\tMax accepted (Collector and Distributor) clients.\n"
+ "\t-u\tChange UID to the numeric value of user.\n"
+ "\t \tDefault: %s\n"
+ "\t-g\tChange GID to the numeric value of group.\n"
+ "\t-C\tMax buffered JSON lines before nDPIsrvd disconnects/blocking-IO a client.\n"
+ "\t-D\tDisconnect a slow client instead of falling back to blocking-IO.\n"
+ "\t-s\tPath to a listening UNIX socket (nDPIsrvd Distributor).\n"
+ "\t \tDefault: %s\n"
+ "\t-S\tAddress:Port of the listening TCP/IP socket (nDPIsrvd Distributor).\n"
+ "\t-v\tversion\n"
+ "\t-h\tthis\n\n",
+ argv[0],
+ get_cmdarg(&nDPIsrvd_options.collector_un_sockpath),
+ get_cmdarg(&nDPIsrvd_options.pidfile),
+ get_cmdarg(&nDPIsrvd_options.user),
+ get_cmdarg(&nDPIsrvd_options.distributor_un_sockpath));
return 1;
}
}
- if (nDPIsrvd_options.pidfile == NULL)
- {
- nDPIsrvd_options.pidfile = strdup(nDPIsrvd_PIDFILE);
- }
- if (is_path_absolute("Pidfile", nDPIsrvd_options.pidfile) != 0)
+ if (is_path_absolute("Pidfile", get_cmdarg(&nDPIsrvd_options.pidfile)) != 0)
{
return 1;
}
- if (nDPIsrvd_options.collector_un_sockpath == NULL)
- {
- nDPIsrvd_options.collector_un_sockpath = strdup(COLLECTOR_UNIX_SOCKET);
- }
- if (is_path_absolute("Collector UNIX socket", nDPIsrvd_options.collector_un_sockpath) != 0)
+ if (is_path_absolute("Collector UNIX socket", get_cmdarg(&nDPIsrvd_options.collector_un_sockpath)) != 0)
{
return 1;
}
- if (nDPIsrvd_options.distributor_un_sockpath == NULL)
- {
- nDPIsrvd_options.distributor_un_sockpath = strdup(DISTRIBUTOR_UNIX_SOCKET);
- }
- if (is_path_absolute("Distributor UNIX socket", nDPIsrvd_options.distributor_un_sockpath) != 0)
+ if (is_path_absolute("Distributor UNIX socket", get_cmdarg(&nDPIsrvd_options.distributor_un_sockpath)) != 0)
{
return 1;
}
- if (nDPIsrvd_options.distributor_in_address != NULL)
+ if (is_cmdarg_set(&nDPIsrvd_options.distributor_in_address) != 0)
{
- if (nDPIsrvd_setup_address(&distributor_in_address, nDPIsrvd_options.distributor_in_address) != 0)
+ if (nDPIsrvd_setup_address(&distributor_in_address, get_cmdarg(&nDPIsrvd_options.distributor_in_address)) != 0)
{
- logger_early(1, "%s: Could not parse address %s", argv[0], nDPIsrvd_options.distributor_in_address);
+ logger_early(1,
+ "%s: Could not parse address %s",
+ argv[0],
+ get_cmdarg(&nDPIsrvd_options.distributor_in_address));
return 1;
}
if (distributor_in_address.raw.sa_family == AF_UNIX)
@@ -898,8 +911,8 @@ static int nDPIsrvd_parse_options(int argc, char ** argv)
logger_early(1,
"%s: You've requested to setup another UNIX socket `%s', but there is already one at `%s'",
argv[0],
- nDPIsrvd_options.distributor_in_address,
- nDPIsrvd_options.distributor_un_sockpath);
+ get_cmdarg(&nDPIsrvd_options.distributor_in_address),
+ get_cmdarg(&nDPIsrvd_options.distributor_un_sockpath));
return 1;
}
}
@@ -1536,27 +1549,27 @@ int main(int argc, char ** argv)
return 1;
}
- if (access(nDPIsrvd_options.collector_un_sockpath, F_OK) == 0)
+ if (access(get_cmdarg(&nDPIsrvd_options.collector_un_sockpath), F_OK) == 0)
{
logger_early(1,
"UNIX socket `%s' exists; nDPIsrvd already running? "
"Please remove the socket manually or change socket path.",
- nDPIsrvd_options.collector_un_sockpath);
+ get_cmdarg(&nDPIsrvd_options.collector_un_sockpath));
return 1;
}
- if (access(nDPIsrvd_options.distributor_un_sockpath, F_OK) == 0)
+ if (access(get_cmdarg(&nDPIsrvd_options.distributor_un_sockpath), F_OK) == 0)
{
logger_early(1,
"UNIX socket `%s' exists; nDPIsrvd already running? "
"Please remove the socket manually or change socket path.",
- nDPIsrvd_options.distributor_un_sockpath);
+ get_cmdarg(&nDPIsrvd_options.distributor_un_sockpath));
return 1;
}
log_app_info();
- if (daemonize_with_pidfile(nDPIsrvd_options.pidfile) != 0)
+ if (daemonize_with_pidfile(get_cmdarg(&nDPIsrvd_options.pidfile)) != 0)
{
goto error;
}
@@ -1573,7 +1586,7 @@ int main(int argc, char ** argv)
case 1:
goto error;
case 2:
- unlink(nDPIsrvd_options.collector_un_sockpath);
+ unlink(get_cmdarg(&nDPIsrvd_options.collector_un_sockpath));
goto error;
case 3:
goto error_unlink_sockets;
@@ -1581,8 +1594,8 @@ int main(int argc, char ** argv)
goto error;
}
- logger(0, "collector UNIX socket listen on `%s'", nDPIsrvd_options.collector_un_sockpath);
- logger(0, "distributor UNIX listen on `%s'", nDPIsrvd_options.distributor_un_sockpath);
+ logger(0, "collector UNIX socket listen on `%s'", get_cmdarg(&nDPIsrvd_options.collector_un_sockpath));
+ logger(0, "distributor UNIX listen on `%s'", get_cmdarg(&nDPIsrvd_options.distributor_un_sockpath));
switch (distributor_in_address.raw.sa_family)
{
default:
@@ -1599,28 +1612,27 @@ int main(int argc, char ** argv)
}
errno = 0;
- if (nDPIsrvd_options.user != NULL &&
- change_user_group(nDPIsrvd_options.user,
- nDPIsrvd_options.group,
- nDPIsrvd_options.pidfile,
- nDPIsrvd_options.collector_un_sockpath,
- nDPIsrvd_options.distributor_un_sockpath) != 0 &&
+ if (change_user_group(get_cmdarg(&nDPIsrvd_options.user),
+ get_cmdarg(&nDPIsrvd_options.group),
+ get_cmdarg(&nDPIsrvd_options.pidfile),
+ get_cmdarg(&nDPIsrvd_options.collector_un_sockpath),
+ get_cmdarg(&nDPIsrvd_options.distributor_un_sockpath)) != 0 &&
errno != EPERM)
{
if (errno != 0)
{
logger(1,
"Change user/group to %s/%s failed: %s",
- nDPIsrvd_options.user,
- (nDPIsrvd_options.group != NULL ? nDPIsrvd_options.group : "-"),
+ get_cmdarg(&nDPIsrvd_options.user),
+ (is_cmdarg_set(&nDPIsrvd_options.group) != 0 ? get_cmdarg(&nDPIsrvd_options.group) : "-"),
strerror(errno));
}
else
{
logger(1,
"Change user/group to %s/%s failed.",
- nDPIsrvd_options.user,
- (nDPIsrvd_options.group != NULL ? nDPIsrvd_options.group : "-"));
+ get_cmdarg(&nDPIsrvd_options.user),
+ (is_cmdarg_set(&nDPIsrvd_options.group) != 0 ? get_cmdarg(&nDPIsrvd_options.group) : "-"));
}
goto error_unlink_sockets;
}
@@ -1640,14 +1652,14 @@ int main(int argc, char ** argv)
close_event_queue(epollfd);
error_unlink_sockets:
- unlink(nDPIsrvd_options.collector_un_sockpath);
- unlink(nDPIsrvd_options.distributor_un_sockpath);
+ unlink(get_cmdarg(&nDPIsrvd_options.collector_un_sockpath));
+ unlink(get_cmdarg(&nDPIsrvd_options.distributor_un_sockpath));
error:
close(collector_un_sockfd);
close(distributor_un_sockfd);
close(distributor_in_sockfd);
- daemonize_shutdown(nDPIsrvd_options.pidfile);
+ daemonize_shutdown(get_cmdarg(&nDPIsrvd_options.pidfile));
logger(0, "Bye.");
shutdown_logging();
diff --git a/utils.c b/utils.c
index 7f6665d1a..fbdc2b79e 100644
--- a/utils.c
+++ b/utils.c
@@ -6,6 +6,7 @@
#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#ifndef NO_MAIN
#include <syslog.h>
@@ -21,6 +22,42 @@ static int daemonize = 0;
static int log_to_console = 0;
static int log_to_file_fd = -1;
+void set_cmdarg(struct cmdarg * const ca, char const * const val)
+{
+ if (ca == NULL || val == NULL)
+ {
+ return;
+ }
+
+ free(ca->value);
+ ca->value = strdup(val);
+}
+
+char const * get_cmdarg(struct cmdarg const * const ca)
+{
+ if (ca == NULL)
+ {
+ return NULL;
+ }
+
+ if (ca->value != NULL)
+ {
+ return ca->value;
+ }
+
+ return ca->default_value;
+}
+
+int is_cmdarg_set(struct cmdarg const * const ca)
+{
+ if (ca == NULL)
+ {
+ return 0;
+ }
+
+ return ca->value != NULL;
+}
+
void daemonize_enable(void)
{
daemonize = 1;
@@ -182,8 +219,7 @@ int change_user_group(char const * const user,
if (uds_collector_path != NULL)
{
errno = 0;
- if (chmod(uds_collector_path, S_IRUSR | S_IWUSR) != 0 ||
- chown(uds_collector_path, pwd->pw_uid, gid) != 0)
+ if (chmod(uds_collector_path, S_IRUSR | S_IWUSR) != 0 || chown(uds_collector_path, pwd->pw_uid, gid) != 0)
{
return -errno;
}
diff --git a/utils.h b/utils.h
index 2db510067..fb170fbb5 100644
--- a/utils.h
+++ b/utils.h
@@ -3,6 +3,23 @@
#include <stdarg.h>
+#define CMDARG(_default_value) \
+ { \
+ .value = NULL, .default_value = (_default_value) \
+ }
+
+struct cmdarg
+{
+ char * value;
+ char const * const default_value;
+};
+
+void set_cmdarg(struct cmdarg * const ca, char const * const val);
+
+char const * get_cmdarg(struct cmdarg const * const ca);
+
+int is_cmdarg_set(struct cmdarg const * const ca);
+
int is_path_absolute(char const * const prefix, char const * const path);
void daemonize_enable(void);