1 /*
2     pmacct (Promiscuous mode IP Accounting package)
3     pmacct is Copyright (C) 2003-2020 by Paolo Lucente
4 */
5 
6 /*
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 
22 /* includes */
23 #include "pmacct.h"
24 #include "plugin_hooks.h"
25 #include "pmacct-data.h"
26 #include "pkt_handlers.h"
27 
28 static const struct _dictionary_line dictionary[] = {
29   {"debug", cfg_key_debug},
30   {"debug_internal_msg", cfg_key_debug_internal_msg},
31   {"syslog", cfg_key_syslog},
32   {"logfile", cfg_key_logfile},
33   {"pidfile", cfg_key_pidfile},
34   {"daemonize", cfg_key_daemonize},
35   {"aggregate", cfg_key_aggregate},
36   {"aggregate_primitives", cfg_key_aggregate_primitives},
37   {"cluster_name", cfg_key_cluster_name},
38   {"cluster_id", cfg_key_cluster_id},
39   {"redis_host", cfg_key_redis_host},
40   {"redis_db", cfg_key_redis_db},
41   {"snaplen", cfg_key_snaplen},
42   {"aggregate_filter", cfg_key_aggregate_filter},
43   {"promisc", cfg_key_promisc},
44   {"pcap_filter", cfg_key_pcap_filter},
45   {"pcap_protocol", cfg_key_pcap_protocol},
46   {"pcap_savefile", cfg_key_pcap_savefile},
47   {"pcap_savefile_wait", cfg_key_pcap_savefile_wait},
48   {"pcap_savefile_delay", cfg_key_pcap_savefile_delay},
49   {"pcap_savefile_replay", cfg_key_pcap_savefile_replay},
50   {"pcap_interface", cfg_key_pcap_interface},
51   {"pcap_interface_wait", cfg_key_pcap_interface_wait},
52   {"pcap_direction", cfg_key_pcap_direction},
53   {"pcap_ifindex", cfg_key_pcap_ifindex},
54   {"pcap_interfaces_map", cfg_key_pcap_interfaces_map},
55   {"core_proc_name", cfg_key_proc_name},
56   {"proc_priority", cfg_key_proc_priority},
57   {"pmacctd_as", cfg_key_nfacctd_as_new},
58   {"uacctd_as", cfg_key_nfacctd_as_new},
59   {"pmacctd_net", cfg_key_nfacctd_net},
60   {"uacctd_net", cfg_key_nfacctd_net},
61   {"use_ip_next_hop", cfg_key_use_ip_next_hop},
62   {"decode_arista_trailer", cfg_key_decode_arista_trailer},
63   {"thread_stack", cfg_key_thread_stack},
64   {"plugins", NULL},
65   {"plugin_pipe_size", cfg_key_plugin_pipe_size},
66   {"plugin_buffer_size", cfg_key_plugin_buffer_size},
67   {"plugin_pipe_zmq", cfg_key_plugin_pipe_zmq},
68   {"plugin_pipe_zmq_retry", cfg_key_plugin_pipe_zmq_retry},
69   {"plugin_pipe_zmq_profile", cfg_key_plugin_pipe_zmq_profile},
70   {"plugin_pipe_zmq_hwm", cfg_key_plugin_pipe_zmq_hwm},
71   {"plugin_exit_any", cfg_key_plugin_exit_any},
72   {"interface", cfg_key_pcap_interface}, 		/* Legacy key */
73   {"interface_wait", cfg_key_pcap_interface_wait},	/* Legacy key */
74   {"files_umask", cfg_key_files_umask},
75   {"files_uid", cfg_key_files_uid},
76   {"files_gid", cfg_key_files_gid},
77   {"networks_mask", cfg_key_networks_mask},
78   {"networks_file", cfg_key_networks_file},
79   {"networks_file_filter", cfg_key_networks_file_filter},
80   {"networks_file_no_lpm", cfg_key_networks_file_no_lpm},
81   {"networks_no_mask_if_zero", cfg_key_networks_no_mask_if_zero},
82   {"networks_cache_entries", cfg_key_networks_cache_entries},
83   {"ports_file", cfg_key_ports_file},
84   {"timestamps_rfc3339", cfg_key_timestamps_rfc3339},
85   {"timestamps_utc", cfg_key_timestamps_utc},
86   {"timestamps_secs", cfg_key_timestamps_secs},
87   {"timestamps_since_epoch", cfg_key_timestamps_since_epoch},
88   {"imt_path", cfg_key_imt_path},
89   {"imt_passwd", cfg_key_imt_passwd},
90   {"imt_buckets", cfg_key_imt_buckets},
91   {"imt_mem_pools_number", cfg_key_imt_mem_pools_number},
92   {"imt_mem_pools_size", cfg_key_imt_mem_pools_size},
93   {"sql_db", cfg_key_sql_db},
94   {"sql_table", cfg_key_sql_table},
95   {"sql_table_schema", cfg_key_sql_table_schema},
96   {"sql_table_version", cfg_key_sql_table_version},
97   {"sql_table_type", cfg_key_sql_table_type},
98   {"sql_conn_ca_file", cfg_key_sql_conn_ca_file},
99   {"sql_host", cfg_key_sql_host},
100   {"sql_port", cfg_key_sql_port},
101   {"sql_data", cfg_key_sql_data},
102   {"sql_user", cfg_key_sql_user},
103   {"sql_passwd", cfg_key_sql_passwd},
104   {"sql_refresh_time", cfg_key_sql_refresh_time},
105   {"sql_startup_delay", cfg_key_sql_startup_delay},
106   {"sql_optimize_clauses", cfg_key_sql_optimize_clauses},
107   {"sql_history", cfg_key_sql_history},
108   {"sql_history_offset", cfg_key_sql_history_offset},
109   {"sql_history_roundoff", cfg_key_sql_history_roundoff},
110   {"sql_history_since_epoch", cfg_key_timestamps_since_epoch}, /* Legacy key */
111   {"sql_backup_host", cfg_key_sql_recovery_backup_host}, /* Legacy feature; to be obsoleted */
112   {"sql_recovery_backup_host", cfg_key_sql_recovery_backup_host},
113   {"sql_delimiter", cfg_key_sql_delimiter},
114   {"sql_max_writers", cfg_key_dump_max_writers},
115   {"sql_trigger_exec", cfg_key_sql_trigger_exec},
116   {"sql_trigger_time", cfg_key_sql_trigger_time},
117   {"sql_cache_entries", cfg_key_sql_cache_entries},
118   {"sql_dont_try_update", cfg_key_sql_dont_try_update},
119   {"sql_preprocess", cfg_key_sql_preprocess},
120   {"sql_preprocess_type", cfg_key_sql_preprocess_type},
121   {"sql_multi_values", cfg_key_sql_multi_values},
122   {"sql_locking_style", cfg_key_sql_locking_style},
123   {"sql_use_copy", cfg_key_sql_use_copy},
124   {"sql_num_protos", cfg_key_num_protos},
125   {"sql_num_hosts", cfg_key_num_hosts},
126   {"print_refresh_time", cfg_key_sql_refresh_time},
127   {"print_cache_entries", cfg_key_print_cache_entries},
128   {"print_markers", cfg_key_print_markers},
129   {"print_output", cfg_key_print_output},
130   {"print_output_file", cfg_key_print_output_file},
131   {"print_output_file_append", cfg_key_print_output_file_append},
132   {"print_output_lock_file", cfg_key_print_output_lock_file},
133   {"print_output_separator", cfg_key_print_output_separator},
134   {"print_output_custom_lib", cfg_key_print_output_custom_lib},
135   {"print_output_custom_cfg_file", cfg_key_print_output_custom_cfg_file},
136   {"print_write_empty_file", cfg_key_print_write_empty_file},
137   {"print_latest_file", cfg_key_print_latest_file},
138   {"print_num_protos", cfg_key_num_protos},
139   {"print_trigger_exec", cfg_key_sql_trigger_exec},
140   {"print_history", cfg_key_sql_history},
141   {"print_history_offset", cfg_key_sql_history_offset},
142   {"print_history_roundoff", cfg_key_sql_history_roundoff},
143   {"print_max_writers", cfg_key_dump_max_writers},
144   {"print_preprocess", cfg_key_sql_preprocess},
145   {"print_preprocess_type", cfg_key_sql_preprocess_type},
146   {"print_startup_delay", cfg_key_sql_startup_delay},
147   {"mongo_host", cfg_key_sql_host},
148   {"mongo_table", cfg_key_sql_table},
149   {"mongo_user", cfg_key_sql_user},
150   {"mongo_passwd", cfg_key_sql_passwd},
151   {"mongo_refresh_time", cfg_key_sql_refresh_time},
152   {"mongo_cache_entries", cfg_key_print_cache_entries},
153   {"mongo_history", cfg_key_sql_history},
154   {"mongo_history_offset", cfg_key_sql_history_offset},
155   {"mongo_history_roundoff", cfg_key_sql_history_roundoff},
156   {"mongo_time_roundoff", cfg_key_sql_history_roundoff},
157   {"mongo_trigger_exec", cfg_key_sql_trigger_exec},
158   {"mongo_insert_batch", cfg_key_mongo_insert_batch},
159   {"mongo_indexes_file", cfg_key_sql_table_schema},
160   {"mongo_max_writers", cfg_key_dump_max_writers},
161   {"mongo_preprocess", cfg_key_sql_preprocess},
162   {"mongo_preprocess_type", cfg_key_sql_preprocess_type},
163   {"mongo_startup_delay", cfg_key_sql_startup_delay},
164   {"mongo_num_protos", cfg_key_num_protos},
165   {"avro_buffer_size", cfg_key_avro_buffer_size},
166   {"avro_schema_output_file", cfg_key_avro_schema_file}, /* to be discontinued */
167   {"avro_schema_file", cfg_key_avro_schema_file},
168   {"amqp_refresh_time", cfg_key_sql_refresh_time},
169   {"amqp_history", cfg_key_sql_history},
170   {"amqp_history_offset", cfg_key_sql_history_offset},
171   {"amqp_history_roundoff", cfg_key_sql_history_roundoff},
172   {"amqp_time_roundoff", cfg_key_sql_history_roundoff},
173   {"amqp_host", cfg_key_sql_host},
174   {"amqp_user", cfg_key_sql_user},
175   {"amqp_passwd", cfg_key_sql_passwd},
176   {"amqp_exchange", cfg_key_sql_db},
177   {"amqp_exchange_type", cfg_key_amqp_exchange_type},
178   {"amqp_routing_key", cfg_key_sql_table},
179   {"amqp_routing_key_rr", cfg_key_amqp_routing_key_rr},
180   {"amqp_persistent_msg", cfg_key_amqp_persistent_msg},
181   {"amqp_frame_max", cfg_key_amqp_frame_max},
182   {"amqp_cache_entries", cfg_key_print_cache_entries},
183   {"amqp_max_writers", cfg_key_dump_max_writers},
184   {"amqp_preprocess", cfg_key_sql_preprocess},
185   {"amqp_preprocess_type", cfg_key_sql_preprocess_type},
186   {"amqp_startup_delay", cfg_key_sql_startup_delay},
187   {"amqp_heartbeat_interval", cfg_key_amqp_heartbeat_interval},
188   {"amqp_multi_values", cfg_key_sql_multi_values},
189   {"amqp_num_protos", cfg_key_num_protos},
190   {"amqp_vhost", cfg_key_amqp_vhost},
191   {"amqp_markers", cfg_key_print_markers},
192   {"amqp_output", cfg_key_message_broker_output},
193   {"amqp_avro_schema_routing_key", cfg_key_amqp_avro_schema_routing_key}, /* XXX: Legacy key */
194   {"amqp_avro_schema_refresh_time", cfg_key_amqp_avro_schema_refresh_time}, /* XXX: Legacy key */
195   {"amqp_trigger_exec", cfg_key_sql_trigger_exec},
196   {"kafka_refresh_time", cfg_key_sql_refresh_time},
197   {"kafka_history", cfg_key_sql_history},
198   {"kafka_history_offset", cfg_key_sql_history_offset},
199   {"kafka_history_roundoff", cfg_key_sql_history_roundoff},
200   {"kafka_broker_host", cfg_key_sql_host},
201   {"kafka_broker_port", cfg_key_kafka_broker_port},
202   {"kafka_topic", cfg_key_sql_table},
203   {"kafka_topic_rr", cfg_key_amqp_routing_key_rr},
204   {"kafka_partition", cfg_key_kafka_partition},
205   {"kafka_partition_dynamic", cfg_key_kafka_partition_dynamic},
206   {"kafka_partition_key", cfg_key_kafka_partition_key},
207   {"kafka_cache_entries", cfg_key_print_cache_entries},
208   {"kafka_max_writers", cfg_key_dump_max_writers},
209   {"kafka_preprocess", cfg_key_sql_preprocess},
210   {"kafka_preprocess_type", cfg_key_sql_preprocess_type},
211   {"kafka_startup_delay", cfg_key_sql_startup_delay},
212   {"kafka_multi_values", cfg_key_sql_multi_values},
213   {"kafka_num_protos", cfg_key_num_protos},
214   {"kafka_markers", cfg_key_print_markers},
215   {"kafka_output", cfg_key_message_broker_output},
216   {"kafka_avro_schema_registry", cfg_key_kafka_avro_schema_registry},
217   {"kafka_config_file", cfg_key_kafka_config_file},
218   {"kafka_trigger_exec", cfg_key_sql_trigger_exec},
219   {"nfacctd_proc_name", cfg_key_proc_name},
220   {"nfacctd_port", cfg_key_nfacctd_port},
221   {"nfacctd_ip", cfg_key_nfacctd_ip},
222   {"nfacctd_allow_file", cfg_key_nfacctd_allow_file},
223   {"nfacctd_time_secs", cfg_key_nfacctd_time_secs},
224   {"nfacctd_time_new", cfg_key_nfacctd_time_new},
225   {"nfacctd_as_new", cfg_key_nfacctd_as_new},
226   {"nfacctd_as", cfg_key_nfacctd_as_new},
227   {"nfacctd_net", cfg_key_nfacctd_net},
228   {"nfacctd_mcast_groups", cfg_key_nfacctd_mcast_groups},
229   {"nfacctd_peer_as", cfg_key_nfprobe_peer_as},
230   {"nfacctd_pipe_size", cfg_key_nfacctd_pipe_size},
231   {"nfacctd_pro_rating", cfg_key_nfacctd_pro_rating},
232   {"nfacctd_templates_file", cfg_key_nfacctd_templates_file},
233   {"nfacctd_templates_receiver", cfg_key_nfacctd_templates_receiver},
234   {"nfacctd_templates_port", cfg_key_nfacctd_templates_port},
235   {"nfacctd_account_options", cfg_key_nfacctd_account_options},
236   {"nfacctd_stitching", cfg_key_nfacctd_stitching},
237   {"nfacctd_ext_sampling_rate", cfg_key_pmacctd_ext_sampling_rate},
238   {"nfacctd_renormalize", cfg_key_sfacctd_renormalize},
239   {"nfacctd_disable_checks", cfg_key_nfacctd_disable_checks},
240   {"nfacctd_disable_opt_scope_check", cfg_key_nfacctd_disable_opt_scope_check},
241   {"nfacctd_kafka_broker_host", cfg_key_nfacctd_kafka_broker_host},
242   {"nfacctd_kafka_broker_port", cfg_key_nfacctd_kafka_broker_port},
243   {"nfacctd_kafka_topic", cfg_key_nfacctd_kafka_topic},
244   {"nfacctd_kafka_config_file", cfg_key_nfacctd_kafka_config_file},
245   {"nfacctd_zmq_address", cfg_key_nfacctd_zmq_address},
246   {"pmacctd_proc_name", cfg_key_proc_name},
247   {"pmacctd_force_frag_handling", cfg_key_pmacctd_force_frag_handling},
248   {"pmacctd_frag_buffer_size", cfg_key_pmacctd_frag_buffer_size},
249   {"pmacctd_flow_buffer_size", cfg_key_pmacctd_flow_buffer_size},
250   {"pmacctd_flow_buffer_buckets", cfg_key_pmacctd_flow_buffer_buckets},
251   {"pmacctd_conntrack_buffer_size", cfg_key_pmacctd_conntrack_buffer_size},
252   {"pmacctd_flow_lifetime", cfg_key_pmacctd_flow_lifetime},
253   {"pmacctd_flow_tcp_lifetime", cfg_key_pmacctd_flow_tcp_lifetime},
254   {"pmacctd_ext_sampling_rate", cfg_key_pmacctd_ext_sampling_rate},
255   {"pmacctd_pipe_size", cfg_key_nfacctd_pipe_size},
256   {"pmacctd_stitching", cfg_key_nfacctd_stitching},
257   {"pmacctd_renormalize", cfg_key_sfacctd_renormalize},
258   {"pmacctd_nonroot", cfg_key_pmacctd_nonroot},
259   {"pmacctd_time_new", cfg_key_nfacctd_time_new},
260   {"uacctd_proc_name", cfg_key_proc_name},
261   {"uacctd_force_frag_handling", cfg_key_pmacctd_force_frag_handling},
262   {"uacctd_frag_buffer_size", cfg_key_pmacctd_frag_buffer_size},
263   {"uacctd_flow_buffer_size", cfg_key_pmacctd_flow_buffer_size},
264   {"uacctd_flow_buffer_buckets", cfg_key_pmacctd_flow_buffer_buckets},
265   {"uacctd_conntrack_buffer_size", cfg_key_pmacctd_conntrack_buffer_size},
266   {"uacctd_flow_lifetime", cfg_key_pmacctd_flow_lifetime},
267   {"uacctd_flow_tcp_lifetime", cfg_key_pmacctd_flow_tcp_lifetime},
268   {"uacctd_ext_sampling_rate", cfg_key_pmacctd_ext_sampling_rate},
269   {"uacctd_stitching", cfg_key_nfacctd_stitching},
270   {"uacctd_renormalize", cfg_key_sfacctd_renormalize},
271   {"uacctd_direction", cfg_key_pcap_direction},
272   {"telemetry_daemon", cfg_key_telemetry_daemon},
273   {"telemetry_daemon_port_tcp", cfg_key_telemetry_port_tcp},
274   {"telemetry_daemon_port_udp", cfg_key_telemetry_port_udp},
275   {"telemetry_daemon_ip", cfg_key_telemetry_ip},
276   {"telemetry_daemon_zmq_address", cfg_key_telemetry_zmq_address},
277   {"telemetry_daemon_kafka_broker_host", cfg_key_telemetry_kafka_broker_host},
278   {"telemetry_daemon_kafka_broker_port", cfg_key_telemetry_kafka_broker_port},
279   {"telemetry_daemon_kafka_topic", cfg_key_telemetry_kafka_topic},
280   {"telemetry_daemon_kafka_config_file", cfg_key_telemetry_kafka_config_file},
281   {"telemetry_daemon_decoder", cfg_key_telemetry_decoder},
282   {"telemetry_daemon_max_peers", cfg_key_telemetry_max_peers},
283   {"telemetry_daemon_peer_timeout", cfg_key_telemetry_peer_timeout},
284   {"telemetry_daemon_allow_file", cfg_key_telemetry_allow_file},
285   {"telemetry_daemon_pipe_size", cfg_key_telemetry_pipe_size},
286   {"telemetry_daemon_ipprec", cfg_key_telemetry_ip_precedence},
287   {"telemetry_daemon_msglog_output", cfg_key_telemetry_msglog_output},
288   {"telemetry_daemon_msglog_file", cfg_key_telemetry_msglog_file},
289   {"telemetry_daemon_msglog_amqp_host", cfg_key_telemetry_msglog_amqp_host},
290   {"telemetry_daemon_msglog_amqp_vhost", cfg_key_telemetry_msglog_amqp_vhost},
291   {"telemetry_daemon_msglog_amqp_user", cfg_key_telemetry_msglog_amqp_user},
292   {"telemetry_daemon_msglog_amqp_passwd", cfg_key_telemetry_msglog_amqp_passwd},
293   {"telemetry_daemon_msglog_amqp_exchange", cfg_key_telemetry_msglog_amqp_exchange},
294   {"telemetry_daemon_msglog_amqp_exchange_type", cfg_key_telemetry_msglog_amqp_exchange_type},
295   {"telemetry_daemon_msglog_amqp_routing_key", cfg_key_telemetry_msglog_amqp_routing_key},
296   {"telemetry_daemon_msglog_amqp_routing_key_rr", cfg_key_telemetry_msglog_amqp_routing_key_rr},
297   {"telemetry_daemon_msglog_amqp_persistent_msg", cfg_key_telemetry_msglog_amqp_persistent_msg},
298   {"telemetry_daemon_msglog_amqp_frame_max", cfg_key_telemetry_msglog_amqp_frame_max},
299   {"telemetry_daemon_msglog_amqp_heartbeat_interval", cfg_key_telemetry_msglog_amqp_heartbeat_interval},
300   {"telemetry_daemon_msglog_amqp_retry", cfg_key_telemetry_msglog_amqp_retry},
301   {"telemetry_daemon_msglog_kafka_broker_host", cfg_key_telemetry_msglog_kafka_broker_host},
302   {"telemetry_daemon_msglog_kafka_broker_port", cfg_key_telemetry_msglog_kafka_broker_port},
303   {"telemetry_daemon_msglog_kafka_topic", cfg_key_telemetry_msglog_kafka_topic},
304   {"telemetry_daemon_msglog_kafka_topic_rr", cfg_key_telemetry_msglog_kafka_topic_rr},
305   {"telemetry_daemon_msglog_kafka_partition", cfg_key_telemetry_msglog_kafka_partition},
306   {"telemetry_daemon_msglog_kafka_partition_key", cfg_key_telemetry_msglog_kafka_partition_key},
307   {"telemetry_daemon_msglog_kafka_retry", cfg_key_telemetry_msglog_kafka_retry},
308   {"telemetry_daemon_msglog_kafka_config_file", cfg_key_telemetry_msglog_kafka_config_file},
309   {"telemetry_dump_output", cfg_key_telemetry_dump_output},
310   {"telemetry_dump_file", cfg_key_telemetry_dump_file},
311   {"telemetry_dump_latest_file", cfg_key_telemetry_dump_latest_file},
312   {"telemetry_dump_refresh_time", cfg_key_telemetry_dump_refresh_time},
313   {"telemetry_dump_amqp_host", cfg_key_telemetry_dump_amqp_host},
314   {"telemetry_dump_amqp_vhost", cfg_key_telemetry_dump_amqp_vhost},
315   {"telemetry_dump_amqp_user", cfg_key_telemetry_dump_amqp_user},
316   {"telemetry_dump_amqp_passwd", cfg_key_telemetry_dump_amqp_passwd},
317   {"telemetry_dump_amqp_exchange", cfg_key_telemetry_dump_amqp_exchange},
318   {"telemetry_dump_amqp_exchange_type", cfg_key_telemetry_dump_amqp_exchange_type},
319   {"telemetry_dump_amqp_routing_key", cfg_key_telemetry_dump_amqp_routing_key},
320   {"telemetry_dump_amqp_routing_key_rr", cfg_key_telemetry_dump_amqp_routing_key_rr},
321   {"telemetry_dump_amqp_persistent_msg", cfg_key_telemetry_dump_amqp_persistent_msg},
322   {"telemetry_dump_amqp_frame_max", cfg_key_telemetry_dump_amqp_frame_max},
323   {"telemetry_dump_amqp_heartbeat_interval", cfg_key_telemetry_dump_amqp_heartbeat_interval},
324   {"telemetry_dump_kafka_broker_host", cfg_key_telemetry_dump_kafka_broker_host},
325   {"telemetry_dump_kafka_broker_port", cfg_key_telemetry_dump_kafka_broker_port},
326   {"telemetry_dump_kafka_topic", cfg_key_telemetry_dump_kafka_topic},
327   {"telemetry_dump_kafka_topic_rr", cfg_key_telemetry_dump_kafka_topic_rr},
328   {"telemetry_dump_kafka_partition", cfg_key_telemetry_dump_kafka_partition},
329   {"telemetry_dump_kafka_partition_key", cfg_key_telemetry_dump_kafka_partition_key},
330   {"telemetry_dump_kafka_config_file", cfg_key_telemetry_dump_kafka_config_file},
331   {"refresh_maps", cfg_key_maps_refresh}, /* Legacy key */
332   {"maps_refresh", cfg_key_maps_refresh},
333   {"maps_index", cfg_key_maps_index},
334   {"maps_entries", cfg_key_maps_entries},
335   {"maps_row_len", cfg_key_maps_row_len},
336   {"pre_tag_map", cfg_key_pre_tag_map},
337   {"pre_tag_map_entries", cfg_key_maps_entries}, /* Legacy key */
338   {"pre_tag_filter", cfg_key_pre_tag_filter},
339   {"pre_tag2_filter", cfg_key_pre_tag2_filter},
340   {"pre_tag_label_filter", cfg_key_pre_tag_label_filter},
341   {"post_tag", cfg_key_post_tag},
342   {"post_tag2", cfg_key_post_tag2},
343   {"sampling_rate", cfg_key_sampling_rate},
344   {"sampling_map", cfg_key_sampling_map},
345   {"sfacctd_proc_name", cfg_key_proc_name},
346   {"sfacctd_port", cfg_key_nfacctd_port},
347   {"sfacctd_ip", cfg_key_nfacctd_ip},
348   {"sfacctd_allow_file", cfg_key_nfacctd_allow_file},
349   {"sfacctd_as_new", cfg_key_nfacctd_as_new},
350   {"sfacctd_as", cfg_key_nfacctd_as_new},
351   {"sfacctd_net", cfg_key_nfacctd_net},
352   {"sfacctd_peer_as", cfg_key_nfprobe_peer_as},
353   {"sfacctd_time_new", cfg_key_nfacctd_time_new},
354   {"sfacctd_pipe_size", cfg_key_nfacctd_pipe_size},
355   {"sfacctd_renormalize", cfg_key_sfacctd_renormalize},
356   {"sfacctd_disable_checks", cfg_key_nfacctd_disable_checks},
357   {"sfacctd_mcast_groups", cfg_key_nfacctd_mcast_groups},
358   {"sfacctd_stitching", cfg_key_nfacctd_stitching},
359   {"sfacctd_ext_sampling_rate", cfg_key_pmacctd_ext_sampling_rate},
360   {"sfacctd_counter_output", cfg_key_sfacctd_counter_output},
361   {"sfacctd_counter_file", cfg_key_sfacctd_counter_file},
362   {"sfacctd_counter_amqp_host", cfg_key_sfacctd_counter_amqp_host},
363   {"sfacctd_counter_amqp_vhost", cfg_key_sfacctd_counter_amqp_vhost},
364   {"sfacctd_counter_amqp_user", cfg_key_sfacctd_counter_amqp_user},
365   {"sfacctd_counter_amqp_passwd", cfg_key_sfacctd_counter_amqp_passwd},
366   {"sfacctd_counter_amqp_exchange", cfg_key_sfacctd_counter_amqp_exchange},
367   {"sfacctd_counter_amqp_exchange_type", cfg_key_sfacctd_counter_amqp_exchange_type},
368   {"sfacctd_counter_amqp_routing_key", cfg_key_sfacctd_counter_amqp_routing_key},
369   {"sfacctd_counter_amqp_persistent_msg", cfg_key_sfacctd_counter_amqp_persistent_msg},
370   {"sfacctd_counter_amqp_frame_max", cfg_key_sfacctd_counter_amqp_frame_max},
371   {"sfacctd_counter_amqp_heartbeat_interval", cfg_key_sfacctd_counter_amqp_heartbeat_interval},
372   {"sfacctd_counter_amqp_retry", cfg_key_sfacctd_counter_amqp_retry},
373   {"sfacctd_counter_kafka_broker_host", cfg_key_sfacctd_counter_kafka_broker_host},
374   {"sfacctd_counter_kafka_broker_port", cfg_key_sfacctd_counter_kafka_broker_port},
375   {"sfacctd_counter_kafka_topic", cfg_key_sfacctd_counter_kafka_topic},
376   {"sfacctd_counter_kafka_partition", cfg_key_sfacctd_counter_kafka_partition},
377   {"sfacctd_counter_kafka_partition_key", cfg_key_sfacctd_counter_kafka_partition_key},
378   {"sfacctd_counter_kafka_retry", cfg_key_sfacctd_counter_kafka_retry},
379   {"sfacctd_counter_kafka_config_file", cfg_key_sfacctd_counter_kafka_config_file},
380   {"sfacctd_kafka_broker_host", cfg_key_nfacctd_kafka_broker_host},
381   {"sfacctd_kafka_broker_port", cfg_key_nfacctd_kafka_broker_port},
382   {"sfacctd_kafka_topic", cfg_key_nfacctd_kafka_topic},
383   {"sfacctd_kafka_config_file", cfg_key_nfacctd_kafka_config_file},
384   {"sfacctd_zmq_address", cfg_key_nfacctd_zmq_address},
385   {"classifiers", cfg_key_classifiers},
386   {"classifier_tentatives", cfg_key_classifier_tentatives},
387   {"classifier_table_num", cfg_key_classifier_table_num},
388 #if defined (WITH_NDPI)
389   {"classifier_num_roots", cfg_key_classifier_ndpi_num_roots},
390   {"classifier_max_flows", cfg_key_classifier_ndpi_max_flows},
391   {"classifier_proto_guess", cfg_key_classifier_ndpi_proto_guess},
392   {"classifier_idle_scan_period", cfg_key_classifier_ndpi_idle_scan_period},
393   {"classifier_idle_max_time", cfg_key_classifier_ndpi_idle_max_time},
394   {"classifier_idle_scan_budget", cfg_key_classifier_ndpi_idle_scan_budget},
395   {"classifier_giveup_proto_tcp", cfg_key_classifier_ndpi_giveup_proto_tcp},
396   {"classifier_giveup_proto_udp", cfg_key_classifier_ndpi_giveup_proto_udp},
397   {"classifier_giveup_proto_other", cfg_key_classifier_ndpi_giveup_proto_other},
398 #endif
399   {"nfprobe_timeouts", cfg_key_nfprobe_timeouts},
400   {"nfprobe_hoplimit", cfg_key_nfprobe_hoplimit},
401   {"nfprobe_maxflows", cfg_key_nfprobe_maxflows},
402   {"nfprobe_receiver", cfg_key_nfprobe_receiver},
403   {"nfprobe_engine", cfg_key_nfprobe_engine},
404   {"nfprobe_version", cfg_key_nfprobe_version},
405   {"nfprobe_peer_as", cfg_key_nfprobe_peer_as},
406   {"nfprobe_source_ip", cfg_key_nfprobe_source_ip},
407   {"nfprobe_ipprec", cfg_key_nfprobe_ip_precedence},
408   {"nfprobe_direction", cfg_key_nfprobe_direction},
409   {"nfprobe_ifindex", cfg_key_nfprobe_ifindex},
410   {"nfprobe_dont_cache", cfg_key_nfprobe_dont_cache},
411   {"nfprobe_ifindex_override", cfg_key_nfprobe_ifindex_override},
412   {"nfprobe_tstamp_usec", cfg_key_nfprobe_tstamp_usec},
413   {"sfprobe_receiver", cfg_key_sfprobe_receiver},
414   {"sfprobe_agentip", cfg_key_sfprobe_agentip},
415   {"sfprobe_agentsubid", cfg_key_sfprobe_agentsubid},
416   {"sfprobe_peer_as", cfg_key_nfprobe_peer_as},
417   {"sfprobe_source_ip", cfg_key_nfprobe_source_ip},
418   {"sfprobe_ipprec", cfg_key_nfprobe_ip_precedence},
419   {"sfprobe_direction", cfg_key_nfprobe_direction},
420   {"sfprobe_ifindex", cfg_key_nfprobe_ifindex},
421   {"sfprobe_ifspeed", cfg_key_sfprobe_ifspeed},
422   {"sfprobe_ifindex_override", cfg_key_nfprobe_ifindex_override},
423   {"tee_receivers", cfg_key_tee_receivers},
424   {"tee_source_ip", cfg_key_nfprobe_source_ip},
425   {"tee_transparent", cfg_key_tee_transparent},
426   {"tee_max_receivers", cfg_key_tee_max_receivers},
427   {"tee_max_receiver_pools", cfg_key_tee_max_receiver_pools},
428   {"tee_ipprec", cfg_key_nfprobe_ip_precedence},
429   {"tee_pipe_size", cfg_key_tee_pipe_size},
430   {"tee_kafka_config_file", cfg_key_tee_kafka_config_file},
431   {"bgp_daemon", cfg_key_bgp_daemon},
432   {"bgp_daemon_ip", cfg_key_bgp_daemon_ip},
433   {"bgp_daemon_id", cfg_key_bgp_daemon_id},
434   {"bgp_daemon_as", cfg_key_bgp_daemon_as},
435   {"bgp_daemon_port", cfg_key_bgp_daemon_port},
436   {"bgp_daemon_pipe_size", cfg_key_bgp_daemon_pipe_size},
437   {"bgp_daemon_max_peers", cfg_key_bgp_daemon_max_peers},
438   {"bgp_daemon_msglog_output", cfg_key_bgp_daemon_msglog_output},
439   {"bgp_daemon_msglog_file", cfg_key_bgp_daemon_msglog_file},
440   {"bgp_daemon_msglog_avro_schema_file", cfg_key_bgp_daemon_msglog_avro_schema_file},
441   {"bgp_daemon_msglog_amqp_host", cfg_key_bgp_daemon_msglog_amqp_host},
442   {"bgp_daemon_msglog_amqp_vhost", cfg_key_bgp_daemon_msglog_amqp_vhost},
443   {"bgp_daemon_msglog_amqp_user", cfg_key_bgp_daemon_msglog_amqp_user},
444   {"bgp_daemon_msglog_amqp_passwd", cfg_key_bgp_daemon_msglog_amqp_passwd},
445   {"bgp_daemon_msglog_amqp_exchange", cfg_key_bgp_daemon_msglog_amqp_exchange},
446   {"bgp_daemon_msglog_amqp_exchange_type", cfg_key_bgp_daemon_msglog_amqp_exchange_type},
447   {"bgp_daemon_msglog_amqp_routing_key", cfg_key_bgp_daemon_msglog_amqp_routing_key},
448   {"bgp_daemon_msglog_amqp_routing_key_rr", cfg_key_bgp_daemon_msglog_amqp_routing_key_rr},
449   {"bgp_daemon_msglog_amqp_persistent_msg", cfg_key_bgp_daemon_msglog_amqp_persistent_msg},
450   {"bgp_daemon_msglog_amqp_frame_max", cfg_key_bgp_daemon_msglog_amqp_frame_max},
451   {"bgp_daemon_msglog_amqp_heartbeat_interval", cfg_key_bgp_daemon_msglog_amqp_heartbeat_interval},
452   {"bgp_daemon_msglog_amqp_retry", cfg_key_bgp_daemon_msglog_amqp_retry},
453   {"bgp_daemon_msglog_kafka_broker_host", cfg_key_bgp_daemon_msglog_kafka_broker_host},
454   {"bgp_daemon_msglog_kafka_broker_port", cfg_key_bgp_daemon_msglog_kafka_broker_port},
455   {"bgp_daemon_msglog_kafka_topic", cfg_key_bgp_daemon_msglog_kafka_topic},
456   {"bgp_daemon_msglog_kafka_topic_rr", cfg_key_bgp_daemon_msglog_kafka_topic_rr},
457   {"bgp_daemon_msglog_kafka_partition", cfg_key_bgp_daemon_msglog_kafka_partition},
458   {"bgp_daemon_msglog_kafka_partition_key", cfg_key_bgp_daemon_msglog_kafka_partition_key},
459   {"bgp_daemon_msglog_kafka_retry", cfg_key_bgp_daemon_msglog_kafka_retry},
460   {"bgp_daemon_msglog_kafka_config_file", cfg_key_bgp_daemon_msglog_kafka_config_file},
461   {"bgp_daemon_msglog_kafka_avro_schema_registry", cfg_key_bgp_daemon_msglog_kafka_avro_schema_registry},
462   {"bgp_daemon_allow_file", cfg_key_bgp_daemon_allow_file},
463   {"bgp_daemon_ipprec", cfg_key_bgp_daemon_ip_precedence},
464   {"bgp_daemon_md5_file", cfg_key_bgp_daemon_md5_file},
465   {"bgp_daemon_batch", cfg_key_bgp_daemon_batch},
466   {"bgp_daemon_batch_interval", cfg_key_bgp_daemon_batch_interval},
467   {"bgp_aspath_radius", cfg_key_bgp_daemon_aspath_radius},
468   {"bgp_stdcomm_pattern", cfg_key_bgp_daemon_stdcomm_pattern},
469   {"bgp_extcomm_pattern", cfg_key_bgp_daemon_extcomm_pattern},
470   {"bgp_lrgcomm_pattern", cfg_key_bgp_daemon_lrgcomm_pattern},
471   {"bgp_stdcomm_pattern_to_asn", cfg_key_bgp_daemon_stdcomm_pattern_to_asn},
472   {"bgp_lrgcomm_pattern_to_asn", cfg_key_bgp_daemon_lrgcomm_pattern_to_asn},
473   {"bgp_blackhole_stdcomm_list", cfg_key_bgp_blackhole_stdcomm_list},
474   {"bgp_peer_as_skip_subas", cfg_key_bgp_daemon_peer_as_skip_subas},
475   {"bgp_peer_src_as_map", cfg_key_bgp_daemon_peer_src_as_map},
476   {"bgp_src_local_pref_map", cfg_key_bgp_daemon_src_local_pref_map},
477   {"bgp_src_med_map", cfg_key_bgp_daemon_src_med_map},
478   {"bgp_peer_src_as_type", cfg_key_bgp_daemon_peer_src_as_type},
479   {"bgp_src_std_comm_type", cfg_key_bgp_daemon_src_std_comm_type},
480   {"bgp_src_ext_comm_type", cfg_key_bgp_daemon_src_ext_comm_type},
481   {"bgp_src_lrg_comm_type", cfg_key_bgp_daemon_src_lrg_comm_type},
482   {"bgp_src_as_path_type", cfg_key_bgp_daemon_src_as_path_type},
483   {"bgp_src_local_pref_type", cfg_key_bgp_daemon_src_local_pref_type},
484   {"bgp_src_med_type", cfg_key_bgp_daemon_src_med_type},
485   {"bgp_src_roa_type", cfg_key_bgp_daemon_src_roa_type},
486   {"bgp_agent_map", cfg_key_bgp_daemon_to_xflow_agent_map},
487   {"bgp_follow_default", cfg_key_bgp_daemon_follow_default},
488   {"bgp_follow_nexthop", cfg_key_bgp_daemon_follow_nexthop},
489   {"bgp_follow_nexthop_external", cfg_key_bgp_daemon_follow_nexthop_external},
490   {"bgp_disable_router_id_check", cfg_key_bgp_daemon_disable_router_id_check},
491   {"bgp_neighbors_file", cfg_key_bgp_daemon_neighbors_file},
492   {"bgp_table_peer_buckets", cfg_key_bgp_daemon_table_peer_buckets},
493   {"bgp_table_per_peer_buckets", cfg_key_bgp_daemon_table_per_peer_buckets},
494   {"bgp_table_attr_hash_buckets", cfg_key_bgp_daemon_table_attr_hash_buckets},
495   {"bgp_table_per_peer_hash", cfg_key_bgp_daemon_table_per_peer_hash},
496   {"bgp_table_dump_output", cfg_key_bgp_daemon_table_dump_output},
497   {"bgp_table_dump_file", cfg_key_bgp_daemon_table_dump_file},
498   {"bgp_table_dump_latest_file", cfg_key_bgp_daemon_table_dump_latest_file},
499   {"bgp_table_dump_avro_schema_file", cfg_key_bgp_daemon_table_dump_avro_schema_file},
500   {"bgp_table_dump_refresh_time", cfg_key_bgp_daemon_table_dump_refresh_time},
501   {"bgp_table_dump_amqp_host", cfg_key_bgp_daemon_table_dump_amqp_host},
502   {"bgp_table_dump_amqp_vhost", cfg_key_bgp_daemon_table_dump_amqp_vhost},
503   {"bgp_table_dump_amqp_user", cfg_key_bgp_daemon_table_dump_amqp_user},
504   {"bgp_table_dump_amqp_passwd", cfg_key_bgp_daemon_table_dump_amqp_passwd},
505   {"bgp_table_dump_amqp_exchange", cfg_key_bgp_daemon_table_dump_amqp_exchange},
506   {"bgp_table_dump_amqp_exchange_type", cfg_key_bgp_daemon_table_dump_amqp_exchange_type},
507   {"bgp_table_dump_amqp_routing_key", cfg_key_bgp_daemon_table_dump_amqp_routing_key},
508   {"bgp_table_dump_amqp_routing_key_rr", cfg_key_bgp_daemon_table_dump_amqp_routing_key_rr},
509   {"bgp_table_dump_amqp_persistent_msg", cfg_key_bgp_daemon_table_dump_amqp_persistent_msg},
510   {"bgp_table_dump_amqp_frame_max", cfg_key_bgp_daemon_table_dump_amqp_frame_max},
511   {"bgp_table_dump_amqp_heartbeat_interval", cfg_key_bgp_daemon_table_dump_amqp_heartbeat_interval},
512   {"bgp_table_dump_kafka_broker_host", cfg_key_bgp_daemon_table_dump_kafka_broker_host},
513   {"bgp_table_dump_kafka_broker_port", cfg_key_bgp_daemon_table_dump_kafka_broker_port},
514   {"bgp_table_dump_kafka_topic", cfg_key_bgp_daemon_table_dump_kafka_topic},
515   {"bgp_table_dump_kafka_topic_rr", cfg_key_bgp_daemon_table_dump_kafka_topic_rr},
516   {"bgp_table_dump_kafka_partition", cfg_key_bgp_daemon_table_dump_kafka_partition},
517   {"bgp_table_dump_kafka_partition_key", cfg_key_bgp_daemon_table_dump_kafka_partition_key},
518   {"bgp_table_dump_kafka_config_file", cfg_key_bgp_daemon_table_dump_kafka_config_file},
519   {"bgp_table_dump_kafka_avro_schema_registry", cfg_key_bgp_daemon_table_dump_kafka_avro_schema_registry},
520   {"bgp_daemon_lg", cfg_key_bgp_lg},
521   {"bgp_daemon_lg_ip", cfg_key_bgp_lg_ip},
522   {"bgp_daemon_lg_port", cfg_key_bgp_lg_port},
523   {"bgp_daemon_lg_threads", cfg_key_bgp_lg_threads},
524   {"bgp_daemon_lg_user", cfg_key_bgp_lg_user},
525   {"bgp_daemon_lg_passwd", cfg_key_bgp_lg_passwd},
526   {"bgp_daemon_xconnect_map", cfg_key_bgp_xconnect_map},
527   {"bmp_daemon", cfg_key_bmp_daemon},
528   {"bmp_daemon_ip", cfg_key_bmp_daemon_ip},
529   {"bmp_daemon_port", cfg_key_bmp_daemon_port},
530   {"bmp_daemon_pipe_size", cfg_key_bmp_daemon_pipe_size},
531   {"bmp_daemon_max_peers", cfg_key_bmp_daemon_max_peers},
532   {"bmp_daemon_allow_file", cfg_key_bmp_daemon_allow_file},
533   {"bmp_daemon_ipprec", cfg_key_bmp_daemon_ip_precedence},
534   {"bmp_daemon_batch", cfg_key_bmp_daemon_batch},
535   {"bmp_daemon_batch_interval", cfg_key_bmp_daemon_batch_interval},
536   {"bmp_daemon_msglog_output", cfg_key_bmp_daemon_msglog_output},
537   {"bmp_daemon_msglog_file", cfg_key_bmp_daemon_msglog_file},
538   {"bmp_daemon_msglog_avro_schema_file", cfg_key_bmp_daemon_msglog_avro_schema_file},
539   {"bmp_daemon_msglog_amqp_host", cfg_key_bmp_daemon_msglog_amqp_host},
540   {"bmp_daemon_msglog_amqp_vhost", cfg_key_bmp_daemon_msglog_amqp_vhost},
541   {"bmp_daemon_msglog_amqp_user", cfg_key_bmp_daemon_msglog_amqp_user},
542   {"bmp_daemon_msglog_amqp_passwd", cfg_key_bmp_daemon_msglog_amqp_passwd},
543   {"bmp_daemon_msglog_amqp_exchange", cfg_key_bmp_daemon_msglog_amqp_exchange},
544   {"bmp_daemon_msglog_amqp_exchange_type", cfg_key_bmp_daemon_msglog_amqp_exchange_type},
545   {"bmp_daemon_msglog_amqp_routing_key", cfg_key_bmp_daemon_msglog_amqp_routing_key},
546   {"bmp_daemon_msglog_amqp_routing_key_rr", cfg_key_bmp_daemon_msglog_amqp_routing_key_rr},
547   {"bmp_daemon_msglog_amqp_persistent_msg", cfg_key_bmp_daemon_msglog_amqp_persistent_msg},
548   {"bmp_daemon_msglog_amqp_frame_max", cfg_key_bmp_daemon_msglog_amqp_frame_max},
549   {"bmp_daemon_msglog_amqp_heartbeat_interval", cfg_key_bmp_daemon_msglog_amqp_heartbeat_interval},
550   {"bmp_daemon_msglog_amqp_retry", cfg_key_bmp_daemon_msglog_amqp_retry},
551   {"bmp_daemon_msglog_kafka_broker_host", cfg_key_bmp_daemon_msglog_kafka_broker_host},
552   {"bmp_daemon_msglog_kafka_broker_port", cfg_key_bmp_daemon_msglog_kafka_broker_port},
553   {"bmp_daemon_msglog_kafka_topic", cfg_key_bmp_daemon_msglog_kafka_topic},
554   {"bmp_daemon_msglog_kafka_topic_rr", cfg_key_bmp_daemon_msglog_kafka_topic_rr},
555   {"bmp_daemon_msglog_kafka_partition", cfg_key_bmp_daemon_msglog_kafka_partition},
556   {"bmp_daemon_msglog_kafka_partition_key", cfg_key_bmp_daemon_msglog_kafka_partition_key},
557   {"bmp_daemon_msglog_kafka_retry", cfg_key_bmp_daemon_msglog_kafka_retry},
558   {"bmp_daemon_msglog_kafka_config_file", cfg_key_bmp_daemon_msglog_kafka_config_file},
559   {"bmp_daemon_msglog_kafka_avro_schema_registry", cfg_key_bmp_daemon_msglog_kafka_avro_schema_registry},
560   {"bmp_table_peer_buckets", cfg_key_bmp_daemon_table_peer_buckets},
561   {"bmp_table_per_peer_buckets", cfg_key_bmp_daemon_table_per_peer_buckets},
562   {"bmp_table_attr_hash_buckets", cfg_key_bmp_daemon_table_attr_hash_buckets},
563   {"bmp_table_per_peer_hash", cfg_key_bmp_daemon_table_per_peer_hash},
564   {"bmp_dump_output", cfg_key_bmp_daemon_dump_output},
565   {"bmp_dump_file", cfg_key_bmp_daemon_dump_file},
566   {"bmp_dump_latest_file", cfg_key_bmp_daemon_dump_latest_file},
567   {"bmp_dump_avro_schema_file", cfg_key_bmp_daemon_dump_avro_schema_file},
568   {"bmp_dump_refresh_time", cfg_key_bmp_daemon_dump_refresh_time},
569   {"bmp_dump_amqp_host", cfg_key_bmp_daemon_dump_amqp_host},
570   {"bmp_dump_amqp_vhost", cfg_key_bmp_daemon_dump_amqp_vhost},
571   {"bmp_dump_amqp_user", cfg_key_bmp_daemon_dump_amqp_user},
572   {"bmp_dump_amqp_passwd", cfg_key_bmp_daemon_dump_amqp_passwd},
573   {"bmp_dump_amqp_exchange", cfg_key_bmp_daemon_dump_amqp_exchange},
574   {"bmp_dump_amqp_exchange_type", cfg_key_bmp_daemon_dump_amqp_exchange_type},
575   {"bmp_dump_amqp_routing_key", cfg_key_bmp_daemon_dump_amqp_routing_key},
576   {"bmp_dump_amqp_routing_key_rr", cfg_key_bmp_daemon_dump_amqp_routing_key_rr},
577   {"bmp_dump_amqp_persistent_msg", cfg_key_bmp_daemon_dump_amqp_persistent_msg},
578   {"bmp_dump_amqp_frame_max", cfg_key_bmp_daemon_dump_amqp_frame_max},
579   {"bmp_dump_amqp_heartbeat_interval", cfg_key_bmp_daemon_dump_amqp_heartbeat_interval},
580   {"bmp_dump_kafka_broker_host", cfg_key_bmp_daemon_dump_kafka_broker_host},
581   {"bmp_dump_kafka_broker_port", cfg_key_bmp_daemon_dump_kafka_broker_port},
582   {"bmp_dump_kafka_topic", cfg_key_bmp_daemon_dump_kafka_topic},
583   {"bmp_dump_kafka_topic_rr", cfg_key_bmp_daemon_dump_kafka_topic_rr},
584   {"bmp_dump_kafka_partition", cfg_key_bmp_daemon_dump_kafka_partition},
585   {"bmp_dump_kafka_partition_key", cfg_key_bmp_daemon_dump_kafka_partition_key},
586   {"bmp_dump_kafka_config_file", cfg_key_bmp_daemon_dump_kafka_config_file},
587   {"bmp_dump_kafka_avro_schema_registry", cfg_key_bmp_daemon_dump_kafka_avro_schema_registry},
588   {"rpki_roas_file", cfg_key_rpki_roas_file},
589   {"rpki_rtr_cache", cfg_key_rpki_rtr_cache},
590   {"rpki_rtr_cache_version", cfg_key_rpki_rtr_cache_version},
591   {"rpki_rtr_cache_pipe_size", cfg_key_rpki_rtr_cache_pipe_size},
592   {"rpki_rtr_cache_ipprec", cfg_key_rpki_rtr_cache_ip_precedence},
593   {"flow_to_rd_map", cfg_key_nfacctd_flow_to_rd_map},
594   {"isis_daemon", cfg_key_nfacctd_isis},
595   {"isis_daemon_ip", cfg_key_nfacctd_isis_ip},
596   {"isis_daemon_net", cfg_key_nfacctd_isis_net},
597   {"isis_daemon_iface", cfg_key_nfacctd_isis_iface},
598   {"isis_daemon_mtu", cfg_key_nfacctd_isis_mtu},
599   {"isis_daemon_msglog", cfg_key_nfacctd_isis_msglog},
600   {"igp_daemon", cfg_key_nfacctd_isis},
601   {"igp_daemon_map", cfg_key_igp_daemon_map},
602   {"igp_daemon_map_msglog", cfg_key_igp_daemon_map_msglog},
603 #if defined WITH_GEOIP
604   {"geoip_ipv4_file", cfg_key_geoip_ipv4_file},
605   {"geoip_ipv6_file", cfg_key_geoip_ipv6_file},
606 #endif
607 #if defined WITH_GEOIPV2
608   {"geoipv2_file", cfg_key_geoipv2_file},
609 #endif
610   {"uacctd_group", cfg_key_uacctd_group},
611   {"uacctd_nl_size", cfg_key_uacctd_nl_size},
612   {"uacctd_threshold", cfg_key_uacctd_threshold},
613   {"tunnel_0", cfg_key_tunnel_0},
614   {"tmp_asa_bi_flow", cfg_key_tmp_asa_bi_flow},
615   {"tmp_bgp_lookup_compare_ports", cfg_key_tmp_bgp_lookup_compare_ports},
616   {"tmp_bgp_daemon_route_refresh", cfg_key_tmp_bgp_daemon_route_refresh},
617   {"", NULL}
618 };
619 
620 static struct plugin_type_entry plugin_types_list[] = {
621   {PLUGIN_ID_CORE, 	"core", 	NULL},
622   {PLUGIN_ID_MEMORY, 	"memory", 	imt_plugin},
623   {PLUGIN_ID_PRINT,	"print",	print_plugin},
624   {PLUGIN_ID_NFPROBE,	"nfprobe",	nfprobe_plugin},
625   {PLUGIN_ID_SFPROBE,	"sfprobe",	sfprobe_plugin},
626 #ifdef WITH_MYSQL
627   {PLUGIN_ID_MYSQL,	"mysql",	mysql_plugin},
628 #endif
629 #ifdef WITH_PGSQL
630   {PLUGIN_ID_PGSQL,	"pgsql",	pgsql_plugin},
631 #endif
632 #ifdef WITH_SQLITE3
633   {PLUGIN_ID_SQLITE3,	"sqlite3",	sqlite3_plugin},
634 #endif
635 #ifdef WITH_MONGODB
636   {PLUGIN_ID_UNKNOWN,	"mongodb",		mongodb_legacy_warning},
637   {PLUGIN_ID_MONGODB,  	"mongodb_legacy",	mongodb_plugin},
638 #endif
639 #ifdef WITH_RABBITMQ
640   {PLUGIN_ID_AMQP,	"amqp",		amqp_plugin},
641 #endif
642 #ifdef WITH_KAFKA
643   {PLUGIN_ID_KAFKA,     "kafka",        kafka_plugin},
644 #endif
645   {PLUGIN_ID_TEE,	"tee",		tee_plugin},
646   {PLUGIN_ID_UNKNOWN,	"",		NULL},
647 };
648 
649 //Global variables
650 char *cfg[LARGEBUFLEN], *cfg_cmdline[SRVBUFLEN];
651 struct custom_primitives custom_primitives_registry;
652 pm_cfgreg_t custom_primitives_type;
653 int rows;
654 char default_proc_name[] = "default";
655 
656 /* evaluate_configuration() handles all supported configuration
657    keys and inserts them in configuration structure of plugins */
evaluate_configuration(char * filename,int rows)658 void evaluate_configuration(char *filename, int rows)
659 {
660   char *key, *value, *name, *delim;
661   int index = 0, dindex, valid_line, key_found = 0, res;
662 
663   while (index < rows) {
664     if (*cfg[index] == '\0') valid_line = FALSE;
665     else valid_line = TRUE;
666 
667     if (valid_line) {
668       /* debugging the line if required */
669       if (debug) Log(LOG_DEBUG, "DEBUG: [%s] %s\n", filename, cfg[index]);
670 
671       /* splitting key, value and name */
672       delim = strchr(cfg[index], ':');
673       *delim = '\0';
674       key = cfg[index];
675       value = delim+1;
676 
677       delim = strchr(key, '[');
678       if (delim) {
679         *delim = '\0';
680         name = delim+1;
681         delim = strchr(name, ']');
682         *delim = '\0';
683       }
684       else name = NULL;
685 
686       /* parsing keys */
687       for (dindex = 0; strcmp(dictionary[dindex].key, ""); dindex++) {
688         if (!strcmp(dictionary[dindex].key, key)) {
689 	  res = FALSE;
690           if ((*dictionary[dindex].func)) {
691 	    res = (*dictionary[dindex].func)(filename, name, value);
692 	    if (res < 0) Log(LOG_WARNING, "WARN: [%s:%u] Invalid value. Ignored.\n", filename, index+1);
693 	    else if (!res) Log(LOG_WARNING, "WARN: [%s:%u] Unknown symbol '%s'. Ignored.\n", filename, index+1, name);
694 	  }
695 	  else Log(LOG_WARNING, "WARN: [%s:%u] Unable to handle key: %s. Ignored.\n", filename, index+1, key);
696 	  key_found = TRUE;
697 	  break;
698         }
699 	else key_found = FALSE;
700       }
701 
702       if (!key_found) Log(LOG_WARNING, "WARN: [%s:%u] Unknown key: %s. Ignored.\n", filename, index+1, key);
703     }
704 
705     index++;
706   }
707 }
708 
709 /* parse_configuration_file() reads configuration file
710    and stores its content in an array; then creates
711    plugin structures and parses supported config keys */
parse_configuration_file(char * filename)712 int parse_configuration_file(char *filename)
713 {
714   char localbuf[10240];
715   char cmdline [] = "cmdline";
716   FILE *file;
717   int num = 0, cmdlineflag = FALSE, rows_cmdline = rows, idx;
718   rows = 0;
719 
720   /* NULL filename means we don't have a configuration file; 1st stage: read from
721      file and store lines into a first char* array; merge commandline options, if
722      required, placing them at the tail - in order to override directives placed
723      in the configuration file */
724   if (filename) {
725     if ((file = fopen(filename,"r")) == NULL) {
726       Log(LOG_ERR, "ERROR: [%s] file not found.\n", filename);
727       return ERR;
728     }
729     else {
730       while (!feof(file)) {
731         if (rows == LARGEBUFLEN) {
732 	  Log(LOG_ERR, "ERROR: [%s] maximum number of %d lines reached.\n", filename, LARGEBUFLEN);
733 	  break;
734         }
735 	memset(localbuf, 0, sizeof(localbuf));
736         if (fgets(localbuf, sizeof(localbuf), file) == NULL) break;
737         else {
738 	  localbuf[sizeof(localbuf)-1] = '\0';
739           cfg[rows] = malloc(strlen(localbuf)+2);
740 	  if (!cfg[rows]) {
741 	    Log(LOG_ERR, "ERROR: [%s] malloc() failed (parse_configuration_file). Exiting.\n", filename);
742 	    exit(1);
743 	  }
744           strcpy(cfg[rows], localbuf);
745           cfg[rows][strlen(localbuf)+1] = '\0';
746           rows++;
747         }
748       }
749     }
750     fclose(file);
751   }
752   else {
753     filename = cmdline;
754     cmdlineflag = TRUE;
755   }
756 
757   if (rows_cmdline) {
758     for (idx = 0; idx < rows_cmdline && (rows+idx) < LARGEBUFLEN; idx++) {
759       cfg[rows+idx] = cfg_cmdline[idx];
760     }
761     rows += idx;
762   }
763 
764   /* 2nd stage: sanitize lines */
765   sanitize_cfg(rows, filename);
766 
767   /* 3rd stage: plugin structures creation; we discard
768      plugin names if 'pmacctd' has been invoked commandline;
769      if any plugin has been activated we default to a single
770      'imt' plugin */
771   if (!cmdlineflag) parse_core_process_name(filename, rows, FALSE);
772   else parse_core_process_name(filename, rows, TRUE);
773 
774   if (!cmdlineflag) num = parse_plugin_names(filename, rows, FALSE);
775   else num = parse_plugin_names(filename, rows, TRUE);
776 
777   if (!num && config.acct_type < ACCT_FWPLANE_MAX) {
778     Log(LOG_WARNING, "WARN: [%s] No plugin has been activated; defaulting to in-memory table.\n", filename);
779     num = create_plugin(filename, "default_memory", "memory");
780   }
781 
782   if (debug) {
783     struct plugins_list_entry *list = plugins_list;
784 
785     while (list) {
786       Log(LOG_DEBUG, "DEBUG: [%s] plugin name/type: '%s'/'%s'.\n", filename, list->name, list->type.string);
787       list = list->next;
788     }
789   }
790 
791   /* 4th stage: setting some default value */
792   set_default_values();
793 
794   /* 5th stage: parsing keys and building configurations */
795   evaluate_configuration(filename, rows);
796 
797   return SUCCESS;
798 }
799 
sanitize_cfg(int rows,char * filename)800 void sanitize_cfg(int rows, char *filename)
801 {
802   int rindex = 0, len;
803   char localbuf[10240];
804 
805   while (rindex < rows) {
806     memset(localbuf, 0, 10240);
807 
808     /* checking the whole line: if it's a comment starting with
809        '!', it will be removed */
810     if (iscomment(cfg[rindex])) memset(cfg[rindex], 0, strlen(cfg[rindex]));
811 
812     /* checking the whole line: if it's void, it will be removed */
813     if (isblankline(cfg[rindex])) memset(cfg[rindex], 0, strlen(cfg[rindex]));
814 
815     /*
816        a pair of syntax checks on the whole line:
817        - does the line contain at least a ':' verb ?
818        - are the square brackets weighted both in key and value ?
819     */
820     len = strlen(cfg[rindex]);
821     if (len) {
822       int symbol = FALSE, cindex = 0, got_first = 0, got_first_colon = 0;
823 
824       if (!strchr(cfg[rindex], ':')) {
825 	Log(LOG_ERR, "ERROR: [%s:%u] Syntax error: missing ':'. Exiting.\n", filename, rindex+1);
826 	exit(1);
827       }
828 
829       while(cindex <= len) {
830         if (cfg[rindex][cindex] == '[') symbol++;
831         else if (cfg[rindex][cindex] == ']') {
832 	  symbol--;
833 	  got_first++;
834 	}
835 
836 	if (cfg[rindex][cindex] == ':' && !got_first_colon) {
837 	  got_first_colon = TRUE;
838 
839 	  if (symbol) {
840 	    Log(LOG_ERR, "ERROR: [%s:%u] Syntax error: illegal brackets. Exiting.\n", filename, rindex+1);
841 	    exit(1);
842 	  }
843 	}
844 
845 	if (cfg[rindex][cindex] == '\0') {
846 	  if (symbol && !got_first) {
847             Log(LOG_ERR, "ERROR: [%s:%u] Syntax error: not weighted brackets (1). Exiting.\n", filename, rindex+1);
848 	    exit(1);
849 	  }
850 	}
851 
852 	if (symbol < 0 && !got_first) {
853 	  Log(LOG_ERR, "ERROR: [%s:%u] Syntax error: not weighted brackets (2). Exiting.\n", filename, rindex+1);
854 	  exit(1);
855 	}
856 
857 	if (symbol > 1 && !got_first) {
858 	  Log(LOG_ERR, "ERROR: [%s:%u] Syntax error: nested symbols not allowed. Exiting.\n", filename, rindex+1);
859 	  exit(1);
860 	}
861 
862 	cindex++;
863       }
864     }
865 
866     /* checking the whole line: erasing unwanted spaces from key;
867        trimming start/end spaces from value; symbols will be left
868        untouched */
869     len = strlen(cfg[rindex]);
870     if (len) {
871       int symbol = FALSE, value = FALSE, cindex = 0, lbindex = 0;
872       char *valueptr = NULL;
873 
874       while(cindex <= len) {
875 	if (!value) {
876           if (cfg[rindex][cindex] == '[') symbol++;
877           else if (cfg[rindex][cindex] == ']') symbol--;
878 	  else if (cfg[rindex][cindex] == ':') {
879 	    value++;
880 	    valueptr = &localbuf[lbindex+1];
881 	  }
882 	}
883         if ((!symbol) && (!value)) {
884 	  if (!isspace(cfg[rindex][cindex])) {
885 	    localbuf[lbindex] = cfg[rindex][cindex];
886 	    lbindex++;
887 	  }
888         }
889         else {
890 	  localbuf[lbindex] = cfg[rindex][cindex];
891 	  lbindex++;
892         }
893         cindex++;
894       }
895       localbuf[lbindex] = '\0';
896       trim_spaces(valueptr);
897       strcpy(cfg[rindex], localbuf);
898     }
899 
900     /* checking key field: each symbol must refer to a key */
901     len = strlen(cfg[rindex]);
902     if (len) {
903       int symbol = FALSE, key = FALSE, cindex = 0;
904 
905       while (cindex < rows) {
906         if (cfg[rindex][cindex] == '[') symbol++;
907 	else if (cfg[rindex][cindex] == ']') {
908 	  symbol--;
909 	  key--;
910 	}
911 
912 	if (cfg[rindex][cindex] == ':') break;
913 
914 	if (!symbol) {
915 	  if (isalpha(cfg[rindex][cindex])) key = TRUE;
916 	}
917 	else {
918 	  if (!key) {
919             Log(LOG_ERR, "ERROR: [%s:%u] Syntax error: symbol not referring to any key. Exiting.\n", filename, rindex+1);
920 	    exit(1);
921 	  }
922 	}
923         cindex++;
924       }
925     }
926 
927 
928     /* checking key field: does a key still exist ? */
929     len = strlen(cfg[rindex]);
930     if (len) {
931       if (cfg[rindex][0] == ':') {
932 	Log(LOG_ERR, "ERROR: [%s:%u] Syntax error: missing key. Exiting.\n", filename, rindex+1);
933 	exit(1);
934       }
935     }
936 
937     /* checking key field: converting key to lower chars */
938     len = strlen(cfg[rindex]);
939     if (len) {
940       int symbol = FALSE, cindex = 0;
941 
942       while(cindex <= len) {
943         if (cfg[rindex][cindex] == '[') symbol++;
944 	else if (cfg[rindex][cindex] == ']') symbol--;
945 
946 	if (cfg[rindex][cindex] == ':') break;
947 	if (!symbol) {
948 	  if (isalpha(cfg[rindex][cindex]))
949 	    cfg[rindex][cindex] = tolower(cfg[rindex][cindex]);
950 	}
951 	cindex++;
952       }
953     }
954 
955     rindex++;
956   }
957 }
958 
parse_core_process_name(char * filename,int rows,int ignore_names)959 void parse_core_process_name(char *filename, int rows, int ignore_names)
960 {
961   int index = 0, found = 0;
962   char key[SRVBUFLEN], name[SRVBUFLEN], *start, *end;
963 
964   /* searching for 'core_proc_name' key */
965   while (index < rows) {
966     memset(key, 0, SRVBUFLEN);
967     start = NULL; end = NULL;
968 
969     start = cfg[index];
970     end = strchr(cfg[index], ':');
971     if (end > start) {
972       strlcpy(key, cfg[index], (end-start)+1);
973       if (!strncmp(key, "core_proc_name", sizeof("core_proc_name"))) {
974         start = end+1;
975         strlcpy(name, start, SRVBUFLEN);
976 	found = TRUE;
977         break;
978       }
979     }
980     index++;
981   }
982 
983   if (!found || ignore_names) create_plugin(filename, "default", "core");
984   else create_plugin(filename, name, "core");
985 }
986 
987 /* parse_plugin_names() leaves cfg array untouched: parses the key 'plugins'
988    if it exists and creates the plugins linked list */
parse_plugin_names(char * filename,int rows,int ignore_names)989 int parse_plugin_names(char *filename, int rows, int ignore_names)
990 {
991   int index = 0, num = 0, found = 0, default_name = FALSE;
992   char *start, *end, *start_name, *end_name;
993   char key[SRVBUFLEN], value[10240], token[SRVBUFLEN], name[SRVBUFLEN];
994 
995   /* searching for 'plugins' key */
996   while (index < rows) {
997     memset(key, 0, SRVBUFLEN);
998     start = NULL; end = NULL;
999 
1000     start = cfg[index];
1001     end = strchr(cfg[index], ':');
1002     if (end > start) {
1003       strlcpy(key, cfg[index], (end-start)+1);
1004       if (!strncmp(key, "plugins", sizeof("plugins"))) {
1005 	start = end+1;
1006 	strcpy(value, start);
1007 	found = TRUE;
1008 	break;
1009       }
1010     }
1011     index++;
1012   }
1013 
1014   if (!found) return 0;
1015 
1016   /* parsing declared plugins */
1017   start = value;
1018   while (*end != '\0') {
1019     memset(token, 0, SRVBUFLEN);
1020     if (!(end = strchr(start, ','))) end = strchr(start, '\0');
1021     if (end > start) {
1022       strlcpy(token, start, (end-start)+1);
1023       if ((start_name = strchr(token, '[')) && (end_name = strchr(token, ']'))) {
1024         if (end_name > (start_name+1)) {
1025           strlcpy(name, (start_name+1), (end_name-start_name));
1026 	  trim_spaces(name);
1027 	  *start_name = '\0';
1028 	}
1029       }
1030       else default_name = TRUE;
1031 
1032       /* Having already plugins name and type, we'll filter out reserved symbols */
1033       trim_spaces(token);
1034       lower_string(token);
1035       if (!strcmp(token, "core")) {
1036         Log(LOG_ERR, "ERROR: [%s] plugins of type 'core' are not allowed. Exiting.\n", filename);
1037         exit(1);
1038       }
1039 
1040       if (!ignore_names) {
1041         if (default_name) compose_default_plugin_name(name, SRVBUFLEN, token);
1042         if (create_plugin(filename, name, token)) num++;
1043       }
1044       else {
1045         compose_default_plugin_name(name, SRVBUFLEN, token);
1046         if (create_plugin(filename, name, token)) num++;
1047       }
1048     }
1049     start = end+1;
1050   }
1051 
1052   /* having already processed it, we erase 'plugins' line */
1053   memset(cfg[index], 0, strlen(cfg[index]));
1054 
1055   return num;
1056 }
1057 
1058 /* rough and dirty function to assign default values to
1059    configuration file of each plugin */
set_default_values()1060 void set_default_values()
1061 {
1062   struct plugins_list_entry *list = plugins_list;
1063 
1064   while (list) {
1065     list->cfg.promisc = TRUE;
1066     list->cfg.maps_refresh = TRUE;
1067 
1068     list = list->next;
1069   }
1070 }
1071 
compose_default_plugin_name(char * out,int outlen,char * type)1072 void compose_default_plugin_name(char *out, int outlen, char *type)
1073 {
1074   strcpy(out, "default");
1075   strcat(out, "_");
1076   strncat(out, type, (outlen - 10));
1077 }
1078 
create_plugin(char * filename,char * name,char * type)1079 int create_plugin(char *filename, char *name, char *type)
1080 {
1081   struct plugins_list_entry *plugin, *ptr;
1082   struct plugin_type_entry *ptype = NULL;
1083   int index = 0, id = 0;
1084 
1085   /* searching for a valid known plugin type */
1086   while(strcmp(plugin_types_list[index].string, "")) {
1087     if (!strcmp(type, plugin_types_list[index].string)) ptype = &plugin_types_list[index];
1088     index++;
1089   }
1090 
1091   if (!ptype) {
1092     Log(LOG_ERR, "ERROR: [%s] Unknown plugin type: %s. Ignoring.\n", filename, type);
1093     return FALSE;
1094   }
1095 
1096   /* checks */
1097   if (plugins_list) {
1098     id = 0;
1099     ptr = plugins_list;
1100 
1101     while (ptr) {
1102       /* plugin id */
1103       if (ptr->id > id) id = ptr->id;
1104 
1105       /* dupes */
1106       if (!strcmp(name, ptr->name)) {
1107         Log(LOG_WARNING, "WARN: [%s] another plugin with the same name '%s' already exists. Preserving first.\n", filename, name);
1108         return FALSE;
1109       }
1110       ptr = ptr->next;
1111     }
1112     id++;
1113   }
1114 
1115   /* creating a new plugin structure */
1116   plugin = (struct plugins_list_entry *) malloc(sizeof(struct plugins_list_entry));
1117   if (!plugin) {
1118     Log(LOG_ERR, "ERROR: [%s] malloc() failed (create_plugin). Exiting.\n", filename);
1119     exit(1);
1120   }
1121 
1122   memset(plugin, 0, sizeof(struct plugins_list_entry));
1123 
1124   strcpy(plugin->name, name);
1125   plugin->id = id;
1126   memcpy(&plugin->type, ptype, sizeof(struct plugin_type_entry));
1127   plugin->next = NULL;
1128 
1129   /* inserting our object in plugin's linked list */
1130   if (plugins_list) {
1131     ptr = plugins_list;
1132     while(ptr->next) ptr = ptr->next;
1133     ptr->next = plugin;
1134   }
1135   else plugins_list = plugin;
1136 
1137   return TRUE;
1138 }
1139 
delete_plugin_by_id(int id)1140 int delete_plugin_by_id(int id)
1141 {
1142   struct plugins_list_entry *list = plugins_list;
1143   struct plugins_list_entry *aux = plugins_list;
1144   int highest_id = 0;
1145 
1146   if (id == 0) return ERR;
1147 
1148   while (list) {
1149     if (list->id == id) {
1150       aux->next = list->next;
1151       free(list);
1152       list = aux;
1153     }
1154     else {
1155       if (list->id > highest_id) highest_id = list->id;
1156     }
1157     aux = list;
1158     list = list->next;
1159   }
1160 
1161   return highest_id;
1162 }
1163 
search_plugin_by_pipe(int pipe)1164 struct plugins_list_entry *search_plugin_by_pipe(int pipe)
1165 {
1166   struct plugins_list_entry *list = plugins_list;
1167 
1168   if (pipe < 0) return NULL;
1169 
1170   while (list) {
1171     if (list->pipe[1] == pipe) return list;
1172     else list = list->next;
1173   }
1174 
1175   return NULL;
1176 }
1177 
search_plugin_by_pid(pid_t pid)1178 struct plugins_list_entry *search_plugin_by_pid(pid_t pid)
1179 {
1180   struct plugins_list_entry *list = plugins_list;
1181 
1182   if (pid <= 0) return NULL;
1183 
1184   while (list) {
1185     if (list->pid == pid) return list;
1186     else list = list->next;
1187   }
1188 
1189   return NULL;
1190 }
1191