Skip to content

Commit 3c1f7ac

Browse files
committed
Add generic functions for library configuration
This is a new way to provide (more) configuration options in nDPI. The idea is to have a simple way to configure (most of) nDPI: only one function (`ndpi_set_config()`) to set any configuration parameters (in the present or on in the future) and this function prototype is as agnostic as possible. This way, anytime we need to add a new configuration parameter: * we don't need to add two public functions (a getter and a setter) * we don't break API/ABI compatibility of the library; even changing the parameter type (from integer to a list of integer, for example) doesn't break the compatibility. Two examples of how to extend the configuration are provided: * the ability to enable/disable the extraction of the sha1 fingerprint of the TLS certificates. * the upper limit on the number of packets per flow that will be subject to inspection
1 parent c34bded commit 3c1f7ac

File tree

14 files changed

+411
-50
lines changed

14 files changed

+411
-50
lines changed

doc/configuration_parameters.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
# Configuration knobs
3+
4+
TODO
5+
6+
| Protocol | Parameter | Default value | Min value | Max value | Description |
7+
| ------ | ------ | ------ | ------ | ------ | ------ |
8+
| NULL | "packets_limit_per_flow" | 32 | 0 | 255 | The upper limit on the number of packets per flow that will be subject to DPI, after which classification will be considered complete (0 = no limit)|
9+
| "tls" | "metadata.sha1_fingerprint.enable" | 1 | NULL | NULL | Enable/disable computation and export of SHA1 fingerprint for TLS flows. Note that if it is disable, the flow risk `NDPI_MALICIOUS_SHA1_CERTIFICATE` is not checked |

example/ndpiReader.c

Lines changed: 89 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ u_int8_t enable_protocol_guess = 1, enable_payload_analyzer = 0, num_bin_cluster
9696
u_int8_t verbose = 0, enable_flow_stats = 0;
9797
int stun_monitoring_pkts_to_process = -1; /* Default */
9898
int stun_monitoring_flags = -1; /* Default */
99+
100+
struct cfg {
101+
char *proto;
102+
char *param;
103+
char *value;
104+
};
105+
#define MAX_NUM_CFGS 16
106+
static struct cfg cfgs[MAX_NUM_CFGS];
107+
static int num_cfgs = 0;
108+
99109
int nDPI_LogLevel = 0;
100110
char *_debug_protocols = NULL;
101111
char *_disabled_protocols = NULL;
@@ -594,11 +604,20 @@ static void help(u_int long_help) {
594604
" --lru-cache-ttl=NAME:size | Specify the TTL [in seconds] for this LRU cache (0 to disable it). This flag can be used multiple times\n"
595605
" --stun-monitoring=<pkts>:<flags> | Configure STUN monitoring: keep monitoring STUN session for <pkts> more pkts looking for RTP\n"
596606
" | (0:0 to disable the feature); set the specified features in <flags>\n"
607+
" --cfg=proto,param,value | Configure the specific attribute of this protocol\n"
597608
,
598609
human_readeable_string_len,
599610
min_pattern_len, max_pattern_len, max_num_packets_per_flow, max_packet_payload_dissection,
600611
max_num_reported_top_payloads, max_num_tcp_dissected_pkts, max_num_udp_dissected_pkts);
601612

613+
NDPI_PROTOCOL_BITMASK all;
614+
ndpi_info_mod = ndpi_init_detection_module(init_prefs);
615+
NDPI_BITMASK_SET_ALL(all);
616+
ndpi_set_protocol_detection_bitmask2(ndpi_info_mod, &all);
617+
618+
printf("\nProtocols configuration parameters:\n");
619+
ndpi_dump_config(ndpi_info_mod, stdout);
620+
602621
printf("\nLRU Cache names: ookla, bittorrent, zoom, stun, tls_cert, mining, msteams, stun_zoom\n");
603622

604623
#ifndef WIN32
@@ -621,24 +640,18 @@ static void help(u_int long_help) {
621640
ndpi_detection_get_sizeof_ndpi_flow_struct(),
622641
sizeof(((struct ndpi_flow_struct *)0)->protos));
623642

624-
NDPI_PROTOCOL_BITMASK all;
625-
626-
ndpi_info_mod = ndpi_init_detection_module(init_prefs);
627643
printf("\n\nnDPI supported protocols:\n");
628644
printf("%3s %-22s %-10s %-8s %-12s %s\n",
629645
"Id", "Protocol", "Layer_4", "Nw_Proto", "Breed", "Category");
630646
num_threads = 1;
631647

