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 #include "pmacct.h"
23 #include "addr.h"
24 #include "bgp/bgp_packet.h"
25 #include "bgp/bgp.h"
26 #include "nfacctd.h"
27 #include "sflow.h"
28 #include "sfacctd.h"
29 #include "pretag_handlers.h"
30 #include "net_aggr.h"
31 #include "bgp/bgp.h"
32 #include "rpki/rpki.h"
33 #include "pmacct-data.h"
34 #include "plugin_hooks.h"
35 #include "pkt_handlers.h"
36 
PT_map_id_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)37 int PT_map_id_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
38 {
39   struct host_addr a;
40   char *endptr = NULL, *incptr;
41   pm_id_t j = 0, z = 0;
42   int x, inc = 0;
43 
44   e->id = 0;
45   e->flags = FALSE;
46 
47   /* If we parse a bgp_agent_map and spot a '.' within the string let's
48      check if we are given a valid IPv4 address */
49   if (acct_type == MAP_BGP_TO_XFLOW_AGENT && strchr(value, '.')) {
50     memset(&a, 0, sizeof(a));
51     str_to_addr(value, &a);
52     if (a.family == AF_INET) j = a.address.ipv4.s_addr;
53     else {
54       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] ID does not appear to be a valid IPv4 address.\n", config.name, config.type, filename);
55       return TRUE;
56     }
57   }
58   /* If we parse a bgp_agent_map and spot a ':' within the string let's
59      check if we are given a valid IPv6 address */
60   else if (acct_type == MAP_BGP_TO_XFLOW_AGENT && strchr(value, ':')) {
61     memset(&a, 0, sizeof(a));
62     str_to_addr(value, &a);
63     if (a.family == AF_INET6) {
64       ip6_addr_32bit_cpy(&j, &a.address.ipv6, 0, 0, 1);
65       ip6_addr_32bit_cpy(&z, &a.address.ipv6, 0, 2, 3);
66 
67       e->flags = BTA_MAP_RCODE_ID_ID2;
68     }
69     else {
70       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] ID does not appear to be a valid IPv6 address.\n", config.name, config.type, filename);
71       return TRUE;
72     }
73   }
74   else if (acct_type == MAP_FLOW_TO_RD && strchr(value, ':')) {
75     rd_t rd;
76 
77     bgp_str2rd(&rd, value);
78     memcpy(&j, &rd, sizeof(rd));
79   }
80   /* If we spot the word "bgp", let's check this is a map that supports it */
81   else if ((acct_type == MAP_BGP_PEER_AS_SRC || acct_type == MAP_BGP_SRC_LOCAL_PREF ||
82 	   acct_type == MAP_BGP_SRC_MED) && !strncmp(value, "bgp", strlen("bgp"))) {
83     e->flags = BPAS_MAP_RCODE_BGP;
84   }
85   else {
86     if ((incptr = strstr(value, "++"))) {
87       inc = TRUE;
88       *incptr = '\0';
89     }
90 
91     j = strtoull(value, &endptr, 10);
92     if (j > UINT64_MAX) {
93       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Invalid set_tag/id specified.\n", config.name, config.type, filename);
94       return TRUE;
95     }
96   }
97 
98   e->id = j;
99   if (z) e->id2 = z;
100   if (inc) e->id_inc = TRUE;
101 
102   if (acct_type == ACCT_NF || acct_type == ACCT_SF || acct_type == ACCT_PM) {
103     for (x = 0; e->set_func[x]; x++) {
104       if (e->set_func_type[x] == PRETAG_SET_TAG) {
105         Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'set_tag' (id) clauses part of the same statement.\n", config.name, config.type, filename);
106         return TRUE;
107       }
108     }
109 
110     e->set_func[x] = pretag_id_handler;
111     e->set_func_type[x] = PRETAG_SET_TAG;
112   }
113 
114   return FALSE;
115 }
116 
PT_map_id2_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)117 int PT_map_id2_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
118 {
119   char *endptr = NULL, *incptr;
120   pm_id_t j;
121   int x, inc = 0;
122 
123   if ((incptr = strstr(value, "++"))) {
124     inc = TRUE;
125     *incptr = '\0';
126   }
127 
128   j = strtoull(value, &endptr, 10);
129   if (j > UINT64_MAX) {
130     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Invalid set_tag2/id2 specified.\n", config.name, config.type, filename);
131     return TRUE;
132   }
133   e->id2 = j;
134   if (inc) e->id2_inc = TRUE;
135 
136   if (acct_type == ACCT_NF || acct_type == ACCT_SF || acct_type == ACCT_PM) {
137     for (x = 0; e->set_func[x]; x++) {
138       if (e->set_func_type[x] == PRETAG_SET_TAG2) {
139         Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'set_tag2' (id2) clauses part of the same statement.\n", config.name, config.type, filename);
140         return TRUE;
141       }
142     }
143 
144     e->set_func[x] = pretag_id2_handler;
145     e->set_func_type[x] = PRETAG_SET_TAG2;
146   }
147 
148   return FALSE;
149 }
150 
PT_map_label_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)151 int PT_map_label_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
152 {
153   char default_sep = ',';
154   int x, len;
155 
156   // XXX: isprint check?
157 
158   len = strlen(value);
159   if (!strchr(value, default_sep)) {
160     if (pretag_malloc_label(&e->label, len + 1 /* null */)) return TRUE;
161     strcpy(e->label.val, value);
162     e->label.len = len;
163     e->label.val[e->label.len] = '\0';
164   }
165   else {
166     e->label.val = NULL;
167     e->label.len = 0;
168 
169     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Invalid set_label specified.\n", config.name, config.type, filename);
170     return TRUE;
171   }
172 
173   if (acct_type == ACCT_NF || acct_type == ACCT_SF || acct_type == ACCT_PM) {
174     for (x = 0; e->set_func[x]; x++) {
175       if (e->set_func_type[x] == PRETAG_SET_LABEL) {
176         Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'set_label' clauses part of the same statement.\n", config.name, config.type, filename);
177         return TRUE;
178       }
179     }
180 
181     e->set_func[x] = pretag_label_handler;
182     e->set_func_type[x] = PRETAG_SET_LABEL;
183   }
184 
185   return FALSE;
186 }
187 
PT_map_ip_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)188 int PT_map_ip_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
189 {
190   int x = 0;
191 
192   if (!str_to_addr_mask(value, &e->key.agent_ip.a, &e->key.agent_mask)) {
193     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Bad IP address or prefix '%s'.\n", config.name, config.type, filename, value);
194     return TRUE;
195   }
196 
197   for (x = 0; e->func[x]; x++) {
198     if (e->func_type[x] == PRETAG_IP) {
199       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'ip' clauses part of the same statement.\n", config.name, config.type, filename);
200       return TRUE;
201     }
202   }
203 
204   e->func[x] = pretag_dummy_ip_handler;
205   if (e->func[x]) e->func_type[x] = PRETAG_IP;
206 
207   return FALSE;
208 }
209 
PT_map_input_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)210 int PT_map_input_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
211 {
212   int x = 0, len;
213   char *endptr;
214 
215   if (acct_type == MAP_SAMPLING) sampling_map_caching = FALSE;
216   if (acct_type == MAP_BGP_TO_XFLOW_AGENT) bta_map_caching = FALSE;
217   if (req->ptm_c.load_ptm_plugin == PLUGIN_ID_TEE) req->ptm_c.load_ptm_res = TRUE;
218 
219   e->key.input.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
220   len = strlen(value);
221 
222   while (x < len) {
223     if (!isdigit(value[x])) {
224       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] bad 'in' value: '%s'.\n", config.name, config.type, filename, value);
225       return TRUE;
226     }
227     x++;
228   }
229 
230   e->key.input.n = strtoul(value, &endptr, 10);
231   for (x = 0; e->func[x]; x++) {
232     if (e->func_type[x] == PRETAG_IN_IFACE) {
233       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'input' clauses part of the same statement.\n", config.name, config.type, filename);
234       return TRUE;
235     }
236   }
237   if (config.acct_type == ACCT_NF) e->func[x] = pretag_input_handler;
238   else if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_input_handler;
239   else if (config.acct_type == ACCT_PM) e->func[x] = PM_pretag_input_handler;
240   if (e->func[x]) e->func_type[x] = PRETAG_IN_IFACE;
241 
242   return FALSE;
243 }
244 
PT_map_output_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)245 int PT_map_output_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
246 {
247   int x = 0, len;
248   char *endptr;
249 
250   if (acct_type == MAP_SAMPLING) sampling_map_caching = FALSE;
251   if (acct_type == MAP_BGP_TO_XFLOW_AGENT) bta_map_caching = FALSE;
252   if (req->ptm_c.load_ptm_plugin == PLUGIN_ID_TEE) req->ptm_c.load_ptm_res = TRUE;
253 
254   e->key.output.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
255   len = strlen(value);
256 
257   while (x < len) {
258     if (!isdigit(value[x])) {
259       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] bad 'out' value: '%s'.\n", config.name, config.type, filename, value);
260       return TRUE;
261     }
262     x++;
263   }
264 
265   e->key.output.n = strtoul(value, &endptr, 10);
266   for (x = 0; e->func[x]; x++) {
267     if (e->func_type[x] == PRETAG_OUT_IFACE) {
268       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'output' clauses part of the same statement.\n", config.name, config.type, filename);
269       return TRUE;
270     }
271   }
272   if (config.acct_type == ACCT_NF) e->func[x] = pretag_output_handler;
273   else if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_output_handler;
274   else if (config.acct_type == ACCT_PM) e->func[x] = PM_pretag_output_handler;
275   if (e->func[x]) e->func_type[x] = PRETAG_OUT_IFACE;
276 
277   return FALSE;
278 }
279 
PT_map_nexthop_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)280 int PT_map_nexthop_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
281 {
282   int x = 0;
283 
284   e->key.nexthop.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
285 
286   if (!str_to_addr(value, &e->key.nexthop.a)) {
287     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Bad nexthop address '%s'.\n", config.name, config.type, filename, value);
288     return TRUE;
289   }
290 
291   for (x = 0; e->func[x]; x++) {
292     if (e->func_type[x] == PRETAG_NEXTHOP) {
293       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'nexthop' clauses part of the same statement.\n", config.name, config.type, filename);
294       return TRUE;
295     }
296   }
297   if (config.acct_type == ACCT_NF) e->func[x] = pretag_nexthop_handler;
298   else if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_nexthop_handler;
299   if (e->func[x]) e->func_type[x] = PRETAG_NEXTHOP;
300 
301   return FALSE;
302 }
303 
PT_map_bgp_nexthop_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)304 int PT_map_bgp_nexthop_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
305 {
306   int x = 0, have_bgp = 0;
307 
308   if (req->ptm_c.load_ptm_plugin == PLUGIN_ID_TEE) req->ptm_c.load_ptm_res = TRUE;
309 
310   e->key.bgp_nexthop.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
311 
312   if (!str_to_addr(value, &e->key.bgp_nexthop.a)) {
313     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Bad BGP nexthop address '%s'.\n", config.name, config.type, filename, value);
314     return TRUE;
315   }
316 
317   for (x = 0; e->func[x]; x++) {
318     if (e->func_type[x] == PRETAG_BGP_NEXTHOP) {
319       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'bgp_nexthop' clauses part of the same statement.\n", config.name, config.type, filename);
320       return TRUE;
321     }
322   }
323 
324   if (config.nfacctd_net & NF_NET_BGP) {
325     e->func[x] = pretag_bgp_bgp_nexthop_handler;
326     have_bgp = TRUE;
327     e->func_type[x] = PRETAG_BGP_NEXTHOP;
328     x++;
329   }
330 
331   /* XXX: IGP? */
332 
333   if (config.nfacctd_net & NF_NET_KEEP && config.acct_type == ACCT_NF) {
334     e->func[x] = pretag_bgp_nexthop_handler;
335     e->func_type[x] = PRETAG_BGP_NEXTHOP;
336     return FALSE;
337   }
338   else if (config.nfacctd_net & NF_NET_KEEP && config.acct_type == ACCT_SF) {
339     e->func[x] = SF_pretag_bgp_nexthop_handler;
340     e->func_type[x] = PRETAG_BGP_NEXTHOP;
341     return FALSE;
342   }
343 
344   if (have_bgp) return FALSE;
345 
346   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'bgp_nexthop' is not supported when a 'networks_file' is specified or by the 'pmacctd' daemon.\n", config.name, config.type, filename);
347 
348   return TRUE;
349 }
350 
BPAS_map_bgp_nexthop_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)351 int BPAS_map_bgp_nexthop_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
352 {
353   int x = 0;
354 
355   e->key.bgp_nexthop.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
356 
357   if (!str_to_addr(value, &e->key.bgp_nexthop.a)) {
358     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Bad BGP nexthop address '%s'.\n", config.name, config.type, filename, value);
359     return TRUE;
360   }
361 
362   for (x = 0; e->func[x]; x++);
363   if (config.bgp_daemon) {
364     e->func[x] = BPAS_bgp_nexthop_handler;
365     e->func_type[x] = PRETAG_BGP_NEXTHOP;
366   }
367 
368   return FALSE;
369 }
370 
BPAS_map_bgp_peer_dst_as_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)371 int BPAS_map_bgp_peer_dst_as_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
372 {
373   as_t tmp;
374   int x = 0;
375   char *endptr;
376 
377   e->key.peer_dst_as.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
378 
379   tmp = strtoul(value, &endptr, 10);
380   e->key.peer_dst_as.n = tmp;
381 
382   for (x = 0; e->func[x]; x++);
383   if (config.bgp_daemon) {
384     e->func[x] = BPAS_bgp_peer_dst_as_handler;
385     e->func_type[x] = PRETAG_BGP_NEXTHOP;
386   }
387 
388   return FALSE;
389 }
390 
BITR_map_mpls_label_bottom_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)391 int BITR_map_mpls_label_bottom_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
392 {
393   as_t tmp;
394   int x = 0;
395   char *endptr;
396 
397   e->key.mpls_label_bottom.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
398 
399   tmp = strtoul(value, &endptr, 10);
400   e->key.mpls_label_bottom.n = tmp;
401 
402   for (x = 0; e->func[x]; x++);
403 
404   /* Currently supported only in nfacctd */
405   if (config.acct_type == ACCT_NF) e->func[x] = BITR_mpls_label_bottom_handler;
406   if (e->func[x]) e->func_type[x] = PRETAG_MPLS_LABEL_BOTTOM;
407 
408   return FALSE;
409 }
410 
BITR_map_mpls_vpn_id_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)411 int BITR_map_mpls_vpn_id_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
412 {
413   int x = 0;
414   char *endptr;
415 
416   e->key.mpls_vpn_id.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
417   e->key.mpls_vpn_id.n = strtoul(value, &endptr, 10);
418 
419   if (!e->key.mpls_vpn_id.n) {
420     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Bad MPLS VPN ID value '%u'.\n", config.name, config.type, filename, e->key.mpls_vpn_id.n);
421     return TRUE;
422   }
423 
424   for (x = 0; e->func[x]; x++) {
425     if (e->func_type[x] == PRETAG_MPLS_VPN_ID) {
426       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'mpls_vpn_id' clauses part of the same statement.\n", config.name, config.type, filename);
427       return TRUE;
428     }
429   }
430 
431   if (config.acct_type == ACCT_NF) e->func[x] = BITR_mpls_vpn_id_handler;
432   if (e->func[x]) e->func_type[x] = PRETAG_MPLS_VPN_ID;
433 
434   return FALSE;
435 }
436 
PT_map_engine_type_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)437 int PT_map_engine_type_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
438 {
439   int x = 0, j, len;
440 
441   e->key.engine_type.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
442   len = strlen(value);
443 
444   while (x < len) {
445     if (!isdigit(value[x])) {
446       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] bad 'engine_type' value: '%s'.\n", config.name, config.type, filename, value);
447       return TRUE;
448     }
449     x++;
450   }
451 
452   j = atoi(value);
453   if (j > 255) {
454     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] bad 'engine_type' value (range: 0 >= value > 256).\n", config.name, config.type, filename);
455     return TRUE;
456   }
457   e->key.engine_type.n = j;
458 
459   for (x = 0; e->func[x]; x++) {
460     if (e->func_type[x] == PRETAG_ENGINE_TYPE) {
461       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'engine_type' clauses part of the same statement.\n", config.name, config.type, filename);
462       return TRUE;
463     }
464   }
465   if (config.acct_type == ACCT_NF) e->func[x] = pretag_engine_type_handler;
466   if (e->func[x]) e->func_type[x] = PRETAG_ENGINE_TYPE;
467 
468   return FALSE;
469 }
470 
PT_map_engine_id_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)471 int PT_map_engine_id_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
472 {
473   int x = 0, len;
474   char *endptr;
475 
476   e->key.engine_id.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
477   len = strlen(value);
478 
479   while (x < len) {
480     if (!isdigit(value[x])) {
481       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] bad 'engine_id' or 'source_id' value: '%s'.\n", config.name, config.type, filename, value);
482       return TRUE;
483     }
484     x++;
485   }
486 
487   e->key.engine_id.n = strtoul(value, &endptr, 10);
488 
489   for (x = 0; e->func[x]; x++) {
490     if (e->func_type[x] == PRETAG_ENGINE_ID) {
491       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'engine_id' clauses part of the same statement.\n", config.name, config.type, filename);
492       return TRUE;
493     }
494   }
495 
496   if (config.acct_type == ACCT_NF) e->func[x] = pretag_engine_id_handler;
497   if (e->func[x]) e->func_type[x] = PRETAG_ENGINE_ID;
498 
499   return FALSE;
500 }
501 
PT_map_filter_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)502 int PT_map_filter_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
503 {
504   struct pm_pcap_device dev;
505   bpf_u_int32 localnet, netmask;  /* pcap library stuff */
506   char errbuf[PCAP_ERRBUF_SIZE];
507   int x;
508 
509   if (acct_type == MAP_BGP_TO_XFLOW_AGENT) {
510     if (strncmp(value, "ip", 2) && strncmp(value, "ip6", 3) && strncmp(value, "vlan and ip", 11) && strncmp(value, "vlan and ip6", 12)) {
511       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] bgp_agent_map filter supports only 'ip', 'ip6', 'vlan and ip' and 'vlan and ip6' keywords\n",
512 	  config.name, config.type, filename);
513       return TRUE;
514     }
515   }
516 
517   memset(&dev, 0, sizeof(struct pm_pcap_device));
518   // XXX: fix if multiple interfaces
519   if (devices.list[0].dev_desc) dev.link_type = pcap_datalink(devices.list[0].dev_desc);
520   else if (config.uacctd_group) dev.link_type = DLT_RAW;
521   else dev.link_type = 1;
522   dev.dev_desc = pcap_open_dead(dev.link_type, 128); /* snaplen=eth_header+pm_iphdr+pm_tlhdr */
523 
524   pcap_lookupnet(config.pcap_if, &localnet, &netmask, errbuf);
525   if (pcap_compile(dev.dev_desc, &e->key.filter, value, 0, netmask) < 0) {
526     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] malformed filter: %s\n", config.name, config.type, filename, pcap_geterr(dev.dev_desc));
527     return TRUE;
528   }
529 
530   pcap_close(dev.dev_desc);
531 
532   for (x = 0; e->func[x]; x++) {
533     if (e->func_type[x] == PRETAG_FILTER) {
534       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'filter' clauses part of the same statement.\n", config.name, config.type, filename);
535       return TRUE;
536     }
537   }
538 
539   e->func[x] = pretag_filter_handler;
540   if (e->func[x]) e->func_type[x] = PRETAG_FILTER;
541   req->bpf_filter = TRUE;
542   return FALSE;
543 }
544 
PT_map_agent_id_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)545 int PT_map_agent_id_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
546 {
547   int x = 0;
548 
549   e->key.agent_id.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
550   e->key.agent_id.n = atoi(value);
551   for (x = 0; e->func[x]; x++) {
552     if (e->func_type[x] == PRETAG_SF_AGENTID) {
553       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'agent_id' clauses part of the same statement.\n", config.name, config.type, filename);
554       return TRUE;
555     }
556   }
557   if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_agent_id_handler;
558   if (e->func[x]) e->func_type[x] = PRETAG_SF_AGENTID;
559 
560   return FALSE;
561 }
562 
PT_map_flowset_id_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)563 int PT_map_flowset_id_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
564 {
565   int x = 0;
566 
567   e->key.flowset_id.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
568   e->key.flowset_id.n = htons(atoi(value));
569   for (x = 0; e->func[x]; x++) {
570     if (e->func_type[x] == PRETAG_FLOWSET_ID) {
571       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'flowset_id' clauses part of the same statement.\n", config.name, config.type, filename);
572       return TRUE;
573     }
574   }
575   if (config.acct_type == ACCT_NF) e->func[x] = pretag_flowset_id_handler;
576   if (e->func[x]) e->func_type[x] = PRETAG_FLOWSET_ID;
577 
578   return FALSE;
579 }
580 
PT_map_sample_type_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)581 int PT_map_sample_type_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
582 {
583   char *token = NULL;
584   u_int32_t tmp;
585   int x = 0;
586 
587   e->key.sample_type.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
588 
589   if (acct_type == ACCT_SF && strchr(value, ':')) {
590     while ((token = extract_token(&value, ':'))) {
591       switch (x) {
592       case 0:
593         tmp = atoi(token);
594         if (tmp > 1048575) { // 2^20-1: 20 bit Enterprise value
595           Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Invalid 'sample_type' value.\n", config.name, config.type, filename);
596           return TRUE;
597         }
598         e->key.sample_type.n = tmp;
599         e->key.sample_type.n <<= 12;
600         break;
601       case 1:
602         tmp = atoi(token);
603         if (tmp > 4095) { // 2^12-1: 12 bit Format value
604           Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Invalid 'sample_type' value.\n", config.name, config.type, filename);
605           return TRUE;
606         }
607         e->key.sample_type.n |= tmp;
608         break;
609       default:
610         Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Invalid 'sample_type' value.\n", config.name, config.type, filename);
611         return TRUE;
612       }
613 
614       x++;
615     }
616   }
617   else if (acct_type == ACCT_NF) {
618     if (!strncmp(value, "flow", strlen("flow")))
619       e->key.sample_type.n = NF9_FTYPE_TRAFFIC;
620     else if (!strncmp(value, "event", strlen("event")))
621       e->key.sample_type.n = NF9_FTYPE_EVENT;
622     else if (!strncmp(value, "option", strlen("option")))
623       e->key.sample_type.n = NF9_FTYPE_OPTION;
624     else {
625       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Invalid 'sample_type' value.\n", config.name, config.type, filename);
626       return TRUE;
627     }
628   }
629   else return FALSE; /* silently ignore */
630 
631   for (x = 0; e->func[x]; x++) {
632     if (e->func_type[x] == PRETAG_SAMPLE_TYPE) {
633       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'sample_type' clauses part of the same statement.\n", config.name, config.type, filename);
634       return TRUE;
635     }
636   }
637 
638   if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_sample_type_handler;
639   else if (config.acct_type == ACCT_NF) e->func[x] = pretag_sample_type_handler;
640   if (e->func[x]) e->func_type[x] = PRETAG_SAMPLE_TYPE;
641 
642   return FALSE;
643 }
644 
PT_map_direction_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)645 int PT_map_direction_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
646 {
647   int x = 0;
648 
649   e->key.direction.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
650   e->key.direction.n = atoi(value);
651   for (x = 0; e->func[x]; x++) {
652     if (e->func_type[x] == PRETAG_DIRECTION) {
653       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'direction' clauses part of the same statement.\n", config.name, config.type, filename);
654       return TRUE;
655     }
656   }
657 
658   if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_direction_handler;
659   else if (config.acct_type == ACCT_NF) e->func[x] = pretag_direction_handler;
660   else if (config.acct_type == ACCT_PM) e->func[x] = PM_pretag_direction_handler;
661   if (e->func[x]) e->func_type[x] = PRETAG_DIRECTION;
662 
663   return FALSE;
664 }
665 
PT_map_nat_event_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)666 int PT_map_nat_event_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
667 {
668   int x = 0;
669 
670   e->key.nat_event.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
671   e->key.nat_event.n = atoi(value);
672   for (x = 0; e->func[x]; x++) {
673     if (e->func_type[x] == PRETAG_NAT_EVENT) {
674       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'nat_event' clauses part of the same statement.\n", config.name, config.type, filename);
675       return TRUE;
676     }
677   }
678 
679   if (config.acct_type == ACCT_NF) e->func[x] = pretag_nat_event_handler;
680   if (e->func[x]) e->func_type[x] = PRETAG_NAT_EVENT;
681 
682   return FALSE;
683 }
684 
PT_map_src_as_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)685 int PT_map_src_as_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
686 {
687   as_t tmp;
688   int x = 0, have_bgp = 0;
689   char *endptr;
690 
691   e->key.src_as.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
692 
693   tmp = strtoul(value, &endptr, 10);
694 
695   e->key.src_as.n = tmp;
696   for (x = 0; e->func[x]; x++) {
697     if (e->func_type[x] == PRETAG_SRC_AS) {
698       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'src_as' clauses part of the same statement.\n", config.name, config.type, filename);
699       return TRUE;
700     }
701   }
702 
703   if (config.nfacctd_as & NF_AS_BGP) {
704     e->func[x] = pretag_bgp_src_as_handler;
705     e->func_type[x] = PRETAG_SRC_AS;
706     have_bgp = TRUE;
707     x++;
708   }
709 
710   if ((config.nfacctd_as & NF_AS_NEW || config.acct_type == ACCT_PM) && config.networks_file) {
711     req->bpf_filter = TRUE;
712     e->func[x] = PM_pretag_src_as_handler;
713     e->func_type[x] = PRETAG_SRC_AS;
714     return FALSE;
715   }
716   else if (config.nfacctd_as & NF_AS_KEEP && config.acct_type == ACCT_NF) {
717     e->func[x] = pretag_src_as_handler;
718     e->func_type[x] = PRETAG_SRC_AS;
719     return FALSE;
720   }
721   else if (config.nfacctd_as & NF_AS_KEEP && config.acct_type == ACCT_SF) {
722     e->func[x] = SF_pretag_src_as_handler;
723     e->func_type[x] = PRETAG_SRC_AS;
724     return FALSE;
725   }
726 
727   if (have_bgp) return FALSE;
728 
729   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'src_as' requires either 'networks_file' or 'nf|sfacctd_as: false' to be specified.\n", config.name, config.type, filename);
730 
731   return TRUE;
732 }
733 
PT_map_dst_as_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)734 int PT_map_dst_as_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
735 {
736   as_t tmp;
737   int x = 0, have_bgp = 0;
738   char *endptr;
739 
740   e->key.dst_as.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
741 
742   tmp = strtoul(value, &endptr, 10);
743 
744   e->key.dst_as.n = tmp;
745   for (x = 0; e->func[x]; x++) {
746     if (e->func_type[x] == PRETAG_DST_AS) {
747       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'dst_as' clauses part of the same statement.\n", config.name, config.type, filename);
748       return TRUE;
749     }
750   }
751 
752   if (config.nfacctd_as & NF_AS_BGP) {
753     e->func[x] = pretag_bgp_dst_as_handler;
754     e->func_type[x] = PRETAG_DST_AS;
755     have_bgp = TRUE;
756     x++;
757   }
758 
759   if ((config.nfacctd_as & NF_AS_NEW || config.acct_type == ACCT_PM) && config.networks_file) {
760     req->bpf_filter = TRUE;
761     e->func[x] = PM_pretag_dst_as_handler;
762     e->func_type[x] = PRETAG_DST_AS;
763     return FALSE;
764   }
765   else if (config.nfacctd_as & NF_AS_KEEP && config.acct_type == ACCT_NF) {
766     e->func[x] = pretag_dst_as_handler;
767     e->func_type[x] = PRETAG_DST_AS;
768     return FALSE;
769   }
770   else if (config.nfacctd_as & NF_AS_KEEP && config.acct_type == ACCT_SF) {
771     e->func[x] = SF_pretag_dst_as_handler;
772     e->func_type[x] = PRETAG_DST_AS;
773     return FALSE;
774   }
775 
776   if (have_bgp) return FALSE;
777 
778   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'dst_as' requires either 'networks_file' or 'nf|sfacctd_as: false' to be specified.\n", config.name, config.type, filename);
779 
780   return TRUE;
781 }
782 
PT_map_peer_src_as_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)783 int PT_map_peer_src_as_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
784 {
785   as_t tmp;
786   int x = 0;
787   char *endptr;
788 
789   e->key.peer_src_as.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
790 
791   tmp = strtoul(value, &endptr, 10);
792 
793   e->key.peer_src_as.n = tmp;
794   for (x = 0; e->func[x]; x++) {
795     if (e->func_type[x] == PRETAG_PEER_SRC_AS) {
796       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'peer_src_as' clauses part of the same statement.\n", config.name, config.type, filename);
797       return TRUE;
798     }
799   }
800 
801   if (config.nfacctd_as & NF_AS_BGP) {
802     e->func[x] = pretag_peer_src_as_handler;
803     e->func_type[x] = PRETAG_PEER_SRC_AS;
804     return FALSE;
805   }
806 
807   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'peer_src_as' requires '[nf|sf]acctd_as_new: [ bgp | longest ]' to be specified.\n", config.name, config.type, filename);
808 
809   return TRUE;
810 }
811 
PT_map_peer_dst_as_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)812 int PT_map_peer_dst_as_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
813 {
814   as_t tmp;
815   int x = 0;
816   char *endptr;
817 
818   e->key.peer_dst_as.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
819 
820   tmp = strtoul(value, &endptr, 10);
821 
822   e->key.peer_dst_as.n = tmp;
823   for (x = 0; e->func[x]; x++) {
824     if (e->func_type[x] == PRETAG_PEER_DST_AS) {
825       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'peer_dst_as' clauses part of the same statement.\n", config.name, config.type, filename);
826       return TRUE;
827     }
828   }
829 
830   if (config.nfacctd_as & NF_AS_BGP) {
831     e->func[x] = pretag_peer_dst_as_handler;
832     e->func_type[x] = PRETAG_PEER_DST_AS;
833     return FALSE;
834   }
835 
836   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'peer_dst_as' requires '[nf|sf]acctd_as_new: [ bgp | longest ]' to be specified.\n", config.name, config.type, filename);
837 
838   return TRUE;
839 }
840 
PT_map_src_local_pref_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)841 int PT_map_src_local_pref_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
842 {
843   u_int32_t tmp;
844   int x = 0;
845   char *endptr;
846 
847   e->key.src_local_pref.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
848 
849   tmp = strtoul(value, &endptr, 10);
850 
851   e->key.src_local_pref.n = tmp;
852   for (x = 0; e->func[x]; x++) {
853     if (e->func_type[x] == PRETAG_SRC_LOCAL_PREF) {
854       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'src_local_pref' clauses part of the same statement.\n", config.name, config.type, filename);
855       return TRUE;
856     }
857   }
858 
859   if (config.nfacctd_as & NF_AS_BGP) {
860     e->func[x] = pretag_src_local_pref_handler;
861     e->func_type[x] = PRETAG_SRC_LOCAL_PREF;
862     return FALSE;
863   }
864 
865   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'src_local_pref' requires '[nf|sf]acctd_as_new: [ bgp | longest ]' to be specified.\n", config.name, config.type, filename);
866 
867   return TRUE;
868 }
869 
PT_map_local_pref_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)870 int PT_map_local_pref_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
871 {
872   u_int32_t tmp;
873   int x = 0;
874   char *endptr;
875 
876   e->key.local_pref.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
877 
878   tmp = strtoul(value, &endptr, 10);
879 
880   e->key.local_pref.n = tmp;
881   for (x = 0; e->func[x]; x++) {
882     if (e->func_type[x] == PRETAG_LOCAL_PREF) {
883       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'local_pref' clauses part of the same statement.\n", config.name, config.type, filename);
884       return TRUE;
885     }
886   }
887 
888   if (config.nfacctd_as & NF_AS_BGP) {
889     e->func[x] = pretag_local_pref_handler;
890     e->func_type[x] = PRETAG_LOCAL_PREF;
891     return FALSE;
892   }
893 
894   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'local_pref' requires '[nf|sf]acctd_as_new: [ bgp | longest ]' to be specified.\n", config.name, config.type, filename);
895 
896   return TRUE;
897 }
898 
PT_map_src_roa_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)899 int PT_map_src_roa_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
900 {
901   int x = 0;
902 
903   e->key.src_roa.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
904   e->key.src_roa.n = rpki_str2roa(value);
905 
906   for (x = 0; e->func[x]; x++) {
907     if (e->func_type[x] == PRETAG_SRC_ROA) {
908       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'src_roa' clauses part of the same statement.\n", config.name, config.type, filename);
909       return TRUE;
910     }
911   }
912 
913   if (config.nfacctd_as & NF_AS_BGP) {
914     e->func[x] = pretag_src_roa_handler;
915     e->func_type[x] = PRETAG_SRC_ROA;
916     return FALSE;
917   }
918 
919   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'src_roa' requires '[nf|sf]acctd_as_new: [ bgp | longest ]' to be specified.\n", config.name, config.type, filename);
920 
921   return TRUE;
922 }
923 
PT_map_dst_roa_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)924 int PT_map_dst_roa_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
925 {
926   int x = 0;
927 
928   e->key.dst_roa.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
929   e->key.dst_roa.n = rpki_str2roa(value);
930 
931   for (x = 0; e->func[x]; x++) {
932     if (e->func_type[x] == PRETAG_DST_ROA) {
933       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'dst_roa' clauses part of the same statement.\n", config.name, config.type, filename);
934       return TRUE;
935     }
936   }
937 
938   if (config.nfacctd_as & NF_AS_BGP) {
939     e->func[x] = pretag_dst_roa_handler;
940     e->func_type[x] = PRETAG_DST_ROA;
941     return FALSE;
942   }
943 
944   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'dst_roa' requires '[nf|sf]acctd_as_new: [ bgp | longest ]' to be specified.\n", config.name, config.type, filename);
945 
946   return TRUE;
947 }
948 
PT_map_src_comms_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)949 int PT_map_src_comms_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
950 {
951   int x = 0, idx = 0;
952   char *token;
953 
954   memset(e->key.src_comms, 0, sizeof(e->key.src_comms));
955 
956   /* Negation not supported here */
957 
958   while ( (token = extract_token(&value, ',')) && idx < MAX_BGP_COMM_PATTERNS ) {
959     e->key.src_comms[idx] = malloc(MAX_BGP_STD_COMMS);
960     if (!e->key.src_comms[idx]) {
961       Log(LOG_ERR, "ERROR ( %s/%s ): [%s] malloc() failed (PT_map_src_comms_handler). Exiting.\n", config.name, config.type, filename);
962       exit_gracefully(1);
963     }
964     strlcpy(e->key.src_comms[idx], token, MAX_BGP_STD_COMMS);
965     trim_spaces(e->key.src_comms[idx]);
966     idx++;
967   }
968 
969   for (x = 0; e->func[x]; x++) {
970     if (e->func_type[x] == PRETAG_SRC_STD_COMM) {
971       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'src_comms' clauses part of the same statement.\n", config.name, config.type, filename);
972       return TRUE;
973     }
974   }
975 
976   if (config.nfacctd_as & NF_AS_BGP && e->key.src_comms[0]) {
977     e->func[x] = pretag_src_comms_handler;
978     e->func_type[x] = PRETAG_SRC_STD_COMM;
979     return FALSE;
980   }
981 
982   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'src_comms' requires '[nf|sf]acctd_as_new: [ bgp | longest ]' to be specified.\n", config.name, config.type, filename);
983 
984   return TRUE;
985 }
986 
PT_map_comms_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)987 int PT_map_comms_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
988 {
989   int x = 0, idx = 0;
990   char *token;
991 
992   memset(e->key.comms, 0, sizeof(e->key.comms));
993 
994   /* Negation not supported here */
995 
996   while ( (token = extract_token(&value, ',')) && idx < MAX_BGP_COMM_PATTERNS ) {
997     e->key.comms[idx] = malloc(MAX_BGP_STD_COMMS);
998     if (!e->key.comms[idx]) {
999       Log(LOG_ERR, "ERROR ( %s/%s ): [%s] malloc() failed (PT_map_comms_handler). Exiting.\n", config.name, config.type, filename);
1000       exit_gracefully(1);
1001     }
1002     strlcpy(e->key.comms[idx], token, MAX_BGP_STD_COMMS);
1003     trim_spaces(e->key.comms[idx]);
1004     idx++;
1005   }
1006 
1007   for (x = 0; e->func[x]; x++) {
1008     if (e->func_type[x] == PRETAG_STD_COMM) {
1009       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'comms' clauses part of the same statement.\n", config.name, config.type, filename);
1010       return TRUE;
1011     }
1012   }
1013 
1014   if (config.nfacctd_as & NF_AS_BGP && e->key.comms[0]) {
1015     e->func[x] = pretag_comms_handler;
1016     e->func_type[x] = PRETAG_STD_COMM;
1017     return FALSE;
1018   }
1019 
1020   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'comms' requires '[nf|sf]acctd_as_new: [ bgp | longest ]' to be specified.\n", config.name, config.type, filename);
1021 
1022   return TRUE;
1023 }
1024 
PT_map_mpls_vpn_rd_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1025 int PT_map_mpls_vpn_rd_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1026 {
1027   int x = 0, ret;
1028 
1029   memset(&e->key.mpls_vpn_rd, 0, sizeof(e->key.mpls_vpn_rd));
1030 
1031   e->key.mpls_vpn_rd.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
1032   ret = bgp_str2rd(&e->key.mpls_vpn_rd.rd, value);
1033 
1034   for (x = 0; e->func[x]; x++) {
1035     if (e->func_type[x] == PRETAG_MPLS_VPN_RD) {
1036       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'mpls_vpn_rd' clauses part of the same statement.\n", config.name, config.type, filename);
1037       return TRUE;
1038     }
1039   }
1040 
1041   if (ret) {
1042     e->func[x] = pretag_mpls_vpn_rd_handler;
1043     e->func_type[x] = PRETAG_MPLS_VPN_RD;
1044     return FALSE;
1045   }
1046   else return TRUE;
1047 }
1048 
PT_map_mpls_pw_id_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1049 int PT_map_mpls_pw_id_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1050 {
1051   int x = 0;
1052   char *endptr;
1053 
1054   e->key.mpls_pw_id.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
1055   e->key.mpls_pw_id.n = strtoul(value, &endptr, 10);
1056 
1057   for (x = 0; e->func[x]; x++) {
1058     if (e->func_type[x] == PRETAG_MPLS_PW_ID) {
1059       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'mpls_pw_id' clauses part of the same statement.\n", config.name, config.type, filename);
1060       return TRUE;
1061     }
1062   }
1063 
1064   if (config.acct_type == ACCT_NF) e->func[x] = pretag_mpls_pw_id_handler;
1065   else if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_mpls_pw_id_handler;
1066   if (e->func[x]) e->func_type[x] = PRETAG_MPLS_PW_ID;
1067 
1068   return FALSE;
1069 }
1070 
PT_map_src_mac_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1071 int PT_map_src_mac_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1072 {
1073   int x = 0;
1074 
1075   if (req->ptm_c.load_ptm_plugin == PLUGIN_ID_TEE) req->ptm_c.load_ptm_res = TRUE;
1076 
1077   e->key.src_mac.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
1078 
1079   if (string_etheraddr(value, e->key.src_mac.a)) {
1080     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Bad source MAC address '%s'.\n", config.name, config.type, filename, value);
1081     return TRUE;
1082   }
1083 
1084   for (x = 0; e->func[x]; x++) {
1085     if (e->func_type[x] == PRETAG_SRC_MAC) {
1086       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'src_mac' clauses part of the same statement.\n", config.name, config.type, filename);
1087       return TRUE;
1088     }
1089   }
1090 
1091   if (config.acct_type == ACCT_NF) e->func[x] = pretag_src_mac_handler;
1092   else if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_src_mac_handler;
1093   if (e->func[x]) e->func_type[x] = PRETAG_SRC_MAC;
1094 
1095   return FALSE;
1096 }
1097 
PT_map_dst_mac_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1098 int PT_map_dst_mac_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1099 {
1100   int x = 0;
1101 
1102   if (req->ptm_c.load_ptm_plugin == PLUGIN_ID_TEE) req->ptm_c.load_ptm_res = TRUE;
1103 
1104   e->key.dst_mac.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
1105 
1106   if (string_etheraddr(value, e->key.dst_mac.a)) {
1107     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Bad destination MAC address '%s'.\n", config.name, config.type, filename, value);
1108     return TRUE;
1109   }
1110 
1111   for (x = 0; e->func[x]; x++) {
1112     if (e->func_type[x] == PRETAG_DST_MAC) {
1113       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'dst_mac' clauses part of the same statement.\n", config.name, config.type, filename);
1114       return TRUE;
1115     }
1116   }
1117 
1118   if (config.acct_type == ACCT_NF) e->func[x] = pretag_dst_mac_handler;
1119   else if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_dst_mac_handler;
1120   if (e->func[x]) e->func_type[x] = PRETAG_DST_MAC;
1121 
1122   return FALSE;
1123 }
1124 
PT_map_vlan_id_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1125 int PT_map_vlan_id_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1126 {
1127   int tmp, x = 0;
1128 
1129   if (req->ptm_c.load_ptm_plugin == PLUGIN_ID_TEE) req->ptm_c.load_ptm_res = TRUE;
1130 
1131   e->key.vlan_id.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
1132 
1133   tmp = atoi(value);
1134   if (tmp < 0 || tmp > 4096) {
1135     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'vlan' need to be in the following range: 0 > value > 4096.\n", config.name, config.type, filename);
1136     return TRUE;
1137   }
1138   e->key.vlan_id.n = tmp;
1139 
1140   for (x = 0; e->func[x]; x++) {
1141     if (e->func_type[x] == PRETAG_VLAN_ID) {
1142       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'vlan' clauses part of the same statement.\n", config.name, config.type, filename);
1143       return TRUE;
1144     }
1145   }
1146 
1147   if (config.acct_type == ACCT_NF) e->func[x] = pretag_vlan_id_handler;
1148   else if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_vlan_id_handler;
1149   if (e->func[x]) e->func_type[x] = PRETAG_VLAN_ID;
1150 
1151   return FALSE;
1152 }
1153 
PT_map_cvlan_id_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1154 int PT_map_cvlan_id_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1155 {
1156   int tmp, x = 0;
1157 
1158   e->key.cvlan_id.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
1159 
1160   tmp = atoi(value);
1161   if (tmp < 0 || tmp > 4096) {
1162     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'cvlan' need to be in the following range: 0 > value > 4096.\n", config.name, config.type, filename);
1163     return TRUE;
1164   }
1165   e->key.cvlan_id.n = tmp;
1166 
1167   for (x = 0; e->func[x]; x++) {
1168     if (e->func_type[x] == PRETAG_CVLAN_ID) {
1169       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'cvlan' clauses part of the same statement.\n", config.name, config.type, filename);
1170       return TRUE;
1171     }
1172   }
1173 
1174   if (config.acct_type == ACCT_NF) e->func[x] = pretag_cvlan_id_handler;
1175   /* else if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_vlan_id_handler; */
1176   if (e->func[x]) e->func_type[x] = PRETAG_CVLAN_ID;
1177 
1178   return FALSE;
1179 }
1180 
PT_map_src_net_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1181 int PT_map_src_net_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1182 {
1183   int x = 0;
1184 
1185   if (req->ptm_c.load_ptm_plugin == PLUGIN_ID_TEE) req->ptm_c.load_ptm_res = TRUE;
1186 
1187   e->key.src_net.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
1188 
1189   if (!str_to_addr_mask(value, &e->key.src_net.a, &e->key.src_net.m)) {
1190     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Bad source network address '%s'.\n", config.name, config.type, filename, value);
1191     return TRUE;
1192   }
1193 
1194   for (x = 0; e->func[x]; x++) {
1195     if (e->func_type[x] == PRETAG_SRC_NET) {
1196       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'src_net' clauses part of the same statement.\n", config.name, config.type, filename);
1197       return TRUE;
1198     }
1199   }
1200 
1201   if (config.acct_type == ACCT_NF) e->func[x] = pretag_src_net_handler;
1202   else if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_src_net_handler;
1203   if (e->func[x]) e->func_type[x] = PRETAG_SRC_NET;
1204 
1205   return FALSE;
1206 }
1207 
PT_map_dst_net_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1208 int PT_map_dst_net_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1209 {
1210   int x = 0;
1211 
1212   if (req->ptm_c.load_ptm_plugin == PLUGIN_ID_TEE) req->ptm_c.load_ptm_res = TRUE;
1213 
1214   e->key.dst_net.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
1215 
1216   if (!str_to_addr_mask(value, &e->key.dst_net.a, &e->key.dst_net.m)) {
1217     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Bad destination network address '%s'.\n", config.name, config.type, filename, value);
1218     return TRUE;
1219   }
1220 
1221   for (x = 0; e->func[x]; x++) {
1222     if (e->func_type[x] == PRETAG_DST_NET) {
1223       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'dst_net' clauses part of the same statement.\n", config.name, config.type, filename);
1224       return TRUE;
1225     }
1226   }
1227 
1228   if (config.acct_type == ACCT_NF) e->func[x] = pretag_dst_net_handler;
1229   else if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_dst_net_handler;
1230   if (e->func[x]) e->func_type[x] = PRETAG_DST_NET;
1231 
1232   return FALSE;
1233 }
1234 
PT_map_set_tos_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1235 int PT_map_set_tos_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1236 {
1237   int x = 0, len;
1238   char *endptr;
1239 
1240   e->set_tos.set = TRUE;
1241   len = strlen(value);
1242 
1243   while (x < len) {
1244     if (!isdigit(value[x])) {
1245       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] bad 'set_tos' value: '%s'.\n", config.name, config.type, filename, value);
1246       return TRUE;
1247     }
1248     x++;
1249   }
1250 
1251   e->set_tos.n = strtoul(value, &endptr, 10);
1252   for (x = 0; e->set_func[x]; x++) {
1253     if (e->set_func_type[x] == PRETAG_SET_TOS) {
1254       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'set_tos' clauses part of the same statement.\n", config.name, config.type, filename);
1255       return TRUE;
1256     }
1257   }
1258 
1259   /* feature currently only supported in nfacctd */
1260   if (config.acct_type == ACCT_NF) e->set_func[x] = pretag_set_tos_handler;
1261 
1262   if (e->set_func[x]) e->set_func_type[x] = PRETAG_SET_TOS;
1263 
1264   return FALSE;
1265 }
1266 
BTA_map_lookup_bgp_port_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1267 int BTA_map_lookup_bgp_port_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1268 {
1269   int x = 0, len;
1270   char *endptr;
1271 
1272   e->key.lookup_bgp_port.set = TRUE;
1273   len = strlen(value);
1274 
1275   while (x < len) {
1276     if (!isdigit(value[x])) {
1277       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] bad 'bgp_port' value: '%s'.\n", config.name, config.type, filename, value);
1278       return TRUE;
1279     }
1280     x++;
1281   }
1282 
1283   e->key.lookup_bgp_port.n = strtoul(value, &endptr, 10);
1284   for (x = 0; e->set_func[x]; x++) {
1285     if (e->set_func_type[x] == PRETAG_LOOKUP_BGP_PORT) {
1286       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'bgp_port' clauses part of the same statement.\n", config.name, config.type, filename);
1287       return TRUE;
1288     }
1289   }
1290 
1291   /* feature currently only supported in bgp_agent_map */
1292   if (acct_type == MAP_BGP_TO_XFLOW_AGENT) e->set_func[x] = BTA_lookup_bgp_port_handler;
1293 
1294   if (e->set_func[x]) e->set_func_type[x] = PRETAG_LOOKUP_BGP_PORT;
1295 
1296   return FALSE;
1297 }
1298 
PT_map_entry_label_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1299 int PT_map_entry_label_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1300 {
1301   int len = strlen(value);
1302 
1303   memset(e->entry_label, 0, MAX_LABEL_LEN);
1304 
1305   if (len >= MAX_LABEL_LEN) {
1306     strncpy(e->entry_label, value, (MAX_LABEL_LEN - 1));
1307     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] entry label '%s' cut to '%s'.\n", config.name, config.type, filename, value, e->entry_label);
1308   }
1309   else strcpy(e->entry_label, value);
1310 
1311   return FALSE;
1312 }
1313 
PT_map_jeq_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1314 int PT_map_jeq_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1315 {
1316   int len = strlen(value);
1317 
1318   e->jeq.label = malloc(MAX_LABEL_LEN);
1319   if (!e->jeq.label) {
1320     Log(LOG_ERR, "ERROR ( %s/%s ): [%s] malloc() failed (PT_map_jeq_handler). Exiting.\n", config.name, config.type, filename);
1321     exit_gracefully(1);
1322   }
1323   else memset(e->jeq.label, 0, MAX_LABEL_LEN);
1324 
1325   if (len >= MAX_LABEL_LEN) {
1326     strncpy(e->jeq.label, value, (MAX_LABEL_LEN - 1));
1327     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] JEQ label '%s' cut to '%s'.\n", config.name, config.type, filename, value, e->jeq.label);
1328   }
1329   else strcpy(e->jeq.label, value);
1330 
1331   return FALSE;
1332 }
1333 
PT_map_return_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1334 int PT_map_return_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1335 {
1336   int res = parse_truefalse(value);
1337 
1338   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] RETURN is in the process of being discontinued.\n", config.name, config.type, filename);
1339   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] %s: %s\n", config.name, config.type, filename, GET_IN_TOUCH_MSG, MANTAINER);
1340 
1341   if (res < 0) Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Unknown RETURN value: '%s'. Ignoring.\n", config.name, config.type, filename, value);
1342   else e->ret = res;
1343 
1344   return FALSE;
1345 }
1346 
PT_map_stack_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1347 int PT_map_stack_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1348 {
1349   e->stack.func = NULL;
1350 
1351   if (*value == '+' || !strncmp(value, "sum", 3)) e->stack.func = PT_stack_sum;
1352   else if (!strncmp(value, "or", 2)) e->stack.func = PT_stack_logical_or;
1353   else Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Unknown STACK operator: '%s'. Ignoring.\n", config.name, config.type, filename, value);
1354 
1355   return FALSE;
1356 }
PT_map_fwdstatus_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)1357 int PT_map_fwdstatus_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
1358 {
1359   int tmp, x = 0;
1360 
1361   if (req->ptm_c.load_ptm_plugin == PLUGIN_ID_TEE) req->ptm_c.load_ptm_res = TRUE;
1362 
1363   e->key.fwdstatus.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
1364 
1365   tmp = atoi(value);
1366   if (tmp < 0 || tmp > 256) {
1367     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] 'fwdstatus' need to be in the following range: 0 > value > 256.\n", config.name, config.type, filename);
1368     return TRUE;
1369   }
1370   e->key.fwdstatus.n = tmp;
1371 
1372 
1373   for (x = 0; e->func[x]; x++) {
1374     if (e->func_type[x] == PRETAG_FWDSTATUS_ID) {
1375       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Multiple 'fwdstatus' clauses part of the same statement.\n", config.name, config.type, filename);
1376       return TRUE;
1377     }
1378   }
1379 
1380   if (config.acct_type == ACCT_NF) e->func[x] = pretag_forwarding_status_handler;
1381   if (e->func[x]) e->func_type[x] = PRETAG_FWDSTATUS_ID;
1382 
1383   return FALSE;
1384 }
1385 
pretag_dummy_ip_handler(struct packet_ptrs * pptrs,void * unused,void * e)1386 int pretag_dummy_ip_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1387 {
1388   return FALSE;
1389 }
1390 
pretag_input_handler(struct packet_ptrs * pptrs,void * unused,void * e)1391 int pretag_input_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1392 {
1393   struct id_entry *entry = e;
1394   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1395   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1396   u_int16_t input16 = htons(entry->key.input.n);
1397   u_int32_t input32 = htonl(entry->key.input.n);
1398   u_int8_t neg = entry->key.input.neg;
1399 
1400   if (!pptrs->f_data) return TRUE;
1401 
1402   switch(hdr->version) {
1403   case 10:
1404   case 9:
1405     if (tpl->tpl[NF9_INPUT_SNMP].len == 2) {
1406       if (!memcmp(&input16, pptrs->f_data+tpl->tpl[NF9_INPUT_SNMP].off, tpl->tpl[NF9_INPUT_SNMP].len))
1407 	return (FALSE | neg);
1408     }
1409     else if (tpl->tpl[NF9_INPUT_SNMP].len == 4) {
1410       if (!memcmp(&input32, pptrs->f_data+tpl->tpl[NF9_INPUT_SNMP].off, tpl->tpl[NF9_INPUT_SNMP].len))
1411 	return (FALSE | neg);
1412     }
1413     else if (tpl->tpl[NF9_INPUT_PHYSINT].len == 4) {
1414       if (!memcmp(&input32, pptrs->f_data+tpl->tpl[NF9_INPUT_PHYSINT].off, tpl->tpl[NF9_INPUT_PHYSINT].len))
1415         return (FALSE | neg);
1416     }
1417     return (TRUE ^ neg);
1418   case 5:
1419     if (input16 == ((struct struct_export_v5 *)pptrs->f_data)->input) return (FALSE | neg);
1420     else return (TRUE ^ neg);
1421   default:
1422     return TRUE;
1423   }
1424 }
1425 
pretag_output_handler(struct packet_ptrs * pptrs,void * unused,void * e)1426 int pretag_output_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1427 {
1428   struct id_entry *entry = e;
1429   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1430   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1431   u_int16_t output16 = htons(entry->key.output.n);
1432   u_int32_t output32 = htonl(entry->key.output.n);
1433   u_int8_t neg = entry->key.output.neg;
1434 
1435   if (!pptrs->f_data) return TRUE;
1436 
1437   switch(hdr->version) {
1438   case 10:
1439   case 9:
1440     if (tpl->tpl[NF9_OUTPUT_SNMP].len == 2) {
1441       if (!memcmp(&output16, pptrs->f_data+tpl->tpl[NF9_OUTPUT_SNMP].off, tpl->tpl[NF9_OUTPUT_SNMP].len))
1442 	return (FALSE | neg);
1443     }
1444     else if (tpl->tpl[NF9_OUTPUT_SNMP].len == 4) {
1445       if (!memcmp(&output32, pptrs->f_data+tpl->tpl[NF9_OUTPUT_SNMP].off, tpl->tpl[NF9_OUTPUT_SNMP].len))
1446 	return (FALSE | neg);
1447     }
1448     else if (tpl->tpl[NF9_OUTPUT_PHYSINT].len == 4) {
1449       if (!memcmp(&output32, pptrs->f_data+tpl->tpl[NF9_OUTPUT_PHYSINT].off, tpl->tpl[NF9_OUTPUT_PHYSINT].len))
1450         return (FALSE | neg);
1451     }
1452     return (TRUE ^ neg);
1453   case 5:
1454     if (output16 == ((struct struct_export_v5 *)pptrs->f_data)->output) return (FALSE | neg);
1455     else return (TRUE ^ neg);
1456   default:
1457     return TRUE;
1458   }
1459 }
1460 
pretag_nexthop_handler(struct packet_ptrs * pptrs,void * unused,void * e)1461 int pretag_nexthop_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1462 {
1463   struct id_entry *entry = e;
1464   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1465   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1466 
1467   if (!pptrs->f_data) return TRUE;
1468 
1469   switch(hdr->version) {
1470   case 10:
1471   case 9:
1472     if (entry->key.nexthop.a.family == AF_INET) {
1473       if (!memcmp(&entry->key.nexthop.a.address.ipv4, pptrs->f_data+tpl->tpl[NF9_IPV4_NEXT_HOP].off, tpl->tpl[NF9_IPV4_NEXT_HOP].len))
1474 	return (FALSE | entry->key.nexthop.neg);
1475     }
1476     else if (entry->key.nexthop.a.family == AF_INET6) {
1477       if (!memcmp(&entry->key.nexthop.a.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_NEXT_HOP].off, tpl->tpl[NF9_IPV6_NEXT_HOP].len))
1478 	return (FALSE | entry->key.nexthop.neg);
1479     }
1480     return (TRUE ^ entry->key.nexthop.neg);
1481   case 5:
1482     if (entry->key.nexthop.a.address.ipv4.s_addr == ((struct struct_export_v5 *)pptrs->f_data)->nexthop.s_addr) return (FALSE | entry->key.nexthop.neg);
1483     else return (TRUE ^ entry->key.nexthop.neg);
1484   default:
1485     return TRUE;
1486   }
1487 }
1488 
pretag_bgp_nexthop_handler(struct packet_ptrs * pptrs,void * unused,void * e)1489 int pretag_bgp_nexthop_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1490 {
1491   struct id_entry *entry = e;
1492   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1493   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1494 
1495   if (entry->last_matched == PRETAG_BGP_NEXTHOP) return FALSE;
1496 
1497   /* check network-related primitives against fallback scenarios */
1498   if (!evaluate_lm_method(pptrs, TRUE, config.nfacctd_net, NF_NET_KEEP)) return TRUE;
1499 
1500   if (!pptrs->f_data) return TRUE;
1501 
1502   switch(hdr->version) {
1503   case 10:
1504   case 9:
1505     if (entry->key.bgp_nexthop.a.family == AF_INET) {
1506       if (tpl->tpl[NF9_BGP_IPV4_NEXT_HOP].len) {
1507 	if (!memcmp(&entry->key.bgp_nexthop.a.address.ipv4, pptrs->f_data+tpl->tpl[NF9_BGP_IPV4_NEXT_HOP].off, tpl->tpl[NF9_BGP_IPV4_NEXT_HOP].len))
1508 	  return (FALSE | entry->key.bgp_nexthop.neg);
1509       }
1510       else if (tpl->tpl[NF9_MPLS_TOP_LABEL_ADDR].len) {
1511 	if (!memcmp(&entry->key.bgp_nexthop.a.address.ipv4, pptrs->f_data+tpl->tpl[NF9_MPLS_TOP_LABEL_ADDR].off, tpl->tpl[NF9_MPLS_TOP_LABEL_ADDR].len))
1512 	  return (FALSE | entry->key.bgp_nexthop.neg);
1513       }
1514     }
1515     else if (entry->key.nexthop.a.family == AF_INET6) {
1516       if (tpl->tpl[NF9_BGP_IPV6_NEXT_HOP].len) {
1517 	if (!memcmp(&entry->key.bgp_nexthop.a.address.ipv6, pptrs->f_data+tpl->tpl[NF9_BGP_IPV6_NEXT_HOP].off, tpl->tpl[NF9_BGP_IPV6_NEXT_HOP].len))
1518 	  return (FALSE | entry->key.bgp_nexthop.neg);
1519       }
1520       else if (tpl->tpl[NF9_MPLS_TOP_LABEL_IPV6_ADDR].len) {
1521 	if (!memcmp(&entry->key.bgp_nexthop.a.address.ipv6, pptrs->f_data+tpl->tpl[NF9_MPLS_TOP_LABEL_IPV6_ADDR].off, tpl->tpl[NF9_MPLS_TOP_LABEL_IPV6_ADDR].len))
1522 	  return (FALSE | entry->key.bgp_nexthop.neg);
1523       }
1524     }
1525     return (TRUE ^ entry->key.bgp_nexthop.neg);
1526   case 5:
1527     if (entry->key.bgp_nexthop.a.address.ipv4.s_addr == ((struct struct_export_v5 *)pptrs->f_data)->nexthop.s_addr) return (FALSE | entry->key.bgp_nexthop.neg);
1528     else return (TRUE ^ entry->key.bgp_nexthop.neg);
1529   default:
1530     return TRUE;
1531   }
1532 }
1533 
pretag_bgp_bgp_nexthop_handler(struct packet_ptrs * pptrs,void * unused,void * e)1534 int pretag_bgp_bgp_nexthop_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1535 {
1536   struct id_entry *entry = e;
1537   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
1538   struct bgp_info *info;
1539   int ret = -1;
1540 
1541   /* check network-related primitives against fallback scenarios */
1542   if (!evaluate_lm_method(pptrs, TRUE, config.nfacctd_net, NF_NET_BGP)) goto way_out;
1543 
1544   if (dst_ret) {
1545     if (pptrs->bgp_nexthop_info)
1546       info = (struct bgp_info *) pptrs->bgp_nexthop_info;
1547     else
1548       info = (struct bgp_info *) pptrs->bgp_dst_info;
1549 
1550     if (info && info->attr) {
1551       if (info->attr->mp_nexthop.family == AF_INET) {
1552         ret = memcmp(&entry->key.bgp_nexthop.a.address.ipv4, &info->attr->mp_nexthop.address.ipv4, 4);
1553       }
1554       else if (info->attr->mp_nexthop.family == AF_INET6) {
1555         ret = memcmp(&entry->key.bgp_nexthop.a.address.ipv6, &info->attr->mp_nexthop.address.ipv6, 16);
1556       }
1557       else {
1558 	ret = memcmp(&entry->key.bgp_nexthop.a.address.ipv4, &info->attr->nexthop, 4);
1559       }
1560     }
1561   }
1562 
1563   way_out:
1564 
1565   if (!ret) {
1566     entry->last_matched = PRETAG_BGP_NEXTHOP;
1567     return (FALSE | entry->key.bgp_nexthop.neg);
1568   }
1569   else if (config.nfacctd_net & NF_NET_KEEP) return FALSE;
1570   else return (TRUE ^ entry->key.bgp_nexthop.neg);
1571 }
1572 
pretag_engine_type_handler(struct packet_ptrs * pptrs,void * unused,void * e)1573 int pretag_engine_type_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1574 {
1575   struct id_entry *entry = e;
1576   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1577 
1578   switch(hdr->version) {
1579   case 5:
1580     if (entry->key.engine_type.n == ((struct struct_header_v5 *)pptrs->f_header)->engine_type) return (FALSE | entry->key.engine_type.neg);
1581     else return (TRUE ^ entry->key.engine_type.neg);
1582   default:
1583     return TRUE; /* this field does not exist: condition is always true */
1584   }
1585 }
1586 
pretag_engine_id_handler(struct packet_ptrs * pptrs,void * unused,void * e)1587 int pretag_engine_id_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1588 {
1589   struct id_entry *entry = e;
1590   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1591   u_int32_t value;
1592 
1593   switch(hdr->version) {
1594   case 10:
1595   {
1596     struct struct_header_ipfix *hdr = (struct struct_header_ipfix *) pptrs->f_header;
1597 
1598     value = ntohl(hdr->source_id);
1599     if (entry->key.engine_id.n == value) return (FALSE | entry->key.engine_id.neg);
1600     else return (TRUE ^ entry->key.engine_id.neg);
1601   }
1602   case 9:
1603   {
1604     struct struct_header_v9 *hdr = (struct struct_header_v9 *) pptrs->f_header;
1605 
1606     value = ntohl(hdr->source_id);
1607     if (entry->key.engine_id.n == value) return (FALSE | entry->key.engine_id.neg);
1608     else return (TRUE ^ entry->key.engine_id.neg);
1609   }
1610   case 5:
1611     if (entry->key.engine_id.n == ((struct struct_header_v5 *)pptrs->f_header)->engine_id) return (FALSE | entry->key.engine_id.neg);
1612     else return (TRUE ^ entry->key.engine_id.neg);
1613   default:
1614     return TRUE; /* this field does not exist: condition is always true */
1615   }
1616 }
1617 
pretag_flowset_id_handler(struct packet_ptrs * pptrs,void * unused,void * e)1618 int pretag_flowset_id_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1619 {
1620   struct id_entry *entry = e;
1621   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1622   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1623 
1624   if (!pptrs->f_tpl) return TRUE;
1625 
1626   switch(hdr->version) {
1627   case 10:
1628   case 9:
1629     if (tpl) {
1630       if (entry->key.flowset_id.n == tpl->template_id) return (FALSE | entry->key.flowset_id.neg);
1631       else return (TRUE ^ entry->key.flowset_id.neg);
1632     }
1633     else return TRUE; /* template not received yet */
1634   default:
1635     return TRUE; /* this field does not exist: condition is always true */
1636   }
1637 }
1638 
pretag_filter_handler(struct packet_ptrs * pptrs,void * unused,void * e)1639 int pretag_filter_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1640 {
1641   struct id_entry *entry = e;
1642 
1643   if (bpf_filter(entry->key.filter.bf_insns, pptrs->packet_ptr, pptrs->pkthdr->len, pptrs->pkthdr->caplen))
1644     return FALSE; /* matched filter */
1645   else return TRUE;
1646 }
1647 
pretag_src_as_handler(struct packet_ptrs * pptrs,void * unused,void * e)1648 int pretag_src_as_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1649 {
1650   struct id_entry *entry = e;
1651   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1652   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1653   u_int16_t asn16 = 0;
1654   u_int32_t asn32 = 0;
1655 
1656   if (entry->last_matched == PRETAG_SRC_AS) return FALSE;
1657 
1658   if (!pptrs->f_data) return TRUE;
1659 
1660   switch(hdr->version) {
1661   case 10:
1662   case 9:
1663     if (tpl->tpl[NF9_SRC_AS].len == 2) {
1664       memcpy(&asn16, pptrs->f_data+tpl->tpl[NF9_SRC_AS].off, 2);
1665       asn32 = ntohs(asn16);
1666     }
1667     else if (tpl->tpl[NF9_SRC_AS].len == 4) {
1668       memcpy(&asn32, pptrs->f_data+tpl->tpl[NF9_SRC_AS].off, 4);
1669       asn32 = ntohl(asn32);
1670     }
1671     break;
1672   case 5:
1673     asn32 = ntohs(((struct struct_export_v5 *) pptrs->f_data)->src_as);
1674     break;
1675   default:
1676     break;
1677   }
1678 
1679   if (entry->key.src_as.n == asn32) return (FALSE | entry->key.src_as.neg);
1680   else return (TRUE ^ entry->key.src_as.neg);
1681 }
1682 
pretag_bgp_src_as_handler(struct packet_ptrs * pptrs,void * unused,void * e)1683 int pretag_bgp_src_as_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1684 {
1685   struct id_entry *entry = e;
1686   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
1687   struct bgp_info *info;
1688   as_t asn = 0;
1689 
1690   if (src_ret) {
1691     info = (struct bgp_info *) pptrs->bgp_src_info;
1692     if (info && info->attr) {
1693       if (info->attr->aspath) {
1694         asn = evaluate_last_asn(info->attr->aspath);
1695       }
1696     }
1697   }
1698 
1699   if (entry->key.src_as.n == asn) {
1700     entry->last_matched = PRETAG_SRC_AS;
1701     return (FALSE | entry->key.src_as.neg);
1702   }
1703   else if (config.nfacctd_as & NF_AS_KEEP) return FALSE;
1704   else return (TRUE ^ entry->key.src_as.neg);
1705 }
1706 
pretag_dst_as_handler(struct packet_ptrs * pptrs,void * unused,void * e)1707 int pretag_dst_as_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1708 {
1709   struct id_entry *entry = e;
1710   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1711   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1712   u_int16_t asn16 = 0;
1713   u_int32_t asn32 = 0;
1714 
1715   if (entry->last_matched == PRETAG_DST_AS) return FALSE;
1716 
1717   if (!pptrs->f_data) return TRUE;
1718 
1719   switch(hdr->version) {
1720   case 10:
1721   case 9:
1722     if (tpl->tpl[NF9_DST_AS].len == 2) {
1723       memcpy(&asn16, pptrs->f_data+tpl->tpl[NF9_DST_AS].off, 2);
1724       asn32 = ntohs(asn16);
1725     }
1726     else if (tpl->tpl[NF9_DST_AS].len == 4) {
1727       memcpy(&asn32, pptrs->f_data+tpl->tpl[NF9_DST_AS].off, 4);
1728       asn32 = ntohl(asn32);
1729     }
1730     break;
1731   case 5:
1732     asn32 = ntohs(((struct struct_export_v5 *) pptrs->f_data)->dst_as);
1733     break;
1734   default:
1735     break;
1736   }
1737 
1738   if (entry->key.dst_as.n == asn32) return (FALSE | entry->key.dst_as.neg);
1739   else return (TRUE ^ entry->key.dst_as.neg);
1740 }
1741 
pretag_bgp_dst_as_handler(struct packet_ptrs * pptrs,void * unused,void * e)1742 int pretag_bgp_dst_as_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1743 {
1744   struct id_entry *entry = e;
1745   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
1746   struct bgp_info *info;
1747   as_t asn = 0;
1748 
1749   if (dst_ret) {
1750     info = (struct bgp_info *) pptrs->bgp_dst_info;
1751     if (info && info->attr) {
1752       if (info->attr->aspath) {
1753         asn = evaluate_last_asn(info->attr->aspath);
1754       }
1755     }
1756   }
1757 
1758   if (entry->key.dst_as.n == asn) {
1759     entry->last_matched = PRETAG_DST_AS;
1760     return (FALSE | entry->key.dst_as.neg);
1761   }
1762   else if (config.nfacctd_as & NF_AS_KEEP) return FALSE;
1763   else return (TRUE ^ entry->key.dst_as.neg);
1764 }
1765 
pretag_peer_src_as_handler(struct packet_ptrs * pptrs,void * unused,void * e)1766 int pretag_peer_src_as_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1767 {
1768   struct id_entry *entry = e;
1769   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
1770   struct bgp_info *info;
1771   as_t asn = 0;
1772 
1773   if (config.bgp_daemon_peer_as_src_type == BGP_SRC_PRIMITIVES_MAP) {
1774     asn = pptrs->bpas;
1775   }
1776   else if (config.bgp_daemon_peer_as_src_type & BGP_SRC_PRIMITIVES_BGP) {
1777     if (src_ret) {
1778       info = (struct bgp_info *) pptrs->bgp_src_info;
1779       if (info && info->attr) {
1780 	if (info->attr->aspath && info->attr->aspath->str) {
1781 	  asn = evaluate_first_asn(info->attr->aspath->str);
1782 	}
1783       }
1784     }
1785   }
1786 
1787   if (entry->key.peer_src_as.n == asn) return (FALSE | entry->key.peer_src_as.neg);
1788   else return (TRUE ^ entry->key.peer_src_as.neg);
1789 }
1790 
pretag_peer_dst_as_handler(struct packet_ptrs * pptrs,void * unused,void * e)1791 int pretag_peer_dst_as_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1792 {
1793   struct id_entry *entry = e;
1794   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
1795   struct bgp_info *info;
1796   as_t asn = 0;
1797 
1798   if (dst_ret) {
1799     info = (struct bgp_info *) pptrs->bgp_dst_info;
1800     if (info && info->attr) {
1801       if (info->attr->aspath && info->attr->aspath->str) {
1802         asn = evaluate_first_asn(info->attr->aspath->str);
1803       }
1804     }
1805   }
1806 
1807   if (entry->key.peer_dst_as.n == asn) return (FALSE | entry->key.peer_dst_as.neg);
1808   else return (TRUE ^ entry->key.peer_dst_as.neg);
1809 }
1810 
pretag_src_local_pref_handler(struct packet_ptrs * pptrs,void * unused,void * e)1811 int pretag_src_local_pref_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1812 {
1813   struct id_entry *entry = e;
1814   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
1815   struct bgp_info *info;
1816   u_int32_t local_pref = 0;
1817 
1818   if (config.bgp_daemon_src_local_pref_type == BGP_SRC_PRIMITIVES_MAP) {
1819     local_pref = pptrs->blp;
1820   }
1821   else if (config.bgp_daemon_src_local_pref_type & BGP_SRC_PRIMITIVES_BGP) {
1822     if (src_ret) {
1823       info = (struct bgp_info *) pptrs->bgp_src_info;
1824       if (info && info->attr) {
1825 	local_pref = info->attr->local_pref;
1826       }
1827     }
1828   }
1829 
1830   if (entry->key.src_local_pref.n == local_pref) return (FALSE | entry->key.src_local_pref.neg);
1831   else return (TRUE ^ entry->key.src_local_pref.neg);
1832 }
1833 
pretag_local_pref_handler(struct packet_ptrs * pptrs,void * unused,void * e)1834 int pretag_local_pref_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1835 {
1836   struct id_entry *entry = e;
1837   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
1838   struct bgp_info *info;
1839   u_int32_t local_pref = 0;
1840 
1841   if (dst_ret) {
1842     info = (struct bgp_info *) pptrs->bgp_dst_info;
1843     if (info && info->attr) {
1844       local_pref = info->attr->local_pref;
1845     }
1846   }
1847 
1848   if (entry->key.local_pref.n == local_pref) return (FALSE | entry->key.local_pref.neg);
1849   else return (TRUE ^ entry->key.local_pref.neg);
1850 }
1851 
pretag_src_roa_handler(struct packet_ptrs * pptrs,void * unused,void * e)1852 int pretag_src_roa_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1853 {
1854   struct id_entry *entry = e;
1855   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
1856   u_int8_t roa = ROA_STATUS_UNKNOWN;
1857 
1858   if (config.bgp_daemon_src_roa_type & BGP_SRC_PRIMITIVES_BGP) {
1859     if (src_ret) roa = pptrs->src_roa;
1860   }
1861 
1862   if (entry->key.src_roa.n == roa) return (FALSE | entry->key.src_roa.neg);
1863   else return (TRUE ^ entry->key.src_roa.neg);
1864 }
1865 
pretag_dst_roa_handler(struct packet_ptrs * pptrs,void * unused,void * e)1866 int pretag_dst_roa_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1867 {
1868   struct id_entry *entry = e;
1869   u_int8_t roa = ROA_STATUS_UNKNOWN;
1870 
1871   if (entry->key.dst_roa.n == roa) return (FALSE | entry->key.dst_roa.neg);
1872   else return (TRUE ^ entry->key.dst_roa.neg);
1873 }
1874 
pretag_src_comms_handler(struct packet_ptrs * pptrs,void * unused,void * e)1875 int pretag_src_comms_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1876 {
1877   struct id_entry *entry = e;
1878   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
1879   struct bgp_info *info;
1880   char tmp_stdcomms[MAX_BGP_STD_COMMS];
1881 
1882   memset(tmp_stdcomms, 0, sizeof(tmp_stdcomms));
1883 
1884   if (src_ret) {
1885     info = (struct bgp_info *) pptrs->bgp_src_info;
1886     if (info && info->attr && info->attr->community && info->attr->community->str) {
1887       evaluate_comm_patterns(tmp_stdcomms, info->attr->community->str, entry->key.src_comms, MAX_BGP_STD_COMMS);
1888     }
1889   }
1890 
1891   if (strlen(tmp_stdcomms)) return FALSE;
1892   else return TRUE;
1893 }
1894 
pretag_comms_handler(struct packet_ptrs * pptrs,void * unused,void * e)1895 int pretag_comms_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1896 {
1897   struct id_entry *entry = e;
1898   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
1899   struct bgp_info *info;
1900   char tmp_stdcomms[MAX_BGP_STD_COMMS];
1901 
1902   memset(tmp_stdcomms, 0, sizeof(tmp_stdcomms));
1903 
1904   if (dst_ret) {
1905     info = (struct bgp_info *) pptrs->bgp_dst_info;
1906     if (info && info->attr && info->attr->community && info->attr->community->str) {
1907       evaluate_comm_patterns(tmp_stdcomms, info->attr->community->str, entry->key.comms, MAX_BGP_STD_COMMS);
1908     }
1909   }
1910 
1911   if (strlen(tmp_stdcomms)) return FALSE;
1912   else return TRUE;
1913 }
1914 
pretag_sample_type_handler(struct packet_ptrs * pptrs,void * unused,void * e)1915 int pretag_sample_type_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1916 {
1917   struct id_entry *entry = e;
1918   u_int8_t flow_type = pptrs->flow_type;
1919 
1920   if (flow_type >= NF9_FTYPE_TRAFFIC && flow_type <= NF9_FTYPE_TRAFFIC_MAX) {
1921     flow_type = NF9_FTYPE_TRAFFIC;
1922   }
1923 
1924   if (entry->key.sample_type.n == flow_type) return (FALSE | entry->key.sample_type.neg);
1925   else return (TRUE ^ entry->key.sample_type.neg);
1926 }
1927 
pretag_direction_handler(struct packet_ptrs * pptrs,void * unused,void * e)1928 int pretag_direction_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1929 {
1930   struct id_entry *entry = e;
1931   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1932   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1933   u_int8_t direction = 0;
1934 
1935   if (!pptrs->f_data) return TRUE;
1936 
1937   switch (hdr->version) {
1938   case 10:
1939   case 9:
1940     if (tpl->tpl[NF9_DIRECTION].len == 1) {
1941       memcpy(&direction, pptrs->f_data+tpl->tpl[NF9_DIRECTION].off, 1);
1942     }
1943     if (entry->key.direction.n == direction) return (FALSE | entry->key.direction.neg);
1944     else return (TRUE ^ entry->key.direction.neg);
1945   default:
1946     return TRUE; /* this field does not exist: condition is always true */
1947   }
1948 }
1949 
pretag_nat_event_handler(struct packet_ptrs * pptrs,void * unused,void * e)1950 int pretag_nat_event_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1951 {
1952   struct id_entry *entry = e;
1953   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1954   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1955   u_int8_t nat_event = 0;
1956 
1957   if (!pptrs->f_data) return TRUE;
1958 
1959   switch (hdr->version) {
1960   case 10:
1961   case 9:
1962     if (tpl->tpl[NF9_NAT_EVENT].len == 1) {
1963       memcpy(&nat_event, pptrs->f_data+tpl->tpl[NF9_NAT_EVENT].off, 1);
1964     }
1965     if (entry->key.nat_event.n == nat_event) return (FALSE | entry->key.nat_event.neg);
1966     else return (TRUE ^ entry->key.nat_event.neg);
1967   default:
1968     return TRUE; /* this field does not exist: condition is always true */
1969   }
1970 }
1971 
pretag_mpls_vpn_rd_handler(struct packet_ptrs * pptrs,void * unused,void * e)1972 int pretag_mpls_vpn_rd_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1973 {
1974   struct id_entry *entry = e;
1975   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
1976   struct bgp_info *info;
1977   int ret = -1;
1978 
1979   /* XXX: no src_ret lookup? */
1980 
1981   if (dst_ret) {
1982     info = (struct bgp_info *) pptrs->bgp_dst_info;
1983     if (info && info->extra) {
1984       ret = memcmp(&entry->key.mpls_vpn_rd.rd, &info->extra->rd, sizeof(rd_t));
1985     }
1986   }
1987 
1988   if (!ret) return (FALSE | entry->key.mpls_vpn_rd.neg);
1989   else return (TRUE ^ entry->key.mpls_vpn_rd.neg);
1990 }
1991 
pretag_mpls_pw_id_handler(struct packet_ptrs * pptrs,void * unused,void * e)1992 int pretag_mpls_pw_id_handler(struct packet_ptrs *pptrs, void *unused, void *e)
1993 {
1994   struct id_entry *entry = e;
1995   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1996   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1997   u_int32_t tmp32 = 0, mpls_pw_id = 0;;
1998 
1999   switch (hdr->version) {
2000   case 10:
2001   case 9:
2002     if (tpl->tpl[NF9_PSEUDOWIREID].len) {
2003       memcpy(&tmp32, pptrs->f_data+tpl->tpl[NF9_PSEUDOWIREID].off, 4);
2004       mpls_pw_id = ntohl(tmp32);
2005     }
2006 
2007     if (entry->key.mpls_pw_id.n == mpls_pw_id) return (FALSE | entry->key.mpls_pw_id.neg);
2008     else return (TRUE ^ entry->key.mpls_pw_id.neg);
2009   default:
2010     return TRUE; /* this field does not exist: condition is always true */
2011   }
2012 }
2013 
pretag_src_mac_handler(struct packet_ptrs * pptrs,void * unused,void * e)2014 int pretag_src_mac_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2015 {
2016   struct id_entry *entry = e;
2017   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2018   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2019 
2020   if (!pptrs->f_data) return TRUE;
2021 
2022   switch (hdr->version) {
2023   case 10:
2024   case 9:
2025     if (tpl->tpl[NF9_IN_SRC_MAC].len) {
2026       if (!memcmp(&entry->key.src_mac.a, pptrs->f_data+tpl->tpl[NF9_IN_SRC_MAC].off, MIN(tpl->tpl[NF9_IN_SRC_MAC].len, 6)))
2027 	return (FALSE | entry->key.src_mac.neg);
2028     }
2029     return (TRUE ^ entry->key.src_mac.neg);
2030   default:
2031     return TRUE; /* this field does not exist: condition is always true */
2032   }
2033 }
2034 
pretag_dst_mac_handler(struct packet_ptrs * pptrs,void * unused,void * e)2035 int pretag_dst_mac_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2036 {
2037   struct id_entry *entry = e;
2038   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2039   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2040 
2041   if (!pptrs->f_data) return TRUE;
2042 
2043   switch (hdr->version) {
2044   case 10:
2045   case 9:
2046     if (tpl->tpl[NF9_IN_DST_MAC].len) {
2047       if (!memcmp(&entry->key.dst_mac.a, pptrs->f_data+tpl->tpl[NF9_IN_DST_MAC].off, MIN(tpl->tpl[NF9_IN_DST_MAC].len, 6)))
2048         return (FALSE | entry->key.dst_mac.neg);
2049     }
2050     return (TRUE ^ entry->key.dst_mac.neg);
2051   default:
2052     return TRUE; /* this field does not exist: condition is always true */
2053   }
2054 }
2055 
pretag_vlan_id_handler(struct packet_ptrs * pptrs,void * unused,void * e)2056 int pretag_vlan_id_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2057 {
2058   struct id_entry *entry = e;
2059   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2060   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2061   u_int16_t tmp16 = 0, vlan_id = 0;
2062 
2063   if (!pptrs->f_data) return TRUE;
2064 
2065   switch (hdr->version) {
2066   case 10:
2067   case 9:
2068     if (tpl->tpl[NF9_IN_VLAN].len) {
2069       memcpy(&tmp16, pptrs->f_data+tpl->tpl[NF9_IN_VLAN].off, MIN(tpl->tpl[NF9_IN_VLAN].len, 2));
2070     }
2071     else if (tpl->tpl[NF9_DOT1QVLANID].len) {
2072       memcpy(&tmp16, pptrs->f_data+tpl->tpl[NF9_DOT1QVLANID].off, MIN(tpl->tpl[NF9_DOT1QVLANID].len, 2));
2073     }
2074     vlan_id = ntohs(tmp16);
2075     if (entry->key.vlan_id.n == vlan_id) return (FALSE | entry->key.vlan_id.neg);
2076     else return (TRUE ^ entry->key.vlan_id.neg);
2077   default:
2078     return TRUE; /* this field does not exist: condition is always true */
2079   }
2080 }
2081 
pretag_src_net_handler(struct packet_ptrs * pptrs,void * unused,void * e)2082 int pretag_src_net_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2083 {
2084   struct id_entry *entry = e;
2085   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2086   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2087   struct host_addr addr;
2088 
2089   if (!pptrs->f_data) return TRUE;
2090 
2091   switch(hdr->version) {
2092   case 10:
2093   case 9:
2094     if (tpl->tpl[NF9_IPV4_SRC_ADDR].len) {
2095       memcpy(&addr.address.ipv4, pptrs->f_data+tpl->tpl[NF9_IPV4_SRC_ADDR].off, MIN(tpl->tpl[NF9_IPV4_SRC_ADDR].len, 4));
2096       addr.family = AF_INET;
2097     }
2098     else if (tpl->tpl[NF9_IPV4_SRC_PREFIX].len) {
2099       memcpy(&addr.address.ipv4, pptrs->f_data+tpl->tpl[NF9_IPV4_SRC_PREFIX].off, MIN(tpl->tpl[NF9_IPV4_SRC_PREFIX].len, 4));
2100       addr.family = AF_INET;
2101     }
2102     if (tpl->tpl[NF9_IPV6_SRC_ADDR].len) {
2103       memcpy(&addr.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_SRC_ADDR].off, MIN(tpl->tpl[NF9_IPV6_SRC_ADDR].len, 16));
2104       addr.family = AF_INET6;
2105     }
2106     else if (tpl->tpl[NF9_IPV6_SRC_PREFIX].len) {
2107       memcpy(&addr.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_SRC_PREFIX].off, MIN(tpl->tpl[NF9_IPV6_SRC_PREFIX].len, 16));
2108       addr.family = AF_INET6;
2109     }
2110     break;
2111   case 5:
2112     addr.address.ipv4.s_addr = ((struct struct_export_v5 *) pptrs->f_data)->srcaddr.s_addr;
2113     addr.family = AF_INET;
2114     break;
2115   default:
2116     return TRUE;
2117   }
2118 
2119   if (!host_addr_mask_cmp(&entry->key.src_net.a, &entry->key.src_net.m, &addr))
2120     return (FALSE | entry->key.src_net.neg);
2121   else
2122     return (TRUE ^ entry->key.src_net.neg);
2123 }
2124 
pretag_dst_net_handler(struct packet_ptrs * pptrs,void * unused,void * e)2125 int pretag_dst_net_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2126 {
2127   struct id_entry *entry = e;
2128   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2129   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2130   struct host_addr addr;
2131 
2132   if (!pptrs->f_data) return TRUE;
2133 
2134   switch(hdr->version) {
2135   case 10:
2136   case 9:
2137     if (tpl->tpl[NF9_IPV4_DST_ADDR].len) {
2138       memcpy(&addr.address.ipv4, pptrs->f_data+tpl->tpl[NF9_IPV4_DST_ADDR].off, MIN(tpl->tpl[NF9_IPV4_DST_ADDR].len, 4));
2139       addr.family = AF_INET;
2140     }
2141     else if (tpl->tpl[NF9_IPV4_DST_PREFIX].len) {
2142       memcpy(&addr.address.ipv4, pptrs->f_data+tpl->tpl[NF9_IPV4_DST_PREFIX].off, MIN(tpl->tpl[NF9_IPV4_DST_PREFIX].len, 4));
2143       addr.family = AF_INET;
2144     }
2145     if (tpl->tpl[NF9_IPV6_DST_ADDR].len) {
2146       memcpy(&addr.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_DST_ADDR].off, MIN(tpl->tpl[NF9_IPV6_DST_ADDR].len, 16));
2147       addr.family = AF_INET6;
2148     }
2149     else if (tpl->tpl[NF9_IPV6_DST_PREFIX].len) {
2150       memcpy(&addr.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_DST_PREFIX].off, MIN(tpl->tpl[NF9_IPV6_DST_PREFIX].len, 16));
2151       addr.family = AF_INET6;
2152     }
2153     break;
2154   case 5:
2155     addr.address.ipv4.s_addr = ((struct struct_export_v5 *) pptrs->f_data)->dstaddr.s_addr;
2156     addr.family = AF_INET;
2157     break;
2158   default:
2159     return TRUE;
2160   }
2161 
2162   if (!host_addr_mask_cmp(&entry->key.dst_net.a, &entry->key.dst_net.m, &addr))
2163     return (FALSE | entry->key.dst_net.neg);
2164   else
2165     return (TRUE ^ entry->key.dst_net.neg);
2166 }
2167 
pretag_forwarding_status_handler(struct packet_ptrs * pptrs,void * unused,void * e)2168 int pretag_forwarding_status_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2169 {
2170   struct id_entry *entry = e;
2171   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2172   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2173   u_int32_t fwdstatus = 0;
2174 
2175   if (!pptrs->f_data) return TRUE;
2176 
2177   switch (hdr->version) {
2178   case 10:
2179   case 9:
2180     /* being specific on the length because IANA defines this field as
2181        unsigned32 but vendor implementation suggests this is defined as
2182        1 octet */
2183     if (tpl->tpl[NF9_FORWARDING_STATUS].len == 1) {
2184       memcpy(&fwdstatus, pptrs->f_data+tpl->tpl[NF9_FORWARDING_STATUS].off, MIN(tpl->tpl[NF9_FORWARDING_STATUS].len, 1));
2185     }
2186     else return TRUE;
2187 
2188     u_int32_t comp = (entry->key.fwdstatus.n & 0xC0);
2189     if (comp == entry->key.fwdstatus.n) {
2190       /* We have a generic (unknown) status provided so we then take everything that match that. */
2191       u_int32_t base = (fwdstatus & 0xC0);
2192       if ( comp == base )
2193         return (FALSE | entry->key.fwdstatus.neg);
2194       else
2195         return (TRUE ^ entry->key.fwdstatus.neg);
2196     }
2197     else { /* We have a specific code so lets handle that. */
2198       if (entry->key.fwdstatus.n == fwdstatus)
2199         return (FALSE | entry->key.fwdstatus.neg);
2200       else
2201         return (TRUE ^ entry->key.fwdstatus.neg);
2202     }
2203   default:
2204     return TRUE; /* this field does not exist: condition is always true */
2205   }
2206 }
2207 
2208 
pretag_cvlan_id_handler(struct packet_ptrs * pptrs,void * unused,void * e)2209 int pretag_cvlan_id_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2210 {
2211   struct id_entry *entry = e;
2212   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2213   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2214   u_int16_t tmp16 = 0, cvlan_id = 0;
2215 
2216   if (!pptrs->f_data) return TRUE;
2217 
2218   switch (hdr->version) {
2219   case 10:
2220   case 9:
2221     if (tpl->tpl[NF9_DOT1QCVLANID].len) {
2222       memcpy(&tmp16, pptrs->f_data+tpl->tpl[NF9_DOT1QCVLANID].off, MIN(tpl->tpl[NF9_DOT1QCVLANID].len, 2));
2223     }
2224     cvlan_id = ntohs(tmp16);
2225     if (entry->key.cvlan_id.n == cvlan_id) return (FALSE | entry->key.cvlan_id.neg);
2226     else return (TRUE ^ entry->key.cvlan_id.neg);
2227   default:
2228     return TRUE; /* this field does not exist: condition is always true */
2229   }
2230 }
2231 
pretag_set_tos_handler(struct packet_ptrs * pptrs,void * unused,void * e)2232 int pretag_set_tos_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2233 {
2234   struct id_entry *entry = e;
2235 
2236   memcpy(&pptrs->set_tos, &entry->set_tos, sizeof(s_uint8_t));
2237 
2238   return PRETAG_MAP_RCODE_SET_TOS;
2239 }
2240 
BTA_lookup_bgp_port_handler(struct packet_ptrs * pptrs,void * unused,void * e)2241 int BTA_lookup_bgp_port_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2242 {
2243   struct id_entry *entry = e;
2244 
2245   memcpy(&pptrs->lookup_bgp_port, &entry->key.lookup_bgp_port, sizeof(s_uint16_t));
2246 
2247   return BTA_MAP_RCODE_LOOKUP_BGP_PORT;
2248 }
2249 
pretag_id_handler(struct packet_ptrs * pptrs,void * id,void * e)2250 int pretag_id_handler(struct packet_ptrs *pptrs, void *id, void *e)
2251 {
2252   struct id_entry *entry = e;
2253   pm_id_t *tid = id;
2254 
2255   *tid = entry->id;
2256 
2257   if (!entry->id && entry->flags == BPAS_MAP_RCODE_BGP) {
2258     struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
2259     struct bgp_info *info;
2260 
2261     if (src_ret) {
2262       info = (struct bgp_info *) pptrs->bgp_src_info;
2263 
2264       if (info && info->attr) {
2265 	if (info->attr->aspath && info->attr->aspath->str) {
2266 	  *tid = evaluate_first_asn(info->attr->aspath->str);
2267 
2268 	  if (!(*tid) && config.bgp_daemon_stdcomm_pattern_to_asn) {
2269 	    char tmp_stdcomms[MAX_BGP_STD_COMMS];
2270 
2271 	    if (info->attr->community && info->attr->community->str) {
2272 	      evaluate_comm_patterns(tmp_stdcomms, info->attr->community->str, std_comm_patterns_to_asn, MAX_BGP_STD_COMMS);
2273 	      copy_stdcomm_to_asn(tmp_stdcomms, (as_t *)tid, FALSE);
2274 	    }
2275           }
2276 
2277 	  if (!(*tid) && config.bgp_daemon_lrgcomm_pattern_to_asn) {
2278 	    char tmp_lrgcomms[MAX_BGP_LRG_COMMS];
2279 
2280 	    if (info->attr->lcommunity && info->attr->lcommunity->str) {
2281 	      evaluate_comm_patterns(tmp_lrgcomms, info->attr->lcommunity->str, lrg_comm_patterns_to_asn, MAX_BGP_LRG_COMMS);
2282 	      copy_lrgcomm_to_asn(tmp_lrgcomms, (as_t *)tid, FALSE);
2283 	    }
2284           }
2285         }
2286       }
2287     }
2288   }
2289 
2290   if (entry->id_inc) entry->id++;
2291 
2292   if (entry->flags == BTA_MAP_RCODE_ID_ID2) {
2293     return BTA_MAP_RCODE_ID_ID2; /* cap */
2294   }
2295 
2296   return PRETAG_MAP_RCODE_ID; /* cap */
2297 }
2298 
pretag_id2_handler(struct packet_ptrs * pptrs,void * id,void * e)2299 int pretag_id2_handler(struct packet_ptrs *pptrs, void *id, void *e)
2300 {
2301   struct id_entry *entry = e;
2302   pm_id_t *tid = id;
2303 
2304   *tid = entry->id2;
2305 
2306   if (entry->id2_inc) entry->id2++;
2307 
2308   return PRETAG_MAP_RCODE_ID2; /* cap */
2309 }
2310 
pretag_label_handler(struct packet_ptrs * pptrs,void * id,void * e)2311 int pretag_label_handler(struct packet_ptrs *pptrs, void *id, void *e)
2312 {
2313   struct id_entry *entry = e;
2314   pt_label_t *out_label = (pt_label_t *) id;
2315 
2316   if (out_label) {
2317     pretag_copy_label(out_label, &entry->label);
2318   }
2319 
2320   return PRETAG_MAP_RCODE_LABEL; /* cap */
2321 }
2322 
SF_pretag_input_handler(struct packet_ptrs * pptrs,void * unused,void * e)2323 int SF_pretag_input_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2324 {
2325   struct id_entry *entry = e;
2326   SFSample *sample = (SFSample *) pptrs->f_data;
2327 
2328   if (entry->key.input.n == sample->inputPort) return (FALSE | entry->key.input.neg);
2329   else return (TRUE ^ entry->key.input.neg);
2330 }
2331 
SF_pretag_output_handler(struct packet_ptrs * pptrs,void * unused,void * e)2332 int SF_pretag_output_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2333 {
2334   struct id_entry *entry = e;
2335   SFSample *sample = (SFSample *) pptrs->f_data;
2336 
2337   if (entry->key.output.n == sample->outputPort) return (FALSE | entry->key.output.neg);
2338   else return (TRUE ^ entry->key.output.neg);
2339 }
2340 
SF_pretag_nexthop_handler(struct packet_ptrs * pptrs,void * unused,void * e)2341 int SF_pretag_nexthop_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2342 {
2343   struct id_entry *entry = e;
2344   SFSample *sample = (SFSample *) pptrs->f_data;
2345 
2346   if (entry->key.nexthop.a.family == AF_INET) {
2347     if (!memcmp(&entry->key.nexthop.a.address.ipv4, &sample->nextHop.address.ip_v4, 4)) return (FALSE | entry->key.nexthop.neg);
2348   }
2349   else if (entry->key.nexthop.a.family == AF_INET6) {
2350     if (!memcmp(&entry->key.nexthop.a.address.ipv6, &sample->nextHop.address.ip_v6, IP6AddrSz)) return (FALSE | entry->key.nexthop.neg);
2351   }
2352 
2353   return (TRUE ^ entry->key.nexthop.neg);
2354 }
2355 
SF_pretag_bgp_nexthop_handler(struct packet_ptrs * pptrs,void * unused,void * e)2356 int SF_pretag_bgp_nexthop_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2357 {
2358   struct id_entry *entry = e;
2359   SFSample *sample = (SFSample *) pptrs->f_data;
2360 
2361   if (entry->last_matched == PRETAG_BGP_NEXTHOP) return FALSE;
2362 
2363   /* check network-related primitives against fallback scenarios */
2364   if (!evaluate_lm_method(pptrs, TRUE, config.nfacctd_net, NF_NET_KEEP)) return TRUE;
2365 
2366   if (entry->key.bgp_nexthop.a.family == AF_INET) {
2367     if (!memcmp(&entry->key.bgp_nexthop.a.address.ipv4, &sample->bgp_nextHop.address.ip_v4, 4)) return (FALSE | entry->key.bgp_nexthop.neg);
2368   }
2369   else if (entry->key.bgp_nexthop.a.family == AF_INET6) {
2370     if (!memcmp(&entry->key.bgp_nexthop.a.address.ipv6, &sample->bgp_nextHop.address.ip_v6, IP6AddrSz)) return (FALSE | entry->key.bgp_nexthop.neg);
2371   }
2372 
2373   return (TRUE ^ entry->key.bgp_nexthop.neg);
2374 }
2375 
SF_pretag_agent_id_handler(struct packet_ptrs * pptrs,void * unused,void * e)2376 int SF_pretag_agent_id_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2377 {
2378   struct id_entry *entry = e;
2379   SFSample *sample = (SFSample *) pptrs->f_data;
2380 
2381   if (entry->key.agent_id.n == sample->agentSubId) return (FALSE | entry->key.agent_id.neg);
2382   else return (TRUE ^ entry->key.agent_id.neg);
2383 }
2384 
SF_pretag_sample_type_handler(struct packet_ptrs * pptrs,void * unused,void * e)2385 int SF_pretag_sample_type_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2386 {
2387   struct id_entry *entry = e;
2388 
2389   if (entry->key.sample_type.n == pptrs->sample_type) return (FALSE | entry->key.sample_type.neg);
2390   else return (TRUE ^ entry->key.sample_type.neg);
2391 }
2392 
SF_pretag_direction_handler(struct packet_ptrs * pptrs,void * unused,void * e)2393 int SF_pretag_direction_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2394 {
2395   struct id_entry *entry = e;
2396   SFSample *sample = (SFSample *) pptrs->f_data;
2397 
2398   if ((sample->inputPort == sample->ds_index && entry->key.direction.n == 0) ||
2399       (sample->outputPort == sample->ds_index && entry->key.direction.n == 1)) {
2400     return (FALSE | entry->key.direction.neg);
2401   }
2402   else return (TRUE ^ entry->key.direction.neg);
2403 }
2404 
SF_pretag_src_as_handler(struct packet_ptrs * pptrs,void * unused,void * e)2405 int SF_pretag_src_as_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2406 {
2407   struct id_entry *entry = e;
2408   SFSample *sample = (SFSample *) pptrs->f_data;
2409 
2410   /* If in a fallback scenario, ie. NF_AS_BGP + NF_AS_KEEP set, check BGP first */
2411   if (config.nfacctd_as & NF_AS_BGP && pptrs->bgp_src) return FALSE;
2412 
2413   if (entry->key.src_as.n == sample->src_as) return (FALSE | entry->key.src_as.neg);
2414   else return (TRUE ^ entry->key.src_as.neg);
2415 }
2416 
SF_pretag_dst_as_handler(struct packet_ptrs * pptrs,void * unused,void * e)2417 int SF_pretag_dst_as_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2418 {
2419   struct id_entry *entry = e;
2420   SFSample *sample = (SFSample *) pptrs->f_data;
2421 
2422   /* If in a fallback scenario, ie. NF_AS_BGP + NF_AS_KEEP set, check BGP first */
2423   if (config.nfacctd_as & NF_AS_BGP && pptrs->bgp_dst) return FALSE;
2424 
2425   if (entry->key.dst_as.n == sample->dst_as) return (FALSE | entry->key.dst_as.neg);
2426   else return (TRUE ^ entry->key.dst_as.neg);
2427 }
2428 
SF_pretag_src_mac_handler(struct packet_ptrs * pptrs,void * unused,void * e)2429 int SF_pretag_src_mac_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2430 {
2431   struct id_entry *entry = e;
2432   SFSample *sample = (SFSample *) pptrs->f_data;
2433 
2434   if (!memcmp(entry->key.src_mac.a, sample->eth_src, ETH_ADDR_LEN)) return (FALSE | entry->key.src_mac.neg);
2435   else return (TRUE ^ entry->key.src_mac.neg);
2436 }
2437 
SF_pretag_dst_mac_handler(struct packet_ptrs * pptrs,void * unused,void * e)2438 int SF_pretag_dst_mac_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2439 {
2440   struct id_entry *entry = e;
2441   SFSample *sample = (SFSample *) pptrs->f_data;
2442 
2443   if (!memcmp(entry->key.dst_mac.a, sample->eth_dst, ETH_ADDR_LEN)) return (FALSE | entry->key.dst_mac.neg);
2444   else return (TRUE ^ entry->key.dst_mac.neg);
2445 }
2446 
SF_pretag_vlan_id_handler(struct packet_ptrs * pptrs,void * unused,void * e)2447 int SF_pretag_vlan_id_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2448 {
2449   struct id_entry *entry = e;
2450   SFSample *sample = (SFSample *) pptrs->f_data;
2451 
2452   if (entry->key.vlan_id.n == sample->in_vlan ||
2453       entry->key.vlan_id.n == sample->out_vlan) return (FALSE | entry->key.vlan_id.neg);
2454   else return (TRUE ^ entry->key.vlan_id.neg);
2455 }
2456 
SF_pretag_mpls_pw_id_handler(struct packet_ptrs * pptrs,void * unused,void * e)2457 int SF_pretag_mpls_pw_id_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2458 {
2459   struct id_entry *entry = e;
2460   SFSample *sample = (SFSample *) pptrs->f_data;
2461 
2462   if (entry->key.mpls_pw_id.n == sample->mpls_vll_vc_id) return (FALSE | entry->key.mpls_pw_id.neg);
2463   else return (TRUE ^ entry->key.mpls_pw_id.neg);
2464 }
2465 
SF_pretag_src_net_handler(struct packet_ptrs * pptrs,void * unused,void * e)2466 int SF_pretag_src_net_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2467 {
2468   struct id_entry *entry = e;
2469   SFSample *sample = (SFSample *) pptrs->f_data;
2470   SFLAddress *sf_addr = &sample->ipsrc;
2471   struct host_addr addr;
2472 
2473   if (sample->gotIPV4) {
2474     addr.address.ipv4.s_addr = sample->dcd_srcIP.s_addr;
2475     addr.family = AF_INET;
2476   }
2477   else if (sample->gotIPV6) {
2478     memcpy(&addr.address.ipv6, &sf_addr->address.ip_v6, IP6AddrSz);
2479     addr.family = AF_INET6;
2480   }
2481 
2482   if (!host_addr_mask_cmp(&entry->key.src_net.a, &entry->key.src_net.m, &addr))
2483     return (FALSE | entry->key.src_net.neg);
2484   else
2485     return (TRUE ^ entry->key.src_net.neg);
2486 }
2487 
SF_pretag_dst_net_handler(struct packet_ptrs * pptrs,void * unused,void * e)2488 int SF_pretag_dst_net_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2489 {
2490   struct id_entry *entry = e;
2491   SFSample *sample = (SFSample *) pptrs->f_data;
2492   SFLAddress *sf_addr = &sample->ipdst;
2493   struct host_addr addr;
2494 
2495   if (sample->gotIPV4) {
2496     addr.address.ipv4.s_addr = sample->dcd_dstIP.s_addr;
2497     addr.family = AF_INET;
2498   }
2499   else if (sample->gotIPV6) {
2500     memcpy(&addr.address.ipv6, &sf_addr->address.ip_v6, IP6AddrSz);
2501     addr.family = AF_INET6;
2502   }
2503 
2504   if (!host_addr_mask_cmp(&entry->key.dst_net.a, &entry->key.dst_net.m, &addr))
2505     return (FALSE | entry->key.dst_net.neg);
2506   else
2507     return (TRUE ^ entry->key.dst_net.neg);
2508 }
2509 
PM_pretag_src_as_handler(struct packet_ptrs * pptrs,void * unused,void * e)2510 int PM_pretag_src_as_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2511 {
2512   struct id_entry *entry = e;
2513   as_t res = search_pretag_src_as(&nt, &nc, pptrs);
2514 
2515   if (entry->key.src_as.n == res) return (FALSE | entry->key.src_as.neg);
2516   else return (TRUE ^ entry->key.src_as.neg);
2517 }
2518 
PM_pretag_dst_as_handler(struct packet_ptrs * pptrs,void * unused,void * e)2519 int PM_pretag_dst_as_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2520 {
2521   struct id_entry *entry = e;
2522   as_t res = search_pretag_dst_as(&nt, &nc, pptrs);
2523 
2524   if (entry->key.dst_as.n == res) return (FALSE | entry->key.dst_as.neg);
2525   else return (TRUE ^ entry->key.dst_as.neg);
2526 }
2527 
PM_pretag_input_handler(struct packet_ptrs * pptrs,void * unused,void * e)2528 int PM_pretag_input_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2529 {
2530   struct id_entry *entry = e;
2531 
2532   if (entry->key.input.n == pptrs->ifindex_in) return (FALSE | entry->key.input.neg);
2533   else return (TRUE ^ entry->key.input.neg);
2534 }
2535 
PM_pretag_output_handler(struct packet_ptrs * pptrs,void * unused,void * e)2536 int PM_pretag_output_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2537 {
2538   struct id_entry *entry = e;
2539 
2540   if (entry->key.output.n == pptrs->ifindex_out) return (FALSE | entry->key.output.neg);
2541   else return (TRUE ^ entry->key.output.neg);
2542 }
2543 
PM_pretag_direction_handler(struct packet_ptrs * pptrs,void * unused,void * e)2544 int PM_pretag_direction_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2545 {
2546   struct id_entry *entry = e;
2547 
2548   if (entry->key.direction.n == pptrs->direction) return (FALSE | entry->key.output.neg);
2549   else return (TRUE ^ entry->key.output.neg);
2550 }
2551 
PT_stack_sum(pm_id_t tag,pm_id_t pre)2552 pm_id_t PT_stack_sum(pm_id_t tag, pm_id_t pre)
2553 {
2554   return tag + pre;
2555 }
2556 
PT_stack_logical_or(pm_id_t tag,pm_id_t pre)2557 pm_id_t PT_stack_logical_or(pm_id_t tag, pm_id_t pre)
2558 {
2559   return tag | pre;
2560 }
2561 
BPAS_bgp_nexthop_handler(struct packet_ptrs * pptrs,void * unused,void * e)2562 int BPAS_bgp_nexthop_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2563 {
2564   struct id_entry *entry = e;
2565   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
2566   struct bgp_info *info;
2567 
2568   if (src_ret) {
2569     info = (struct bgp_info *) pptrs->bgp_src_info;
2570     if (info && info->attr) {
2571       if (entry->key.bgp_nexthop.a.family == AF_INET) {
2572 	if (info->attr->mp_nexthop.family == AF_INET) {
2573           if (!memcmp(&entry->key.bgp_nexthop.a.address.ipv4, &info->attr->mp_nexthop.address.ipv4, 4))
2574             return (FALSE | entry->key.bgp_nexthop.neg);
2575 	}
2576 	else {
2577           if (!memcmp(&entry->key.bgp_nexthop.a.address.ipv4, &info->attr->nexthop, 4))
2578             return (FALSE | entry->key.bgp_nexthop.neg);
2579 	}
2580       }
2581       else if (entry->key.nexthop.a.family == AF_INET6) {
2582 	if (!memcmp(&entry->key.bgp_nexthop.a.address.ipv6, &info->attr->mp_nexthop.address.ipv6, 16))
2583           return (FALSE | entry->key.bgp_nexthop.neg);
2584       }
2585     }
2586   }
2587 
2588   return (TRUE ^ entry->key.bgp_nexthop.neg);
2589 }
2590 
BPAS_bgp_peer_dst_as_handler(struct packet_ptrs * pptrs,void * unused,void * e)2591 int BPAS_bgp_peer_dst_as_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2592 {
2593   struct id_entry *entry = e;
2594   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
2595   struct bgp_info *info;
2596   as_t asn = 0;
2597 
2598   if (src_ret) {
2599     info = (struct bgp_info *) pptrs->bgp_src_info;
2600     if (info && info->attr) {
2601       if (info->attr->aspath && info->attr->aspath->str) {
2602         asn = evaluate_first_asn(info->attr->aspath->str);
2603 
2604         if (!asn && config.bgp_daemon_stdcomm_pattern_to_asn) {
2605           char tmp_stdcomms[MAX_BGP_STD_COMMS];
2606 
2607           if (info->attr->community && info->attr->community->str) {
2608             evaluate_comm_patterns(tmp_stdcomms, info->attr->community->str, std_comm_patterns_to_asn, MAX_BGP_STD_COMMS);
2609             copy_stdcomm_to_asn(tmp_stdcomms, &asn, FALSE);
2610           }
2611         }
2612 
2613         if (!asn && config.bgp_daemon_lrgcomm_pattern_to_asn) {
2614           char tmp_lrgcomms[MAX_BGP_LRG_COMMS];
2615 
2616           if (info->attr->lcommunity && info->attr->lcommunity->str) {
2617             evaluate_comm_patterns(tmp_lrgcomms, info->attr->lcommunity->str, lrg_comm_patterns_to_asn, MAX_BGP_LRG_COMMS);
2618             copy_lrgcomm_to_asn(tmp_lrgcomms, &asn, FALSE);
2619           }
2620         }
2621       }
2622     }
2623   }
2624 
2625   if (entry->key.peer_dst_as.n == asn) return (FALSE | entry->key.peer_dst_as.neg);
2626   else return (TRUE ^ entry->key.peer_dst_as.neg);
2627 }
2628 
BITR_mpls_label_bottom_handler(struct packet_ptrs * pptrs,void * unused,void * e)2629 int BITR_mpls_label_bottom_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2630 {
2631   struct id_entry *entry = e;
2632   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2633   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2634   int label_idx;
2635   u_int32_t label;
2636 
2637   switch(hdr->version) {
2638   case 10:
2639   case 9:
2640     for (label_idx = NF9_MPLS_LABEL_1; label_idx <= NF9_MPLS_LABEL_9; label_idx++) {
2641       if (tpl->tpl[label_idx].len == 3 && check_bosbit(pptrs->f_data+tpl->tpl[label_idx].off)) {
2642         label = decode_mpls_label(pptrs->f_data+tpl->tpl[label_idx].off);
2643 	if (entry->key.mpls_label_bottom.n == label) return (FALSE | entry->key.mpls_label_bottom.neg);
2644       }
2645     }
2646     return (TRUE ^ entry->key.mpls_label_bottom.neg);
2647     break;
2648   default:
2649     return (TRUE ^ entry->key.mpls_label_bottom.neg);
2650     break;
2651   }
2652 }
2653 
BITR_mpls_vpn_id_handler(struct packet_ptrs * pptrs,void * unused,void * e)2654 int BITR_mpls_vpn_id_handler(struct packet_ptrs *pptrs, void *unused, void *e)
2655 {
2656   struct id_entry *entry = e;
2657   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2658   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2659   u_int32_t tmp32 = 0, id = 0;
2660 
2661   switch(hdr->version) {
2662   case 10:
2663   case 9:
2664     if (tpl->tpl[NF9_INGRESS_VRFID].len) {
2665       memcpy(&tmp32, pptrs->f_data+tpl->tpl[NF9_INGRESS_VRFID].off, MIN(tpl->tpl[NF9_INGRESS_VRFID].len, 4));
2666       id = ntohl(tmp32);
2667 
2668       if (entry->key.mpls_vpn_id.n == id) return (FALSE | entry->key.mpls_vpn_id.neg);
2669     }
2670 
2671     if (tpl->tpl[NF9_EGRESS_VRFID].len) {
2672       memcpy(&tmp32, pptrs->f_data+tpl->tpl[NF9_EGRESS_VRFID].off, MIN(tpl->tpl[NF9_EGRESS_VRFID].len, 4));
2673       id = ntohl(tmp32);
2674 
2675       if (entry->key.mpls_vpn_id.n == id) return (FALSE | entry->key.mpls_vpn_id.neg);
2676     }
2677 
2678     return (TRUE ^ entry->key.mpls_vpn_id.neg);
2679     break;
2680   default:
2681     return (TRUE ^ entry->key.mpls_vpn_id.neg);
2682     break;
2683   }
2684 }
2685 
custom_primitives_map_name_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)2686 int custom_primitives_map_name_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
2687 {
2688   struct custom_primitives *table = (struct custom_primitives *) req->key_value_table;
2689   int idx;
2690 
2691   if (table) {
2692     lower_string(value);
2693     for (idx = 0; idx < table->num && strlen(table->primitive[idx].name); idx++) {
2694       if (!strcmp(table->primitive[idx].name, value)) {
2695         Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Duplicate custom aggregate primitive name specified: %s.\n",
2696 		config.name, config.type, filename, value);
2697         return TRUE;
2698       }
2699     }
2700 
2701     strlcpy(table->primitive[table->num].name, value, MAX_CUSTOM_PRIMITIVE_NAMELEN);
2702   }
2703   else {
2704     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] custom aggregate primitives registry not allocated.\n", config.name, config.type, filename);
2705     return TRUE;
2706   }
2707 
2708   return FALSE;
2709 }
2710 
custom_primitives_map_field_type_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)2711 int custom_primitives_map_field_type_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
2712 {
2713   struct custom_primitives *table = (struct custom_primitives *) req->key_value_table;
2714   char *pen = NULL, *type = NULL, *endptr;
2715 
2716   if (table) {
2717     u_int8_t repeat_id;
2718     int idx;
2719 
2720     if ((type = strchr(value, ':'))) {
2721       pen = value;
2722       *type = '\0';
2723       type++;
2724     }
2725     else type = value;
2726 
2727     if (pen) table->primitive[table->num].pen = strtoul(pen, &endptr, 10);
2728     table->primitive[table->num].field_type = atoi(type);
2729     if (!table->primitive[table->num].field_type) {
2730       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Invalid NetFlow v9/IPFIX field type '%s'.\n", config.name, config.type, filename, value);
2731       return TRUE;
2732     }
2733 
2734     for (idx = 0, repeat_id = 0; idx < table->num; idx++) {
2735       if (table->primitive[idx].field_type == table->primitive[table->num].field_type &&
2736 	  table->primitive[idx].pen == table->primitive[table->num].pen)
2737 	repeat_id++;
2738     }
2739     table->primitive[table->num].repeat_id = repeat_id;
2740   }
2741   else {
2742     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] custom aggregate primitives registry not allocated.\n", config.name, config.type, filename);
2743     return TRUE;
2744   }
2745 
2746   return FALSE;
2747 }
2748 
custom_primitives_map_packet_ptr_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)2749 int custom_primitives_map_packet_ptr_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
2750 {
2751   struct custom_primitives *table = (struct custom_primitives *) req->key_value_table;
2752   struct packet_data_ptr *pd_ptr = NULL;
2753   char *layer = NULL, *proto_ptr = NULL, *offset_ptr = NULL, *endptr;
2754   u_int16_t offset = 0, proto = 0, idx = 0;
2755 
2756   if (/* config.acct_type == ACCT_PM && */ table) {
2757     for (idx = 0; idx < MAX_CUSTOM_PRIMITIVE_PD_PTRS; idx++) {
2758       if (!table->primitive[table->num].pd_ptr[idx].ptr_idx.set) {
2759 	pd_ptr = &table->primitive[table->num].pd_ptr[idx];
2760 	break;
2761       }
2762     }
2763 
2764     if (!pd_ptr) {
2765       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] exceeded %u 'packet_ptr' limit per rule.\n",
2766 		config.name, config.type, filename, MAX_CUSTOM_PRIMITIVE_PD_PTRS);
2767       return TRUE;
2768     }
2769 
2770     layer = value;
2771 
2772     proto_ptr = strchr(value, ':');
2773     offset_ptr = strchr(value, '+');
2774 
2775     if (offset_ptr) {
2776       *offset_ptr = '\0';
2777       offset_ptr++;
2778       endptr = NULL;
2779       offset = strtoul(offset_ptr, &endptr, 10);
2780     }
2781 
2782     if (proto_ptr) {
2783       *proto_ptr = '\0';
2784       proto_ptr++;
2785       endptr = NULL;
2786       if (strchr(proto_ptr, 'x')) proto = strtoul(proto_ptr, &endptr, 16);
2787       else proto = strtoul(proto_ptr, &endptr, 10);
2788     }
2789 
2790     if (!strncmp(layer, "packet", 6)) {
2791       pd_ptr->ptr_idx.n = CUSTOM_PRIMITIVE_PACKET_PTR;
2792       pd_ptr->ptr_idx.set = TRUE;
2793       if (proto) goto proto_err;
2794     }
2795     else if (!strncmp(layer, "mac", 3)) {
2796       pd_ptr->ptr_idx.n = CUSTOM_PRIMITIVE_MAC_PTR;
2797       pd_ptr->ptr_idx.set = TRUE;
2798       if (proto) goto proto_err;
2799     }
2800     else if (!strncmp(layer, "vlan", 4)) {
2801       pd_ptr->ptr_idx.n = CUSTOM_PRIMITIVE_VLAN_PTR;
2802       pd_ptr->ptr_idx.set = TRUE;
2803       if (proto) goto proto_err;
2804     }
2805     else if (!strncmp(layer, "mpls", 4)) {
2806       pd_ptr->ptr_idx.n = CUSTOM_PRIMITIVE_MPLS_PTR;
2807       pd_ptr->ptr_idx.set = TRUE;
2808       if (proto) goto proto_err;
2809     }
2810     else if (!strncmp(layer, "l3", 2)) {
2811       pd_ptr->ptr_idx.n = CUSTOM_PRIMITIVE_L3_PTR;
2812       pd_ptr->ptr_idx.set = TRUE;
2813       if (proto) {
2814         pd_ptr->proto.n = proto;
2815         pd_ptr->proto.set = TRUE;
2816       }
2817     }
2818     else if (!strncmp(layer, "l4", 2)) {
2819       pd_ptr->ptr_idx.n = CUSTOM_PRIMITIVE_L4_PTR;
2820       pd_ptr->ptr_idx.set = TRUE;
2821       if (proto) {
2822         pd_ptr->proto.n = proto;
2823         pd_ptr->proto.set = TRUE;
2824       }
2825     }
2826     else if (!strncmp(layer, "payload", 7)) {
2827       pd_ptr->ptr_idx.n = CUSTOM_PRIMITIVE_PAYLOAD_PTR;
2828       pd_ptr->ptr_idx.set = TRUE;
2829       if (proto) goto proto_err;
2830     }
2831     else {
2832       Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Invalid packet pointer '%s'.\n", config.name, config.type, filename, value);
2833       return TRUE;
2834     }
2835 
2836     pd_ptr->off = offset;
2837   }
2838   else {
2839     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] custom aggregate primitives registry not allocated.\n", config.name, config.type, filename);
2840     return TRUE;
2841   }
2842 
2843   return FALSE;
2844 
2845   proto_err:
2846   Log(LOG_WARNING, "WARN ( %s/%s ): [%s] protocol type not supported for '%s'.\n", config.name, config.type, filename, layer);
2847   return TRUE;
2848 }
2849 
custom_primitives_map_len_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)2850 int custom_primitives_map_len_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
2851 {
2852   struct custom_primitives *table = (struct custom_primitives *) req->key_value_table;
2853 
2854   if (table) {
2855     table->primitive[table->num].len = atoi(value);
2856     if (table->primitive[table->num].len) {
2857       if (table->primitive[table->num].len == PM_VARIABLE_LENGTH) {
2858         Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Invalid length '%s'.\n", config.name, config.type, filename, value);
2859         return TRUE;
2860       }
2861     }
2862     else {
2863       if ((config.acct_type == ACCT_NF || config.acct_type == ACCT_PM) && !strncmp(value, "vlen", 4)) {
2864         table->primitive[table->num].len = PM_VARIABLE_LENGTH;
2865       }
2866       else {
2867         table->primitive[table->num].len = 0; /* pedantic */
2868         Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Invalid length '%s'.\n", config.name, config.type, filename, value);
2869         return TRUE;
2870       }
2871     }
2872   }
2873   else {
2874     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] custom aggregate primitives registry not allocated.\n", config.name, config.type, filename);
2875     return TRUE;
2876   }
2877 
2878   return FALSE;
2879 }
2880 
custom_primitives_map_semantics_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)2881 int custom_primitives_map_semantics_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
2882 {
2883   struct custom_primitives *table = (struct custom_primitives *) req->key_value_table;
2884 
2885   if (table) {
2886     if (!strncmp(value, "u_int", 5)) {
2887       table->primitive[table->num].semantics = CUSTOM_PRIMITIVE_TYPE_UINT;
2888     }
2889     else if (!strncmp(value, "hex", 3)) {
2890       table->primitive[table->num].semantics = CUSTOM_PRIMITIVE_TYPE_HEX;
2891     }
2892     else if (!strncmp(value, "str", 3)) {
2893       table->primitive[table->num].semantics = CUSTOM_PRIMITIVE_TYPE_STRING;
2894     }
2895     else if (!strncmp(value, "ip", 2)) {
2896       table->primitive[table->num].semantics = CUSTOM_PRIMITIVE_TYPE_IP;
2897     }
2898     else if (!strncmp(value, "mac", 3)) {
2899       table->primitive[table->num].semantics = CUSTOM_PRIMITIVE_TYPE_MAC;
2900     }
2901     else if (!strncmp(value, "raw", 3)) {
2902       table->primitive[table->num].semantics = CUSTOM_PRIMITIVE_TYPE_RAW;
2903     }
2904   }
2905   else {
2906     Log(LOG_WARNING, "WARN ( %s/%s ): [%s] custom aggregate primitives registry not allocated.\n", config.name, config.type, filename);
2907     return TRUE;
2908   }
2909 
2910   return FALSE;
2911 }
2912 
custom_primitives_map_initialize()2913 void custom_primitives_map_initialize()
2914 {
2915   custom_primitives_type = (COUNT_INDEX_CP | 0x1);
2916 }
2917 
custom_primitives_map_validate(char * filename,struct plugin_requests * req)2918 void custom_primitives_map_validate(char *filename, struct plugin_requests *req)
2919 {
2920   struct custom_primitives *table = (struct custom_primitives *) req->key_value_table;
2921   int valid = FALSE;
2922 
2923   if (table) {
2924     if (strcmp(table->primitive[table->num].name, "") && (table->primitive[table->num].field_type ||
2925 	table->primitive[table->num].pd_ptr[0].ptr_idx.set) && table->primitive[table->num].len &&
2926 	table->primitive[table->num].semantics) {
2927       valid = TRUE;
2928       if (table->primitive[table->num].semantics == CUSTOM_PRIMITIVE_TYPE_RAW) {
2929 	table->primitive[table->num].alloc_len = (table->primitive[table->num].len * 3) + 1;
2930       }
2931       else {
2932 	table->primitive[table->num].alloc_len = table->primitive[table->num].len;
2933       }
2934     }
2935     else valid = FALSE;
2936 
2937     if (valid && table->primitive[table->num].len == PM_VARIABLE_LENGTH) {
2938       if (table->primitive[table->num].semantics != CUSTOM_PRIMITIVE_TYPE_STRING &&
2939 	  table->primitive[table->num].semantics != CUSTOM_PRIMITIVE_TYPE_RAW)
2940 	valid = FALSE;
2941 
2942       table->primitive[table->num].alloc_len = PM_VARIABLE_LENGTH;
2943     }
2944 
2945     if (valid && (table->num + 1 < MAX_CUSTOM_PRIMITIVES)) {
2946       table->primitive[table->num].type = custom_primitives_type;
2947       custom_primitives_type = (COUNT_INDEX_CP | (custom_primitives_type << 1));
2948       table->num++;
2949     }
2950     else {
2951       if (!valid) {
2952 	Log(LOG_WARNING, "WARN ( %s/%s ): [%s:%u] Invalid entry: name=%s\n",
2953 	    config.name, config.type, filename, table->num + 1, table->primitive[table->num].name);
2954       }
2955       else if (table->num + 1 < MAX_CUSTOM_PRIMITIVES) {
2956         Log(LOG_WARNING, "WARN ( %s/%s ): [%s] Maximum entries (%d) reached in aggregate_primitives\n",
2957 	    config.name, config.type, filename, MAX_CUSTOM_PRIMITIVES);
2958       }
2959 
2960       memset(&table->primitive[table->num], 0, sizeof(struct custom_primitive_entry));
2961     }
2962   }
2963 }
2964 
PT_map_index_entries_ip_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)2965 int PT_map_index_entries_ip_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
2966 {
2967   struct id_entry *src_e = (struct id_entry *) src;
2968 
2969   if (!e || !hash_serializer || !src_e) return TRUE;
2970 
2971   memcpy(&e->key.agent_ip, &src_e->key.agent_ip, sizeof(pt_hostaddr_t));
2972   hash_serial_append(hash_serializer, (char *)&src_e->key.agent_ip.a, sizeof(struct host_addr), TRUE);
2973 
2974   return FALSE;
2975 }
2976 
PT_map_index_entries_input_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)2977 int PT_map_index_entries_input_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
2978 {
2979   struct id_entry *src_e = (struct id_entry *) src;
2980 
2981   if (!e || !hash_serializer || !src_e) return TRUE;
2982 
2983   memcpy(&e->key.input, &src_e->key.input, sizeof(pt_uint32_t));
2984   hash_serial_append(hash_serializer, (char *)&src_e->key.input.n, sizeof(u_int32_t), TRUE);
2985 
2986   return FALSE;
2987 }
2988 
PT_map_index_entries_output_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)2989 int PT_map_index_entries_output_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
2990 {
2991   struct id_entry *src_e = (struct id_entry *) src;
2992 
2993   if (!e || !hash_serializer || !src_e) return TRUE;
2994 
2995   memcpy(&e->key.output, &src_e->key.output, sizeof(pt_uint32_t));
2996   hash_serial_append(hash_serializer, (char *)&src_e->key.output.n, sizeof(u_int32_t), TRUE);
2997 
2998   return FALSE;
2999 }
3000 
PT_map_index_entries_bgp_nexthop_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3001 int PT_map_index_entries_bgp_nexthop_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3002 {
3003   struct id_entry *src_e = (struct id_entry *) src;
3004 
3005   if (!e || !hash_serializer || !src_e) return TRUE;
3006 
3007   memcpy(&e->key.bgp_nexthop, &src_e->key.bgp_nexthop, sizeof(pt_hostaddr_t));
3008   hash_serial_append(hash_serializer, (char *)&src_e->key.bgp_nexthop.a, sizeof(struct host_addr), TRUE);
3009 
3010   return FALSE;
3011 }
3012 
PT_map_index_entries_src_as_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3013 int PT_map_index_entries_src_as_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3014 {
3015   struct id_entry *src_e = (struct id_entry *) src;
3016 
3017   if (!e || !hash_serializer || !src_e) return TRUE;
3018 
3019   memcpy(&e->key.src_as, &src_e->key.src_as, sizeof(pt_uint32_t));
3020   hash_serial_append(hash_serializer, (char *)&src_e->key.src_as.n, sizeof(u_int32_t), TRUE);
3021 
3022   return FALSE;
3023 }
3024 
PT_map_index_entries_dst_as_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3025 int PT_map_index_entries_dst_as_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3026 {
3027   struct id_entry *src_e = (struct id_entry *) src;
3028 
3029   if (!e || !hash_serializer || !src_e) return TRUE;
3030 
3031   memcpy(&e->key.dst_as, &src_e->key.dst_as, sizeof(pt_uint32_t));
3032   hash_serial_append(hash_serializer, (char *)&src_e->key.dst_as.n, sizeof(u_int32_t), TRUE);
3033 
3034   return FALSE;
3035 }
3036 
PT_map_index_entries_peer_src_as_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3037 int PT_map_index_entries_peer_src_as_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3038 {
3039   struct id_entry *src_e = (struct id_entry *) src;
3040 
3041   if (!e || !hash_serializer || !src_e) return TRUE;
3042 
3043   memcpy(&e->key.peer_src_as, &src_e->key.peer_src_as, sizeof(pt_uint32_t));
3044   hash_serial_append(hash_serializer, (char *)&src_e->key.peer_src_as.n, sizeof(u_int32_t), TRUE);
3045 
3046   return FALSE;
3047 }
3048 
PT_map_index_entries_peer_dst_as_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3049 int PT_map_index_entries_peer_dst_as_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3050 {
3051   struct id_entry *src_e = (struct id_entry *) src;
3052 
3053   if (!e || !hash_serializer || !src_e) return TRUE;
3054 
3055   memcpy(&e->key.peer_dst_as, &src_e->key.peer_dst_as, sizeof(pt_uint32_t));
3056   hash_serial_append(hash_serializer, (char *)&src_e->key.peer_dst_as.n, sizeof(u_int32_t), TRUE);
3057 
3058   return FALSE;
3059 }
3060 
PT_map_index_entries_mpls_vpn_rd_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3061 int PT_map_index_entries_mpls_vpn_rd_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3062 {
3063   struct id_entry *src_e = (struct id_entry *) src;
3064 
3065   if (!e || !hash_serializer || !src_e) return TRUE;
3066 
3067   memcpy(&e->key.mpls_vpn_rd, &src_e->key.mpls_vpn_rd, sizeof(pt_rd_t));
3068   hash_serial_append(hash_serializer, (char *)&src_e->key.mpls_vpn_rd.rd, sizeof(rd_t), TRUE);
3069 
3070   return FALSE;
3071 }
3072 
PT_map_index_entries_mpls_pw_id_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3073 int PT_map_index_entries_mpls_pw_id_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3074 {
3075   struct id_entry *src_e = (struct id_entry *) src;
3076 
3077   if (!e || !hash_serializer || !src_e) return TRUE;
3078 
3079   memcpy(&e->key.mpls_pw_id, &src_e->key.mpls_pw_id, sizeof(pt_uint32_t));
3080   hash_serial_append(hash_serializer, (char *)&src_e->key.mpls_pw_id.n, sizeof(u_int32_t), TRUE);
3081 
3082   return FALSE;
3083 }
3084 
PT_map_index_entries_mpls_label_bottom_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3085 int PT_map_index_entries_mpls_label_bottom_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3086 {
3087   struct id_entry *src_e = (struct id_entry *) src;
3088 
3089   if (!e || !hash_serializer || !src_e) return TRUE;
3090 
3091   memcpy(&e->key.mpls_label_bottom, &src_e->key.mpls_label_bottom, sizeof(pt_uint32_t));
3092   hash_serial_append(hash_serializer, (char *)&src_e->key.mpls_label_bottom.n, sizeof(u_int32_t), TRUE);
3093 
3094   return FALSE;
3095 }
3096 
PT_map_index_entries_mpls_vpn_id_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3097 int PT_map_index_entries_mpls_vpn_id_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3098 {
3099   struct id_entry *src_e = (struct id_entry *) src;
3100 
3101   if (!e || !hash_serializer || !src_e) return TRUE;
3102 
3103   memcpy(&e->key.mpls_vpn_id, &src_e->key.mpls_vpn_id, sizeof(pt_uint32_t));
3104   hash_serial_append(hash_serializer, (char *)&src_e->key.mpls_vpn_id.n, sizeof(u_int32_t), TRUE);
3105 
3106   return FALSE;
3107 }
3108 
PT_map_index_entries_src_mac_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3109 int PT_map_index_entries_src_mac_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3110 {
3111   struct id_entry *src_e = (struct id_entry *) src;
3112 
3113   if (!e || !hash_serializer || !src_e) return TRUE;
3114 
3115   memcpy(&e->key.src_mac, &src_e->key.src_mac, sizeof(pt_etheraddr_t));
3116   hash_serial_append(hash_serializer, (char *)&src_e->key.src_mac.a, ETH_ADDR_LEN, TRUE);
3117 
3118   return FALSE;
3119 }
3120 
PT_map_index_entries_dst_mac_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3121 int PT_map_index_entries_dst_mac_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3122 {
3123   struct id_entry *src_e = (struct id_entry *) src;
3124 
3125   if (!e || !hash_serializer || !src_e) return TRUE;
3126 
3127   memcpy(&e->key.dst_mac, &src_e->key.dst_mac, sizeof(pt_etheraddr_t));
3128   hash_serial_append(hash_serializer, (char *)&src_e->key.dst_mac.a, ETH_ADDR_LEN, TRUE);
3129 
3130   return FALSE;
3131 }
3132 
PT_map_index_entries_vlan_id_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3133 int PT_map_index_entries_vlan_id_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3134 {
3135   struct id_entry *src_e = (struct id_entry *) src;
3136 
3137   if (!e || !hash_serializer || !src_e) return TRUE;
3138 
3139   memcpy(&e->key.vlan_id, &src_e->key.vlan_id, sizeof(pt_uint16_t));
3140   hash_serial_append(hash_serializer, (char *)&src_e->key.vlan_id.n, sizeof(u_int16_t), TRUE);
3141 
3142   return FALSE;
3143 }
3144 
PT_map_index_entries_cvlan_id_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3145 int PT_map_index_entries_cvlan_id_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3146 {
3147   struct id_entry *src_e = (struct id_entry *) src;
3148 
3149   if (!e || !hash_serializer || !src_e) return TRUE;
3150 
3151   memcpy(&e->key.cvlan_id, &src_e->key.cvlan_id, sizeof(pt_uint16_t));
3152   hash_serial_append(hash_serializer, (char *)&src_e->key.cvlan_id.n, sizeof(u_int16_t), TRUE);
3153 
3154   return FALSE;
3155 }
3156 
PT_map_index_entries_fwdstatus_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3157 int PT_map_index_entries_fwdstatus_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3158 {
3159   struct id_entry *src_e = (struct id_entry *) src;
3160 
3161   if (!e || !hash_serializer || !src_e) return TRUE;
3162 
3163   memcpy(&e->key.fwdstatus, &src_e->key.fwdstatus, sizeof(u_int8_t));
3164   hash_serial_append(hash_serializer, (char *)&src_e->key.fwdstatus.n, sizeof(u_int8_t), TRUE);
3165 
3166   return FALSE;
3167 }
3168 
PT_map_index_fdata_ip_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3169 int PT_map_index_fdata_ip_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3170 {
3171   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3172   struct sockaddr *sa = (struct sockaddr *) pptrs->f_agent;
3173   SFSample *sample = (SFSample *)pptrs->f_data;
3174   u_int16_t port;
3175 
3176   if (config.acct_type == ACCT_NF) {
3177     sa_to_addr((struct sockaddr *)sa, &e->key.agent_ip.a, &port);
3178   }
3179   else if (config.acct_type == ACCT_SF) {
3180     if (sample->agent_addr.type == SFLADDRESSTYPE_IP_V4) {
3181       e->key.agent_ip.a.family = AF_INET;
3182       e->key.agent_ip.a.address.ipv4.s_addr = sample->agent_addr.address.ip_v4.s_addr;
3183     }
3184     else if (sample->agent_addr.type == SFLADDRESSTYPE_IP_V6) {
3185       e->key.agent_ip.a.family = AF_INET6;
3186       memcpy(e->key.agent_ip.a.address.ipv6.s6_addr, sample->agent_addr.address.ip_v6.s6_addr, 16);
3187     }
3188   }
3189   else return TRUE;
3190 
3191   hash_serial_append(hash_serializer, (char *)&e->key.agent_ip.a, sizeof(struct host_addr), FALSE);
3192 
3193   return FALSE;
3194 }
3195 
PT_map_index_fdata_input_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3196 int PT_map_index_fdata_input_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3197 {
3198   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3199   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3200   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3201   SFSample *sample = (SFSample *) pptrs->f_data;
3202 
3203   if (config.acct_type == ACCT_NF) {
3204     u_int16_t iface16 = 0;
3205     u_int32_t iface32 = 0;
3206 
3207     switch(hdr->version) {
3208     case 10:
3209     case 9:
3210       if (tpl->tpl[NF9_INPUT_SNMP].len == 2) {
3211         memcpy(&iface16, pptrs->f_data+tpl->tpl[NF9_INPUT_SNMP].off, 2);
3212         e->key.input.n = ntohs(iface16);
3213       }
3214       else if (tpl->tpl[NF9_INPUT_SNMP].len == 4) {
3215         memcpy(&iface32, pptrs->f_data+tpl->tpl[NF9_INPUT_SNMP].off, 4);
3216         e->key.input.n = ntohl(iface32);
3217       }
3218       else if (tpl->tpl[NF9_INPUT_PHYSINT].len == 4) {
3219         memcpy(&iface32, pptrs->f_data+tpl->tpl[NF9_INPUT_PHYSINT].off, 4);
3220         e->key.input.n = ntohl(iface32);
3221       }
3222       break;
3223     case 5:
3224       iface16 = ntohs(((struct struct_export_v5 *) pptrs->f_data)->input);
3225       e->key.input.n = iface16;
3226       break;
3227     default:
3228       break;
3229     }
3230   }
3231   else if (config.acct_type == ACCT_SF) {
3232     e->key.input.n = sample->inputPort;
3233   }
3234   else if (config.acct_type == ACCT_PM) {
3235     e->key.input.n = pptrs->ifindex_in;
3236   }
3237 
3238   hash_serial_append(hash_serializer, (char *)&e->key.input.n, sizeof(u_int32_t), FALSE);
3239 
3240   return FALSE;
3241 }
3242 
PT_map_index_fdata_output_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3243 int PT_map_index_fdata_output_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3244 {
3245   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3246   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3247   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3248   SFSample *sample = (SFSample *) pptrs->f_data;
3249 
3250   if (config.acct_type == ACCT_NF) {
3251     u_int16_t iface16 = 0;
3252     u_int32_t iface32 = 0;
3253 
3254     switch(hdr->version) {
3255     case 10:
3256     case 9:
3257       if (tpl->tpl[NF9_OUTPUT_SNMP].len == 2) {
3258         memcpy(&iface16, pptrs->f_data+tpl->tpl[NF9_OUTPUT_SNMP].off, 2);
3259         e->key.output.n = ntohs(iface16);
3260       }
3261       else if (tpl->tpl[NF9_OUTPUT_SNMP].len == 4) {
3262         memcpy(&iface32, pptrs->f_data+tpl->tpl[NF9_OUTPUT_SNMP].off, 4);
3263         e->key.output.n = ntohl(iface32);
3264       }
3265       else if (tpl->tpl[NF9_OUTPUT_PHYSINT].len == 4) {
3266         memcpy(&iface32, pptrs->f_data+tpl->tpl[NF9_OUTPUT_PHYSINT].off, 4);
3267         e->key.output.n = ntohl(iface32);
3268       }
3269       break;
3270     case 5:
3271       iface16 = ntohs(((struct struct_export_v5 *) pptrs->f_data)->output);
3272       e->key.output.n = iface16;
3273       break;
3274     default:
3275       break;
3276     }
3277   }
3278   else if (config.acct_type == ACCT_SF) {
3279     e->key.output.n = sample->outputPort;
3280   }
3281   else if (config.acct_type == ACCT_PM) {
3282     e->key.output.n = pptrs->ifindex_out;
3283   }
3284 
3285   hash_serial_append(hash_serializer, (char *)&e->key.output.n, sizeof(u_int32_t), FALSE);
3286 
3287   return FALSE;
3288 }
3289 
PT_map_index_fdata_bgp_nexthop_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3290 int PT_map_index_fdata_bgp_nexthop_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3291 {
3292   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3293   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3294   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3295   SFSample *sample = (SFSample *) pptrs->f_data;
3296 
3297   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
3298   struct bgp_info *info;
3299 
3300   if (evaluate_lm_method(pptrs, TRUE, config.nfacctd_net, NF_NET_BGP)) {
3301     if (dst_ret) {
3302       if (pptrs->bgp_nexthop_info) info = (struct bgp_info *) pptrs->bgp_nexthop_info;
3303       else info = (struct bgp_info *) pptrs->bgp_dst_info;
3304 
3305       if (info && info->attr) {
3306 	if (info->attr->mp_nexthop.family == AF_INET) {
3307 	  memcpy(&e->key.bgp_nexthop.a, &info->attr->mp_nexthop, HostAddrSz);
3308 	}
3309 	else if (info->attr->mp_nexthop.family == AF_INET6) {
3310 	  memcpy(&e->key.bgp_nexthop.a, &info->attr->mp_nexthop, HostAddrSz);
3311 	}
3312 	else {
3313 	  e->key.bgp_nexthop.a.address.ipv4.s_addr = info->attr->nexthop.s_addr;
3314 	  e->key.bgp_nexthop.a.family = AF_INET;
3315 	}
3316       }
3317     }
3318   }
3319   else if (evaluate_lm_method(pptrs, TRUE, config.nfacctd_net, NF_NET_KEEP)) {
3320     if (config.acct_type == ACCT_NF) {
3321       switch(hdr->version) {
3322       case 10:
3323       case 9:
3324 	if (pptrs->l3_proto == ETHERTYPE_IP) {
3325 	  if (tpl->tpl[NF9_BGP_IPV4_NEXT_HOP].len) {
3326 	    memcpy(&e->key.bgp_nexthop.a.address.ipv4, pptrs->f_data+tpl->tpl[NF9_BGP_IPV4_NEXT_HOP].off, MIN(tpl->tpl[NF9_BGP_IPV4_NEXT_HOP].len, 4));
3327 	    e->key.bgp_nexthop.a.family = AF_INET;
3328 	  }
3329 	  else if (tpl->tpl[NF9_MPLS_TOP_LABEL_ADDR].len) {
3330 	    memcpy(&e->key.bgp_nexthop.a.address.ipv4, pptrs->f_data+tpl->tpl[NF9_MPLS_TOP_LABEL_ADDR].off, MIN(tpl->tpl[NF9_MPLS_TOP_LABEL_ADDR].len, 4));
3331 	    e->key.bgp_nexthop.a.family = AF_INET;
3332 	  }
3333 	}
3334 	else if (pptrs->l3_proto == ETHERTYPE_IPV6) {
3335 	  if (tpl->tpl[NF9_BGP_IPV6_NEXT_HOP].len) {
3336 	    memcpy(&e->key.bgp_nexthop.a.address.ipv6, pptrs->f_data+tpl->tpl[NF9_BGP_IPV6_NEXT_HOP].off, MIN(tpl->tpl[NF9_BGP_IPV6_NEXT_HOP].len, 16));
3337 	    e->key.bgp_nexthop.a.family = AF_INET6;
3338 	  }
3339 	  else if (tpl->tpl[NF9_MPLS_TOP_LABEL_ADDR].len) {
3340 	    memcpy(&e->key.bgp_nexthop.a.address.ipv6, pptrs->f_data+tpl->tpl[NF9_MPLS_TOP_LABEL_ADDR].off, MIN(tpl->tpl[NF9_MPLS_TOP_LABEL_ADDR].len, 4));
3341 	    e->key.bgp_nexthop.a.family = AF_INET;
3342 	  }
3343 	  else if (tpl->tpl[NF9_MPLS_TOP_LABEL_IPV6_ADDR].len) {
3344 	    memcpy(&e->key.bgp_nexthop.a.address.ipv6, pptrs->f_data+tpl->tpl[NF9_MPLS_TOP_LABEL_IPV6_ADDR].off, MIN(tpl->tpl[NF9_MPLS_TOP_LABEL_IPV6_ADDR].len, 16));
3345 	    e->key.bgp_nexthop.a.family = AF_INET6;
3346 	  }
3347 	}
3348       }
3349     }
3350     else if (config.acct_type == ACCT_SF) {
3351       if (sample->gotIPV4) {
3352 	e->key.bgp_nexthop.a.family = AF_INET;
3353 	e->key.bgp_nexthop.a.address.ipv4.s_addr = sample->bgp_nextHop.address.ip_v4.s_addr;
3354       }
3355       else if (sample->gotIPV6) {
3356 	e->key.bgp_nexthop.a.family = AF_INET6;
3357 	memcpy(&e->key.bgp_nexthop.a.address.ipv6, &sample->bgp_nextHop.address.ip_v6, IP6AddrSz);
3358       }
3359     }
3360     else return TRUE;
3361   }
3362 
3363   hash_serial_append(hash_serializer, (char *)&e->key.bgp_nexthop.a, sizeof(struct host_addr), FALSE);
3364 
3365   return FALSE;
3366 }
3367 
PT_map_index_fdata_src_as_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3368 int PT_map_index_fdata_src_as_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3369 {
3370   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3371   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3372   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3373   SFSample *sample = (SFSample *) pptrs->f_data;
3374 
3375   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
3376   struct bgp_info *info;
3377 
3378   if (src_ret && evaluate_lm_method(pptrs, FALSE, config.nfacctd_as, NF_AS_BGP)) {
3379     info = (struct bgp_info *) pptrs->bgp_src_info;
3380     if (info && info->attr && info->attr->aspath) {
3381       e->key.src_as.n = evaluate_last_asn(info->attr->aspath);
3382     }
3383   }
3384   else if (evaluate_lm_method(pptrs, FALSE, config.nfacctd_as, NF_AS_KEEP)) {
3385     if (config.acct_type == ACCT_NF) {
3386       u_int16_t asn16 = 0;
3387       u_int32_t asn32 = 0;
3388 
3389       switch(hdr->version) {
3390       case 10:
3391       case 9:
3392 	if (tpl->tpl[NF9_SRC_AS].len == 2) {
3393 	  memcpy(&asn16, pptrs->f_data+tpl->tpl[NF9_SRC_AS].off, 2);
3394 	  e->key.src_as.n = ntohs(asn16);
3395 	}
3396 	else if (tpl->tpl[NF9_SRC_AS].len == 4) {
3397 	  memcpy(&asn32, pptrs->f_data+tpl->tpl[NF9_SRC_AS].off, 4);
3398 	  e->key.src_as.n = ntohl(asn32);
3399 	}
3400 	break;
3401       case 5:
3402 	e->key.src_as.n = ntohs(((struct struct_export_v5 *) pptrs->f_data)->src_as);
3403 	break;
3404       default:
3405 	break;
3406       }
3407     }
3408     else if (config.acct_type == ACCT_SF) {
3409       e->key.src_as.n = sample->src_as;
3410     }
3411     else return TRUE;
3412   }
3413 
3414   hash_serial_append(hash_serializer, (char *)&e->key.src_as.n, sizeof(u_int32_t), FALSE);
3415 
3416   return FALSE;
3417 }
3418 
PT_map_index_fdata_dst_as_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3419 int PT_map_index_fdata_dst_as_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3420 {
3421   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3422   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3423   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3424   SFSample *sample = (SFSample *) pptrs->f_data;
3425 
3426   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
3427   struct bgp_info *info;
3428 
3429   if (dst_ret && evaluate_lm_method(pptrs, FALSE, config.nfacctd_as, NF_AS_BGP)) {
3430     info = (struct bgp_info *) pptrs->bgp_dst_info;
3431     if (info && info->attr && info->attr->aspath) {
3432       e->key.dst_as.n = evaluate_last_asn(info->attr->aspath);
3433     }
3434   }
3435   else if (evaluate_lm_method(pptrs, TRUE, config.nfacctd_as, NF_AS_KEEP)) {
3436     if (config.acct_type == ACCT_NF) {
3437       u_int16_t asn16 = 0;
3438       u_int32_t asn32 = 0;
3439 
3440       switch(hdr->version) {
3441       case 10:
3442       case 9:
3443         if (tpl->tpl[NF9_DST_AS].len == 2) {
3444           memcpy(&asn16, pptrs->f_data+tpl->tpl[NF9_DST_AS].off, 2);
3445           e->key.dst_as.n = ntohs(asn16);
3446         }
3447         else if (tpl->tpl[NF9_DST_AS].len == 4) {
3448           memcpy(&asn32, pptrs->f_data+tpl->tpl[NF9_DST_AS].off, 4);
3449           e->key.dst_as.n = ntohl(asn32);
3450         }
3451         break;
3452       case 5:
3453         e->key.dst_as.n = ntohs(((struct struct_export_v5 *) pptrs->f_data)->dst_as);
3454         break;
3455       default:
3456 	break;
3457       }
3458     }
3459     else if (config.acct_type == ACCT_SF) {
3460       e->key.dst_as.n = sample->dst_as;
3461     }
3462   }
3463   else return TRUE;
3464 
3465   hash_serial_append(hash_serializer, (char *)&e->key.dst_as.n, sizeof(u_int32_t), FALSE);
3466 
3467   return FALSE;
3468 }
3469 
PT_map_index_fdata_peer_src_as_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3470 int PT_map_index_fdata_peer_src_as_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3471 {
3472   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3473   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3474   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3475   SFSample *sample = (SFSample *) pptrs->f_data;
3476 
3477   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
3478   struct bgp_info *info;
3479 
3480   if (config.bgp_daemon_peer_as_src_type & BGP_SRC_PRIMITIVES_MAP) {
3481     e->key.peer_src_as.n = pptrs->bpas;
3482   }
3483   else {
3484     if (src_ret && evaluate_lm_method(pptrs, FALSE, config.nfacctd_as, NF_AS_BGP)) {
3485       info = (struct bgp_info *) pptrs->bgp_src_info;
3486       if (info && info->attr && info->attr->aspath) {
3487         e->key.peer_src_as.n = evaluate_first_asn(info->attr->aspath->str);
3488       }
3489     }
3490     else if (evaluate_lm_method(pptrs, FALSE, config.nfacctd_as, NF_AS_KEEP)) {
3491       if (config.acct_type == ACCT_NF) {
3492         u_int16_t asn16 = 0;
3493         u_int32_t asn32 = 0;
3494 
3495         switch(hdr->version) {
3496         case 10:
3497         case 9:
3498           if (tpl->tpl[NF9_PEER_SRC_AS].len == 2) {
3499             memcpy(&asn16, pptrs->f_data+tpl->tpl[NF9_PEER_SRC_AS].off, 2);
3500             e->key.peer_src_as.n = ntohs(asn16);
3501           }
3502           else if (tpl->tpl[NF9_PEER_SRC_AS].len == 4) {
3503             memcpy(&asn32, pptrs->f_data+tpl->tpl[NF9_PEER_SRC_AS].off, 4);
3504             e->key.peer_src_as.n = ntohl(asn32);
3505           }
3506           break;
3507         default:
3508           break;
3509         }
3510       }
3511       else if (config.acct_type == ACCT_SF) {
3512         e->key.peer_src_as.n = sample->src_peer_as;
3513       }
3514       else return TRUE;
3515     }
3516   }
3517 
3518   hash_serial_append(hash_serializer, (char *)&e->key.peer_src_as.n, sizeof(u_int32_t), FALSE);
3519 
3520   return FALSE;
3521 }
3522 
PT_map_index_fdata_peer_dst_as_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3523 int PT_map_index_fdata_peer_dst_as_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3524 {
3525   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3526   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3527   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3528   SFSample *sample = (SFSample *) pptrs->f_data;
3529 
3530   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
3531   struct bgp_info *info;
3532 
3533   if (dst_ret && evaluate_lm_method(pptrs, FALSE, config.nfacctd_as, NF_AS_BGP)) {
3534     info = (struct bgp_info *) pptrs->bgp_dst_info;
3535     if (info && info->attr && info->attr->aspath) {
3536       e->key.peer_dst_as.n = evaluate_first_asn(info->attr->aspath->str);
3537     }
3538   }
3539   else if (evaluate_lm_method(pptrs, FALSE, config.nfacctd_as, NF_AS_KEEP)) {
3540     if (config.acct_type == ACCT_NF) {
3541       u_int16_t asn16 = 0;
3542       u_int32_t asn32 = 0;
3543 
3544       switch(hdr->version) {
3545       case 10:
3546       case 9:
3547         if (tpl->tpl[NF9_PEER_DST_AS].len == 2) {
3548           memcpy(&asn16, pptrs->f_data+tpl->tpl[NF9_PEER_DST_AS].off, 2);
3549           e->key.peer_dst_as.n = ntohs(asn16);
3550         }
3551         else if (tpl->tpl[NF9_PEER_DST_AS].len == 4) {
3552           memcpy(&asn32, pptrs->f_data+tpl->tpl[NF9_PEER_DST_AS].off, 4);
3553           e->key.peer_dst_as.n = ntohl(asn32);
3554         }
3555         break;
3556       default:
3557         break;
3558       }
3559     }
3560     else if (config.acct_type == ACCT_SF) {
3561       e->key.peer_dst_as.n = sample->dst_peer_as;
3562     }
3563     else return TRUE;
3564   }
3565 
3566   hash_serial_append(hash_serializer, (char *)&e->key.peer_dst_as.n, sizeof(u_int32_t), FALSE);
3567 
3568   return FALSE;
3569 }
3570 
PT_map_index_fdata_mpls_vpn_rd_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3571 int PT_map_index_fdata_mpls_vpn_rd_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3572 {
3573   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3574   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
3575   struct bgp_info *info;
3576 
3577   /* if bitr is populate we infer non-zero config.nfacctd_flow_to_rd_map */
3578   if (pptrs->bitr) memcpy(&e->key.mpls_vpn_rd.rd, &pptrs->bitr, sizeof(rd_t));
3579   else {
3580     /* XXX: no src_ret lookup? */
3581 
3582     if (dst_ret) {
3583       info = (struct bgp_info *) pptrs->bgp_dst_info;
3584       if (info && info->extra) memcpy(&e->key.mpls_vpn_rd.rd, &info->extra->rd, sizeof(rd_t));
3585     }
3586   }
3587 
3588   hash_serial_append(hash_serializer, (char *)&e->key.mpls_vpn_rd.rd, sizeof(rd_t), FALSE);
3589 
3590   return FALSE;
3591 }
3592 
PT_map_index_fdata_mpls_pw_id_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3593 int PT_map_index_fdata_mpls_pw_id_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3594 {
3595   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3596   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3597   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3598   SFSample *sample = (SFSample *) pptrs->f_data;
3599   u_int32_t tmp32 = 0;
3600 
3601   if (config.acct_type == ACCT_NF) {
3602     switch (hdr->version) {
3603     case 10:
3604     case 9:
3605       if (tpl->tpl[NF9_PSEUDOWIREID].len) {
3606 	memcpy(&tmp32, pptrs->f_data+tpl->tpl[NF9_PSEUDOWIREID].off, 4);
3607 	e->key.mpls_pw_id.n = ntohl(tmp32);
3608       }
3609     }
3610   }
3611   else if (config.acct_type == ACCT_SF) {
3612     e->key.mpls_pw_id.n = sample->mpls_vll_vc_id;
3613   }
3614   else return TRUE;
3615 
3616   hash_serial_append(hash_serializer, (char *)&e->key.mpls_pw_id.n, sizeof(u_int32_t), FALSE);
3617   return FALSE;
3618 }
3619 
PT_map_index_fdata_mpls_vpn_id_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3620 int PT_map_index_fdata_mpls_vpn_id_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3621 {
3622   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3623   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3624   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3625   u_int32_t tmp32 = 0;
3626 
3627   if (config.acct_type == ACCT_NF) {
3628     switch(hdr->version) {
3629     case 10:
3630     case 9:
3631       if (tpl->tpl[NF9_INGRESS_VRFID].len) {
3632         memcpy(&tmp32, pptrs->f_data+tpl->tpl[NF9_INGRESS_VRFID].off, MIN(tpl->tpl[NF9_INGRESS_VRFID].len, 4));
3633 	e->key.mpls_vpn_id.n = ntohl(tmp32);
3634       }
3635 
3636       if (tpl->tpl[NF9_EGRESS_VRFID].len && !e->key.mpls_vpn_id.n) {
3637         memcpy(&tmp32, pptrs->f_data+tpl->tpl[NF9_EGRESS_VRFID].off, MIN(tpl->tpl[NF9_EGRESS_VRFID].len, 4));
3638 	e->key.mpls_vpn_id.n = ntohl(tmp32);
3639       }
3640     }
3641   }
3642 
3643   hash_serial_append(hash_serializer, (char *)&e->key.mpls_vpn_id.n, sizeof(u_int32_t), FALSE);
3644 
3645   return FALSE;
3646 }
3647 
PT_map_index_fdata_mpls_label_bottom_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3648 int PT_map_index_fdata_mpls_label_bottom_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3649 {
3650   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3651   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3652   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3653 
3654   if (config.acct_type == ACCT_NF) {
3655     int label_idx;
3656 
3657     switch(hdr->version) {
3658     case 10:
3659     case 9:
3660       for (label_idx = NF9_MPLS_LABEL_1; label_idx <= NF9_MPLS_LABEL_9; label_idx++) {
3661         if (tpl->tpl[label_idx].len == 3 && check_bosbit(pptrs->f_data+tpl->tpl[label_idx].off)) {
3662           e->key.mpls_label_bottom.n = decode_mpls_label(pptrs->f_data+tpl->tpl[label_idx].off);
3663           break;
3664         }
3665       }
3666       break;
3667     }
3668   }
3669 
3670   hash_serial_append(hash_serializer, (char *)&e->key.mpls_label_bottom.n, sizeof(u_int32_t), FALSE);
3671 
3672   return FALSE;
3673 }
3674 
PT_map_index_fdata_src_mac_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3675 int PT_map_index_fdata_src_mac_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3676 {
3677   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3678   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3679   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3680   SFSample *sample = (SFSample *) pptrs->f_data;
3681 
3682   if (config.acct_type == ACCT_NF) {
3683     switch (hdr->version) {
3684     case 10:
3685     case 9:
3686       if (tpl->tpl[NF9_IN_SRC_MAC].len) {
3687         memcpy(&e->key.src_mac.a, pptrs->f_data+tpl->tpl[NF9_IN_SRC_MAC].off, MIN(tpl->tpl[NF9_IN_SRC_MAC].len, 6));
3688       }
3689     }
3690   }
3691   else if (config.acct_type == ACCT_SF) {
3692     memcpy(&e->key.src_mac.a, sample->eth_src, ETH_ADDR_LEN);
3693   }
3694   else return TRUE;
3695 
3696   hash_serial_append(hash_serializer, (char *)&e->key.src_mac.a, ETH_ADDR_LEN, FALSE);
3697 
3698   return FALSE;
3699 }
3700 
PT_map_index_fdata_dst_mac_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3701 int PT_map_index_fdata_dst_mac_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3702 {
3703   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3704   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3705   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3706   SFSample *sample = (SFSample *) pptrs->f_data;
3707 
3708   if (config.acct_type == ACCT_NF) {
3709     switch (hdr->version) {
3710     case 10:
3711     case 9:
3712       if (tpl->tpl[NF9_IN_DST_MAC].len) {
3713         memcpy(&e->key.dst_mac.a, pptrs->f_data+tpl->tpl[NF9_IN_DST_MAC].off, MIN(tpl->tpl[NF9_IN_DST_MAC].len, 6));
3714       }
3715     }
3716   }
3717   else if (config.acct_type == ACCT_SF) {
3718     memcpy(&e->key.dst_mac.a, sample->eth_dst, ETH_ADDR_LEN);
3719   }
3720   else return TRUE;
3721 
3722   hash_serial_append(hash_serializer, (char *)&e->key.dst_mac.a, ETH_ADDR_LEN, FALSE);
3723 
3724   return FALSE;
3725 }
3726 
PT_map_index_fdata_vlan_id_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3727 int PT_map_index_fdata_vlan_id_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3728 {
3729   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3730   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3731   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3732   SFSample *sample = (SFSample *) pptrs->f_data;
3733   u_int16_t tmp16 = 0;
3734 
3735   if (config.acct_type == ACCT_NF) {
3736     switch (hdr->version) {
3737     case 10:
3738     case 9:
3739       if (tpl->tpl[NF9_IN_VLAN].len) {
3740         memcpy(&tmp16, pptrs->f_data+tpl->tpl[NF9_IN_VLAN].off, MIN(tpl->tpl[NF9_IN_VLAN].len, 2));
3741       }
3742       else if (tpl->tpl[NF9_DOT1QVLANID].len) {
3743         memcpy(&tmp16, pptrs->f_data+tpl->tpl[NF9_DOT1QVLANID].off, MIN(tpl->tpl[NF9_DOT1QVLANID].len, 2));
3744       }
3745       e->key.vlan_id.n = ntohs(tmp16);
3746     }
3747   }
3748   else if (config.acct_type == ACCT_SF) {
3749     if (sample->in_vlan) e->key.vlan_id.n = sample->in_vlan;
3750     else if (sample->out_vlan) e->key.vlan_id.n = sample->out_vlan;
3751   }
3752   else return TRUE;
3753 
3754   hash_serial_append(hash_serializer, (char *)&e->key.vlan_id.n, sizeof(u_int16_t), FALSE);
3755 
3756   return FALSE;
3757 }
3758 
PT_map_index_fdata_cvlan_id_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3759 int PT_map_index_fdata_cvlan_id_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3760 {
3761   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3762   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3763   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3764   u_int16_t tmp16 = 0;
3765 
3766   if (config.acct_type == ACCT_NF) {
3767     switch (hdr->version) {
3768     case 10:
3769     case 9:
3770       if (tpl->tpl[NF9_DOT1QCVLANID].len) {
3771         memcpy(&tmp16, pptrs->f_data+tpl->tpl[NF9_DOT1QCVLANID].off, MIN(tpl->tpl[NF9_DOT1QCVLANID].len, 2));
3772 	e->key.cvlan_id.n = ntohs(tmp16);
3773       }
3774     }
3775   }
3776   else return TRUE;
3777 
3778   hash_serial_append(hash_serializer, (char *)&e->key.cvlan_id.n, sizeof(u_int16_t), FALSE);
3779 
3780   return FALSE;
3781 }
3782 
PT_map_index_fdata_fwdstatus_handler(struct id_entry * e,pm_hash_serial_t * hash_serializer,void * src)3783 int PT_map_index_fdata_fwdstatus_handler(struct id_entry *e, pm_hash_serial_t *hash_serializer, void *src)
3784 {
3785   struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
3786   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3787   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3788   u_int32_t fwdstatus = 0;
3789 
3790   if (config.acct_type == ACCT_NF) {
3791     switch (hdr->version) {
3792     case 10:
3793     case 9:
3794       if (tpl->tpl[NF9_FORWARDING_STATUS].len == 1) {
3795         memcpy(&fwdstatus, pptrs->f_data+tpl->tpl[NF9_FORWARDING_STATUS].off, MIN(tpl->tpl[NF9_FORWARDING_STATUS].len, 1));
3796         e->key.fwdstatus.n = fwdstatus;
3797       }
3798     }
3799   }
3800   else return TRUE;
3801 
3802   hash_serial_append(hash_serializer, (char *)&e->key.fwdstatus.n, sizeof(u_int8_t), FALSE);
3803 
3804   return FALSE;
3805 }
3806 
pm_pcap_interfaces_map_validate(char * filename,struct plugin_requests * req)3807 void pm_pcap_interfaces_map_validate(char *filename, struct plugin_requests *req)
3808 {
3809   struct pm_pcap_interfaces *table = (struct pm_pcap_interfaces *) req->key_value_table;
3810   int valid = FALSE;
3811 
3812   if (table && table->list) {
3813     if (table->list[table->num].ifindex && strlen(table->list[table->num].ifname))
3814       valid = TRUE;
3815 
3816     if (valid) table->num++;
3817     else memset(&table->list[table->num], 0, sizeof(struct pm_pcap_interface));
3818   }
3819 }
3820 
pm_pcap_interfaces_map_ifindex_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)3821 int pm_pcap_interfaces_map_ifindex_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
3822 {
3823   struct pm_pcap_interfaces *table = (struct pm_pcap_interfaces *) req->key_value_table;
3824   char *endp;
3825 
3826   if (table && table->list) {
3827     if (table->num < PCAP_MAX_INTERFACES) {
3828       table->list[table->num].ifindex = strtoul(value, &endp, 10);
3829       if (!table->list[table->num].ifindex) {
3830 	Log(LOG_ERR, "ERROR ( %s/%s ): [%s] invalid 'ifindex' value: '%s'.\n", config.name, config.type, filename, value);
3831         return TRUE;
3832       }
3833     }
3834     else {
3835       Log(LOG_ERR, "ERROR ( %s/%s ): [%s] maximum entries (%u) reached.\n", config.name, config.type, filename, PCAP_MAX_INTERFACES);
3836       return TRUE;
3837     }
3838   }
3839   else {
3840     Log(LOG_ERR, "ERROR ( %s/%s ): [%s] pcap_interfaces_map not allocated.\n", config.name, config.type, filename);
3841     return TRUE;
3842   }
3843 
3844   return FALSE;
3845 }
3846 
pm_pcap_interfaces_map_ifname_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)3847 int pm_pcap_interfaces_map_ifname_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
3848 {
3849   struct pm_pcap_interfaces *table = (struct pm_pcap_interfaces *) req->key_value_table;
3850 
3851   if (table && table->list) {
3852     if (table->num < PCAP_MAX_INTERFACES) {
3853       strncpy(table->list[table->num].ifname, value, IFNAMSIZ);
3854       if (!strlen(table->list[table->num].ifname)) {
3855 	Log(LOG_ERR, "ERROR ( %s/%s ): [%s] invalid 'ifname' value: '%s'.\n", config.name, config.type, filename, value);
3856         return TRUE;
3857       }
3858     }
3859     else {
3860       Log(LOG_ERR, "ERROR ( %s/%s ): [%s] maximum entries (%u) reached.\n", config.name, config.type, filename, PCAP_MAX_INTERFACES);
3861       return TRUE;
3862     }
3863   }
3864   else {
3865     Log(LOG_ERR, "ERROR ( %s/%s ): [%s] pcap_interfaces_map not allocated.\n", config.name, config.type, filename);
3866     return TRUE;
3867   }
3868 
3869   return FALSE;
3870 }
3871 
pm_pcap_interfaces_map_direction_handler(char * filename,struct id_entry * e,char * value,struct plugin_requests * req,int acct_type)3872 int pm_pcap_interfaces_map_direction_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
3873 {
3874   struct pm_pcap_interfaces *table = (struct pm_pcap_interfaces *) req->key_value_table;
3875 
3876   if (table && table->list) {
3877     if (table->num < PCAP_MAX_INTERFACES) {
3878       lower_string(value);
3879       if (!strncmp(value, "in", strlen("in"))) table->list[table->num].direction = PCAP_D_IN;
3880       else if (!strncmp(value, "out", strlen("out"))) table->list[table->num].direction = PCAP_D_OUT;
3881       else {
3882         Log(LOG_ERR, "ERROR ( %s/%s ): [%s] invalid 'direction' value: '%s'.\n", config.name, config.type, filename, value);
3883         return TRUE;
3884       }
3885     }
3886     else {
3887       Log(LOG_ERR, "ERROR ( %s/%s ): [%s] maximum entries (%u) reached.\n", config.name, config.type, filename, PCAP_MAX_INTERFACES);
3888       return TRUE;
3889     }
3890   }
3891   else {
3892     Log(LOG_ERR, "ERROR ( %s/%s ): [%s] pcap_interfaces_map not allocated.\n", config.name, config.type, filename);
3893     return TRUE;
3894   }
3895 
3896   return FALSE;
3897 }
3898 
pm_pcap_interfaces_map_initialize(struct pm_pcap_interfaces * map)3899 void pm_pcap_interfaces_map_initialize(struct pm_pcap_interfaces *map)
3900 {
3901   memset(map, 0, sizeof(struct pm_pcap_interfaces));
3902 
3903   /* Setting up the list */
3904   map->list = malloc((PCAP_MAX_INTERFACES) * sizeof(struct pm_pcap_interface));
3905   if (!map->list) {
3906     Log(LOG_ERR, "ERROR ( %s/%s ): unable to allocate pcap_interfaces_map. Exiting ...\n", config.name, config.type);
3907     exit_gracefully(1);
3908   }
3909   else memset(map->list, 0, (PCAP_MAX_INTERFACES) * sizeof(struct pm_pcap_interface));
3910 }
3911 
pm_pcap_interfaces_map_load(struct pm_pcap_interfaces * map)3912 void pm_pcap_interfaces_map_load(struct pm_pcap_interfaces *map)
3913 {
3914   struct plugin_requests req;
3915   int pm_pcap_interfaces_allocated = FALSE;
3916 
3917   memset(&req, 0, sizeof(req));
3918 
3919   req.key_value_table = (void *) map;
3920   load_id_file(MAP_PCAP_INTERFACES, config.pcap_interfaces_map, NULL, &req, &pm_pcap_interfaces_allocated);
3921 }
3922 
pm_pcap_interfaces_map_destroy(struct pm_pcap_interfaces * map)3923 void pm_pcap_interfaces_map_destroy(struct pm_pcap_interfaces *map)
3924 {
3925   int idx;
3926 
3927   for (idx = 0; idx < map->num; idx++) memset(&map->list[idx], 0, sizeof(struct pm_pcap_interface));
3928 
3929   map->num = 0;
3930 }
3931 
pm_pcap_interfaces_map_copy(struct pm_pcap_interfaces * dst,struct pm_pcap_interfaces * src)3932 void pm_pcap_interfaces_map_copy(struct pm_pcap_interfaces *dst, struct pm_pcap_interfaces *src)
3933 {
3934   int idx;
3935 
3936   for (idx = 0; idx < src->num; idx++) memcpy(&dst->list[idx], &src->list[idx], sizeof(struct pm_pcap_interface));
3937 
3938   dst->num = src->num;
3939 }
3940 
pm_pcap_interfaces_map_lookup_ifname(struct pm_pcap_interfaces * map,char * ifname)3941 u_int32_t pm_pcap_interfaces_map_lookup_ifname(struct pm_pcap_interfaces *map, char *ifname)
3942 {
3943   u_int32_t ifindex = 0;
3944   int idx;
3945 
3946   for (idx = 0; idx < map->num; idx++) {
3947     if (strlen(map->list[idx].ifname) == strlen(ifname) && !strncmp(map->list[idx].ifname, ifname, strlen(ifname))) {
3948       ifindex = map->list[idx].ifindex;
3949       break;
3950     }
3951   }
3952 
3953   return ifindex;
3954 }
3955 
pm_pcap_interfaces_map_getentry_by_ifname(struct pm_pcap_interfaces * map,char * ifname)3956 struct pm_pcap_interface *pm_pcap_interfaces_map_getentry_by_ifname(struct pm_pcap_interfaces *map, char *ifname)
3957 {
3958   int idx;
3959 
3960   for (idx = 0; idx < map->num; idx++) {
3961     if (strlen(map->list[idx].ifname) == strlen(ifname) && !strncmp(map->list[idx].ifname, ifname, strlen(ifname))) {
3962       return &map->list[idx];
3963     }
3964   }
3965 
3966   return NULL;
3967 }
3968 
pm_pcap_interfaces_map_getnext_ifname(struct pm_pcap_interfaces * map,int * index)3969 char *pm_pcap_interfaces_map_getnext_ifname(struct pm_pcap_interfaces *map, int *index)
3970 {
3971   char *ifname = NULL;
3972   int loc_idx = (*index);
3973 
3974   if (loc_idx < map->num) {
3975     ifname = map->list[loc_idx].ifname;
3976     loc_idx++; (*index) = loc_idx;
3977   }
3978 
3979   return ifname;
3980 }
3981