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