/* status of read and fill pre-prepared structure lnf_rec */ int lnf_write(lnf_file_t *lnf_file, lnf_rec_t *lnf_rec) { extension_map_t *map; /* lookup and add map into file it it is nescessary */ map = lnf_lookup_map(lnf_file, lnf_rec->extensions_arr); if (map == NULL) { return LNF_ERR_WRITE; } lnf_rec->master_record->map_ref = map; lnf_rec->master_record->ext_map = map->map_id; lnf_rec->master_record->type = CommonRecordType; UpdateStat(lnf_file->nffile->stat_record, lnf_rec->master_record); PackRecord(lnf_rec->master_record, lnf_file->nffile); return LNF_OK; }
int main( int argc, char **argv ) { int i, c; master_record_t record; nffile_t *nffile; when = ISO2UNIX(strdup("200407111030")); while ((c = getopt(argc, argv, "h")) != EOF) { switch(c) { case 'h': break; default: fprintf(stderr, "ERROR: Unsupported option: '%c'\n", c); exit(255); } } extension_info.map = (extension_map_t *)malloc(sizeof(extension_map_t) + 32 * sizeof(uint16_t)); if ( !extension_info.map ) { fprintf(stderr, "malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror (errno)); exit(255); } extension_info.map->type = ExtensionMapType; extension_info.map->map_id = 0; i = 0; extension_info.map->ex_id[i++] = EX_IO_SNMP_2; extension_info.map->ex_id[i++] = EX_AS_2; extension_info.map->ex_id[i++] = EX_MULIPLE; extension_info.map->ex_id[i++] = EX_NEXT_HOP_v4; extension_info.map->ex_id[i++] = EX_NEXT_HOP_BGP_v4; extension_info.map->ex_id[i++] = EX_VLAN; extension_info.map->ex_id[i++] = EX_OUT_PKG_4; extension_info.map->ex_id[i++] = EX_OUT_BYTES_4; extension_info.map->ex_id[i++] = EX_AGGR_FLOWS_4; extension_info.map->ex_id[i++] = EX_MAC_1; extension_info.map->ex_id[i++] = EX_MAC_2; extension_info.map->ex_id[i++] = EX_MPLS; extension_info.map->ex_id[i++] = EX_ROUTER_IP_v4; extension_info.map->ex_id[i++] = EX_ROUTER_ID; extension_info.map->ex_id[i++] = EX_BGPADJ; extension_info.map->ex_id[i] = 0; extension_info.map->size = sizeof(extension_map_t) + i * sizeof(uint16_t); // align 32bits if (( extension_info.map->size & 0x3 ) != 0 ) { extension_info.map->size += 4 - ( extension_info.map->size & 0x3 ); } extension_info.map->extension_size = 0; i=0; while (extension_info.map->ex_id[i]) { int id = extension_info.map->ex_id[i]; extension_info.map->extension_size += extension_descriptor[id].size; i++; } memset((void *)&record, 0, sizeof(record)); nffile = OpenNewFile("-", NULL, 0, 0, NULL); if ( !nffile ) { exit(255); } AppendToBuffer(nffile, (void *)extension_info.map, extension_info.map->size); record.map_ref = extension_info.map; record.type = CommonRecordType; record.flags = 0; record.exporter_sysid = 1; record.tcp_flags = 1; record.tos = 2; record.fwd_status = 0; record.srcport = 1024; record.dstport = 25; record.prot = IPPROTO_TCP; record.input = 12; record.output = 14; record.srcas = 775; record.dstas = 8404; SetIPaddress(&record, PF_INET, "172.16.1.66", "192.168.170.100"); SetNextIPaddress(&record, PF_INET, "172.72.1.2"); SetBGPNextIPaddress(&record, PF_INET, "172.73.2.3"); SetRouterIPaddress(&record, PF_INET, "127.0.0.1"); record.engine_type = 5; record.engine_id = 6; record.dPkts = 202; record.dOctets = 303; record.dst_tos = 128; record.dir = 1; record.src_mask = 16; record.dst_mask = 24; record.src_vlan = 82; record.dst_vlan = 93; record.out_pkts = 212; record.out_bytes = 3234; record.aggr_flows = 3; record.in_src_mac = 0x0234567890aaLL; record.out_dst_mac = 0xffeeddccbbaaLL; record.out_src_mac = 0xaa3456789002LL; record.in_dst_mac = 0xaaeeddccbbffLL; record.mpls_label[0] = 1010 << 4; record.mpls_label[1] = 2020 << 4; record.mpls_label[2] = 3030 << 4; record.mpls_label[3] = 4040 << 4; record.mpls_label[4] = 5050 << 4; record.mpls_label[5] = 6060 << 4; record.mpls_label[6] = 7070 << 4; record.mpls_label[7] = 8080 << 4; record.mpls_label[8] = 9090 << 4; record.mpls_label[9] = (100100 << 4) + 1; record.client_nw_delay_usec = 2; record.server_nw_delay_usec = 22; record.appl_latency_usec = 222; record.bgpNextAdjacentAS = 45804; record.bgpPrevAdjacentAS = 32775; fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.2.66", "192.168.170.101"); fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); record.dPkts = 101; record.dOctets = 102; fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.3.66", "192.168.170.102"); fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.4.66", "192.168.170.103"); record.srcport = 2024; record.prot = IPPROTO_UDP; record.tcp_flags = 1; record.tos = 1; record.dPkts = 1001; record.dOctets = 1002; fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.5.66", "192.168.170.104"); record.srcport = 3024; record.prot = 51; record.tcp_flags = 2; record.tos = 2; record.dPkts = 10001; record.dOctets = 10002; fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.6.66", "192.168.170.105"); record.srcport = 4024; record.prot = IPPROTO_TCP; record.tcp_flags = 4; record.tos = 3; record.dPkts = 100001; record.dOctets = 100002; fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.7.66", "192.168.170.106"); record.srcport = 5024; record.tcp_flags = 8; record.tos = 4; record.dPkts = 1000001; record.dOctets = 1000002; fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.8.66", "192.168.170.107"); record.tcp_flags = 1; record.tos = 4; record.dPkts = 10000001; record.dOctets = 1001; fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.9.66", "192.168.170.108"); record.srcport = 6024; record.tcp_flags = 16; record.tos = 5; record.dPkts = 500; record.dOctets = 10000001; fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.10.66", "192.168.170.109"); fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.11.66", "192.168.170.110"); record.srcport = 7024; record.tcp_flags = 32; record.tos = 255; record.dPkts = 5000; record.dOctets = 100000001; fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.12.66", "192.168.170.111"); record.srcport = 8024; record.tcp_flags = 63; record.tos = 0; record.dOctets = 1000000001; fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.13.66", "192.168.170.112"); record.srcport = 0; record.dstport = 8; record.prot = 1; record.tcp_flags = 0; record.tos = 0; record.dPkts = 50002; record.dOctets = 50000; fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.160.160.166", "172.160.160.180"); record.srcport = 10024; record.dstport = 25000; record.prot = IPPROTO_TCP; record.dPkts = 500001; record.dOctets = 500000; fprintf(stderr, "IPv4 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET6, "fe80::2110:abcd:1234:0", "fe80::2110:abcd:1235:4321"); // SetNextIPaddress(&record, PF_INET6, "2003:234:aabb::211:24ff:fe80:d01e"); // SetBGPNextIPaddress(&record, PF_INET6, "2004:234:aabb::211:24ff:fe80:d01e"); record.srcport = 1024; record.dstport = 25; record.tcp_flags = 27; record.dPkts = 10; record.dOctets = 15100; fprintf(stderr, "IPv6 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET6, "2001:234:aabb::211:24ff:fe80:d01e", "2001:620::8:203:baff:fe52:38e5"); record.srcport = 10240; record.dstport = 52345; record.dPkts = 10100; record.dOctets = 15000000; fprintf(stderr, "IPv6 32bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); record.dPkts = 10100000; record.dOctets = 0x100000000LL; fprintf(stderr, "IPv6 32bit packets 64bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); record.dPkts = 0x100000000LL; record.dOctets = 15000000; fprintf(stderr, "IPv6 64bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); record.dOctets = 0x200000000LL; fprintf(stderr, "IPv6 64bit packets 64bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.14.18", "192.168.170.113"); // SetNextIPaddress(&record, PF_INET, "172.72.1.2"); // SetBGPNextIPaddress(&record, PF_INET, "172.73.2.3"); record.srcport = 10240; record.dstport = 52345; record.dPkts = 10100000; record.dOctets = 0x100000000LL; fprintf(stderr, "IPv4 32bit packets 64bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.15.18", "192.168.170.114"); record.dPkts = 0x100000000LL; record.dOctets = 15000000; fprintf(stderr, "IPv4 64bit packets 32bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); SetIPaddress(&record, PF_INET, "172.16.16.18", "192.168.170.115"); record.dOctets = 0x200000000LL; fprintf(stderr, "IPv4 64bit packets 64bit bytes\n"); UpdateRecord(&record); PackRecord(&record, nffile); extension_info.map->ex_id[0] = EX_IO_SNMP_4; extension_info.map->extension_size = 0; i=0; while (extension_info.map->ex_id[i]) { int id = extension_info.map->ex_id[i]; extension_info.map->extension_size += extension_descriptor[id].size; i++; } memcpy(nffile->buff_ptr, (void *)extension_info.map, extension_info.map->size); nffile->buff_ptr += extension_info.map->size; nffile->block_header->NumRecords++; nffile->block_header->size += extension_info.map->size; UpdateRecord(&record); fprintf(stderr, "4 bytes interfaces, 2 bytes AS numbers %d %d\n", record.fwd_status, nffile->block_header->NumRecords); PackRecord(&record, nffile); extension_info.map->ex_id[0] = EX_IO_SNMP_2; extension_info.map->ex_id[1] = EX_AS_4; extension_info.map->extension_size = 0; i=0; while (extension_info.map->ex_id[i]) { int id = extension_info.map->ex_id[i]; extension_info.map->extension_size += extension_descriptor[id].size; i++; } memcpy(nffile->buff_ptr, (void *)extension_info.map, extension_info.map->size); nffile->buff_ptr += extension_info.map->size; nffile->block_header->NumRecords++; nffile->block_header->size += extension_info.map->size; UpdateRecord(&record); fprintf(stderr, "2 bytes interfaces, 4 bytes AS numbers %d %d\n", record.fwd_status, nffile->block_header->NumRecords); PackRecord(&record, nffile); extension_info.map->ex_id[0] = EX_IO_SNMP_4; extension_info.map->extension_size = 0; i=0; while (extension_info.map->ex_id[i]) { int id = extension_info.map->ex_id[i]; extension_info.map->extension_size += extension_descriptor[id].size; i++; } memcpy(nffile->buff_ptr, (void *)extension_info.map, extension_info.map->size); nffile->buff_ptr += extension_info.map->size; nffile->block_header->NumRecords++; nffile->block_header->size += extension_info.map->size; UpdateRecord(&record); fprintf(stderr, "4 bytes interfaces, 4 bytes AS numbers %d %d\n", record.fwd_status, nffile->block_header->NumRecords); PackRecord(&record, nffile); if ( nffile->block_header->NumRecords ) { if ( WriteBlock(nffile) <= 0 ) { fprintf(stderr, "Failed to write output buffer to disk: '%s'" , strerror(errno)); } } return 0; }
int ExportFlowTable(nffile_t *nffile, int aggregate, int bidir, int date_sorted, extension_map_list_t *extension_map_list) { hash_FlowTable *FlowTable; FlowTableRecord_t *r; SortElement_t *SortList; master_record_t *aggr_record_mask; uint32_t i; uint32_t maxindex, c; #ifdef DEVEL char *string; #endif ExportExtensionMaps(aggregate, bidir, nffile, extension_map_list); ExportExporterList(nffile); aggr_record_mask = GetMasterAggregateMask(); FlowTable = GetFlowTable(); c = 0; maxindex = FlowTable->NumRecords; if ( date_sorted ) { // Sort records according the date SortList = (SortElement_t *)calloc(maxindex, sizeof(SortElement_t)); if ( !SortList ) { LogError("malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror (errno)); return 0; } // preset SortList table - still unsorted for ( i=0; i<=FlowTable->IndexMask; i++ ) { r = FlowTable->bucket[i]; if ( !r ) continue; // foreach elem in this bucket while ( r ) { SortList[c].count = 1000LL * r->flowrecord.first + r->flowrecord.msec_first; // sort according the date SortList[c].record = (void *)r; c++; r = r->next; } } if ( c != maxindex ) { LogError("Abort: Mismatch %s line %d: %s\n", __FILE__, __LINE__, strerror (errno)); return 0; } if ( c >= 2 ) heapSort(SortList, c, 0); for ( i = 0; i < c; i++ ) { master_record_t *flow_record; common_record_t *raw_record; extension_info_t *extension_info; r = (FlowTableRecord_t *)(SortList[i].record); raw_record = &(r->flowrecord); extension_info = r->map_info_ref; flow_record = &(extension_info->master_record); ExpandRecord_v2( raw_record, extension_info, r->exp_ref, flow_record); flow_record->dPkts = r->counter[INPACKETS]; flow_record->dOctets = r->counter[INBYTES]; flow_record->out_pkts = r->counter[OUTPACKETS]; flow_record->out_bytes = r->counter[OUTBYTES]; flow_record->aggr_flows = r->counter[FLOWS]; // apply IP mask from aggregation, to provide a pretty output if ( FlowTable->has_masks ) { flow_record->V6.srcaddr[0] &= FlowTable->IPmask[0]; flow_record->V6.srcaddr[1] &= FlowTable->IPmask[1]; flow_record->V6.dstaddr[0] &= FlowTable->IPmask[2]; flow_record->V6.dstaddr[1] &= FlowTable->IPmask[3]; } if ( FlowTable->apply_netbits ) ApplyNetMaskBits(flow_record, FlowTable->apply_netbits); if ( aggr_record_mask ) { ApplyAggrMask(flow_record, aggr_record_mask); } // switch to output extension map flow_record->map_ref = extension_info->map; flow_record->ext_map = extension_info->map->map_id; PackRecord(flow_record, nffile); #ifdef DEVEL format_file_block_record((void *)flow_record, &string, 0); printf("%s\n", string); #endif // Update statistics UpdateStat(nffile->stat_record, flow_record); } } else { // print them as they came for ( i=0; i<=FlowTable->IndexMask; i++ ) { r = FlowTable->bucket[i]; while ( r ) { master_record_t *flow_record; common_record_t *raw_record; extension_info_t *extension_info; raw_record = &(r->flowrecord); extension_info = r->map_info_ref; flow_record = &(extension_info->master_record); ExpandRecord_v2( raw_record, extension_info, r->exp_ref, flow_record); flow_record->dPkts = r->counter[INPACKETS]; flow_record->dOctets = r->counter[INBYTES]; flow_record->out_pkts = r->counter[OUTPACKETS]; flow_record->out_bytes = r->counter[OUTBYTES]; flow_record->aggr_flows = r->counter[FLOWS]; // apply IP mask from aggregation, to provide a pretty output if ( FlowTable->has_masks ) { flow_record->V6.srcaddr[0] &= FlowTable->IPmask[0]; flow_record->V6.srcaddr[1] &= FlowTable->IPmask[1]; flow_record->V6.dstaddr[0] &= FlowTable->IPmask[2]; flow_record->V6.dstaddr[1] &= FlowTable->IPmask[3]; } if ( FlowTable->apply_netbits ) ApplyNetMaskBits(flow_record, FlowTable->apply_netbits); if ( aggr_record_mask ) { ApplyAggrMask(flow_record, aggr_record_mask); } // switch to output extension map flow_record->map_ref = extension_info->map; flow_record->ext_map = extension_info->map->map_id; PackRecord(flow_record, nffile); #ifdef DEVEL format_file_block_record((void *)flow_record, &string, 0); printf("%s\n", string); #endif // Update statistics UpdateStat(nffile->stat_record, flow_record); r = r->next; } } } if ( nffile->block_header->NumRecords ) { if ( WriteBlock(nffile) <= 0 ) { LogError("Failed to write output buffer to disk: '%s'" , strerror(errno)); return 0; } } return 1; } // End of ExportFlowTable
int flows2nfdump(struct ftio *ftio, char *wfile, int compress, extension_info_t *extension_info, int extended, uint32_t limitflows) { // required flow tools variables struct fttime ftt; struct fts3rec_offsets fo; struct ftver ftv; char *rec; // nfdump variables nffile_t *nffile; master_record_t record; char *s; uint32_t cnt; s = "flow-tools"; nffile = OpenNewFile( wfile , NULL, compress, 0, s); if ( !nffile ) { fprintf(stderr, "%s\n", s); return 1; } AppendToBuffer(nffile, (void *)extension_info->map, extension_info->map->size); ftio_get_ver(ftio, &ftv); fts3rec_compute_offsets(&fo, &ftv); memset((void *)&record, 0, sizeof(record)); record.map_ref = extension_info->map; record.type = CommonRecordType; record.exporter_sysid = 0; // only v4 addresses ClearFlag(record.flags, FLAG_IPV6_ADDR); cnt = 0; while ((rec = ftio_read(ftio))) { uint32_t when, unix_secs, unix_nsecs, sysUpTime; int i, id; unix_secs = *((uint32_t*)(rec+fo.unix_secs)); unix_nsecs = *((uint32_t*)(rec+fo.unix_nsecs)); sysUpTime = *((uint32_t*)(rec+fo.sysUpTime)); when = *((uint32_t*)(rec+fo.First)); ftt = ftltime(sysUpTime, unix_secs, unix_nsecs, when); record.first = ftt.secs; record.msec_first = ftt.msecs; when = *((uint32_t*)(rec+fo.Last)); ftt = ftltime(sysUpTime, unix_secs, unix_nsecs, when); record.last = ftt.secs; record.msec_last = ftt.msecs; record.v4.srcaddr = *((uint32_t*)(rec+fo.srcaddr)); record.v4.dstaddr = *((uint32_t*)(rec+fo.dstaddr)); record.srcport = *((uint16_t*)(rec+fo.srcport)); record.dstport = *((uint16_t*)(rec+fo.dstport)); record.prot = *((uint8_t*)(rec+fo.prot)); record.tcp_flags = *((uint8_t*)(rec+fo.tcp_flags)); record.tos = *((uint8_t*)(rec+fo.tos)); record.dOctets = *((uint32_t*)(rec+fo.dOctets)); record.dPkts = *((uint32_t*)(rec+fo.dPkts)); i = 0; while ( (id = extension_info->map->ex_id[i]) != 0 ) { switch (id) { case EX_IO_SNMP_2: record.input = *((uint16_t*)(rec+fo.input)); record.output = *((uint16_t*)(rec+fo.output)); break; case EX_AS_2: record.srcas = *((uint16_t*)(rec+fo.src_as)); record.dstas = *((uint16_t*)(rec+fo.dst_as)); break; case EX_MULIPLE: record.src_mask = *((uint8_t*)(rec+fo.src_mask)); record.dst_mask = *((uint8_t*)(rec+fo.dst_mask)); record.dir = 0; record.dst_tos = 0; break; case EX_ROUTER_IP_v4: record.ip_nexthop.v4 = *((uint32_t*)(rec+fo.peer_nexthop)); break; case EX_NEXT_HOP_v4: record.ip_router.v4 = *((uint32_t*)(rec+fo.router_sc)); break; case EX_ROUTER_ID: record.engine_type = *((uint8_t*)(rec+fo.engine_type)); record.engine_id = *((uint8_t*)(rec+fo.engine_id)); break; // default: Other extensions can not be sent with v5 } i++; } PackRecord(&record, nffile); if ( extended ) { char *string; format_file_block_record(&record, &string, 0); fprintf(stderr, "%s\n", string); } cnt++; if ( cnt == limitflows ) break; } /* while */ // write the last records in buffer if ( nffile->block_header->NumRecords ) { if ( WriteBlock(nffile) <= 0 ) { fprintf(stderr, "Failed to write output buffer: '%s'" , strerror(errno)); } } free((void *)extension_info->map); free((void *)extension_info); DisposeFile(nffile); return 0; } // End of flows2nfdump