ntopng/src/Prefs.cpp
2026-06-29 17:57:12 +02:00

3847 lines
125 KiB
C++

/*
*
* (C) 2013-26 - ntop.org
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "ntop_includes.h"
#include <algorithm> /* For trimming strings (Prefs::parseLocalNetworks) */
#ifndef FORCE_VALID_LICENSE
#ifdef NTOPNG_PRO
extern "C" {
#ifdef WIN32
#include "license.h"
#else
#include "../../license/license.h"
#endif
}
#endif
#endif
/* ******************************************* */
Prefs::Prefs(Ntop* _ntop) {
if (trace_new_delete && (ntop->getTrace() != NULL))
ntop->getTrace()->traceEvent(TRACE_NORMAL, "[new] %s", __FILE__);
num_deferred_interfaces_to_register = 0, cli = NULL;
ntop = _ntop, pcap_file_purge_hosts_flows = false, ignore_vlans = false,
simulate_vlans = false, simulate_macs = false, ignore_macs = false;
housekeeping_frequency = HOUSEKEEPING_FREQUENCY;
insecure_tls = false, clickhouse_client = clickhouse_cluster_name = NULL;
local_networks = strdup(CONST_DEFAULT_HOME_NET "," CONST_DEFAULT_LOCAL_NETS);
num_simulated_ips = 0, enable_behaviour_analysis = false;
custom_if_mtu = 0;
local_networks_set = false, shutdown_when_done = false;
enable_users_login = true, disable_localhost_login = false;
enable_dns_resolution = sniff_dns_responses = sniff_name_responses =
sniff_local_name_responses = true,
limited_resources_mode = false;
use_promiscuous_mode = true, do_reforge_timestamps = false;
resolve_all_host_ip = false, service_license_check = false;
add_vlan_tags_to_cloud_exporters = false, disable_purge = false,
strict_startup = false;
max_num_hosts = MAX_NUM_INTERFACE_HOSTS,
max_num_flows = MAX_NUM_INTERFACE_HOSTS;
attacker_max_num_flows_per_sec = victim_max_num_flows_per_sec =
CONST_MAX_NEW_FLOWS_SECOND;
attacker_max_num_syn_per_sec = victim_max_num_syn_per_sec =
CONST_MAX_NUM_SYN_PER_SECOND;
ewma_alpha_percent = CONST_DEFAULT_EWMA_ALPHA_PERCENT;
data_dir = strdup(CONST_DEFAULT_DATA_DIR);
emit_flow_alerts = emit_host_alerts = true;
fail_on_invalid_license = false;
zmq_publish_events_url = NULL;
custom_geoip_dir = NULL;
influx_internal_db_name = strdup(CONST_DEFAULT_INFLUXDB_INTERNAL_DB_NAME);
influx_internal_available = true;
enable_access_log = false, enable_assets_log = false, enable_sql_log = false;
enable_flow_device_port_rrd_creation =
enable_observation_points_rrd_creation =
enable_intranet_traffic_rrd_creation = false;
http_log_path = NULL;
reproduce_at_original_speed = false;
enable_top_talkers = enable_sites_collection = enable_dns_cache = false;
enable_active_local_hosts_cache = false, enable_tiny_flows_export = true,
enable_captive_portal = false, mac_based_captive_portal = false,
enable_arp_matrix_generation = false,
enable_informative_captive_portal = false,
enable_external_auth_captive_portal = false, full_stats_enabled = true,
override_dst_with_post_nat_dst = false,
override_src_with_post_nat_src = false, message_broker_enabled = false;
hostMask = no_host_mask, collect_blacklist_stats = false;
enable_asn_behaviour_analysis = enable_network_behaviour_analysis =
enable_iface_l7_behaviour_analysis = false;
enable_broadcast_domain_too_large = false;
enable_mac_ndpi_stats = false;
auto_assigned_pool_id = NO_HOST_POOL_ID;
default_l7policy = PASS_ALL_SHAPER_ID;
#ifndef HAVE_NEDGE
use_mac_in_flow_key = false;
#endif
use_host_pools_for_local = false;
fingerprint_stats = false;
ciphers_list = NULL;
device_protocol_policies_enabled = false, enable_vlan_trunk_bridge = false;
max_extracted_pcap_bytes = CONST_DEFAULT_MAX_EXTR_PCAP_BYTES;
max_extracted_pcap_files = CONST_DEFAULT_MAX_EXTR_PCAP_FILES;
behaviour_analysis_learning_period =
CONST_DEFAULT_BEHAVIOUR_ANALYSIS_LEARNING_PERIOD;
mac_address_cache_duration = MAX_MAC_IDLE;
enable_flow_swap_heuristic = true; /* Enabled by default */
skip_dpi_for_collected_flows = false; /* Disabled by default */
behaviour_analysis_learning_status_during_learning = service_allowed;
behaviour_analysis_learning_status_post_learning = service_allowed;
iec60870_learning_period = CONST_IEC104_LEARNING_TIME;
modbus_learning_period = CONST_MODBUS_LEARNING_TIME;
s7comm_learning_period = CONST_S7COMM_LEARNING_TIME;
devices_learning_period = CONST_DEVICES_LEARNING_TIME;
host_port_learning_period = CONST_HOST_PORT_LEARNING_TIME;
auth_session_duration = HTTP_SESSION_DURATION;
auth_session_midnight_expiration = HTTP_SESSION_MIDNIGHT_EXPIRATION;
install_dir = NULL, captureDirection = PCAP_D_INOUT;
docs_dir = strdup(CONST_DEFAULT_DOCS_DIR);
scripts_dir = strdup(CONST_DEFAULT_SCRIPTS_DIR);
callbacks_dir = strdup(CONST_DEFAULT_CALLBACKS_DIR);
#ifdef NTOPNG_PRO
asset_inventory_enabled = CONST_DEFAULT_ASSET_INVENTORY_ENABLED;
snmp_trap_enabled = CONST_DEFAULT_SNMP_TRAP_ENABLED;
pro_callbacks_dir = strdup(CONST_DEFAULT_PRO_CALLBACKS_DIR);
lic_mgr_config_file = NULL;
#endif
pcap_dir = NULL;
clickhouse_archive_dir = NULL;
test_pre_script_path = test_post_script_path = test_runtime_script_path =
NULL;
message_broker_url = NULL;
message_broker = NULL;
config_file_path = ndpi_proto_path = NULL;
http_port = 0; // CONST_DEFAULT_NTOP_PORT
http_prefix = strdup("");
http_index_page = strdup(INDEX_URL);
asn_mode_enabled = false;
instance_name = NULL;
categorization_enabled = false, enable_users_login = true;
categorization_key = NULL, zmq_encryption_pwd = NULL;
enable_zmq_encryption = false, zmq_encryption_priv_key = NULL;
export_zmq_encryption_key = NULL;
es_index = es_url = es_user = es_pwd = es_host = NULL;
https_port = 0; // CONST_DEFAULT_NTOP_PORT+1;
change_user = true;
user = strdup(CONST_DEFAULT_NTOP_USER);
user_set = false;
http_binding_address1 = NULL;
http_binding_address2 = NULL;
https_binding_address1 = NULL; // CONST_ANY_ADDRESS;
https_binding_address2 = NULL;
enable_client_x509_auth = false;
timeseries_driver = ts_driver_rrd;
split_ts_direction = false;
cpu_affinity = other_cpu_affinity = NULL;
flow_table_time = flow_table_probe_order = false;
#ifdef HAVE_LIBCAP
CPU_ZERO(&other_cpu_affinity_mask);
#endif
#ifdef HAVE_PF_RING
pfring_cluster_id = -1;
#endif
redis_host = strdup("127.0.0.1");
redis_password = NULL;
redis_tls_ca_cert = NULL;
redis_tls_cert = NULL;
redis_tls_key = NULL;
redis_tls_skip_verify = false;
redis_port = 6379;
redis_db_id = 0;
dns_mode = 0;
pid_path = strdup(DEFAULT_PID_PATH);
packet_filter = NULL;
num_interfaces = 0, enable_auto_logout = true,
enable_auto_logout_at_runtime = true;
enable_interface_name_only = false, dump_flows_on_clickhouse = false;
dump_flows_on_es = dump_flows_on_syslog = false;
dump_json_flows_on_disk = dump_ext_json = false;
routing_mode_enabled = false;
global_dns_forging_enabled = false;
#ifdef NTOPNG_PRO
dump_queue_len = CLICKHOUSE_MAX_DUMP_BLOCKS;
dump_queue_block_size = CLICKHOUSE_MAX_DUMP_ROWS_PER_BLOCK;
dump_flows_direct = false;
max_aggregated_flows_upperbound = 10000,
max_aggregated_flows_traffic_upperbound = 1;
data_archive_before_ttl_delete = false;
#endif
enable_runtime_flows_dump = true;
readonly_flows_dump = false;
enable_activities_debug = false;
snmp_polling = true;
active_monitoring = network_discovery = starttls = false;
dump_pcap_to_clickhouse = false;
query_performance_log = false;
vs_max_num_scans = 4;
vs_slow_scan = false;
tls_quic_hostnaming = false;
#ifndef HAVE_NEDGE
appliance = false;
#endif
#if defined(HAVE_KAFKA) && defined(NTOPNG_PRO)
kafka_brokers_list = kafka_topic = kafka_options = NULL;
#endif
#ifdef NTOPNG_PRO
print_maintenance = print_license = false;
#endif
print_version = print_version_json = false;
if (!(ifNames = (InterfaceInfo*)calloc(UNLIMITED_NUM_INTERFACES,
sizeof(InterfaceInfo))) ||
!(deferred_interfaces_to_register =
(char**)calloc(UNLIMITED_NUM_INTERFACES, sizeof(char*))))
throw "Not enough memory";
json_labels_string_format = true;
#ifdef WIN32
daemonize = true;
#else
daemonize = false;
#endif
export_endpoint = NULL;
enable_ixia_timestamps = false;
es_type = strdup((char*)"flows"), es_index = strdup((char*)"ntopng-%Y.%m.%d"),
es_url = strdup((char*)"http://localhost:9200/_bulk"),
es_user = strdup((char*)""), es_pwd = strdup((char*)""),
es_host = strdup((char*)"");
clickhouse_host = clickhouse_dbname = clickhouse_user = clickhouse_pw = NULL;
clickhouse_ro_user = clickhouse_ro_pw = NULL;
#if defined(HAVE_CLICKHOUSE) && defined(NTOPNG_PRO)
clickhouse_cluster_user = NULL;
ntopng_assets_inventory_enabled = true;
#endif
clickhouse_tcp_port = CONST_DEFAULT_CLICKHOUSE_TCP_PORT;
clickhouse_tcp_port_secure = false; /* No TLS */
#if !defined(WIN32) && !defined(__APPLE__)
flows_syslog_facility = CONST_DEFAULT_DUMP_SYSLOG_FACILITY;
#endif
ls_host = NULL;
ls_port = NULL;
ls_proto = NULL;
has_cmdl_trace_lvl = false;
gateway = new (std::nothrow) ServerConfiguration();
dns_servers = new (std::nothrow) ServerConfiguration();
ntp_servers = new (std::nothrow) ServerConfiguration();
dhcp_servers = new (std::nothrow) ServerConfiguration();
smtp_servers = new (std::nothrow) ServerConfiguration();
customer_asn = new (std::nothrow) ASNConfiguration();
sub_customer_asn = new (std::nothrow) ASNConfiguration();
remote_asn = new (std::nothrow) ASNConfiguration();
#ifdef NTOPNG_PRO
networks_policy_configuration = NULL;
networks_policy_configuration_shadow = NULL;
#endif
#ifdef HAVE_NEDGE
disable_dns_resolution();
disable_dns_responses_decoding();
#endif
/* All allowed */
iec104_allowed_typeids[0] = (u_int64_t)-1,
iec104_allowed_typeids[1] = (u_int64_t)-1;
#ifdef NTOPNG_PRO
modbus_allowed_function_codes = NULL; /* All allowed */
modbus_too_many_exceptions = 5;
s7comm_allowed_function_codes = NULL; /* All allowed */
s7comm_too_many_errors = 5;
profinet_too_many_errors = 5;
#endif
}
/* ******************************************* */
Prefs::~Prefs() {
if (ifNames) {
for (int i = 0; i < num_interfaces; i++) {
if (ifNames[i].name) free(ifNames[i].name);
if (ifNames[i].alias) free(ifNames[i].alias);
if (ifNames[i].description) free(ifNames[i].description);
}
free(ifNames);
ifNames = NULL;
}
if (deferred_interfaces_to_register) {
for (int i = 0; i < num_deferred_interfaces_to_register; i++) {
if (deferred_interfaces_to_register[i])
free(deferred_interfaces_to_register[i]);
}
free(deferred_interfaces_to_register);
deferred_interfaces_to_register = NULL;
}
if (influx_internal_db_name) free(influx_internal_db_name);
if (http_log_path) free(http_log_path);
if (zmq_publish_events_url) free(zmq_publish_events_url);
if (data_dir) free(data_dir);
if (install_dir) free(install_dir);
if (docs_dir) free(docs_dir);
if (scripts_dir) free(scripts_dir);
if (callbacks_dir) free(callbacks_dir);
#ifdef NTOPNG_PRO
if (pro_callbacks_dir) free(pro_callbacks_dir);
#endif
if (pcap_dir) free(pcap_dir);
if (clickhouse_archive_dir) free(clickhouse_archive_dir);
if (config_file_path) free(config_file_path);
if (user) free(user);
if (pid_path) free(pid_path);
if (packet_filter) free(packet_filter);
if (cpu_affinity) free(cpu_affinity);
if (other_cpu_affinity) free(other_cpu_affinity);
if (es_type) free(es_type);
if (es_index) free(es_index);
if (es_url) free(es_url);
if (es_user) free(es_user);
if (es_pwd) free(es_pwd);
if (es_host) free(es_host);
if (instance_name) free(instance_name);
if (http_index_page) free(http_index_page);
free(http_prefix);
free(local_networks);
free(redis_host);
if (redis_password) free(redis_password);
if (redis_tls_ca_cert) free(redis_tls_ca_cert);
if (redis_tls_cert) free(redis_tls_cert);
if (redis_tls_key) free(redis_tls_key);
if (cli) free(cli);
if (ciphers_list) free(ciphers_list);
if (clickhouse_host) free(clickhouse_host);
if (clickhouse_dbname) free(clickhouse_dbname);
if (clickhouse_user) free(clickhouse_user);
#if defined(HAVE_CLICKHOUSE) && defined(NTOPNG_PRO)
if (clickhouse_cluster_user) free(clickhouse_cluster_user);
#endif
if (clickhouse_pw) free(clickhouse_pw);
if (clickhouse_ro_user) free(clickhouse_ro_user);
if (clickhouse_ro_pw) free(clickhouse_ro_pw);
if (ls_host) free(ls_host);
if (ls_port) free(ls_port);
if (ls_proto) free(ls_proto);
if (http_binding_address1) free(http_binding_address1);
if (http_binding_address2) free(http_binding_address2);
if (https_binding_address1) free(https_binding_address1);
if (https_binding_address2) free(https_binding_address2);
if (ndpi_proto_path) free(ndpi_proto_path);
if (test_pre_script_path) free(test_pre_script_path);
if (test_runtime_script_path) free(test_runtime_script_path);
if (test_post_script_path) free(test_post_script_path);
if (message_broker_url) free(message_broker_url);
if (message_broker) free(message_broker);
#ifdef NTOPNG_PRO
if (modbus_allowed_function_codes)
ndpi_bitmap_free(modbus_allowed_function_codes);
if (s7comm_allowed_function_codes)
ndpi_bitmap_free(s7comm_allowed_function_codes);
#endif
if (gateway) delete gateway;
if (dns_servers) delete dns_servers;
if (ntp_servers) delete ntp_servers;
if (dhcp_servers) delete dhcp_servers;
if (smtp_servers) delete smtp_servers;
if (customer_asn) delete customer_asn;
if (sub_customer_asn) delete sub_customer_asn;
if (remote_asn) delete remote_asn;
#ifdef NTOPNG_PRO
if (networks_policy_configuration) delete networks_policy_configuration;
if (networks_policy_configuration_shadow)
delete networks_policy_configuration_shadow;
#endif
}
/* ******************************************* */
/* C-binding needed by Win32 service call */
void nDPIusage() {
struct ndpi_detection_module_struct* ndpi_struct =
ndpi_init_detection_module(NULL);
printf("\nnDPI detected protocols:\n");
ndpi_dump_protocols(ndpi_struct, stdout);
exit(0);
}
/* ******************************************* */
/* C-binding needed by Win32 service call */
void usage() {
printf(
"ntopng %s%s v.%s - " NTOP_COPYRIGHT
"\n\n"
"Usage:\n"
" ntopng <configuration file path>\n"
" or\n"
" ntopng <command line options> \n\n"
"Options:\n"
#ifndef HAVE_NEDGE
"[--dns-mode|-n] <mode> | DNS address resolution mode\n"
" | 0 - Decode DNS responses and "
"resolve\n"
" | local numeric IPs only "
"(default)\n"
" | 1 - Decode DNS responses and "
"resolve all\n"
" | numeric IPs\n"
" | 2 - Decode DNS responses but "
"don't\n"
" | resolve numeric IPs\n"
" | 3 - Don't decode "
"DNS/MDNS/HTTP/TLS responses\n"
" | and don't resolve numeric IPs "
"(all hosts)\n"
" | 4 - Don't decode "
"DNS/MDNS/HTTP/TLS responses\n"
" | and don't resolve numeric IPs "
"(localhost only)\n"
#endif
"[--interface|-i] <interface|pcap> | Input interface name "
"(numeric/symbolic),\n"
" | view or pcap file path, "
"including:\n"
" | zmq://<IP address> [ZMQ "
"flow collection]\n"
" | tcp://<IP address> "
"[Deprecated - use zmq://]\n"
#if defined(HAVE_KAFKA) && defined(NTOPNG_PRO)
" | kafka://<brokers list> [Kafka "
"flow collection]\n"
" | kafka-ssl://<brokers list> [Kafka "
"flow collection over SSL/TLS]\n"
#endif
#ifndef WIN32
"[--data-dir|-d] <path> | Data directory (must be "
"writable).\n"
" | Default: %s\n"
"[--install-dir|-t] <path> | Set the installation directory to "
"<dir>.\n"
" | Should be set when installing "
"ntopng \n"
" | under custom directories\n"
"[--daemon|-e] | Daemonize ntopng\n"
#endif
"[--httpdocs-dir|-1] <path> | HTTP documents root directory.\n"
" | Default: %s\n"
"[--scripts-dir|-2] <path> | Scripts directory.\n"
" | Default: %s\n"
"[--callbacks-dir|-3] <path> | Callbacks directory.\n"
" | Default: %s\n"
"[--pcap-dir|-5] <path> | Storage directory used for "
"continuous traffic\n"
" | recording in PCAP format.\n"
" | Default: %s\n"
"[--db-archive-dir|-6] <path> | Directory used for archiving "
"historical flows\n"
" | recorded on ClickHouse when data "
"retention is over.\n"
" | Default: %s\n"
"[--no-promisc|-u] | Don't set the interface in "
"promisc mode.\n"
"[--geoip-dir] <dir> | Load GeoIP databases from the "
"specified directory.\n"
"[--http-port|-w] <[addr:]port> | HTTP. Set to 0 to disable http "
"server.\n"
" | Addr can be an IPv4 "
"(192.168.1.1)\n"
" | or IPv6 ([3ffe:2a00:100:7031::1]) "
"addr.\n"
" | Surround IPv6 addr with square "
"brackets.\n"
" | Prepend a ':' without addr before "
"the\n"
" | listening port on the loopback "
"address.\n"
" | Default port: %u\n"
" | Examples:\n"
" | -w :3000\n"
" | -w 192.168.1.1:3001\n"
" | -w [3ffe:2a00:100:7031::1]:3002\n"
"[--https-port|-W] <[:]https port> | HTTPS. See also -w above. "
"Default: %u\n"
"[--http-log|-L] <path> | Log HTTP requests in the "
"specified file\n"
"[--local-networks|-m] <local list> | Local networks and local "
"autonomous systems list.\n"
" | <local list> is a comma-separated "
"list or a path to a file.\n"
" | Local networks in CIDR format "
"and\n"
" | autonomous system in asn<number> "
"format.\n"
" | The file accepts multiple lines "
"with networks\n"
" | and as with specified format.\n"
" | An optional '=<alias>' is "
"supported for local networks\n"
" | to specify an alias.\n"
" | Examples:\n"
" | -m "
"\"192.168.1.0/24,172.16.0.0/16\"\n"
" | -m "
"\"192.168.1.0/24=LAN_1,192.168.2.0/24=LAN_2,10.0.0.0/8\"\n"
" | -m "
"\"/path/to/local_networks_file\"\n"
"[--ppp-networks|-M] <local list> | Disable detection of broadcast IP "
"addresses\n"
" | for local networks "
"(point-to-point addresses).\n"
"[--ndpi-protocols|-p] <file>|<URL> | Specify a nDPI protocol file\n"
" | (e.g. protos.txt) or URL (e.g. "
"https://localhost/protos.txt)\n"
"[--redis|-r] <fmt> | Redis connection. <fmt> is specified as\n"
" | [h[:port[:pwd]]][@db-id] where db-id\n"
" | identifies the database Id (default 0).\n"
" | h is the host running Redis (default\n"
" | localhost), optionally followed by a\n"
" | ':'-separated port (default 6379).\n"
" | The special characters \\ and ` are not\n"
" | supported by ntopng.\n"
" | A password can be specified after\n"
" | the port when Redis auth is required.\n"
" | By default password auth is disabled.\n"
#ifdef __linux__
" | On unix <fmt> can also be the redis socket file path.\n"
" | Port is ignored for socket-based connections.\n"
#endif
" | Examples:\n"
" | -r @2\n"
" | -r 129.168.1.3\n"
" | -r 129.168.1.3:6379@3\n"
" | -r 129.168.1.3:6379:nt0pngPwD@0\n"
#ifdef __linux__
" | -r /var/run/redis/redis.sock\n"
" | -r /var/run/redis/redis.sock@2\n"
#endif
#ifdef HAVE_HIREDIS_SSL
"[--redis-tls-ca-cert] <path> | CA certificate file to verify the\n"
" | Redis server TLS certificate.\n"
"[--redis-tls-cert] <path> | Client certificate file for mutual\n"
" | TLS authentication with Redis.\n"
"[--redis-tls-key] <path> | Client private key file for mutual\n"
" | TLS authentication with Redis.\n"
"[--redis-tls-skip-verify] | Disable Redis server TLS certificate\n"
" | verification (insecure).\n"
#endif
#ifdef __linux__
"[--core-affinity|-g] <ids> | Bind the capture/processing "
"threads to\n"
" | specific CPU cores (specified as "
"a comma-\n"
" | separated list of core id)\n"
"[--other-core-affinity|-y] <ids> | Bind service threads to specific "
"CPU cores\n"
" | (specified as a comma-separated "
"list of core id)\n"
#endif
"[--user|-U] <sys user> | Run ntopng with the specified "
"user\n"
" | instead of %s\n"
"[--dont-change-user|-s] | Do not change user (debug only)\n"
"[--disable-purge] | Disable data purge (debug only)\n"
"[--ciphers-list] <list> | Specify the list of TLS ciphers "
"to be used\n"
" | when https is used. Default: "
"\"%s\"\n"
"[--shutdown-when-done] | Terminate after reading the pcap "
"(debug only)\n"
"[--offline] | Run in offline mode (avoid "
"contacting remote sites, including blacklists) \n"
"[--strict-startup] | Exit on startup if critical "
"subsystems "
"(e.g. ClickHouse) fail to initialize\n"
"[--insecure] | Allow connections to TLS sites "
"with invalid certificates \n"
#if HAVE_ZMQ
"[--zmq-encryption] | Enable ZMQ encryption\n"
"[--zmq-encryption-key-priv <key>] | ZMQ (collection) encryption "
"secret key (debug only) \n"
"[--zmq-publish-events <URL>] | Endpoint for publishing events "
#endif
"(e.g. IPS)\n"
"[--disable-autologout|-q] | Disable web logout for "
"inactivity\n"
"[--disable-login|-l] <mode> | Disable user login "
"authentication:\n"
" | 0 - Disable login only for "
"localhost\n"
" | 1 - Disable login for all hosts\n"
"[--max-num-flows|-X] <num> | Max number of active flows\n"
" | (default: %u)\n"
"[--max-num-hosts|-x] <num> | Max number of active hosts\n"
" | (default: %u)\n"
"[--pcap-reforge-timestamps|-z] | Reforge timestamps when reading "
"from file\n"
"[--users-file] <path> | Users configuration file path\n"
" | Default: %s\n"
"[--original-speed] | Reproduce (-i) the pcap file at "
"original speed\n",
#ifdef HAVE_NEDGE
"edge "
#else
""
#endif
,
PACKAGE_MACHINE, PACKAGE_VERSION,
#ifndef WIN32
ntop->get_working_dir(),
#endif
CONST_DEFAULT_DOCS_DIR, CONST_DEFAULT_SCRIPTS_DIR,
CONST_DEFAULT_CALLBACKS_DIR, CONST_DEFAULT_DATA_DIR,
CONST_DEFAULT_DATA_DIR, CONST_DEFAULT_NTOP_PORT,
CONST_DEFAULT_NTOP_PORT + 1, CONST_DEFAULT_NTOP_USER,
CONST_DEFAULT_TLS_CIPHERS, MAX_NUM_INTERFACE_HOSTS,
MAX_NUM_INTERFACE_HOSTS, CONST_DEFAULT_USERS_FILE);
printf(
#ifndef WIN32
"[--pid|-G] <path> | Pid file path\n"
#endif
"[--packet-filter|-B] <filter> | Ingress packet filter (BPF "
"filter)\n"
"[--dump-flows|-F] <mode> | Dump expired flows. Mode:\n"
" |\n"
#ifndef HAVE_NEDGE
" | es Dump in "
"ElasticSearch database\n"
" | Format:\n"
" | es;<mapping type>;<idx "
"name>;<es URL>;<username>:<password>\n"
" | Example:\n"
" | "
"es;ntopng;ntopng-%%Y.%%m.%%d;http://localhost:9200/_bulk;user:pwd\n"
" | Notes:\n"
" | The <idx name> accepts the "
"strftime() format.\n"
" | <mapping type> must be set to "
"ntopng and it is\n"
" | used until ElasticSearch "
"version 6 and ignored in newer versions.\n"
" |\n"
#endif
#ifndef HAVE_NEDGE
#if !defined(WIN32) && !defined(__APPLE__)
" | syslog Dump in syslog\n"
" | Format:\n"
" | syslog[;<facility-text>]\n"
" | Example:\n"
" | syslog\n"
" | syslog;local3\n"
" | Notes:\n"
" | <facility-text> is "
"case-insensitive.\n"
" |\n"
#endif
#endif
);
#if defined(HAVE_CLICKHOUSE) && defined(NTOPNG_PRO)
printf(
" | clickhouse Dump in ClickHouse "
"(Enterprise M and better)\n"
" | Format:\n"
" | clickhouse[;<host[@<tcp-port>,<mysql-port>]|socket>;<dbname>;<user>;<pw>[;<ro-user>[;<ro-pw>]]]\n"
" | Example:\n"
" | clickhouse;127.0.0.1;ntopng;default;xxx;ntop_ro;xxx\n"
" | You can also use just '-F clickhouse' as alias of:\n"
" | -F \"clickhouse;127.0.0.1@%u,%u;ntopng;default;\"\n"
" |\n"
" | NOTE:\n"
" | - tcp-port used by the clickhouse API\n"
" | - mysql-port used by the mysql API\n"
" | - ro-user, when configured, is created by ntopng (if not exist)\n"
" |\n"
#ifndef HAVE_NEDGE
" | clickhouse-cluster Dump in ClickHouse Cluster (Enterprise M/L/XL/XXL)\n"
" | Format:\n"
" | clickhouse-cluster;<host[@<tcp-port>,<mysql-port>]|socket>;<dbname>;<user>;<pw>;<cluster name>[;<ro-user>[;<ro-pw>]]\n"
" | Example:\n"
" | clickhouse-cluster;127.0.0.1;ntopng;default;ntop_cluster\n"
" | You can also use just -F clickhouse-cluster as alias of:\n"
" | -F \"clickhouse-cluster;127.0.0.1@%u,%u;ntopng;default;ntop_cluster\"\n"
" |\n"
#endif
" | clickhouse-cloud Dump in ClickHouse Cloud (Enterprise M/L/XL/XXL)\n"
" | Format:\n"
" | clickhouse-cloud;<host[@<tcp-port>,<mysql-port>]|socket>;<dbname>;<clickhouse-user>,<mysql-user>;<pw>;\n"
" | Example:\n"
" | clickhouse-cloud;europe-east15.clickhouse.cloud@9440s,3306;ntopng;default,mysql-user;mych-password\n"
" |\n"
" | NOTE:\n"
" | - clickhouse-user used by clickhouse-client\n"
" | - mysql-user used by the mysql API\n"
" |\n",
CONST_DEFAULT_CLICKHOUSE_TCP_PORT, CONST_DEFAULT_CLICKHOUSE_MYSQL_PORT
#ifndef HAVE_NEDGE
,
CONST_DEFAULT_CLICKHOUSE_TCP_PORT, CONST_DEFAULT_CLICKHOUSE_MYSQL_PORT
#endif
);
#endif
#ifndef HAVE_NEDGE
#if defined(HAVE_KAFKA) && defined(NTOPNG_PRO)
printf(
" |\n"
" | kafka Dump to Kafka (Enterprise "
"M/L/XL/XXL)\n"
" | Format:\n"
" | "
"kafka;[<brokerIP[:<port>]]+;<topic>[;<kafka option>=<value>]+\n"
" | \n"
" | Example:\n"
" | \"kafka;127.0.0.1;flows\"\n"
" | "
"\"kafka;127.0.0.1:7689,192.168.1.20,192.168.1.2:9092;flows;compression."
"codec=gzip,debug=all\"\n"
" | \n"
" | See at the bottom of this help "
"the list of (comma separated) supported kafka configuration options.\n"
" |\n");
#endif
#endif
#ifdef NTOPNG_PRO
printf(
"[--dump-queue-len] <len> | Set the in-memory ClickHouse dump "
"queue length (Default: %u)\n"
"[--dump-queue-block-size] <size> | Set the in-memory ClickHouse data "
"block size (Default: %u)\n"
"[--direct-flows-dump] | Dump collected flows directly "
"before any additional processing\n"
"[--readonly-flows-dump] | Keep ClickHouse connected for "
"reading but disable flow dump (writing)\n",
CLICKHOUSE_MAX_DUMP_BLOCKS, CLICKHOUSE_MAX_DUMP_ROWS_PER_BLOCK);
#endif
printf(
"[--export-flows|-I] <endpoint> | Export flows with the specified "
"endpoint\n"
" | See https://wp.me/p1LxdS-O5 for a "
"-I use case.\n"
#if HAVE_ZMQ
"[--zmq-encryption-key <key>] | ZMQ (export) encryption public "
"key (-I only) \n"
#endif
"[--hw-timestamp-mode] <mode> | Enable hw "
"timestamping/stripping.\n"
" | Supported TS modes:\n"
" | ixia - Timestamped pkts by "
"ixiacom.com\n"
" | hardware devices\n"
"[--capture-direction] <dir> | Specify packet capture direction\n"
" | 0=RX+TX (default), 1=RX only, "
"2=TX only\n"
#ifdef HAVE_PF_RING
"[--cluster-id] <cluster id> | Specify the PF_RING cluster ID on "
"which incoming packets will be bound.\n"
#endif
"[--http-prefix|-Z <prefix>] | HTTP prefix to be prepended to "
"URLs.\n"
" | Useful when using ntopng behind a "
"proxy.\n"
"[--instance-name|-N <name>] | Assign a name to this ntopng "
"instance.\n"
#ifdef NTOPNG_PRO
"[--fail-invalid-license] | Exit without a valid license.\n"
"[--check-license] | Check if the license is valid.\n"
"[--check-maintenance] | Check until maintenance is "
"included\n"
" | in the license.\n"
#endif
"[--version|-V] | Print version and license\n"
" | information, then quit\n"
#ifdef NTOPNG_PRO
"[--version-json] | Print version and license\n"
" | info in JSON format, then quit\n"
#endif
"[--verbose|-v] <level> | Verbose tracing [range 0 (min).. "
"6 (max)]\n"
" | 0 - Errors only\n"
" | 1 - Warning\n"
" | 2 - Normal (default value)\n"
" | 3 - Informative\n"
" | 4 - Future use\n"
" | 5 - Future use\n"
" | 6 - Debug\n"
"[--print-ndpi-protocols] | Print the nDPI protocols list\n"
#ifndef HAVE_NEDGE
"[--ignore-macs] | Ignore packets MAC addresses\n"
#endif
"[--ignore-vlans] | Ignore packets VLAN tags\n"
"[--pcap-file-purge-flows] | Enable flow purge with pcap files "
"(debug only)\n"
"[--simulate-vlans] | Simulate VLAN traffic (debug "
"only)\n"
"[--simulate-macs] | Simulate MACs in the traffic "
"(debug only)\n"
"[--simulate-ips] <num> | Simulate IPs by choosing clients "
"and servers among <num> random addresses\n"
"[--mtu] <mtu> | Force expected MTU for capture "
"interfaces\n"
" | Overrides the auto-detected MTU\n"
"[--limit-resources] | Non-essential features are "
"disabled\n"
" | in order to save memory and "
"threads\n"
"[--help|-h] | Help\n");
printf("\n");
/* Just create an instance of the system interface to print out the available
* interfaces */
NetworkInterface n(SYSTEM_INTERFACE_NAME);
n.printAvailableInterfaces(true, 0, NULL, 0);
#if defined(HAVE_KAFKA) && defined(NTOPNG_PRO)
printf("\n\nList of supported kafka configuration options:\n");
rd_kafka_conf_properties_show(stdout);
printf("\n");
#endif
exit(0);
}
/* ******************************************* */
void Prefs::setTraceLevelFromRedis() {
char* lvlStr;
if ((lvlStr = (char*)malloc(CONST_MAX_LEN_REDIS_VALUE)) == NULL)
;
if (!hasCmdlTraceLevel() &&
ntop->getRedis()->get((char*)CONST_RUNTIME_PREFS_LOGGING_LEVEL, lvlStr,
CONST_MAX_LEN_REDIS_VALUE) == 0) {
if (!strcmp(lvlStr, "trace")) {
ntop->getTrace()->set_trace_level(TRACE_LEVEL_TRACE);
} else if (!strcmp(lvlStr, "debug")) {
ntop->getTrace()->set_trace_level(TRACE_LEVEL_DEBUG);
} else if (!strcmp(lvlStr, "info")) {
ntop->getTrace()->set_trace_level(TRACE_LEVEL_INFO);
} else if (!strcmp(lvlStr, "normal")) {
ntop->getTrace()->set_trace_level(TRACE_LEVEL_NORMAL);
} else if (!strcmp(lvlStr, "warning")) {
ntop->getTrace()->set_trace_level(TRACE_LEVEL_WARNING);
} else if (!strcmp(lvlStr, "error")) {
ntop->getTrace()->set_trace_level(TRACE_LEVEL_ERROR);
}
}
free(lvlStr);
}
/* ******************************************* */
char* Prefs::get_if_name(int id) {
for (int i = 0; i < num_interfaces; i++) {
if (ifNames[i].id == id) return ifNames[i].name;
}
return NULL;
};
/* ******************************************* */
char* Prefs::get_if_descr(int id) {
for (int i = 0; i < num_interfaces; i++) {
if (ifNames[i].id == id) return ifNames[i].description;
}
return NULL;
};
/* ******************************************* */
char* Prefs::get_if_alias(int id) {
for (int i = 0; i < num_interfaces; i++) {
if (ifNames[i].id == id) return ifNames[i].alias;
}
return NULL;
};
/* ******************************************* */
void Prefs::getDefaultStringPrefsValue(const char* pref_key, char** buffer,
const char* default_value) {
char rsp[MAX_PATH];
if ((ntop->getRedis()->get((char*)pref_key, rsp, sizeof(rsp)) == 0) &&
(rsp[0] != '\0') && strcmp(rsp, "nil"))
*buffer = strdup(rsp);
else
*buffer = strdup(default_value);
}
/* ******************************************* */
bool Prefs::getDefaultBoolPrefsValue(const char* pref_key,
const bool default_value) {
char rsp[8];
if (ntop->getRedis()->get((char*)pref_key, rsp, sizeof(rsp)) == 0 &&
rsp[0] != '\0') {
return ((rsp[0] == '1' || rsp[0] == 't' /* true */) ? true : false);
} else {
snprintf(rsp, sizeof(rsp), "%c", default_value ? '1' : '0');
ntop->getRedis()->set((char*)pref_key, rsp);
return (default_value);
}
}
/* ******************************************* */
bool Prefs::do_active_monitoring() {
return get_active_monitoring_pref()
#ifndef WIN32
&& ntop->isPingInitialized()
#endif
;
};
/* ******************************************* */
int32_t Prefs::getDefaultPrefsValue(const char* pref_key,
int32_t default_value) {
char rsp[32];
if (ntop->getRedis()->get((char*)pref_key, rsp, sizeof(rsp)) == 0)
return (atoi(rsp));
else {
snprintf(rsp, sizeof(rsp), "%i", default_value);
ntop->getRedis()->set((char*)pref_key, rsp);
return (default_value);
}
}
/* ******************************************* */
static TsDriver str2TsDriver(const char* driver) {
if (!strcmp(driver, "influxdb"))
return (ts_driver_influxdb);
else if (!strcmp(driver, "clickhouse"))
return (ts_driver_clickhouse);
else
return (ts_driver_rrd);
}
/* ******************************************* */
void Prefs::reloadPrefsFromRedis() {
char* aux = NULL;
char* tmp = NULL;
// sets to the default value in redis if no key is found
#ifdef PREFS_RELOAD_DEBUG
ntop->getTrace()->traceEvent(TRACE_DEBUG,
"A preference has changed, reloading...");
#endif
enable_auto_logout_at_runtime = getDefaultPrefsValue(
CONST_RUNTIME_IS_AUTOLOGOUT_ENABLED, CONST_DEFAULT_IS_AUTOLOGOUT_ENABLED);
enable_interface_name_only =
getDefaultPrefsValue(CONST_RUNTIME_IS_INTERFACE_NAME_ONLY, false);
#ifdef NTOPNG_PRO
max_aggregated_flows_upperbound =
getDefaultPrefsValue(CONST_MAX_AGGREGATED_FLOWS_UPPERBOUND, 10000);
max_aggregated_flows_traffic_upperbound =
getDefaultPrefsValue(CONST_MAX_AGGREGATED_FLOWS_TRAFFIC_UPPERBOUND, 1);
#endif
// alert preferences
enable_access_log =
getDefaultBoolPrefsValue(CONST_PREFS_ENABLE_ACCESS_LOG, false);
enable_assets_log =
getDefaultBoolPrefsValue(CONST_PREFS_ENABLE_ASSETS_LOG, false);
enable_sql_log = getDefaultBoolPrefsValue(CONST_PREFS_ENABLE_SQL_LOG, false);
#ifndef HAVE_NEDGE
use_mac_in_flow_key =
getDefaultPrefsValue(CONST_PREFS_USE_MAC_IN_FLOW_KEY, false);
#endif
use_host_pools_for_local =
getDefaultBoolPrefsValue(CONST_PREFS_USE_HOST_POOLS_FOR_LOCAL, false);
fingerprint_stats =
getDefaultPrefsValue(CONST_PREFS_FINGERPRINT_STATS, false);
// vulnerability scan preferences
vs_max_num_scans = getDefaultPrefsValue(CONST_VS_MAX_NUM_SCANS, 4);
vs_slow_scan = getDefaultBoolPrefsValue(CONST_VS_SLOW_SCAN, false);
// auth session preferences
auth_session_duration = getDefaultPrefsValue(
CONST_AUTH_SESSION_DURATION_PREFS, HTTP_SESSION_DURATION),
auth_session_midnight_expiration = getDefaultBoolPrefsValue(
CONST_AUTH_SESSION_MIDNIGHT_EXP_PREFS, HTTP_SESSION_MIDNIGHT_EXPIRATION);
/* Runtime Preferences */
housekeeping_frequency = getDefaultPrefsValue(
CONST_RUNTIME_PREFS_HOUSEKEEPING_FREQ, HOUSEKEEPING_FREQUENCY),
local_host_cache_duration = getDefaultPrefsValue(
CONST_LOCAL_HOST_CACHE_DURATION_PREFS, LOCAL_HOSTS_CACHE_DURATION),
local_host_max_idle =
getDefaultPrefsValue(CONST_LOCAL_HOST_IDLE_PREFS, MAX_LOCAL_HOST_IDLE),
non_local_host_max_idle =
getDefaultPrefsValue(CONST_REMOTE_HOST_IDLE_PREFS, MAX_REMOTE_HOST_IDLE),
pkt_ifaces_flow_max_idle =
getDefaultPrefsValue(CONST_FLOW_MAX_IDLE_PREFS, MAX_FLOW_IDLE),
active_local_hosts_cache_interval =
getDefaultPrefsValue(CONST_RUNTIME_ACTIVE_LOCAL_HOSTS_CACHE_INTERVAL,
CONST_DEFAULT_ACTIVE_LOCAL_HOSTS_CACHE_INTERVAL),
mac_address_cache_duration = getDefaultPrefsValue(
CONST_RUNTIME_MAC_ADDRESS_CACHE_DURATION, MAX_MAC_IDLE),
enable_flow_swap_heuristic =
getDefaultBoolPrefsValue(CONST_RUNTIME_ENABLE_FLOW_SWAP_HEURISTIC, true),
skip_dpi_for_collected_flows = getDefaultBoolPrefsValue(
CONST_RUNTIME_SKIP_DPI_FOR_COLLECTED_FLOWS, false),
enable_assets_log =
getDefaultBoolPrefsValue(CONST_PREFS_ENABLE_ASSETS_LOG, false);
log_to_file =
getDefaultBoolPrefsValue(CONST_RUNTIME_PREFS_LOG_TO_FILE, false);
intf_rrd_raw_days =
getDefaultPrefsValue(CONST_INTF_RRD_RAW_DAYS, INTF_RRD_RAW_DAYS),
intf_rrd_1min_days =
getDefaultPrefsValue(CONST_INTF_RRD_1MIN_DAYS, INTF_RRD_1MIN_DAYS),
intf_rrd_1h_days =
getDefaultPrefsValue(CONST_INTF_RRD_1H_DAYS, INTF_RRD_1H_DAYS),
intf_rrd_1d_days =
getDefaultPrefsValue(CONST_INTF_RRD_1D_DAYS, INTF_RRD_1D_DAYS),
other_rrd_raw_days =
getDefaultPrefsValue(CONST_OTHER_RRD_RAW_DAYS, OTHER_RRD_RAW_DAYS),
other_rrd_1min_days =
getDefaultPrefsValue(CONST_OTHER_RRD_1MIN_DAYS, OTHER_RRD_1MIN_DAYS),
other_rrd_1h_days =
getDefaultPrefsValue(CONST_OTHER_RRD_1H_DAYS, OTHER_RRD_1H_DAYS),
other_rrd_1d_days =
getDefaultPrefsValue(CONST_OTHER_RRD_1D_DAYS, OTHER_RRD_1D_DAYS),
enable_top_talkers = getDefaultBoolPrefsValue(
CONST_TOP_TALKERS_ENABLED, CONST_DEFAULT_TOP_TALKERS_ENABLED),
enable_sites_collection = getDefaultBoolPrefsValue(
CONST_SITES_COLLECTION_ENABLED, CONST_DEFAULT_SITES_COLLECTION_ENABLED),
message_broker_enabled = getDefaultBoolPrefsValue(
CONST_PREFS_MESSAGE_BROKER_ENABLED, DEFAULT_MESSAGE_BROKER_ENABLED),
enable_dns_cache = getDefaultBoolPrefsValue(CONST_DNS_CACHE_ENABLED,
CONST_DEFAULT_DNS_CACHE_ENABLED),
enable_active_local_hosts_cache = getDefaultBoolPrefsValue(
CONST_RUNTIME_ACTIVE_LOCAL_HOSTS_CACHE_ENABLED,
CONST_DEFAULT_IS_ACTIVE_LOCAL_HOSTS_CACHE_ENABLED),
enable_tiny_flows_export =
getDefaultBoolPrefsValue(CONST_IS_TINY_FLOW_EXPORT_ENABLED,
CONST_DEFAULT_IS_TINY_FLOW_EXPORT_ENABLED),
max_entity_alerts = getDefaultPrefsValue(CONST_MAX_ENTITY_ALERTS,
ALERTS_MANAGER_MAX_ENTITY_ALERTS),
max_num_secs_before_delete_alert = getDefaultPrefsValue(
CONST_MAX_NUM_SECS_ALERTS_BEFORE_DEL, ALERTS_MAX_SECS_BEFORE_PURGE),
alert_page_refresh_rate = getDefaultPrefsValue(CONST_ALERT_PAGE_REFRESH_RATE,
ALERTS_PAGE_REFRESH_RATE),
enable_observation_points_rrd_creation = getDefaultBoolPrefsValue(
CONST_RUNTIME_PREFS_OBSERVATION_POINTS_RRD_CREATION, false),
enable_intranet_traffic_rrd_creation = getDefaultBoolPrefsValue(
CONST_RUNTIME_PREFS_INTRANET_TRAFFIC_RRD_CREATION, false),
enable_flow_device_port_rrd_creation = getDefaultBoolPrefsValue(
CONST_RUNTIME_PREFS_FLOW_DEVICE_PORT_RRD_CREATION, false),
disable_alerts = getDefaultBoolPrefsValue(CONST_ALERT_DISABLED_PREFS, false),
enable_activities_debug =
getDefaultBoolPrefsValue(CONST_ACTIVITIES_DEBUG_ENABLED, false),
snmp_polling =
getDefaultBoolPrefsValue(CONST_PREFS_ENABLE_SNMP_POLLING, true);
active_monitoring =
getDefaultBoolPrefsValue(CONST_PREFS_ENABLE_ACTIVE_MONITORING, false);
network_discovery =
getDefaultBoolPrefsValue(CONST_PREFS_ENABLE_NETWORK_DISCOVERY, false);
starttls = getDefaultBoolPrefsValue(CONST_PREFS_ENABLE_STARTTLS, false);
dump_pcap_to_clickhouse = getDefaultBoolPrefsValue(
CONST_PREFS_ENABLE_DUMP_PCAP_TO_CLICKHOUSE, false);
#ifdef NTOPNG_PRO
data_archive_before_ttl_delete = getDefaultBoolPrefsValue(
CONST_PREFS_ENABLE_ARCHIVE_BEFORE_TTL_DELETE, false);
#endif
query_performance_log =
getDefaultBoolPrefsValue(CONST_PREFS_ENABLE_QUERY_PERFORMANCE_LOG, false);
enable_arp_matrix_generation =
getDefaultBoolPrefsValue(CONST_DEFAULT_ARP_MATRIX_GENERATION, false),
override_dst_with_post_nat_dst =
getDefaultBoolPrefsValue(CONST_DEFAULT_OVERRIDE_DST_WITH_POST_NAT, false),
override_src_with_post_nat_src =
getDefaultBoolPrefsValue(CONST_DEFAULT_OVERRIDE_SRC_WITH_POST_NAT, false),
max_num_packets_per_tiny_flow =
getDefaultPrefsValue(CONST_MAX_NUM_PACKETS_PER_TINY_FLOW,
CONST_DEFAULT_MAX_NUM_PACKETS_PER_TINY_FLOW),
dump_frequency =
getDefaultPrefsValue(CONST_DUMP_FREQUENCY, ES_BULK_MAX_DELAY),
max_num_bytes_per_tiny_flow =
getDefaultPrefsValue(CONST_MAX_NUM_BYTES_PER_TINY_FLOW,
CONST_DEFAULT_MAX_NUM_BYTES_PER_TINY_FLOW),
max_extracted_pcap_bytes = getDefaultPrefsValue(
CONST_MAX_EXTR_PCAP_BYTES, CONST_DEFAULT_MAX_EXTR_PCAP_BYTES);
max_extracted_pcap_files = getDefaultPrefsValue(
CONST_MAX_EXTR_PCAP_FILES, CONST_DEFAULT_MAX_EXTR_PCAP_FILES);
ewma_alpha_percent = getDefaultPrefsValue(CONST_EWMA_ALPHA_PERCENT,
CONST_DEFAULT_EWMA_ALPHA_PERCENT);
enable_captive_portal =
getDefaultBoolPrefsValue(CONST_PREFS_CAPTIVE_PORTAL, false);
mac_based_captive_portal =
getDefaultBoolPrefsValue(CONST_PREFS_MAC_CAPTIVE_PORTAL, true);
enable_informative_captive_portal =
getDefaultBoolPrefsValue(CONST_PREFS_INFORM_CAPTIVE_PORTAL, false);
enable_external_auth_captive_portal =
getDefaultBoolPrefsValue(CONST_PREFS_EXTERNAL_AUTH, false);
full_stats_enabled =
getDefaultBoolPrefsValue(CONST_PREFS_ENABLE_FULL_STATS, true);
enable_vlan_trunk_bridge =
getDefaultBoolPrefsValue(CONST_PREFS_VLAN_TRUNK_MODE_ENABLED, false);
default_l7policy =
getDefaultPrefsValue(CONST_PREFS_DEFAULT_L7_POLICY, PASS_ALL_SHAPER_ID);
max_ui_strlen = getDefaultPrefsValue(CONST_RUNTIME_MAX_UI_STRLEN,
CONST_DEFAULT_MAX_UI_STRLEN);
hostMask = (HostMask)getDefaultPrefsValue(CONST_RUNTIME_PREFS_HOSTMASK,
no_host_mask);
flow_table_time =
(bool)getDefaultPrefsValue(CONST_FLOW_TABLE_TIME, flow_table_time);
flow_table_probe_order = (bool)getDefaultPrefsValue(
CONST_FLOW_TABLE_PROBE_ORDER, flow_table_probe_order);
auto_assigned_pool_id = (u_int16_t)getDefaultPrefsValue(
CONST_RUNTIME_PREFS_AUTO_ASSIGNED_POOL_ID, NO_HOST_POOL_ID);
enable_broadcast_domain_too_large =
getDefaultBoolPrefsValue(CONST_PREFS_BROADCAST_DOMAIN_TOO_LARGE, false);
getDefaultStringPrefsValue(CONST_RUNTIME_PREFS_TS_DRIVER, &aux, (char*)"rrd");
if (aux) {
timeseries_driver = str2TsDriver(aux);
free(aux);
}
getDefaultStringPrefsValue(CONST_RUNTIME_PREFS_SPLIT_TS_DIRECTION, &aux,
DEFAULT_SPLIT_TS_DIRECTION);
if (aux) {
split_ts_direction = strncmp(aux, DEFAULT_SPLIT_TS_DIRECTION, 5);
free(aux);
}
getDefaultStringPrefsValue(CONST_RUNTIME_PREFS_ENABLE_MAC_NDPI_STATS, &aux,
(char*)"none");
if (aux) {
enable_mac_ndpi_stats = strncmp(aux, (char*)"none", 4);
free(aux);
}
getDefaultStringPrefsValue(CONST_SAFE_SEARCH_DNS, &aux,
DEFAULT_SAFE_SEARCH_DNS);
if (aux) {
safe_search_dns_ip = Utils::inet_addr(aux);
free(aux);
}
getDefaultStringPrefsValue(CONST_GLOBAL_DNS, &aux, DEFAULT_GLOBAL_DNS);
if (aux) {
global_primary_dns_ip = Utils::inet_addr(aux);
free(aux);
}
getDefaultStringPrefsValue(CONST_SECONDARY_DNS, &aux, DEFAULT_GLOBAL_DNS);
if (aux) {
global_secondary_dns_ip = Utils::inet_addr(aux);
free(aux);
}
getDefaultStringPrefsValue(CONST_PREFS_MESSAGE_BROKER_URL, &tmp,
DEFAULT_MESSAGE_BROKER_URL);
if (tmp) {
if (message_broker_url) free(message_broker_url);
message_broker_url = strdup(tmp);
free(tmp);
}
getDefaultStringPrefsValue(CONST_PREFS_MESSAGE_BROKER, &tmp,
DEFAULT_MESSAGE_BROKER);
if (message_broker) free(message_broker);
message_broker = tmp;
getDefaultStringPrefsValue(CONST_PREFS_HTTP_INDEX_PAGE, &tmp,
DEFAULT_HTTP_INDEX_PAGE);
if (http_index_page) free(http_index_page);
if (tmp[0] == '\0') {
free(tmp);
tmp = strdup(INDEX_URL);
}
http_index_page = tmp;
asn_mode_enabled =
getDefaultBoolPrefsValue(CONST_PREFS_ASN_MODE_ENABLED, false);
global_dns_forging_enabled =
getDefaultBoolPrefsValue(CONST_PREFS_GLOBAL_DNS_FORGING_ENABLED, false);
enable_client_x509_auth =
getDefaultBoolPrefsValue(CONST_PREFS_CLIENT_X509_AUTH, false);
emit_flow_alerts =
getDefaultBoolPrefsValue(CONST_PREFS_EMIT_FLOW_ALERTS, true);
emit_host_alerts =
getDefaultBoolPrefsValue(CONST_PREFS_EMIT_HOST_ALERTS, true);
tls_quic_hostnaming =
getDefaultBoolPrefsValue(CONST_PREFS_TLS_QUIC_HOSTNAMING, false);
/* Used for stats */
collect_blacklist_stats =
getDefaultBoolPrefsValue(CONST_PREFS_COLLECT_BLACKLISTSTATS, false);
setTraceLevelFromRedis();
refreshHostsAlertsPrefs();
refreshDeviceProtocolsPolicyPref();
refreshDbDumpPrefs();
refreshBehaviourAnalysis();
#ifdef NTOPNG_PRO
// reset value
/* TODO: add a preference in the prefs page */
asset_inventory_enabled =
getDefaultPrefsValue(CONST_PREFS_ASSET_INVENTORY_ENABLED,
CONST_DEFAULT_ASSET_INVENTORY_ENABLED);
snmp_trap_enabled = getDefaultPrefsValue(CONST_PREFS_SNMP_TRAP_ENABLED,
CONST_DEFAULT_SNMP_TRAP_ENABLED);
#endif
#if defined(HAVE_CLICKHOUSE) && defined(NTOPNG_PRO)
ntopng_assets_inventory_enabled =
getDefaultPrefsValue(CONST_PREFS_NTOPNG_ASSETS_INVENTORY_ENABLED,
CONST_DEFAULT_NTOPNG_ASSETS_INVENTORY_ENABLED);
#endif
#if defined(NTOPNG_PRO)
reloadNetworksPolicyConfiguration();
#endif
#ifdef PREFS_RELOAD_DEBUG
ntop->getTrace()->traceEvent(TRACE_NORMAL,
"Updated IPs "
"[global_primary_dns_ip: %u]"
"[global_secondary_dns_ip: %u]"
"[safe_search_dns_ip: %u]",
global_primary_dns_ip, global_secondary_dns_ip,
safe_search_dns_ip);
ntop->getTrace()->traceEvent(TRACE_NORMAL,
"Masked hosts"
"[no_host_mask: %u]"
"[mask_local_hosts: %u]"
"[mask_remote_hosts: %u]",
hostMask == no_host_mask ? 1 : 0,
hostMask == mask_local_hosts ? 1 : 0,
hostMask == mask_remote_hosts ? 1 : 0);
ntop->getTrace()->traceEvent(TRACE_NORMAL, "[disable_alerts: %u]",
disable_alerts ? 1 : 0);
ntop->getTrace()->traceEvent(TRACE_NORMAL, "[mac_ndpi_stats: %u]",
enable_mac_ndpi_stats ? 1 : 0);
#endif
}
/* ******************************************* */
void Prefs::refreshBehaviourAnalysis() {
enable_behaviour_analysis = is_enterprise_l_edition();
enable_asn_behaviour_analysis =
getDefaultBoolPrefsValue(CONST_PREFS_ASN_BEHAVIOR_ANALYSIS, false);
enable_network_behaviour_analysis =
getDefaultBoolPrefsValue(CONST_PREFS_NETWORK_BEHAVIOR_ANALYSIS, false);
enable_iface_l7_behaviour_analysis =
getDefaultBoolPrefsValue(CONST_PREFS_IFACE_L7_BEHAVIOR_ANALYSIS, false);
behaviour_analysis_learning_period =
getDefaultPrefsValue(CONST_PREFS_BEHAVIOUR_ANALYSIS_LEARNING_PERIOD,
CONST_DEFAULT_BEHAVIOUR_ANALYSIS_LEARNING_PERIOD);
behaviour_analysis_learning_status_during_learning =
(ServiceAcceptance)getDefaultPrefsValue(
CONST_PREFS_BEHAVIOUR_ANALYSIS_STATUS_DURING_LEARNING,
service_allowed);
behaviour_analysis_learning_status_post_learning =
(ServiceAcceptance)getDefaultPrefsValue(
CONST_PREFS_BEHAVIOUR_ANALYSIS_STATUS_POST_LEARNING, service_allowed);
iec60870_learning_period =
getDefaultPrefsValue(CONST_PREFS_IEC60870_ANALYSIS_LEARNING_PERIOD,
CONST_IEC104_LEARNING_TIME);
modbus_learning_period = getDefaultPrefsValue(
CONST_PREFS_MODBUS_ANALYSIS_LEARNING_PERIOD, CONST_MODBUS_LEARNING_TIME);
s7comm_learning_period = getDefaultPrefsValue(
CONST_PREFS_S7COMM_ANALYSIS_LEARNING_PERIOD, CONST_S7COMM_LEARNING_TIME);
devices_learning_period =
getDefaultPrefsValue(CONST_PREFS_DEVICES_ANALYSIS_LEARNING_PERIOD,
CONST_DEVICES_LEARNING_TIME);
host_port_learning_period = getDefaultPrefsValue(
CONST_PREFS_HOST_PORT_LEARNING_PERIOD, CONST_HOST_PORT_LEARNING_TIME);
}
/* ******************************************* */
void Prefs::loadInstanceNameDefaults() {
// Do not re-set the interface name if it has already been set via command
// line
if (instance_name || !ntop)
return;
else {
char tmp[256];
if (gethostname(tmp, sizeof(tmp)))
ntop->getTrace()->traceEvent(TRACE_ERROR, "Unable to read hostname [%s]",
strerror(errno));
else
instance_name = strdup(tmp);
}
}
/* ******************************************* */
static const struct option long_options[] = {
#ifndef WIN32
{"data-dir", required_argument, NULL, 'd'},
#endif
{"daemon", no_argument, NULL, 'e'},
{"core-affinity", required_argument, NULL, 'g'},
{"help", no_argument, NULL, 'h'},
{"interface", required_argument, NULL, 'i'},
{"traffic-filtering", required_argument, NULL, 'k'},
{"disable-login", required_argument, NULL, 'l'},
{"local-networks", required_argument, NULL, 'm'},
#ifndef HAVE_NEDGE
{"dns-mode", required_argument, NULL, 'n'},
#endif
{"ndpi-protocols", required_argument, NULL, 'p'},
{"disable-autologout", no_argument, NULL, 'q'},
{"redis", required_argument, NULL, 'r'},
{"dont-change-user", no_argument, NULL, 's'},
#ifndef WIN32
{"install-dir", required_argument, NULL, 't'},
#endif
{"no-promisc", no_argument, NULL, 'u'},
{"verbose", required_argument, NULL, 'v'},
{"http-port", required_argument, NULL, 'w'},
{"max-num-hosts", required_argument, NULL, 'x'},
{"other-core-affinity", required_argument, NULL, 'y'},
{"pcap-reforge-timestamps", no_argument, NULL, 'z'},
{"packet-filter", required_argument, NULL, 'B'},
{"dump-hosts", required_argument, NULL, 'D'},
{"dump-flows", required_argument, NULL, 'F'},
#ifndef WIN32
{"pid", required_argument, NULL, 'G'},
#endif
{"export-flows", required_argument, NULL, 'I'},
{"http-log", required_argument, NULL, 'L'},
{"ppp-networks", no_argument, NULL, 'M'},
{"instance-name", required_argument, NULL, 'N'},
{"capture-direction", required_argument, NULL, 'Q'},
{"sticky-hosts", required_argument, NULL, 'S'},
{"user", required_argument, NULL, 'U'},
{"version", no_argument, NULL, 'V'},
{"https-port", required_argument, NULL, 'W'},
{"max-num-flows", required_argument, NULL, 'X'},
{"http-prefix", required_argument, NULL, 'Z'},
{"httpdocs-dir", required_argument, NULL, '1'},
{"scripts-dir", required_argument, NULL, '2'},
{"callbacks-dir", required_argument, NULL, '3'},
{"prefs-dir", required_argument, NULL, '4'},
{"pcap-dir", required_argument, NULL, '5'},
{"db-archive-dir", required_argument, NULL, '6'},
{"geoip-dir", required_argument, NULL, 196},
#ifdef NTOPNG_PRO
{"license-mgr", required_argument, NULL, 197},
#endif
{"ciphers-list", required_argument, NULL, 198},
{"disable-purge", no_argument, NULL, 199},
{"limit-resources", no_argument, NULL, 200},
{"test-script-post", required_argument, NULL, 201},
#ifdef HAVE_PF_RING
{"cluster-id", required_argument, NULL, 204},
#endif
#ifdef NTOPNG_PRO
{"version-json", no_argument, NULL, 205},
#endif
{"test-script-pre", required_argument, NULL, 206},
{"pcap-file-purge-flows", no_argument, NULL, 207},
{"original-speed", no_argument, NULL, 208},
{"online-check", no_argument, NULL, 209},
{"print-ndpi-protocols", no_argument, NULL, 210},
{"online-license-check", no_argument, NULL, 211}, // deprecated (removed)
{"hw-timestamp-mode", required_argument, NULL, 212},
{"shutdown-when-done", no_argument, NULL, 213},
{"simulate-vlans", no_argument, NULL, 214},
#ifndef HAVE_NEDGE
{"ignore-macs", no_argument, NULL, 216},
#endif
{"ignore-vlans", no_argument, NULL, 217},
{"test-script", required_argument, NULL, 218},
#if HAVE_ZMQ
{"zmq-publish-events", required_argument, NULL, 203},
{"zmq-encrypt-pwd", required_argument, NULL, 215},
{"zmq-encryption", no_argument, NULL, 219},
{"zmq-encryption-key-priv", required_argument, NULL, 220},
{"zmq-encryption-key", required_argument, NULL, 222},
#endif
{"simulate-ips", required_argument, NULL, 221},
#ifndef HAVE_NEDGE
{"appliance", no_argument, NULL, 223},
#endif
{"simulate-macs", no_argument, NULL, 224},
{"insecure", no_argument, NULL, 225},
{"offline", no_argument, NULL, 226},
{"readonly-flows-dump", no_argument, NULL, 227},
{"strict-startup", no_argument, NULL, 228},
{"mtu", required_argument, NULL, 229},
#ifdef HAVE_HIREDIS_SSL
{"redis-tls-ca-cert", required_argument, NULL, 230},
{"redis-tls-cert", required_argument, NULL, 231},
{"redis-tls-key", required_argument, NULL, 232},
{"redis-tls-skip-verify", no_argument, NULL, 233},
#endif
#ifdef NTOPNG_PRO
{"dump-queue-len", no_argument, NULL, 248},
{"dump-queue-block-size", no_argument, NULL, 249},
{"direct-flows-dump", no_argument, NULL, 250},
{"fail-invalid-license", no_argument, NULL, 251},
{"check-maintenance", no_argument, NULL, 252},
{"check-license", no_argument, NULL, 253},
{"community", no_argument, NULL, 254}, /* Deprecated, kept for backward compatibility */
#endif
/* End of options */
{NULL, no_argument, NULL, 0}};
/* ******************************************* */
/* Those options are hidden and will not be shown in the GUI cli string.
Typically, such options contains passwords or other sensitive fields. */
static const int hidden_optkeys[] = {'F' /* flows export */, 'r' /* redis */,
215 /* zmq encryption password */,
220 /* zmq encryption secret key */, 0};
/* ******************************************* */
/* This function is used in order to set ports in case they were not set in the config file */
void Prefs::checkPorts() {
// No ports set in the config, set HTTP to 3000
if (!http_port && !https_port) {
http_port = CONST_DEFAULT_NTOP_PORT;
} else if (http_port == https_port) {
// In case the http and https ports are the same
// Only load the https
http_port = 0;
}
}
/* ******************************************* */
void Prefs::parseHTTPPort(char* arg) {
char tmp[32], *a, *_t;
snprintf(tmp, sizeof(tmp), "%s", arg);
a = strtok_r(tmp, ",", &_t);
if (a) http_port = atoi(a);
}
/* ******************************************* */
char* Prefs::parseLocalNetworks(char* arg) {
struct stat buf;
if ((stat(arg, &buf) == 0) && S_ISREG(buf.st_mode)) {
string res;
string line;
ifstream fl(arg);
char to_trim[] = {'\t', ' ', '\n', '\r', '"', '\'', '\0'};
if (fl.is_open()) {
/*
A file with local networks.
Multiple local networks are expressed either using commas and also on
multiple lines.
File example:
192.168.2.0/24=office,192.168.2.1/32,8.8.8.8/32
9.9.9.9/32
10.0.0.0/8
*/
while (getline(fl, line)) {
const char* l = line.c_str();
if ((l[0] == '\0') || (l[0] == '#')) continue;
for (u_int i = 0; to_trim[i] != '\0'; i++)
line.erase(std::remove(line.begin(), line.end(), to_trim[i]),
line.end());
l = line.c_str(); /* Update line */
/* Append the comma if local networks are specified across multiple file
* lines */
if (res.size() > 0) res += ",";
/* Append the current line with one or more local networks */
res += line;
}
fl.close();
}
return strdup(res.c_str());
}
/* Assumes local networks are specified as comma-separated straight into `arg`
*/
return strdup(arg);
}
/* ******************************************* */
void Prefs::setCommandLineString(int optkey, const char* optarg) {
char *p, *opt = NULL;
int len = 6;
int i;
if (optarg) {
for (i = 0; hidden_optkeys[i] != 0; i++) {
if (optkey == hidden_optkeys[i]) {
optarg = "[hidden]";
break;
}
}
len += strlen(optarg);
}
for (i = 0; long_options[i].name != NULL; i++) {
if (long_options[i].val == optkey) {
opt = (char*)long_options[i].name;
len += strlen(opt) + 2;
break;
}
}
if ((p = (char*)malloc(len)) != NULL) {
if (opt) {
if (optarg && strlen(optarg))
snprintf(p, len - 1, "--%s \'%s\' ", opt, optarg);
else
snprintf(p, len - 1, "--%s ", opt);
} else {
if (optarg && strlen(optarg))
snprintf(p, len - 1, "-%c %s ", optkey, optarg);
else
snprintf(p, len - 1, "-%c ", optkey);
}
if (cli == NULL)
cli = p;
else {
int l = strlen(cli);
char* backup = cli;
if ((cli = (char*)realloc(cli, l + len)) != NULL) {
strcpy(&cli[l], p);
free(p);
} else
cli = backup;
}
}
}
/* ******************************************* */
/* NOTE: avoid Redis connection in this function */
static void printVersionInformation() {
printf("Version:\t%s [%s%s build]\n", PACKAGE_VERSION,
#ifndef HAVE_NEDGE
#ifdef NTOPNG_PRO
"Enterprise/Professional"
#else
"Community"
#endif
#else
"Edge"
#endif
,
#ifdef NTOPNG_PRO
ntop->getPro()->is_embedded_version() ? "/Embedded" :
#endif
"");
printf("GIT rev:\t%s\n", NTOPNG_GIT_RELEASE);
#ifdef NTOPNG_PRO
printf("Pro rev:\t%s\n", NTOPNG_PRO_GIT_RELEASE);
printf("Built on:\t%s%s\n", PACKAGE_OS,
#ifdef HAVE_RASPBERRY
" [Raspberry]"
#else
""
#endif
);
printf("System Id:\t%s\n", ntop->getPro()->get_system_id());
printf("Platform:\t%s\n", PACKAGE_MACHINE);
#endif
}
/* ******************************************* */
int Prefs::setOption(int optkey, char* optarg) {
const struct option* opt;
char *double_dot, buf[128] = {'\0'};
opt = long_options;
while (opt->name != NULL) {
if (optkey == opt->val) {
if (opt->has_arg == required_argument && (!optarg || optarg[0] == '\0')) {
ntop->getTrace()->traceEvent(
TRACE_WARNING,
"Missing required argument. Skipping option -%c (--%s).", opt->val,
opt->name);
return (-1);
}
break;
}
opt++;
}
setCommandLineString(optkey, optarg);
switch (optkey) {
case 'B':
if ((optarg[0] == '\"') && (strlen(optarg) > 2)) {
packet_filter = strdup(&optarg[1]);
packet_filter[strlen(packet_filter) - 1] = '\0';
} else
packet_filter = strdup(optarg);
break;
case 'u':
use_promiscuous_mode = false;
break;
#ifndef WIN32
case 'd':
ntop->setWorkingDir(optarg);
break;
case 't':
install_dir = strndup(optarg, MAX_PATH);
break;
#endif
case 'D':
ntop->getTrace()->traceEvent(TRACE_ERROR, "-D deprecated.");
break;
case 'e':
daemonize = true;
break;
case 'S':
ntop->getTrace()->traceEvent(
TRACE_ERROR,
"-S deprecated, sticky hosts no longer supported. "
"Configure remote and local hosts idle timeouts "
"from the preferences.");
break;
case 'g':
cpu_affinity = strdup(optarg);
break;
case 'm': {
char* cur_nets = parseLocalNetworks(optarg);
if (cur_nets) {
if (!local_networks_set) {
free(local_networks);
local_networks = cur_nets;
local_networks_set = true;
} else {
/* If local_networks is already set up, the new -m argument is going
* to be concat (comma separeted) to the old one */
if (strlen(cur_nets) > 0) {
int new_local_networks_size =
strlen(local_networks) + strlen(cur_nets) + 2;
char* new_local_networks =
(char*)malloc(sizeof(char) * new_local_networks_size);
if (new_local_networks) {
snprintf(new_local_networks, new_local_networks_size, "%s,%s",
local_networks, cur_nets);
free(local_networks);
local_networks = new_local_networks;
}
}
free(cur_nets);
}
}
} break;
case 'M':
ntop->disableBroadcastIP();
break;
#ifndef HAVE_NEDGE
case 'n':
dns_mode = atoi(optarg);
switch (dns_mode) {
case 0:
break;
case 1:
resolve_all_hosts();
break;
case 2:
disable_dns_resolution();
break;
case 3:
disable_dns_resolution();
disable_dns_responses_decoding();
disable_all_name_decoding();
break;
case 4:
disable_localhost_name_decoding();
break;
default:
usage();
}
break;
#endif
case 'p':
ndpi_proto_path = strdup(optarg);
ntop->setCustomnDPIProtos(ndpi_proto_path);
break;
case 'q':
enable_auto_logout = false;
break;
case 'Q':
switch (atoi(optarg)) {
case 1:
setCaptureDirection(PCAP_D_IN);
break;
case 2:
setCaptureDirection(PCAP_D_OUT);
break;
default:
setCaptureDirection(PCAP_D_INOUT);
break;
}
break;
case 'h':
help();
break;
case 'i':
if (!optarg)
ntop->getTrace()->traceEvent(TRACE_ERROR,
"No interface specified, -i ignored");
else if (strlen(optarg) > MAX_INTERFACE_NAME_LEN - 1)
ntop->getTrace()->traceEvent(
TRACE_ERROR,
"Interface name too long (exceeding %d characters): ignored %s",
MAX_INTERFACE_NAME_LEN - 1, optarg);
else if (!addDeferredInterfaceToRegister(optarg))
ntop->getTrace()->traceEvent(
TRACE_ERROR, "Too many interfaces specified with -i: ignored %s",
optarg);
break;
case 'w':
if (strchr(optarg, ':') == NULL) {
// only the port
parseHTTPPort(optarg);
} else if (optarg[0] == ':') {
// first char == ':' binds to the loopback address
parseHTTPPort(&optarg[1]);
bind_http_to_loopback();
} else {
// ':' is after the first character, so
// we need to parse both the ip address and the port
double_dot = strrchr(optarg, ':');
u_int len = double_dot - optarg;
http_binding_address1 = strndup(optarg, len);
parseHTTPPort(&double_dot[1]);
}
break;
case 'W':
if (strchr(optarg, ':') == NULL) {
// only the port
https_port = atoi(optarg);
} else if (optarg[0] == ':') {
// first char == ':' binds to the loopback address
https_port = atoi(&optarg[1]);
bind_https_to_loopback();
} else {
// ':' is after the first character, so
// we need to parse both the ip address and the port
double_dot = strrchr(optarg, ':');
u_int len = double_dot - optarg;
https_binding_address1 = strndup(optarg, len);
https_port = atoi(&double_dot[1]);
}
break;
case 'z':
do_reforge_timestamps = true;
break;
case 'Z':
if (optarg[0] != '/') {
ntop->getTrace()->traceEvent(
TRACE_WARNING,
"-Z argument (%s) must begin with '/' (example /ntopng): skipped",
optarg);
} else {
int len = strlen(optarg);
if (len > 0) {
if (optarg[len - 1] == '/') {
ntop->getTrace()->traceEvent(TRACE_WARNING,
"-Z argument (%s) cannot end with '/' "
"(example /ntopng): skipped",
optarg);
} else {
free(http_prefix);
http_prefix = strdup(optarg);
}
}
}
break;
case 'N':
instance_name = strndup(optarg, 256);
break;
case 'r': {
char* r;
/*
Supported formats for --redis
host:port
host@redis_instance
host:port@redis_instance
host:port:password@redis_instance
*/
snprintf(buf, sizeof(buf), "%s", optarg);
r = strrchr(buf, '@');
if (r) {
bool is_float;
char* idptr = &r[1];
if (Utils::isNumber(idptr, strlen(idptr), &is_float)) {
int id = atoi((const char*)idptr);
if (id < 0 || id > 0xff) {
ntop->getTrace()->traceEvent(
TRACE_WARNING,
"Redis DB ID provided with --redis|-r cannot be bigger than %u",
0xff);
} else {
redis_db_id = id;
}
(*r) = '\0';
}
}
if (strchr(buf, ':')) {
char *w, *c;
c = strtok_r(buf, ":", &w);
if (redis_host) free(redis_host);
redis_host = strdup(c);
c = strtok_r(NULL, ":", &w);
if (c) redis_port = atoi(c);
c = strtok_r(NULL, "\0", &w);
if (c) redis_password = strdup(c);
} else if (strlen(buf) > 0) {
/* only the host */
if (redis_host) free(redis_host);
redis_host = strdup(buf);
}
ntop->getTrace()->traceEvent(TRACE_NORMAL, "ntopng will use redis %s@%u",
redis_host, redis_db_id);
if (redis_password)
ntop->getTrace()->traceEvent(TRACE_NORMAL,
"redis connection is password-protected");
} break;
case 's':
change_user = false;
break;
case '1':
free(docs_dir);
docs_dir = strdup(optarg);
break;
case '2':
free(scripts_dir);
scripts_dir = strdup(optarg);
break;
case '3':
free(callbacks_dir);
callbacks_dir = strdup(optarg);
break;
case '5':
if (pcap_dir) free(pcap_dir);
pcap_dir = strdup(optarg);
break;
case '6':
if (clickhouse_archive_dir) free(clickhouse_archive_dir);
clickhouse_archive_dir = strdup(optarg);
break;
case 'l':
switch (atoi(optarg)) {
case 0:
disable_localhost_login = true;
ntop->getTrace()->traceEvent(TRACE_NORMAL,
"Localhost HTTP user login disabled");
break;
case 1:
enable_users_login = false;
ntop->getTrace()->traceEvent(TRACE_NORMAL,
"All HTTP user login disabled");
break;
default:
ntop->getTrace()->traceEvent(
TRACE_ERROR, "Invalid '%s' value specified for -l: ignored",
optarg);
}
break;
case 'L':
http_log_path = strdup(optarg);
break;
case 'x':
max_num_hosts = atoi(optarg);
break;
case 'X':
max_num_flows = atoi(optarg);
break;
case 'y':
other_cpu_affinity = strdup(optarg);
#ifdef HAVE_LIBCAP
Utils::setAffinityMask(optarg, &other_cpu_affinity_mask);
#endif
break;
case 'v': {
if (!optarg)
ntop->getTrace()->traceEvent(
TRACE_ERROR, "No value specified for verbosity: ignored");
else {
int8_t lvl = (int8_t)strtol(optarg, NULL, 10);
has_cmdl_trace_lvl = true;
errno = 0;
if (errno)
ntop->getTrace()->traceEvent(
TRACE_ERROR, "Invalid '%s' value specified for -v: ignored",
optarg);
else {
if (lvl < 0) lvl = 0;
ntop->getTrace()->set_trace_level((u_int8_t)lvl);
}
}
} break;
case 'F':
if (!optarg)
ntop->getTrace()->traceEvent(TRACE_ERROR,
"No connection specified, -F ignored");
#ifndef HAVE_NEDGE
else if ((strncmp(optarg, "es", 2) == 0) && (strlen(optarg) > 3)) {
char *elastic_index_type = NULL, *elastic_index_name = NULL,
*tmp = NULL, *elastic_url = NULL, *elastic_user = NULL,
*elastic_pwd = NULL;
/* es;<index type>;<index name>;<es URL>;<es pwd> */
if ((elastic_index_type = strtok_r(&optarg[3], ";", &tmp)) != NULL) {
if ((elastic_index_name = strtok_r(NULL, ";", &tmp)) != NULL) {
if ((elastic_url = strtok_r(NULL, ";", &tmp)) != NULL) {
if ((elastic_user = strtok_r(NULL, ";", &tmp)) == NULL)
elastic_pwd = (char*)"";
else {
char* double_col = strchr(elastic_user, ':');
if (double_col)
elastic_pwd = &double_col[1], double_col[0] = '\0';
else
elastic_pwd = (char*)"";
}
}
}
}
if (elastic_index_type && elastic_index_name && elastic_url) {
if (es_type) free(es_type);
if (es_index) free(es_index);
if (es_url) free(es_url);
if (es_user) free(es_user);
if (es_pwd) free(es_pwd);
if (es_host) free(es_host);
if ((es_type = strdup(elastic_index_type)) == NULL)
ntop->getTrace()->traceEvent(TRACE_WARNING, "Not enough memory");
if ((es_index = strdup(elastic_index_name)) == NULL)
ntop->getTrace()->traceEvent(TRACE_WARNING, "Not enough memory");
if ((es_url = strdup(elastic_url)) == NULL)
ntop->getTrace()->traceEvent(TRACE_WARNING, "Not enough memory");
if ((es_user = strdup(elastic_user ? elastic_user : "")) == NULL)
ntop->getTrace()->traceEvent(TRACE_WARNING, "Not enough memory");
if ((es_pwd = strdup(elastic_pwd ? elastic_pwd : "")) == NULL)
ntop->getTrace()->traceEvent(TRACE_WARNING, "Not enough memory");
if ((es_host = strdup(elastic_url)) == NULL)
ntop->getTrace()->traceEvent(TRACE_WARNING, "Not enough memory");
if (es_type && es_index && es_url && es_user && es_pwd && es_host) {
if (!strncmp(es_host, "http://",
7)) // url starts either with http or https
Utils::tokenizer(es_host + 7, '/', NULL);
else if (!strncmp(es_host, "https://", 8))
Utils::tokenizer(es_host + 8, '/', NULL);
else
Utils::tokenizer(es_host, '/', NULL);
ntop->getTrace()->traceEvent(
TRACE_NORMAL,
"Using ElasticSearch for data dump [%s][%s][%s][%s]", es_type,
es_index, es_url, es_host);
dump_flows_on_es = true;
} else
dump_flows_on_es = false;
} else {
ntop->getTrace()->traceEvent(TRACE_WARNING,
"Discarding -F: invalid format for es");
ntop->getTrace()->traceEvent(
TRACE_WARNING,
"Format: -F es;<index type>;<index name>;<es URL>;<user>:<pwd>");
}
}
#endif /* HAVE_NEDGE */
#ifndef HAVE_NEDGE
#if defined(HAVE_KAFKA) && defined(NTOPNG_PRO)
else if ((strncmp(optarg, "kafka", 5) == 0) && (strlen(optarg) > 3)) {
char* conf = strdup(&optarg[5]);
if (conf != NULL) {
char *brokers_list, *tmp;
if ((brokers_list = strtok_r(conf, ";", &tmp)) != NULL) {
char* topic = strtok_r(NULL, ";", &tmp);
if (conf != NULL) {
char* options = strtok_r(NULL, ";", &tmp);
if ((kafka_brokers_list = strdup(brokers_list)) != NULL) {
if ((kafka_topic = strdup(topic)) != NULL) {
kafka_options = options ? strdup(options) : NULL;
}
}
if ((kafka_brokers_list == NULL) || (kafka_topic == NULL)) {
/* Out of memory */
ntop->getTrace()->traceEvent(TRACE_WARNING,
"Not enough memory");
if (kafka_brokers_list) {
free(kafka_brokers_list);
kafka_brokers_list = NULL;
}
if (kafka_topic) {
free(kafka_topic);
kafka_topic = NULL;
}
}
} else
ntop->getTrace()->traceEvent(
TRACE_WARNING, "Unable to parse kafka topic: skipping -F");
} else
ntop->getTrace()->traceEvent(
TRACE_WARNING, "Unable to parse brokers list: skipping -F");
free(conf);
} else
ntop->getTrace()->traceEvent(
TRACE_WARNING, "Discarding -F: unable to parse kafka options");
}
#endif
#endif /* HAVE_NEDGE */
else if ((!strncmp(optarg, "clickhouse", 10)) ||
(!strncmp(optarg, "clickhouse-cluster", 18)) ||
(!strncmp(optarg, "clickhouse-cloud", 16))) {
#if defined(HAVE_CLICKHOUSE) && defined(NTOPNG_PRO)
char* sep = strchr(optarg, ';');
bool all_good = true;
bool use_clickhouse_cluster;
bool use_clickhouse_cloud;
dump_flows_on_clickhouse = true;
use_clickhouse_cluster =
(strncmp(optarg, "clickhouse-cluster", 18) == 0) ? true : false;
use_clickhouse_cloud =
(strncmp(optarg, "clickhouse-cloud", 16) == 0) ? true : false;
/* Check if CLICKHOUSE_CLIENT is present */
struct stat buf;
bool client_found =
((stat(CONST_BIN_DIR "/" CLICKHOUSE_CLIENT, &buf) == 0) &&
(S_ISREG(buf.st_mode)))
? true
: false;
if (!client_found) {
client_found =
((stat(CONST_BIN_DIR "/" CLICKHOUSE_ALT_CLIENT, &buf) == 0) &&
(S_ISREG(buf.st_mode)))
? true
: false;
if (client_found)
clickhouse_client = CONST_BIN_DIR "/" CLICKHOUSE_ALT_CLIENT_CMD;
} else {
if (!client_found) {
client_found = ((stat(CONST_LOCAL_BIN_DIR "/" CLICKHOUSE_ALT_CLIENT,
&buf) == 0) &&
(S_ISREG(buf.st_mode)))
? true
: false;
if (client_found)
clickhouse_client =
CONST_LOCAL_BIN_DIR "/" CLICKHOUSE_ALT_CLIENT_CMD;
} else {
clickhouse_client = CONST_BIN_DIR "/" CLICKHOUSE_CLIENT;
}
}
if (!client_found) {
ntop->getTrace()->traceEvent(TRACE_WARNING,
"-F clickhouse is not available "
"(ClickHouse client not found)");
ntop->getTrace()->traceEvent(TRACE_WARNING, "Expected %s or %s",
CONST_BIN_DIR "/" CLICKHOUSE_CLIENT,
CONST_BIN_DIR "/" CLICKHOUSE_ALT_CLIENT);
all_good = dump_flows_on_clickhouse = false;
}
if (all_good) {
u_int num_semicolumns = 0;
for (u_int i = 0; optarg[i] != '\0'; i++)
if (optarg[i] == ';') num_semicolumns++;
if ((num_semicolumns == 0) && dump_flows_on_clickhouse) {
clickhouse_host = strdup((char*)"127.0.0.1");
clickhouse_dbname = strdup((char*)"ntopng");
clickhouse_user = strdup((char*)"default");
clickhouse_pw = strdup((char*)"");
if (use_clickhouse_cluster)
clickhouse_cluster_name = strdup((char*)DEFAULT_CLICKHOUSE_CLUSTER);
} else {
char *after_pw;
optarg = Utils::tokenizer(sep + 1, ';', &clickhouse_host);
optarg = Utils::tokenizer(optarg, ';', &clickhouse_dbname);
optarg = Utils::tokenizer(optarg, ';', &clickhouse_user);
after_pw = Utils::tokenizer(optarg, ';', &clickhouse_pw);
if (after_pw != optarg) {
if (use_clickhouse_cluster) {
/* read cluster_name */
char* cluster_name_tmp = NULL;
char* after_cluster;
after_cluster = Utils::tokenizer(after_pw, ';', &cluster_name_tmp);
if (cluster_name_tmp) clickhouse_cluster_name = cluster_name_tmp;
if (after_cluster != after_pw) {
/* read optional ro user/pwd */
char* after_ro_user;
after_ro_user = Utils::tokenizer(after_cluster, ';', &clickhouse_ro_user);
if (clickhouse_ro_user && clickhouse_ro_user[0] &&
after_ro_user != after_cluster)
clickhouse_ro_pw = strdup(after_ro_user);
}
} else {
char* after_ro_user;
/* read ro user/pwd */
after_ro_user = Utils::tokenizer(after_pw, ';', &clickhouse_ro_user);
if (clickhouse_ro_user && clickhouse_ro_user[0] &&
after_ro_user != after_pw)
clickhouse_ro_pw = strdup(after_ro_user);
}
}
}
if (use_clickhouse_cloud) {
char* comma;
char* tmp = clickhouse_user;
clickhouse_user = NULL;
if (tmp && (comma = strchr(tmp, ','))) {
// clickhouse_cluster_user = clickhouse_user;
*(comma++) = '\0';
clickhouse_user = strdup(comma);
clickhouse_cluster_user = strdup(tmp);
free(tmp);
}
if (!clickhouse_cluster_user || !clickhouse_user) {
/* Falling back to default values */
ntop->getTrace()->traceEvent(
TRACE_WARNING,
"Invalid ClickHouse user, falling back to local ClickHouse "
"[ClickHouse user: %s / %s]",
clickhouse_cluster_user ? clickhouse_cluster_user : "",
clickhouse_user ? clickhouse_user : "");
clickhouse_host = strdup((char*)"127.0.0.1");
clickhouse_dbname = strdup((char*)"ntopng");
clickhouse_user = strdup((char*)"default");
clickhouse_pw = strdup((char*)"");
clickhouse_cluster_user = NULL; /* No CH user by default */
}
}
if (use_clickhouse_cluster &&
((clickhouse_cluster_name == NULL) ||
(clickhouse_cluster_name[0] == '\0'))) {
if (clickhouse_cluster_name) {
free((void*)clickhouse_cluster_name);
clickhouse_cluster_name = NULL;
}
clickhouse_cluster_name = strdup((char*)DEFAULT_CLICKHOUSE_CLUSTER);
}
if (clickhouse_host && clickhouse_user) {
if ((clickhouse_dbname == NULL) || (clickhouse_dbname[0] == '\0'))
clickhouse_dbname = strdup("ntopng");
if (clickhouse_pw == NULL) clickhouse_pw = strdup("");
/* Check for non-default SQL port on -F line */
/* mysql deprecated and not used (still parsed for backward
* compatibility) */
char* mysql_port_str;
int mysql_port = CONST_DEFAULT_CLICKHOUSE_MYSQL_PORT;
/* Default ports */
clickhouse_tcp_port = CONST_DEFAULT_CLICKHOUSE_TCP_PORT;
clickhouse_tcp_port_secure = false; /* No TLS */
/* Configured ports, if any */
if ((mysql_port_str = strchr(clickhouse_host, '@'))) {
char *comma, *clickhouse_tcp_port_str;
long l;
int len;
*(mysql_port_str++) = '\0';
if ((comma = strchr(mysql_port_str, ','))) {
clickhouse_tcp_port_str = mysql_port_str;
*(comma++) = '\0';
mysql_port_str = comma;
errno = 0;
len = strlen(clickhouse_tcp_port_str);
if (len > 1) {
len--;
if (clickhouse_tcp_port_str[len] == 's') {
clickhouse_tcp_port_secure = true;
clickhouse_tcp_port_str[len] = '\0';
}
}
l = strtol(clickhouse_tcp_port_str, NULL, 10);
if (errno || !l)
ntop->getTrace()->traceEvent(
TRACE_WARNING,
"Invalid MySQL port, using default port %d [%s]",
clickhouse_tcp_port, strerror(errno));
else
clickhouse_tcp_port = (int)l;
}
errno = 0;
len = strlen(mysql_port_str);
if (len > 1) {
len--;
if (mysql_port_str[len] == 's') {
// mysql_port_secure = true;
mysql_port_str[len] = '\0';
}
}
l = strtol(mysql_port_str, NULL, 10);
if (errno || !l)
ntop->getTrace()->traceEvent(
TRACE_WARNING,
"Invalid MySQL port, using default port %d [%s]",
mysql_port, strerror(errno));
else
mysql_port = (int)l;
}
if (clickhouse_host) {
if (strcmp(clickhouse_host, "localhost") == 0) {
/* Clickhouse does not like localhost */
free(clickhouse_host);
clickhouse_host = strdup("127.0.0.1");
}
}
if (!clickhouse_ro_user || !clickhouse_ro_user[0])
ntop->getTrace()->traceEvent(TRACE_WARNING,
"ClickHouse configured without a read-only user: all queries "
"will use the privileged account. Consider configuring it in "
"the -F clickhouse option.");
} else {
ntop->getTrace()->traceEvent(
TRACE_WARNING, "Invalid format for -F clickhouse;....");
}
} /* all_good */
#else
ntop->getTrace()->traceEvent(
TRACE_WARNING, "-F clickhouse not available: missing support");
#endif
} /* "clickhouse" */
#ifndef HAVE_NEDGE
#if !defined(WIN32) && !defined(__APPLE__)
else if (!strncmp(optarg, "syslog", strlen("syslog"))) {
char* flows_syslog_facility_text;
dump_flows_on_syslog = true;
if (strchr(optarg, ';') != NULL) {
int syslog_facility_value;
optarg = Utils::tokenizer(strchr(optarg, ';') + 1, ';',
&flows_syslog_facility_text);
syslog_facility_value =
Utils::mapSyslogFacilityTextToValue(flows_syslog_facility_text);
if (syslog_facility_value != -1) {
flows_syslog_facility = syslog_facility_value;
ntop->getTrace()->traceEvent(
TRACE_DEBUG,
"Syslog facility for dumping flows is set to %s (%d)",
flows_syslog_facility_text, flows_syslog_facility);
}
}
ntop->getTrace()->traceEvent(TRACE_NORMAL,
"Dumping flows to syslog in JSON format");
}
#endif
#endif /* HAVE_NEDGE */
else {
ntop->getTrace()->traceEvent(TRACE_ERROR,
"Unsupported export format '%s'", optarg);
}
break;
#ifndef WIN32
case 'G':
if (pid_path) free(pid_path);
pid_path = strdup(optarg);
break;
#endif
case 'I':
export_endpoint = strdup(optarg);
break;
case 'U':
set_user(optarg);
break;
case 'V':
print_version = true;
break;
case 196:
setCustomGeoIPDir(optarg);
break;
#ifdef NTOPNG_PRO
case 197:
lic_mgr_config_file = strdup(optarg);
break;
#endif
case 198:
ciphers_list = strdup(optarg);
break;
case 199:
disable_purge = true;
break;
case 200:
limited_resources_mode = true;
break;
case 201:
if (test_post_script_path) free(test_post_script_path);
test_post_script_path = strdup(optarg);
break;
case 203:
zmq_publish_events_url = strdup(optarg);
break;
#ifdef HAVE_PF_RING
case 204:
pfring_cluster_id = atoi(optarg);
break;
#endif
case 205:
print_version_json = true;
break;
case 206:
if (test_pre_script_path) free(test_pre_script_path);
test_pre_script_path = strdup(optarg);
break;
case 207:
pcap_file_purge_hosts_flows = true;
break;
case 208:
reproduce_at_original_speed = true;
break;
case 209:
service_license_check = true;
break;
case 210:
nDPIhelp();
break;
case 211:
ntop->getTrace()->traceEvent(
TRACE_WARNING,
"Online check no longer supported (please remove "
"--online-license-check from the configuration)");
break;
case 212:
if (!strcmp(optarg, "ixia"))
enable_ixia_timestamps = true;
else
ntop->getTrace()->traceEvent(
TRACE_WARNING,
"Unknown --hw-timestamp-mode mode, it has been ignored\n");
break;
case 213:
shutdown_when_done = true;
break;
case 214:
simulate_vlans = true;
break;
case 215:
zmq_encryption_pwd = strdup(optarg);
break;
#ifndef HAVE_NEDGE
case 216:
ignore_macs = true;
break;
#endif
case 217:
ignore_vlans = true;
break;
case 219:
enable_zmq_encryption = true;
break;
case 220:
enable_zmq_encryption = true;
zmq_encryption_priv_key = strdup(optarg);
break;
case 221:
num_simulated_ips = atoi(optarg);
break;
case 222:
export_zmq_encryption_key = strdup(optarg);
break;
#ifndef HAVE_NEDGE
case 223:
appliance = true;
break;
#endif
case 224:
simulate_macs = true;
break;
case 225:
insecure_tls = true;
break;
case 226:
ntop->toggleForcedOffline(true);
ntop->toggleOffline(true);
break;
case 227:
readonly_flows_dump = true;
ntop->getTrace()->traceEvent(TRACE_NORMAL, "Read-only flows dump set");
break;
case 228:
strict_startup = true;
break;
case 229:
custom_if_mtu = (u_int16_t)atoi(optarg);
break;
#ifdef HAVE_HIREDIS_SSL
case 230:
if (redis_tls_ca_cert) free(redis_tls_ca_cert);
redis_tls_ca_cert = strdup(optarg);
break;
case 231:
if (redis_tls_cert) free(redis_tls_cert);
redis_tls_cert = strdup(optarg);
break;
case 232:
if (redis_tls_key) free(redis_tls_key);
redis_tls_key = strdup(optarg);
break;
case 233:
redis_tls_skip_verify = true;
break;
#endif
#ifdef NTOPNG_PRO
case 248:
dump_queue_len = atoi(optarg);
break;
case 249:
dump_queue_block_size = atoi(optarg);
break;
case 250:
toggle_dump_flows_direct(true);
break;
case 251:
fail_on_invalid_license = true;
break;
case 252:
print_maintenance = true;
break;
case 253:
print_license = true;
break;
case 254:
/* Deprecated --community, kept for backward compatibility */
break;
#endif
case 218:
if (test_runtime_script_path) free(test_runtime_script_path);
test_runtime_script_path = strdup(optarg);
break;
default:
ntop->getTrace()->traceEvent(
TRACE_WARNING, "Unknown option -%c: Ignored.", (char)optkey);
return (-1);
}
return (0);
}
/* ******************************************* */
int Prefs::checkOptions() {
#ifdef NTOPNG_PRO
if (print_maintenance) {
/* Disable tracing messages */
ntop->getTrace()->set_trace_level(0);
ntop->registerPrefs(this, true);
if (ntop->getPro()->check_maintenance_duration())
exit(0);
else
exit(1);
}
if (print_license) {
/* Disable tracing messages */
ntop->getTrace()->set_trace_level(0);
ntop->registerPrefs(this, true);
if (ntop->getPro()->check_license_validity())
exit(0);
else
exit(1);
}
#endif
if (print_version) {
#ifdef NTOPNG_PRO
char buf[128];
#endif
printVersionInformation();
#ifdef NTOPNG_PRO
ntop->getTrace()->set_trace_level((u_int8_t)1);
ntop->registerPrefs(this, true);
printf("Edition:\t%s\n", ntop->getPro()->get_edition());
printf("License Type:\t%s\n",
ntop->getPro()->get_license_type(buf, sizeof(buf)));
if (ntop->getPro()->demo_ends_at())
printf("Validity:\t%s\n",
ntop->getPro()->get_demo_expiration(buf, sizeof(buf)));
else
printf("Maintenance:\t%s\n",
ntop->getPro()->get_maintenance_expiration(buf, sizeof(buf)));
if (ntop->getPro()->get_encoded_license()[0] != '\0') {
char* enc_license = ntop->getPro()->get_encoded_license();
int i, len = strlen(enc_license);
for (i = 0; i < len; i += 69) {
char buff[70];
int clen = min((size_t)69, strlen(&enc_license[i]));
memcpy(buff, &enc_license[i], clen);
buff[clen] = '\0';
if (i == 0)
printf("License:\t%s\n", buff);
else
printf(" \t%s\n", buff);
}
}
if (ntop->getPro()->get_license()[0] != '\0')
printf("License Hash:\t%s\n", ntop->getPro()->get_license());
#endif
exit(0);
} else if (print_version_json) {
#if defined(NTOPNG_PRO) && (!defined(FORCE_VALID_LICENSE))
time_t license_until = (time_t)-1, maintenance_until = (time_t)-1;
char outbuf[256], edition[64];
snprintf(edition, sizeof(edition), "%s%s",
#ifndef HAVE_NEDGE
#ifdef NTOPNG_PRO
"Enterprise/Professional"
#else
"Community"
#endif
#else
"Edge"
#endif
,
#ifdef NTOPNG_PRO
ntop->getPro()->is_embedded_version() ? "/Embedded" :
#endif
"");
ntop->getTrace()->set_trace_level((u_int8_t)0);
ntop->registerPrefs(this, true);
if ((license_until = ntop->getPro()->demo_ends_at()) == 0)
license_until = (time_t)-1;
maintenance_until = ntop->getPro()->maintenance_ends_at();
printf("%s\n",
getLicenseJSON((char*)PACKAGE_VERSION, (char*)PACKAGE_OS, edition,
(char*)ntop->getPro()->get_system_id(), license_until,
maintenance_until, outbuf, sizeof(outbuf)));
exit(0);
#endif
}
if (install_dir) ntop->set_install_dir(install_dir);
free(data_dir);
data_dir = strdup(ntop->get_install_dir());
if (!pcap_dir) pcap_dir = strdup(ntop->get_working_dir());
if (!clickhouse_archive_dir)
clickhouse_archive_dir = strdup(ntop->get_working_dir());
docs_dir = ntop->getValidPath(docs_dir);
scripts_dir = ntop->getValidPath(scripts_dir);
callbacks_dir = ntop->getValidPath(callbacks_dir);
ntop->fixPath(pcap_dir);
ntop->fixPath(clickhouse_archive_dir);
#ifdef NTOPNG_PRO
pro_callbacks_dir = ntop->getValidPath(pro_callbacks_dir);
if (!pro_callbacks_dir) {
ntop->getTrace()->traceEvent(TRACE_ERROR,
"Unable to locate pro callbacks dir");
return (-1);
}
ntop->removeTrailingSlash(pro_callbacks_dir);
#endif
if (!data_dir) {
ntop->getTrace()->traceEvent(TRACE_ERROR, "Unable to locate data dir");
return (-1);
}
if (!docs_dir[0]) {
ntop->getTrace()->traceEvent(TRACE_ERROR, "Unable to locate docs dir");
return (-1);
}
if (!scripts_dir[0]) {
ntop->getTrace()->traceEvent(TRACE_ERROR, "Unable to locate scripts dir");
return (-1);
}
if (!callbacks_dir[0]) {
ntop->getTrace()->traceEvent(TRACE_ERROR, "Unable to locate callbacks dir");
return (-1);
}
if (!pcap_dir[0]) {
ntop->getTrace()->traceEvent(TRACE_ERROR, "Unable to locate pcap dir");
return (-1);
}
if (!clickhouse_archive_dir[0]) {
ntop->getTrace()->traceEvent(TRACE_ERROR,
"Unable to locate ClickHouse archive dir");
return (-1);
}
ntop->removeTrailingSlash(docs_dir);
ntop->removeTrailingSlash(scripts_dir);
ntop->removeTrailingSlash(callbacks_dir);
ntop->removeTrailingSlash(pcap_dir);
ntop->removeTrailingSlash(clickhouse_archive_dir);
if (http_binding_address1 == NULL)
http_binding_address1 = strdup(CONST_ANY_ADDRESS);
if (http_binding_address2 == NULL)
http_binding_address2 = strdup(CONST_ANY_ADDRESS);
if (https_binding_address1 == NULL)
https_binding_address1 = strdup(CONST_ANY_ADDRESS);
if (https_binding_address2 == NULL)
https_binding_address2 = strdup(CONST_ANY_ADDRESS);
if (strcmp(ntop->get_working_dir(), CONST_OLD_DEFAULT_DATA_DIR) == 0 &&
!is_user_set()) {
/* Using the old /var/tmp/ntopng with the default user:
* keep using 'nobody' to preserve backward compaitibility */
set_user(CONST_OLD_DEFAULT_NTOP_USER);
}
return (0);
}
/* ******************************************* */
int Prefs::loadFromCLI(int argc, char* argv[]) {
u_char c;
while ((c = getopt_long(
#ifdef WIN32
(int*(__cdecl*)(void))argc, (char* const**(__cdecl*)(void))argv,
#else
argc, argv,
#endif
"k:eg:hi:w:r:sg:m:n:p:qd:t:x:y:1:2:3:4:5:6:l:L:uv:zA:B:c:CD:E:F:"
"MN:G:I:O:Q:"
"S:TU:X:W:VZ:",
long_options, NULL)) != '?') {
if (c == 255) break;
setOption(c, optarg);
}
return (checkOptions());
}
/* ******************************************* */
int Prefs::loadFromFile(const char* path) {
char buffer[16384], *line, *key, *value;
u_int line_len, opt_name_len, num_line = 0;
FILE* fd;
const struct option* opt;
config_file_path = strdup(path);
fd = fopen(config_file_path, "r");
if (fd == NULL) {
ntop->getTrace()->traceEvent(TRACE_WARNING, "Config file %s not found",
config_file_path);
return (-1);
}
while (true) {
if (!(line = fgets(buffer, sizeof(buffer), fd))) break;
line = Utils::trim(line);
num_line++, value = NULL;
if ((line_len = strlen(line)) < 2 || line[0] == '#') continue;
if (!strncmp(line, "--", 2)) { /* long opt */
key = &line[2], line_len -= 2;
opt = long_options;
while (opt->name != NULL) {
opt_name_len = strlen(opt->name);
if (strncmp(key, opt->name, opt_name_len) == 0 &&
(line_len <= opt_name_len || key[opt_name_len] == '\0' ||
key[opt_name_len] == ' ' || key[opt_name_len] == '=')) {
if (line_len > opt_name_len) key[opt_name_len] = '\0';
if (line_len > opt_name_len + 1)
value = Utils::trim(&key[opt_name_len + 1]);
// ntop->getTrace()->traceEvent(TRACE_NORMAL, "key: %s value: %s",
// key, value);
setOption(opt->val, value);
break;
}
opt++;
}
} else if (line[0] == '-') { /* short opt */
key = &line[1], line_len--;
if (key[1] != ' ' && key[1] != '=' && key[1] != '\0') {
ntop->getTrace()->traceEvent(
TRACE_WARNING, "Skipping unrecognized line format %s:%u : %s",
config_file_path, num_line, buffer);
continue;
}
if (line_len > 1) key[1] = '\0';
if (line_len > 2)
value = Utils::trim(&key[2]);
else
value = NULL;
// ntop->getTrace()->traceEvent(TRACE_NORMAL, "key: %c value: %s", key[0],
// value);
setOption(key[0], value);
} else {
ntop->getTrace()->traceEvent(TRACE_WARNING,
"Skipping unrecognized line format %s:%u",
config_file_path, num_line);
continue;
}
}
fclose(fd);
return (checkOptions());
}
/* ******************************************* */
void Prefs::add_network_interface(char* name, char* description) {
if (num_interfaces < MAX_NUM_DEFINED_INTERFACES) {
char* real_name = NULL;
char* ifname = NULL;
int id;
if (strncmp(name, "-", 1) == 0) {
ifname = strdup("stdin");
} else {
/* check if this is an alias (linux altname)*/
real_name = Utils::get_real_name(name);
if (real_name)
ifname = real_name;
else
ifname = strdup(name);
}
id = Utils::ifname2id(ifname);
if (id >= 0) {
ifNames[num_interfaces].name = ifname;
ifNames[num_interfaces].alias = real_name ? strdup(name) : NULL;
ifNames[num_interfaces].description =
strdup(description ? description : name);
ifNames[num_interfaces].id = id;
num_interfaces++;
} else {
free(ifname);
ntop->getTrace()->traceEvent(
TRACE_ERROR, "Unable to get a valid id for %s, skipping.", name);
}
} else {
ntop->getTrace()->traceEvent(TRACE_ERROR,
"Too many interfaces (%d): discarded %s",
num_interfaces, name);
ntop->getTrace()->traceEvent(
TRACE_ERROR,
"Hint: reset redis (redis-cli flushall) and then start ntopng again");
}
}
/* ******************************************* */
void Prefs::add_default_interfaces() {
NetworkInterface* dummy = new (std::nothrow) NetworkInterface("dummy");
dummy->addAllAvailableInterfaces();
delete dummy;
};
/* *************************************** */
void Prefs::bind_http_to_address(const char* addr1, const char* addr2) {
if (http_binding_address1) free(http_binding_address1);
http_binding_address1 = strdup(addr1);
if (http_binding_address2) free(http_binding_address2);
http_binding_address2 = strdup(addr2);
}
void Prefs::bind_https_to_address(const char* addr1, const char* addr2) {
if (https_binding_address1) free(https_binding_address1);
https_binding_address1 = strdup(addr1);
if (https_binding_address2) free(https_binding_address2);
https_binding_address2 = strdup(addr2);
}
/* *************************************** */
void Prefs::lua(lua_State* vm) {
char buf[32];
#ifdef NTOPNG_PRO
char HTTP_stats_base_dir[MAX_PATH * 2];
#endif
lua_newtable(vm);
lua_push_bool_table_entry(vm, "is_dns_resolution_enabled_for_all_hosts",
resolve_all_host_ip);
lua_push_bool_table_entry(vm, "is_dns_resolution_enabled",
enable_dns_resolution);
lua_push_bool_table_entry(vm, "is_flow_deduplication_enabled",
isFlowDedupEnabled());
lua_push_bool_table_entry(vm, "is_autologout_enabled", enable_auto_logout);
lua_push_bool_table_entry(vm, "is_interface_name_only",
enable_interface_name_only);
lua_push_uint64_table_entry(vm, "http_port", http_port);
lua_push_str_table_entry(vm, "http_index_page", http_index_page);
lua_push_uint64_table_entry(vm, "max_num_hosts", max_num_hosts);
lua_push_uint64_table_entry(vm, "max_num_flows", max_num_flows);
lua_push_uint64_table_entry(vm, "flows_limit", MAX_NUM_ACTIVE_FLOWS);
lua_push_uint64_table_entry(vm, "hosts_limit", MAX_NUM_ACTIVE_HOSTS);
lua_push_bool_table_entry(vm, "is_dump_flows_enabled", do_dump_flows());
lua_push_bool_table_entry(vm, "is_dump_flows_runtime_enabled",
is_runtime_flows_dump_enabled());
#ifdef NTOPNG_PRO
lua_push_bool_table_entry(vm, "is_dump_flows_direct_enabled",
do_dump_flows_direct());
lua_push_int32_table_entry(vm, "max_aggregated_flows_upperbound",
max_aggregated_flows_upperbound);
lua_push_int32_table_entry(vm, "max_aggregated_flows_traffic_upperbound",
max_aggregated_flows_traffic_upperbound);
lua_push_bool_table_entry(vm, "data_archive_before_ttl_delete",
data_archive_before_ttl_delete);
#endif
lua_push_bool_table_entry(vm, "is_asn_mode_enabled", asn_mode_enabled);
if (clickhouse_dbname)
lua_push_str_table_entry(vm, "clickhouse_dbname", clickhouse_dbname);
if (clickhouse_ro_user && clickhouse_ro_user[0])
lua_push_str_table_entry(vm, "clickhouse_ro_user", clickhouse_ro_user);
lua_push_bool_table_entry(vm, "is_dump_flows_to_es_enabled",
do_dump_flows_on_es());
#if defined(HAVE_KAFKA) && defined(NTOPNG_PRO)
lua_push_bool_table_entry(vm, "is_dump_flows_to_kafka_enabled",
do_dump_flows_on_kafka());
#endif
lua_push_bool_table_entry(vm, "is_dump_flows_to_syslog_enabled",
do_dump_flows_on_syslog());
lua_push_int32_table_entry(vm, "host_to_scan_max_num_scans",
vs_max_num_scans);
lua_push_bool_table_entry(vm, "vs_slow_scan", vs_slow_scan);
lua_push_bool_table_entry(vm, "snmp_polling", snmp_polling);
lua_push_bool_table_entry(vm, "active_monitoring", do_active_monitoring());
lua_push_bool_table_entry(vm, "active_monitoring_pref",
get_active_monitoring_pref());
lua_push_bool_table_entry(vm, "network_discovery", network_discovery);
lua_push_bool_table_entry(vm, "starttls", starttls);
lua_push_bool_table_entry(vm, "dump_pcap_to_clickhouse",
dump_pcap_to_clickhouse);
lua_push_bool_table_entry(vm, "query_performance_log_enabled",
query_performance_log);
lua_push_bool_table_entry(vm, "tls_quic_hostnaming", tls_quic_hostnaming);
#ifdef HAVE_NEDGE
lua_push_bool_table_entry(vm, "is_mac_based_captive_portal",
mac_based_captive_portal);
#endif
lua_push_uint64_table_entry(vm, "http.port", get_http_port());
lua_push_str_table_entry(vm, "instance_name",
instance_name ? instance_name : (char*)"");
/* Command line options */
lua_push_bool_table_entry(vm, "has_cmdl_trace_lvl", has_cmdl_trace_lvl);
#ifdef NTOPNG_PRO
memset(HTTP_stats_base_dir, '\0', MAX_PATH);
strncat(HTTP_stats_base_dir, (const char*)ntop->get_working_dir(), MAX_PATH);
strncat(HTTP_stats_base_dir, "/httpstats/", MAX_PATH);
lua_push_str_table_entry(vm, "http_stats_base_dir", HTTP_stats_base_dir);
#endif
lua_push_uint64_table_entry(vm, "auth_session_duration",
get_auth_session_duration());
lua_push_bool_table_entry(vm, "auth_session_midnight_expiration",
get_auth_session_midnight_expiration());
lua_push_bool_table_entry(vm, "fingerprint_stats",
areFingerprintStatsEnabled());
#ifndef HAVE_NEDGE
lua_push_uint64_table_entry(vm, "use_mac_in_flow_key",
useMacAddressInFlowKey());
#endif
lua_push_uint64_table_entry(vm, "housekeeping_frequency",
housekeeping_frequency);
lua_push_uint64_table_entry(vm, "local_host_cache_duration",
local_host_cache_duration);
lua_push_uint64_table_entry(vm, "local_host_max_idle", local_host_max_idle);
lua_push_uint64_table_entry(vm, "non_local_host_max_idle",
non_local_host_max_idle);
lua_push_uint64_table_entry(vm, "flow_max_idle", pkt_ifaces_flow_max_idle);
if (enable_active_local_hosts_cache)
lua_push_uint64_table_entry(vm, "active_local_hosts_cache_interval",
active_local_hosts_cache_interval);
lua_push_uint64_table_entry(vm, "intf_rrd_raw_days", intf_rrd_raw_days);
lua_push_uint64_table_entry(vm, "intf_rrd_1min_days", intf_rrd_1min_days);
lua_push_uint64_table_entry(vm, "intf_rrd_1h_days", intf_rrd_1h_days);
lua_push_uint64_table_entry(vm, "intf_rrd_1d_days", intf_rrd_1d_days);
lua_push_uint64_table_entry(vm, "other_rrd_raw_days", other_rrd_raw_days);
lua_push_uint64_table_entry(vm, "other_rrd_1min_days", other_rrd_1min_days);
lua_push_uint64_table_entry(vm, "other_rrd_1h_days", other_rrd_1h_days);
lua_push_uint64_table_entry(vm, "other_rrd_1d_days", other_rrd_1d_days);
lua_push_bool_table_entry(vm, "are_top_talkers_enabled", enable_top_talkers);
lua_push_bool_table_entry(vm, "sites_collection", enable_sites_collection);
lua_push_bool_table_entry(vm, "dns_cache", enable_dns_cache);
lua_push_bool_table_entry(vm, "flow_table_time", flow_table_time);
lua_push_bool_table_entry(vm, "flow_table_probe_order",
flow_table_probe_order);
lua_push_bool_table_entry(vm, "enable_full_stats", full_stats_enabled);
lua_push_bool_table_entry(vm, "is_active_local_hosts_cache_enabled",
enable_active_local_hosts_cache);
lua_push_bool_table_entry(vm, "is_tiny_flows_export_enabled",
enable_tiny_flows_export);
lua_push_uint64_table_entry(vm, "max_entity_alerts", max_entity_alerts);
lua_push_uint64_table_entry(vm, "max_num_secs_before_delete_alert",
max_num_secs_before_delete_alert);
lua_push_uint64_table_entry(vm, "alert_page_refresh_rate",
alert_page_refresh_rate);
lua_push_bool_table_entry(vm, "is_observation_points_rrd_creation_enabled",
enable_observation_points_rrd_creation);
lua_push_bool_table_entry(vm, "is_intranet_traffic_rrd_creation_enabled",
enable_intranet_traffic_rrd_creation);
lua_push_bool_table_entry(vm, "is_flow_device_port_rrd_creation_enabled",
enable_flow_device_port_rrd_creation);
lua_push_bool_table_entry(vm, "are_alerts_enabled", !disable_alerts);
lua_push_bool_table_entry(vm, "use_host_pools_for_local",
use_host_pools_for_local);
lua_push_bool_table_entry(vm, "is_arp_matrix_generation_enabled",
is_arp_matrix_generation_enabled());
lua_push_bool_table_entry(vm, "is_users_login_enabled", enable_users_login);
lua_push_uint64_table_entry(vm, "dump_frequency", dump_frequency);
lua_push_uint64_table_entry(vm, "max_num_packets_per_tiny_flow",
max_num_packets_per_tiny_flow);
lua_push_uint64_table_entry(vm, "max_num_bytes_per_tiny_flow",
max_num_bytes_per_tiny_flow);
lua_push_uint64_table_entry(vm, "max_extracted_pcap_bytes",
max_extracted_pcap_bytes);
lua_push_uint64_table_entry(vm, "max_extracted_pcap_files",
max_extracted_pcap_files);
lua_push_uint64_table_entry(vm, "ewma_alpha_percent", ewma_alpha_percent);
lua_push_uint64_table_entry(vm, "behaviour_analysis_learning_period",
behaviour_analysis_learning_period);
lua_push_uint64_table_entry(vm, "iec60870_learning_period",
iec60870_learning_period);
lua_push_uint64_table_entry(vm, "modbus_learning_period",
modbus_learning_period);
lua_push_uint64_table_entry(vm, "s7comm_learning_period",
s7comm_learning_period);
lua_push_uint64_table_entry(vm, "mac_address_cache_duration",
mac_address_cache_duration);
lua_push_bool_table_entry(vm, "enable_flow_swap_heuristic",
enable_flow_swap_heuristic);
lua_push_bool_table_entry(vm, "enable_assets_log", enable_assets_log);
lua_push_uint64_table_entry(vm, "devices_learning_period",
devices_learning_period);
lua_push_uint64_table_entry(vm, "host_port_learning_period",
host_port_learning_period);
lua_push_str_table_entry(
vm, "safe_search_dns",
Utils::intoaV4(ntohl(safe_search_dns_ip), buf, sizeof(buf)));
lua_push_str_table_entry(
vm, "global_dns",
global_primary_dns_ip
? Utils::intoaV4(ntohl(global_primary_dns_ip), buf, sizeof(buf))
: (char*)"");
lua_push_str_table_entry(
vm, "secondary_dns",
global_secondary_dns_ip
? Utils::intoaV4(ntohl(global_secondary_dns_ip), buf, sizeof(buf))
: (char*)"");
lua_push_bool_table_entry(vm, "is_captive_portal_enabled",
enable_captive_portal);
lua_push_bool_table_entry(vm, "is_informative_captive_portal_enabled",
enable_informative_captive_portal);
lua_push_bool_table_entry(vm, "is_external_auth_captive_portal_enabled",
enable_external_auth_captive_portal);
lua_push_uint64_table_entry(vm, "max_ui_strlen", max_ui_strlen);
lua_push_str_table_entry(vm, "config_file",
config_file_path ? config_file_path : (char*)"");
lua_push_str_table_entry(vm, "ndpi_proto_file",
ndpi_proto_path ? ndpi_proto_path : (char*)"");
lua_push_str_table_entry(vm, "cpu_affinity",
cpu_affinity ? cpu_affinity : (char*)"");
lua_push_str_table_entry(vm, "other_cpu_affinity",
other_cpu_affinity ? other_cpu_affinity : (char*)"");
lua_push_str_table_entry(vm, "user", change_user ? user : (char*)"");
lua_push_str_table_entry(vm, "capture_direction",
Utils::captureDirection2Str(captureDirection));
lua_push_str_table_entry(vm, "message_broker_url",
message_broker_url ? message_broker_url : "");
lua_push_str_table_entry(vm, "message_broker",
message_broker ? message_broker : "");
lua_push_bool_table_entry(vm, "toggle_message_broker",
message_broker_enabled);
lua_push_str_table_entry(vm, "zmq_publish_events_url",
zmq_publish_events_url);
lua_push_bool_table_entry(vm, "limited_resources_mode",
limited_resources_mode);
lua_push_str_table_entry(vm, "split_ts_direction",
split_ts_direction ? "rx_tx" : "total");
}
/* *************************************** */
void Prefs::refreshHostsAlertsPrefs() {
char rsp[32];
if (ntop->getRedis()->hashGet(
(char*)CONST_RUNTIME_PREFS_HOSTS_ALERTS_CONFIG,
(char*)CONST_HOST_FLOW_ATTACKER_ALERT_THRESHOLD_KEY, rsp,
sizeof(rsp)) == 0)
attacker_max_num_flows_per_sec = atol(rsp);
else
attacker_max_num_flows_per_sec = CONST_MAX_NEW_FLOWS_SECOND;
if (ntop->getRedis()->hashGet(
(char*)CONST_RUNTIME_PREFS_HOSTS_ALERTS_CONFIG,
(char*)CONST_HOST_FLOW_VICTIM_ALERT_THRESHOLD_KEY, rsp,
sizeof(rsp)) == 0)
victim_max_num_flows_per_sec = atol(rsp);
else
victim_max_num_flows_per_sec = CONST_MAX_NEW_FLOWS_SECOND;
if (ntop->getRedis()->hashGet(
(char*)CONST_RUNTIME_PREFS_HOSTS_ALERTS_CONFIG,
(char*)CONST_HOST_SYN_ATTACKER_ALERT_THRESHOLD_KEY, rsp,
sizeof(rsp)) == 0)
attacker_max_num_syn_per_sec = atol(rsp);
else
attacker_max_num_syn_per_sec = CONST_MAX_NUM_SYN_PER_SECOND;
if (ntop->getRedis()->hashGet(
(char*)CONST_RUNTIME_PREFS_HOSTS_ALERTS_CONFIG,
(char*)CONST_HOST_SYN_VICTIM_ALERT_THRESHOLD_KEY, rsp,
sizeof(rsp)) == 0)
victim_max_num_syn_per_sec = atol(rsp);
else
victim_max_num_syn_per_sec = CONST_MAX_NUM_SYN_PER_SECOND;
}
/* *************************************** */
void Prefs::refreshDeviceProtocolsPolicyPref() {
device_protocol_policies_enabled = getDefaultBoolPrefsValue(
CONST_PREFS_ENABLE_DEVICE_PROTOCOL_POLICIES, false);
}
/* *************************************** */
void Prefs::refreshDbDumpPrefs() {
enable_runtime_flows_dump =
getDefaultBoolPrefsValue(CONST_PREFS_ENABLE_RUNTIME_FLOWS_DUMP, true);
}
/* *************************************** */
void Prefs::resetDeferredInterfacesToRegister() {
int num = 0;
ntop->getTrace()->traceEvent(TRACE_ERROR, "Reset interfaces");
for (int i = 0; i < num_deferred_interfaces_to_register; i++) {
/* Reset network interfaces, excluding event interfaces like syslog/zmq */
if (deferred_interfaces_to_register[i] != NULL) {
if (strstr(deferred_interfaces_to_register[i], "syslog://") ||
strstr(deferred_interfaces_to_register[i], "tcp://"))
deferred_interfaces_to_register[num++] =
deferred_interfaces_to_register[i];
else
free(deferred_interfaces_to_register[i]);
}
}
num_deferred_interfaces_to_register = num;
}
/* *************************************** */
bool Prefs::addDeferredInterfaceToRegister(const char* ifname) {
if (num_deferred_interfaces_to_register < UNLIMITED_NUM_INTERFACES) {
bool isView = strstr(ifname, "view:");
if (isView) {
/* View interface only available with pro version */
#ifdef NTOPNG_PRO
deferred_interfaces_to_register[num_deferred_interfaces_to_register] =
strdup(ifname);
num_deferred_interfaces_to_register++;
return true;
#endif
} else if (!isView) {
deferred_interfaces_to_register[num_deferred_interfaces_to_register] =
strdup(ifname);
num_deferred_interfaces_to_register++;
return true;
}
return true; // Simply ignore the -i view option
} else {
return false;
}
}
/* *************************************** */
void Prefs::registerNetworkInterfaces() {
for (int i = 0; i < num_deferred_interfaces_to_register; i++) {
if (deferred_interfaces_to_register[i] != NULL) {
add_network_interface(deferred_interfaces_to_register[i], NULL);
free(deferred_interfaces_to_register[i]);
deferred_interfaces_to_register[i] = NULL;
}
}
}
/* *************************************** */
bool Prefs::is_pro_edition() {
return
#ifdef NTOPNG_PRO
ntop->getPro()->has_valid_license()
#else
false
#endif
;
}
/* *************************************** */
bool Prefs::is_nanalyst_available() {
return
#ifdef NTOPNG_PRO
ntop->getPro()->is_nanalyst_available() && is_enterprise_m_edition()
#else
false
#endif
;
}
/* *************************************** */
bool Prefs::is_enterprise_m_edition() {
return
#ifdef NTOPNG_PRO
ntop->getPro()->has_valid_enterprise_m_license() ||
is_enterprise_l_edition() /* L or higher */
#else
false
#endif
;
}
/* *************************************** */
bool Prefs::is_enterprise_l_edition() {
return
#ifdef NTOPNG_PRO
ntop->getPro()->has_valid_enterprise_l_license() ||
is_enterprise_xl_edition() /* XL or higher */
#else
false
#endif
;
}
/* *************************************** */
bool Prefs::is_enterprise_xl_edition() {
return
#ifdef NTOPNG_PRO
ntop->getPro()->has_valid_enterprise_xl_license() ||
is_enterprise_xxl_edition() /* XXL or higher */
#else
false
#endif
;
}
/* *************************************** */
bool Prefs::is_enterprise_xxl_edition() {
return
#ifdef NTOPNG_PRO
ntop->getPro()->has_valid_enterprise_xxl_license()
#else
false
#endif
;
}
/* *************************************** */
bool Prefs::is_enterprise_xxxl_edition() {
return
#ifdef NTOPNG_PRO
ntop->getPro()->has_valid_enterprise_xxxl_license()
#else
false
#endif
;
}
/* *************************************** */
bool Prefs::is_nedge_pro_edition() {
return
#ifdef HAVE_NEDGE
ntop->getPro()->has_valid_license()
#else
false
#endif
;
}
/* *************************************** */
bool Prefs::is_nedge_enterprise_edition() {
return
#ifdef HAVE_NEDGE
ntop->getPro()->has_valid_nedge_enterprise_license()
#else
false
#endif
;
}
/* *************************************** */
bool Prefs::is_embedded_edition() {
return
#if defined(NTOPNG_PRO) || defined(HAVE_NEDGE)
ntop->getPro()->is_embedded_version()
#else
false
#endif
;
}
/* *************************************** */
void Prefs::set_routing_mode(bool enabled) {
#ifdef HAVE_NEDGE
routing_mode_enabled =
enabled && ntop->getPro()->has_valid_nedge_enterprise_license();
#else
routing_mode_enabled = false;
#endif
}
/* *************************************** */
time_t Prefs::pro_edition_demo_ends_at() {
return
#ifdef NTOPNG_PRO
ntop->getPro()->demo_ends_at()
#else
0
#endif
;
}
/* *************************************** */
void Prefs::validate() {
/* Perform here post-initialization validations */
if (is_enterprise_m_edition() /* M or higher */
|| is_nedge_enterprise_edition()) {
; /* All good */
} else if (dump_flows_on_clickhouse) {
ntop->getTrace()->traceEvent(
TRACE_WARNING, "-F clickhouse is available only on Enterprise");
dump_flows_on_clickhouse = false;
}
if (timeseries_driver == ts_driver_clickhouse && !do_dump_flows_on_clickhouse()) {
ntop->getTrace()->traceEvent(TRACE_WARNING, "ClickHouse timeseries enabled in preferences but ClickHouse is not "
"available (-F clickhouse not set): disabling ClickHouse timeseries, falling back to RRD");
timeseries_driver = ts_driver_rrd;
ntop->getRedis()->set((char *)CONST_RUNTIME_PREFS_TS_DRIVER, (char *)"rrd");
}
/* Use max num flows as upper limit for flows/hosts cache size to avoid
* configuration mistakes */
/* Note: check the size here, after detecting the model (and setting the
* corresponding limits) */
u_int32_t limit = MAX_NUM_ACTIVE_FLOWS * 2;
max_num_hosts = max_val(min_val(max_num_hosts, limit), 1024);
max_num_flows = max_val(min_val(max_num_flows, limit), 1024);
}
/* *************************************** */
#ifdef HAVE_NEDGE
bool Prefs::isInformativeCaptivePortalEnabled() const {
return (enable_informative_captive_portal && !enable_vlan_trunk_bridge);
}
/* *************************************** */
const char* Prefs::getCaptivePortalUrl() {
if (isInformativeCaptivePortalEnabled()) {
return CAPTIVE_PORTAL_INFO_URL;
} else {
return CAPTIVE_PORTAL_URL;
}
}
/* *************************************** */
bool Prefs::isExternalAuthCaptivePortalEnabled() const {
return (enable_external_auth_captive_portal);
}
#endif
/* *************************************** */
void Prefs::setIEC104AllowedTypeIDs(const char* type_ids) {
char *p, *buf, *tmp;
if (!type_ids) return;
if ((strcmp(type_ids, "-1") == 0))
iec104_allowed_typeids[0] = (u_int64_t)-1,
iec104_allowed_typeids[1] = (u_int64_t)-1; /* All */
else if ((buf = strdup(type_ids))) {
iec104_allowed_typeids[0] = (u_int64_t)0,
iec104_allowed_typeids[1] = (u_int64_t)0;
p = strtok_r(buf, ",", &tmp);
while (p != NULL) {
int type_id = atoi(p);
// ntop->getTrace()->traceEvent(TRACE_WARNING, "-> %d", type_id);
if (type_id < 64)
iec104_allowed_typeids[0] |= ((u_int64_t)1 << type_id);
else if (type_id < 128)
iec104_allowed_typeids[1] |= ((u_int64_t)1 << (type_id - 64));
p = strtok_r(NULL, ",", &tmp);
}
free(buf);
}
}
/* *************************************** */
#ifdef NTOPNG_PRO
void Prefs::setModbusAllowedFunctionCodes(const char* function_codes) {
char *p, *buf, *tmp;
if (!function_codes) return;
if ((strcmp(function_codes, "-1") == 0)) {
if (modbus_allowed_function_codes != NULL) {
ndpi_bitmap_free(modbus_allowed_function_codes);
modbus_allowed_function_codes = NULL;
}
} else if ((buf = strdup(function_codes))) {
if (modbus_allowed_function_codes == NULL) {
if ((modbus_allowed_function_codes = ndpi_bitmap_alloc()) == NULL)
ntop->getTrace()->traceEvent(TRACE_WARNING,
"Unable to allocate bitmap memory");
}
if (modbus_allowed_function_codes) {
ndpi_bitmap_free(modbus_allowed_function_codes);
if ((modbus_allowed_function_codes = ndpi_bitmap_alloc()) != NULL) {
p = strtok_r(buf, ",", &tmp);
while (p != NULL) {
int f_code = atoi(p);
ndpi_bitmap_set(modbus_allowed_function_codes, f_code);
p = strtok_r(NULL, ",", &tmp);
}
}
}
free(buf);
}
}
/* *************************************** */
void Prefs::setS7CommAllowedFunctionCodes(const char* function_codes) {
char *p, *buf, *tmp;
if (!function_codes) return;
if ((strcmp(function_codes, "-1") == 0)) {
if (s7comm_allowed_function_codes != NULL) {
ndpi_bitmap_free(s7comm_allowed_function_codes);
s7comm_allowed_function_codes = NULL;
}
} else if ((buf = strdup(function_codes))) {
if (s7comm_allowed_function_codes == NULL) {
if ((s7comm_allowed_function_codes = ndpi_bitmap_alloc()) == NULL)
ntop->getTrace()->traceEvent(TRACE_WARNING,
"Unable to allocate bitmap memory");
}
if (s7comm_allowed_function_codes) {
ndpi_bitmap_free(s7comm_allowed_function_codes);
if ((s7comm_allowed_function_codes = ndpi_bitmap_alloc()) != NULL) {
p = strtok_r(buf, ",", &tmp);
while (p != NULL) {
int f_code = atoi(p);
ndpi_bitmap_set(s7comm_allowed_function_codes, f_code);
p = strtok_r(NULL, ",", &tmp);
}
}
}
free(buf);
}
}
#endif
/* *************************************** */
void Prefs::reloadServersConfiguration() {
ntop->getTrace()->traceEvent(TRACE_NORMAL, "Reloading servers configurations");
gateway->reloadServerConfiguration((char*)CONST_GATEWAY_CONFIGURATION_REDIS_KEY);
dns_servers->reloadServerConfiguration((char*)CONST_DNS_SERVER_CONFIGURATION_REDIS_KEY);
ntp_servers->reloadServerConfiguration((char*)CONST_NTP_SERVER_CONFIGURATION_REDIS_KEY);
ntop->getTrace()->traceEvent(TRACE_NORMAL, "Reloading DHCP servers...");
dhcp_servers->reloadServerConfiguration((char*)CONST_DHCP_SERVER_CONFIGURATION_REDIS_KEY);
ntop->getTrace()->traceEvent(TRACE_NORMAL, "Reloading DHCP servers done");
smtp_servers->reloadServerConfiguration((char*)CONST_SMTP_SERVER_CONFIGURATION_REDIS_KEY);
}
/* *************************************** */
void Prefs::reloadASNConfiguration() {
customer_asn->reloadASNConfiguration(
(char*)CONST_CUSTOMER_ASN_CONFIGURATION_REDIS_KEY);
sub_customer_asn->reloadASNConfiguration(
(char*)CONST_SUB_CUSTOMER_ASN_CONFIGURATION_REDIS_KEY);
remote_asn->reloadASNConfiguration(
(char*)CONST_REMOTE_ASN_CONFIGURATION_REDIS_KEY);
/*
customer_asn->debugPrint("customer_asn");
sub_customer_asn->debugPrint("sub_customer_asn");
remote_asn->debugPrint("remote_asn");
*/
}
/* *************************************** */
#ifdef NTOPNG_PRO
bool Prefs::reloadNetworksPolicyConfiguration() {
AddressTree* new_tree = NULL;
new_tree = new (std::nothrow) AddressTree;
if (new_tree == NULL) {
ntop->getTrace()->traceEvent(TRACE_ERROR, "Unable to Load Configuration");
return false;
}
/* NetworkPolicyCheck */
bool res =
loadPolicyConfiguration(
new_tree, (char*)CONST_LOCAL_DEVICES_NETWORKS_CONFIGURATION_REDIS_KEY,
restricted_host_network_id) &&
loadPolicyConfiguration(
new_tree,
(char*)CONST_CORPORATE_DEVICES_NETWORKS_CONFIGURATION_REDIS_KEY,
core_host_network_id) &&
loadPolicyConfiguration(
new_tree, (char*)CONST_WHITELISTED_NETWORKS_CONFIGURATION_REDIS_KEY,
whitelisted_host_network_id);
if (new_tree && res) {
if (networks_policy_configuration) {
if (networks_policy_configuration_shadow)
delete networks_policy_configuration_shadow;
networks_policy_configuration_shadow = networks_policy_configuration;
}
networks_policy_configuration = new_tree;
}
return res;
}
/* *************************************** */
bool Prefs::loadPolicyConfiguration(AddressTree* tree, char* key,
NetworkConfigurationId id) {
char* rsp = NULL;
Redis* redis = ntop->getRedis();
u_int actual_len = redis->len(key);
if ((actual_len++ /* ++ for the \0 */ > 0) &&
((rsp = (char*)malloc(actual_len)) != NULL)) {
redis->get(key, rsp, actual_len);
/* Get a list of server separated by commas */
std::string ipStr(rsp);
char charToRemove = ' ';
/* Remove the spaces between the IPs */
ipStr.erase(std::remove(ipStr.begin(), ipStr.end(), charToRemove),
ipStr.end());
/* Now iterate the string */
std::stringstream ipList(ipStr);
std::string ip;
while (std::getline(ipList, ip, ',')) {
if (!tree->addAddress(ip.c_str(), id)) {
ntop->getTrace()->traceEvent(
TRACE_WARNING,
"Unable to add tree node in Policy Configuration [Network: %s]",
(char*)ip.c_str());
return false;
}
ntop->getTrace()->traceEvent(TRACE_DEBUG,
"Added [Network: %s] to Redis %s list",
(char*)ip.c_str(), key);
}
if (rsp) free(rsp);
}
return true;
}
#endif
/* *************************************** */
#ifdef NTOPNG_PRO
AddressTree* Prefs::getNetworksPolicyConfiguration() {
return networks_policy_configuration;
}
#endif
/* *************************************** */
bool Prefs::isGateway(IpAddress* ip, u_int16_t vlan_id) {
return (gateway->findAddress(ip, vlan_id));
}
/* *************************************** */
bool Prefs::isDNSServer(IpAddress* ip, u_int16_t vlan_id) {
return (dns_servers->findAddress(ip, vlan_id));
}
/* *************************************** */
bool Prefs::isNTPServer(IpAddress* ip, u_int16_t vlan_id) {
return (ntp_servers->findAddress(ip, vlan_id));
}
/* *************************************** */
bool Prefs::isDHCPServer(IpAddress* ip, u_int16_t vlan_id) {
return (dhcp_servers->findAddress(ip, vlan_id));
}
/* *************************************** */
bool Prefs::isSMTPServer(IpAddress* ip, u_int16_t vlan_id) {
return (smtp_servers->findAddress(ip, vlan_id));
}
/* *************************************** */
bool Prefs::isCustomerASN(u_int32_t asn) {
return (customer_asn->findASN(asn));
}
/* *************************************** */
bool Prefs::isSubCustomerASN(u_int32_t asn) {
return (sub_customer_asn->findASN(asn));
}
/* *************************************** */
bool Prefs::isRemoteASN(u_int32_t asn) { return (remote_asn->findASN(asn)); }
/* *************************************** */
void Prefs::setCustomGeoIPDir(char* d) {
if (d != NULL) {
if (custom_geoip_dir) free(custom_geoip_dir);
custom_geoip_dir = strdup(d);
}
}
/* *************************************** */
void Prefs::set_influx_internal_db_name(char* internal_name) {
if (internal_name && internal_name[0] != '\0') {
if (influx_internal_db_name) free(influx_internal_db_name);
influx_internal_db_name = strdup(internal_name);
}
};
/* *************************************** */