1 /*
2     pmacct (Promiscuous mode IP Accounting package)
3     pmacct is Copyright (C) 2003-2019 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 no, write to the Free Software
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 
22 /* includes */
23 #include "pmacct.h"
24 #include "pmacct-data.h"
25 #include "bgp/bgp_packet.h"
26 #include "bgp/bgp.h"
27 #include "nfacctd.h"
28 #include "sflow.h"
29 #include "sfacctd.h"
30 #include "plugin_hooks.h"
31 #include "pkt_handlers.h"
32 #include "addr.h"
33 #include "bgp/bgp.h"
34 #include "isis/prefix.h"
35 #include "isis/table.h"
36 #if defined (WITH_NDPI)
37 #include "ndpi/ndpi.h"
38 #endif
39 
40 //Global variables
41 struct channels_list_entry channels_list[MAX_N_PLUGINS];
42 pkt_handler phandler[N_PRIMITIVES];
43 
44 
45 
46 /* functions */
evaluate_packet_handlers()47 void evaluate_packet_handlers()
48 {
49   int primitives = 0, index = 0;
50 
51   while (channels_list[index].aggregation) {
52     primitives = 0;
53     memset(&channels_list[index].phandler, 0, N_PRIMITIVES*sizeof(pkt_handler));
54 
55 #if defined (HAVE_L2)
56     if (channels_list[index].aggregation & (COUNT_SRC_MAC|COUNT_SUM_MAC)) {
57       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = src_mac_handler;
58       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_src_mac_handler;
59       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_src_mac_handler;
60       primitives++;
61     }
62 
63     if (channels_list[index].aggregation & (COUNT_DST_MAC|COUNT_SUM_MAC)) {
64       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = dst_mac_handler;
65       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_dst_mac_handler;
66       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_dst_mac_handler;
67       primitives++;
68     }
69 
70     if (channels_list[index].aggregation & COUNT_VLAN) {
71       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = vlan_handler;
72       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_vlan_handler;
73       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_vlan_handler;
74       primitives++;
75     }
76 
77     if (channels_list[index].aggregation & COUNT_COS) {
78       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = cos_handler;
79       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_cos_handler;
80       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_cos_handler;
81       primitives++;
82     }
83 
84     if (channels_list[index].aggregation & COUNT_ETHERTYPE) {
85       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = etype_handler;
86       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_etype_handler;
87       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_etype_handler;
88       primitives++;
89     }
90 #endif
91 
92     if (channels_list[index].aggregation & (COUNT_SRC_HOST|COUNT_SRC_NET|COUNT_SUM_HOST|COUNT_SUM_NET)) {
93       /* always copy the host */
94       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = src_host_handler;
95       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_src_host_handler;
96       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_src_host_handler;
97       primitives++;
98 
99       /* optionally copy mask */
100       if (channels_list[index].aggregation & (COUNT_SRC_NET|COUNT_SUM_NET)) {
101 	if (!(channels_list[index].aggregation & COUNT_SRC_NMASK)) {
102           if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_BGP) {
103 	    channels_list[index].phandler[primitives] = bgp_src_nmask_handler;
104 	    primitives++;
105           }
106 
107           if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_IGP) {
108             channels_list[index].phandler[primitives] = igp_src_nmask_handler;
109             primitives++;
110           }
111 
112           if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_KEEP) {
113             if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_src_nmask_handler;
114             else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_src_nmask_handler;
115 	    else primitives--; /* Just in case */
116 	    primitives++;
117           }
118         }
119       }
120     }
121 
122     if (channels_list[index].aggregation & (COUNT_DST_HOST|COUNT_DST_NET|COUNT_SUM_HOST|COUNT_SUM_NET)) {
123       /* always copy the host */
124       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = dst_host_handler;
125       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_dst_host_handler;
126       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_dst_host_handler;
127       primitives++;
128 
129       /* optionally copy mask */
130       if (channels_list[index].aggregation & (COUNT_DST_NET|COUNT_SUM_NET)) {
131         if (!(channels_list[index].aggregation & COUNT_DST_NMASK)) {
132           if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_BGP) {
133             channels_list[index].phandler[primitives] = bgp_dst_nmask_handler;
134 	    primitives++;
135 	  }
136 
137           if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_IGP) {
138             channels_list[index].phandler[primitives] = igp_dst_nmask_handler;
139             primitives++;
140           }
141 
142           if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_KEEP) {
143             if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_dst_nmask_handler;
144             else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_dst_nmask_handler;
145             else primitives--; /* Just in case */
146             primitives++;
147 	  }
148 	}
149       }
150     }
151 
152     if (channels_list[index].aggregation & COUNT_SRC_NMASK) {
153       if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_BGP) {
154         channels_list[index].phandler[primitives] = bgp_src_nmask_handler;
155 	primitives++;
156       }
157 
158       if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_IGP) {
159         channels_list[index].phandler[primitives] = igp_src_nmask_handler;
160         primitives++;
161       }
162 
163       if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_KEEP) {
164         if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_src_nmask_handler;
165         else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_src_nmask_handler;
166         else primitives--; /* Just in case */
167 	primitives++;
168       }
169 
170       if (channels_list[index].plugin->cfg.nfacctd_net & (NF_NET_COMPAT|NF_NET_NEW)) {
171 	if (!(channels_list[index].aggregation & (COUNT_SRC_HOST|COUNT_SRC_NET|COUNT_SUM_HOST|COUNT_SUM_NET))) {
172           if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = src_host_handler;
173           else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_src_host_handler;
174           else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_src_host_handler;
175           primitives++;
176 	}
177       }
178     }
179 
180     if (channels_list[index].aggregation & COUNT_DST_NMASK) {
181       if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_BGP) {
182         channels_list[index].phandler[primitives] = bgp_dst_nmask_handler;
183 	primitives++;
184       }
185 
186       if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_IGP) {
187         channels_list[index].phandler[primitives] = igp_dst_nmask_handler;
188         primitives++;
189       }
190 
191       if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_KEEP) {
192         if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_dst_nmask_handler;
193         else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_dst_nmask_handler;
194         else primitives--; /* Just in case */
195         primitives++;
196       }
197 
198       if (channels_list[index].plugin->cfg.nfacctd_net & (NF_NET_COMPAT|NF_NET_NEW)) {
199 	if (!(channels_list[index].aggregation & (COUNT_DST_HOST|COUNT_DST_NET|COUNT_SUM_HOST|COUNT_SUM_NET))) {
200           if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = dst_host_handler;
201           else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_dst_host_handler;
202           else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_dst_host_handler;
203           primitives++;
204 	}
205       }
206     }
207 
208     if (channels_list[index].aggregation & (COUNT_SRC_AS|COUNT_SUM_AS)) {
209       if (channels_list[index].plugin->cfg.nfacctd_as & NF_AS_KEEP) {
210         if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = src_host_handler;
211         else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_src_as_handler;
212         else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_src_as_handler;
213         primitives++;
214       }
215 
216       if (channels_list[index].plugin->cfg.nfacctd_as & NF_AS_NEW) {
217         if (!(channels_list[index].aggregation & (COUNT_SRC_HOST|COUNT_SRC_NET|COUNT_SUM_HOST|COUNT_SUM_NET))) {
218           if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = src_host_handler;
219           else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_src_host_handler;
220           else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_src_host_handler;
221           primitives++;
222         }
223 
224         if (!(channels_list[index].aggregation & COUNT_SRC_NMASK)) {
225           if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_BGP) {
226             channels_list[index].phandler[primitives] = bgp_src_nmask_handler;
227             primitives++;
228           }
229 
230           if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_IGP) {
231             channels_list[index].phandler[primitives] = igp_src_nmask_handler;
232             primitives++;
233           }
234 
235           if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_KEEP) {
236             if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_src_nmask_handler;
237             else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_src_nmask_handler;
238             else primitives--; /* Just in case */
239             primitives++;
240           }
241         }
242       }
243     }
244 
245     if (channels_list[index].aggregation & (COUNT_DST_AS|COUNT_SUM_AS)) {
246       if (channels_list[index].plugin->cfg.nfacctd_as & NF_AS_KEEP) {
247         if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = dst_host_handler;
248         else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_dst_as_handler;
249         else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_dst_as_handler;
250         primitives++;
251       }
252 
253       if (channels_list[index].plugin->cfg.nfacctd_as & NF_AS_NEW) {
254         if (!(channels_list[index].aggregation & (COUNT_DST_HOST|COUNT_DST_NET|COUNT_SUM_HOST|COUNT_SUM_NET))) {
255           if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = dst_host_handler;
256           else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_dst_host_handler;
257           else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_dst_host_handler;
258           primitives++;
259         }
260 
261         if (!(channels_list[index].aggregation & COUNT_DST_NMASK)) {
262           if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_BGP) {
263             channels_list[index].phandler[primitives] = bgp_dst_nmask_handler;
264             primitives++;
265           }
266 
267           if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_IGP) {
268             channels_list[index].phandler[primitives] = igp_dst_nmask_handler;
269             primitives++;
270           }
271 
272           if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_KEEP) {
273             if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_dst_nmask_handler;
274             else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_dst_nmask_handler;
275             else primitives--; /* Just in case */
276             primitives++;
277           }
278         }
279       }
280     }
281 
282     if (channels_list[index].aggregation & COUNT_PEER_SRC_IP) {
283       if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_peer_src_ip_handler;
284       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_peer_src_ip_handler;
285       else primitives--; /* Just in case */
286       primitives++;
287     }
288 
289     if (channels_list[index].aggregation & COUNT_PEER_DST_IP) {
290       if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_BGP) {
291         channels_list[index].phandler[primitives] = bgp_peer_dst_ip_handler;
292         primitives++;
293       }
294 
295       if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_IGP) {
296         channels_list[index].phandler[primitives] = igp_peer_dst_ip_handler;
297         primitives++;
298       }
299 
300       if (channels_list[index].plugin->cfg.nfacctd_net & NF_NET_KEEP) {
301         if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_peer_dst_ip_handler;
302         else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_peer_dst_ip_handler;
303         else primitives--; /* Just in case */
304         primitives++;
305       }
306     }
307 
308     if (channels_list[index].aggregation & COUNT_AS_PATH) {
309       if (config.acct_type == ACCT_SF) {
310         if (config.nfacctd_as & NF_AS_KEEP) {
311           channels_list[index].phandler[primitives] = SF_as_path_handler;
312           primitives++;
313         }
314       }
315     }
316 
317     if (channels_list[index].aggregation & COUNT_PEER_SRC_AS) {
318       if (config.acct_type == ACCT_NF) {
319         if (channels_list[index].plugin->cfg.nfacctd_as & NF_AS_KEEP && config.bgp_daemon_peer_as_src_type & BGP_SRC_PRIMITIVES_KEEP) {
320 	  if (channels_list[index].plugin->cfg.nfprobe_peer_as) {
321             channels_list[index].phandler[primitives] = NF_src_as_handler;
322             primitives++;
323 	  }
324 	  else {
325             channels_list[index].phandler[primitives] = NF_peer_src_as_handler;
326             primitives++;
327 	  }
328         }
329       }
330       else if (config.acct_type == ACCT_SF) {
331         if (channels_list[index].plugin->cfg.nfacctd_as & NF_AS_KEEP && config.bgp_daemon_peer_as_src_type & BGP_SRC_PRIMITIVES_KEEP) {
332 	  if (channels_list[index].plugin->cfg.nfprobe_peer_as) {
333             channels_list[index].phandler[primitives] = SF_src_as_handler;
334             primitives++;
335 	  }
336 	  else {
337             channels_list[index].phandler[primitives] = SF_peer_src_as_handler;
338             primitives++;
339 	  }
340         }
341       }
342     }
343 
344     if (channels_list[index].aggregation & COUNT_PEER_DST_AS) {
345       if (config.acct_type == ACCT_NF) {
346         if (channels_list[index].plugin->cfg.nfacctd_as & NF_AS_KEEP) {
347           if (channels_list[index].plugin->cfg.nfprobe_peer_as) {
348             channels_list[index].phandler[primitives] = NF_dst_as_handler;
349             primitives++;
350 	  }
351 	  else {
352 	    channels_list[index].phandler[primitives] = NF_peer_dst_as_handler;
353 	    primitives++;
354 	  }
355 	}
356       }
357       else if (config.acct_type == ACCT_SF) {
358         if (channels_list[index].plugin->cfg.nfacctd_as & NF_AS_KEEP) {
359           if (channels_list[index].plugin->cfg.nfprobe_peer_as) {
360             channels_list[index].phandler[primitives] = SF_dst_as_handler;
361             primitives++;
362           }
363           else {
364             channels_list[index].phandler[primitives] = SF_peer_dst_as_handler;
365             primitives++;
366 	  }
367         }
368       }
369     }
370 
371     if (channels_list[index].aggregation & COUNT_LOCAL_PREF) {
372       if (config.acct_type == ACCT_SF) {
373         if (channels_list[index].plugin->cfg.nfacctd_as & NF_AS_KEEP) {
374           channels_list[index].phandler[primitives] = SF_local_pref_handler;
375           primitives++;
376         }
377       }
378     }
379 
380     if (channels_list[index].aggregation & COUNT_STD_COMM) {
381       if (config.acct_type == ACCT_SF) {
382         if (channels_list[index].plugin->cfg.nfacctd_as & NF_AS_KEEP) {
383           channels_list[index].phandler[primitives] = SF_std_comms_handler;
384           primitives++;
385         }
386       }
387     }
388 
389     if ((channels_list[index].aggregation & (COUNT_STD_COMM|COUNT_EXT_COMM|COUNT_LOCAL_PREF|COUNT_MED|
390                                             COUNT_AS_PATH|COUNT_PEER_DST_AS|COUNT_SRC_AS_PATH|COUNT_SRC_STD_COMM|
391                                             COUNT_SRC_EXT_COMM|COUNT_SRC_MED|COUNT_SRC_LOCAL_PREF|COUNT_SRC_AS|
392 					    COUNT_DST_AS|COUNT_PEER_SRC_AS) ||
393 	channels_list[index].aggregation_2 & (COUNT_LRG_COMM|COUNT_SRC_LRG_COMM|COUNT_SRC_ROA|COUNT_DST_ROA)) &&
394         channels_list[index].plugin->cfg.nfacctd_as & NF_AS_BGP) {
395       if (config.acct_type == ACCT_PM && (config.bgp_daemon || config.bmp_daemon)) {
396         if (channels_list[index].plugin->type.id == PLUGIN_ID_SFPROBE) {
397           channels_list[index].phandler[primitives] = sfprobe_bgp_ext_handler;
398         }
399         else if (channels_list[index].plugin->type.id == PLUGIN_ID_NFPROBE) {
400           channels_list[index].phandler[primitives] = nfprobe_bgp_ext_handler;
401         }
402         else {
403           channels_list[index].phandler[primitives] = bgp_ext_handler;
404         }
405         primitives++;
406       }
407       else if (config.acct_type == ACCT_NF && (config.bgp_daemon || config.bmp_daemon)) {
408         channels_list[index].phandler[primitives] = bgp_ext_handler;
409         primitives++;
410       }
411       else if (config.acct_type == ACCT_SF && (config.bgp_daemon || config.bmp_daemon)) {
412         channels_list[index].phandler[primitives] = bgp_ext_handler;
413         primitives++;
414       }
415     }
416 
417     if (channels_list[index].aggregation & COUNT_MPLS_VPN_RD) {
418       if (config.nfacctd_flow_to_rd_map) {
419         channels_list[index].phandler[primitives] = mpls_vpn_rd_frommap_handler;
420         primitives++;
421       }
422 
423       if (config.acct_type == ACCT_NF) {
424         channels_list[index].phandler[primitives] = NF_mpls_vpn_id_handler;
425         primitives++;
426       }
427     }
428 
429     if (channels_list[index].aggregation_2 & COUNT_MPLS_PW_ID) {
430       if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_mpls_pw_id_handler;
431       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_mpls_pw_id_handler;
432       else primitives--;
433       primitives++;
434     }
435 
436     if (channels_list[index].aggregation & COUNT_PEER_SRC_AS) {
437       if (config.acct_type == ACCT_PM && config.bgp_daemon) {
438 	if (config.bgp_daemon_peer_as_src_type & BGP_SRC_PRIMITIVES_MAP) {
439           channels_list[index].phandler[primitives] = bgp_peer_src_as_frommap_handler;
440           primitives++;
441 	}
442       }
443       else if (config.acct_type == ACCT_NF) {
444 	if (config.bgp_daemon && config.bgp_daemon_peer_as_src_type & BGP_SRC_PRIMITIVES_MAP) {
445           channels_list[index].phandler[primitives] = bgp_peer_src_as_frommap_handler;
446           primitives++;
447         }
448       }
449       else if (config.acct_type == ACCT_SF) {
450 	if (config.bgp_daemon && config.bgp_daemon_peer_as_src_type & BGP_SRC_PRIMITIVES_MAP) {
451           channels_list[index].phandler[primitives] = bgp_peer_src_as_frommap_handler;
452           primitives++;
453         }
454       }
455     }
456 
457     if (channels_list[index].aggregation & COUNT_SRC_LOCAL_PREF) {
458       if (config.acct_type == ACCT_PM && config.bgp_daemon) {
459         if (config.bgp_daemon_src_local_pref_type & BGP_SRC_PRIMITIVES_MAP) {
460           channels_list[index].phandler[primitives] = bgp_src_local_pref_frommap_handler;
461           primitives++;
462         }
463       }
464       else if (config.acct_type == ACCT_NF && config.bgp_daemon) {
465         if (config.bgp_daemon_src_local_pref_type & BGP_SRC_PRIMITIVES_MAP) {
466           channels_list[index].phandler[primitives] = bgp_src_local_pref_frommap_handler;
467           primitives++;
468         }
469       }
470       else if (config.acct_type == ACCT_SF && config.bgp_daemon) {
471         if (config.bgp_daemon_src_local_pref_type & BGP_SRC_PRIMITIVES_MAP) {
472           channels_list[index].phandler[primitives] = bgp_src_local_pref_frommap_handler;
473           primitives++;
474         }
475       }
476     }
477 
478     if (channels_list[index].aggregation & COUNT_SRC_MED) {
479       if (config.acct_type == ACCT_PM && config.bgp_daemon) {
480         if (config.bgp_daemon_src_med_type & BGP_SRC_PRIMITIVES_MAP) {
481           channels_list[index].phandler[primitives] = bgp_src_med_frommap_handler;
482           primitives++;
483         }
484       }
485       else if (config.acct_type == ACCT_NF && config.bgp_daemon) {
486         if (config.bgp_daemon_src_med_type & BGP_SRC_PRIMITIVES_MAP) {
487           channels_list[index].phandler[primitives] = bgp_src_med_frommap_handler;
488           primitives++;
489         }
490       }
491       else if (config.acct_type == ACCT_SF && config.bgp_daemon) {
492         if (config.bgp_daemon_src_med_type & BGP_SRC_PRIMITIVES_MAP) {
493           channels_list[index].phandler[primitives] = bgp_src_med_frommap_handler;
494           primitives++;
495         }
496       }
497     }
498 
499     if (channels_list[index].aggregation & (COUNT_SRC_PORT|COUNT_SUM_PORT)) {
500       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = src_port_handler;
501       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_src_port_handler;
502       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_src_port_handler;
503       primitives++;
504     }
505 
506     if (channels_list[index].aggregation & (COUNT_DST_PORT|COUNT_SUM_PORT)) {
507       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = dst_port_handler;
508       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_dst_port_handler;
509       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_dst_port_handler;
510       primitives++;
511     }
512 
513     if (channels_list[index].aggregation & COUNT_IP_TOS) {
514       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = ip_tos_handler;
515       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_ip_tos_handler;
516       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_ip_tos_handler;
517       primitives++;
518     }
519 
520     if (channels_list[index].aggregation & COUNT_IP_PROTO) {
521       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = ip_proto_handler;
522       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_ip_proto_handler;
523       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_ip_proto_handler;
524       primitives++;
525     }
526 
527     if (channels_list[index].aggregation & COUNT_TCPFLAGS) {
528       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = tcp_flags_handler;
529       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_tcp_flags_handler;
530       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_tcp_flags_handler;
531       primitives++;
532     }
533 
534     if (channels_list[index].aggregation & COUNT_FLOWS) {
535       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = flows_handler;
536       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_flows_handler;
537       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_flows_handler;
538       primitives++;
539     }
540 
541     if (channels_list[index].aggregation & COUNT_CLASS) {
542       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = class_handler;
543       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_class_handler;
544       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_class_handler;
545       primitives++;
546     }
547 
548 #if defined (WITH_NDPI)
549     if (channels_list[index].aggregation_2 & COUNT_NDPI_CLASS) {
550       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = ndpi_class_handler;
551       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_ndpi_class_handler;
552       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_ndpi_class_handler;
553       primitives++;
554     }
555 #endif
556 
557     if (channels_list[index].aggregation & COUNT_IN_IFACE) {
558       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = in_iface_handler;
559       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_in_iface_handler;
560       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_in_iface_handler;
561       primitives++;
562     }
563 
564     if (channels_list[index].aggregation & COUNT_OUT_IFACE) {
565       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = out_iface_handler;
566       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_out_iface_handler;
567       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_out_iface_handler;
568       primitives++;
569     }
570 
571     if (channels_list[index].aggregation_2 & COUNT_SAMPLING_RATE) {
572       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = sampling_rate_handler;
573       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_sampling_rate_handler;
574       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_sampling_rate_handler;
575       primitives++;
576     }
577 
578     if (channels_list[index].aggregation_2 & COUNT_SAMPLING_DIRECTION) {
579       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = sampling_direction_handler;
580       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_sampling_direction_handler;
581       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = SF_sampling_direction_handler;
582       primitives++;
583     }
584 
585 #if defined (WITH_GEOIP)
586     if (channels_list[index].aggregation_2 & COUNT_SRC_HOST_COUNTRY) {
587       channels_list[index].phandler[primitives] = src_host_country_geoip_handler;
588       primitives++;
589     }
590 
591     if (channels_list[index].aggregation_2 & COUNT_DST_HOST_COUNTRY) {
592       channels_list[index].phandler[primitives] = dst_host_country_geoip_handler;
593       primitives++;
594     }
595 #endif
596 
597 #if defined (WITH_GEOIPV2)
598     pm_geoipv2_init();
599 
600     if (channels_list[index].aggregation_2 & (COUNT_SRC_HOST_COUNTRY|COUNT_SRC_HOST_POCODE|COUNT_SRC_HOST_COORDS) /* other GeoIP primitives here */) {
601       channels_list[index].phandler[primitives] = src_host_geoipv2_lookup_handler;
602       primitives++;
603 
604       if (channels_list[index].aggregation_2 & COUNT_SRC_HOST_COUNTRY) {
605         channels_list[index].phandler[primitives] = src_host_country_geoipv2_handler;
606         primitives++;
607       }
608 
609       if (channels_list[index].aggregation_2 & COUNT_SRC_HOST_POCODE) {
610         channels_list[index].phandler[primitives] = src_host_pocode_geoipv2_handler;
611         primitives++;
612       }
613 
614       if (channels_list[index].aggregation_2 & COUNT_SRC_HOST_COORDS) {
615         channels_list[index].phandler[primitives] = src_host_coords_geoipv2_handler;
616         primitives++;
617       }
618     }
619 
620     if (channels_list[index].aggregation_2 & (COUNT_DST_HOST_COUNTRY|COUNT_DST_HOST_POCODE|COUNT_DST_HOST_COORDS) /* other GeoIP primitives here */) {
621       channels_list[index].phandler[primitives] = dst_host_geoipv2_lookup_handler;
622       primitives++;
623 
624       if (channels_list[index].aggregation_2 & COUNT_DST_HOST_COUNTRY) {
625         channels_list[index].phandler[primitives] = dst_host_country_geoipv2_handler;
626         primitives++;
627       }
628 
629       if (channels_list[index].aggregation_2 & COUNT_DST_HOST_POCODE) {
630         channels_list[index].phandler[primitives] = dst_host_pocode_geoipv2_handler;
631         primitives++;
632       }
633 
634       if (channels_list[index].aggregation_2 & COUNT_DST_HOST_COORDS) {
635         channels_list[index].phandler[primitives] = dst_host_coords_geoipv2_handler;
636         primitives++;
637       }
638     }
639 #endif
640 
641     if (channels_list[index].aggregation_2 & COUNT_POST_NAT_SRC_HOST) {
642       if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_post_nat_src_host_handler;
643       else primitives--;
644       primitives++;
645     }
646 
647     if (channels_list[index].aggregation_2 & COUNT_POST_NAT_DST_HOST) {
648       if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_post_nat_dst_host_handler;
649       else primitives--;
650       primitives++;
651     }
652 
653     if (channels_list[index].aggregation_2 & COUNT_POST_NAT_SRC_PORT) {
654       if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_post_nat_src_port_handler;
655       else primitives--;
656       primitives++;
657     }
658 
659     if (channels_list[index].aggregation_2 & COUNT_POST_NAT_DST_PORT) {
660       if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_post_nat_dst_port_handler;
661       else primitives--;
662       primitives++;
663     }
664 
665     if (channels_list[index].aggregation_2 & COUNT_NAT_EVENT) {
666       if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_nat_event_handler;
667       else primitives--;
668       primitives++;
669     }
670 
671     if (channels_list[index].aggregation_2 & COUNT_TUNNEL_SRC_MAC) {
672       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = tunnel_src_mac_handler;
673       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_tunnel_src_mac_handler;
674       else primitives--;
675       primitives++;
676     }
677 
678     if (channels_list[index].aggregation_2 & COUNT_TUNNEL_DST_MAC) {
679       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = tunnel_dst_mac_handler;
680       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_tunnel_dst_mac_handler;
681       else primitives--;
682       primitives++;
683     }
684 
685     if (channels_list[index].aggregation_2 & COUNT_TUNNEL_SRC_HOST) {
686       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = tunnel_src_host_handler;
687       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_tunnel_src_host_handler;
688       else primitives--;
689       primitives++;
690     }
691 
692     if (channels_list[index].aggregation_2 & COUNT_TUNNEL_DST_HOST) {
693       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = tunnel_dst_host_handler;
694       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_tunnel_dst_host_handler;
695       else primitives--;
696       primitives++;
697     }
698 
699     if (channels_list[index].aggregation_2 & COUNT_TUNNEL_IP_PROTO) {
700       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = tunnel_ip_proto_handler;
701       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_tunnel_ip_proto_handler;
702       else primitives--;
703       primitives++;
704     }
705 
706     if (channels_list[index].aggregation_2 & COUNT_TUNNEL_IP_TOS) {
707       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = tunnel_ip_tos_handler;
708       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_tunnel_ip_tos_handler;
709       else primitives--;
710       primitives++;
711     }
712 
713     if (channels_list[index].aggregation_2 & COUNT_TUNNEL_SRC_PORT) {
714       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = tunnel_src_port_handler;
715       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_tunnel_src_port_handler;
716       else primitives--;
717       primitives++;
718     }
719 
720     if (channels_list[index].aggregation_2 & COUNT_TUNNEL_DST_PORT) {
721       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = tunnel_dst_port_handler;
722       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_tunnel_dst_port_handler;
723       else primitives--;
724       primitives++;
725     }
726 
727     if (channels_list[index].aggregation_2 & COUNT_VXLAN) {
728       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = vxlan_handler;
729       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_vxlan_handler;
730       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_vxlan_handler;
731       else primitives--;
732       primitives++;
733     }
734 
735     if (channels_list[index].aggregation_2 & COUNT_MPLS_LABEL_TOP) {
736       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = mpls_label_top_handler;
737       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_mpls_label_top_handler;
738       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_mpls_label_top_handler;
739       primitives++;
740     }
741 
742     if (channels_list[index].aggregation_2 & COUNT_MPLS_LABEL_BOTTOM) {
743       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = mpls_label_bottom_handler;
744       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_mpls_label_bottom_handler;
745       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_mpls_label_bottom_handler;
746       else primitives--;
747       primitives++;
748     }
749 
750     if (channels_list[index].aggregation_2 & COUNT_MPLS_STACK_DEPTH) {
751       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = mpls_stack_depth_handler;
752       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_mpls_stack_depth_handler;
753       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_mpls_stack_depth_handler;
754       else primitives--;
755       primitives++;
756     }
757 
758     if (channels_list[index].aggregation_2 & COUNT_TIMESTAMP_START) {
759       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = timestamp_start_handler; // XXX: to be removed
760       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_timestamp_start_handler;
761       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_timestamp_start_handler; // XXX: to be removed
762       primitives++;
763     }
764 
765     if (channels_list[index].aggregation_2 & COUNT_TIMESTAMP_END) {
766       if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_timestamp_end_handler;
767       else primitives--;
768       primitives++;
769     }
770 
771     if (channels_list[index].aggregation_2 & COUNT_TIMESTAMP_ARRIVAL) {
772       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = timestamp_arrival_handler;
773       else if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_timestamp_arrival_handler;
774       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_timestamp_arrival_handler;
775       primitives++;
776     }
777 
778     if (channels_list[index].aggregation_2 & COUNT_EXPORT_PROTO_SEQNO) {
779       if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_sequence_number_handler;
780       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_sequence_number_handler;
781       else primitives--;
782       primitives++;
783     }
784 
785     if (channels_list[index].aggregation_2 & COUNT_EXPORT_PROTO_VERSION) {
786       if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_version_handler;
787       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_version_handler;
788       else primitives--;
789       primitives++;
790     }
791 
792     if (channels_list[index].aggregation_2 & COUNT_EXPORT_PROTO_SYSID) {
793       if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_sysid_handler;
794       else if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_sysid_handler;
795       else primitives--;
796       primitives++;
797     }
798 
799     /* if cpptrs.num > 0 one or multiple custom primitives are defined */
800     if (channels_list[index].plugin->cfg.cpptrs.num) {
801       if (config.acct_type == ACCT_PM) {
802 	channels_list[index].phandler[primitives] = custom_primitives_handler;
803 	primitives++;
804       }
805       else if (config.acct_type == ACCT_NF) {
806 	channels_list[index].phandler[primitives] = NF_custom_primitives_handler;
807 	primitives++;
808       }
809       else if (config.acct_type == ACCT_SF) {
810         channels_list[index].phandler[primitives] = SF_custom_primitives_handler;
811         primitives++;
812       }
813     }
814 
815     if (channels_list[index].aggregation & COUNT_COUNTERS) {
816       if (config.acct_type == ACCT_PM) {
817 	channels_list[index].phandler[primitives] = counters_handler;
818 
819 	primitives++;
820 	if (config.nfacctd_time == NF_TIME_NEW) channels_list[index].phandler[primitives] = time_new_handler;
821 	else channels_list[index].phandler[primitives] = time_pcap_handler; /* default */
822 
823 	if (config.sfacctd_renormalize && config.ext_sampling_rate) {
824 	  primitives++;
825 	  channels_list[index].phandler[primitives] = counters_renormalize_handler;
826 	}
827       }
828       else if (config.acct_type == ACCT_NF) {
829 	channels_list[index].phandler[primitives] = NF_counters_handler;
830 
831 	primitives++;
832 	if (config.nfacctd_time == NF_TIME_SECS) channels_list[index].phandler[primitives] = NF_time_secs_handler;
833 	else if (config.nfacctd_time == NF_TIME_NEW) channels_list[index].phandler[primitives] = NF_time_new_handler;
834 	else channels_list[index].phandler[primitives] = NF_time_msecs_handler; /* default */
835 
836 	if (config.sfacctd_renormalize) {
837 	  primitives++;
838 	  if (config.ext_sampling_rate) channels_list[index].phandler[primitives] = counters_renormalize_handler;
839 	  else if (config.sampling_map) {
840 	    channels_list[index].phandler[primitives] = NF_counters_map_renormalize_handler;
841 
842 	    /* Fallback to advertised sampling rate if needed */
843 	    primitives++;
844 	    channels_list[index].phandler[primitives] = NF_counters_renormalize_handler;
845 	  }
846 	  else channels_list[index].phandler[primitives] = NF_counters_renormalize_handler;
847 	}
848       }
849       else if (config.acct_type == ACCT_SF) {
850 	channels_list[index].phandler[primitives] = SF_counters_handler;
851 	if (config.sfacctd_renormalize) {
852 	  primitives++;
853 	  if (config.ext_sampling_rate) channels_list[index].phandler[primitives] = counters_renormalize_handler;
854 	  else if (config.sampling_map) {
855 	    channels_list[index].phandler[primitives] = SF_counters_map_renormalize_handler;
856 
857             /* Fallback to advertised sampling rate if needed */
858             primitives++;
859             channels_list[index].phandler[primitives] = SF_counters_renormalize_handler;
860 	  }
861 	  else channels_list[index].phandler[primitives] = SF_counters_renormalize_handler;
862 	}
863       }
864       primitives++;
865     }
866 
867     if (channels_list[index].plugin->type.id == PLUGIN_ID_NFPROBE) {
868       if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = nfprobe_extras_handler;
869       else primitives--; /* This case is filtered out at startup: getting out silently */
870       primitives++;
871     }
872 
873     if (config.acct_type == ACCT_PM || config.acct_type == ACCT_NF || config.acct_type == ACCT_SF) {
874       if (channels_list[index].aggregation & COUNT_TAG) {
875 	/* we infer 'pre_tag_map' from configuration because it's global */
876         if (channels_list[index].plugin->cfg.pre_tag_map) {
877 	  channels_list[index].phandler[primitives] = pre_tag_handler;
878 	  primitives++;
879 	}
880 
881 	if (config.acct_type == ACCT_NF) {
882 	  channels_list[index].phandler[primitives] = NF_cust_tag_handler;
883 	  primitives++;
884 	}
885 	else if (config.acct_type == ACCT_SF) {
886 	  channels_list[index].phandler[primitives] = SF_tag_handler;
887 	  primitives++;
888 	}
889 
890 	if (channels_list[index].tag) {
891 	  channels_list[index].phandler[primitives] = post_tag_handler;
892 	  primitives++;
893 	}
894       }
895     }
896 
897     if (config.acct_type == ACCT_PM || config.acct_type == ACCT_NF || config.acct_type == ACCT_SF) {
898       if (channels_list[index].aggregation & COUNT_TAG2) {
899         if (channels_list[index].plugin->cfg.pre_tag_map) {
900           channels_list[index].phandler[primitives] = pre_tag2_handler;
901           primitives++;
902         }
903 
904         if (config.acct_type == ACCT_NF) {
905           channels_list[index].phandler[primitives] = NF_cust_tag2_handler;
906           primitives++;
907         }
908         else if (config.acct_type == ACCT_SF) {
909           channels_list[index].phandler[primitives] = SF_tag2_handler;
910           primitives++;
911         }
912 
913         if (channels_list[index].tag2) {
914           channels_list[index].phandler[primitives] = post_tag2_handler;
915           primitives++;
916         }
917       }
918     }
919 
920     /* struct pkt_vlen_hdr_primitives/off_pkt_vlen_hdr_primitives handling: START */
921 
922     if (channels_list[index].aggregation_2 & COUNT_LABEL) {
923       if (channels_list[index].plugin->cfg.pre_tag_map) {
924         channels_list[index].phandler[primitives] = pre_tag_label_handler;
925         primitives++;
926       }
927 
928       if (config.acct_type == ACCT_NF) {
929         channels_list[index].phandler[primitives] = NF_cust_label_handler;
930         primitives++;
931       }
932     }
933 
934     /* struct pkt_vlen_hdr_primitives/off_pkt_vlen_hdr_primitives handling: END */
935 
936     /* sfprobe plugin: struct pkt_payload handling */
937     if (channels_list[index].aggregation & COUNT_PAYLOAD) {
938       if (channels_list[index].plugin->type.id == PLUGIN_ID_SFPROBE) {
939         if (config.acct_type == ACCT_PM) channels_list[index].phandler[primitives] = sfprobe_payload_handler;
940         else primitives--; /* This case is filtered out at startup: getting out silently */
941       }
942       primitives++;
943     }
944 
945     if (channels_list[index].s.rate) {
946       if (channels_list[index].plugin->type.id == PLUGIN_ID_SFPROBE)
947         channels_list[index].phandler[primitives] = sfprobe_sampling_handler;
948       else channels_list[index].phandler[primitives] = sampling_handler;
949       primitives++;
950     }
951 
952     /* tee plugin: struct pkt_msg handling */
953     if (channels_list[index].aggregation & COUNT_NONE) {
954       if (channels_list[index].plugin->type.id == PLUGIN_ID_TEE) {
955         if (config.acct_type == ACCT_SF) channels_list[index].phandler[primitives] = SF_tee_payload_handler;
956         if (config.acct_type == ACCT_NF) channels_list[index].phandler[primitives] = NF_tee_payload_handler;
957         else primitives--; /* This case is filtered out at startup: getting out silently */
958       }
959       primitives++;
960     }
961 
962     index++;
963   }
964 
965   assert(primitives < N_PRIMITIVES);
966 }
967 
968 #if defined (HAVE_L2)
src_mac_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)969 void src_mac_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
970 {
971   struct pkt_data *pdata = (struct pkt_data *) *data;
972 
973   if (pptrs->mac_ptr) memcpy(pdata->primitives.eth_shost, (pptrs->mac_ptr + ETH_ADDR_LEN), ETH_ADDR_LEN);
974 }
975 
dst_mac_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)976 void dst_mac_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
977 {
978   struct pkt_data *pdata = (struct pkt_data *) *data;
979 
980   if (pptrs->mac_ptr) memcpy(pdata->primitives.eth_dhost, pptrs->mac_ptr, ETH_ADDR_LEN);
981 }
982 
vlan_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)983 void vlan_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
984 {
985   struct pkt_data *pdata = (struct pkt_data *) *data;
986   u_int16_t vlan_id = 0;
987 
988   if (pptrs->vlan_ptr) {
989     memcpy(&vlan_id, pptrs->vlan_ptr, 2);
990     pdata->primitives.vlan_id = ntohs(vlan_id);
991     pdata->primitives.vlan_id = pdata->primitives.vlan_id & 0x0FFF;
992   }
993 }
994 
cos_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)995 void cos_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
996 {
997   struct pkt_data *pdata = (struct pkt_data *) *data;
998   u_int16_t cos = 0;
999 
1000   if (pptrs->vlan_ptr) {
1001     memcpy(&cos, pptrs->vlan_ptr, 2);
1002     cos = ntohs(cos);
1003     pdata->primitives.cos = cos >> 13;
1004   }
1005 }
1006 
etype_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1007 void etype_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1008 {
1009   struct pkt_data *pdata = (struct pkt_data *) *data;
1010 
1011   pdata->primitives.etype = pptrs->l3_proto;
1012 }
1013 #endif
1014 
mpls_label_top_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1015 void mpls_label_top_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1016 {
1017   struct pkt_mpls_primitives *pmpls = (struct pkt_mpls_primitives *) ((*data) + chptr->extras.off_pkt_mpls_primitives);
1018   u_int32_t *label = (u_int32_t *) pptrs->mpls_ptr;
1019 
1020   if (label) pmpls->mpls_label_top = MPLS_LABEL(ntohl(*label));
1021 }
1022 
mpls_label_bottom_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1023 void mpls_label_bottom_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1024 {
1025   struct pkt_mpls_primitives *pmpls = (struct pkt_mpls_primitives *) ((*data) + chptr->extras.off_pkt_mpls_primitives);
1026   u_int32_t lvalue = 0, *label = (u_int32_t *) pptrs->mpls_ptr;
1027 
1028   if (label) {
1029     do {
1030       lvalue = ntohl(*label);
1031       label += 4;
1032     } while (!MPLS_STACK(lvalue));
1033 
1034     pmpls->mpls_label_bottom = MPLS_LABEL(lvalue);
1035   }
1036 }
1037 
mpls_stack_depth_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1038 void mpls_stack_depth_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1039 {
1040   struct pkt_mpls_primitives *pmpls = (struct pkt_mpls_primitives *) ((*data) + chptr->extras.off_pkt_mpls_primitives);
1041   u_int32_t lvalue = 0, *label = (u_int32_t *) pptrs->mpls_ptr;
1042 
1043   if (label) {
1044     do {
1045       lvalue = ntohl(*label);
1046       label += 4;
1047       pmpls->mpls_stack_depth++;
1048     } while (!MPLS_STACK(lvalue));
1049   }
1050 }
1051 
bgp_src_nmask_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1052 void bgp_src_nmask_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1053 {
1054   struct pkt_data *pdata = (struct pkt_data *) *data;
1055   struct bgp_node *ret = (struct bgp_node *) pptrs->bgp_src;
1056 
1057   /* check network-related primitives against fallback scenarios */
1058   if (!evaluate_lm_method(pptrs, FALSE, chptr->plugin->cfg.nfacctd_net, NF_NET_BGP)) return;
1059 
1060   if (ret) pdata->primitives.src_nmask = ret->p.prefixlen;
1061 }
1062 
bgp_dst_nmask_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1063 void bgp_dst_nmask_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1064 {
1065   struct pkt_data *pdata = (struct pkt_data *) *data;
1066   struct bgp_node *ret = (struct bgp_node *) pptrs->bgp_dst;
1067 
1068   /* check network-related primitives against fallback scenarios */
1069   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_net, NF_NET_BGP)) return;
1070 
1071   if (ret) pdata->primitives.dst_nmask = ret->p.prefixlen;
1072 }
1073 
bgp_peer_dst_ip_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1074 void bgp_peer_dst_ip_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1075 {
1076   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
1077   struct bgp_info *nh_info = NULL;
1078 
1079   /* check network-related primitives against fallback scenarios */
1080   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_net, NF_NET_BGP)) return;
1081 
1082   if (pptrs->bgp_nexthop_info)
1083     nh_info = (struct bgp_info *) pptrs->bgp_nexthop_info;
1084   else if (pptrs->bgp_dst_info)
1085     nh_info = (struct bgp_info *) pptrs->bgp_dst_info;
1086 
1087   if (nh_info && nh_info->attr) {
1088     if (nh_info->attr->mp_nexthop.family == AF_INET) {
1089       pbgp->peer_dst_ip.family = AF_INET;
1090       memcpy(&pbgp->peer_dst_ip.address.ipv4, &nh_info->attr->mp_nexthop.address.ipv4, 4);
1091     }
1092     else if (nh_info->attr->mp_nexthop.family == AF_INET6) {
1093       pbgp->peer_dst_ip.family = AF_INET6;
1094       memcpy(&pbgp->peer_dst_ip.address.ipv6, &nh_info->attr->mp_nexthop.address.ipv6, 16);
1095     }
1096     else {
1097       pbgp->peer_dst_ip.family = AF_INET;
1098       pbgp->peer_dst_ip.address.ipv4.s_addr = nh_info->attr->nexthop.s_addr;
1099     }
1100   }
1101 }
1102 
igp_src_nmask_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1103 void igp_src_nmask_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1104 {
1105   struct pkt_data *pdata = (struct pkt_data *) *data;
1106   struct route_node *ret = (struct route_node *) pptrs->igp_src;
1107 
1108   /* check network-related primitives against fallback scenarios */
1109   if (!evaluate_lm_method(pptrs, FALSE, chptr->plugin->cfg.nfacctd_net, NF_NET_IGP)) return;
1110 
1111   if (ret) pdata->primitives.src_nmask = ret->p.prefixlen;
1112 }
1113 
igp_dst_nmask_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1114 void igp_dst_nmask_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1115 {
1116   struct pkt_data *pdata = (struct pkt_data *) *data;
1117   struct route_node *ret = (struct route_node *) pptrs->igp_dst;
1118 
1119   /* check network-related primitives against fallback scenarios */
1120   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_net, NF_NET_IGP)) return;
1121 
1122   if (ret) pdata->primitives.dst_nmask = ret->p.prefixlen;
1123 }
1124 
igp_peer_dst_ip_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1125 void igp_peer_dst_ip_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1126 {
1127   struct route_node *ret = (struct route_node *) pptrs->igp_dst;
1128   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
1129 
1130   /* check network-related primitives against fallback scenarios */
1131   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_net, NF_NET_IGP)) return;
1132 
1133   if (ret) {
1134     pbgp->peer_dst_ip.family = AF_INET;
1135     memcpy(&pbgp->peer_dst_ip.address.ipv4, &ret->p.adv_router, 4);
1136   }
1137 }
1138 
src_host_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1139 void src_host_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1140 {
1141   struct pkt_data *pdata = (struct pkt_data *) *data;
1142 
1143   if (pptrs->l3_proto == ETHERTYPE_IP) {
1144     pdata->primitives.src_ip.address.ipv4.s_addr = ((struct pm_iphdr *) pptrs->iph_ptr)->ip_src.s_addr;
1145     pdata->primitives.src_ip.family = AF_INET;
1146   }
1147   else if (pptrs->l3_proto == ETHERTYPE_IPV6) {
1148     memcpy(&pdata->primitives.src_ip.address.ipv6, &((struct ip6_hdr *)pptrs->iph_ptr)->ip6_src, IP6AddrSz);
1149     pdata->primitives.src_ip.family = AF_INET6;
1150   }
1151 }
1152 
dst_host_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1153 void dst_host_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1154 {
1155   struct pkt_data *pdata = (struct pkt_data *) *data;
1156 
1157   if (pptrs->l3_proto == ETHERTYPE_IP) {
1158     pdata->primitives.dst_ip.address.ipv4.s_addr = ((struct pm_iphdr *) pptrs->iph_ptr)->ip_dst.s_addr;
1159     pdata->primitives.dst_ip.family = AF_INET;
1160   }
1161   else if (pptrs->l3_proto == ETHERTYPE_IPV6) {
1162     memcpy(&pdata->primitives.dst_ip.address.ipv6, &((struct ip6_hdr *)pptrs->iph_ptr)->ip6_dst, IP6AddrSz);
1163     pdata->primitives.dst_ip.family = AF_INET6;
1164   }
1165 }
1166 
src_port_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1167 void src_port_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1168 {
1169   struct pkt_data *pdata = (struct pkt_data *) *data;
1170 
1171   if (pptrs->l4_proto == IPPROTO_UDP || pptrs->l4_proto == IPPROTO_TCP)
1172     pdata->primitives.src_port = ntohs(((struct pm_tlhdr *) pptrs->tlh_ptr)->src_port);
1173   else pdata->primitives.src_port = 0;
1174 }
1175 
dst_port_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1176 void dst_port_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1177 {
1178   struct pkt_data *pdata = (struct pkt_data *) *data;
1179 
1180   if (pptrs->l4_proto == IPPROTO_UDP || pptrs->l4_proto == IPPROTO_TCP)
1181     pdata->primitives.dst_port = ntohs(((struct pm_tlhdr *) pptrs->tlh_ptr)->dst_port);
1182   else pdata->primitives.dst_port = 0;
1183 }
1184 
ip_tos_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1185 void ip_tos_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1186 {
1187   struct pkt_data *pdata = (struct pkt_data *) *data;
1188   u_int32_t tos = 0;
1189 
1190   if (pptrs->l3_proto == ETHERTYPE_IP) {
1191     pdata->primitives.tos = ((struct pm_iphdr *) pptrs->iph_ptr)->ip_tos;
1192   }
1193   else if (pptrs->l3_proto == ETHERTYPE_IPV6) {
1194     tos = ntohl(((struct ip6_hdr *) pptrs->iph_ptr)->ip6_flow);
1195     tos = ((tos & 0x0ff00000) >> 20);
1196     pdata->primitives.tos = tos;
1197   }
1198 }
1199 
ip_proto_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1200 void ip_proto_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1201 {
1202   struct pkt_data *pdata = (struct pkt_data *) *data;
1203 
1204   pdata->primitives.proto = pptrs->l4_proto;
1205 }
1206 
tcp_flags_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1207 void tcp_flags_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1208 {
1209   struct pkt_data *pdata = (struct pkt_data *) *data;
1210 
1211   if (pptrs->l4_proto == IPPROTO_TCP) pdata->tcp_flags = pptrs->tcp_flags;
1212 }
1213 
tunnel_src_mac_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1214 void tunnel_src_mac_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1215 {
1216   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
1217   struct packet_ptrs *tpptrs = (struct packet_ptrs *) pptrs->tun_pptrs;
1218 
1219   if (tpptrs) {
1220     if (tpptrs->mac_ptr) memcpy(ptun->tunnel_eth_shost, (tpptrs->mac_ptr + ETH_ADDR_LEN), ETH_ADDR_LEN);
1221   }
1222 }
1223 
tunnel_dst_mac_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1224 void tunnel_dst_mac_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1225 {
1226   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
1227   struct packet_ptrs *tpptrs = (struct packet_ptrs *) pptrs->tun_pptrs;
1228 
1229   if (tpptrs) {
1230     if (tpptrs->mac_ptr) memcpy(ptun->tunnel_eth_dhost, tpptrs->mac_ptr, ETH_ADDR_LEN);
1231   }
1232 }
1233 
tunnel_src_host_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1234 void tunnel_src_host_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1235 {
1236   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
1237   struct packet_ptrs *tpptrs = (struct packet_ptrs *) pptrs->tun_pptrs;
1238 
1239   if (tpptrs) {
1240     if (tpptrs->l3_proto == ETHERTYPE_IP) {
1241       ptun->tunnel_src_ip.address.ipv4.s_addr = ((struct pm_iphdr *) tpptrs->iph_ptr)->ip_src.s_addr;
1242       ptun->tunnel_src_ip.family = AF_INET;
1243     }
1244     else if (tpptrs->l3_proto == ETHERTYPE_IPV6) {
1245       memcpy(&ptun->tunnel_src_ip.address.ipv6, &((struct ip6_hdr *) tpptrs->iph_ptr)->ip6_src, IP6AddrSz);
1246       ptun->tunnel_src_ip.family = AF_INET6;
1247     }
1248   }
1249 }
1250 
tunnel_dst_host_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1251 void tunnel_dst_host_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1252 {
1253   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
1254   struct packet_ptrs *tpptrs = (struct packet_ptrs *) pptrs->tun_pptrs;
1255 
1256   if (tpptrs) {
1257     if (tpptrs->l3_proto == ETHERTYPE_IP) {
1258       ptun->tunnel_dst_ip.address.ipv4.s_addr = ((struct pm_iphdr *) tpptrs->iph_ptr)->ip_dst.s_addr;
1259       ptun->tunnel_dst_ip.family = AF_INET;
1260     }
1261     else if (tpptrs->l3_proto == ETHERTYPE_IPV6) {
1262       memcpy(&ptun->tunnel_dst_ip.address.ipv6, &((struct ip6_hdr *) tpptrs->iph_ptr)->ip6_dst, IP6AddrSz);
1263       ptun->tunnel_dst_ip.family = AF_INET6;
1264     }
1265   }
1266 }
1267 
tunnel_ip_proto_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1268 void tunnel_ip_proto_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1269 {
1270   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
1271   struct packet_ptrs *tpptrs = (struct packet_ptrs *) pptrs->tun_pptrs;
1272 
1273   if (tpptrs) ptun->tunnel_proto = tpptrs->l4_proto;;
1274 }
1275 
tunnel_ip_tos_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1276 void tunnel_ip_tos_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1277 {
1278   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
1279   struct packet_ptrs *tpptrs = (struct packet_ptrs *) pptrs->tun_pptrs;
1280   u_int32_t tos = 0;
1281 
1282   if (tpptrs) {
1283     if (tpptrs->l3_proto == ETHERTYPE_IP) {
1284       ptun->tunnel_tos = ((struct pm_iphdr *) tpptrs->iph_ptr)->ip_tos;
1285     }
1286     else if (tpptrs->l3_proto == ETHERTYPE_IPV6) {
1287       tos = ntohl(((struct ip6_hdr *) tpptrs->iph_ptr)->ip6_flow);
1288       tos = ((tos & 0x0ff00000) >> 20);
1289       ptun->tunnel_tos = tos;
1290     }
1291   }
1292 }
1293 
tunnel_src_port_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1294 void tunnel_src_port_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1295 {
1296   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
1297   struct packet_ptrs *tpptrs = (struct packet_ptrs *) pptrs->tun_pptrs;
1298 
1299   ptun->tunnel_src_port = 0;
1300 
1301   if (tpptrs) {
1302     if (tpptrs->l4_proto == IPPROTO_UDP || tpptrs->l4_proto == IPPROTO_TCP) {
1303       ptun->tunnel_src_port = ntohs(((struct pm_tlhdr *) tpptrs->tlh_ptr)->src_port);
1304     }
1305   }
1306 }
1307 
tunnel_dst_port_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1308 void tunnel_dst_port_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1309 {
1310   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
1311   struct packet_ptrs *tpptrs = (struct packet_ptrs *) pptrs->tun_pptrs;
1312 
1313   if (tpptrs) {
1314     if (tpptrs->l4_proto == IPPROTO_UDP || tpptrs->l4_proto == IPPROTO_TCP) {
1315       ptun->tunnel_dst_port = ntohs(((struct pm_tlhdr *) tpptrs->tlh_ptr)->dst_port);
1316     }
1317   }
1318 }
1319 
vxlan_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1320 void vxlan_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1321 {
1322   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
1323   u_char *vni_ptr;
1324 
1325   if (pptrs->vxlan_ptr) {
1326     vni_ptr = pptrs->vxlan_ptr;
1327 
1328     ptun->tunnel_id = *vni_ptr++;
1329     ptun->tunnel_id <<= 8;
1330     ptun->tunnel_id += *vni_ptr++;
1331     ptun->tunnel_id <<= 8;
1332     ptun->tunnel_id += *vni_ptr++;
1333   }
1334 }
1335 
counters_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1336 void counters_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1337 {
1338   struct pkt_data *pdata = (struct pkt_data *) *data;
1339 
1340   if (pptrs->l3_proto == ETHERTYPE_IP) pdata->pkt_len = ntohs(((struct pm_iphdr *) pptrs->iph_ptr)->ip_len);
1341   else if (pptrs->l3_proto == ETHERTYPE_IPV6) pdata->pkt_len = ntohs(((struct ip6_hdr *) pptrs->iph_ptr)->ip6_plen)+IP6HdrSz;
1342 
1343   if (pptrs->frag_sum_bytes) {
1344     pdata->pkt_len += pptrs->frag_sum_bytes;
1345     pptrs->frag_sum_bytes = 0;
1346   }
1347 
1348   pdata->pkt_num = 1;
1349   if (pptrs->frag_sum_pkts) {
1350     pdata->pkt_num += pptrs->frag_sum_pkts;
1351     pptrs->frag_sum_pkts = 0;
1352   }
1353 
1354   pdata->flow_type = pptrs->flow_type;
1355 }
1356 
counters_renormalize_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1357 void counters_renormalize_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1358 {
1359   struct pkt_data *pdata = (struct pkt_data *) *data;
1360 
1361   if (pptrs->renormalized) return;
1362 
1363   pdata->pkt_len = pdata->pkt_len*config.ext_sampling_rate;
1364   pdata->pkt_num = pdata->pkt_num*config.ext_sampling_rate;
1365 
1366   pptrs->renormalized = TRUE;
1367 }
1368 
time_new_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1369 void time_new_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1370 {
1371   struct pkt_data *pdata = (struct pkt_data *) *data;
1372 
1373   pdata->time_start.tv_sec = 0;
1374   pdata->time_start.tv_usec = 0;
1375   pdata->time_end.tv_sec = 0;
1376   pdata->time_end.tv_usec = 0;
1377 }
1378 
time_pcap_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1379 void time_pcap_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1380 {
1381   struct pkt_data *pdata = (struct pkt_data *) *data;
1382 
1383   pdata->time_start.tv_sec = ((struct pcap_pkthdr *)pptrs->pkthdr)->ts.tv_sec;
1384   pdata->time_start.tv_usec = ((struct pcap_pkthdr *)pptrs->pkthdr)->ts.tv_usec;
1385   pdata->time_end.tv_sec = 0;
1386   pdata->time_end.tv_usec = 0;
1387 }
1388 
post_tag_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1389 void post_tag_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1390 {
1391   struct pkt_data *pdata = (struct pkt_data *) *data;
1392 
1393   pdata->primitives.tag = chptr->tag;
1394 }
1395 
post_tag2_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1396 void post_tag2_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1397 {
1398   struct pkt_data *pdata = (struct pkt_data *) *data;
1399 
1400   pdata->primitives.tag2 = chptr->tag2;
1401 }
1402 
flows_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1403 void flows_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1404 {
1405   struct pkt_data *pdata = (struct pkt_data *) *data;
1406 
1407   if (pptrs->new_flow) pdata->flo_num = 1;
1408 }
1409 
class_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1410 void class_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1411 {
1412   struct pkt_data *pdata = (struct pkt_data *) *data;
1413 
1414   pdata->primitives.class = pptrs->class;
1415   pdata->cst.ba = pptrs->cst.ba;
1416   pdata->cst.pa = pptrs->cst.pa;
1417   if (chptr->aggregation & COUNT_FLOWS)
1418     pdata->cst.fa = pptrs->cst.fa;
1419   pdata->cst.stamp.tv_sec = pptrs->cst.stamp.tv_sec;
1420   pdata->cst.stamp.tv_usec = pptrs->cst.stamp.tv_usec;
1421   pdata->cst.tentatives = pptrs->cst.tentatives;
1422 }
1423 
1424 #if defined (WITH_NDPI)
ndpi_class_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1425 void ndpi_class_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1426 {
1427   struct pkt_data *pdata = (struct pkt_data *) *data;
1428 
1429   memcpy(&pdata->primitives.ndpi_class, &pptrs->ndpi_class, sizeof(pm_class2_t));
1430 }
1431 #endif
1432 
sfprobe_payload_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1433 void sfprobe_payload_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1434 {
1435   struct pkt_payload *payload = (struct pkt_payload *) *data;
1436   struct pkt_data tmp;
1437   struct pkt_bgp_primitives tmp_bgp;
1438   struct eth_header eh;
1439   char *buf = (char *) *data, *tmpp = (char *) &tmp;
1440   char *tmp_bgpp = (char *) &tmp_bgp;
1441   int space = (chptr->bufend - chptr->bufptr) - PpayloadSz;
1442   int ethHdrLen = 0;
1443 
1444   memset(&tmp, 0, sizeof(tmp));
1445   memset(&tmp_bgp, 0, sizeof(tmp_bgp));
1446 
1447   if (chptr->plugin->cfg.nfacctd_as & NF_AS_NEW ||
1448       chptr->plugin->cfg.nfacctd_net == NF_NET_NEW) {
1449     src_host_handler(chptr, pptrs, &tmpp);
1450     dst_host_handler(chptr, pptrs, &tmpp);
1451     memcpy(&payload->src_ip, &tmp.primitives.src_ip, HostAddrSz);
1452     memcpy(&payload->dst_ip, &tmp.primitives.dst_ip, HostAddrSz);
1453   }
1454 
1455   if (chptr->plugin->cfg.nfacctd_net == NF_NET_BGP) {
1456     bgp_src_nmask_handler(chptr, pptrs, &tmpp);
1457     bgp_dst_nmask_handler(chptr, pptrs, &tmpp);
1458     payload->src_nmask = tmp.primitives.src_nmask;
1459     payload->dst_nmask = tmp.primitives.dst_nmask;
1460 
1461     bgp_peer_dst_ip_handler(chptr, pptrs, &tmp_bgpp);
1462     memcpy(&payload->bgp_next_hop, &tmp_bgp.peer_dst_ip, HostAddrSz);
1463   }
1464 
1465   payload->cap_len = ((struct pcap_pkthdr *)pptrs->pkthdr)->caplen;
1466   payload->pkt_len = ((struct pcap_pkthdr *)pptrs->pkthdr)->len;
1467   payload->pkt_num = 1;
1468   payload->time_start = ((struct pcap_pkthdr *)pptrs->pkthdr)->ts.tv_sec;
1469   payload->class = pptrs->class;
1470 #if defined (WITH_NDPI)
1471   memcpy(&payload->ndpi_class, &pptrs->ndpi_class, sizeof(pm_class2_t));
1472 #endif
1473   payload->tag = pptrs->tag;
1474   payload->tag2 = pptrs->tag2;
1475   if (pptrs->ifindex_in > 0)  payload->ifindex_in  = pptrs->ifindex_in;
1476   if (pptrs->ifindex_out > 0) payload->ifindex_out = pptrs->ifindex_out;
1477   if (pptrs->vlan_ptr) {
1478     u_int16_t vlan_id = 0;
1479 
1480     memcpy(&vlan_id, pptrs->vlan_ptr, 2);
1481     vlan_id = ntohs(vlan_id);
1482     payload->vlan = vlan_id & 0x0FFF;
1483     payload->priority = vlan_id >> 13;
1484   }
1485 
1486   /* Typically don't have L2 info under NFLOG */
1487   if (!pptrs->mac_ptr) {
1488     ethHdrLen = sizeof(struct eth_header);
1489     memset(&eh, 0, ethHdrLen);
1490     eh.ether_type = htons(pptrs->l3_proto);
1491     payload->cap_len += ethHdrLen;
1492     payload->pkt_len += ethHdrLen;
1493   }
1494 
1495   /* We could be capturing the entire packet; DEFAULT_PLOAD_SIZE is our cut-off point */
1496   if (payload->cap_len > DEFAULT_PLOAD_SIZE) payload->cap_len = DEFAULT_PLOAD_SIZE;
1497 
1498   if (space >= payload->cap_len) {
1499     buf += PpayloadSz;
1500     if (!pptrs->mac_ptr) {
1501       memcpy(buf, &eh, ethHdrLen);
1502       buf += ethHdrLen;
1503     }
1504     memcpy(buf, pptrs->packet_ptr, payload->cap_len-ethHdrLen);
1505     chptr->bufptr += payload->cap_len; /* don't count pkt_payload here */
1506 #if NEED_ALIGN
1507     while (chptr->bufptr % 4 != 0) chptr->bufptr++; /* Don't worry, it's harmless increasing here */
1508 #endif
1509   }
1510   else {
1511     chptr->bufptr += space;
1512     chptr->reprocess = TRUE;
1513   }
1514 }
1515 
NF_tee_payload_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1516 void NF_tee_payload_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1517 {
1518   struct pkt_msg *pmsg = (struct pkt_msg *) *data;
1519   char *ppayload = ((*data) + PmsgSz);
1520 
1521   if (!pptrs->tee_dissect) {
1522     pmsg->seqno = pptrs->seqno;
1523     pmsg->len = pptrs->f_len;
1524     pmsg->payload = NULL;
1525     memcpy(&pmsg->agent, pptrs->f_agent, sizeof(pmsg->agent));
1526     pmsg->tag = pptrs->tag;
1527     pmsg->tag2 = pptrs->tag2;
1528     pmsg->bcast = FALSE;
1529     if (!check_pipe_buffer_space(chptr, NULL, pptrs->f_len)) {
1530       memcpy(ppayload, pptrs->f_header, pptrs->f_len);
1531     }
1532   }
1533   else {
1534     struct NF_dissect *tee_dissect = (struct NF_dissect *) pptrs->tee_dissect;
1535 
1536     pmsg->seqno = pptrs->seqno;
1537     pmsg->len = (tee_dissect->hdrLen + tee_dissect->flowSetLen + tee_dissect->elemLen);
1538     pmsg->payload = NULL;
1539     memcpy(&pmsg->agent, pptrs->f_agent, sizeof(pmsg->agent));
1540     pmsg->tag = pptrs->tag;
1541     pmsg->tag2 = pptrs->tag2;
1542     pmsg->bcast = pptrs->tee_dissect_bcast;
1543     if (!check_pipe_buffer_space(chptr, NULL, pmsg->len)) {
1544       memcpy(ppayload, tee_dissect->hdrBasePtr, tee_dissect->hdrLen);
1545       if (tee_dissect->flowSetLen) memcpy((ppayload + tee_dissect->hdrLen), tee_dissect->flowSetBasePtr, tee_dissect->flowSetLen);
1546       memcpy((ppayload + tee_dissect->hdrLen + tee_dissect->flowSetLen), tee_dissect->elemBasePtr, tee_dissect->elemLen);
1547 
1548       /* fix-ups */
1549       ((struct struct_header_v5 *)ppayload)->version = htons(tee_dissect->hdrVersion);
1550 
1551       switch (tee_dissect->hdrVersion) {
1552       case 5:
1553         ((struct struct_header_v5 *)ppayload)->count = htons(tee_dissect->hdrCount);
1554         break;
1555       case 9:
1556         ((struct struct_header_v9 *)ppayload)->count = htons(tee_dissect->hdrCount);
1557         ((struct data_hdr_v9 *)(ppayload + tee_dissect->hdrLen))->flow_len = htons(tee_dissect->flowSetLen + tee_dissect->elemLen);
1558         break;
1559       case 10:
1560         ((struct struct_header_ipfix *)ppayload)->len = htons(tee_dissect->hdrLen + tee_dissect->flowSetLen + tee_dissect->elemLen);
1561         ((struct data_hdr_v9 *)(ppayload + tee_dissect->hdrLen))->flow_len = htons(tee_dissect->flowSetLen + tee_dissect->elemLen);
1562         break;
1563       }
1564     }
1565   }
1566 }
1567 
SF_tee_payload_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1568 void SF_tee_payload_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1569 {
1570   struct pkt_msg *pmsg = (struct pkt_msg *) *data;
1571   char *ppayload = ((*data) + PmsgSz);
1572 
1573   if (!pptrs->tee_dissect) {
1574     pmsg->seqno = pptrs->seqno;
1575     pmsg->len = pptrs->f_len;
1576     pmsg->payload = NULL;
1577     memcpy(&pmsg->agent, pptrs->f_agent, sizeof(pmsg->agent));
1578     pmsg->tag = pptrs->tag;
1579     pmsg->tag2 = pptrs->tag2;
1580     pmsg->bcast = FALSE;
1581     if (!check_pipe_buffer_space(chptr, NULL, pptrs->f_len)) {
1582       memcpy(ppayload, pptrs->f_header, pptrs->f_len);
1583     }
1584   }
1585   else {
1586     struct SF_dissect *dissect = (struct SF_dissect *) pptrs->tee_dissect;
1587 
1588     pmsg->seqno = pptrs->seqno;
1589     pmsg->len = (dissect->hdrLen + dissect->flowLen);
1590     pmsg->payload = NULL;
1591     memcpy(&pmsg->agent, pptrs->f_agent, sizeof(pmsg->agent));
1592     pmsg->tag = pptrs->tag;
1593     pmsg->tag2 = pptrs->tag2;
1594     if (!check_pipe_buffer_space(chptr, NULL, pmsg->len)) {
1595       memcpy(ppayload, dissect->hdrBasePtr, dissect->hdrLen);
1596       memcpy((ppayload + dissect->hdrLen), dissect->flowBasePtr, dissect->flowLen);
1597     }
1598   }
1599 }
1600 
nfprobe_extras_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1601 void nfprobe_extras_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1602 {
1603   struct pkt_data *pdata = (struct pkt_data *) *data;
1604   struct pkt_extras *pextras = (struct pkt_extras *) ++pdata;
1605 
1606   --pdata; /* Bringing back to original place */
1607 
1608   if (pptrs->l4_proto == IPPROTO_TCP) pextras->tcp_flags = pptrs->tcp_flags;
1609 }
1610 
in_iface_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1611 void in_iface_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1612 {
1613   struct pkt_data *pdata = (struct pkt_data *) *data;
1614 
1615   if (pptrs->ifindex_in > 0)  pdata->primitives.ifindex_in  = pptrs->ifindex_in;
1616 }
1617 
out_iface_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1618 void out_iface_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1619 {
1620   struct pkt_data *pdata = (struct pkt_data *) *data;
1621 
1622   if (pptrs->ifindex_out > 0) pdata->primitives.ifindex_out = pptrs->ifindex_out;
1623 }
1624 
sampling_rate_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1625 void sampling_rate_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1626 {
1627   struct pkt_data *pdata = (struct pkt_data *) *data;
1628 
1629   pdata->primitives.sampling_rate = config.ext_sampling_rate ? config.ext_sampling_rate : 1;
1630 
1631   if (config.sfacctd_renormalize)
1632     pdata->primitives.sampling_rate = 1; /* already renormalized */
1633 }
1634 
sampling_direction_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1635 void sampling_direction_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1636 {
1637   struct pkt_data *pdata = (struct pkt_data *) *data;
1638 
1639   /* dummy */
1640   pdata->primitives.sampling_direction[0] = 'u';
1641   pdata->primitives.sampling_direction[1] = '\0';
1642 }
1643 
mpls_vpn_rd_frommap_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1644 void mpls_vpn_rd_frommap_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1645 {
1646   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
1647 
1648   if (pbgp && pptrs->bitr) memcpy(&pbgp->mpls_vpn_rd, &pptrs->bitr, sizeof(rd_t));
1649 }
1650 
timestamp_start_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1651 void timestamp_start_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1652 {
1653   struct pkt_nat_primitives *pnat = (struct pkt_nat_primitives *) ((*data) + chptr->extras.off_pkt_nat_primitives);
1654 
1655   pnat->timestamp_start.tv_sec = ((struct pcap_pkthdr *)pptrs->pkthdr)->ts.tv_sec;
1656   if (!chptr->plugin->cfg.timestamps_secs) {
1657     pnat->timestamp_start.tv_usec = ((struct pcap_pkthdr *)pptrs->pkthdr)->ts.tv_usec;
1658   }
1659 }
1660 
timestamp_arrival_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1661 void timestamp_arrival_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1662 {
1663   struct pkt_nat_primitives *pnat = (struct pkt_nat_primitives *) ((*data) + chptr->extras.off_pkt_nat_primitives);
1664 
1665   pnat->timestamp_arrival.tv_sec = ((struct pcap_pkthdr *)pptrs->pkthdr)->ts.tv_sec;
1666   if (!chptr->plugin->cfg.timestamps_secs) {
1667     pnat->timestamp_arrival.tv_usec = ((struct pcap_pkthdr *)pptrs->pkthdr)->ts.tv_usec;
1668   }
1669 }
1670 
custom_primitives_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1671 void custom_primitives_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1672 {
1673   u_char *pcust = (u_char *)((*data) + chptr->extras.off_custom_primitives);
1674   struct pkt_vlen_hdr_primitives *pvlen = (struct pkt_vlen_hdr_primitives *) ((*data) + chptr->extras.off_pkt_vlen_hdr_primitives);
1675   struct custom_primitive_entry *cpe;
1676   int cpptrs_idx, pd_ptr_idx;
1677 
1678   for (cpptrs_idx = 0; cpptrs_idx < chptr->plugin->cfg.cpptrs.num; cpptrs_idx++) {
1679     if (chptr->plugin->cfg.cpptrs.primitive[cpptrs_idx].ptr) {
1680       cpe = chptr->plugin->cfg.cpptrs.primitive[cpptrs_idx].ptr;
1681 
1682       for (pd_ptr_idx = 0; pd_ptr_idx < MAX_CUSTOM_PRIMITIVE_PD_PTRS && cpe->pd_ptr[pd_ptr_idx].ptr_idx.set; pd_ptr_idx++) {
1683         if (pptrs->pkt_data_ptrs[cpe->pd_ptr[pd_ptr_idx].ptr_idx.n] &&
1684 	    ((pptrs->pkt_data_ptrs[cpe->pd_ptr[pd_ptr_idx].ptr_idx.n] -
1685 		pptrs->pkt_data_ptrs[0]) +
1686 		cpe->pd_ptr[pd_ptr_idx].off + (cpe->len % PM_VARIABLE_LENGTH)) <
1687 	    ((struct pcap_pkthdr *)pptrs->pkthdr)->caplen) {
1688 	  if (!cpe->pd_ptr[pd_ptr_idx].proto.set ||
1689 	      pptrs->pkt_proto[cpe->pd_ptr[pd_ptr_idx].ptr_idx.n] ==
1690 			cpe->pd_ptr[pd_ptr_idx].proto.n) {
1691 	    if (cpe->semantics == CUSTOM_PRIMITIVE_TYPE_RAW) {
1692               unsigned char hexbuf[cpe->alloc_len];
1693               int hexbuflen = 0;
1694 
1695               hexbuflen = serialize_hex((pptrs->pkt_data_ptrs[cpe->pd_ptr[pd_ptr_idx].ptr_idx.n] + cpe->pd_ptr[pd_ptr_idx].off), hexbuf, cpe->len);
1696               if (cpe->alloc_len < hexbuflen) hexbuf[cpe->alloc_len-1] = '\0';
1697               memcpy(pcust+chptr->plugin->cfg.cpptrs.primitive[cpptrs_idx].off, hexbuf, MIN(hexbuflen, cpe->alloc_len));
1698 	    }
1699 	    else {
1700 	      // XXX: maybe prone to SEGV if not a string: check to be added?
1701 	      if (cpe->semantics == CUSTOM_PRIMITIVE_TYPE_STRING && cpe->len == PM_VARIABLE_LENGTH) {
1702 		char *str_ptr = (char *)(pptrs->pkt_data_ptrs[cpe->pd_ptr[pd_ptr_idx].ptr_idx.n] + cpe->pd_ptr[pd_ptr_idx].off);
1703 		int remaining_len, str_len;
1704 
1705 		remaining_len = (((struct pcap_pkthdr *)pptrs->pkthdr)->caplen -
1706 				 ((pptrs->pkt_data_ptrs[cpe->pd_ptr[pd_ptr_idx].ptr_idx.n] -
1707                 		   pptrs->pkt_data_ptrs[0]) + cpe->pd_ptr[pd_ptr_idx].off));
1708 
1709 		if (remaining_len > 0) {
1710 		  str_ptr[remaining_len-1] = '\0'; /* maybe too simplistic */
1711 		  str_len = strlen(str_ptr);
1712 
1713 		  if (str_len) {
1714                     if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + str_len + 1 /* terminating zero */)) {
1715                       vlen_prims_init(pvlen, 0);
1716                       return;
1717                     }
1718                     else vlen_prims_insert(pvlen, cpe->type, str_len, (u_char *) str_ptr, PM_MSG_STR_COPY_ZERO);
1719 		  }
1720 		}
1721 	      }
1722 	      else {
1723 		memcpy(pcust+chptr->plugin->cfg.cpptrs.primitive[cpptrs_idx].off,
1724 		       pptrs->pkt_data_ptrs[cpe->pd_ptr[pd_ptr_idx].ptr_idx.n]+cpe->pd_ptr[pd_ptr_idx].off,
1725 		       cpe->len);
1726 	      }
1727 	    }
1728 	  }
1729 	}
1730       }
1731     }
1732   }
1733 }
1734 
1735 #if defined (HAVE_L2)
NF_src_mac_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1736 void NF_src_mac_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1737 {
1738   struct pkt_data *pdata = (struct pkt_data *) *data;
1739   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1740   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1741 
1742   switch(hdr->version) {
1743   case 10:
1744   case 9:
1745     if (tpl->tpl[NF9_IN_SRC_MAC].len)
1746       memcpy(&pdata->primitives.eth_shost, pptrs->f_data+tpl->tpl[NF9_IN_SRC_MAC].off, MIN(tpl->tpl[NF9_IN_SRC_MAC].len, 6));
1747     else if (tpl->tpl[NF9_OUT_SRC_MAC].len)
1748       memcpy(&pdata->primitives.eth_shost, pptrs->f_data+tpl->tpl[NF9_OUT_SRC_MAC].off, MIN(tpl->tpl[NF9_OUT_SRC_MAC].len, 6));
1749     else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
1750       src_mac_handler(chptr, pptrs, data);
1751 
1752     break;
1753   default:
1754     break;
1755   }
1756 }
1757 
NF_dst_mac_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1758 void NF_dst_mac_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1759 {
1760   struct pkt_data *pdata = (struct pkt_data *) *data;
1761   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1762   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1763 
1764   switch(hdr->version) {
1765   case 10:
1766   case 9:
1767     if (tpl->tpl[NF9_IN_DST_MAC].len)
1768       memcpy(&pdata->primitives.eth_dhost, pptrs->f_data+tpl->tpl[NF9_IN_DST_MAC].off, MIN(tpl->tpl[NF9_IN_DST_MAC].len, 6));
1769     else if (tpl->tpl[NF9_OUT_DST_MAC].len)
1770       memcpy(&pdata->primitives.eth_dhost, pptrs->f_data+tpl->tpl[NF9_OUT_DST_MAC].off, MIN(tpl->tpl[NF9_OUT_DST_MAC].len, 6));
1771     else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
1772       dst_mac_handler(chptr, pptrs, data);
1773 
1774     break;
1775   default:
1776     break;
1777   }
1778 }
1779 
NF_vlan_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1780 void NF_vlan_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1781 {
1782   struct pkt_data *pdata = (struct pkt_data *) *data;
1783   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1784   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1785   u_int8_t direction;
1786 
1787   switch(hdr->version) {
1788   case 10:
1789   case 9:
1790     if (tpl->tpl[NF9_DIRECTION].len) {
1791       memcpy(&direction, pptrs->f_data+tpl->tpl[NF9_DIRECTION].off, MIN(tpl->tpl[NF9_DIRECTION].len, 1));
1792 
1793       if (direction == FALSE) {
1794 	if (tpl->tpl[NF9_IN_VLAN].len)
1795 	  memcpy(&pdata->primitives.vlan_id, pptrs->f_data+tpl->tpl[NF9_IN_VLAN].off, MIN(tpl->tpl[NF9_IN_VLAN].len, 2));
1796 	else if (tpl->tpl[NF9_DOT1QVLANID].len)
1797 	  memcpy(&pdata->primitives.vlan_id, pptrs->f_data+tpl->tpl[NF9_DOT1QVLANID].off, MIN(tpl->tpl[NF9_DOT1QVLANID].len, 2));
1798       }
1799       else if (direction == TRUE) {
1800         if (tpl->tpl[NF9_OUT_VLAN].len)
1801           memcpy(&pdata->primitives.vlan_id, pptrs->f_data+tpl->tpl[NF9_OUT_VLAN].off, MIN(tpl->tpl[NF9_OUT_VLAN].len, 2));
1802         else if (tpl->tpl[NF9_POST_DOT1QVLANID].len)
1803           memcpy(&pdata->primitives.vlan_id, pptrs->f_data+tpl->tpl[NF9_POST_DOT1QVLANID].off, MIN(tpl->tpl[NF9_POST_DOT1QVLANID].len, 2));
1804       }
1805     }
1806     else {
1807       if (tpl->tpl[NF9_IN_VLAN].len)
1808         memcpy(&pdata->primitives.vlan_id, pptrs->f_data+tpl->tpl[NF9_IN_VLAN].off, MIN(tpl->tpl[NF9_IN_VLAN].len, 2));
1809       else if (tpl->tpl[NF9_OUT_VLAN].len)
1810         memcpy(&pdata->primitives.vlan_id, pptrs->f_data+tpl->tpl[NF9_OUT_VLAN].off, MIN(tpl->tpl[NF9_OUT_VLAN].len, 2));
1811       else if (tpl->tpl[NF9_DOT1QVLANID].len)
1812         memcpy(&pdata->primitives.vlan_id, pptrs->f_data+tpl->tpl[NF9_DOT1QVLANID].off, MIN(tpl->tpl[NF9_DOT1QVLANID].len, 2));
1813       else if (tpl->tpl[NF9_POST_DOT1QVLANID].len)
1814         memcpy(&pdata->primitives.vlan_id, pptrs->f_data+tpl->tpl[NF9_POST_DOT1QVLANID].off, MIN(tpl->tpl[NF9_POST_DOT1QVLANID].len, 2));
1815       else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len) {
1816         vlan_handler(chptr, pptrs, data);
1817 	break;
1818       }
1819     }
1820 
1821     pdata->primitives.vlan_id = ntohs(pdata->primitives.vlan_id);
1822     break;
1823   default:
1824     break;
1825   }
1826 }
1827 
NF_cos_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1828 void NF_cos_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1829 {
1830   struct pkt_data *pdata = (struct pkt_data *) *data;
1831   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1832   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1833 
1834   switch(hdr->version) {
1835   case 10:
1836   case 9:
1837     if (tpl->tpl[NF9_DOT1QPRIORITY].len)
1838       memcpy(&pdata->primitives.cos, pptrs->f_data+tpl->tpl[NF9_DOT1QPRIORITY].off, MIN(tpl->tpl[NF9_DOT1QPRIORITY].len, 1));
1839     else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
1840       cos_handler(chptr, pptrs, data);
1841 
1842     break;
1843   default:
1844     break;
1845   }
1846 }
1847 
NF_etype_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1848 void NF_etype_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1849 {
1850   struct pkt_data *pdata = (struct pkt_data *) *data;
1851   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1852   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1853 
1854   switch(hdr->version) {
1855   case 10:
1856   case 9:
1857     if (tpl->tpl[NF9_ETHERTYPE].len == 2) {
1858       memcpy(&pdata->primitives.etype, pptrs->f_data+tpl->tpl[NF9_ETHERTYPE].off, MIN(tpl->tpl[NF9_ETHERTYPE].len, 2));
1859       pdata->primitives.etype = ntohs(pdata->primitives.etype);
1860     }
1861     else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
1862       etype_handler(chptr, pptrs, data);
1863     else
1864       pdata->primitives.etype = pptrs->l3_proto;
1865 
1866     break;
1867   default:
1868     pdata->primitives.etype = pptrs->l3_proto;
1869     break;
1870   }
1871 }
1872 #endif
1873 
NF_src_host_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1874 void NF_src_host_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1875 {
1876   struct pkt_data *pdata = (struct pkt_data *) *data;
1877   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1878   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1879 
1880   switch(hdr->version) {
1881   case 10:
1882   case 9:
1883     if (pptrs->l3_proto == ETHERTYPE_IP || pptrs->flow_type == NF9_FTYPE_NAT_EVENT /* NAT64 case */) {
1884       if (tpl->tpl[NF9_IPV4_SRC_ADDR].len) {
1885         memcpy(&pdata->primitives.src_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_IPV4_SRC_ADDR].off, MIN(tpl->tpl[NF9_IPV4_SRC_ADDR].len, 4));
1886         pdata->primitives.src_ip.family = AF_INET;
1887       }
1888       else if (tpl->tpl[NF9_IPV4_SRC_PREFIX].len) {
1889         memcpy(&pdata->primitives.src_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_IPV4_SRC_PREFIX].off, MIN(tpl->tpl[NF9_IPV4_SRC_PREFIX].len, 4));
1890         pdata->primitives.src_ip.family = AF_INET;
1891       }
1892       else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
1893 	src_host_handler(chptr, pptrs, data);
1894     }
1895     if (pptrs->l3_proto == ETHERTYPE_IPV6 || pptrs->flow_type == NF9_FTYPE_NAT_EVENT /* NAT64 case */) {
1896       if (tpl->tpl[NF9_IPV6_SRC_ADDR].len) {
1897 	memcpy(&pdata->primitives.src_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_SRC_ADDR].off, MIN(tpl->tpl[NF9_IPV6_SRC_ADDR].len, 16));
1898         pdata->primitives.src_ip.family = AF_INET6;
1899       }
1900       else if (tpl->tpl[NF9_IPV6_SRC_PREFIX].len) {
1901 	memcpy(&pdata->primitives.src_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_SRC_PREFIX].off, MIN(tpl->tpl[NF9_IPV6_SRC_PREFIX].len, 16));
1902         pdata->primitives.src_ip.family = AF_INET6;
1903       }
1904       else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
1905 	src_host_handler(chptr, pptrs, data);
1906     }
1907     break;
1908   case 5:
1909     pdata->primitives.src_ip.address.ipv4.s_addr = ((struct struct_export_v5 *) pptrs->f_data)->srcaddr.s_addr;
1910     pdata->primitives.src_ip.family = AF_INET;
1911     break;
1912   default:
1913     break;
1914   }
1915 }
1916 
NF_dst_host_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1917 void NF_dst_host_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1918 {
1919   struct pkt_data *pdata = (struct pkt_data *) *data;
1920   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1921   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1922 
1923   switch(hdr->version) {
1924   case 10:
1925   case 9:
1926     if (pptrs->l3_proto == ETHERTYPE_IP || pptrs->flow_type == NF9_FTYPE_NAT_EVENT /* NAT64 case */) {
1927       if (tpl->tpl[NF9_IPV4_DST_ADDR].len) {
1928         memcpy(&pdata->primitives.dst_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_IPV4_DST_ADDR].off, MIN(tpl->tpl[NF9_IPV4_DST_ADDR].len, 4));
1929         pdata->primitives.dst_ip.family = AF_INET;
1930       }
1931       else if (tpl->tpl[NF9_IPV4_DST_PREFIX].len) {
1932         memcpy(&pdata->primitives.dst_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_IPV4_DST_PREFIX].off, MIN(tpl->tpl[NF9_IPV4_DST_PREFIX].len, 4));
1933         pdata->primitives.dst_ip.family = AF_INET;
1934       }
1935       else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
1936 	dst_host_handler(chptr, pptrs, data);
1937     }
1938     if (pptrs->l3_proto == ETHERTYPE_IPV6 || pptrs->flow_type == NF9_FTYPE_NAT_EVENT /* NAT64 case */) {
1939       if (tpl->tpl[NF9_IPV6_DST_ADDR].len) {
1940         memcpy(&pdata->primitives.dst_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_DST_ADDR].off, MIN(tpl->tpl[NF9_IPV6_DST_ADDR].len, 16));
1941         pdata->primitives.dst_ip.family = AF_INET6;
1942       }
1943       else if (tpl->tpl[NF9_IPV6_DST_PREFIX].len) {
1944         memcpy(&pdata->primitives.dst_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_DST_PREFIX].off, MIN(tpl->tpl[NF9_IPV6_DST_PREFIX].len, 16));
1945         pdata->primitives.dst_ip.family = AF_INET6;
1946       }
1947       else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
1948 	dst_host_handler(chptr, pptrs, data);
1949     }
1950     break;
1951   case 5:
1952     pdata->primitives.dst_ip.address.ipv4.s_addr = ((struct struct_export_v5 *) pptrs->f_data)->dstaddr.s_addr;
1953     pdata->primitives.dst_ip.family = AF_INET;
1954     break;
1955   default:
1956     break;
1957   }
1958 }
1959 
NF_src_nmask_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1960 void NF_src_nmask_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1961 {
1962   struct pkt_data *pdata = (struct pkt_data *) *data;
1963   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1964   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1965 
1966   /* check network-related primitives against fallback scenarios */
1967   if (!evaluate_lm_method(pptrs, FALSE, chptr->plugin->cfg.nfacctd_net, NF_NET_KEEP)) return;
1968 
1969   switch(hdr->version) {
1970   case 10:
1971   case 9:
1972     if (pptrs->l3_proto == ETHERTYPE_IP) {
1973       if (tpl->tpl[NF9_SRC_MASK].len)
1974         memcpy(&pdata->primitives.src_nmask, pptrs->f_data+tpl->tpl[NF9_SRC_MASK].off, tpl->tpl[NF9_SRC_MASK].len);
1975     }
1976     else if (pptrs->l3_proto == ETHERTYPE_IPV6) {
1977       if (tpl->tpl[NF9_IPV6_SRC_MASK].len)
1978         memcpy(&pdata->primitives.src_nmask, pptrs->f_data+tpl->tpl[NF9_IPV6_SRC_MASK].off, tpl->tpl[NF9_IPV6_SRC_MASK].len);
1979     }
1980     break;
1981   case 5:
1982     pdata->primitives.src_nmask = ((struct struct_export_v5 *) pptrs->f_data)->src_mask;
1983     break;
1984   default:
1985     break;
1986   }
1987 }
1988 
NF_dst_nmask_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)1989 void NF_dst_nmask_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
1990 {
1991   struct pkt_data *pdata = (struct pkt_data *) *data;
1992   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
1993   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
1994 
1995   /* check network-related primitives against fallback scenarios */
1996   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_net, NF_NET_KEEP)) return;
1997 
1998   switch(hdr->version) {
1999   case 10:
2000   case 9:
2001     if (pptrs->l3_proto == ETHERTYPE_IP) {
2002       if (tpl->tpl[NF9_DST_MASK].len)
2003         memcpy(&pdata->primitives.dst_nmask, pptrs->f_data+tpl->tpl[NF9_DST_MASK].off, tpl->tpl[NF9_DST_MASK].len);
2004     }
2005     else if (pptrs->l3_proto == ETHERTYPE_IPV6) {
2006       if (tpl->tpl[NF9_IPV6_DST_MASK].len)
2007         memcpy(&pdata->primitives.dst_nmask, pptrs->f_data+tpl->tpl[NF9_IPV6_DST_MASK].off, tpl->tpl[NF9_IPV6_DST_MASK].len);
2008     }
2009     break;
2010   case 5:
2011     pdata->primitives.dst_nmask = ((struct struct_export_v5 *) pptrs->f_data)->dst_mask;
2012     break;
2013   default:
2014     break;
2015   }
2016 }
2017 
NF_src_as_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2018 void NF_src_as_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2019 {
2020   struct pkt_data *pdata = (struct pkt_data *) *data;
2021   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2022   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2023   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
2024   u_int16_t asn16 = 0;
2025   u_int32_t asn32 = 0;
2026 
2027   /* check network-related primitives against fallback scenarios */
2028   if (!evaluate_lm_method(pptrs, FALSE, chptr->plugin->cfg.nfacctd_as, NF_AS_KEEP)) return;
2029 
2030   switch(hdr->version) {
2031   case 10:
2032   case 9:
2033     if (tpl->tpl[NF9_SRC_AS].len == 2) {
2034       memcpy(&asn16, pptrs->f_data+tpl->tpl[NF9_SRC_AS].off, 2);
2035       pdata->primitives.src_as = ntohs(asn16);
2036     }
2037     else if (tpl->tpl[NF9_SRC_AS].len == 4) {
2038       memcpy(&asn32, pptrs->f_data+tpl->tpl[NF9_SRC_AS].off, 4);
2039       pdata->primitives.src_as = ntohl(asn32);
2040     }
2041     break;
2042   case 5:
2043     pdata->primitives.src_as = ntohs(((struct struct_export_v5 *) pptrs->f_data)->src_as);
2044     break;
2045   default:
2046     break;
2047   }
2048 
2049   if (chptr->plugin->cfg.nfprobe_peer_as) {
2050     if (chptr->aggregation & COUNT_PEER_SRC_AS) pbgp->peer_src_as = pdata->primitives.src_as;
2051     pdata->primitives.src_as = 0;
2052   }
2053 }
2054 
NF_dst_as_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2055 void NF_dst_as_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2056 {
2057   struct pkt_data *pdata = (struct pkt_data *) *data;
2058   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2059   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2060   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
2061   u_int16_t asn16 = 0;
2062   u_int32_t asn32 = 0;
2063 
2064   /* check network-related primitives against fallback scenarios */
2065   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_as, NF_AS_KEEP)) return;
2066 
2067   switch(hdr->version) {
2068   case 10:
2069   case 9:
2070     if (tpl->tpl[NF9_DST_AS].len == 2) {
2071       memcpy(&asn16, pptrs->f_data+tpl->tpl[NF9_DST_AS].off, 2);
2072       pdata->primitives.dst_as = ntohs(asn16);
2073     }
2074     else if (tpl->tpl[NF9_DST_AS].len == 4) {
2075       memcpy(&asn32, pptrs->f_data+tpl->tpl[NF9_DST_AS].off, 4);
2076       pdata->primitives.dst_as = ntohl(asn32);
2077     }
2078     break;
2079   case 5:
2080     pdata->primitives.dst_as = ntohs(((struct struct_export_v5 *) pptrs->f_data)->dst_as);
2081     break;
2082   default:
2083     break;
2084   }
2085 
2086   if (chptr->plugin->cfg.nfprobe_peer_as) {
2087     if (chptr->aggregation & COUNT_PEER_DST_AS) pbgp->peer_dst_as = pdata->primitives.dst_as;
2088     pdata->primitives.dst_as = 0;
2089   }
2090 }
2091 
NF_peer_src_as_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2092 void NF_peer_src_as_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2093 {
2094   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2095   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2096   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
2097   u_int16_t asn16 = 0;
2098   u_int32_t asn32 = 0;
2099 
2100   /* check network-related primitives against fallback scenarios */
2101   if (!evaluate_lm_method(pptrs, FALSE, chptr->plugin->cfg.nfacctd_as, NF_AS_KEEP)) return;
2102 
2103   switch (hdr->version) {
2104   case 10:
2105   case 9:
2106     if (tpl->tpl[NF9_PEER_SRC_AS].len == 2) {
2107       memcpy(&asn16, pptrs->f_data+tpl->tpl[NF9_PEER_SRC_AS].off, 2);
2108       pbgp->peer_src_as = ntohs(asn16);
2109     }
2110     else if (tpl->tpl[NF9_PEER_SRC_AS].len == 4) {
2111       memcpy(&asn32, pptrs->f_data+tpl->tpl[NF9_PEER_SRC_AS].off, 4);
2112       pbgp->peer_src_as = ntohl(asn32);
2113     }
2114     break;
2115   default:
2116     break;
2117   }
2118 }
2119 
NF_peer_dst_as_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2120 void NF_peer_dst_as_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2121 {
2122   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2123   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2124   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
2125   u_int16_t asn16 = 0;
2126   u_int32_t asn32 = 0;
2127 
2128   /* check network-related primitives against fallback scenarios */
2129   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_as, NF_AS_KEEP)) return;
2130 
2131   switch (hdr->version) {
2132   case 10:
2133   case 9:
2134     if (tpl->tpl[NF9_PEER_DST_AS].len == 2) {
2135       memcpy(&asn16, pptrs->f_data+tpl->tpl[NF9_PEER_DST_AS].off, 2);
2136       pbgp->peer_dst_as = ntohs(asn16);
2137     }
2138     else if (tpl->tpl[NF9_PEER_DST_AS].len == 4) {
2139       memcpy(&asn32, pptrs->f_data+tpl->tpl[NF9_PEER_DST_AS].off, 4);
2140       pbgp->peer_dst_as = ntohl(asn32);
2141     }
2142     break;
2143   default:
2144     break;
2145   }
2146 }
2147 
NF_peer_src_ip_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2148 void NF_peer_src_ip_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2149 {
2150   struct xflow_status_entry *entry = (struct xflow_status_entry *) pptrs->f_status;
2151   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2152   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2153   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
2154   struct sockaddr *sa = (struct sockaddr *) pptrs->f_agent;
2155 
2156   /* 1) NF9_EXPORTER_IPV[46]_ADDRESS from NetFlow v9/IPFIX options */
2157   if (entry->exp_addr.family) {
2158     memcpy(&pbgp->peer_src_ip, &entry->exp_addr, sizeof(struct host_addr));
2159   }
2160   /* 2) Socket IP address */
2161   else {
2162     if (sa->sa_family == AF_INET) {
2163       pbgp->peer_src_ip.address.ipv4.s_addr = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
2164       pbgp->peer_src_ip.family = AF_INET;
2165     }
2166     else if (sa->sa_family == AF_INET6) {
2167       memcpy(&pbgp->peer_src_ip.address.ipv6, &((struct sockaddr_in6 *)sa)->sin6_addr, IP6AddrSz);
2168       pbgp->peer_src_ip.family = AF_INET6;
2169     }
2170   }
2171 
2172   /* 3) NetFlow v9/IPFIX inline NF9_EXPORTER_IPV[46]_ADDRESS */
2173   if (!pbgp->peer_src_ip.family) {
2174     switch (hdr->version) {
2175     case 10:
2176     case 9:
2177       if (tpl->tpl[NF9_EXPORTER_IPV4_ADDRESS].len) {
2178 	memcpy(&pbgp->peer_src_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_EXPORTER_IPV4_ADDRESS].off, MIN(tpl->tpl[NF9_EXPORTER_IPV4_ADDRESS].len, 4));
2179 	pbgp->peer_src_ip.family = AF_INET;
2180       }
2181       else if (tpl->tpl[NF9_EXPORTER_IPV6_ADDRESS].len) {
2182 	memcpy(&pbgp->peer_src_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_EXPORTER_IPV6_ADDRESS].off, MIN(tpl->tpl[NF9_EXPORTER_IPV6_ADDRESS].len, 16));
2183 	pbgp->peer_src_ip.family = AF_INET6;
2184       }
2185     }
2186   }
2187 }
2188 
NF_peer_dst_ip_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2189 void NF_peer_dst_ip_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2190 {
2191   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2192   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2193   struct pkt_bgp_primitives *pbgp;
2194   int use_ip_next_hop = FALSE;
2195 
2196   /* we determine if this is called by exec_plugins() or bgp_srcdst_lookup() */
2197   if (chptr) {
2198     pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
2199     use_ip_next_hop = chptr->plugin->cfg.use_ip_next_hop;
2200 
2201     /* check network-related primitives against fallback scenarios */
2202     if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_net, NF_NET_KEEP)) return;
2203   }
2204   else {
2205     pbgp = (struct pkt_bgp_primitives *) (*data);
2206     use_ip_next_hop = config.use_ip_next_hop;
2207   }
2208 
2209   switch(hdr->version) {
2210   case 10:
2211   case 9:
2212     if (tpl->tpl[NF9_BGP_IPV4_NEXT_HOP].len) {
2213       memcpy(&pbgp->peer_dst_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_BGP_IPV4_NEXT_HOP].off, MIN(tpl->tpl[NF9_BGP_IPV4_NEXT_HOP].len, 4));
2214       pbgp->peer_dst_ip.family = AF_INET;
2215     }
2216     else if (tpl->tpl[NF9_MPLS_TOP_LABEL_ADDR].len) {
2217       memcpy(&pbgp->peer_dst_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_MPLS_TOP_LABEL_ADDR].off, MIN(tpl->tpl[NF9_MPLS_TOP_LABEL_ADDR].len, 4));
2218       pbgp->peer_dst_ip.family = AF_INET;
2219     }
2220     else if (tpl->tpl[NF9_IPV4_NEXT_HOP].len) {
2221       if (use_ip_next_hop) {
2222         memcpy(&pbgp->peer_dst_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_IPV4_NEXT_HOP].off, MIN(tpl->tpl[NF9_IPV4_NEXT_HOP].len, 4));
2223         pbgp->peer_dst_ip.family = AF_INET;
2224       }
2225     }
2226     else if (tpl->tpl[NF9_BGP_IPV6_NEXT_HOP].len) {
2227       memcpy(&pbgp->peer_dst_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_BGP_IPV6_NEXT_HOP].off, MIN(tpl->tpl[NF9_BGP_IPV6_NEXT_HOP].len, 16));
2228       pbgp->peer_dst_ip.family = AF_INET6;
2229     }
2230     else if (tpl->tpl[NF9_MPLS_TOP_LABEL_IPV6_ADDR].len) {
2231       memcpy(&pbgp->peer_dst_ip.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));
2232       pbgp->peer_dst_ip.family = AF_INET6;
2233     }
2234     else if (tpl->tpl[NF9_IPV6_NEXT_HOP].len) {
2235       if (use_ip_next_hop) {
2236 	memcpy(&pbgp->peer_dst_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_NEXT_HOP].off, MIN(tpl->tpl[NF9_IPV6_NEXT_HOP].len, 16));
2237 	pbgp->peer_dst_ip.family = AF_INET6;
2238       }
2239     }
2240     break;
2241   case 5:
2242     if (use_ip_next_hop) {
2243       pbgp->peer_dst_ip.address.ipv4.s_addr = ((struct struct_export_v5 *) pptrs->f_data)->nexthop.s_addr;
2244       pbgp->peer_dst_ip.family = AF_INET;
2245     }
2246     break;
2247   default:
2248     break;
2249   }
2250 }
2251 
NF_src_port_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2252 void NF_src_port_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2253 {
2254   struct pkt_data *pdata = (struct pkt_data *) *data;
2255   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2256   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2257   u_int8_t l4_proto = 0;
2258 
2259   switch(hdr->version) {
2260   case 10:
2261   case 9:
2262     if (tpl->tpl[NF9_L4_PROTOCOL].len == 1)
2263       memcpy(&l4_proto, pptrs->f_data+tpl->tpl[NF9_L4_PROTOCOL].off, 1);
2264 
2265     if (tpl->tpl[NF9_L4_SRC_PORT].len)
2266       memcpy(&pdata->primitives.src_port, pptrs->f_data+tpl->tpl[NF9_L4_SRC_PORT].off, MIN(tpl->tpl[NF9_L4_SRC_PORT].len, 2));
2267     else if (tpl->tpl[NF9_UDP_SRC_PORT].len)
2268       memcpy(&pdata->primitives.src_port, pptrs->f_data+tpl->tpl[NF9_UDP_SRC_PORT].off, MIN(tpl->tpl[NF9_UDP_SRC_PORT].len, 2));
2269     else if (tpl->tpl[NF9_TCP_SRC_PORT].len)
2270       memcpy(&pdata->primitives.src_port, pptrs->f_data+tpl->tpl[NF9_TCP_SRC_PORT].off, MIN(tpl->tpl[NF9_TCP_SRC_PORT].len, 2));
2271     else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len) {
2272       src_port_handler(chptr, pptrs, data);
2273       break;
2274     }
2275 
2276     pdata->primitives.src_port = ntohs(pdata->primitives.src_port);
2277     break;
2278   case 5:
2279     if ((((struct struct_export_v5 *) pptrs->f_data)->prot == IPPROTO_UDP) ||
2280         ((struct struct_export_v5 *) pptrs->f_data)->prot == IPPROTO_TCP) {
2281       pdata->primitives.src_port = ntohs(((struct struct_export_v5 *) pptrs->f_data)->srcport);
2282     }
2283     else pdata->primitives.src_port = 0;
2284     break;
2285   default:
2286     break;
2287   }
2288 }
2289 
NF_dst_port_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2290 void NF_dst_port_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2291 {
2292   struct pkt_data *pdata = (struct pkt_data *) *data;
2293   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2294   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2295   u_int8_t l4_proto = 0;
2296 
2297   switch(hdr->version) {
2298   case 10:
2299   case 9:
2300     if (tpl->tpl[NF9_L4_PROTOCOL].len == 1)
2301       memcpy(&l4_proto, pptrs->f_data+tpl->tpl[NF9_L4_PROTOCOL].off, 1);
2302 
2303     if (tpl->tpl[NF9_L4_DST_PORT].len)
2304       memcpy(&pdata->primitives.dst_port, pptrs->f_data+tpl->tpl[NF9_L4_DST_PORT].off, MIN(tpl->tpl[NF9_L4_DST_PORT].len, 2));
2305     else if (tpl->tpl[NF9_UDP_DST_PORT].len)
2306       memcpy(&pdata->primitives.dst_port, pptrs->f_data+tpl->tpl[NF9_UDP_DST_PORT].off, MIN(tpl->tpl[NF9_UDP_DST_PORT].len, 2));
2307     else if (tpl->tpl[NF9_TCP_DST_PORT].len)
2308       memcpy(&pdata->primitives.dst_port, pptrs->f_data+tpl->tpl[NF9_TCP_DST_PORT].off, MIN(tpl->tpl[NF9_TCP_DST_PORT].len, 2));
2309     else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len) {
2310       dst_port_handler(chptr, pptrs, data);
2311       break;
2312     }
2313 
2314     pdata->primitives.dst_port = ntohs(pdata->primitives.dst_port);
2315     break;
2316   case 5:
2317     if ((((struct struct_export_v5 *) pptrs->f_data)->prot == IPPROTO_UDP) ||
2318         ((struct struct_export_v5 *) pptrs->f_data)->prot == IPPROTO_TCP)
2319       pdata->primitives.dst_port = ntohs(((struct struct_export_v5 *) pptrs->f_data)->dstport);
2320     else pdata->primitives.dst_port = 0;
2321     break;
2322   default:
2323     break;
2324   }
2325 }
2326 
NF_ip_tos_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2327 void NF_ip_tos_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2328 {
2329   struct pkt_data *pdata = (struct pkt_data *) *data;
2330   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2331   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2332 
2333   /* setting tos from pre_tag_map */
2334   if (pptrs->set_tos.set) {
2335     pdata->primitives.tos = pptrs->set_tos.n;
2336     return;
2337   }
2338 
2339   switch(hdr->version) {
2340   case 10:
2341   case 9:
2342     if (tpl->tpl[NF9_SRC_TOS].len)
2343       memcpy(&pdata->primitives.tos, pptrs->f_data+tpl->tpl[NF9_SRC_TOS].off, MIN(tpl->tpl[NF9_SRC_TOS].len, 1));
2344     else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
2345       ip_tos_handler(chptr, pptrs, data);
2346 
2347     break;
2348   case 5:
2349     pdata->primitives.tos = ((struct struct_export_v5 *) pptrs->f_data)->tos;
2350     break;
2351   default:
2352     break;
2353   }
2354 }
2355 
NF_ip_proto_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2356 void NF_ip_proto_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2357 {
2358   struct pkt_data *pdata = (struct pkt_data *) *data;
2359   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2360   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2361 
2362   switch(hdr->version) {
2363   case 10:
2364   case 9:
2365     if (tpl->tpl[NF9_L4_PROTOCOL].len)
2366       memcpy(&pdata->primitives.proto, pptrs->f_data+tpl->tpl[NF9_L4_PROTOCOL].off, MIN(tpl->tpl[NF9_L4_PROTOCOL].len, 1));
2367     else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
2368       ip_proto_handler(chptr, pptrs, data);
2369 
2370     break;
2371   case 5:
2372     pdata->primitives.proto = ((struct struct_export_v5 *) pptrs->f_data)->prot;
2373     break;
2374   default:
2375     break;
2376   }
2377 }
2378 
NF_tcp_flags_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2379 void NF_tcp_flags_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2380 {
2381   struct pkt_data *pdata = (struct pkt_data *) *data;
2382   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2383   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2384   u_int8_t tcp_flags = 0;
2385 
2386   switch(hdr->version) {
2387   case 10:
2388   case 9:
2389     if (tpl->tpl[NF9_TCP_FLAGS].len == 1) {
2390       memcpy(&tcp_flags, pptrs->f_data+tpl->tpl[NF9_TCP_FLAGS].off, MIN(tpl->tpl[NF9_TCP_FLAGS].len, 1));
2391       pdata->tcp_flags = tcp_flags;
2392     }
2393     else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
2394       tcp_flags_handler(chptr, pptrs, data);
2395 
2396     break;
2397   case 5:
2398     if (((struct struct_export_v5 *) pptrs->f_data)->prot == IPPROTO_TCP && hdr->version == 5)
2399       pdata->tcp_flags = ((struct struct_export_v5 *) pptrs->f_data)->tcp_flags;
2400     break;
2401   default:
2402     break;
2403   }
2404 }
2405 
NF_counters_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2406 void NF_counters_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2407 {
2408   struct pkt_data *pdata = (struct pkt_data *) *data;
2409   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2410   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2411   u_int32_t t32 = 0;
2412   u_int64_t t64 = 0;
2413 
2414   switch(hdr->version) {
2415   case 10:
2416   case 9:
2417     if (tpl->tpl[NF9_IN_BYTES].len == 4) {
2418       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_IN_BYTES].off, 4);
2419       pdata->pkt_len = ntohl(t32);
2420     }
2421     else if (tpl->tpl[NF9_IN_BYTES].len == 8) {
2422       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_IN_BYTES].off, 8);
2423       pdata->pkt_len = pm_ntohll(t64);
2424     }
2425     else if (tpl->tpl[NF9_FLOW_BYTES].len == 4) {
2426       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_FLOW_BYTES].off, 4);
2427       pdata->pkt_len = ntohl(t32);
2428     }
2429     else if (tpl->tpl[NF9_FLOW_BYTES].len == 8) {
2430       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_FLOW_BYTES].off, 8);
2431       pdata->pkt_len = pm_ntohll(t64);
2432     }
2433     else if (tpl->tpl[NF9_OUT_BYTES].len == 4) {
2434       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_OUT_BYTES].off, 4);
2435       pdata->pkt_len = ntohl(t32);
2436     }
2437     else if (tpl->tpl[NF9_OUT_BYTES].len == 8) {
2438       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_OUT_BYTES].off, 8);
2439       pdata->pkt_len = pm_ntohll(t64);
2440     }
2441     else if (tpl->tpl[NF9_LAYER2OCTETDELTACOUNT].len == 8) {
2442       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_LAYER2OCTETDELTACOUNT].off, 8);
2443       pdata->pkt_len = pm_ntohll(t64);
2444     }
2445     else if (tpl->tpl[NF9_INITIATOR_OCTETS].len == 4) {
2446       if (chptr->plugin->cfg.tmp_asa_bi_flow) {
2447         memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_INITIATOR_OCTETS].off, 4);
2448         pdata->pkt_len = ntohl(t32);
2449       }
2450     }
2451 
2452     if (tpl->tpl[NF9_IN_PACKETS].len == 4) {
2453       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_IN_PACKETS].off, 4);
2454       pdata->pkt_num = ntohl(t32);
2455     }
2456     else if (tpl->tpl[NF9_IN_PACKETS].len == 8) {
2457       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_IN_PACKETS].off, 8);
2458       pdata->pkt_num = pm_ntohll(t64);
2459     }
2460     else if (tpl->tpl[NF9_FLOW_PACKETS].len == 4) {
2461       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_FLOW_PACKETS].off, 4);
2462       pdata->pkt_num = ntohl(t32);
2463     }
2464     else if (tpl->tpl[NF9_FLOW_PACKETS].len == 8) {
2465       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_FLOW_PACKETS].off, 8);
2466       pdata->pkt_num = pm_ntohll(t64);
2467     }
2468     else if (tpl->tpl[NF9_OUT_PACKETS].len == 4) {
2469       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_OUT_PACKETS].off, 4);
2470       pdata->pkt_num = ntohl(t32);
2471     }
2472     else if (tpl->tpl[NF9_OUT_PACKETS].len == 8) {
2473       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_OUT_PACKETS].off, 8);
2474       pdata->pkt_num = pm_ntohll(t64);
2475     }
2476     else if (tpl->tpl[NF9_RESPONDER_OCTETS].len == 4) {
2477       if (chptr->plugin->cfg.tmp_asa_bi_flow) {
2478         memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_RESPONDER_OCTETS].off, 4);
2479         pdata->pkt_num = ntohl(t32);
2480       }
2481     }
2482 
2483     if (!pdata->pkt_len && !pdata->pkt_num) {
2484       if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
2485 	counters_handler(chptr, pptrs, data);
2486     }
2487 
2488     break;
2489   case 5:
2490     pdata->pkt_len = ntohl(((struct struct_export_v5 *) pptrs->f_data)->dOctets);
2491     pdata->pkt_num = ntohl(((struct struct_export_v5 *) pptrs->f_data)->dPkts);
2492     break;
2493   default:
2494     break;
2495   }
2496 
2497   pdata->flow_type = pptrs->flow_type;
2498 }
2499 
2500 /* times from the netflow engine are in msecs */
NF_time_msecs_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2501 void NF_time_msecs_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2502 {
2503   struct pkt_data *pdata = (struct pkt_data *) *data;
2504   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2505   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2506   time_t fstime = 0;
2507   u_int32_t t32 = 0;
2508   u_int64_t t64 = 0;
2509 
2510   switch(hdr->version) {
2511   case 10:
2512   case 9:
2513     if (tpl->tpl[NF9_FIRST_SWITCHED].len && hdr->version == 9) {
2514       memcpy(&fstime, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED].off, tpl->tpl[NF9_FIRST_SWITCHED].len);
2515       pdata->time_start.tv_sec = ntohl(((struct struct_header_v9 *) pptrs->f_header)->unix_secs)-
2516         ((ntohl(((struct struct_header_v9 *) pptrs->f_header)->SysUptime)-ntohl(fstime))/1000);
2517     }
2518     else if (tpl->tpl[NF9_FIRST_SWITCHED].len && hdr->version == 10) {
2519       if (tpl->tpl[NF9_SYS_UPTIME_MSEC].len == 8) {
2520         memcpy(&fstime, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED].off, tpl->tpl[NF9_FIRST_SWITCHED].len);
2521         memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_SYS_UPTIME_MSEC].off, tpl->tpl[NF9_SYS_UPTIME_MSEC].len);
2522         t32 = pm_ntohll(t64)/1000;
2523         pdata->time_start.tv_sec = t32+(ntohl(fstime)/1000);
2524       }
2525     }
2526     else if (tpl->tpl[NF9_FIRST_SWITCHED_MSEC].len) {
2527       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED_MSEC].off, tpl->tpl[NF9_FIRST_SWITCHED_MSEC].len);
2528       pdata->time_start.tv_sec = pm_ntohll(t64)/1000;
2529       pdata->time_start.tv_usec = (pm_ntohll(t64)%1000)*1000;
2530     }
2531     else if (tpl->tpl[NF9_FIRST_SWITCHED_USEC].len) {
2532       if (tpl->tpl[NF9_FIRST_SWITCHED_USEC].len == 16) {
2533 	memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED_USEC].off, 8);
2534         pdata->time_start.tv_sec = pm_ntohll(t64);
2535 	memcpy(&t64, (pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED_USEC].off+8), 8);
2536         pdata->time_start.tv_usec = pm_ntohll(t64);
2537       }
2538     }
2539     else if (tpl->tpl[NF9_OBSERVATION_TIME_MSEC].len) {
2540       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_OBSERVATION_TIME_MSEC].off, tpl->tpl[NF9_OBSERVATION_TIME_MSEC].len);
2541       pdata->time_start.tv_sec = pm_ntohll(t64)/1000;
2542       pdata->time_start.tv_usec = (pm_ntohll(t64)%1000)*1000;
2543     }
2544     /* sec handling here: msec vs sec restricted to NetFlow v5 */
2545     else if (tpl->tpl[NF9_FIRST_SWITCHED_SEC].len == 4) {
2546       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED_SEC].off, tpl->tpl[NF9_FIRST_SWITCHED_SEC].len);
2547       pdata->time_start.tv_sec = ntohl(t32);
2548     }
2549     else if (tpl->tpl[NF9_FIRST_SWITCHED_SEC].len == 8) {
2550       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED_SEC].off, tpl->tpl[NF9_FIRST_SWITCHED_SEC].len);
2551       pdata->time_start.tv_sec = pm_ntohll(t64);
2552     }
2553     else if (tpl->tpl[NF9_FIRST_SWITCHED_DELTA_MICRO].len && hdr->version == 10) {
2554       struct struct_header_ipfix *hdr_ipfix = (struct struct_header_ipfix *) pptrs->f_header;
2555       u_int32_t t32h = 0, h32h = 0;
2556       u_int64_t t64_1 = 0, t64_2 = 0;
2557 
2558       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED_DELTA_MICRO].off, tpl->tpl[NF9_FIRST_SWITCHED_DELTA_MICRO].len);
2559       t32h = ntohl(t32);
2560 
2561       h32h = ntohl(hdr_ipfix->unix_secs);
2562 
2563       t64 = h32h;
2564       t64 = t64 * 1000 * 1000;
2565       t64 -= t32h;
2566       t64_1 = (t64 / (1000 * 1000));
2567       t64_2 = (t64 % (1000 * 1000));
2568 
2569       pdata->time_start.tv_sec = t64_1;
2570       pdata->time_start.tv_usec = t64_2;
2571     }
2572 
2573     /* fallback to header timestamp if no other time reference is available */
2574     if (!pdata->time_start.tv_sec) {
2575       if (hdr->version == 10) {
2576         struct struct_header_ipfix *hdr_ipfix = (struct struct_header_ipfix *) pptrs->f_header;
2577 
2578         pdata->time_start.tv_sec = ntohl(hdr_ipfix->unix_secs);
2579       }
2580       else if (hdr->version == 9) {
2581         struct struct_header_v9 *hdr_v9 = (struct struct_header_v9 *) pptrs->f_header;
2582 
2583         pdata->time_start.tv_sec = ntohl(hdr_v9->unix_secs);
2584       }
2585     }
2586 
2587     if (tpl->tpl[NF9_LAST_SWITCHED].len && hdr->version == 9) {
2588       memcpy(&fstime, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED].off, tpl->tpl[NF9_LAST_SWITCHED].len);
2589       pdata->time_end.tv_sec = ntohl(((struct struct_header_v9 *) pptrs->f_header)->unix_secs)-
2590         ((ntohl(((struct struct_header_v9 *) pptrs->f_header)->SysUptime)-ntohl(fstime))/1000);
2591     }
2592     else if (tpl->tpl[NF9_LAST_SWITCHED].len && hdr->version == 10) {
2593       if (tpl->tpl[NF9_SYS_UPTIME_MSEC].len == 8) {
2594         memcpy(&fstime, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED].off, tpl->tpl[NF9_LAST_SWITCHED].len);
2595         memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_SYS_UPTIME_MSEC].off, tpl->tpl[NF9_SYS_UPTIME_MSEC].len);
2596         t32 = pm_ntohll(t64)/1000;
2597         pdata->time_end.tv_sec = t32+(ntohl(fstime)/1000);
2598       }
2599     }
2600     else if (tpl->tpl[NF9_LAST_SWITCHED_MSEC].len) {
2601       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED_MSEC].off, tpl->tpl[NF9_LAST_SWITCHED_MSEC].len);
2602       pdata->time_end.tv_sec = pm_ntohll(t64)/1000;
2603       pdata->time_end.tv_usec = (pm_ntohll(t64)%1000)*1000;
2604     }
2605     else if (tpl->tpl[NF9_LAST_SWITCHED_USEC].len) {
2606       if (tpl->tpl[NF9_LAST_SWITCHED_USEC].len == 16) {
2607 	memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED_USEC].off, 8);
2608         pdata->time_end.tv_sec = pm_ntohll(t64);
2609 	memcpy(&t64, (pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED_USEC].off+8), 8);
2610         pdata->time_end.tv_usec = pm_ntohll(t64);
2611       }
2612     }
2613     /* sec handling here: msec vs sec restricted to NetFlow v5 */
2614     else if (tpl->tpl[NF9_LAST_SWITCHED_SEC].len == 4) {
2615       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED_SEC].off, tpl->tpl[NF9_LAST_SWITCHED_SEC].len);
2616       pdata->time_end.tv_sec = ntohl(t32);
2617     }
2618     else if (tpl->tpl[NF9_LAST_SWITCHED_SEC].len == 8) {
2619       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED_SEC].off, tpl->tpl[NF9_LAST_SWITCHED_SEC].len);
2620       pdata->time_end.tv_sec = pm_ntohll(t64);
2621     }
2622     else if (tpl->tpl[NF9_LAST_SWITCHED_DELTA_MICRO].len && hdr->version == 10) {
2623       struct struct_header_ipfix *hdr_ipfix = (struct struct_header_ipfix *) pptrs->f_header;
2624       u_int32_t t32h = 0, h32h = 0;
2625       u_int64_t t64_1 = 0, t64_2 = 0;
2626 
2627       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED_DELTA_MICRO].off, tpl->tpl[NF9_LAST_SWITCHED_DELTA_MICRO].len);
2628       t32h = ntohl(t32);
2629 
2630       h32h = ntohl(hdr_ipfix->unix_secs);
2631 
2632       t64 = h32h;
2633       t64 = t64 * 1000 * 1000;
2634       t64 -= t32h;
2635       t64_1 = (t64 / (1000 * 1000));
2636       t64_2 = (t64 % (1000 * 1000));
2637 
2638       pdata->time_end.tv_sec = t64_1;
2639       pdata->time_end.tv_usec = t64_2;
2640     }
2641 
2642     break;
2643   case 5:
2644     pdata->time_start.tv_sec = ntohl(((struct struct_header_v5 *) pptrs->f_header)->unix_secs)-
2645       ((ntohl(((struct struct_header_v5 *) pptrs->f_header)->SysUptime))/1000)+
2646       ((ntohl(((struct struct_export_v5 *) pptrs->f_data)->First))/1000);
2647 
2648     pdata->time_end.tv_sec = ntohl(((struct struct_header_v5 *) pptrs->f_header)->unix_secs)-
2649       ((ntohl(((struct struct_header_v5 *) pptrs->f_header)->SysUptime))/1000)+
2650       ((ntohl(((struct struct_export_v5 *) pptrs->f_data)->Last))/1000);
2651 
2652     break;
2653   default:
2654     break;
2655   }
2656 
2657   pdata->flow_type = pptrs->flow_type;
2658 }
2659 
2660 /* times from the netflow engine are in secs */
NF_time_secs_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2661 void NF_time_secs_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2662 {
2663   struct pkt_data *pdata = (struct pkt_data *) *data;
2664   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2665   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2666   time_t fstime = 0;
2667 
2668   switch(hdr->version) {
2669   case 10:
2670   case 9:
2671     memcpy(&fstime, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED].off, tpl->tpl[NF9_FIRST_SWITCHED].len);
2672     pdata->time_start.tv_sec = ntohl(((struct struct_header_v9 *) pptrs->f_header)->unix_secs)-
2673       (ntohl(((struct struct_header_v9 *) pptrs->f_header)->SysUptime)-ntohl(fstime));
2674     memcpy(&fstime, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED].off, tpl->tpl[NF9_LAST_SWITCHED].len);
2675     pdata->time_end.tv_sec = ntohl(((struct struct_header_v9 *) pptrs->f_header)->unix_secs)-
2676       (ntohl(((struct struct_header_v9 *) pptrs->f_header)->SysUptime)-ntohl(fstime));
2677     break;
2678   case 5:
2679     pdata->time_start.tv_sec = ntohl(((struct struct_header_v5 *) pptrs->f_header)->unix_secs)-
2680       (ntohl(((struct struct_header_v5 *) pptrs->f_header)->SysUptime)-ntohl(((struct struct_export_v5 *) pptrs->f_data)->First));
2681     pdata->time_end.tv_sec = ntohl(((struct struct_header_v5 *) pptrs->f_header)->unix_secs)-
2682       (ntohl(((struct struct_header_v5 *) pptrs->f_header)->SysUptime)-ntohl(((struct struct_export_v5 *) pptrs->f_data)->Last));
2683     break;
2684   default:
2685     break;
2686   }
2687 
2688   pdata->flow_type = pptrs->flow_type;
2689 }
2690 
2691 /* ignore netflow engine times and generate new ones */
NF_time_new_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2692 void NF_time_new_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2693 {
2694   struct pkt_data *pdata = (struct pkt_data *) *data;
2695 
2696   pdata->time_start.tv_sec = 0;
2697   pdata->time_start.tv_usec = 0;
2698   pdata->time_end.tv_sec = 0;
2699   pdata->time_end.tv_usec = 0;
2700 
2701   pdata->flow_type = pptrs->flow_type;
2702 }
2703 
pre_tag_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2704 void pre_tag_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2705 {
2706   struct pkt_data *pdata = (struct pkt_data *) *data;
2707 
2708   pdata->primitives.tag = pptrs->tag;
2709 }
2710 
pre_tag2_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2711 void pre_tag2_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2712 {
2713   struct pkt_data *pdata = (struct pkt_data *) *data;
2714 
2715   pdata->primitives.tag2 = pptrs->tag2;
2716 }
2717 
pre_tag_label_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2718 void pre_tag_label_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2719 {
2720   struct pkt_vlen_hdr_primitives *pvlen = (struct pkt_vlen_hdr_primitives *) ((*data) + chptr->extras.off_pkt_vlen_hdr_primitives);
2721 
2722   if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + pptrs->label.len)) {
2723     vlen_prims_init(pvlen, 0);
2724     return;
2725   }
2726   else vlen_prims_insert(pvlen, COUNT_INT_LABEL, pptrs->label.len, (u_char *) pptrs->label.val, PM_MSG_STR_COPY);
2727 }
2728 
NF_flows_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2729 void NF_flows_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2730 {
2731   struct pkt_data *pdata = (struct pkt_data *) *data;
2732   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2733   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2734   u_int32_t t32 = 0;
2735   u_int64_t t64 = 0;
2736 
2737   switch(hdr->version) {
2738   case 10:
2739   case 9:
2740     if (tpl->tpl[NF9_FLOWS].len == 4) {
2741       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_FLOWS].off, 4);
2742       pdata->flo_num = ntohl(t32);
2743     }
2744     else if (tpl->tpl[NF9_FLOWS].len == 8) {
2745       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_FLOWS].off, 8);
2746       pdata->flo_num = pm_ntohll(t64);
2747     }
2748     if (!pdata->flo_num) pdata->flo_num = 1;
2749     break;
2750   case 5:
2751     pdata->flo_num = 1;
2752     break;
2753   default:
2754     break;
2755   }
2756 }
2757 
NF_in_iface_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2758 void NF_in_iface_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2759 {
2760   struct pkt_data *pdata = (struct pkt_data *) *data;
2761   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2762   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2763   u_int16_t iface16 = 0;
2764   u_int32_t iface32 = 0;
2765 
2766   switch(hdr->version) {
2767   case 10:
2768   case 9:
2769     if (tpl->tpl[NF9_INPUT_SNMP].len == 2) {
2770       memcpy(&iface16, pptrs->f_data+tpl->tpl[NF9_INPUT_SNMP].off, 2);
2771       pdata->primitives.ifindex_in = ntohs(iface16);
2772     }
2773     else if (tpl->tpl[NF9_INPUT_SNMP].len == 4) {
2774       memcpy(&iface32, pptrs->f_data+tpl->tpl[NF9_INPUT_SNMP].off, 4);
2775       pdata->primitives.ifindex_in = ntohl(iface32);
2776     }
2777     else if (tpl->tpl[NF9_INPUT_PHYSINT].len == 4) {
2778       memcpy(&iface32, pptrs->f_data+tpl->tpl[NF9_INPUT_PHYSINT].off, 4);
2779       pdata->primitives.ifindex_in = ntohl(iface32);
2780     }
2781     break;
2782   case 5:
2783     iface16 = ntohs(((struct struct_export_v5 *) pptrs->f_data)->input);
2784     pdata->primitives.ifindex_in = iface16;
2785     break;
2786   default:
2787     break;
2788   }
2789 }
2790 
NF_out_iface_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2791 void NF_out_iface_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2792 {
2793   struct pkt_data *pdata = (struct pkt_data *) *data;
2794   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2795   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2796   u_int16_t iface16 = 0;
2797   u_int32_t iface32 = 0;
2798 
2799   switch(hdr->version) {
2800   case 10:
2801   case 9:
2802     if (tpl->tpl[NF9_OUTPUT_SNMP].len == 2) {
2803       memcpy(&iface16, pptrs->f_data+tpl->tpl[NF9_OUTPUT_SNMP].off, 2);
2804       pdata->primitives.ifindex_out = ntohs(iface16);
2805     }
2806     else if (tpl->tpl[NF9_OUTPUT_SNMP].len == 4) {
2807       memcpy(&iface32, pptrs->f_data+tpl->tpl[NF9_OUTPUT_SNMP].off, 4);
2808       pdata->primitives.ifindex_out = ntohl(iface32);
2809     }
2810     else if (tpl->tpl[NF9_OUTPUT_PHYSINT].len == 4) {
2811       memcpy(&iface32, pptrs->f_data+tpl->tpl[NF9_OUTPUT_PHYSINT].off, 4);
2812       pdata->primitives.ifindex_out = ntohl(iface32);
2813     }
2814     break;
2815   case 5:
2816     iface16 = ntohs(((struct struct_export_v5 *) pptrs->f_data)->output);
2817     pdata->primitives.ifindex_out = iface16;
2818     break;
2819   default:
2820     break;
2821   }
2822 }
2823 
NF_sampling_rate_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2824 void NF_sampling_rate_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2825 {
2826   struct xflow_status_entry *xsentry = (struct xflow_status_entry *) pptrs->f_status;
2827   struct xflow_status_entry *entry = (struct xflow_status_entry *) pptrs->f_status;
2828   struct xflow_status_entry_sampling *sentry = NULL;
2829   struct pkt_data *pdata = (struct pkt_data *) *data;
2830   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2831   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2832   u_int16_t srate = 0;
2833   u_int16_t t16 = 0;
2834   u_int32_t sampler_id = 0, sample_pool = 0, t32 = 0;
2835   u_int8_t t8 = 0;
2836   u_int64_t t64 = 0;
2837 
2838   pdata->primitives.sampling_rate = 0; /* 0 = unknown */
2839 
2840   if (config.sampling_map) {
2841     if (sampling_map_caching && xsentry && timeval_cmp(&xsentry->st.stamp, &reload_map_tstamp) > 0) {
2842       pdata->primitives.sampling_rate = xsentry->st.tag;
2843     }
2844     else {
2845       find_id_func((struct id_table *)pptrs->sampling_table, pptrs, (pm_id_t *) &pdata->primitives.sampling_rate, NULL);
2846 
2847       if (xsentry) {
2848         xsentry->st.tag = pdata->primitives.sampling_rate;
2849         gettimeofday(&xsentry->st.stamp, NULL);
2850       }
2851     }
2852   }
2853 
2854   if (pdata->primitives.sampling_rate == 0) { /* 0 = still unknown */
2855     switch (hdr->version) {
2856     case 10:
2857     case 9:
2858       if (tpl->tpl[NF9_FLOW_SAMPLER_ID].len || tpl->tpl[NF9_SELECTOR_ID].len == 8) {
2859         if (tpl->tpl[NF9_FLOW_SAMPLER_ID].len == 1) {
2860           memcpy(&t8, pptrs->f_data+tpl->tpl[NF9_FLOW_SAMPLER_ID].off, 1);
2861           sampler_id = t8;
2862         }
2863         else if (tpl->tpl[NF9_FLOW_SAMPLER_ID].len == 2) {
2864           memcpy(&t16, pptrs->f_data+tpl->tpl[NF9_FLOW_SAMPLER_ID].off, 2);
2865           sampler_id = ntohs(t16);
2866         }
2867         else if (tpl->tpl[NF9_FLOW_SAMPLER_ID].len == 4) {
2868           memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_FLOW_SAMPLER_ID].off, 4);
2869           sampler_id = ntohl(t32);
2870         }
2871         else if (tpl->tpl[NF9_SELECTOR_ID].len == 8) {
2872           memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_SELECTOR_ID].off, 8);
2873           sampler_id = pm_ntohll(t64); /* XXX: sampler_id to be moved to 64 bit */
2874         }
2875 
2876         if (entry) {
2877 	  sentry = search_smp_id_status_table(entry->sampling, sampler_id, TRUE);
2878 	  if (!sentry && pptrs->f_status_g) {
2879 	    entry = (struct xflow_status_entry *) pptrs->f_status_g;
2880 	    sentry = search_smp_id_status_table(entry->sampling, sampler_id, FALSE);
2881 	  }
2882         }
2883         if (sentry) pdata->primitives.sampling_rate = sentry->sample_pool;
2884       }
2885       /* SAMPLING_INTERVAL part of the NetFlow v9/IPFIX record seems to be reality, ie. FlowMon by Invea-Tech */
2886       else if (tpl->tpl[NF9_SAMPLING_INTERVAL].len || tpl->tpl[NF9_FLOW_SAMPLER_INTERVAL].len) {
2887         if (tpl->tpl[NF9_SAMPLING_INTERVAL].len == 2) {
2888 	  memcpy(&t16, pptrs->f_data+tpl->tpl[NF9_SAMPLING_INTERVAL].off, 2);
2889 	  sample_pool = ntohs(t16);
2890         }
2891         else if (tpl->tpl[NF9_SAMPLING_INTERVAL].len == 4) {
2892 	  memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_SAMPLING_INTERVAL].off, 4);
2893 	  sample_pool = ntohl(t32);
2894         }
2895 
2896         if (tpl->tpl[NF9_FLOW_SAMPLER_INTERVAL].len == 2) {
2897 	  memcpy(&t16, pptrs->f_data+tpl->tpl[NF9_FLOW_SAMPLER_INTERVAL].off, 2);
2898 	  sample_pool = ntohs(t16);
2899         }
2900         else if (tpl->tpl[NF9_FLOW_SAMPLER_INTERVAL].len == 4) {
2901 	  memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_FLOW_SAMPLER_INTERVAL].off, 4);
2902           sample_pool = ntohl(t32);
2903         }
2904 
2905         pdata->primitives.sampling_rate = sample_pool;
2906       }
2907       /* case of no SAMPLER_ID, ALU & IPFIX */
2908       else {
2909         if (entry) {
2910           sentry = search_smp_id_status_table(entry->sampling, 0, TRUE);
2911           if (!sentry && pptrs->f_status_g) {
2912             entry = (struct xflow_status_entry *) pptrs->f_status_g;
2913             sentry = search_smp_id_status_table(entry->sampling, 0, FALSE);
2914           }
2915         }
2916         if (sentry) pdata->primitives.sampling_rate = sentry->sample_pool;
2917       }
2918       break;
2919     case 5:
2920       /* is_sampled = ( ntohs(hdr->sampling) & 0xC000 ); */
2921       srate = ( ntohs(hdr->sampling) & 0x3FFF );
2922       if (srate) pdata->primitives.sampling_rate = srate;
2923       break;
2924     default:
2925       break;
2926     }
2927   }
2928 
2929   if (config.sfacctd_renormalize && pdata->primitives.sampling_rate)
2930     pdata->primitives.sampling_rate = 1; /* already renormalized */
2931 }
2932 
NF_sampling_direction_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2933 void NF_sampling_direction_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2934 {
2935   struct pkt_data *pdata = (struct pkt_data *) *data;
2936   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2937   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2938   u_int8_t direction8;
2939   int direction = ERR;
2940 
2941   switch(hdr->version) {
2942   case 10:
2943   case 9:
2944     if (tpl->tpl[NF9_DIRECTION].len == 1) {
2945       memcpy(&direction8, pptrs->f_data+tpl->tpl[NF9_DIRECTION].off, 1);
2946       direction = direction8;
2947     }
2948     break;
2949   default:
2950     break;
2951   }
2952 
2953   switch(direction) {
2954   case 0:
2955     pdata->primitives.sampling_direction[0] = 'i';
2956     break;
2957   case 1:
2958     pdata->primitives.sampling_direction[0] = 'e';
2959     break;
2960   default:
2961     pdata->primitives.sampling_direction[0] = 'u';
2962     break;
2963   }
2964 
2965   pdata->primitives.sampling_direction[1] = '\0';
2966 }
2967 
NF_timestamp_start_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)2968 void NF_timestamp_start_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
2969 {
2970   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
2971   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
2972   struct pkt_nat_primitives *pnat = (struct pkt_nat_primitives *) ((*data) + chptr->extras.off_pkt_nat_primitives);
2973 
2974   time_t fstime = 0;
2975   u_int32_t t32 = 0;
2976   u_int64_t t64 = 0;
2977 
2978   switch(hdr->version) {
2979   case 10:
2980   case 9:
2981     if (tpl->tpl[NF9_FIRST_SWITCHED].len && hdr->version == 9) {
2982       memcpy(&fstime, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED].off, tpl->tpl[NF9_FIRST_SWITCHED].len);
2983       pnat->timestamp_start.tv_sec = ntohl(((struct struct_header_v9 *) pptrs->f_header)->unix_secs)-
2984         ((ntohl(((struct struct_header_v9 *) pptrs->f_header)->SysUptime)-ntohl(fstime))/1000);
2985     }
2986     else if (tpl->tpl[NF9_FIRST_SWITCHED].len && hdr->version == 10) {
2987       if (tpl->tpl[NF9_SYS_UPTIME_MSEC].len == 8) {
2988         memcpy(&fstime, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED].off, tpl->tpl[NF9_FIRST_SWITCHED].len);
2989         memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_SYS_UPTIME_MSEC].off, tpl->tpl[NF9_SYS_UPTIME_MSEC].len);
2990 	t32 = pm_ntohll(t64)/1000;
2991         pnat->timestamp_start.tv_sec = t32+(ntohl(fstime)/1000);
2992       }
2993     }
2994     else if (tpl->tpl[NF9_FIRST_SWITCHED_MSEC].len) {
2995       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED_MSEC].off, tpl->tpl[NF9_FIRST_SWITCHED_MSEC].len);
2996       pnat->timestamp_start.tv_sec = pm_ntohll(t64)/1000;
2997       pnat->timestamp_start.tv_usec = (pm_ntohll(t64)%1000)*1000;
2998     }
2999     else if (tpl->tpl[NF9_OBSERVATION_TIME_MSEC].len) {
3000       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_OBSERVATION_TIME_MSEC].off, tpl->tpl[NF9_OBSERVATION_TIME_MSEC].len);
3001       pnat->timestamp_start.tv_sec = pm_ntohll(t64)/1000;
3002       pnat->timestamp_start.tv_usec = (pm_ntohll(t64)%1000)*1000;
3003     }
3004     else if (tpl->tpl[NF9_FIRST_SWITCHED_USEC].len) {
3005       if (tpl->tpl[NF9_FIRST_SWITCHED_USEC].len == 16) {
3006         memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED_USEC].off, 8);
3007         pnat->timestamp_start.tv_sec = pm_ntohll(t64);
3008         memcpy(&t64, (pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED_USEC].off+8), 8);
3009         pnat->timestamp_start.tv_usec = pm_ntohll(t64);
3010       }
3011     }
3012     /* sec handling here: msec vs sec restricted to NetFlow v5 */
3013     else if (tpl->tpl[NF9_FIRST_SWITCHED_SEC].len == 4) {
3014       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED_SEC].off, tpl->tpl[NF9_FIRST_SWITCHED_SEC].len);
3015       pnat->timestamp_start.tv_sec = ntohl(t32);
3016     }
3017     else if (tpl->tpl[NF9_FIRST_SWITCHED_SEC].len == 8) {
3018       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED_SEC].off, tpl->tpl[NF9_FIRST_SWITCHED_SEC].len);
3019       pnat->timestamp_start.tv_sec = pm_ntohll(t64);
3020     }
3021     else if (tpl->tpl[NF9_FIRST_SWITCHED_DELTA_MICRO].len && hdr->version == 10) {
3022       struct struct_header_ipfix *hdr_ipfix = (struct struct_header_ipfix *) pptrs->f_header;
3023       u_int32_t t32h = 0, h32h = 0;
3024       u_int64_t t64_1 = 0, t64_2 = 0;
3025 
3026       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED_DELTA_MICRO].off, tpl->tpl[NF9_FIRST_SWITCHED_DELTA_MICRO].len);
3027       t32h = ntohl(t32);
3028 
3029       h32h = ntohl(hdr_ipfix->unix_secs);
3030 
3031       t64 = h32h;
3032       t64 = t64 * 1000 * 1000;
3033       t64 -= t32h;
3034       t64_1 = (t64 / (1000 * 1000));
3035       t64_2 = (t64 % (1000 * 1000));
3036 
3037       pnat->timestamp_start.tv_sec = t64_1;
3038       pnat->timestamp_start.tv_usec = t64_2;
3039     }
3040 
3041     /* fallback to header timestamp if no other time reference is available */
3042     if (!pnat->timestamp_start.tv_sec) {
3043       if (hdr->version == 10) {
3044         struct struct_header_ipfix *hdr_ipfix = (struct struct_header_ipfix *) pptrs->f_header;
3045 
3046         pnat->timestamp_start.tv_sec = ntohl(hdr_ipfix->unix_secs);
3047       }
3048       else if (hdr->version == 9) {
3049         struct struct_header_v9 *hdr_v9 = (struct struct_header_v9 *) pptrs->f_header;
3050 
3051         pnat->timestamp_start.tv_sec = ntohl(hdr_v9->unix_secs);
3052       }
3053     }
3054 
3055     break;
3056   case 5:
3057     pnat->timestamp_start.tv_sec = ntohl(((struct struct_header_v5 *) pptrs->f_header)->unix_secs)-
3058       ((ntohl(((struct struct_header_v5 *) pptrs->f_header)->SysUptime)-ntohl(((struct struct_export_v5 *) pptrs->f_data)->First))/1000);
3059     break;
3060   default:
3061     break;
3062   }
3063 
3064   if (chptr->plugin->cfg.timestamps_secs) pnat->timestamp_start.tv_usec = 0;
3065 }
3066 
NF_timestamp_end_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3067 void NF_timestamp_end_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3068 {
3069   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3070   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3071   struct pkt_nat_primitives *pnat = (struct pkt_nat_primitives *) ((*data) + chptr->extras.off_pkt_nat_primitives);
3072 
3073   time_t fstime = 0;
3074   u_int32_t t32 = 0;
3075   u_int64_t t64 = 0;
3076 
3077   switch(hdr->version) {
3078   case 10:
3079   case 9:
3080     if (tpl->tpl[NF9_LAST_SWITCHED].len && hdr->version == 9) {
3081       memcpy(&fstime, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED].off, tpl->tpl[NF9_LAST_SWITCHED].len);
3082       pnat->timestamp_end.tv_sec = ntohl(((struct struct_header_v9 *) pptrs->f_header)->unix_secs)-
3083         ((ntohl(((struct struct_header_v9 *) pptrs->f_header)->SysUptime)-ntohl(fstime))/1000);
3084     }
3085     else if (tpl->tpl[NF9_LAST_SWITCHED].len && hdr->version == 10) {
3086       if (tpl->tpl[NF9_SYS_UPTIME_MSEC].len == 8) {
3087         memcpy(&fstime, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED].off, tpl->tpl[NF9_LAST_SWITCHED].len);
3088         memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_SYS_UPTIME_MSEC].off, tpl->tpl[NF9_SYS_UPTIME_MSEC].len);
3089         t32 = pm_ntohll(t64)/1000;
3090         pnat->timestamp_end.tv_sec = t32+(ntohl(fstime)/1000);
3091       }
3092     }
3093     else if (tpl->tpl[NF9_LAST_SWITCHED_MSEC].len) {
3094       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED_MSEC].off, tpl->tpl[NF9_LAST_SWITCHED_MSEC].len);
3095       pnat->timestamp_end.tv_sec = pm_ntohll(t64)/1000;
3096       pnat->timestamp_end.tv_usec = (pm_ntohll(t64)%1000)*1000;
3097     }
3098     else if (tpl->tpl[NF9_LAST_SWITCHED_USEC].len) {
3099       if (tpl->tpl[NF9_LAST_SWITCHED_USEC].len == 16) {
3100         memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED_USEC].off, 8);
3101         pnat->timestamp_end.tv_sec = pm_ntohll(t64);
3102         memcpy(&t64, (pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED_USEC].off+8), 8);
3103         pnat->timestamp_end.tv_usec = pm_ntohll(t64);
3104       }
3105     }
3106     /* sec handling here: msec vs sec restricted to NetFlow v5 */
3107     else if (tpl->tpl[NF9_LAST_SWITCHED_SEC].len == 4) {
3108       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED_SEC].off, tpl->tpl[NF9_LAST_SWITCHED_SEC].len);
3109       pnat->timestamp_end.tv_sec = ntohl(t32);
3110     }
3111     else if (tpl->tpl[NF9_LAST_SWITCHED_SEC].len == 8) {
3112       memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED_SEC].off, tpl->tpl[NF9_LAST_SWITCHED_SEC].len);
3113       pnat->timestamp_end.tv_sec = pm_ntohll(t64);
3114     }
3115     else if (tpl->tpl[NF9_LAST_SWITCHED_DELTA_MICRO].len && hdr->version == 10) {
3116       struct struct_header_ipfix *hdr_ipfix = (struct struct_header_ipfix *) pptrs->f_header;
3117       u_int32_t t32h = 0, h32h = 0;
3118       u_int64_t t64_1 = 0, t64_2 = 0;
3119 
3120       memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_LAST_SWITCHED_DELTA_MICRO].off, tpl->tpl[NF9_LAST_SWITCHED_DELTA_MICRO].len);
3121       t32h = ntohl(t32);
3122 
3123       h32h = ntohl(hdr_ipfix->unix_secs);
3124 
3125       t64 = h32h;
3126       t64 = t64 * 1000 * 1000;
3127       t64 -= t32h;
3128       t64_1 = (t64 / (1000 * 1000));
3129       t64_2 = (t64 % (1000 * 1000));
3130 
3131       pnat->timestamp_end.tv_sec = t64_1;
3132       pnat->timestamp_end.tv_usec = t64_2;
3133     }
3134     break;
3135   case 5:
3136     pnat->timestamp_end.tv_sec = ntohl(((struct struct_header_v5 *) pptrs->f_header)->unix_secs)-
3137       ((ntohl(((struct struct_header_v5 *) pptrs->f_header)->SysUptime)-ntohl(((struct struct_export_v5 *) pptrs->f_data)->Last))/1000);
3138     break;
3139   default:
3140     break;
3141   }
3142 
3143   if (chptr->plugin->cfg.timestamps_secs) pnat->timestamp_end.tv_usec = 0;
3144 }
3145 
NF_timestamp_arrival_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3146 void NF_timestamp_arrival_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3147 {
3148   struct pkt_nat_primitives *pnat = (struct pkt_nat_primitives *) ((*data) + chptr->extras.off_pkt_nat_primitives);
3149 
3150   gettimeofday(&pnat->timestamp_arrival, NULL);
3151   if (chptr->plugin->cfg.timestamps_secs) pnat->timestamp_arrival.tv_usec = 0;
3152 }
3153 
NF_sequence_number_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3154 void NF_sequence_number_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3155 {
3156   struct pkt_data *pdata = (struct pkt_data *) *data;
3157   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3158 
3159   switch(hdr->version) {
3160   case 10:
3161     pdata->primitives.export_proto_seqno = ntohl(((struct struct_header_ipfix *) pptrs->f_header)->flow_sequence);
3162     break;
3163   case 9:
3164     pdata->primitives.export_proto_seqno = ntohl(((struct struct_header_v9 *) pptrs->f_header)->flow_sequence);
3165     break;
3166   case 5:
3167     pdata->primitives.export_proto_seqno = ntohl(((struct struct_header_v5 *) pptrs->f_header)->flow_sequence);
3168     break;
3169   default:
3170     break;
3171   }
3172 }
3173 
NF_version_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3174 void NF_version_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3175 {
3176   struct pkt_data *pdata = (struct pkt_data *) *data;
3177   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3178 
3179   pdata->primitives.export_proto_version = hdr->version;
3180 }
3181 
NF_sysid_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3182 void NF_sysid_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3183 {
3184   struct pkt_data *pdata = (struct pkt_data *) *data;
3185   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3186 
3187   switch(hdr->version) {
3188   case 10:
3189     pdata->primitives.export_proto_sysid = ntohl(((struct struct_header_ipfix *) pptrs->f_header)->source_id);
3190     break;
3191   case 9:
3192     pdata->primitives.export_proto_sysid = ntohl(((struct struct_header_v9 *) pptrs->f_header)->source_id);
3193     break;
3194   case 5:
3195     pdata->primitives.export_proto_sysid = ((struct struct_header_v5 *) pptrs->f_header)->engine_id;
3196     /* XXX: engine type? */
3197     break;
3198   default:
3199     break;
3200   }
3201 }
3202 
NF_custom_primitives_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3203 void NF_custom_primitives_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3204 {
3205   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3206   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3207   struct utpl_field *utpl = NULL;
3208   u_char *pcust = (u_char *)((*data) + chptr->extras.off_custom_primitives);
3209   struct pkt_vlen_hdr_primitives *pvlen = (struct pkt_vlen_hdr_primitives *) ((*data) + chptr->extras.off_pkt_vlen_hdr_primitives);
3210   struct custom_primitive_entry *cpe;
3211   int cpptrs_idx;
3212 
3213   switch(hdr->version) {
3214   case 10:
3215   case 9:
3216     for (cpptrs_idx = 0; cpptrs_idx < chptr->plugin->cfg.cpptrs.num; cpptrs_idx++) {
3217       if (chptr->plugin->cfg.cpptrs.primitive[cpptrs_idx].ptr) {
3218 	cpe = chptr->plugin->cfg.cpptrs.primitive[cpptrs_idx].ptr;
3219 	if (cpe->field_type < NF9_MAX_DEFINED_FIELD && !cpe->pen) {
3220 	  if (cpe->semantics == CUSTOM_PRIMITIVE_TYPE_RAW) {
3221             unsigned char hexbuf[cpe->alloc_len];
3222             int hexbuflen = 0;
3223 
3224             hexbuflen = serialize_hex(pptrs->f_data+tpl->tpl[cpe->field_type].off, hexbuf, tpl->tpl[cpe->field_type].len);
3225             if (cpe->alloc_len < hexbuflen) hexbuf[cpe->alloc_len-1] = '\0';
3226             memcpy(pcust+chptr->plugin->cfg.cpptrs.primitive[cpptrs_idx].off, hexbuf, MIN(hexbuflen, cpe->alloc_len));
3227           }
3228 	  else {
3229 	    if (tpl->tpl[cpe->field_type].len == cpe->len) {
3230 	      memcpy(pcust+chptr->plugin->cfg.cpptrs.primitive[cpptrs_idx].off, pptrs->f_data+tpl->tpl[cpe->field_type].off, cpe->len);
3231 	    }
3232 	    /* else this is a configuration mistake: do nothing */
3233 	  }
3234 	}
3235 	else {
3236 	  if ((utpl = (*get_ext_db_ie_by_type)(tpl, cpe->pen, cpe->field_type, cpe->repeat_id))) {
3237 	    if (cpe->semantics == CUSTOM_PRIMITIVE_TYPE_RAW) {
3238               unsigned char hexbuf[cpe->alloc_len];
3239               int hexbuflen = 0;
3240 
3241               hexbuflen = serialize_hex(pptrs->f_data+utpl->off, hexbuf, utpl->len);
3242               if (cpe->alloc_len < hexbuflen) hexbuf[cpe->alloc_len-1] = '\0';
3243 
3244 	      if (cpe->len == PM_VARIABLE_LENGTH) {
3245 		if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + hexbuflen)) {
3246 		  vlen_prims_init(pvlen, 0);
3247 		  return;
3248 		}
3249 		else vlen_prims_insert(pvlen, cpe->type, hexbuflen, hexbuf, PM_MSG_BIN_COPY);
3250               }
3251 	      else memcpy(pcust+chptr->plugin->cfg.cpptrs.primitive[cpptrs_idx].off, hexbuf, MIN(hexbuflen, cpe->alloc_len));
3252 
3253             }
3254 	    else {
3255 	      if (utpl->len == cpe->len) {
3256 	        memcpy(pcust+chptr->plugin->cfg.cpptrs.primitive[cpptrs_idx].off, pptrs->f_data+utpl->off, cpe->len);
3257 	      }
3258               else {
3259                 if (cpe->semantics == CUSTOM_PRIMITIVE_TYPE_STRING && cpe->len == PM_VARIABLE_LENGTH) {
3260 		  if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + utpl->len + 1 /* terminating zero */)) {
3261 		    vlen_prims_init(pvlen, 0);
3262 		    return;
3263 		  }
3264 		  else vlen_prims_insert(pvlen, cpe->type, utpl->len, pptrs->f_data+utpl->off, PM_MSG_STR_COPY_ZERO);
3265 		}
3266 	      }
3267             }
3268 	  }
3269 	}
3270       }
3271     }
3272 
3273     if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len) custom_primitives_handler(chptr, pptrs, data);
3274 
3275     break;
3276   default:
3277     break;
3278   }
3279 }
3280 
NF_post_nat_src_host_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3281 void NF_post_nat_src_host_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3282 {
3283   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3284   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3285   struct pkt_nat_primitives *pnat = (struct pkt_nat_primitives *) ((*data) + chptr->extras.off_pkt_nat_primitives);
3286   struct utpl_field *utpl = NULL;
3287 
3288   switch(hdr->version) {
3289   case 10:
3290   case 9:
3291     if (pptrs->l3_proto == ETHERTYPE_IP) {
3292       if (tpl->tpl[NF9_POST_NAT_IPV4_SRC_ADDR].len) {
3293         memcpy(&pnat->post_nat_src_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_POST_NAT_IPV4_SRC_ADDR].off, MIN(tpl->tpl[NF9_POST_NAT_IPV4_SRC_ADDR].len, 4));
3294         pnat->post_nat_src_ip.family = AF_INET;
3295       }
3296       else if ((utpl = (*get_ext_db_ie_by_type)(tpl, 0, NF9_ASA_XLATE_IPV4_SRC_ADDR, FALSE))) {
3297         memcpy(&pnat->post_nat_src_ip.address.ipv4, pptrs->f_data+utpl->off, MIN(utpl->len, 4));
3298         pnat->post_nat_src_ip.family = AF_INET;
3299       }
3300     }
3301     break;
3302   default:
3303     break;
3304   }
3305 }
3306 
NF_post_nat_dst_host_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3307 void NF_post_nat_dst_host_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3308 {
3309   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3310   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3311   struct pkt_nat_primitives *pnat = (struct pkt_nat_primitives *) ((*data) + chptr->extras.off_pkt_nat_primitives);
3312   struct utpl_field *utpl = NULL;
3313 
3314   switch(hdr->version) {
3315   case 10:
3316   case 9:
3317     if (pptrs->l3_proto == ETHERTYPE_IP) {
3318       if (tpl->tpl[NF9_POST_NAT_IPV4_DST_ADDR].len) {
3319         memcpy(&pnat->post_nat_dst_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_POST_NAT_IPV4_DST_ADDR].off, MIN(tpl->tpl[NF9_POST_NAT_IPV4_DST_ADDR].len, 4));
3320         pnat->post_nat_dst_ip.family = AF_INET;
3321       }
3322       else if ((utpl = (*get_ext_db_ie_by_type)(tpl, 0, NF9_ASA_XLATE_IPV4_DST_ADDR, FALSE))) {
3323         memcpy(&pnat->post_nat_dst_ip.address.ipv4, pptrs->f_data+utpl->off, MIN(utpl->len, 4));
3324         pnat->post_nat_dst_ip.family = AF_INET;
3325       }
3326     }
3327     break;
3328   default:
3329     break;
3330   }
3331 }
3332 
NF_post_nat_src_port_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3333 void NF_post_nat_src_port_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3334 {
3335   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3336   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3337   struct pkt_nat_primitives *pnat = (struct pkt_nat_primitives *) ((*data) + chptr->extras.off_pkt_nat_primitives);
3338   struct utpl_field *utpl = NULL;
3339   u_int8_t l4_proto = 0;
3340 
3341   switch(hdr->version) {
3342   case 10:
3343   case 9:
3344     if (tpl->tpl[NF9_L4_PROTOCOL].len == 1)
3345       memcpy(&l4_proto, pptrs->f_data+tpl->tpl[NF9_L4_PROTOCOL].off, 1);
3346 
3347     if (tpl->tpl[NF9_POST_NAT_IPV4_SRC_PORT].len)
3348       memcpy(&pnat->post_nat_src_port, pptrs->f_data+tpl->tpl[NF9_POST_NAT_IPV4_SRC_PORT].off, MIN(tpl->tpl[NF9_POST_NAT_IPV4_SRC_PORT].len, 2));
3349     else if ((utpl = (*get_ext_db_ie_by_type)(tpl, 0, NF9_ASA_XLATE_L4_SRC_PORT, FALSE)))
3350       memcpy(&pnat->post_nat_src_port, pptrs->f_data+utpl->off, MIN(utpl->len, 2));
3351 
3352     pnat->post_nat_src_port = ntohs(pnat->post_nat_src_port);
3353     break;
3354   default:
3355     break;
3356   }
3357 }
3358 
NF_post_nat_dst_port_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3359 void NF_post_nat_dst_port_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3360 {
3361   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3362   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3363   struct pkt_nat_primitives *pnat = (struct pkt_nat_primitives *) ((*data) + chptr->extras.off_pkt_nat_primitives);
3364   struct utpl_field *utpl = NULL;
3365   u_int8_t l4_proto = 0;
3366 
3367   switch(hdr->version) {
3368   case 10:
3369   case 9:
3370     if (tpl->tpl[NF9_L4_PROTOCOL].len == 1)
3371       memcpy(&l4_proto, pptrs->f_data+tpl->tpl[NF9_L4_PROTOCOL].off, 1);
3372 
3373     if (tpl->tpl[NF9_POST_NAT_IPV4_DST_PORT].len)
3374       memcpy(&pnat->post_nat_dst_port, pptrs->f_data+tpl->tpl[NF9_POST_NAT_IPV4_DST_PORT].off, MIN(tpl->tpl[NF9_POST_NAT_IPV4_DST_PORT].len, 2));
3375     else if ((utpl = (*get_ext_db_ie_by_type)(tpl, 0, NF9_ASA_XLATE_L4_DST_PORT, FALSE)))
3376       memcpy(&pnat->post_nat_dst_port, pptrs->f_data+utpl->off, MIN(utpl->len, 2));
3377 
3378     pnat->post_nat_dst_port = ntohs(pnat->post_nat_dst_port);
3379     break;
3380   default:
3381     break;
3382   }
3383 }
3384 
NF_nat_event_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3385 void NF_nat_event_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3386 {
3387   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3388   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3389   struct pkt_nat_primitives *pnat = (struct pkt_nat_primitives *) ((*data) + chptr->extras.off_pkt_nat_primitives);
3390   struct utpl_field *utpl = NULL;
3391 
3392   switch(hdr->version) {
3393   case 10:
3394   case 9:
3395     if (tpl->tpl[NF9_NAT_EVENT].len)
3396       memcpy(&pnat->nat_event, pptrs->f_data+tpl->tpl[NF9_NAT_EVENT].off, MIN(tpl->tpl[NF9_NAT_EVENT].len, 1));
3397     else if ((utpl = (*get_ext_db_ie_by_type)(tpl, 0, NF9_ASA_XLATE_EVENT, FALSE)))
3398       memcpy(&pnat->nat_event, pptrs->f_data+utpl->off, MIN(utpl->len, 1));
3399     break;
3400   default:
3401     break;
3402   }
3403 }
3404 
NF_mpls_label_top_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3405 void NF_mpls_label_top_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3406 {
3407   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3408   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3409   struct pkt_mpls_primitives *pmpls = (struct pkt_mpls_primitives *) ((*data) + chptr->extras.off_pkt_mpls_primitives);
3410 
3411   switch(hdr->version) {
3412   case 10:
3413   case 9:
3414     if (tpl->tpl[NF9_MPLS_LABEL_1].len == 3)
3415       pmpls->mpls_label_top = decode_mpls_label(pptrs->f_data+tpl->tpl[NF9_MPLS_LABEL_1].off);
3416     else if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
3417       mpls_label_top_handler(chptr, pptrs, data);
3418 
3419     break;
3420   default:
3421     break;
3422   }
3423 }
3424 
NF_mpls_label_bottom_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3425 void NF_mpls_label_bottom_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3426 {
3427   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3428   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3429   struct pkt_mpls_primitives *pmpls = (struct pkt_mpls_primitives *) ((*data) + chptr->extras.off_pkt_mpls_primitives);
3430   int label_idx;
3431 
3432   switch(hdr->version) {
3433   case 10:
3434   case 9:
3435     for (label_idx = NF9_MPLS_LABEL_1; label_idx <= NF9_MPLS_LABEL_9; label_idx++) {
3436       if (tpl->tpl[label_idx].len == 3 && check_bosbit(pptrs->f_data+tpl->tpl[label_idx].off)) {
3437         pmpls->mpls_label_bottom = decode_mpls_label(pptrs->f_data+tpl->tpl[label_idx].off);
3438 	break;
3439       }
3440     }
3441 
3442     if (!pmpls->mpls_label_bottom) {
3443       if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
3444         mpls_label_bottom_handler(chptr, pptrs, data);
3445     }
3446 
3447     break;
3448   default:
3449     break;
3450   }
3451 }
3452 
NF_mpls_stack_depth_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3453 void NF_mpls_stack_depth_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3454 {
3455   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3456   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3457   struct pkt_mpls_primitives *pmpls = (struct pkt_mpls_primitives *) ((*data) + chptr->extras.off_pkt_mpls_primitives);
3458   int label_idx, last_label_value = 0, stack_depth, bosbit_found = FALSE;
3459 
3460   switch(hdr->version) {
3461   case 10:
3462   case 9:
3463     for (label_idx = NF9_MPLS_LABEL_1, stack_depth = 0; label_idx <= NF9_MPLS_LABEL_9; label_idx++) {
3464       if (tpl->tpl[label_idx].len == 3) {
3465 	stack_depth++;
3466 	last_label_value = decode_mpls_label(pptrs->f_data+tpl->tpl[label_idx].off);
3467 	if (check_bosbit(pptrs->f_data+tpl->tpl[label_idx].off)) {
3468 	  bosbit_found = TRUE;
3469 	  break;
3470 	}
3471       }
3472     }
3473 
3474     if (last_label_value || bosbit_found) pmpls->mpls_stack_depth = stack_depth;
3475 
3476     if (!pmpls->mpls_stack_depth) {
3477       if (tpl->tpl[NF9_DATALINK_FRAME_SECTION].len)
3478         mpls_stack_depth_handler(chptr, pptrs, data);
3479     }
3480 
3481     break;
3482   default:
3483     break;
3484   }
3485 }
3486 
NF_mpls_vpn_id_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3487 void NF_mpls_vpn_id_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3488 {
3489   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3490   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3491   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
3492   int vrfid = FALSE;
3493 
3494   switch(hdr->version) {
3495   case 10:
3496   case 9:
3497     if (tpl->tpl[NF9_INGRESS_VRFID].len && !pbgp->mpls_vpn_rd.val) {
3498       memcpy(&pbgp->mpls_vpn_rd.val, pptrs->f_data+tpl->tpl[NF9_INGRESS_VRFID].off, MIN(tpl->tpl[NF9_INGRESS_VRFID].len, 4));
3499       vrfid = TRUE;
3500     }
3501 
3502     if (tpl->tpl[NF9_EGRESS_VRFID].len && !pbgp->mpls_vpn_rd.val) {
3503       memcpy(&pbgp->mpls_vpn_rd.val, pptrs->f_data+tpl->tpl[NF9_EGRESS_VRFID].off, MIN(tpl->tpl[NF9_EGRESS_VRFID].len, 4));
3504       vrfid = TRUE;
3505     }
3506 
3507     if (vrfid) {
3508       pbgp->mpls_vpn_rd.val = ntohl(pbgp->mpls_vpn_rd.val);
3509       if (pbgp->mpls_vpn_rd.val) pbgp->mpls_vpn_rd.type = RD_TYPE_VRFID;
3510     }
3511     break;
3512   default:
3513     break;
3514   }
3515 }
3516 
NF_mpls_pw_id_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3517 void NF_mpls_pw_id_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3518 {
3519   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3520   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3521   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
3522   u_int32_t tmp32;
3523 
3524   switch(hdr->version) {
3525   case 10:
3526   case 9:
3527     if (tpl->tpl[NF9_PSEUDOWIREID].len) {
3528       memcpy(&tmp32, pptrs->f_data+tpl->tpl[NF9_PSEUDOWIREID].off, 4);
3529       pbgp->mpls_pw_id = ntohl(tmp32);
3530     }
3531     break;
3532   default:
3533     break;
3534   }
3535 }
3536 
NF_vxlan_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3537 void NF_vxlan_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3538 {
3539   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3540   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3541   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
3542   u_char *vni_ptr = NULL, tmp64[8];
3543   u_int8_t *type = NULL;
3544 
3545   //Make compiler happy
3546   memset(tmp64, 0, sizeof(tmp64));
3547 
3548   switch(hdr->version) {
3549   case 10:
3550   case 9:
3551     if (tpl->tpl[NF9_LAYER2_SEGMENT_ID].len == 8) {
3552       memcpy(tmp64, pptrs->f_data+tpl->tpl[NF9_LAYER2_SEGMENT_ID].off, 8);
3553 
3554       type = (u_int8_t *) &tmp64[0];
3555       if ((*type) == NF9_L2_SID_VXLAN) {
3556 	vni_ptr = &tmp64[6];
3557 
3558 	ptun->tunnel_id = *vni_ptr++;
3559 	ptun->tunnel_id <<= 8;
3560 	ptun->tunnel_id += *vni_ptr++;
3561 	ptun->tunnel_id <<= 8;
3562 	ptun->tunnel_id += *vni_ptr++;
3563       }
3564     }
3565 
3566     break;
3567   default:
3568     break;
3569   }
3570 }
3571 
NF_class_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3572 void NF_class_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3573 {
3574   struct pkt_data *pdata = (struct pkt_data *) *data;
3575   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3576   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3577   time_t fstime;
3578 
3579   switch(hdr->version) {
3580   case 10:
3581   case 9:
3582     if (tpl->tpl[NF9_APPLICATION_ID].len) {
3583       pdata->primitives.class = pptrs->class;
3584       pdata->cst.ba = 0;
3585       pdata->cst.pa = 0;
3586       pdata->cst.fa = 0;
3587 
3588       if (tpl->tpl[NF9_FIRST_SWITCHED].len && hdr->version == 9) {
3589         memcpy(&fstime, pptrs->f_data+tpl->tpl[NF9_FIRST_SWITCHED].off, tpl->tpl[NF9_FIRST_SWITCHED].len);
3590         pdata->cst.stamp.tv_sec = ntohl(((struct struct_header_v9 *) pptrs->f_header)->unix_secs)-
3591            ((ntohl(((struct struct_header_v9 *) pptrs->f_header)->SysUptime)-ntohl(fstime))/1000);
3592       }
3593       else pdata->cst.stamp.tv_sec = time(NULL);
3594       pdata->cst.stamp.tv_usec = 0;
3595     }
3596     break;
3597   default:
3598     break;
3599   }
3600 }
3601 
3602 #if defined (WITH_NDPI)
NF_ndpi_class_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3603 void NF_ndpi_class_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3604 {
3605   struct pkt_data *pdata = (struct pkt_data *) *data;
3606 
3607   memcpy(&pdata->primitives.ndpi_class, &pptrs->ndpi_class, sizeof(pm_class2_t));
3608 }
3609 #endif
3610 
NF_cust_tag_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3611 void NF_cust_tag_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3612 {
3613   struct pkt_data *pdata = (struct pkt_data *) *data;
3614   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3615   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3616   struct utpl_field *utpl = NULL;
3617 
3618   switch(hdr->version) {
3619   case 10:
3620     if ((utpl = (*get_ext_db_ie_by_type)(tpl, PMACCT_PEN, NF9_CUST_TAG, FALSE))) {
3621       memcpy(&pdata->primitives.tag, pptrs->f_data+utpl->off, MIN(utpl->len, 8));
3622       pdata->primitives.tag = pm_ntohll(pdata->primitives.tag);
3623     }
3624     break;
3625   default:
3626     break;
3627   }
3628 }
3629 
NF_cust_tag2_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3630 void NF_cust_tag2_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3631 {
3632   struct pkt_data *pdata = (struct pkt_data *) *data;
3633   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3634   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3635   struct utpl_field *utpl = NULL;
3636 
3637   switch(hdr->version) {
3638   case 10:
3639     if ((utpl = (*get_ext_db_ie_by_type)(tpl, PMACCT_PEN, NF9_CUST_TAG2, FALSE))) {
3640       memcpy(&pdata->primitives.tag2, pptrs->f_data+utpl->off, MIN(utpl->len, 8));
3641       pdata->primitives.tag2 = pm_ntohll(pdata->primitives.tag2);
3642     }
3643 
3644     break;
3645   default:
3646     break;
3647   }
3648 }
3649 
NF_cust_label_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3650 void NF_cust_label_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3651 {
3652   struct pkt_vlen_hdr_primitives *pvlen = (struct pkt_vlen_hdr_primitives *) ((*data) + chptr->extras.off_pkt_vlen_hdr_primitives);
3653   struct struct_header_v5 *hdr = (struct struct_header_v5 *) pptrs->f_header;
3654   struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
3655   struct utpl_field *utpl = NULL;
3656 
3657   switch(hdr->version) {
3658   case 10:
3659     if ((utpl = (*get_ext_db_ie_by_type)(tpl, PMACCT_PEN, NF9_CUST_LABEL, FALSE))) {
3660       return_pipe_buffer_space(chptr, vlen_prims_delete(pvlen, COUNT_INT_LABEL));
3661       if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + utpl->len)) {
3662 	vlen_prims_init(pvlen, 0);
3663 	return;
3664       }
3665       else vlen_prims_insert(pvlen, COUNT_INT_LABEL, utpl->len, pptrs->f_data+utpl->off, PM_MSG_STR_COPY);
3666     }
3667     break;
3668   default:
3669     break;
3670   }
3671 }
3672 
NF_counters_renormalize_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3673 void NF_counters_renormalize_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3674 {
3675   struct xflow_status_entry *entry = (struct xflow_status_entry *) pptrs->f_status;
3676   struct xflow_status_entry_sampling *sentry = NULL;
3677   struct pkt_data *pdata = (struct pkt_data *) *data;
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   u_int16_t srate = 0, is_sampled = 0;
3681   u_int16_t t16 = 0;
3682   u_int32_t sampler_id = 0, sample_pool = 0, t32 = 0;
3683   u_int8_t t8 = 0;
3684   u_int64_t t64 = 0;
3685 
3686   if (pptrs->renormalized) return;
3687 
3688   switch (hdr->version) {
3689   case 10:
3690   case 9:
3691     if (tpl->tpl[NF9_FLOW_SAMPLER_ID].len || tpl->tpl[NF9_SELECTOR_ID].len == 8) {
3692       if (tpl->tpl[NF9_FLOW_SAMPLER_ID].len == 1) {
3693         memcpy(&t8, pptrs->f_data+tpl->tpl[NF9_FLOW_SAMPLER_ID].off, 1);
3694         sampler_id = t8;
3695       }
3696       else if (tpl->tpl[NF9_FLOW_SAMPLER_ID].len == 2) {
3697         memcpy(&t16, pptrs->f_data+tpl->tpl[NF9_FLOW_SAMPLER_ID].off, 2);
3698         sampler_id = ntohs(t16);
3699       }
3700       else if (tpl->tpl[NF9_FLOW_SAMPLER_ID].len == 4) {
3701         memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_FLOW_SAMPLER_ID].off, 4);
3702         sampler_id = ntohl(t32);
3703       }
3704       else if (tpl->tpl[NF9_SELECTOR_ID].len == 8) {
3705         memcpy(&t64, pptrs->f_data+tpl->tpl[NF9_SELECTOR_ID].off, 8);
3706         sampler_id = pm_ntohll(t64); /* XXX: sampler_id to be moved to 64 bit */
3707       }
3708 
3709       if (entry) {
3710         sentry = search_smp_id_status_table(entry->sampling, sampler_id, TRUE);
3711         if (!sentry && pptrs->f_status_g) {
3712           entry = (struct xflow_status_entry *) pptrs->f_status_g;
3713           sentry = search_smp_id_status_table(entry->sampling, sampler_id, FALSE);
3714         }
3715       }
3716       if (sentry) {
3717         pdata->pkt_len = pdata->pkt_len * sentry->sample_pool;
3718         pdata->pkt_num = pdata->pkt_num * sentry->sample_pool;
3719 
3720 	pptrs->renormalized = TRUE;
3721       }
3722     }
3723     /* SAMPLING_INTERVAL part of the NetFlow v9/IPFIX record seems to be reality, ie. FlowMon by Invea-Tech */
3724     else if (tpl->tpl[NF9_SAMPLING_INTERVAL].len || tpl->tpl[NF9_FLOW_SAMPLER_INTERVAL].len) {
3725       if (tpl->tpl[NF9_SAMPLING_INTERVAL].len == 2) {
3726 	memcpy(&t16, pptrs->f_data+tpl->tpl[NF9_SAMPLING_INTERVAL].off, 2);
3727 	sample_pool = ntohs(t16);
3728       }
3729       else if (tpl->tpl[NF9_SAMPLING_INTERVAL].len == 4) {
3730 	memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_SAMPLING_INTERVAL].off, 4);
3731 	sample_pool = ntohl(t32);
3732       }
3733 
3734       if (tpl->tpl[NF9_FLOW_SAMPLER_INTERVAL].len == 2) {
3735 	memcpy(&t16, pptrs->f_data+tpl->tpl[NF9_FLOW_SAMPLER_INTERVAL].off, 2);
3736 	sample_pool = ntohs(t16);
3737       }
3738       else if (tpl->tpl[NF9_FLOW_SAMPLER_INTERVAL].len == 4) {
3739 	memcpy(&t32, pptrs->f_data+tpl->tpl[NF9_FLOW_SAMPLER_INTERVAL].off, 4);
3740         sample_pool = ntohl(t32);
3741       }
3742 
3743       pdata->pkt_len = pdata->pkt_len * sample_pool;
3744       pdata->pkt_num = pdata->pkt_num * sample_pool;
3745 
3746       pptrs->renormalized = TRUE;
3747     }
3748     /* case of no SAMPLER_ID, ALU & IPFIX */
3749     else {
3750       if (entry) {
3751         sentry = search_smp_id_status_table(entry->sampling, 0, TRUE);
3752         if (!sentry && pptrs->f_status_g) {
3753           entry = (struct xflow_status_entry *) pptrs->f_status_g;
3754           sentry = search_smp_id_status_table(entry->sampling, 0, FALSE);
3755         }
3756         if (!sentry) sentry = search_smp_id_status_table(entry->sampling, ntohs(tpl->template_id), FALSE);
3757       }
3758 
3759       if (sentry) {
3760         pdata->pkt_len = pdata->pkt_len * sentry->sample_pool;
3761         pdata->pkt_num = pdata->pkt_num * sentry->sample_pool;
3762 
3763         pptrs->renormalized = TRUE;
3764       }
3765     }
3766 
3767     break;
3768   case 5:
3769     is_sampled = ( ntohs(hdr->sampling) & 0xC000 );
3770     (void)is_sampled;
3771     srate = ( ntohs(hdr->sampling) & 0x3FFF );
3772     /* XXX: checking srate value instead of is_sampled as Sampling
3773        Mode seems not to be a mandatory field. */
3774     if (srate) {
3775       pdata->pkt_len = pdata->pkt_len * srate;
3776       pdata->pkt_num = pdata->pkt_num * srate;
3777 
3778       pptrs->renormalized = TRUE;
3779     }
3780     break;
3781   default:
3782     break;
3783   }
3784 }
3785 
NF_counters_map_renormalize_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3786 void NF_counters_map_renormalize_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3787 {
3788   struct pkt_data *pdata = (struct pkt_data *) *data;
3789   struct xflow_status_entry *xsentry = (struct xflow_status_entry *) pptrs->f_status;
3790 
3791   if (pptrs->renormalized) return;
3792 
3793   if (sampling_map_caching && xsentry && timeval_cmp(&xsentry->st.stamp, &reload_map_tstamp) > 0) {
3794     pptrs->st = xsentry->st.tag;
3795   }
3796   else {
3797     find_id_func((struct id_table *)pptrs->sampling_table, pptrs, &pptrs->st, NULL);
3798 
3799     if (xsentry) {
3800       xsentry->st.tag = pptrs->st;
3801       gettimeofday(&xsentry->st.stamp, NULL);
3802     }
3803   }
3804 
3805   if (pptrs->st) {
3806     pdata->pkt_len = pdata->pkt_len * pptrs->st;
3807     pdata->pkt_num = pdata->pkt_num * pptrs->st;
3808 
3809     pptrs->renormalized = TRUE;
3810   }
3811 }
3812 
bgp_ext_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)3813 void bgp_ext_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
3814 {
3815   struct pkt_data *pdata = (struct pkt_data *) *data;
3816   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
3817   struct pkt_legacy_bgp_primitives *plbgp = (struct pkt_legacy_bgp_primitives *) ((*data) + chptr->extras.off_pkt_lbgp_primitives);
3818   struct pkt_vlen_hdr_primitives *pvlen = (struct pkt_vlen_hdr_primitives *) ((*data) + chptr->extras.off_pkt_vlen_hdr_primitives);
3819   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
3820   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
3821   struct bgp_info *info = NULL;
3822 
3823   /* variables for vlen primitives */
3824   char empty_str = '\0', *ptr = &empty_str;
3825   int len;
3826 
3827   if (src_ret && evaluate_lm_method(pptrs, FALSE, chptr->plugin->cfg.nfacctd_as, NF_AS_BGP)) {
3828     info = (struct bgp_info *) pptrs->bgp_src_info;
3829     if (info && info->attr) {
3830       if (config.nfacctd_as & NF_AS_BGP) {
3831 	if (chptr->aggregation & COUNT_SRC_AS && info->attr->aspath) {
3832 	  pdata->primitives.src_as = evaluate_last_asn(info->attr->aspath);
3833 
3834 	  if (!pdata->primitives.src_as && config.bgp_daemon_stdcomm_pattern_to_asn) {
3835 	    char tmp_stdcomms[MAX_BGP_STD_COMMS];
3836 
3837 	    if (info->attr->community && info->attr->community->str) {
3838 	      evaluate_comm_patterns(tmp_stdcomms, info->attr->community->str, std_comm_patterns_to_asn, MAX_BGP_STD_COMMS);
3839 	      copy_stdcomm_to_asn(tmp_stdcomms, &pdata->primitives.src_as, TRUE);
3840 	    }
3841 	  }
3842 
3843 	  if (!pdata->primitives.src_as && config.bgp_daemon_lrgcomm_pattern_to_asn) {
3844 	    char tmp_lrgcomms[MAX_BGP_LRG_COMMS];
3845 
3846 	    if (info->attr->lcommunity && info->attr->lcommunity->str) {
3847 	      evaluate_comm_patterns(tmp_lrgcomms, info->attr->lcommunity->str, lrg_comm_patterns_to_asn, MAX_BGP_LRG_COMMS);
3848 	      copy_lrgcomm_to_asn(tmp_lrgcomms, &pdata->primitives.src_as, TRUE);
3849 	    }
3850 	  }
3851 	}
3852       }
3853       if (chptr->aggregation & COUNT_SRC_AS_PATH && info->attr->aspath && info->attr->aspath->str) {
3854         if (chptr->plugin->type.id != PLUGIN_ID_MEMORY) {
3855           len = strlen(info->attr->aspath->str);
3856 
3857           if (len && (config.bgp_daemon_src_as_path_type & BGP_SRC_PRIMITIVES_BGP)) {
3858             len++;
3859 
3860             if (config.bgp_daemon_aspath_radius) {
3861               ptr = strndup(info->attr->aspath->str, len);
3862 
3863               if (ptr) {
3864                 evaluate_bgp_aspath_radius(ptr, len, config.bgp_daemon_aspath_radius);
3865                 len = strlen(ptr);
3866                 len++;
3867               }
3868               else len = 0;
3869             }
3870             else ptr = info->attr->aspath->str;
3871           }
3872           else ptr = &empty_str;
3873 
3874           if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
3875             vlen_prims_init(pvlen, 0);
3876             return;
3877           }
3878           else vlen_prims_insert(pvlen, COUNT_INT_SRC_AS_PATH, len, (u_char *) ptr, PM_MSG_STR_COPY);
3879 
3880           if (config.bgp_daemon_aspath_radius && ptr && len) free(ptr);
3881         }
3882         /* fallback to legacy fixed length behaviour */
3883         else {
3884 	  if (config.bgp_daemon_src_as_path_type & BGP_SRC_PRIMITIVES_BGP) {
3885             strlcpy(plbgp->src_as_path, info->attr->aspath->str, MAX_BGP_ASPATH);
3886             if (strlen(info->attr->aspath->str) >= MAX_BGP_ASPATH) {
3887               plbgp->src_as_path[MAX_BGP_ASPATH-2] = '+';
3888               plbgp->src_as_path[MAX_BGP_ASPATH-1] = '\0';
3889             }
3890             if (config.bgp_daemon_aspath_radius)
3891               evaluate_bgp_aspath_radius(plbgp->src_as_path, MAX_BGP_ASPATH, config.bgp_daemon_aspath_radius);
3892 	  }
3893 	  else plbgp->src_as_path[0] = '\0';
3894         }
3895       }
3896       if (chptr->aggregation & COUNT_SRC_STD_COMM && info->attr->community && info->attr->community->str) {
3897         if (chptr->plugin->type.id != PLUGIN_ID_MEMORY) {
3898           len = strlen(info->attr->community->str);
3899 
3900           if (len && (config.bgp_daemon_src_std_comm_type & BGP_SRC_PRIMITIVES_BGP)) {
3901             len++;
3902 
3903             if (config.bgp_daemon_stdcomm_pattern) {
3904               ptr = malloc(len);
3905 
3906               if (ptr) {
3907                 evaluate_comm_patterns(ptr, info->attr->community->str, std_comm_patterns, len);
3908                 len = strlen(ptr);
3909                 len++;
3910               }
3911               else len = 0;
3912             }
3913             else ptr = info->attr->community->str;
3914           }
3915           else ptr = &empty_str;
3916 
3917           if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
3918             vlen_prims_init(pvlen, 0);
3919             return;
3920           }
3921           else {
3922             vlen_prims_insert(pvlen, COUNT_INT_SRC_STD_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
3923             if (config.bgp_daemon_stdcomm_pattern && ptr && len) free(ptr);
3924           }
3925         }
3926         /* fallback to legacy fixed length behaviour */
3927         else {
3928 	  if (config.bgp_daemon_src_std_comm_type & BGP_SRC_PRIMITIVES_BGP) {
3929             if (config.bgp_daemon_stdcomm_pattern)
3930               evaluate_comm_patterns(plbgp->src_std_comms, info->attr->community->str, std_comm_patterns, MAX_BGP_STD_COMMS);
3931             else {
3932               strlcpy(plbgp->src_std_comms, info->attr->community->str, MAX_BGP_STD_COMMS);
3933               if (strlen(info->attr->community->str) >= MAX_BGP_STD_COMMS) {
3934                 plbgp->src_std_comms[MAX_BGP_STD_COMMS-2] = '+';
3935                 plbgp->src_std_comms[MAX_BGP_STD_COMMS-1] = '\0';
3936 	      }
3937             }
3938           }
3939 	  else plbgp->src_std_comms[0] = '\0';
3940         }
3941       }
3942       if (chptr->aggregation & COUNT_SRC_EXT_COMM && info->attr->ecommunity && info->attr->ecommunity->str) {
3943         if (chptr->plugin->type.id != PLUGIN_ID_MEMORY) {
3944           len = strlen(info->attr->ecommunity->str);
3945 
3946           if (len && (config.bgp_daemon_src_ext_comm_type & BGP_SRC_PRIMITIVES_BGP)) {
3947             len++;
3948 
3949             if (config.bgp_daemon_extcomm_pattern) {
3950               ptr = malloc(len);
3951 
3952               if (ptr) {
3953                 evaluate_comm_patterns(ptr, info->attr->ecommunity->str, ext_comm_patterns, len);
3954                 len = strlen(ptr);
3955                 len++;
3956               }
3957               else len = 0;
3958             }
3959             else ptr = info->attr->ecommunity->str;
3960           }
3961           else ptr = &empty_str;
3962 
3963           if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
3964             vlen_prims_init(pvlen, 0);
3965             return;
3966           }
3967           else {
3968             vlen_prims_insert(pvlen, COUNT_INT_SRC_EXT_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
3969             if (config.bgp_daemon_extcomm_pattern && ptr && len) free(ptr);
3970           }
3971         }
3972         /* fallback to legacy fixed length behaviour */
3973         else {
3974 	  if (config.bgp_daemon_src_ext_comm_type & BGP_SRC_PRIMITIVES_BGP) {
3975             if (config.bgp_daemon_extcomm_pattern)
3976               evaluate_comm_patterns(plbgp->src_ext_comms, info->attr->ecommunity->str, ext_comm_patterns, MAX_BGP_EXT_COMMS);
3977             else {
3978               strlcpy(plbgp->src_ext_comms, info->attr->ecommunity->str, MAX_BGP_EXT_COMMS);
3979               if (strlen(info->attr->ecommunity->str) >= MAX_BGP_EXT_COMMS) {
3980                 plbgp->src_ext_comms[MAX_BGP_EXT_COMMS-2] = '+';
3981                 plbgp->src_ext_comms[MAX_BGP_EXT_COMMS-1] = '\0';
3982 	      }
3983             }
3984           }
3985 	  else plbgp->src_ext_comms[0] = '\0';
3986         }
3987       }
3988       if (chptr->aggregation_2 & COUNT_SRC_LRG_COMM && info->attr->lcommunity && info->attr->lcommunity->str) {
3989         if (chptr->plugin->type.id != PLUGIN_ID_MEMORY) {
3990           len = strlen(info->attr->lcommunity->str);
3991 
3992           if (len && (config.bgp_daemon_src_lrg_comm_type & BGP_SRC_PRIMITIVES_BGP)) {
3993             len++;
3994 
3995             if (config.bgp_daemon_lrgcomm_pattern) {
3996               ptr = malloc(len);
3997 
3998               if (ptr) {
3999                 evaluate_comm_patterns(ptr, info->attr->lcommunity->str, lrg_comm_patterns, len);
4000                 len = strlen(ptr);
4001                 len++;
4002               }
4003               else len = 0;
4004             }
4005             else ptr = info->attr->lcommunity->str;
4006           }
4007           else ptr = &empty_str;
4008 
4009           if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4010             vlen_prims_init(pvlen, 0);
4011             return;
4012           }
4013           else {
4014             vlen_prims_insert(pvlen, COUNT_INT_SRC_LRG_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
4015             if (config.bgp_daemon_lrgcomm_pattern && ptr && len) free(ptr);
4016           }
4017         }
4018         else {
4019 	  if (config.bgp_daemon_src_lrg_comm_type & BGP_SRC_PRIMITIVES_BGP) {
4020             if (config.bgp_daemon_lrgcomm_pattern)
4021               evaluate_comm_patterns(plbgp->src_lrg_comms, info->attr->lcommunity->str, lrg_comm_patterns, MAX_BGP_LRG_COMMS);
4022             else {
4023               strlcpy(plbgp->src_lrg_comms, info->attr->lcommunity->str, MAX_BGP_LRG_COMMS);
4024               if (strlen(info->attr->lcommunity->str) >= MAX_BGP_LRG_COMMS) {
4025                 plbgp->src_lrg_comms[MAX_BGP_LRG_COMMS-2] = '+';
4026                 plbgp->src_lrg_comms[MAX_BGP_LRG_COMMS-1] = '\0';
4027 	      }
4028             }
4029           }
4030 	  else plbgp->src_lrg_comms[0] = '\0';
4031         }
4032       }
4033       if (chptr->aggregation & COUNT_SRC_LOCAL_PREF && config.bgp_daemon_src_local_pref_type & BGP_SRC_PRIMITIVES_BGP)
4034 	pbgp->src_local_pref = info->attr->local_pref;
4035 
4036       if (chptr->aggregation & COUNT_SRC_MED && config.bgp_daemon_src_med_type & BGP_SRC_PRIMITIVES_BGP)
4037 	pbgp->src_med = info->attr->med;
4038 
4039       if (chptr->aggregation_2 & COUNT_SRC_ROA && config.bgp_daemon_src_roa_type & BGP_SRC_PRIMITIVES_BGP)
4040 	pbgp->src_roa = pptrs->src_roa;
4041 
4042       if (chptr->aggregation & COUNT_PEER_SRC_AS && config.bgp_daemon_peer_as_src_type & BGP_SRC_PRIMITIVES_BGP && info->attr->aspath && info->attr->aspath->str) {
4043         pbgp->peer_src_as = evaluate_first_asn(info->attr->aspath->str);
4044 
4045         if (!pbgp->peer_src_as && config.bgp_daemon_stdcomm_pattern_to_asn) {
4046           char tmp_stdcomms[MAX_BGP_STD_COMMS];
4047 
4048           if (info->attr->community && info->attr->community->str) {
4049             evaluate_comm_patterns(tmp_stdcomms, info->attr->community->str, std_comm_patterns_to_asn, MAX_BGP_STD_COMMS);
4050             copy_stdcomm_to_asn(tmp_stdcomms, &pbgp->peer_src_as, FALSE);
4051           }
4052         }
4053 
4054         if (!pbgp->peer_src_as && config.bgp_daemon_lrgcomm_pattern_to_asn) {
4055           char tmp_lrgcomms[MAX_BGP_LRG_COMMS];
4056 
4057           if (info->attr->lcommunity && info->attr->lcommunity->str) {
4058             evaluate_comm_patterns(tmp_lrgcomms, info->attr->lcommunity->str, lrg_comm_patterns_to_asn, MAX_BGP_LRG_COMMS);
4059             copy_lrgcomm_to_asn(tmp_lrgcomms, &pbgp->peer_src_as, FALSE);
4060           }
4061         }
4062       }
4063     }
4064   }
4065   /* take care of vlen primitives */
4066   else {
4067     if (chptr->plugin->type.id != PLUGIN_ID_MEMORY) {
4068       if (chptr->aggregation & COUNT_SRC_AS_PATH) {
4069         ptr = &empty_str;
4070         len = strlen(ptr);
4071 
4072         if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4073           vlen_prims_init(pvlen, 0);
4074           return;
4075         }
4076         else vlen_prims_insert(pvlen, COUNT_INT_SRC_AS_PATH, len, (u_char *) ptr, PM_MSG_STR_COPY);
4077       }
4078 
4079       if (chptr->aggregation & COUNT_SRC_STD_COMM) {
4080         ptr = &empty_str;
4081         len = strlen(ptr);
4082 
4083         if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4084           vlen_prims_init(pvlen, 0);
4085           return;
4086         }
4087         else vlen_prims_insert(pvlen, COUNT_INT_SRC_STD_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
4088       }
4089 
4090       if (chptr->aggregation & COUNT_SRC_EXT_COMM) {
4091         ptr = &empty_str;
4092         len = strlen(ptr);
4093 
4094         if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4095           vlen_prims_init(pvlen, 0);
4096           return;
4097         }
4098         else vlen_prims_insert(pvlen, COUNT_INT_SRC_EXT_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
4099       }
4100 
4101       if (chptr->aggregation_2 & COUNT_SRC_LRG_COMM) {
4102         ptr = &empty_str;
4103         len = strlen(ptr);
4104 
4105         if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4106           vlen_prims_init(pvlen, 0);
4107           return;
4108         }
4109         else vlen_prims_insert(pvlen, COUNT_INT_SRC_LRG_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
4110       }
4111     }
4112   }
4113 
4114   if (dst_ret && evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_as, NF_AS_BGP)) {
4115     info = (struct bgp_info *) pptrs->bgp_dst_info;
4116     if (info && info->attr) {
4117       if (chptr->aggregation & COUNT_STD_COMM && info->attr->community && info->attr->community->str) {
4118         if (chptr->plugin->type.id != PLUGIN_ID_MEMORY) {
4119           len = strlen(info->attr->community->str);
4120 
4121           if (len) {
4122 	    len++;
4123 
4124             if (config.bgp_daemon_stdcomm_pattern) {
4125               ptr = malloc(len);
4126 
4127               if (ptr) {
4128                 evaluate_comm_patterns(ptr, info->attr->community->str, std_comm_patterns, len);
4129                 len = strlen(ptr);
4130 		len++;
4131               }
4132               else len = 0;
4133             }
4134             else ptr = info->attr->community->str;
4135           }
4136           else ptr = &empty_str;
4137 
4138           if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4139             vlen_prims_init(pvlen, 0);
4140             return;
4141           }
4142           else {
4143             vlen_prims_insert(pvlen, COUNT_INT_STD_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
4144             if (config.bgp_daemon_stdcomm_pattern && ptr && len) free(ptr);
4145           }
4146         }
4147         /* fallback to legacy fixed length behaviour */
4148 	else {
4149 	  if (config.bgp_daemon_stdcomm_pattern)
4150 	    evaluate_comm_patterns(plbgp->std_comms, info->attr->community->str, std_comm_patterns, MAX_BGP_STD_COMMS);
4151 	  else {
4152             strlcpy(plbgp->std_comms, info->attr->community->str, MAX_BGP_STD_COMMS);
4153 	    if (strlen(info->attr->community->str) >= MAX_BGP_STD_COMMS) {
4154 	      plbgp->std_comms[MAX_BGP_STD_COMMS-2] = '+';
4155 	      plbgp->std_comms[MAX_BGP_STD_COMMS-1] = '\0';
4156 	    }
4157 	  }
4158 	}
4159       }
4160       if (chptr->aggregation & COUNT_EXT_COMM && info->attr->ecommunity && info->attr->ecommunity->str) {
4161         if (chptr->plugin->type.id != PLUGIN_ID_MEMORY) {
4162           len = strlen(info->attr->ecommunity->str);
4163 
4164           if (len) {
4165 	    len++;
4166 
4167             if (config.bgp_daemon_extcomm_pattern) {
4168               ptr = malloc(len);
4169 
4170               if (ptr) {
4171                 evaluate_comm_patterns(ptr, info->attr->ecommunity->str, ext_comm_patterns, len);
4172                 len = strlen(ptr);
4173 		len++;
4174               }
4175               else len = 0;
4176             }
4177             else ptr = info->attr->ecommunity->str;
4178           }
4179           else ptr = &empty_str;
4180 
4181           if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4182             vlen_prims_init(pvlen, 0);
4183             return;
4184           }
4185           else {
4186             vlen_prims_insert(pvlen, COUNT_INT_EXT_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
4187             if (config.bgp_daemon_extcomm_pattern && ptr && len) free(ptr);
4188           }
4189         }
4190         /* fallback to legacy fixed length behaviour */
4191         else {
4192 	  if (config.bgp_daemon_extcomm_pattern)
4193 	    evaluate_comm_patterns(plbgp->ext_comms, info->attr->ecommunity->str, ext_comm_patterns, MAX_BGP_EXT_COMMS);
4194 	  else {
4195             strlcpy(plbgp->ext_comms, info->attr->ecommunity->str, MAX_BGP_EXT_COMMS);
4196 	    if (strlen(info->attr->ecommunity->str) >= MAX_BGP_EXT_COMMS) {
4197 	      plbgp->ext_comms[MAX_BGP_EXT_COMMS-2] = '+';
4198 	      plbgp->ext_comms[MAX_BGP_EXT_COMMS-1] = '\0';
4199 	    }
4200 	  }
4201         }
4202       }
4203       if (chptr->aggregation_2 & COUNT_LRG_COMM && info->attr->lcommunity && info->attr->lcommunity->str) {
4204         if (chptr->plugin->type.id != PLUGIN_ID_MEMORY) {
4205           len = strlen(info->attr->lcommunity->str);
4206 
4207           if (len) {
4208             len++;
4209 
4210             if (config.bgp_daemon_lrgcomm_pattern) {
4211               ptr = malloc(len);
4212 
4213               if (ptr) {
4214                 evaluate_comm_patterns(ptr, info->attr->lcommunity->str, lrg_comm_patterns, len);
4215                 len = strlen(ptr);
4216                 len++;
4217               }
4218               else len = 0;
4219             }
4220             else ptr = info->attr->lcommunity->str;
4221           }
4222           else ptr = &empty_str;
4223 
4224           if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4225             vlen_prims_init(pvlen, 0);
4226             return;
4227           }
4228           else {
4229             vlen_prims_insert(pvlen, COUNT_INT_LRG_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
4230             if (config.bgp_daemon_lrgcomm_pattern && ptr && len) free(ptr);
4231           }
4232         }
4233         /* fallback to legacy fixed length behaviour */
4234         else {
4235           if (config.bgp_daemon_lrgcomm_pattern)
4236             evaluate_comm_patterns(plbgp->lrg_comms, info->attr->lcommunity->str, lrg_comm_patterns, MAX_BGP_LRG_COMMS);
4237           else {
4238             strlcpy(plbgp->lrg_comms, info->attr->lcommunity->str, MAX_BGP_LRG_COMMS);
4239             if (strlen(info->attr->lcommunity->str) >= MAX_BGP_LRG_COMMS) {
4240               plbgp->lrg_comms[MAX_BGP_LRG_COMMS-2] = '+';
4241               plbgp->lrg_comms[MAX_BGP_LRG_COMMS-1] = '\0';
4242             }
4243           }
4244         }
4245       }
4246       if (chptr->aggregation & COUNT_AS_PATH && info->attr->aspath && info->attr->aspath->str) {
4247 	if (chptr->plugin->type.id != PLUGIN_ID_MEMORY) {
4248           len = strlen(info->attr->aspath->str);
4249 
4250           if (len) {
4251 	    len++;
4252 
4253             if (config.bgp_daemon_aspath_radius) {
4254               ptr = strndup(info->attr->aspath->str, len);
4255 
4256               if (ptr) {
4257                 evaluate_bgp_aspath_radius(ptr, len, config.bgp_daemon_aspath_radius);
4258                 len = strlen(ptr);
4259 		len++;
4260               }
4261               else len = 0;
4262             }
4263             else ptr = info->attr->aspath->str;
4264           }
4265           else ptr = &empty_str;
4266 
4267           if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4268             vlen_prims_init(pvlen, 0);
4269             return;
4270           }
4271           else vlen_prims_insert(pvlen, COUNT_INT_AS_PATH, len, (u_char *) ptr, PM_MSG_STR_COPY);
4272 
4273           if (config.bgp_daemon_aspath_radius && ptr && len) free(ptr);
4274 	}
4275 	/* fallback to legacy fixed length behaviour */
4276 	else {
4277 	  strlcpy(plbgp->as_path, info->attr->aspath->str, MAX_BGP_ASPATH);
4278 	  if (strlen(info->attr->aspath->str) >= MAX_BGP_ASPATH) {
4279 	    plbgp->as_path[MAX_BGP_ASPATH-2] = '+';
4280 	    plbgp->as_path[MAX_BGP_ASPATH-1] = '\0';
4281 	  }
4282 	  if (config.bgp_daemon_aspath_radius)
4283 	    evaluate_bgp_aspath_radius(plbgp->as_path, MAX_BGP_ASPATH, config.bgp_daemon_aspath_radius);
4284 	}
4285       }
4286       if (config.nfacctd_as & NF_AS_BGP) {
4287         if (chptr->aggregation & COUNT_DST_AS && info->attr->aspath) {
4288           pdata->primitives.dst_as = evaluate_last_asn(info->attr->aspath);
4289 
4290           if (!pdata->primitives.dst_as && config.bgp_daemon_stdcomm_pattern_to_asn) {
4291             char tmp_stdcomms[MAX_BGP_STD_COMMS];
4292 
4293             if (info->attr->community && info->attr->community->str) {
4294               evaluate_comm_patterns(tmp_stdcomms, info->attr->community->str, std_comm_patterns_to_asn, MAX_BGP_STD_COMMS);
4295               copy_stdcomm_to_asn(tmp_stdcomms, &pdata->primitives.dst_as, TRUE);
4296             }
4297 	  }
4298 
4299           if (!pdata->primitives.dst_as && config.bgp_daemon_lrgcomm_pattern_to_asn) {
4300             char tmp_lrgcomms[MAX_BGP_LRG_COMMS];
4301 
4302             if (info->attr->lcommunity && info->attr->lcommunity->str) {
4303               evaluate_comm_patterns(tmp_lrgcomms, info->attr->lcommunity->str, lrg_comm_patterns_to_asn, MAX_BGP_LRG_COMMS);
4304               copy_lrgcomm_to_asn(tmp_lrgcomms, &pdata->primitives.dst_as, TRUE);
4305             }
4306 	  }
4307         }
4308       }
4309 
4310       if (chptr->aggregation & COUNT_LOCAL_PREF) pbgp->local_pref = info->attr->local_pref;
4311 
4312       if (chptr->aggregation & COUNT_MED) pbgp->med = info->attr->med;
4313 
4314       if (chptr->aggregation_2 & COUNT_DST_ROA) pbgp->dst_roa = pptrs->dst_roa;
4315 
4316       if (chptr->aggregation & COUNT_PEER_DST_AS && info->attr->aspath && info->attr->aspath->str) {
4317         pbgp->peer_dst_as = evaluate_first_asn(info->attr->aspath->str);
4318 
4319         if (!pbgp->peer_dst_as && config.bgp_daemon_stdcomm_pattern_to_asn) {
4320           char tmp_stdcomms[MAX_BGP_STD_COMMS];
4321 
4322           if (info->attr->community && info->attr->community->str) {
4323             evaluate_comm_patterns(tmp_stdcomms, info->attr->community->str, std_comm_patterns_to_asn, MAX_BGP_STD_COMMS);
4324             copy_stdcomm_to_asn(tmp_stdcomms, &pbgp->peer_dst_as, FALSE);
4325           }
4326         }
4327 
4328         if (!pbgp->peer_dst_as && config.bgp_daemon_lrgcomm_pattern_to_asn) {
4329           char tmp_lrgcomms[MAX_BGP_LRG_COMMS];
4330 
4331           if (info->attr->lcommunity && info->attr->lcommunity->str) {
4332             evaluate_comm_patterns(tmp_lrgcomms, info->attr->lcommunity->str, lrg_comm_patterns_to_asn, MAX_BGP_LRG_COMMS);
4333             copy_lrgcomm_to_asn(tmp_lrgcomms, &pbgp->peer_dst_as, FALSE);
4334           }
4335         }
4336       }
4337     }
4338   }
4339   /* take care of vlen primitives */
4340   else {
4341     if (chptr->plugin->type.id != PLUGIN_ID_MEMORY) {
4342       if (chptr->aggregation & COUNT_AS_PATH) {
4343         ptr = &empty_str;
4344         len = strlen(ptr);
4345 
4346         if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4347           vlen_prims_init(pvlen, 0);
4348           return;
4349         }
4350         else vlen_prims_insert(pvlen, COUNT_INT_AS_PATH, len, (u_char *) ptr, PM_MSG_STR_COPY);
4351       }
4352 
4353       if (chptr->aggregation & COUNT_STD_COMM) {
4354         ptr = &empty_str;
4355         len = strlen(ptr);
4356 
4357         if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4358           vlen_prims_init(pvlen, 0);
4359           return;
4360         }
4361         else vlen_prims_insert(pvlen, COUNT_INT_STD_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
4362       }
4363 
4364       if (chptr->aggregation & COUNT_EXT_COMM) {
4365         ptr = &empty_str;
4366         len = strlen(ptr);
4367 
4368         if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4369           vlen_prims_init(pvlen, 0);
4370           return;
4371         }
4372         else vlen_prims_insert(pvlen, COUNT_INT_EXT_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
4373       }
4374 
4375       if (chptr->aggregation_2 & COUNT_LRG_COMM) {
4376         ptr = &empty_str;
4377         len = strlen(ptr);
4378 
4379         if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4380           vlen_prims_init(pvlen, 0);
4381           return;
4382         }
4383         else vlen_prims_insert(pvlen, COUNT_INT_LRG_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
4384       }
4385     }
4386   }
4387 }
4388 
sfprobe_bgp_ext_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4389 void sfprobe_bgp_ext_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4390 {
4391   struct pkt_payload *payload = (struct pkt_payload *) *data;
4392   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
4393   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
4394   struct bgp_info *info = NULL;
4395 
4396   if (src_ret && evaluate_lm_method(pptrs, FALSE, chptr->plugin->cfg.nfacctd_as, NF_AS_BGP)) {
4397     info = (struct bgp_info *) pptrs->bgp_src_info;
4398     if (info && info->attr) {
4399       if (config.nfacctd_as & NF_AS_BGP) {
4400 	if (chptr->aggregation & COUNT_SRC_AS && info->attr->aspath) {
4401 	  if (!chptr->plugin->cfg.nfprobe_peer_as)
4402 	    payload->src_as = evaluate_last_asn(info->attr->aspath);
4403 	  else
4404             payload->src_as = evaluate_first_asn(info->attr->aspath->str);
4405 	}
4406       }
4407     }
4408   }
4409 
4410   if (dst_ret && evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_as, NF_AS_BGP)) {
4411     info = (struct bgp_info *) pptrs->bgp_dst_info;
4412     if (info && info->attr) {
4413       if (config.nfacctd_as & NF_AS_BGP) {
4414         if (chptr->aggregation & COUNT_DST_AS && info->attr->aspath) {
4415 	  if (!chptr->plugin->cfg.nfprobe_peer_as)
4416             payload->dst_as = evaluate_last_asn(info->attr->aspath);
4417           else
4418 	    payload->dst_as = evaluate_first_asn(info->attr->aspath->str);
4419 	}
4420       }
4421     }
4422   }
4423 }
4424 
nfprobe_bgp_ext_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4425 void nfprobe_bgp_ext_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4426 {
4427   struct pkt_data *pdata = (struct pkt_data *) *data;
4428   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
4429   struct bgp_node *dst_ret = (struct bgp_node *) pptrs->bgp_dst;
4430   struct bgp_info *info = NULL;
4431 
4432   --pdata; /* Bringing back to original place */
4433 
4434   if (src_ret && evaluate_lm_method(pptrs, FALSE, chptr->plugin->cfg.nfacctd_as, NF_AS_BGP)) {
4435     info = (struct bgp_info *) pptrs->bgp_src_info;
4436     if (info && info->attr) {
4437       if (config.nfacctd_as & NF_AS_BGP) {
4438         if (chptr->aggregation & COUNT_SRC_AS && info->attr->aspath) {
4439           if (!chptr->plugin->cfg.nfprobe_peer_as)
4440             pdata->primitives.src_as = evaluate_last_asn(info->attr->aspath);
4441           else
4442             pdata->primitives.src_as = evaluate_first_asn(info->attr->aspath->str);
4443         }
4444       }
4445     }
4446   }
4447 
4448   if (dst_ret && evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_as, NF_AS_BGP)) {
4449     info = (struct bgp_info *) pptrs->bgp_dst_info;
4450     if (info && info->attr) {
4451       if (config.nfacctd_as & NF_AS_BGP) {
4452         if (chptr->aggregation & COUNT_DST_AS && info->attr->aspath) {
4453           if (!chptr->plugin->cfg.nfprobe_peer_as)
4454             pdata->primitives.dst_as = evaluate_last_asn(info->attr->aspath);
4455           else
4456             pdata->primitives.dst_as = evaluate_first_asn(info->attr->aspath->str);
4457         }
4458       }
4459     }
4460   }
4461 }
4462 
bgp_peer_src_as_frommap_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4463 void bgp_peer_src_as_frommap_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4464 {
4465   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
4466   struct bgp_node *src_ret = (struct bgp_node *) pptrs->bgp_src;
4467   struct bgp_info *info = NULL;
4468 
4469   pbgp->peer_src_as = pptrs->bpas;
4470 
4471   /* XXX: extra check: was src_as written by copy_stdcomm_to_asn() ? */
4472 
4473   if (!pbgp->peer_src_as && config.bgp_daemon_stdcomm_pattern_to_asn) {
4474     if (src_ret) {
4475       char tmp_stdcomms[MAX_BGP_STD_COMMS];
4476 
4477       info = (struct bgp_info *) pptrs->bgp_src_info;
4478 
4479       if (info && info->attr && info->attr->community && info->attr->community->str) {
4480         evaluate_comm_patterns(tmp_stdcomms, info->attr->community->str, std_comm_patterns_to_asn, MAX_BGP_STD_COMMS);
4481         copy_stdcomm_to_asn(tmp_stdcomms, &pbgp->peer_src_as, FALSE);
4482       }
4483     }
4484   }
4485 
4486   if (!pbgp->peer_src_as && config.bgp_daemon_lrgcomm_pattern_to_asn) {
4487     if (src_ret) {
4488       char tmp_lrgcomms[MAX_BGP_LRG_COMMS];
4489 
4490       info = (struct bgp_info *) pptrs->bgp_src_info;
4491 
4492       if (info && info->attr && info->attr->lcommunity && info->attr->lcommunity->str) {
4493         evaluate_comm_patterns(tmp_lrgcomms, info->attr->lcommunity->str, lrg_comm_patterns_to_asn, MAX_BGP_LRG_COMMS);
4494         copy_lrgcomm_to_asn(tmp_lrgcomms, &pbgp->peer_src_as, FALSE);
4495       }
4496     }
4497   }
4498 }
4499 
bgp_src_local_pref_frommap_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4500 void bgp_src_local_pref_frommap_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4501 {
4502   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
4503 
4504   pbgp->src_local_pref = pptrs->blp;
4505 }
4506 
bgp_src_med_frommap_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4507 void bgp_src_med_frommap_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4508 {
4509   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
4510 
4511   pbgp->src_med = pptrs->bmed;
4512 }
4513 
4514 #if defined (HAVE_L2)
SF_src_mac_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4515 void SF_src_mac_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4516 {
4517   struct pkt_data *pdata = (struct pkt_data *) *data;
4518   SFSample *sample = (SFSample *) pptrs->f_data;
4519 
4520   memcpy(pdata->primitives.eth_shost, sample->eth_src, ETH_ADDR_LEN);
4521 }
4522 
SF_dst_mac_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4523 void SF_dst_mac_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4524 {
4525   struct pkt_data *pdata = (struct pkt_data *) *data;
4526   SFSample *sample = (SFSample *) pptrs->f_data;
4527 
4528   memcpy(pdata->primitives.eth_dhost, sample->eth_dst, ETH_ADDR_LEN);
4529 }
4530 
SF_vlan_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4531 void SF_vlan_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4532 {
4533   struct pkt_data *pdata = (struct pkt_data *) *data;
4534   SFSample *sample = (SFSample *) pptrs->f_data;
4535 
4536   pdata->primitives.vlan_id = sample->in_vlan;
4537   if (!pdata->primitives.vlan_id) pdata->primitives.vlan_id = sample->out_vlan;
4538 }
4539 
SF_cos_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4540 void SF_cos_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4541 {
4542   struct pkt_data *pdata = (struct pkt_data *) *data;
4543   SFSample *sample = (SFSample *) pptrs->f_data;
4544 
4545   pdata->primitives.cos = sample->in_priority;
4546   if (!pdata->primitives.cos) pdata->primitives.cos = sample->out_priority;
4547 }
4548 
SF_etype_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4549 void SF_etype_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4550 {
4551   struct pkt_data *pdata = (struct pkt_data *) *data;
4552   SFSample *sample = (SFSample *) pptrs->f_data;
4553 
4554   pdata->primitives.etype = sample->eth_type;
4555 }
4556 #endif
4557 
SF_src_host_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4558 void SF_src_host_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4559 {
4560   struct pkt_data *pdata = (struct pkt_data *) *data;
4561   SFSample *sample = (SFSample *) pptrs->f_data;
4562   SFLAddress *addr = &sample->ipsrc;
4563 
4564   if (sample->gotIPV4) {
4565     pdata->primitives.src_ip.address.ipv4.s_addr = sample->dcd_srcIP.s_addr;
4566     pdata->primitives.src_ip.family = AF_INET;
4567   }
4568   else if (sample->gotIPV6) {
4569     memcpy(&pdata->primitives.src_ip.address.ipv6, &addr->address.ip_v6, IP6AddrSz);
4570     pdata->primitives.src_ip.family = AF_INET6;
4571   }
4572 }
4573 
SF_dst_host_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4574 void SF_dst_host_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4575 {
4576   struct pkt_data *pdata = (struct pkt_data *) *data;
4577   SFSample *sample = (SFSample *) pptrs->f_data;
4578   SFLAddress *addr = &sample->ipdst;
4579 
4580   if (sample->gotIPV4) {
4581     pdata->primitives.dst_ip.address.ipv4.s_addr = sample->dcd_dstIP.s_addr;
4582     pdata->primitives.dst_ip.family = AF_INET;
4583   }
4584   else if (sample->gotIPV6) {
4585     memcpy(&pdata->primitives.dst_ip.address.ipv6, &addr->address.ip_v6, IP6AddrSz);
4586     pdata->primitives.dst_ip.family = AF_INET6;
4587   }
4588 }
4589 
SF_src_nmask_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4590 void SF_src_nmask_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4591 {
4592   struct pkt_data *pdata = (struct pkt_data *) *data;
4593   SFSample *sample = (SFSample *) pptrs->f_data;
4594 
4595   /* check network-related primitives against fallback scenarios */
4596   if (!evaluate_lm_method(pptrs, FALSE, chptr->plugin->cfg.nfacctd_net, NF_NET_KEEP)) return;
4597 
4598   pdata->primitives.src_nmask = sample->srcMask;
4599 }
4600 
SF_dst_nmask_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4601 void SF_dst_nmask_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4602 {
4603   struct pkt_data *pdata = (struct pkt_data *) *data;
4604   SFSample *sample = (SFSample *) pptrs->f_data;
4605 
4606   /* check network-related primitives against fallback scenarios */
4607   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_net, NF_NET_KEEP)) return;
4608 
4609   pdata->primitives.dst_nmask = sample->dstMask;
4610 }
4611 
SF_src_port_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4612 void SF_src_port_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4613 {
4614   struct pkt_data *pdata = (struct pkt_data *) *data;
4615   SFSample *sample = (SFSample *) pptrs->f_data;
4616 
4617   if (sample->dcd_ipProtocol == IPPROTO_UDP || sample->dcd_ipProtocol == IPPROTO_TCP) {
4618     pdata->primitives.src_port = sample->dcd_sport;
4619   }
4620   else pdata->primitives.src_port = 0;
4621 }
4622 
SF_dst_port_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4623 void SF_dst_port_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4624 {
4625   struct pkt_data *pdata = (struct pkt_data *) *data;
4626   SFSample *sample = (SFSample *) pptrs->f_data;
4627 
4628   if (sample->dcd_ipProtocol == IPPROTO_UDP || sample->dcd_ipProtocol == IPPROTO_TCP) {
4629     pdata->primitives.dst_port = sample->dcd_dport;
4630   }
4631   else pdata->primitives.dst_port = 0;
4632 }
4633 
SF_ip_tos_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4634 void SF_ip_tos_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4635 {
4636   struct pkt_data *pdata = (struct pkt_data *) *data;
4637   SFSample *sample = (SFSample *) pptrs->f_data;
4638 
4639   pdata->primitives.tos = sample->dcd_ipTos;
4640 }
4641 
SF_ip_proto_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4642 void SF_ip_proto_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4643 {
4644   struct pkt_data *pdata = (struct pkt_data *) *data;
4645   SFSample *sample = (SFSample *) pptrs->f_data;
4646 
4647   pdata->primitives.proto = sample->dcd_ipProtocol;
4648 }
4649 
SF_tcp_flags_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4650 void SF_tcp_flags_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4651 {
4652   struct pkt_data *pdata = (struct pkt_data *) *data;
4653   SFSample *sample = (SFSample *) pptrs->f_data;
4654 
4655   if (sample->dcd_ipProtocol == IPPROTO_TCP) {
4656     pdata->tcp_flags = sample->dcd_tcpFlags;
4657   }
4658 }
4659 
SF_flows_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4660 void SF_flows_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4661 {
4662   struct pkt_data *pdata = (struct pkt_data *) *data;
4663   pdata->flo_num = 1;
4664 }
4665 
SF_counters_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4666 void SF_counters_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4667 {
4668   struct pkt_data *pdata = (struct pkt_data *) *data;
4669   SFSample *sample = (SFSample *) pptrs->f_data;
4670 
4671   pdata->pkt_len = sample->sampledPacketSize;
4672   pdata->pkt_num = 1;
4673 
4674   if (!config.nfacctd_time_new && sample->ts) {
4675     pdata->time_start.tv_sec = sample->ts->tv_sec;
4676     pdata->time_start.tv_usec = sample->ts->tv_usec;
4677   }
4678   else {
4679     pdata->time_start.tv_sec = 0;
4680     pdata->time_start.tv_usec = 0;
4681   }
4682 
4683   pdata->time_end.tv_sec = 0;
4684   pdata->time_end.tv_usec = 0;
4685 
4686   pdata->flow_type = pptrs->flow_type;
4687 
4688   /* XXX: fragment handling */
4689 }
4690 
SF_counters_renormalize_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4691 void SF_counters_renormalize_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4692 {
4693   struct xflow_status_entry *entry = (struct xflow_status_entry *) pptrs->f_status;
4694   struct xflow_status_entry_sampling *sentry = NULL;
4695   struct pkt_data *pdata = (struct pkt_data *) *data;
4696   SFSample *sample = (SFSample *) pptrs->f_data;
4697   u_int32_t eff_srate = 0;
4698 
4699   if (pptrs->renormalized) return;
4700 
4701   if (entry) sentry = search_smp_if_status_table(entry->sampling, (sample->ds_class << 24 | sample->ds_index));
4702   if (sentry) {
4703     /* flow sequence number is strictly increasing; however we need a) to avoid
4704        a division-by-zero by checking the last value and the new one and b) to
4705        deal with out-of-order datagrams */
4706     if (sample->samplesGenerated > sentry->seqno && sample->samplePool > sentry->sample_pool) {
4707       eff_srate = (sample->samplePool-sentry->sample_pool) / (sample->samplesGenerated-sentry->seqno);
4708       pdata->pkt_len = pdata->pkt_len * eff_srate;
4709       pdata->pkt_num = pdata->pkt_num * eff_srate;
4710 
4711       sentry->sample_pool = sample->samplePool;
4712       sentry->seqno = sample->samplesGenerated;
4713 
4714       return;
4715     }
4716     /* Let's handle long positive/negative jumps as resets */
4717     else if (MAX(sample->samplesGenerated, sentry->seqno) >
4718 	    (MIN(sample->samplesGenerated, sentry->seqno)+XFLOW_RESET_BOUNDARY)) {
4719       sentry->sample_pool = sample->samplePool;
4720       sentry->seqno = sample->samplesGenerated;
4721     }
4722   }
4723   else {
4724     if (entry) sentry = create_smp_entry_status_table(entry);
4725     if (sentry) {
4726       sentry->interface = (sample->ds_class << 24 | sample->ds_index);
4727       sentry->sample_pool = sample->samplePool;
4728       sentry->seqno = sample->samplesGenerated;
4729     }
4730   }
4731 
4732   pdata->pkt_len = pdata->pkt_len * sample->meanSkipCount;
4733   pdata->pkt_num = pdata->pkt_num * sample->meanSkipCount;
4734 
4735   pptrs->renormalized = TRUE;
4736 }
4737 
SF_counters_map_renormalize_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4738 void SF_counters_map_renormalize_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4739 {
4740   struct pkt_data *pdata = (struct pkt_data *) *data;
4741   struct xflow_status_entry *xsentry = (struct xflow_status_entry *) pptrs->f_status;
4742 
4743   if (pptrs->renormalized) return;
4744 
4745   if (sampling_map_caching && xsentry && timeval_cmp(&xsentry->st.stamp, &reload_map_tstamp) > 0) {
4746     pptrs->st = xsentry->st.tag;
4747   }
4748   else {
4749     find_id_func((struct id_table *)pptrs->sampling_table, pptrs, &pptrs->st, NULL);
4750 
4751     if (xsentry) {
4752       xsentry->st.tag = pptrs->st;
4753       gettimeofday(&xsentry->st.stamp, NULL);
4754     }
4755   }
4756 
4757   if (pptrs->st) {
4758     pdata->pkt_len = pdata->pkt_len * pptrs->st;
4759     pdata->pkt_num = pdata->pkt_num * pptrs->st;
4760 
4761     pptrs->renormalized = TRUE;
4762   }
4763 }
4764 
SF_src_as_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4765 void SF_src_as_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4766 {
4767   struct pkt_data *pdata = (struct pkt_data *) *data;
4768   SFSample *sample = (SFSample *) pptrs->f_data;
4769   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
4770 
4771   /* check network-related primitives against fallback scenarios */
4772   if (!evaluate_lm_method(pptrs, FALSE, chptr->plugin->cfg.nfacctd_as, NF_AS_KEEP)) return;
4773 
4774   pdata->primitives.src_as = sample->src_as;
4775 
4776   if (chptr->plugin->cfg.nfprobe_peer_as) {
4777     if (chptr->aggregation & COUNT_PEER_SRC_AS) pbgp->peer_src_as = pdata->primitives.src_as;
4778     pdata->primitives.src_as = 0;
4779   }
4780 }
4781 
SF_dst_as_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4782 void SF_dst_as_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4783 {
4784   struct pkt_data *pdata = (struct pkt_data *) *data;
4785   SFSample *sample = (SFSample *) pptrs->f_data;
4786   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
4787 
4788   /* check network-related primitives against fallback scenarios */
4789   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_as, NF_AS_KEEP)) return;
4790 
4791   pdata->primitives.dst_as = sample->dst_as;
4792 
4793   if (chptr->plugin->cfg.nfprobe_peer_as) {
4794     if (chptr->aggregation & COUNT_PEER_DST_AS) pbgp->peer_dst_as = pdata->primitives.dst_as;
4795     pdata->primitives.dst_as = 0;
4796   }
4797 }
4798 
SF_as_path_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4799 void SF_as_path_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4800 {
4801   SFSample *sample = (SFSample *) pptrs->f_data;
4802   struct pkt_legacy_bgp_primitives *plbgp = (struct pkt_legacy_bgp_primitives *) ((*data) + chptr->extras.off_pkt_lbgp_primitives);
4803   struct pkt_vlen_hdr_primitives *pvlen = (struct pkt_vlen_hdr_primitives *) ((*data) + chptr->extras.off_pkt_vlen_hdr_primitives);
4804 
4805   /* variables for vlen primitives */
4806   char empty_str = '\0', *ptr = &empty_str;
4807   int len;
4808 
4809   /* check network-related primitives against fallback scenarios */
4810   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_as, NF_AS_KEEP)) return;
4811 
4812   if (chptr->plugin->type.id != PLUGIN_ID_MEMORY) {
4813     len = strlen(sample->dst_as_path);
4814 
4815     if (len) {
4816       len++;
4817 
4818       if (config.bgp_daemon_aspath_radius) {
4819         ptr = strndup(sample->dst_as_path, len);
4820 
4821         if (ptr) {
4822           evaluate_bgp_aspath_radius(ptr, len, config.bgp_daemon_aspath_radius);
4823           len = strlen(ptr);
4824 	  len++;
4825         }
4826         else len = 0;
4827       }
4828       else ptr = sample->dst_as_path;
4829     }
4830 
4831     if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4832       vlen_prims_init(pvlen, 0);
4833       return;
4834     }
4835     else vlen_prims_insert(pvlen, COUNT_INT_AS_PATH, len, (u_char *) ptr, PM_MSG_STR_COPY);
4836 
4837     if (config.bgp_daemon_aspath_radius && ptr && len) free(ptr);
4838   }
4839   /* fallback to legacy fixed length behaviour */
4840   else {
4841     if (sample->dst_as_path_len) {
4842       strlcpy(plbgp->as_path, sample->dst_as_path, MAX_BGP_ASPATH);
4843       if (strlen(sample->dst_as_path)) {
4844 	plbgp->as_path[MAX_BGP_ASPATH-2] = '+';
4845 	plbgp->as_path[MAX_BGP_ASPATH-1] = '\0';
4846       }
4847 
4848       if (config.bgp_daemon_aspath_radius)
4849         evaluate_bgp_aspath_radius(plbgp->as_path, MAX_BGP_ASPATH, config.bgp_daemon_aspath_radius);
4850     }
4851   }
4852 }
4853 
SF_peer_src_as_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4854 void SF_peer_src_as_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4855 {
4856   SFSample *sample = (SFSample *) pptrs->f_data;
4857   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
4858 
4859   /* check network-related primitives against fallback scenarios */
4860   if (!evaluate_lm_method(pptrs, FALSE, chptr->plugin->cfg.nfacctd_as, NF_AS_KEEP)) return;
4861 
4862   pbgp->peer_src_as = sample->src_peer_as;
4863 }
4864 
SF_peer_dst_as_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4865 void SF_peer_dst_as_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4866 {
4867   SFSample *sample = (SFSample *) pptrs->f_data;
4868   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
4869 
4870   /* check network-related primitives against fallback scenarios */
4871   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_as, NF_AS_KEEP)) return;
4872 
4873   pbgp->peer_dst_as = sample->dst_peer_as;
4874 }
4875 
SF_local_pref_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4876 void SF_local_pref_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4877 {
4878   SFSample *sample = (SFSample *) pptrs->f_data;
4879   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
4880 
4881   /* check network-related primitives against fallback scenarios */
4882   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_as, NF_AS_KEEP)) return;
4883 
4884   pbgp->local_pref = sample->localpref;
4885 }
4886 
SF_std_comms_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4887 void SF_std_comms_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4888 {
4889   SFSample *sample = (SFSample *) pptrs->f_data;
4890   struct pkt_legacy_bgp_primitives *plbgp = (struct pkt_legacy_bgp_primitives *) ((*data) + chptr->extras.off_pkt_lbgp_primitives);
4891   struct pkt_vlen_hdr_primitives *pvlen = (struct pkt_vlen_hdr_primitives *) ((*data) + chptr->extras.off_pkt_vlen_hdr_primitives);
4892 
4893   /* variables for vlen primitives */
4894   char empty_str = '\0', *ptr = &empty_str;
4895   int len;
4896 
4897   /* check network-related primitives against fallback scenarios */
4898   if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_as, NF_AS_KEEP)) return;
4899 
4900   if (chptr->plugin->type.id != PLUGIN_ID_MEMORY) {
4901     len = strlen(sample->comms);
4902 
4903     if (len) {
4904       len++;
4905 
4906       if (config.bgp_daemon_stdcomm_pattern) {
4907         ptr = malloc(len);
4908 
4909         if (ptr) {
4910           evaluate_comm_patterns(ptr, sample->comms, std_comm_patterns, len);
4911           len = strlen(ptr);
4912 	  len++;
4913         }
4914         else len = 0;
4915       }
4916       else ptr = sample->comms;
4917     }
4918 
4919     if (check_pipe_buffer_space(chptr, pvlen, PmLabelTSz + len)) {
4920       vlen_prims_init(pvlen, 0);
4921       return;
4922     }
4923     else {
4924       vlen_prims_insert(pvlen, COUNT_INT_STD_COMM, len, (u_char *) ptr, PM_MSG_STR_COPY);
4925       if (config.bgp_daemon_stdcomm_pattern && ptr && len) free(ptr);
4926     }
4927   }
4928   /* fallback to legacy fixed length behaviour */
4929   else {
4930     if (sample->communities_len) {
4931       if (config.bgp_daemon_stdcomm_pattern)
4932 	evaluate_comm_patterns(plbgp->std_comms, sample->comms, std_comm_patterns, MAX_BGP_STD_COMMS);
4933       else {
4934 	strlcpy(plbgp->std_comms, sample->comms, MAX_BGP_STD_COMMS);
4935 	if (strlen(sample->comms)) {
4936 	  plbgp->std_comms[MAX_BGP_STD_COMMS-2] = '+';
4937 	  plbgp->std_comms[MAX_BGP_STD_COMMS-1] = '\0';
4938 	}
4939       }
4940     }
4941   }
4942 }
4943 
SF_peer_src_ip_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4944 void SF_peer_src_ip_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4945 {
4946   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
4947   SFSample *sample = (SFSample *) pptrs->f_data;
4948 
4949   if (sample->agent_addr.type == SFLADDRESSTYPE_IP_V4) {
4950     pbgp->peer_src_ip.address.ipv4.s_addr = sample->agent_addr.address.ip_v4.s_addr;
4951     pbgp->peer_src_ip.family = AF_INET;
4952   }
4953   else if (sample->agent_addr.type == SFLADDRESSTYPE_IP_V6) {
4954     memcpy(&pbgp->peer_src_ip.address.ipv6, &sample->agent_addr.address.ip_v6, IP6AddrSz);
4955     pbgp->peer_src_ip.family = AF_INET6;
4956   }
4957 }
4958 
SF_peer_dst_ip_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4959 void SF_peer_dst_ip_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4960 {
4961   SFSample *sample = (SFSample *) pptrs->f_data;
4962   struct pkt_bgp_primitives *pbgp;
4963   int use_ip_next_hop = FALSE;
4964 
4965   /* we determine if this is called by exec_plugins() or bgp_srcdst_lookup() */
4966   if (chptr) {
4967     pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
4968     use_ip_next_hop = chptr->plugin->cfg.use_ip_next_hop;
4969 
4970     /* check network-related primitives against fallback scenarios */
4971     if (!evaluate_lm_method(pptrs, TRUE, chptr->plugin->cfg.nfacctd_net, NF_NET_KEEP)) return;
4972   }
4973   else {
4974     pbgp = (struct pkt_bgp_primitives *) (*data);
4975     use_ip_next_hop = config.use_ip_next_hop;
4976   }
4977 
4978   if (sample->bgp_nextHop.type == SFLADDRESSTYPE_IP_V4) {
4979     pbgp->peer_dst_ip.address.ipv4.s_addr = sample->bgp_nextHop.address.ip_v4.s_addr;
4980     pbgp->peer_dst_ip.family = AF_INET;
4981   }
4982   else if (sample->bgp_nextHop.type == SFLADDRESSTYPE_IP_V6) {
4983     memcpy(&pbgp->peer_dst_ip.address.ipv6, &sample->bgp_nextHop.address.ip_v6, IP6AddrSz);
4984     pbgp->peer_dst_ip.family = AF_INET6;
4985   }
4986   else if (sample->nextHop.type == SFLADDRESSTYPE_IP_V4) {
4987     if (use_ip_next_hop) {
4988       pbgp->peer_dst_ip.address.ipv4.s_addr = sample->nextHop.address.ip_v4.s_addr;
4989       pbgp->peer_dst_ip.family = AF_INET;
4990     }
4991   }
4992   else if (sample->nextHop.type == SFLADDRESSTYPE_IP_V6) {
4993     memcpy(&pbgp->peer_dst_ip.address.ipv6, &sample->nextHop.address.ip_v6, IP6AddrSz);
4994     pbgp->peer_dst_ip.family = AF_INET6;
4995   }
4996 }
4997 
SF_in_iface_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)4998 void SF_in_iface_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
4999 {
5000   struct pkt_data *pdata = (struct pkt_data *) *data;
5001   SFSample *sample = (SFSample *) pptrs->f_data;
5002 
5003   pdata->primitives.ifindex_in = sample->inputPort;
5004 }
5005 
SF_out_iface_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5006 void SF_out_iface_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5007 {
5008   struct pkt_data *pdata = (struct pkt_data *) *data;
5009   SFSample *sample = (SFSample *) pptrs->f_data;
5010 
5011   pdata->primitives.ifindex_out = sample->outputPort;
5012 }
5013 
SF_sampling_rate_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5014 void SF_sampling_rate_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5015 {
5016   struct xflow_status_entry *xsentry = (struct xflow_status_entry *) pptrs->f_status;
5017   struct pkt_data *pdata = (struct pkt_data *) *data;
5018   SFSample *sample = (SFSample *) pptrs->f_data;
5019 
5020   pdata->primitives.sampling_rate = 0;
5021 
5022   if (config.sampling_map) {
5023     if (sampling_map_caching && xsentry && timeval_cmp(&xsentry->st.stamp, &reload_map_tstamp) > 0) {
5024       pdata->primitives.sampling_rate = xsentry->st.tag;
5025     }
5026     else {
5027       find_id_func((struct id_table *)pptrs->sampling_table, pptrs, (pm_id_t *) &pdata->primitives.sampling_rate, NULL);
5028 
5029       if (xsentry) {
5030         xsentry->st.tag = pdata->primitives.sampling_rate;
5031         gettimeofday(&xsentry->st.stamp, NULL);
5032       }
5033     }
5034   }
5035 
5036   if (pdata->primitives.sampling_rate == 0) { /* 0 = still unknown */
5037     pdata->primitives.sampling_rate = sample->meanSkipCount;
5038   }
5039 
5040   if (config.sfacctd_renormalize && pdata->primitives.sampling_rate)
5041     pdata->primitives.sampling_rate = 1; /* already renormalized */
5042 }
5043 
SF_sampling_direction_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5044 void SF_sampling_direction_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5045 {
5046   struct pkt_data *pdata = (struct pkt_data *) *data;
5047 
5048   /* dummy */
5049   pdata->primitives.sampling_direction[0] = 'u';
5050   pdata->primitives.sampling_direction[1] = '\0';
5051 }
5052 
SF_timestamp_start_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5053 void SF_timestamp_start_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5054 {
5055   struct pkt_nat_primitives *pnat = (struct pkt_nat_primitives *) ((*data) + chptr->extras.off_pkt_nat_primitives);
5056 
5057   gettimeofday(&pnat->timestamp_start, NULL);
5058   if (chptr->plugin->cfg.timestamps_secs) pnat->timestamp_start.tv_usec = 0;
5059 }
5060 
SF_timestamp_arrival_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5061 void SF_timestamp_arrival_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5062 {
5063   struct pkt_nat_primitives *pnat = (struct pkt_nat_primitives *) ((*data) + chptr->extras.off_pkt_nat_primitives);
5064 
5065   gettimeofday(&pnat->timestamp_arrival, NULL);
5066   if (chptr->plugin->cfg.timestamps_secs) pnat->timestamp_arrival.tv_usec = 0;
5067 }
5068 
SF_sequence_number_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5069 void SF_sequence_number_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5070 {
5071   struct pkt_data *pdata = (struct pkt_data *) *data;
5072   SFSample *sample = (SFSample *) pptrs->f_data;
5073 
5074   pdata->primitives.export_proto_seqno = sample->sequenceNo;
5075 }
5076 
SF_version_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5077 void SF_version_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5078 {
5079   struct pkt_data *pdata = (struct pkt_data *) *data;
5080   SFSample *sample = (SFSample *) pptrs->f_data;
5081 
5082   pdata->primitives.export_proto_version = sample->datagramVersion;
5083 }
5084 
SF_sysid_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5085 void SF_sysid_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5086 {
5087   struct pkt_data *pdata = (struct pkt_data *) *data;
5088   SFSample *sample = (SFSample *) pptrs->f_data;
5089 
5090   pdata->primitives.export_proto_sysid = sample->agentSubId;
5091 }
5092 
SF_class_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5093 void SF_class_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5094 {
5095   struct pkt_data *pdata = (struct pkt_data *) *data;
5096   SFSample *sample = (SFSample *) pptrs->f_data;
5097 
5098   pdata->primitives.class = sample->class;
5099   pdata->cst.ba = 0;
5100   pdata->cst.pa = 0;
5101   pdata->cst.fa = 0;
5102 
5103   pdata->cst.stamp.tv_sec = time(NULL); /* XXX */
5104   pdata->cst.stamp.tv_usec = 0;
5105 }
5106 
5107 #if defined (WITH_NDPI)
SF_ndpi_class_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5108 void SF_ndpi_class_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5109 {
5110   struct pkt_data *pdata = (struct pkt_data *) *data;
5111   SFSample *sample = (SFSample *) pptrs->f_data;
5112 
5113   memcpy(&pdata->primitives.ndpi_class, &sample->ndpi_class, sizeof(pm_class2_t));
5114 }
5115 #endif
5116 
SF_tag_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5117 void SF_tag_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5118 {
5119   struct pkt_data *pdata = (struct pkt_data *) *data;
5120   SFSample *sample = (SFSample *) pptrs->f_data;
5121 
5122   if (!pptrs->have_tag) pdata->primitives.tag = sample->tag;
5123 }
5124 
SF_tag2_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5125 void SF_tag2_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5126 {
5127   struct pkt_data *pdata = (struct pkt_data *) *data;
5128   SFSample *sample = (SFSample *) pptrs->f_data;
5129 
5130   if (!pptrs->have_tag2) pdata->primitives.tag2 = sample->tag2;
5131 }
5132 
sampling_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5133 void sampling_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5134 {
5135   struct pkt_data *pdata = (struct pkt_data *) *data;
5136   pm_counter_t sample_pool = 0;
5137 
5138   evaluate_sampling(&chptr->s, &pdata->pkt_len, &pdata->pkt_num, &sample_pool);
5139 }
5140 
sfprobe_sampling_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5141 void sfprobe_sampling_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5142 {
5143   struct pkt_payload *payload = (struct pkt_payload *) *data;
5144 
5145   evaluate_sampling(&chptr->s, &payload->pkt_len, &payload->pkt_num, &payload->sample_pool);
5146 }
5147 
SF_bgp_peer_src_as_fromstd_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5148 void SF_bgp_peer_src_as_fromstd_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5149 {
5150   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
5151 
5152   pbgp->peer_src_as = 0;
5153 
5154   // XXX: fill this in
5155 }
5156 
SF_bgp_peer_src_as_fromext_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5157 void SF_bgp_peer_src_as_fromext_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5158 {
5159   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
5160 
5161   pbgp->peer_src_as = 0;
5162 
5163   // XXX: fill this in
5164 }
5165 
SF_tunnel_src_mac_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5166 void SF_tunnel_src_mac_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5167 {
5168   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
5169   SFSample *sample = (SFSample *) pptrs->f_data, *sppi = (SFSample *) sample->sppi;
5170 
5171   if (sppi) memcpy(ptun->tunnel_eth_shost, sppi->eth_src, ETH_ADDR_LEN);
5172 }
5173 
SF_tunnel_dst_mac_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5174 void SF_tunnel_dst_mac_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5175 {
5176   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
5177   SFSample *sample = (SFSample *) pptrs->f_data, *sppi = (SFSample *) sample->sppi;
5178 
5179   if (sppi) memcpy(ptun->tunnel_eth_dhost, sppi->eth_dst, ETH_ADDR_LEN);
5180 }
5181 
SF_tunnel_src_host_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5182 void SF_tunnel_src_host_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5183 {
5184   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
5185   SFSample *sample = (SFSample *) pptrs->f_data, *sppi = (SFSample *) sample->sppi;
5186 
5187   if (sppi) {
5188     SFLAddress *addr = &sppi->ipsrc;
5189 
5190     if (sppi->gotIPV4) {
5191       ptun->tunnel_src_ip.address.ipv4.s_addr = sppi->dcd_srcIP.s_addr;
5192       ptun->tunnel_src_ip.family = AF_INET;
5193     }
5194     else if (sppi->gotIPV6) {
5195       memcpy(&ptun->tunnel_src_ip.address.ipv6, &addr->address.ip_v6, IP6AddrSz);
5196       ptun->tunnel_src_ip.family = AF_INET6;
5197     }
5198   }
5199 }
5200 
SF_tunnel_dst_host_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5201 void SF_tunnel_dst_host_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5202 {
5203   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
5204   SFSample *sample = (SFSample *) pptrs->f_data, *sppi = (SFSample *) sample->sppi;
5205 
5206   if (sppi) {
5207     SFLAddress *addr = &sppi->ipdst;
5208 
5209     if (sppi->gotIPV4) {
5210       ptun->tunnel_dst_ip.address.ipv4.s_addr = sppi->dcd_dstIP.s_addr;
5211       ptun->tunnel_dst_ip.family = AF_INET;
5212     }
5213     else if (sppi->gotIPV6) {
5214       memcpy(&ptun->tunnel_dst_ip.address.ipv6, &addr->address.ip_v6, IP6AddrSz);
5215       ptun->tunnel_dst_ip.family = AF_INET6;
5216     }
5217   }
5218 }
5219 
SF_tunnel_ip_proto_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5220 void SF_tunnel_ip_proto_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5221 {
5222   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
5223   SFSample *sample = (SFSample *) pptrs->f_data, *sppi = (SFSample *) sample->sppi;
5224 
5225   if (sppi) ptun->tunnel_proto = sppi->dcd_ipProtocol;
5226 }
5227 
SF_tunnel_ip_tos_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5228 void SF_tunnel_ip_tos_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5229 {
5230   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
5231   SFSample *sample = (SFSample *) pptrs->f_data, *sppi = (SFSample *) sample->sppi;
5232 
5233   if (sppi) ptun->tunnel_tos = sppi->dcd_ipTos;
5234 }
5235 
SF_tunnel_src_port_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5236 void SF_tunnel_src_port_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5237 {
5238   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
5239   SFSample *sample = (SFSample *) pptrs->f_data, *sppi = (SFSample *) sample->sppi;
5240 
5241   ptun->tunnel_src_port = 0;
5242 
5243   if (sppi) {
5244     if (sppi->dcd_ipProtocol == IPPROTO_UDP || sppi->dcd_ipProtocol == IPPROTO_TCP) {
5245       ptun->tunnel_src_port = sppi->dcd_sport;
5246     }
5247   }
5248 }
5249 
SF_tunnel_dst_port_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5250 void SF_tunnel_dst_port_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5251 {
5252   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
5253   SFSample *sample = (SFSample *) pptrs->f_data, *sppi = (SFSample *) sample->sppi;
5254 
5255   ptun->tunnel_dst_port = 0;
5256 
5257   if (sppi) {
5258     if (sppi->dcd_ipProtocol == IPPROTO_UDP || sppi->dcd_ipProtocol == IPPROTO_TCP) {
5259       ptun->tunnel_dst_port = sppi->dcd_dport;
5260     }
5261   }
5262 }
5263 
SF_vxlan_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5264 void SF_vxlan_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5265 {
5266   struct pkt_tunnel_primitives *ptun = (struct pkt_tunnel_primitives *) ((*data) + chptr->extras.off_pkt_tun_primitives);
5267   SFSample *sample = (SFSample *) pptrs->f_data;
5268 
5269   ptun->tunnel_id = sample->vni;
5270 }
5271 
SF_mpls_pw_id_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5272 void SF_mpls_pw_id_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5273 {
5274   struct pkt_bgp_primitives *pbgp = (struct pkt_bgp_primitives *) ((*data) + chptr->extras.off_pkt_bgp_primitives);
5275   SFSample *sample = (SFSample *) pptrs->f_data;
5276 
5277   pbgp->mpls_pw_id = sample->mpls_vll_vc_id;
5278 }
5279 
SF_mpls_label_top_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5280 void SF_mpls_label_top_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5281 {
5282   struct pkt_mpls_primitives *pmpls = (struct pkt_mpls_primitives *) ((*data) + chptr->extras.off_pkt_mpls_primitives);
5283   SFSample *sample = (SFSample *) pptrs->f_data;
5284   u_int32_t *label = (u_int32_t *) sample->lstk.stack;
5285 
5286   if (label) pmpls->mpls_label_top = MPLS_LABEL(ntohl(*label));
5287 }
5288 
SF_mpls_label_bottom_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5289 void SF_mpls_label_bottom_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5290 {
5291   struct pkt_mpls_primitives *pmpls = (struct pkt_mpls_primitives *) ((*data) + chptr->extras.off_pkt_mpls_primitives);
5292   SFSample *sample = (SFSample *) pptrs->f_data;
5293   u_int32_t lvalue = 0, *label = (u_int32_t *) sample->lstk.stack;
5294 
5295   if (label) {
5296     do {
5297       lvalue = ntohl(*label);
5298       label += 4;
5299     } while (!MPLS_STACK(lvalue));
5300 
5301     pmpls->mpls_label_bottom = MPLS_LABEL(lvalue);
5302   }
5303 }
5304 
SF_mpls_stack_depth_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5305 void SF_mpls_stack_depth_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5306 {
5307   struct pkt_mpls_primitives *pmpls = (struct pkt_mpls_primitives *) ((*data) + chptr->extras.off_pkt_mpls_primitives);
5308   SFSample *sample = (SFSample *) pptrs->f_data;
5309   u_int32_t lvalue = 0, *label = (u_int32_t *) sample->lstk.stack;
5310 
5311   pmpls->mpls_stack_depth = 0;
5312 
5313   if (label) {
5314     do {
5315       lvalue = ntohl(*label);
5316       label += 4;
5317       pmpls->mpls_stack_depth++;
5318     } while (!MPLS_STACK(lvalue));
5319   }
5320 }
5321 
SF_custom_primitives_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5322 void SF_custom_primitives_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5323 {
5324   SFSample *sample = (SFSample *) pptrs->f_data;
5325 
5326   custom_primitives_handler(chptr, &sample->hdr_ptrs, data);
5327 }
5328 
5329 #if defined WITH_GEOIP
pm_geoip_init()5330 void pm_geoip_init()
5331 {
5332   if (config.geoip_ipv4_file && !config.geoip_ipv4) {
5333     config.geoip_ipv4 = GeoIP_open(config.geoip_ipv4_file, (GEOIP_MEMORY_CACHE|GEOIP_CHECK_CACHE));
5334 
5335     if (!config.geoip_ipv4 && !log_notification_isset(&log_notifications.geoip_ipv4_file_null, FALSE)) {
5336       Log(LOG_WARNING, "WARN ( %s/%s ): geoip_ipv4_file database can't be loaded.\n", config.name, config.type);
5337       log_notification_set(&log_notifications.geoip_ipv4_file_null, FALSE, FALSE);
5338     }
5339   }
5340 
5341   if (config.geoip_ipv6_file && !config.geoip_ipv6) {
5342     config.geoip_ipv6 = GeoIP_open(config.geoip_ipv6_file, (GEOIP_MEMORY_CACHE|GEOIP_CHECK_CACHE));
5343 
5344     if (!config.geoip_ipv6 && !log_notification_isset(&log_notifications.geoip_ipv6_file_null, FALSE)) {
5345       Log(LOG_WARNING, "WARN ( %s/%s ): geoip_ipv6_file database can't be loaded.\n", config.name, config.type);
5346       log_notification_set(&log_notifications.geoip_ipv6_file_null, FALSE, FALSE);
5347     }
5348   }
5349 }
5350 
src_host_country_geoip_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5351 void src_host_country_geoip_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5352 {
5353   struct pkt_data *pdata = (struct pkt_data *) *data;
5354 
5355   pm_geoip_init();
5356   pdata->primitives.src_ip_country.id = 0;
5357 
5358   if (config.geoip_ipv4) {
5359     if (pptrs->l3_proto == ETHERTYPE_IP)
5360       pdata->primitives.src_ip_country.id = GeoIP_id_by_ipnum(config.geoip_ipv4, ntohl(((struct pm_iphdr *) pptrs->iph_ptr)->ip_src.s_addr));
5361   }
5362   if (config.geoip_ipv6) {
5363     if (pptrs->l3_proto == ETHERTYPE_IPV6)
5364       pdata->primitives.src_ip_country.id = GeoIP_id_by_ipnum_v6(config.geoip_ipv6, ((struct ip6_hdr *)pptrs->iph_ptr)->ip6_src);
5365   }
5366 }
5367 
dst_host_country_geoip_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5368 void dst_host_country_geoip_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5369 {
5370   struct pkt_data *pdata = (struct pkt_data *) *data;
5371 
5372   pm_geoip_init();
5373   pdata->primitives.dst_ip_country.id = 0;
5374 
5375   if (config.geoip_ipv4) {
5376     if (pptrs->l3_proto == ETHERTYPE_IP)
5377       pdata->primitives.dst_ip_country.id = GeoIP_id_by_ipnum(config.geoip_ipv4, ntohl(((struct pm_iphdr *) pptrs->iph_ptr)->ip_dst.s_addr));
5378   }
5379 
5380   if (config.geoip_ipv6) {
5381     if (pptrs->l3_proto == ETHERTYPE_IPV6)
5382       pdata->primitives.dst_ip_country.id = GeoIP_id_by_ipnum_v6(config.geoip_ipv6, ((struct ip6_hdr *)pptrs->iph_ptr)->ip6_dst);
5383   }
5384 }
5385 #endif
5386 
5387 #if defined WITH_GEOIPV2
pm_geoipv2_init()5388 void pm_geoipv2_init()
5389 {
5390   int status;
5391 
5392   memset(&config.geoipv2_db, 0, sizeof(config.geoipv2_db));
5393 
5394   if (config.geoipv2_file) {
5395     status = MMDB_open(config.geoipv2_file, MMDB_MODE_MMAP, &config.geoipv2_db);
5396 
5397     if (status != MMDB_SUCCESS) {
5398       Log(LOG_WARNING, "WARN ( %s/%s ): geoipv2_file database can't be loaded (%s).\n", config.name, config.type, MMDB_strerror(status));
5399       log_notification_set(&log_notifications.geoip_ipv4_file_null, FALSE, FALSE);
5400       memset(&config.geoipv2_db, 0, sizeof(config.geoipv2_db));
5401     }
5402     else Log(LOG_INFO, "INFO ( %s/%s ): geoipv2_file database %s loaded\n", config.name, config.type, config.geoipv2_file);
5403   }
5404 }
5405 
pm_geoipv2_close()5406 void pm_geoipv2_close()
5407 {
5408   if (config.geoipv2_file) MMDB_close(&config.geoipv2_db);
5409 }
5410 
src_host_geoipv2_lookup_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5411 void src_host_geoipv2_lookup_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5412 {
5413   struct sockaddr_storage ss;
5414   struct sockaddr *sa = (struct sockaddr *) &ss;
5415   int mmdb_error;
5416 
5417   memset(&pptrs->geoipv2_src, 0, sizeof(pptrs->geoipv2_src));
5418 
5419   if (pptrs->l3_proto == ETHERTYPE_IP) {
5420     raw_to_sa(sa, (u_char *) &((struct pm_iphdr *)pptrs->iph_ptr)->ip_src.s_addr, 0, AF_INET);
5421   }
5422   else if (pptrs->l3_proto == ETHERTYPE_IPV6) {
5423     raw_to_sa(sa, (u_char *) &((struct ip6_hdr *)pptrs->iph_ptr)->ip6_src, 0, AF_INET6);
5424   }
5425 
5426   if (config.geoipv2_db.filename) {
5427     pptrs->geoipv2_src = MMDB_lookup_sockaddr(&config.geoipv2_db, sa, &mmdb_error);
5428 
5429     if (mmdb_error != MMDB_SUCCESS) {
5430       Log(LOG_WARNING, "WARN ( %s/%s ): src_host_geoipv2_lookup_handler(): %s\n", config.name, config.type, MMDB_strerror(mmdb_error));
5431     }
5432   }
5433 }
5434 
dst_host_geoipv2_lookup_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5435 void dst_host_geoipv2_lookup_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5436 {
5437   struct sockaddr_storage ss;
5438   struct sockaddr *sa = (struct sockaddr *) &ss;
5439   int mmdb_error;
5440 
5441   memset(&pptrs->geoipv2_dst, 0, sizeof(pptrs->geoipv2_dst));
5442 
5443   if (pptrs->l3_proto == ETHERTYPE_IP) {
5444     raw_to_sa(sa, (u_char *) &((struct pm_iphdr *)pptrs->iph_ptr)->ip_dst.s_addr, 0, AF_INET);
5445   }
5446   else if (pptrs->l3_proto == ETHERTYPE_IPV6) {
5447     raw_to_sa(sa, (u_char *) &((struct ip6_hdr *)pptrs->iph_ptr)->ip6_dst, 0, AF_INET6);
5448   }
5449 
5450   if (config.geoipv2_db.filename) {
5451     pptrs->geoipv2_dst = MMDB_lookup_sockaddr(&config.geoipv2_db, sa, &mmdb_error);
5452 
5453     if (mmdb_error != MMDB_SUCCESS) {
5454       Log(LOG_WARNING, "WARN ( %s/%s ): dst_host_geoipv2_lookup_handler(): %s\n", config.name, config.type, MMDB_strerror(mmdb_error));
5455     }
5456   }
5457 }
5458 
src_host_country_geoipv2_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5459 void src_host_country_geoipv2_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5460 {
5461   struct pkt_data *pdata = (struct pkt_data *) *data;
5462   MMDB_entry_data_list_s *entry_data_list = NULL;
5463   char other_country[] = "O1";
5464   int status;
5465 
5466   if (pptrs->geoipv2_src.found_entry) {
5467     MMDB_entry_data_s entry_data;
5468 
5469     status = MMDB_get_value(&pptrs->geoipv2_src.entry, &entry_data, "country", "iso_code", NULL);
5470 
5471     if (entry_data.offset) {
5472       MMDB_entry_s entry = { .mmdb = &config.geoipv2_db, .offset = entry_data.offset };
5473       status = MMDB_get_entry_data_list(&entry, &entry_data_list);
5474     }
5475 
5476     if (status != MMDB_SUCCESS && status != MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR) {
5477       Log(LOG_WARNING, "WARN ( %s/%s ): src_host_country_geoipv2_handler(): %s\n", config.name, config.type, MMDB_strerror(status));
5478     }
5479 
5480     if (entry_data_list != NULL) {
5481       if (entry_data_list->entry_data.has_data) {
5482 	if (entry_data_list->entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) {
5483 	  int size = (entry_data_list->entry_data.data_size < (PM_COUNTRY_T_STRLEN-1)) ? entry_data_list->entry_data.data_size : (PM_COUNTRY_T_STRLEN-1);
5484 
5485 	  memcpy(pdata->primitives.src_ip_country.str, entry_data_list->entry_data.utf8_string, size);
5486 	  pdata->primitives.src_ip_country.str[size] = '\0';
5487 	}
5488       }
5489 
5490       MMDB_free_entry_data_list(entry_data_list);
5491     }
5492   }
5493   else {
5494     /* return O1/Other Country: https://dev.maxmind.com/geoip/legacy/codes/iso3166/ */
5495     strncpy(pdata->primitives.src_ip_country.str, other_country, strlen(other_country));
5496   }
5497 }
5498 
dst_host_country_geoipv2_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5499 void dst_host_country_geoipv2_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5500 {
5501   struct pkt_data *pdata = (struct pkt_data *) *data;
5502   MMDB_entry_data_list_s *entry_data_list = NULL;
5503   char other_country[] = "O1";
5504   int status;
5505 
5506   if (pptrs->geoipv2_dst.found_entry) {
5507     MMDB_entry_data_s entry_data;
5508 
5509     status = MMDB_get_value(&pptrs->geoipv2_dst.entry, &entry_data, "country", "iso_code", NULL);
5510 
5511     if (entry_data.offset) {
5512       MMDB_entry_s entry = { .mmdb = &config.geoipv2_db, .offset = entry_data.offset };
5513       status = MMDB_get_entry_data_list(&entry, &entry_data_list);
5514     }
5515 
5516     if (status != MMDB_SUCCESS && status != MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR) {
5517       Log(LOG_WARNING, "WARN ( %s/%s ): dst_host_country_geoipv2_handler(): %s\n", config.name, config.type, MMDB_strerror(status));
5518     }
5519 
5520     if (entry_data_list != NULL) {
5521       if (entry_data_list->entry_data.has_data) {
5522         if (entry_data_list->entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) {
5523           int size = (entry_data_list->entry_data.data_size < (PM_COUNTRY_T_STRLEN-1)) ? entry_data_list->entry_data.data_size : (PM_COUNTRY_T_STRLEN-1);
5524 
5525           memcpy(pdata->primitives.dst_ip_country.str, entry_data_list->entry_data.utf8_string, size);
5526           pdata->primitives.dst_ip_country.str[size] = '\0';
5527         }
5528       }
5529 
5530       MMDB_free_entry_data_list(entry_data_list);
5531     }
5532   }
5533   else {
5534     /* return O1/Other Country: https://dev.maxmind.com/geoip/legacy/codes/iso3166/ */
5535     strncpy(pdata->primitives.dst_ip_country.str, other_country, strlen(other_country));
5536   }
5537 }
5538 
src_host_pocode_geoipv2_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5539 void src_host_pocode_geoipv2_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5540 {
5541   struct pkt_data *pdata = (struct pkt_data *) *data;
5542   MMDB_entry_data_list_s *entry_data_list = NULL;
5543   int status;
5544 
5545   if (pptrs->geoipv2_src.found_entry) {
5546     MMDB_entry_data_s entry_data;
5547 
5548     status = MMDB_get_value(&pptrs->geoipv2_src.entry, &entry_data, "postal", "code", NULL);
5549 
5550     if (entry_data.offset) {
5551       MMDB_entry_s entry = { .mmdb = &config.geoipv2_db, .offset = entry_data.offset };
5552       status = MMDB_get_entry_data_list(&entry, &entry_data_list);
5553     }
5554 
5555     if (status != MMDB_SUCCESS && status != MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR) {
5556       Log(LOG_WARNING, "WARN ( %s/%s ): src_host_pocode_geoipv2_handler(): %s\n", config.name, config.type, MMDB_strerror(status));
5557     }
5558 
5559     if (entry_data_list != NULL) {
5560       if (entry_data_list->entry_data.has_data) {
5561         if (entry_data_list->entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) {
5562           int size = (entry_data_list->entry_data.data_size < (PM_POCODE_T_STRLEN-1)) ? entry_data_list->entry_data.data_size : (PM_POCODE_T_STRLEN-1);
5563 
5564           memcpy(pdata->primitives.src_ip_pocode.str, entry_data_list->entry_data.utf8_string, size);
5565           pdata->primitives.src_ip_pocode.str[size] = '\0';
5566         }
5567       }
5568 
5569       MMDB_free_entry_data_list(entry_data_list);
5570     }
5571   }
5572 }
5573 
dst_host_pocode_geoipv2_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5574 void dst_host_pocode_geoipv2_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5575 {
5576   struct pkt_data *pdata = (struct pkt_data *) *data;
5577   MMDB_entry_data_list_s *entry_data_list = NULL;
5578   int status;
5579 
5580   if (pptrs->geoipv2_dst.found_entry) {
5581     MMDB_entry_data_s entry_data;
5582 
5583     status = MMDB_get_value(&pptrs->geoipv2_dst.entry, &entry_data, "postal", "code", NULL);
5584 
5585     if (entry_data.offset) {
5586       MMDB_entry_s entry = { .mmdb = &config.geoipv2_db, .offset = entry_data.offset };
5587       status = MMDB_get_entry_data_list(&entry, &entry_data_list);
5588     }
5589 
5590     if (status != MMDB_SUCCESS && status != MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR) {
5591       Log(LOG_WARNING, "WARN ( %s/%s ): dst_host_pocode_geoipv2_handler(): %s\n", config.name, config.type, MMDB_strerror(status));
5592     }
5593 
5594     if (entry_data_list != NULL) {
5595       if (entry_data_list->entry_data.has_data) {
5596         if (entry_data_list->entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) {
5597           int size = (entry_data_list->entry_data.data_size < (PM_POCODE_T_STRLEN-1)) ? entry_data_list->entry_data.data_size : (PM_POCODE_T_STRLEN-1);
5598 
5599           memcpy(pdata->primitives.dst_ip_pocode.str, entry_data_list->entry_data.utf8_string, size);
5600           pdata->primitives.dst_ip_pocode.str[size] = '\0';
5601         }
5602       }
5603 
5604       MMDB_free_entry_data_list(entry_data_list);
5605     }
5606   }
5607 }
5608 
src_host_coords_geoipv2_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5609 void src_host_coords_geoipv2_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5610 {
5611   struct pkt_data *pdata = (struct pkt_data *) *data;
5612   MMDB_entry_data_list_s *entry_data_list = NULL;
5613   int status;
5614 
5615   if (pptrs->geoipv2_src.found_entry) {
5616     MMDB_entry_data_s entry_data;
5617 
5618     status = MMDB_get_value(&pptrs->geoipv2_src.entry, &entry_data, "location", "latitude", NULL);
5619 
5620     if (entry_data.offset) {
5621       MMDB_entry_s entry = { .mmdb = &config.geoipv2_db, .offset = entry_data.offset };
5622       status = MMDB_get_entry_data_list(&entry, &entry_data_list);
5623     }
5624 
5625     if (status != MMDB_SUCCESS && status != MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR) {
5626       Log(LOG_WARNING, "WARN ( %s/%s ): src_host_coords_geoipv2_handler(): %s\n", config.name, config.type, MMDB_strerror(status));
5627     }
5628 
5629     if (entry_data_list != NULL) {
5630       if (entry_data_list->entry_data.has_data) {
5631         if (entry_data_list->entry_data.type == MMDB_DATA_TYPE_DOUBLE) {
5632           pdata->primitives.src_ip_lat = entry_data_list->entry_data.double_value;
5633         }
5634       }
5635 
5636       MMDB_free_entry_data_list(entry_data_list);
5637     }
5638 
5639     status = MMDB_get_value(&pptrs->geoipv2_src.entry, &entry_data, "location", "longitude", NULL);
5640 
5641     if (entry_data.offset) {
5642       MMDB_entry_s entry = { .mmdb = &config.geoipv2_db, .offset = entry_data.offset };
5643       status = MMDB_get_entry_data_list(&entry, &entry_data_list);
5644     }
5645 
5646     if (status != MMDB_SUCCESS && status != MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR) {
5647       Log(LOG_WARNING, "WARN ( %s/%s ): src_host_coords_geoipv2_handler(): %s\n", config.name, config.type, MMDB_strerror(status));
5648     }
5649 
5650     if (entry_data_list != NULL) {
5651       if (entry_data_list->entry_data.has_data) {
5652         if (entry_data_list->entry_data.type == MMDB_DATA_TYPE_DOUBLE) {
5653           pdata->primitives.src_ip_lon = entry_data_list->entry_data.double_value;
5654         }
5655       }
5656 
5657       MMDB_free_entry_data_list(entry_data_list);
5658     }
5659   }
5660 }
5661 
dst_host_coords_geoipv2_handler(struct channels_list_entry * chptr,struct packet_ptrs * pptrs,char ** data)5662 void dst_host_coords_geoipv2_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
5663 {
5664   struct pkt_data *pdata = (struct pkt_data *) *data;
5665   MMDB_entry_data_list_s *entry_data_list = NULL;
5666   int status;
5667 
5668   if (pptrs->geoipv2_dst.found_entry) {
5669     MMDB_entry_data_s entry_data;
5670 
5671     status = MMDB_get_value(&pptrs->geoipv2_dst.entry, &entry_data, "location", "latitude", NULL);
5672 
5673     if (entry_data.offset) {
5674       MMDB_entry_s entry = { .mmdb = &config.geoipv2_db, .offset = entry_data.offset };
5675       status = MMDB_get_entry_data_list(&entry, &entry_data_list);
5676     }
5677 
5678     if (status != MMDB_SUCCESS && status != MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR) {
5679       Log(LOG_WARNING, "WARN ( %s/%s ): dst_host_coords_geoipv2_handler(): %s\n", config.name, config.type, MMDB_strerror(status));
5680     }
5681 
5682     if (entry_data_list != NULL) {
5683       if (entry_data_list->entry_data.has_data) {
5684         if (entry_data_list->entry_data.type == MMDB_DATA_TYPE_DOUBLE) {
5685           pdata->primitives.dst_ip_lat = entry_data_list->entry_data.double_value;
5686         }
5687       }
5688 
5689       MMDB_free_entry_data_list(entry_data_list);
5690     }
5691 
5692     status = MMDB_get_value(&pptrs->geoipv2_dst.entry, &entry_data, "location", "longitude", NULL);
5693 
5694     if (entry_data.offset) {
5695       MMDB_entry_s entry = { .mmdb = &config.geoipv2_db, .offset = entry_data.offset };
5696       status = MMDB_get_entry_data_list(&entry, &entry_data_list);
5697     }
5698 
5699     if (status != MMDB_SUCCESS && status != MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR) {
5700       Log(LOG_WARNING, "WARN ( %s/%s ): dst_host_coords_geoipv2_handler(): %s\n", config.name, config.type, MMDB_strerror(status));
5701     }
5702 
5703     if (entry_data_list != NULL) {
5704       if (entry_data_list->entry_data.has_data) {
5705         if (entry_data_list->entry_data.type == MMDB_DATA_TYPE_DOUBLE) {
5706           pdata->primitives.dst_ip_lon = entry_data_list->entry_data.double_value;
5707         }
5708       }
5709 
5710       MMDB_free_entry_data_list(entry_data_list);
5711     }
5712   }
5713 }
5714 #endif
5715 
5716 /* srcdst: 0 == src, 1 == dst */
evaluate_lm_method(struct packet_ptrs * pptrs,u_int8_t srcdst,u_int32_t bitmap,u_int32_t method)5717 int evaluate_lm_method(struct packet_ptrs *pptrs, u_int8_t srcdst, u_int32_t bitmap, u_int32_t method)
5718 {
5719   /* src */
5720   if (srcdst == FALSE) {
5721     if (pptrs->lm_method_src == method || !(bitmap & NF_NET_FALLBACK))
5722       return TRUE;
5723     else
5724       return FALSE;
5725   }
5726   /* dst */
5727   else if (srcdst == TRUE) {
5728     if (pptrs->lm_method_dst == method || !(bitmap & NF_NET_FALLBACK))
5729       return TRUE;
5730     else
5731       return FALSE;
5732   }
5733 
5734   return ERR;
5735 }
5736 
lookup_tpl_ext_db(void * entry,u_int32_t pen,u_int16_t type)5737 char *lookup_tpl_ext_db(void *entry, u_int32_t pen, u_int16_t type)
5738 {
5739   struct template_cache_entry *tpl = (struct template_cache_entry *) entry;
5740   u_int16_t ie_idx, ext_db_modulo = (type%TPL_EXT_DB_ENTRIES);
5741 
5742   for (ie_idx = 0; ie_idx < IES_PER_TPL_EXT_DB_ENTRY; ie_idx++) {
5743     if (tpl->ext_db[ext_db_modulo].ie[ie_idx].type == type &&
5744         tpl->ext_db[ext_db_modulo].ie[ie_idx].pen == pen)
5745       return (char *) &tpl->ext_db[ext_db_modulo].ie[ie_idx];
5746   }
5747 
5748   return NULL;
5749 }
5750