1 /*
2 * Copyright (c) 2009-2020 Peter Haag
3 * Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 * * Neither the name of the author nor the names of its contributors may be
15 * used to endorse or promote products derived from this software without
16 * specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *
30 */
31
32 #include "config.h"
33
34 #include <stdio.h>
35 #include <unistd.h>
36 #include <stdlib.h>
37 #include <stdarg.h>
38 #include <errno.h>
39 #include <time.h>
40 #include <string.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <fcntl.h>
44 #include <sys/socket.h>
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
47
48 #ifdef HAVE_STDINT_H
49 #include <stdint.h>
50 #endif
51
52 #include "util.h"
53 #include "nfdump.h"
54 #include "nffile.h"
55 #include "collector.h"
56 #include "nfx.h"
57
58 extern extension_descriptor_t extension_descriptor[];
59
60 static time_t when;
61 uint32_t offset = 10;
62 uint32_t msecs = 10;
63
64 static extension_info_t extension_info;
65
66 #define NEED_PACKRECORD 1
67 #include "nffile_inline.c"
68 #undef NEED_PACKRECORD
69
70 void *GenRecord(int af, void *buff_ptr, char *src_ip, char *dst_ip, int src_port, int dst_port,
71 int proto, int tcp_flags, int tos, uint64_t packets, uint64_t bytes, int src_as, int dst_as);
72
73 static void SetIPaddress(master_record_t *record, int af, char *src_ip, char *dst_ip);
74
75 static void SetNextIPaddress(master_record_t *record, int af, char *next_ip);
76
77 static void SetRouterIPaddress(master_record_t *record, int af, char *next_ip);
78
79 static void SetBGPNextIPaddress(master_record_t *record, int af, char *next_ip);
80
81 static void UpdateRecord(master_record_t *record);
82
SetIPaddress(master_record_t * record,int af,char * src_ip,char * dst_ip)83 static void SetIPaddress(master_record_t *record, int af, char *src_ip, char *dst_ip) {
84
85 if ( af == PF_INET6 ) {
86 SetFlag(record->flags, FLAG_IPV6_ADDR);
87 inet_pton(PF_INET6, src_ip, &(record->V6.srcaddr[0]));
88 inet_pton(PF_INET6, dst_ip, &(record->V6.dstaddr[0]));
89 record->V6.srcaddr[0] = ntohll(record->V6.srcaddr[0]);
90 record->V6.srcaddr[1] = ntohll(record->V6.srcaddr[1]);
91 record->V6.dstaddr[0] = ntohll(record->V6.dstaddr[0]);
92 record->V6.dstaddr[1] = ntohll(record->V6.dstaddr[1]);
93 } else {
94 ClearFlag(record->flags, FLAG_IPV6_ADDR);
95 inet_pton(PF_INET, src_ip, &record->V4.srcaddr);
96 inet_pton(PF_INET, dst_ip, &record->V4.dstaddr);
97 record->V4.srcaddr = ntohl(record->V4.srcaddr);
98 record->V4.dstaddr = ntohl(record->V4.dstaddr);
99 }
100
101 } // End of SetIPaddress
102
SetNextIPaddress(master_record_t * record,int af,char * next_ip)103 static void SetNextIPaddress(master_record_t *record, int af, char *next_ip) {
104
105 if ( af == PF_INET6 ) {
106 SetFlag(record->flags, FLAG_IPV6_NH);
107 inet_pton(PF_INET6, next_ip, &(record->ip_nexthop.V6[0]));
108 record->ip_nexthop.V6[0] = ntohll(record->ip_nexthop.V6[0]);
109 record->ip_nexthop.V6[1] = ntohll(record->ip_nexthop.V6[1]);
110 } else {
111 ClearFlag(record->flags, FLAG_IPV6_NH);
112 inet_pton(PF_INET, next_ip, &record->ip_nexthop.V4);
113 record->ip_nexthop.V4 = ntohl(record->ip_nexthop.V4);
114 }
115
116 } // End of SetNextIPaddress
117
SetRouterIPaddress(master_record_t * record,int af,char * next_ip)118 static void SetRouterIPaddress(master_record_t *record, int af, char *next_ip) {
119
120 if ( af == PF_INET6 ) {
121 SetFlag(record->flags, FLAG_IPV6_NH);
122 inet_pton(PF_INET6, next_ip, &(record->ip_router.V6[0]));
123 record->ip_router.V6[0] = ntohll(record->ip_router.V6[0]);
124 record->ip_router.V6[1] = ntohll(record->ip_router.V6[1]);
125 } else {
126 ClearFlag(record->flags, FLAG_IPV6_NH);
127 inet_pton(PF_INET, next_ip, &record->ip_router.V4);
128 record->ip_router.V4 = ntohl(record->ip_router.V4);
129 }
130
131 } // End of SetRouterIPaddress
132
SetBGPNextIPaddress(master_record_t * record,int af,char * next_ip)133 static void SetBGPNextIPaddress(master_record_t *record, int af, char *next_ip) {
134
135 if ( af == PF_INET6 ) {
136 SetFlag(record->flags, FLAG_IPV6_NHB);
137 inet_pton(PF_INET6, next_ip, &(record->bgp_nexthop.V6[0]));
138 record->bgp_nexthop.V6[0] = ntohll(record->bgp_nexthop.V6[0]);
139 record->bgp_nexthop.V6[1] = ntohll(record->bgp_nexthop.V6[1]);
140 } else {
141 ClearFlag(record->flags, FLAG_IPV6_NHB);
142 inet_pton(PF_INET, next_ip, &record->bgp_nexthop.V4);
143 record->bgp_nexthop.V4 = ntohl(record->bgp_nexthop.V4);
144 }
145
146 } // End of SetBGPNextIPaddress
147
148
UpdateRecord(master_record_t * record)149 static void UpdateRecord(master_record_t *record) {
150
151 record->first = when;
152 record->last = when + offset;
153 record->msec_first = msecs;
154 record->msec_last = msecs + 10;
155
156 when += 10;
157 offset += 10;
158
159 msecs += 100;
160 if ( msecs > 1000 )
161 msecs = msecs - 1000;
162
163 record->fwd_status++;
164
165 } // End of UpdateRecord
166
main(int argc,char ** argv)167 int main( int argc, char **argv ) {
168 int i, c;
169 master_record_t record;
170 nffile_t *nffile;
171
172 when = ISO2UNIX(strdup("200407111030"));
173 while ((c = getopt(argc, argv, "h")) != EOF) {
174 switch(c) {
175 case 'h':
176 break;
177 default:
178 fprintf(stderr, "ERROR: Unsupported option: '%c'\n", c);
179 exit(255);
180 }
181 }
182
183 extension_info.map = (extension_map_t *)malloc(sizeof(extension_map_t) + 32 * sizeof(uint16_t));
184 if ( !extension_info.map ) {
185 fprintf(stderr, "malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror (errno));
186 exit(255);
187 }
188 extension_info.map->type = ExtensionMapType;
189 extension_info.map->map_id = 0;
190 i = 0;
191 extension_info.map->ex_id[i++] = EX_IO_SNMP_2;
192 extension_info.map->ex_id[i++] = EX_AS_2;
193 extension_info.map->ex_id[i++] = EX_MULIPLE;
194 extension_info.map->ex_id[i++] = EX_NEXT_HOP_v4;
195 extension_info.map->ex_id[i++] = EX_NEXT_HOP_BGP_v4;
196 extension_info.map->ex_id[i++] = EX_VLAN;
197 extension_info.map->ex_id[i++] = EX_OUT_PKG_4;
198 extension_info.map->ex_id[i++] = EX_OUT_BYTES_4;
199 extension_info.map->ex_id[i++] = EX_AGGR_FLOWS_4;
200 extension_info.map->ex_id[i++] = EX_MAC_1;
201 extension_info.map->ex_id[i++] = EX_MAC_2;
202 extension_info.map->ex_id[i++] = EX_MPLS;
203 extension_info.map->ex_id[i++] = EX_ROUTER_IP_v4;
204 extension_info.map->ex_id[i++] = EX_ROUTER_ID;
205 extension_info.map->ex_id[i++] = EX_BGPADJ;
206 extension_info.map->ex_id[i] = 0;
207 extension_info.map->size = sizeof(extension_map_t) + i * sizeof(uint16_t);
208
209 // align 32bits
210 if (( extension_info.map->size & 0x3 ) != 0 ) {
211 extension_info.map->size += 4 - ( extension_info.map->size & 0x3 );
212 }
213
214 extension_info.map->extension_size = 0;
215 i=0;
216 while (extension_info.map->ex_id[i]) {
217 int id = extension_info.map->ex_id[i];
218 extension_info.map->extension_size += extension_descriptor[id].size;
219 i++;
220 }
221 memset((void *)&record, 0, sizeof(record));
222
223 nffile = OpenNewFile("-", NULL, NOT_COMPRESSED, 0, NULL);
224 if ( !nffile ) {
225 exit(255);
226 }
227
228 AppendToBuffer(nffile, (void *)extension_info.map, extension_info.map->size);
229
230 record.map_ref = extension_info.map;
231 record.type = CommonRecordType;
232
233 record.flags = 0;
234 record.exporter_sysid = 1;
235 record.tcp_flags = 1;
236 record.tos = 2;
237 record.fwd_status = 0;
238 record.srcport = 1024;
239 record.dstport = 25;
240 record.prot = IPPROTO_TCP;
241 record.input = 12;
242 record.output = 14;
243 record.srcas = 775;
244 record.dstas = 8404;
245 SetIPaddress(&record, PF_INET, "172.16.1.66", "192.168.170.100");
246 SetNextIPaddress(&record, PF_INET, "172.72.1.2");
247 SetBGPNextIPaddress(&record, PF_INET, "172.73.2.3");
248 SetRouterIPaddress(&record, PF_INET, "127.0.0.1");
249 record.engine_type = 5;
250 record.engine_id = 6;
251 record.dPkts = 202;
252 record.dOctets = 303;
253 record.dst_tos = 128;
254 record.dir = 1;
255 record.src_mask = 16;
256 record.dst_mask = 24;
257 record.src_vlan = 82;
258 record.dst_vlan = 93;
259 record.out_pkts = 212;
260 record.out_bytes = 3234;
261 record.aggr_flows = 3;
262 record.in_src_mac = 0x0234567890aaLL;
263 record.out_dst_mac = 0xffeeddccbbaaLL;
264 record.out_src_mac = 0xaa3456789002LL;
265 record.in_dst_mac = 0xaaeeddccbbffLL;
266 record.mpls_label[0] = 1010 << 4;
267 record.mpls_label[1] = 2020 << 4;
268 record.mpls_label[2] = 3030 << 4;
269 record.mpls_label[3] = 4040 << 4;
270 record.mpls_label[4] = 5050 << 4;
271 record.mpls_label[5] = 6060 << 4;
272 record.mpls_label[6] = 7070 << 4;
273 record.mpls_label[7] = 8080 << 4;
274 record.mpls_label[8] = 9090 << 4;
275 record.mpls_label[9] = (100100 << 4) + 1;
276 record.client_nw_delay_usec = 2;
277 record.server_nw_delay_usec = 22;
278 record.appl_latency_usec = 222;
279 record.bgpNextAdjacentAS = 45804;
280 record.bgpPrevAdjacentAS = 32775;
281
282 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
283 UpdateRecord(&record);
284 PackRecord(&record, nffile);
285
286 SetIPaddress(&record, PF_INET, "172.16.2.66", "192.168.170.101");
287 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
288 UpdateRecord(&record);
289 PackRecord(&record, nffile);
290
291 record.dPkts = 101;
292 record.dOctets = 102;
293 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
294 UpdateRecord(&record);
295 PackRecord(&record, nffile);
296
297 SetIPaddress(&record, PF_INET, "172.16.3.66", "192.168.170.102");
298 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
299 UpdateRecord(&record);
300 PackRecord(&record, nffile);
301
302 SetIPaddress(&record, PF_INET, "172.16.4.66", "192.168.170.103");
303 record.srcport = 2024;
304 record.prot = IPPROTO_UDP;
305 record.tcp_flags = 1;
306 record.tos = 1;
307 record.dPkts = 1001;
308 record.dOctets = 1002;
309 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
310 UpdateRecord(&record);
311 PackRecord(&record, nffile);
312
313 SetIPaddress(&record, PF_INET, "172.16.5.66", "192.168.170.104");
314 record.srcport = 3024;
315 record.prot = 51;
316 record.tcp_flags = 2;
317 record.tos = 2;
318 record.dPkts = 10001;
319 record.dOctets = 10002;
320 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
321 UpdateRecord(&record);
322 PackRecord(&record, nffile);
323
324 SetIPaddress(&record, PF_INET, "172.16.6.66", "192.168.170.105");
325 record.srcport = 4024;
326 record.prot = IPPROTO_TCP;
327 record.tcp_flags = 4;
328 record.tos = 3;
329 record.dPkts = 100001;
330 record.dOctets = 100002;
331 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
332 UpdateRecord(&record);
333 PackRecord(&record, nffile);
334
335 SetIPaddress(&record, PF_INET, "172.16.7.66", "192.168.170.106");
336 record.srcport = 5024;
337 record.tcp_flags = 8;
338 record.tos = 4;
339 record.dPkts = 1000001;
340 record.dOctets = 1000002;
341 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
342 UpdateRecord(&record);
343 PackRecord(&record, nffile);
344
345 SetIPaddress(&record, PF_INET, "172.16.8.66", "192.168.170.107");
346 record.tcp_flags = 1;
347 record.tos = 4;
348 record.dPkts = 10000001;
349 record.dOctets = 1001;
350 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
351 UpdateRecord(&record);
352 PackRecord(&record, nffile);
353
354 SetIPaddress(&record, PF_INET, "172.16.9.66", "192.168.170.108");
355 record.srcport = 6024;
356 record.tcp_flags = 16;
357 record.tos = 5;
358 record.dPkts = 500;
359 record.dOctets = 10000001;
360 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
361 UpdateRecord(&record);
362 PackRecord(&record, nffile);
363
364 SetIPaddress(&record, PF_INET, "172.16.10.66", "192.168.170.109");
365 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
366 UpdateRecord(&record);
367 PackRecord(&record, nffile);
368
369 SetIPaddress(&record, PF_INET, "172.16.11.66", "192.168.170.110");
370 record.srcport = 7024;
371 record.tcp_flags = 32;
372 record.tos = 255;
373 record.dPkts = 5000;
374 record.dOctets = 100000001;
375 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
376 UpdateRecord(&record);
377 PackRecord(&record, nffile);
378
379 SetIPaddress(&record, PF_INET, "172.16.12.66", "192.168.170.111");
380 record.srcport = 8024;
381 record.tcp_flags = 63;
382 record.tos = 0;
383 record.dOctets = 1000000001;
384 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
385 UpdateRecord(&record);
386 PackRecord(&record, nffile);
387
388 SetIPaddress(&record, PF_INET, "172.16.13.66", "192.168.170.112");
389 record.srcport = 0;
390 record.dstport = 8;
391 record.prot = IPPROTO_ICMP;
392 record.tcp_flags = 0;
393 record.tos = 0;
394 record.dPkts = 50002;
395 record.dOctets = 50000;
396 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
397 UpdateRecord(&record);
398 PackRecord(&record, nffile);
399
400 SetIPaddress(&record, PF_INET, "172.160.160.166", "172.160.160.180");
401 record.srcport = 10024;
402 record.dstport = 25000;
403 record.prot = IPPROTO_TCP;
404 record.dPkts = 500001;
405 record.dOctets = 500000;
406 fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
407 UpdateRecord(&record);
408 PackRecord(&record, nffile);
409
410 SetIPaddress(&record, PF_INET6, "fe80::2110:abcd:1234:0", "fe80::2110:abcd:1235:4321");
411 // SetNextIPaddress(&record, PF_INET6, "2003:234:aabb::211:24ff:fe80:d01e");
412 // SetBGPNextIPaddress(&record, PF_INET6, "2004:234:aabb::211:24ff:fe80:d01e");
413 record.srcport = 1024;
414 record.dstport = 25;
415 record.tcp_flags = 27;
416 record.dPkts = 10;
417 record.dOctets = 15100;
418 fprintf(stderr, "IPv6 32bit packets 32bit bytes\n");
419 UpdateRecord(&record);
420 PackRecord(&record, nffile);
421
422 SetIPaddress(&record, PF_INET6, "2001:234:aabb:cc:211:24ff:fe80:d01e", "2001:620:1f:8:203:baff:fe52:38e5");
423 record.src_mask = 88;
424 record.dst_mask = 48;
425 record.srcport = 10240;
426 record.dstport = 52345;
427 record.dPkts = 10100;
428 record.dOctets = 15000000;
429 fprintf(stderr, "IPv6 32bit packets 32bit bytes\n");
430 UpdateRecord(&record);
431 PackRecord(&record, nffile);
432
433 record.dPkts = 10100000;
434 record.dOctets = 0x100000000LL;
435 fprintf(stderr, "IPv6 32bit packets 64bit bytes\n");
436 UpdateRecord(&record);
437 PackRecord(&record, nffile);
438
439 record.dPkts = 0x100000000LL;
440 record.dOctets = 15000000;
441 fprintf(stderr, "IPv6 64bit packets 32bit bytes\n");
442 UpdateRecord(&record);
443 PackRecord(&record, nffile);
444
445 record.dOctets = 0x200000000LL;
446 fprintf(stderr, "IPv6 64bit packets 64bit bytes\n");
447 UpdateRecord(&record);
448 PackRecord(&record, nffile);
449
450 SetIPaddress(&record, PF_INET, "172.16.14.18", "192.168.170.113");
451 // SetNextIPaddress(&record, PF_INET, "172.72.1.2");
452 // SetBGPNextIPaddress(&record, PF_INET, "172.73.2.3");
453 record.src_mask = 16;
454 record.dst_mask = 24;
455 record.srcport = 10240;
456 record.dstport = 52345;
457 record.dPkts = 10100000;
458 record.dOctets = 0x100000000LL;
459 fprintf(stderr, "IPv4 32bit packets 64bit bytes\n");
460 UpdateRecord(&record);
461 PackRecord(&record, nffile);
462
463 SetIPaddress(&record, PF_INET, "172.16.15.18", "192.168.170.114");
464 record.dPkts = 0x100000000LL;
465 record.dOctets = 15000000;
466 fprintf(stderr, "IPv4 64bit packets 32bit bytes\n");
467 UpdateRecord(&record);
468 PackRecord(&record, nffile);
469
470 SetIPaddress(&record, PF_INET, "172.16.16.18", "192.168.170.115");
471 record.dOctets = 0x200000000LL;
472 fprintf(stderr, "IPv4 64bit packets 64bit bytes\n");
473 UpdateRecord(&record);
474 PackRecord(&record, nffile);
475
476 extension_info.map->ex_id[0] = EX_IO_SNMP_4;
477
478 extension_info.map->extension_size = 0;
479 i=0;
480 while (extension_info.map->ex_id[i]) {
481 int id = extension_info.map->ex_id[i];
482 extension_info.map->extension_size += extension_descriptor[id].size;
483 i++;
484 }
485
486 memcpy(nffile->buff_ptr, (void *)extension_info.map, extension_info.map->size);
487 nffile->buff_ptr += extension_info.map->size;
488 nffile->block_header->NumRecords++;
489 nffile->block_header->size += extension_info.map->size;
490
491 UpdateRecord(&record);
492 fprintf(stderr, "4 bytes interfaces, 2 bytes AS numbers %d %d\n", record.fwd_status, nffile->block_header->NumRecords);
493 PackRecord(&record, nffile);
494
495 extension_info.map->ex_id[0] = EX_IO_SNMP_2;
496 extension_info.map->ex_id[1] = EX_AS_4;
497
498 extension_info.map->extension_size = 0;
499 i=0;
500 while (extension_info.map->ex_id[i]) {
501 int id = extension_info.map->ex_id[i];
502 extension_info.map->extension_size += extension_descriptor[id].size;
503 i++;
504 }
505
506 memcpy(nffile->buff_ptr, (void *)extension_info.map, extension_info.map->size);
507 nffile->buff_ptr += extension_info.map->size;
508 nffile->block_header->NumRecords++;
509 nffile->block_header->size += extension_info.map->size;
510
511 UpdateRecord(&record);
512 fprintf(stderr, "2 bytes interfaces, 4 bytes AS numbers %d %d\n", record.fwd_status, nffile->block_header->NumRecords);
513 PackRecord(&record, nffile);
514
515 extension_info.map->ex_id[0] = EX_IO_SNMP_4;
516
517 extension_info.map->extension_size = 0;
518 i=0;
519 while (extension_info.map->ex_id[i]) {
520 int id = extension_info.map->ex_id[i];
521 extension_info.map->extension_size += extension_descriptor[id].size;
522 i++;
523 }
524
525 memcpy(nffile->buff_ptr, (void *)extension_info.map, extension_info.map->size);
526 nffile->buff_ptr += extension_info.map->size;
527 nffile->block_header->NumRecords++;
528 nffile->block_header->size += extension_info.map->size;
529
530 UpdateRecord(&record);
531 fprintf(stderr, "4 bytes interfaces, 4 bytes AS numbers %d %d\n", record.fwd_status, nffile->block_header->NumRecords);
532 PackRecord(&record, nffile);
533
534 if ( nffile->block_header->NumRecords ) {
535 if ( WriteBlock(nffile) <= 0 ) {
536 fprintf(stderr, "Failed to write output buffer to disk: '%s'" , strerror(errno));
537 }
538 }
539
540 return 0;
541 }
542
543