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