632-
NDPI_BITMASK_SET_ALL(all);
633-
ndpi_set_protocol_detection_bitmask2(ndpi_info_mod, &all);
634-
635648
ndpi_dump_protocols(ndpi_info_mod, stdout);
636649

637650
printf("\n\nnDPI supported risks:\n");
638651
ndpi_dump_risks_score(stdout);
639-
640-
ndpi_exit_detection_module(ndpi_info_mod);
641652
}
653+
654+
ndpi_exit_detection_module(ndpi_info_mod);
642655

643656
exit(!long_help);
644657
}
@@ -649,6 +662,8 @@ static void help(u_int long_help) {
649662

650663
#define OPTLONG_VALUE_STUN_MONITORING 2000
651664

665+
#define OPTLONG_VALUE_CFG 3000
666+
652667
static struct option longopts[] = {
653668
/* mandatory extcap options */
654669
{ "extcap-interfaces", no_argument, NULL, '0'},
@@ -694,6 +709,8 @@ static struct option longopts[] = {
694709
{ "lru-cache-ttl", required_argument, NULL, OPTLONG_VALUE_LRU_CACHE_TTL},
695710
{ "stun-monitoring", required_argument, NULL, OPTLONG_VALUE_STUN_MONITORING},
696711

712+
{ "cfg", required_argument, NULL, OPTLONG_VALUE_CFG},
713+
697714
{0, 0, 0, 0}
698715
};
699716

@@ -950,6 +967,42 @@ static int parse_two_unsigned_integer(char *param, u_int32_t *num1, u_int32_t *n
950967
return -1;
951968
}
952969

970+
static int parse_three_strings(char *param, char **s1, char **s2, char **s3)
971+
{
972+
char *saveptr, *tmp_str, *s1_str, *s2_str = NULL, *s3_str;
973+
974+
tmp_str = ndpi_strdup(param);
975+
if(tmp_str) {
976+
if(param[0] == ',') { /* First parameter might be missing */
977+
s1_str = NULL;
978+
s2_str = strtok_r(tmp_str, ",", &saveptr);
979+
} else {
980+
s1_str = strtok_r(tmp_str, ",", &saveptr);
981+
if(s1_str) {
982+
s2_str = strtok_r(NULL, ",", &saveptr);
983+
}
984+
}
985+
if(s2_str) {
986+
s3_str = strtok_r(NULL, ",", &saveptr);
987+
if(s3_str) {
988+
*s1 = ndpi_strdup(s1_str);
989+
*s2 = ndpi_strdup(s2_str);
990+
*s3 = ndpi_strdup(s3_str);
991+
ndpi_free(tmp_str);
992+
if(!s1 || !s2 || !s3) {
993+
ndpi_free(s1);
994+
ndpi_free(s2);
995+
ndpi_free(s3);
996+
return -1;
997+
}
998+
return 0;
999+
}
1000+
}
1001+
}
1002+
ndpi_free(tmp_str);
1003+
return -1;
1004+
}
1005+
9531006
/* ********************************** */
9541007

9551008
/**
@@ -968,6 +1021,7 @@ static void parseOptions(int argc, char **argv) {
9681021
#endif
9691022
int cache_idx, cache_size, cache_ttl;
9701023
u_int32_t num_pkts, flags;
1024+
char *s1, *s2, *s3;
9711025

9721026
#ifdef USE_DPDK
9731027
{
@@ -1316,6 +1370,18 @@ static void parseOptions(int argc, char **argv) {
13161370
stun_monitoring_flags = flags;
13171371
break;
13181372

1373+
case OPTLONG_VALUE_CFG:
1374+
if(num_cfgs >= MAX_NUM_CFGS ||
1375+
parse_three_strings(optarg, &s1, &s2, &s3) == -1) {
1376+
printf("Invalid parameter [%s] [num:%d/%d]\n", optarg, num_cfgs, MAX_NUM_CFGS);
1377+
exit(1);
1378+
}
1379+
cfgs[num_cfgs].proto = s1;
1380+
cfgs[num_cfgs].param = s2;
1381+
cfgs[num_cfgs].value = s3;
1382+
num_cfgs++;
1383+
break;
1384+
13191385
default:
13201386
#ifdef DEBUG_TRACE
13211387
if(trace) fprintf(trace, " #### Unknown option -%c: skipping it #### \n", opt);
@@ -2669,7 +2735,7 @@ static void debug_printf(u_int32_t protocol, void *id_struct,
26692735
static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) {
26702736
NDPI_PROTOCOL_BITMASK enabled_bitmask;
26712737
struct ndpi_workflow_prefs prefs;
2672-
int i;
2738+
int i, rc;
26732739

26742740
memset(&prefs, 0, sizeof(prefs));
26752741
prefs.decode_tunnels = decode_tunnels;
@@ -2757,6 +2823,14 @@ static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) {
27572823
ndpi_set_protocol_aggressiveness(ndpi_thread_info[thread_id].workflow->ndpi_struct, i, aggressiveness[i]);
27582824
}
27592825

2826+
for(i = 0; i < num_cfgs; i++) {
2827+
rc = ndpi_set_config(ndpi_thread_info[thread_id].workflow->ndpi_struct,
2828+
cfgs[i].proto, cfgs[i].param, cfgs[i].value);
2829+
if (rc != 0)
2830+
fprintf(stderr, "Error setting config [%s][%s][%s]: %d\n",
2831+
cfgs[i].proto, cfgs[i].param, cfgs[i].value, rc);
2832+
}
2833+
27602834
if(stun_monitoring_pkts_to_process != -1 &&
27612835
stun_monitoring_flags != -1)
27622836
ndpi_set_monitoring_state(ndpi_thread_info[thread_id].workflow->ndpi_struct, NDPI_PROTOCOL_STUN,
@@ -5684,6 +5758,12 @@ int main(int argc, char **argv) {
56845758
ndpi_free(_debug_protocols);
56855759
ndpi_free(_disabled_protocols);
56865760

5761+
for(i = 0; i < num_cfgs; i++) {
5762+
ndpi_free(cfgs[i].proto);
5763+
ndpi_free(cfgs[i].param);
5764+
ndpi_free(cfgs[i].value);
5765+
}
5766+
56875767
#ifdef DEBUG_TRACE
56885768
if(trace) fclose(trace);
56895769
#endif

src/include/ndpi_api.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,6 +2154,15 @@ extern "C" {
21542154

21552155
/* ******************************* */
21562156

2157+
int ndpi_set_config(struct ndpi_detection_module_struct *ndpi_str,
2158+
const char *proto, const char *param, const char *value);
2159+
char *ndpi_get_config(struct ndpi_detection_module_struct *ndpi_str,
2160+
const char *proto, const char *param, char *buf, int buf_len);
2161+
char *ndpi_dump_config(struct ndpi_detection_module_struct *ndpi_str,
2162+
FILE *fd);
2163+
2164+
/* ******************************* */
2165+
21572166
/* Can't call libc functions from kernel space, define some stub instead */
21582167

21592168
#define ndpi_isalpha(ch) (((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z'))

src/include/ndpi_define.h.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@
153153

154154
/* misc definitions */
155155
#define NDPI_DEFAULT_MAX_TCP_RETRANSMISSION_WINDOW_SIZE 0x10000
156-
#define NDPI_DEFAULT_MAX_NUM_PKTS_PER_FLOW_TO_DISSECT 32
157156

158157
/* TODO: rebuild all memory areas to have a more aligned memory block here */
159158

src/include/ndpi_typedefs.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,6 @@ typedef enum {
10681068

10691069
typedef enum {
10701070
ndpi_pref_direction_detect_disable = 0,
1071-
ndpi_pref_max_packets_to_process,
10721071
ndpi_pref_enable_tls_block_dissection, /* nDPI considers only those blocks past the certificate exchange */
10731072
} ndpi_detection_preference;
10741073

@@ -1154,6 +1153,14 @@ struct ndpi_risk_information {
11541153
char *info;
11551154
};
11561155

1156+
struct ndpi_detection_module_config_struct {
1157+
int max_packets_to_process;
1158+
1159+
/* TLS */
1160+
int sha1_fingerprint_enabled;
1161+
1162+
};
1163+
11571164
struct ndpi_flow_struct {
11581165
u_int16_t detected_protocol_stack[NDPI_PROTOCOL_SIZE];
11591166

0 commit comments

Comments
 (0)