1 /*
2 * Copyright (c) 2017, Peter Haag
3 * Copyright (c) 2016, Peter Haag
4 * Copyright (c) 2014, Peter Haag
5 * Copyright (c) 2009, Peter Haag
6 * Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * * Neither the name of the author nor the names of its contributors may be
18 * used to endorse or promote products derived from this software without
19 * specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35 static inline int CheckBufferSpace(nffile_t *nffile, size_t required);
36
37 static inline void AppendToBuffer(nffile_t *nffile, void *record, size_t required);
38
39 static inline void CopyV6IP(uint32_t *dst, uint32_t *src);
40
41 static inline void ExpandRecord_v2(common_record_t *input_record, extension_info_t *extension_info, exporter_info_record_t *exporter_info, master_record_t *output_record );
42
43 #ifdef NEED_PACKRECORD
44 static void PackRecord(master_record_t *master_record, nffile_t *nffile);
45 #endif
46
CheckBufferSpace(nffile_t * nffile,size_t required)47 static inline int CheckBufferSpace(nffile_t *nffile, size_t required) {
48
49 dbg_printf("Buffer Size %u\n", nffile->block_header->size);
50 // flush current buffer to disc
51 if ( (nffile->block_header->size + required ) > WRITE_BUFFSIZE ) {
52
53 // this should never happen, but catch it anyway
54 if ( required > WRITE_BUFFSIZE ) {
55 LogError("Required buffer size %zu too big for output buffer!" , required);
56 return 0;
57 }
58
59 if ( WriteBlock(nffile) <= 0 ) {
60 LogError("Failed to write output buffer to disk: '%s'" , strerror(errno));
61 return 0;
62 }
63 }
64
65 return 1;
66 } // End of CheckBufferSpace
67
68 // Use 4 uint32_t copy cycles, as SPARC CPUs brak
CopyV6IP(uint32_t * dst,uint32_t * src)69 static inline void CopyV6IP(uint32_t *dst, uint32_t *src) {
70 dst[0] = src[0];
71 dst[1] = src[1];
72 dst[2] = src[2];
73 dst[3] = src[3];
74 } // End of CopyV6IP
75
76 /*
77 * Expand file record into master record for further processing
78 * LP64 CPUs need special 32bit operations as it is not guarateed, that 64bit
79 * values are aligned
80 */
ExpandRecord_v2(common_record_t * input_record,extension_info_t * extension_info,exporter_info_record_t * exporter_info,master_record_t * output_record)81 static inline void ExpandRecord_v2(common_record_t *input_record, extension_info_t *extension_info, exporter_info_record_t *exporter_info, master_record_t *output_record ) {
82 extension_map_t *extension_map = extension_info->map;
83 uint32_t i, *u;
84 void *p = (void *)input_record;
85 // printf("Byte: %u\n", _b);
86
87 #ifdef NSEL
88 // nasty bug work around - compat issues 1.6.10 - 1.6.12 onwards
89 union {
90 uint16_t port[2];
91 uint32_t vrf;
92 } compat_nel_bug;
93 compat_nel_bug.vrf = 0;
94 int compat_nel = 0;
95 #endif
96
97 // set map ref
98 output_record->map_ref = extension_map;
99
100 // Copy common data block
101 memcpy((void *)output_record, (void *)input_record, COMMON_RECORD_DATA_SIZE);
102 p = (void *)input_record->data;
103
104 if ( exporter_info ) {
105 uint32_t sysid = exporter_info->sysid;
106 output_record->exporter_sysid = sysid;
107 input_record->exporter_sysid = sysid;
108 output_record->exp_ref = exporter_info;
109 } else {
110 output_record->exp_ref = NULL;
111 }
112 output_record->label = NULL;
113
114 // map icmp type/code in it's own vars
115 output_record->icmp = output_record->dstport;
116
117 // Required extension 1 - IP addresses
118 if ( (input_record->flags & FLAG_IPV6_ADDR) != 0 ) { // IPv6
119 // IPv6
120 // keep compiler happy
121 // memcpy((void *)output_record->V6.srcaddr, p, 4 * sizeof(uint64_t));
122 memcpy((void *)output_record->ip_union._ip_64.addr, p, 4 * sizeof(uint64_t));
123 p = (void *)((pointer_addr_t)p + 4 * sizeof(uint64_t));
124 } else {
125 // IPv4
126 u = (uint32_t *)p;
127 output_record->V6.srcaddr[0] = 0;
128 output_record->V6.srcaddr[1] = 0;
129 output_record->V4.srcaddr = u[0];
130
131 output_record->V6.dstaddr[0] = 0;
132 output_record->V6.dstaddr[1] = 0;
133 output_record->V4.dstaddr = u[1];
134 p = (void *)((pointer_addr_t)p + 2 * sizeof(uint32_t));
135 }
136
137 // Required extension 2 - packet counter
138 if ( (input_record->flags & FLAG_PKG_64 ) != 0 ) {
139 // 64bit packet counter
140 value64_t l, *v = (value64_t *)p;
141 l.val.val32[0] = v->val.val32[0];
142 l.val.val32[1] = v->val.val32[1];
143 output_record->dPkts = l.val.val64;
144 p = (void *)((pointer_addr_t)p + sizeof(uint64_t));
145 } else {
146 // 32bit packet counter
147 output_record->dPkts = *((uint32_t *)p);
148 p = (void *)((pointer_addr_t)p + sizeof(uint32_t));
149 }
150
151 // Required extension 3 - byte counter
152 if ( (input_record->flags & FLAG_BYTES_64 ) != 0 ) {
153 // 64bit byte counter
154 value64_t l, *v = (value64_t *)p;
155 l.val.val32[0] = v->val.val32[0];
156 l.val.val32[1] = v->val.val32[1];
157 output_record->dOctets = l.val.val64;
158 p = (void *)((pointer_addr_t)p + sizeof(uint64_t));
159 } else {
160 // 32bit bytes counter
161 output_record->dOctets = *((uint32_t *)p);
162 p = (void *)((pointer_addr_t)p + sizeof(uint32_t));
163 }
164
165 // preset one single flow
166 output_record->aggr_flows = 1;
167
168 // Process optional extensions
169 i=0;
170 while ( extension_map->ex_id[i] ) {
171 switch (extension_map->ex_id[i++]) {
172 // 0 - 3 should never be in an extension table so - ignore it
173 case 0:
174 case 1:
175 case 2:
176 case 3:
177 break;
178 case EX_IO_SNMP_2: {
179 tpl_ext_4_t *tpl = (tpl_ext_4_t *)p;
180 output_record->input = tpl->input;
181 output_record->output = tpl->output;
182 p = (void *)tpl->data;
183 } break;
184 case EX_IO_SNMP_4: {
185 tpl_ext_5_t *tpl = (tpl_ext_5_t *)p;
186 output_record->input = tpl->input;
187 output_record->output = tpl->output;
188 p = (void *)tpl->data;
189 } break;
190 case EX_AS_2: {
191 tpl_ext_6_t *tpl = (tpl_ext_6_t *)p;
192 output_record->srcas = tpl->src_as;
193 output_record->dstas = tpl->dst_as;
194 p = (void *)tpl->data;
195 } break;
196 case EX_AS_4: {
197 tpl_ext_7_t *tpl = (tpl_ext_7_t *)p;
198 output_record->srcas = tpl->src_as;
199 output_record->dstas = tpl->dst_as;
200 p = (void *)tpl->data;
201 } break;
202 case EX_MULIPLE: {
203 tpl_ext_8_t *tpl = (tpl_ext_8_t *)p;
204 // use a 32 bit int to copy all 4 fields
205 output_record->any = tpl->any;
206 p = (void *)tpl->data;
207 } break;
208 case EX_NEXT_HOP_v4: {
209 tpl_ext_9_t *tpl = (tpl_ext_9_t *)p;
210 output_record->ip_nexthop.V6[0] = 0;
211 output_record->ip_nexthop.V6[1] = 0;
212 output_record->ip_nexthop.V4 = tpl->nexthop;
213 p = (void *)tpl->data;
214 ClearFlag(output_record->flags, FLAG_IPV6_NH);
215 } break;
216 case EX_NEXT_HOP_v6: {
217 tpl_ext_10_t *tpl = (tpl_ext_10_t *)p;
218 CopyV6IP((uint32_t *)output_record->ip_nexthop.V6, (uint32_t *)tpl->nexthop);
219 p = (void *)tpl->data;
220 SetFlag(output_record->flags, FLAG_IPV6_NH);
221 } break;
222 case EX_NEXT_HOP_BGP_v4: {
223 tpl_ext_11_t *tpl = (tpl_ext_11_t *)p;
224 output_record->bgp_nexthop.V6[0] = 0;
225 output_record->bgp_nexthop.V6[1] = 0;
226 output_record->bgp_nexthop.V4 = tpl->bgp_nexthop;
227 ClearFlag(output_record->flags, FLAG_IPV6_NHB);
228 p = (void *)tpl->data;
229 } break;
230 case EX_NEXT_HOP_BGP_v6: {
231 tpl_ext_12_t *tpl = (tpl_ext_12_t *)p;
232 CopyV6IP((uint32_t *)output_record->bgp_nexthop.V6, (uint32_t *)tpl->bgp_nexthop);
233 p = (void *)tpl->data;
234 SetFlag(output_record->flags, FLAG_IPV6_NHB);
235 } break;
236 case EX_VLAN: {
237 tpl_ext_13_t *tpl = (tpl_ext_13_t *)p;
238 output_record->src_vlan = tpl->src_vlan;
239 output_record->dst_vlan = tpl->dst_vlan;
240 p = (void *)tpl->data;
241 } break;
242 case EX_OUT_PKG_4: {
243 tpl_ext_14_t *tpl = (tpl_ext_14_t *)p;
244 output_record->out_pkts = tpl->out_pkts;
245 p = (void *)tpl->data;
246 } break;
247 case EX_OUT_PKG_8: {
248 tpl_ext_15_t v, *tpl = (tpl_ext_15_t *)p;
249 v.v[0] = tpl->v[0];
250 v.v[1] = tpl->v[1];
251 output_record->out_pkts = v.out_pkts;
252 p = (void *)tpl->data;
253 } break;
254 case EX_OUT_BYTES_4: {
255 tpl_ext_16_t *tpl = (tpl_ext_16_t *)p;
256 output_record->out_bytes = tpl->out_bytes;
257 p = (void *)tpl->data;
258 } break;
259 case EX_OUT_BYTES_8: {
260 tpl_ext_17_t v,*tpl = (tpl_ext_17_t *)p;
261 v.v[0] = tpl->v[0];
262 v.v[1] = tpl->v[1];
263 output_record->out_bytes = v.out_bytes;
264 p = (void *)tpl->data;
265 } break;
266 case EX_AGGR_FLOWS_4: {
267 tpl_ext_18_t *tpl = (tpl_ext_18_t *)p;
268 output_record->aggr_flows = tpl->aggr_flows;
269 p = (void *)tpl->data;
270 } break;
271 case EX_AGGR_FLOWS_8: {
272 tpl_ext_19_t v, *tpl = (tpl_ext_19_t *)p;
273 v.v[0] = tpl->v[0];
274 v.v[1] = tpl->v[1];
275 output_record->aggr_flows = v.aggr_flows;
276 p = (void *)tpl->data;
277 } break;
278 case EX_MAC_1: {
279 tpl_ext_20_t v, *tpl = (tpl_ext_20_t *)p;
280 v.v1[0] = tpl->v1[0];
281 v.v1[1] = tpl->v1[1];
282 output_record->in_src_mac = v.in_src_mac;
283
284 v.v2[0] = tpl->v2[0];
285 v.v2[1] = tpl->v2[1];
286 output_record->out_dst_mac = v.out_dst_mac;
287 p = (void *)tpl->data;
288 } break;
289 case EX_MAC_2: {
290 tpl_ext_21_t v, *tpl = (tpl_ext_21_t *)p;
291 v.v1[0] = tpl->v1[0];
292 v.v1[1] = tpl->v1[1];
293 output_record->in_dst_mac = v.in_dst_mac;
294 v.v2[0] = tpl->v2[0];
295 v.v2[1] = tpl->v2[1];
296 output_record->out_src_mac = v.out_src_mac;
297 p = (void *)tpl->data;
298 } break;
299 case EX_MPLS: {
300 tpl_ext_22_t *tpl = (tpl_ext_22_t *)p;
301 int j;
302 for (j=0; j<10; j++ ) {
303 output_record->mpls_label[j] = tpl->mpls_label[j];
304 }
305 p = (void *)tpl->data;
306 } break;
307 case EX_ROUTER_IP_v4: {
308 tpl_ext_23_t *tpl = (tpl_ext_23_t *)p;
309 output_record->ip_router.V6[0] = 0;
310 output_record->ip_router.V6[1] = 0;
311 output_record->ip_router.V4 = tpl->router_ip;
312 p = (void *)tpl->data;
313 ClearFlag(output_record->flags, FLAG_IPV6_EXP);
314 } break;
315 case EX_ROUTER_IP_v6: {
316 tpl_ext_24_t *tpl = (tpl_ext_24_t *)p;
317 CopyV6IP((uint32_t *)output_record->ip_router.V6, (uint32_t *)tpl->router_ip);
318 p = (void *)tpl->data;
319 SetFlag(output_record->flags, FLAG_IPV6_EXP);
320 } break;
321 case EX_ROUTER_ID: {
322 tpl_ext_25_t *tpl = (tpl_ext_25_t *)p;
323 output_record->engine_type = tpl->engine_type;
324 output_record->engine_id = tpl->engine_id;
325 p = (void *)tpl->data;
326 } break;
327 case EX_BGPADJ: {
328 tpl_ext_26_t *tpl = (tpl_ext_26_t *)p;
329 output_record->bgpNextAdjacentAS = tpl->bgpNextAdjacentAS;
330 output_record->bgpPrevAdjacentAS = tpl->bgpPrevAdjacentAS;
331 p = (void *)tpl->data;
332 } break;
333 case EX_LATENCY: {
334 tpl_ext_latency_t *tpl = (tpl_ext_latency_t *)p;
335 output_record->client_nw_delay_usec = tpl->client_nw_delay_usec;
336 output_record->server_nw_delay_usec = tpl->server_nw_delay_usec;
337 output_record->appl_latency_usec = tpl->appl_latency_usec;
338 p = (void *)tpl->data;
339 } break;
340 case EX_RECEIVED: {
341 tpl_ext_27_t *tpl = (tpl_ext_27_t *)p;
342 value64_t v;
343 v.val.val32[0] = tpl->v[0];
344 v.val.val32[1] = tpl->v[1];
345 output_record->received = v.val.val64;
346 p = (void *)tpl->data;
347 } break;
348 #ifdef NSEL
349 case EX_NSEL_COMMON: {
350 tpl_ext_37_t *tpl = (tpl_ext_37_t *)p;
351 value64_t v;
352 v.val.val32[0] = tpl->v[0];
353 v.val.val32[1] = tpl->v[1];
354 output_record->event_time = v.val.val64;
355 output_record->conn_id = tpl->conn_id;
356 output_record->event = tpl->fw_event;
357 output_record->event_flag = FW_EVENT;
358 output_record->fw_xevent = tpl->fw_xevent;
359 output_record->icmp = tpl->nsel_icmp;
360 output_record->sec_group_tag = tpl->sec_group_tag;
361 p = (void *)tpl->data;
362 } break;
363 case EX_NSEL_XLATE_PORTS: {
364 tpl_ext_38_t *tpl = (tpl_ext_38_t *)p;
365 output_record->xlate_src_port = tpl->xlate_src_port;
366 output_record->xlate_dst_port = tpl->xlate_dst_port;
367 p = (void *)tpl->data;
368 } break;
369 case EX_NSEL_XLATE_IP_v4: {
370 tpl_ext_39_t *tpl = (tpl_ext_39_t *)p;
371 output_record->xlate_src_ip.V6[0] = 0;
372 output_record->xlate_src_ip.V6[1] = 0;
373 output_record->xlate_src_ip.V4 = tpl->xlate_src_ip;
374 output_record->xlate_dst_ip.V6[0] = 0;
375 output_record->xlate_dst_ip.V6[1] = 0;
376 output_record->xlate_dst_ip.V4 = tpl->xlate_dst_ip;
377 p = (void *)tpl->data;
378 output_record->xlate_flags = 0;
379 } break;
380 case EX_NSEL_XLATE_IP_v6: {
381 tpl_ext_40_t *tpl = (tpl_ext_40_t *)p;
382 output_record->xlate_src_ip.V6[0] = tpl->xlate_src_ip[0];
383 output_record->xlate_src_ip.V6[1] = tpl->xlate_src_ip[1];
384 output_record->xlate_dst_ip.V6[0] = tpl->xlate_dst_ip[0];
385 output_record->xlate_dst_ip.V6[1] = tpl->xlate_dst_ip[1];
386 p = (void *)tpl->data;
387 output_record->xlate_flags = 1;
388 } break;
389 case EX_NSEL_ACL: {
390 tpl_ext_41_t *tpl = (tpl_ext_41_t *)p;
391 int j;
392 for (j=0; j<3; j++) {
393 output_record->ingress_acl_id[j] = tpl->ingress_acl_id[j];
394 output_record->egress_acl_id[j] = tpl->egress_acl_id[j];
395 }
396 p = (void *)tpl->data;
397 } break;
398 case EX_NSEL_USER: {
399 tpl_ext_42_t *tpl = (tpl_ext_42_t *)p;
400 strncpy((void *)output_record->username, (void *)tpl->username, sizeof(output_record->username));
401 output_record->username[sizeof(output_record->username)-1] = '\0'; // safety 0
402 p = (void *)tpl->data;
403 } break;
404 case EX_NSEL_USER_MAX: {
405 tpl_ext_43_t *tpl = (tpl_ext_43_t *)p;
406 strncpy((void *)output_record->username, (void *)tpl->username, sizeof(output_record->username));
407 output_record->username[sizeof(output_record->username)-1] = '\0'; // safety 0
408 p = (void *)tpl->data;
409 } break;
410 case EX_NEL_COMMON: {
411 tpl_ext_46_t *tpl = (tpl_ext_46_t *)p;
412 output_record->event = tpl->nat_event;
413 output_record->event_flag = FW_EVENT;
414 // XXX - 3 bytes unused
415 output_record->egress_vrfid = tpl->egress_vrfid;
416 output_record->ingress_vrfid = tpl->ingress_vrfid;
417 p = (void *)tpl->data;
418
419 // remember this value, if we read old 1.6.10 files
420 compat_nel_bug.vrf = tpl->egress_vrfid;
421 if ( compat_nel ) {
422 output_record->xlate_src_port = compat_nel_bug.port[0];
423 output_record->xlate_dst_port = compat_nel_bug.port[1];
424 output_record->egress_vrfid = 0;
425 }
426 } break;
427 // compat record v1.6.10
428 case EX_NEL_GLOBAL_IP_v4: {
429 tpl_ext_47_t *tpl = (tpl_ext_47_t *)p;
430 output_record->xlate_src_ip.V6[0] = 0;
431 output_record->xlate_src_ip.V6[1] = 0;
432 output_record->xlate_src_ip.V4 = tpl->nat_inside;
433 output_record->xlate_dst_ip.V6[0] = 0;
434 output_record->xlate_dst_ip.V6[1] = 0;
435 output_record->xlate_dst_ip.V4 = tpl->nat_outside;
436 p = (void *)tpl->data;
437
438 output_record->xlate_src_port = compat_nel_bug.port[0];
439 output_record->xlate_dst_port = compat_nel_bug.port[1];
440 output_record->egress_vrfid = 0;
441 compat_nel = 1;
442 } break;
443 case EX_PORT_BLOCK_ALLOC: {
444 tpl_ext_48_t *tpl = (tpl_ext_48_t *)p;
445 output_record->block_start = tpl->block_start;
446 output_record->block_end = tpl->block_end;
447 output_record->block_step = tpl->block_step;
448 output_record->block_size = tpl->block_size;
449 if ( output_record->block_end == 0 && output_record->block_size != 0 )
450 output_record->block_end = output_record->block_start + output_record->block_size - 1;
451 p = (void *)tpl->data;
452 } break;
453
454 #endif
455 }
456 }
457
458 } // End of ExpandRecord_v2
459
460 #ifdef NEED_PACKRECORD
PackRecord(master_record_t * master_record,nffile_t * nffile)461 static void PackRecord(master_record_t *master_record, nffile_t *nffile) {
462 extension_map_t *extension_map = master_record->map_ref;
463 common_record_t *common_record;
464 uint32_t required = COMMON_RECORD_DATA_SIZE + extension_map->extension_size;
465 size_t size;
466 void *p;
467 int i;
468
469 // check size of packets and bytes
470 if ( master_record->dPkts > 0xffffffffLL ) {
471 master_record->flags |= FLAG_PKG_64;
472 required += 8;
473 } else {
474 master_record->flags &= ~FLAG_PKG_64;
475 required += 4;
476 }
477
478 if ( master_record->dOctets > 0xffffffffLL ) {
479 master_record->flags |= FLAG_BYTES_64;
480 required += 8;
481 } else {
482 master_record->flags &= ~FLAG_BYTES_64;
483 required += 4;
484 }
485 if ( (master_record->flags & FLAG_IPV6_ADDR) != 0 ) // IPv6
486 required += 32;
487 else
488 required += 8;
489
490 master_record->size = required;
491
492 // flush current buffer to disc if not enough space
493 if ( !CheckBufferSpace(nffile, required) ) {
494 return;
495 }
496
497 // enough buffer space available at this point
498 common_record = (common_record_t *)nffile->buff_ptr;
499
500 // write common record
501 size = COMMON_RECORD_DATA_SIZE;
502 memcpy((void *)common_record, (void *)master_record, size);
503 common_record->reserved = 0;
504 p = (void *)((pointer_addr_t)common_record + size);
505
506 // Required extension 1 - IP addresses
507 if ( (master_record->flags & FLAG_IPV6_ADDR) != 0 ) { // IPv6
508 // IPv6
509 // keep compiler happy
510 // memcpy(p, (void *)master_record->V6.srcaddr, 4 * sizeof(uint64_t));
511 memcpy(p, (void *)master_record->ip_union._ip_64.addr, 4 * sizeof(uint64_t));
512 p = (void *)((pointer_addr_t)p + 4 * sizeof(uint64_t));
513 } else {
514 // IPv4
515 uint32_t *u = (uint32_t *)p;
516 u[0] = master_record->V4.srcaddr;
517 u[1] = master_record->V4.dstaddr;
518 p = (void *)((pointer_addr_t)p + 2 * sizeof(uint32_t));
519 }
520
521 // Required extension 2 - packet counter
522 if ( (master_record->flags & FLAG_PKG_64 ) != 0 ) {
523 // 64bit packet counter
524 value64_t l, *v = (value64_t *)p;
525 l.val.val64 = master_record->dPkts;
526 v->val.val32[0] = l.val.val32[0];
527 v->val.val32[1] = l.val.val32[1];
528 p = (void *)((pointer_addr_t)p + sizeof(uint64_t));
529 } else {
530 // 32bit packet counter
531 *((uint32_t *)p) = master_record->dPkts;
532 p = (void *)((pointer_addr_t)p + sizeof(uint32_t));
533 }
534
535 // Required extension 3 - byte counter
536 if ( (master_record->flags & FLAG_BYTES_64 ) != 0 ) {
537 // 64bit byte counter
538 value64_t l, *v = (value64_t *)p;
539 l.val.val64 = master_record->dOctets;
540 v->val.val32[0] = l.val.val32[0];
541 v->val.val32[1] = l.val.val32[1];
542 p = (void *)((pointer_addr_t)p + sizeof(uint64_t));
543 } else {
544 // 32bit bytes counter
545 *((uint32_t *)p) = master_record->dOctets;
546 p = (void *)((pointer_addr_t)p + sizeof(uint32_t));
547 }
548
549 // Process optional extensions
550 i=0;
551 while ( extension_map->ex_id[i] ) {
552 switch (extension_map->ex_id[i++]) {
553 // 0 - 3 should never be in an extension table so - ignore it
554 case 0:
555 case 1:
556 case 2:
557 case 3:
558 break;
559 case EX_IO_SNMP_2: { // input/output SNMP 2 byte
560 tpl_ext_4_t *tpl = (tpl_ext_4_t *)p;
561 tpl->input = master_record->input;
562 tpl->output = master_record->output;
563 p = (void *)tpl->data;
564 } break;
565 case EX_IO_SNMP_4: { // input/output SNMP 4 byte
566 tpl_ext_5_t *tpl = (tpl_ext_5_t *)p;
567 tpl->input = master_record->input;
568 tpl->output = master_record->output;
569 p = (void *)tpl->data;
570 } break;
571 case EX_AS_2: { // srcas/dstas 2 byte
572 tpl_ext_6_t *tpl = (tpl_ext_6_t *)p;
573 tpl->src_as = master_record->srcas;
574 tpl->dst_as = master_record->dstas;
575 p = (void *)tpl->data;
576 } break;
577 case EX_AS_4: { // srcas/dstas 4 byte
578 tpl_ext_7_t *tpl = (tpl_ext_7_t *)p;
579 tpl->src_as = master_record->srcas;
580 tpl->dst_as = master_record->dstas;
581 p = (void *)tpl->data;
582 } break;
583 case EX_MULIPLE: {
584 tpl_ext_8_t *tpl = (tpl_ext_8_t *)p;
585 // use a 32 bit int to copy all 4 fields
586 tpl->any = master_record->any;
587 p = (void *)tpl->data;
588 } break;
589 case EX_NEXT_HOP_v4: {
590 tpl_ext_9_t *tpl = (tpl_ext_9_t *)p;
591 tpl->nexthop = master_record->ip_nexthop.V4;
592 p = (void *)tpl->data;
593 } break;
594 case EX_NEXT_HOP_v6: {
595 tpl_ext_10_t *tpl = (tpl_ext_10_t *)p;
596 tpl->nexthop[0] = master_record->ip_nexthop.V6[0];
597 tpl->nexthop[1] = master_record->ip_nexthop.V6[1];
598 p = (void *)tpl->data;
599 } break;
600 case EX_NEXT_HOP_BGP_v4: {
601 tpl_ext_11_t *tpl = (tpl_ext_11_t *)p;
602 tpl->bgp_nexthop = master_record->bgp_nexthop.V4;
603 p = (void *)tpl->data;
604 } break;
605 case EX_NEXT_HOP_BGP_v6: {
606 tpl_ext_12_t *tpl = (tpl_ext_12_t *)p;
607 tpl->bgp_nexthop[0] = master_record->bgp_nexthop.V6[0];
608 tpl->bgp_nexthop[1] = master_record->bgp_nexthop.V6[1];
609 p = (void *)tpl->data;
610 } break;
611 case EX_VLAN: {
612 tpl_ext_13_t *tpl = (tpl_ext_13_t *)p;
613 tpl->src_vlan = master_record->src_vlan;
614 tpl->dst_vlan = master_record->dst_vlan;
615 p = (void *)tpl->data;
616 } break;
617 case EX_OUT_PKG_4: {
618 tpl_ext_14_t *tpl = (tpl_ext_14_t *)p;
619 tpl->out_pkts = master_record->out_pkts;
620 p = (void *)tpl->data;
621 } break;
622 case EX_OUT_PKG_8: {
623 tpl_ext_15_t v, *tpl = (tpl_ext_15_t *)p;
624 v.out_pkts = master_record->out_pkts;
625 tpl->v[0] = v.v[0];
626 tpl->v[1] = v.v[1];
627 p = (void *)tpl->data;
628 } break;
629 case EX_OUT_BYTES_4: {
630 tpl_ext_16_t *tpl = (tpl_ext_16_t *)p;
631 tpl->out_bytes = master_record->out_bytes;
632 p = (void *)tpl->data;
633 } break;
634 case EX_OUT_BYTES_8: {
635 tpl_ext_17_t v, *tpl = (tpl_ext_17_t *)p;
636 v.out_bytes = master_record->out_bytes;
637 tpl->v[0] = v.v[0];
638 tpl->v[1] = v.v[1];
639 p = (void *)tpl->data;
640 } break;
641 case EX_AGGR_FLOWS_4: {
642 tpl_ext_18_t *tpl = (tpl_ext_18_t *)p;
643 tpl->aggr_flows = master_record->aggr_flows;
644 p = (void *)tpl->data;
645 } break;
646 case EX_AGGR_FLOWS_8: {
647 tpl_ext_19_t v, *tpl = (tpl_ext_19_t *)p;
648 v.aggr_flows = master_record->aggr_flows;
649 tpl->v[0] = v.v[0];
650 tpl->v[1] = v.v[1];
651 p = (void *)tpl->data;
652 } break;
653 case EX_MAC_1: {
654 tpl_ext_20_t v, *tpl = (tpl_ext_20_t *)p;
655 v.in_src_mac = master_record->in_src_mac;
656 tpl->v1[0] = v.v1[0];
657 tpl->v1[1] = v.v1[1];
658 v.out_dst_mac = master_record->out_dst_mac;
659 tpl->v2[0] = v.v2[0];
660 tpl->v2[1] = v.v2[1];
661 p = (void *)tpl->data;
662 } break;
663 case EX_MAC_2: {
664 tpl_ext_21_t v, *tpl = (tpl_ext_21_t *)p;
665 v.in_dst_mac = master_record->in_dst_mac;
666 tpl->v1[0] = v.v1[0];
667 tpl->v1[1] = v.v1[1];
668 v.out_src_mac = master_record->out_src_mac;
669 tpl->v2[0] = v.v2[0];
670 tpl->v2[1] = v.v2[1];
671 p = (void *)tpl->data;
672 } break;
673 case EX_MPLS: {
674 tpl_ext_22_t *tpl = (tpl_ext_22_t *)p;
675 int j;
676 for (j=0; j<10; j++ ) {
677 tpl->mpls_label[j] = master_record->mpls_label[j];
678 }
679 p = (void *)tpl->data;
680 } break;
681 case EX_ROUTER_IP_v4: {
682 tpl_ext_23_t *tpl = (tpl_ext_23_t *)p;
683 tpl->router_ip = master_record->ip_router.V4;
684 p = (void *)tpl->data;
685 } break;
686 case EX_ROUTER_IP_v6: {
687 tpl_ext_24_t *tpl = (tpl_ext_24_t *)p;
688 tpl->router_ip[0] = master_record->ip_router.V6[0];
689 tpl->router_ip[1] = master_record->ip_router.V6[1];
690 p = (void *)tpl->data;
691 } break;
692 case EX_ROUTER_ID: {
693 tpl_ext_25_t *tpl = (tpl_ext_25_t *)p;
694 tpl->engine_type = master_record->engine_type;
695 tpl->engine_id = master_record->engine_id;
696 p = (void *)tpl->data;
697 } break;
698 case EX_BGPADJ: {
699 tpl_ext_26_t *tpl = (tpl_ext_26_t *)p;
700 tpl->bgpNextAdjacentAS = master_record->bgpNextAdjacentAS;
701 tpl->bgpPrevAdjacentAS = master_record->bgpPrevAdjacentAS;
702 p = (void *)tpl->data;
703 } break;
704 case EX_RECEIVED: {
705 tpl_ext_27_t *tpl = (tpl_ext_27_t *)p;
706 tpl->received = master_record->received;
707 p = (void *)tpl->data;
708 } break;
709 case EX_LATENCY: {
710 tpl_ext_latency_t *tpl = (tpl_ext_latency_t *)p;
711 tpl->client_nw_delay_usec = master_record->client_nw_delay_usec;
712 tpl->server_nw_delay_usec = master_record->server_nw_delay_usec;
713 tpl->appl_latency_usec = master_record->appl_latency_usec;
714 p = (void *)tpl->data;
715 } break;
716 #ifdef NSEL
717 case EX_NSEL_COMMON: {
718 tpl_ext_37_t *tpl = (tpl_ext_37_t *)p;
719 tpl->event_time = master_record->event_time;
720 tpl->conn_id = master_record->conn_id;
721 tpl->fw_event = master_record->event;
722 tpl->nsel_icmp = master_record->icmp;
723 tpl->fill = 0;
724 tpl->sec_group_tag = master_record->sec_group_tag;
725 tpl->fw_xevent = master_record->fw_xevent;
726 p = (void *)tpl->data;
727 } break;
728 case EX_NSEL_XLATE_PORTS: {
729 tpl_ext_38_t *tpl = (tpl_ext_38_t *)p;
730 tpl->xlate_src_port = master_record->xlate_src_port;
731 tpl->xlate_dst_port = master_record->xlate_dst_port;
732 p = (void *)tpl->data;
733 } break;
734 case EX_NSEL_XLATE_IP_v4: {
735 tpl_ext_39_t *tpl = (tpl_ext_39_t *)p;
736 tpl->xlate_src_ip = master_record->xlate_src_ip.V4;
737 tpl->xlate_dst_ip = master_record->xlate_dst_ip.V4;
738 p = (void *)tpl->data;
739 } break;
740 case EX_NSEL_XLATE_IP_v6: {
741 tpl_ext_40_t *tpl = (tpl_ext_40_t *)p;
742 tpl->xlate_src_ip[0] = master_record->xlate_src_ip.V6[0];
743 tpl->xlate_src_ip[1] = master_record->xlate_src_ip.V6[1];
744 p = (void *)tpl->data;
745 tpl->xlate_dst_ip[0] = master_record->xlate_dst_ip.V6[0];
746 tpl->xlate_dst_ip[1] = master_record->xlate_dst_ip.V6[1];
747 p = (void *)tpl->data;
748 } break;
749 case EX_NSEL_ACL: {
750 tpl_ext_41_t *tpl = (tpl_ext_41_t *)p;
751 int j;
752 for (j=0; j<3; j++) {
753 tpl->ingress_acl_id[j] = master_record->ingress_acl_id[j];
754 tpl->egress_acl_id[j] = master_record->egress_acl_id[j];
755 }
756 p = (void *)tpl->data;
757 } break;
758 case EX_NSEL_USER: {
759 tpl_ext_42_t *tpl = (tpl_ext_42_t *)p;
760 strncpy((void *)tpl->username, (void *)master_record->username, sizeof(tpl->username));
761 tpl->username[sizeof(tpl->username)-1] = '\0'; // safety 0
762 p = (void *)tpl->data;
763 } break;
764 case EX_NSEL_USER_MAX: {
765 tpl_ext_43_t *tpl = (tpl_ext_43_t *)p;
766 strncpy((void *)tpl->username, (void *)master_record->username, sizeof(tpl->username));
767 tpl->username[sizeof(tpl->username)-1] = '\0'; // safety 0
768 p = (void *)tpl->data;
769 } break;
770 case EX_NEL_COMMON: {
771 tpl_ext_46_t *tpl = (tpl_ext_46_t *)p;
772 tpl->nat_event = master_record->event;
773 tpl->fill = 0;
774 tpl->flags = 0;
775 tpl->egress_vrfid = master_record->egress_vrfid;
776 tpl->ingress_vrfid = master_record->ingress_vrfid;
777 p = (void *)tpl->data;
778 } break;
779 case EX_PORT_BLOCK_ALLOC: {
780 tpl_ext_48_t *tpl = (tpl_ext_48_t *)p;
781 tpl->block_start = master_record->block_start;
782 tpl->block_end = master_record->block_end;
783 tpl->block_step = master_record->block_step;
784 tpl->block_size = master_record->block_size;
785 p = (void *)tpl->data;
786 } break;
787 #endif
788 }
789 }
790
791 nffile->block_header->size += required;
792 nffile->block_header->NumRecords++;
793 #ifdef DEVEL
794 if ( ((pointer_addr_t)p - (pointer_addr_t)nffile->buff_ptr) != required ) {
795 fprintf(stderr, "Packrecord: size missmatch: required: %i, written: %li!\n",
796 required, (long)((ptrdiff_t)p - (ptrdiff_t)nffile->buff_ptr));
797 exit(255);
798 }
799 #endif
800 nffile->buff_ptr = p;
801
802 } // End of PackRecord
803 #endif
804
AppendToBuffer(nffile_t * nffile,void * record,size_t required)805 static inline void AppendToBuffer(nffile_t *nffile, void *record, size_t required) {
806
807 // flush current buffer to disc
808 if ( !CheckBufferSpace(nffile, required)) {
809 return;
810 }
811
812 // enough buffer space available at this point
813 memcpy(nffile->buff_ptr, record, required);
814
815 // update stat
816 nffile->block_header->NumRecords++;
817 nffile->block_header->size += required;
818
819 // advance write pointer
820 nffile->buff_ptr = (void *)((pointer_addr_t)nffile->buff_ptr + required);
821
822 } // End of AppendToBuffer
823