Exemplo n.º 1
0
int StorePcapFlow(FlowSource_t *fs, struct FlowNode *Node) {
common_record_t		*common_record;
uint32_t			packets, bytes, pcap_output_record_size;
uint64_t	start_time, end_time;
int			j, id;
char		*string;
void		*data_ptr;

	if ( !pcap_extension_map ) {
		pcap_extension_map	= (extension_map_t *)malloc(pcap_extension_info.map->size);
		if ( !pcap_extension_map ) {
			LogError("Process_pcap: malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror (errno));
			return 0;
		}
		memcpy((void *)pcap_extension_map, (void *)pcap_extension_info.map, pcap_extension_info.map->size);
		if ( !AddExtensionMap(fs, pcap_extension_map) ) {
			LogError("Process_pcap: Fatal: AddExtensionMap() failed in %s line %d\n", __FILE__, __LINE__);
			return 0;
		}

	}

	if ( Node->version == AF_INET6 ) {
		pcap_output_record_size = pcap_output_record_size_v6;
		dbg_printf("Store Flow v6 node: size: %u\n", pcap_output_record_size);
	} else if ( Node->version == AF_INET ) {
		pcap_output_record_size = pcap_output_record_size_v4;
		dbg_printf("Store Flow v4 node: size: %u\n", pcap_output_record_size);
	} else {
		LogError("Process_pcap: Unexpected version in %s line %d: %u\n", __FILE__, __LINE__, Node->version);
		return 0;
	}

	// output buffer size check for all expected records
	if ( !CheckBufferSpace(fs->nffile, pcap_output_record_size) ) {
		// fishy! - should never happen. maybe disk full?
		LogError("Process_pcap: output buffer size error. Abort pcap record processing");
		return 0;
	}

	// map output record to memory buffer
	common_record	= (common_record_t *)fs->nffile->buff_ptr;

	// header data
	common_record->flags		= 0;
  	common_record->type			= CommonRecordType;
	common_record->exporter_sysid = 0;
	common_record->ext_map		= pcap_extension_map->map_id;
	common_record->size			= pcap_output_record_size;

	// pcap common fields
	common_record->srcport		= Node->src_port;
	common_record->dstport		= Node->dst_port;
	common_record->tcp_flags	= Node->flags;
	common_record->prot			= Node->proto;
	common_record->tos			= 0;
	common_record->fwd_status 	= 0;

	if ( Node->version == AF_INET6 ) {
		SetFlag(common_record->flags, FLAG_IPV6_ADDR);
		pcap_v6_block_t *pcap_v6_block = (pcap_v6_block_t *)common_record->data;
		pcap_v6_block->srcaddr[0] = Node->src_addr.v6[0];
		pcap_v6_block->srcaddr[1] = Node->src_addr.v6[1];
		pcap_v6_block->dstaddr[0] = Node->dst_addr.v6[0];
		pcap_v6_block->dstaddr[1] = Node->dst_addr.v6[1];
		pcap_v6_block->dPkts	  = packets = Node->packets;
		pcap_v6_block->dOctets	  = bytes   = Node->bytes;

		data_ptr = (void *)pcap_v6_block->data;
	} else {
		pcap_v4_block_t *pcap_v4_block = (pcap_v4_block_t *)common_record->data;
		pcap_v4_block->srcaddr = Node->src_addr.v4;
		pcap_v4_block->dstaddr = Node->dst_addr.v4;
		pcap_v4_block->dPkts   = packets = Node->packets;
		pcap_v4_block->dOctets = bytes   = Node->bytes;

		data_ptr = (void *)pcap_v4_block->data;
	}

	// process optional extensions
	j = 0;
	while ( (id = pcap_extension_map->ex_id[j]) != 0 ) {
		switch (id) {
			case EX_IO_SNMP_2:	{	// 2 byte input/output interface index
				tpl_ext_4_t *tpl = (tpl_ext_4_t *)data_ptr;
 					tpl->input  = 0;
 					tpl->output = 0;
				data_ptr = (void *)tpl->data;
				} break;
			default:
				// this should never happen, as pcap has no other extensions
				LogError("Process_pcap: Unexpected extension %i for pcap record. Skip extension", id);
		}
		j++;
	}

	common_record->first 		= Node->t_first.tv_sec;
	common_record->msec_first	= Node->t_first.tv_usec / 1000;

	common_record->last 		= Node->t_last.tv_sec;
	common_record->msec_last	= Node->t_last.tv_usec / 1000;

	start_time = (1000LL * (uint64_t)common_record->first) + (uint64_t)common_record->msec_first;
	end_time   = (1000LL * (uint64_t)common_record->last) + (uint64_t)common_record->msec_last;

	// update first_seen, last_seen
	if ( start_time < fs->first_seen )
		fs->first_seen = start_time;
	if ( end_time > fs->last_seen )
		fs->last_seen = end_time;


	// Update stats
	switch (common_record->prot) {
		case IPPROTO_ICMP:
		case IPPROTO_ICMPV6:
			fs->nffile->stat_record->numflows_icmp++;
			fs->nffile->stat_record->numpackets_icmp += packets;
			fs->nffile->stat_record->numbytes_icmp   += bytes;
			// fix odd CISCO behaviour for ICMP port/type in src port
			if ( common_record->srcport != 0 ) {
				uint8_t *s1, *s2;
				s1 = (uint8_t *)&(common_record->srcport);
				s2 = (uint8_t *)&(common_record->dstport);
				s2[0] = s1[1];
				s2[1] = s1[0];
				common_record->srcport = 0;
			}
			break;
		case IPPROTO_TCP:
			fs->nffile->stat_record->numflows_tcp++;
			fs->nffile->stat_record->numpackets_tcp += packets;
			fs->nffile->stat_record->numbytes_tcp   += bytes;
			break;
		case IPPROTO_UDP:
			fs->nffile->stat_record->numflows_udp++;
			fs->nffile->stat_record->numpackets_udp += packets;
			fs->nffile->stat_record->numbytes_udp   += bytes;
			break;
		default:
			fs->nffile->stat_record->numflows_other++;
			fs->nffile->stat_record->numpackets_other += packets;
			fs->nffile->stat_record->numbytes_other   += bytes;
	}

	fs->nffile->stat_record->numflows++;
	fs->nffile->stat_record->numpackets	+= packets;
	fs->nffile->stat_record->numbytes	+= bytes;

	if ( fs->xstat ) {
		uint32_t bpp = packets ? bytes/packets : 0;
		if ( bpp > MAX_BPP ) 
			bpp = MAX_BPP;
		if ( common_record->prot == IPPROTO_TCP ) {
			fs->xstat->bpp_histogram->tcp.bpp[bpp]++;
			fs->xstat->bpp_histogram->tcp.count++;

			fs->xstat->port_histogram->src_tcp.port[common_record->srcport]++;
			fs->xstat->port_histogram->dst_tcp.port[common_record->dstport]++;
			fs->xstat->port_histogram->src_tcp.count++;
			fs->xstat->port_histogram->dst_tcp.count++;
		} else if ( common_record->prot == IPPROTO_UDP ) {
			fs->xstat->bpp_histogram->udp.bpp[bpp]++;
			fs->xstat->bpp_histogram->udp.count++;

			fs->xstat->port_histogram->src_udp.port[common_record->srcport]++;
			fs->xstat->port_histogram->dst_udp.port[common_record->dstport]++;
			fs->xstat->port_histogram->src_udp.count++;
			fs->xstat->port_histogram->dst_udp.count++;
		}
	}

	if ( verbose ) {
		master_record_t master_record;
		ExpandRecord_v2((common_record_t *)common_record, &pcap_extension_info, NULL, &master_record);
	 	format_file_block_record(&master_record, &string, 0);
		printf("%s\n", string);
	}

	// update file record size ( -> output buffer size )
	fs->nffile->block_header->NumRecords += 1;
	fs->nffile->block_header->size 		 += pcap_output_record_size;
	fs->nffile->buff_ptr 				 = data_ptr;

	return 1;

} /* End of StorePcapFlow */
Exemplo n.º 2
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
Exemplo n.º 3
0
void Process_v1(void *in_buff, ssize_t in_buff_cnt, FlowSource_t *fs) {
netflow_v1_header_t	*v1_header;
netflow_v1_record_t *v1_record;
exporter_v1_t 		*exporter;
extension_map_t		*extension_map;
common_record_t		*common_record;
uint64_t	start_time, end_time, boot_time;
uint32_t   	First, Last;
uint16_t	count;
uint8_t		flags;
int			i, done, flow_record_length;
ssize_t		size_left;
char		*string;

		// map v1 data structure to input buffer
		v1_header 	= (netflow_v1_header_t *)in_buff;

		exporter = GetExporter(fs, v1_header);
		if ( !exporter ) {
			syslog(LOG_ERR,"Process_v1: Exporter NULL: Abort v1 record processing");
			return;
		}
		flags = 0;

		exporter->packets++;

		extension_map = exporter->extension_map;
		flow_record_length = NETFLOW_V1_RECORD_LENGTH;

		// this many data to process
		size_left	= in_buff_cnt;

		common_record = fs->nffile->buff_ptr;
		done = 0;
		while ( !done ) {
			v1_block_t			*v1_block;

			/* Process header */
	
			// count check
	  		count	= ntohs(v1_header->count);
			if ( count > NETFLOW_V1_MAX_RECORDS ) {
				syslog(LOG_ERR,"Process_v1: Unexpected record count in header: %i. Abort v1 record processing", count);
				fs->nffile->buff_ptr = (void *)common_record;
				return;
			}

			// input buffer size check for all expected records
			if ( size_left < ( NETFLOW_V1_HEADER_LENGTH + count * flow_record_length) ) {
				syslog(LOG_ERR,"Process_v1: Not enough data to process v1 record. Abort v1 record processing");
				fs->nffile->buff_ptr = (void *)common_record;
				return;
			}
	
			// output buffer size check for all expected records
			if ( !CheckBufferSpace(fs->nffile, count * v1_output_record_size) ) {
				// fishy! - should never happen. maybe disk full?
				syslog(LOG_ERR,"Process_v1: output buffer size error. Abort v1 record processing");
				return;
			}

			// map output record to memory buffer
			common_record	= (common_record_t *)fs->nffile->buff_ptr;
			v1_block		= (v1_block_t *)common_record->data;

	  		v1_header->SysUptime	 = ntohl(v1_header->SysUptime);
	  		v1_header->unix_secs	 = ntohl(v1_header->unix_secs);
	  		v1_header->unix_nsecs	 = ntohl(v1_header->unix_nsecs);
	
			/* calculate boot time in msec */
			boot_time  = ((uint64_t)(v1_header->unix_secs)*1000 + 
					((uint64_t)(v1_header->unix_nsecs) / 1000000) ) - (uint64_t)(v1_header->SysUptime);
	
			// process all records
			v1_record	= (netflow_v1_record_t *)((pointer_addr_t)v1_header + NETFLOW_V1_HEADER_LENGTH);

			/* loop over each records associated with this header */
			for (i = 0; i < count; i++) {
				pointer_addr_t	bsize;
				void	*data_ptr;
				uint8_t *s1, *s2;
				int j, id;
				// header data
	  			common_record->flags		= flags;
	  			common_record->type			= CommonRecordType;
	  			common_record->exporter_sysid = exporter->info.sysid;
	  			common_record->ext_map		= extension_map->map_id;
	  			common_record->size			= v1_output_record_size;

				// v1 common fields
	  			common_record->srcport		= ntohs(v1_record->srcport);
	  			common_record->dstport		= ntohs(v1_record->dstport);
	  			common_record->tcp_flags	= v1_record->tcp_flags;
	  			common_record->prot			= v1_record->prot;
	  			common_record->tos			= v1_record->tos;
	  			common_record->fwd_status 	= 0;
	  			common_record->reserved 	= 0;

				// v1 typed data as fixed struct v1_block
	  			v1_block->srcaddr	= ntohl(v1_record->srcaddr);
	  			v1_block->dstaddr	= ntohl(v1_record->dstaddr);
	  			v1_block->dPkts  	= ntohl(v1_record->dPkts);
	  			v1_block->dOctets	= ntohl(v1_record->dOctets);

				// process optional extensions
				data_ptr = (void *)v1_block->data;
				j = 0;
				while ( (id = extension_map->ex_id[j]) != 0 ) {
					switch (id) {
						case EX_IO_SNMP_2:	{	// 2 byte input/output interface index
							tpl_ext_4_t *tpl = (tpl_ext_4_t *)data_ptr;
	  						tpl->input  = ntohs(v1_record->input);
	  						tpl->output = ntohs(v1_record->output);
							data_ptr = (void *)tpl->data;
							} break;
						case EX_NEXT_HOP_v4:	 {	// IPv4 next hop
							tpl_ext_9_t *tpl = (tpl_ext_9_t *)data_ptr;
							tpl->nexthop = ntohl(v1_record->nexthop);
							data_ptr = (void *)tpl->data;
							} break;
						case EX_ROUTER_IP_v4:	 {	// IPv4 router address
							tpl_ext_23_t *tpl = (tpl_ext_23_t *)data_ptr;
							tpl->router_ip = fs->ip.v4;
							data_ptr = (void *)tpl->data;
							ClearFlag(common_record->flags, FLAG_IPV6_EXP);
							} break;
						case EX_RECEIVED: {
							tpl_ext_27_t *tpl = (tpl_ext_27_t *)data_ptr;
							tpl->received  = (uint64_t)((uint64_t)fs->received.tv_sec * 1000LL) + (uint64_t)((uint64_t)fs->received.tv_usec / 1000LL);
							data_ptr = (void *)tpl->data;
							} break;

						default:
							// this should never happen, as v1 has no other extensions
							syslog(LOG_ERR,"Process_v1: Unexpected extension %i for v1 record. Skip extension", id);
					}
					j++;
				}
	
				// Time issues
	  			First	 				= ntohl(v1_record->First);
	  			Last		 			= ntohl(v1_record->Last);

				if ( First > Last ) {
					/* First in msec, in case of msec overflow, between start and end */
					start_time = boot_time - 0x100000000LL + (uint64_t)First;
				} else {
					start_time = boot_time + (uint64_t)First;
				}

				/* end time in msecs */
				end_time = (uint64_t)Last + boot_time;

				// if overflow happened after flow ended but before got exported
				if ( Last > v1_header->SysUptime ) {
					start_time  -= 0x100000000LL;
					end_time    -= 0x100000000LL;
				}

				common_record->first 		= start_time/1000;
				common_record->msec_first	= start_time - common_record->first*1000;
	
				common_record->last 		= end_time/1000;
				common_record->msec_last	= end_time - common_record->last*1000;
	
				// update first_seen, last_seen
				if ( start_time < fs->first_seen )
					fs->first_seen = start_time;
				if ( end_time > fs->last_seen )
					fs->last_seen = end_time;
	
	
				// Update stats
				switch (common_record->prot) {
					case IPPROTO_ICMP:
						fs->nffile->stat_record->numflows_icmp++;
						fs->nffile->stat_record->numpackets_icmp += v1_block->dPkts;
						fs->nffile->stat_record->numbytes_icmp   += v1_block->dOctets;
						// fix odd CISCO behaviour for ICMP port/type in src port
						if ( common_record->srcport != 0 ) {
							s1 = (uint8_t *)&(common_record->srcport);
							s2 = (uint8_t *)&(common_record->dstport);
							s2[0] = s1[1];
							s2[1] = s1[0];
							common_record->srcport = 0;
						}
						break;
					case IPPROTO_TCP:
						fs->nffile->stat_record->numflows_tcp++;
						fs->nffile->stat_record->numpackets_tcp += v1_block->dPkts;
						fs->nffile->stat_record->numbytes_tcp   += v1_block->dOctets;
						break;
					case IPPROTO_UDP:
						fs->nffile->stat_record->numflows_udp++;
						fs->nffile->stat_record->numpackets_udp += v1_block->dPkts;
						fs->nffile->stat_record->numbytes_udp   += v1_block->dOctets;
						break;
					default:
						fs->nffile->stat_record->numflows_other++;
						fs->nffile->stat_record->numpackets_other += v1_block->dPkts;
						fs->nffile->stat_record->numbytes_other   += v1_block->dOctets;
				}
				exporter->flows++;
				fs->nffile->stat_record->numflows++;
				fs->nffile->stat_record->numpackets	+= v1_block->dPkts;
				fs->nffile->stat_record->numbytes	+= v1_block->dOctets;

				if ( fs->xstat ) {
					uint32_t bpp = v1_block->dPkts ? v1_block->dOctets/v1_block->dPkts : 0;
					if ( bpp > MAX_BPP ) 
						bpp = MAX_BPP;
					if ( common_record->prot == IPPROTO_TCP ) {
						fs->xstat->bpp_histogram->tcp.bpp[bpp]++;
						fs->xstat->bpp_histogram->tcp.count++;

						fs->xstat->port_histogram->src_tcp.port[common_record->srcport]++;
						fs->xstat->port_histogram->dst_tcp.port[common_record->dstport]++;
						fs->xstat->port_histogram->src_tcp.count++;
						fs->xstat->port_histogram->dst_tcp.count++;
					} else if ( common_record->prot == IPPROTO_UDP ) {
						fs->xstat->bpp_histogram->udp.bpp[bpp]++;
						fs->xstat->bpp_histogram->udp.count++;

						fs->xstat->port_histogram->src_udp.port[common_record->srcport]++;
						fs->xstat->port_histogram->dst_udp.port[common_record->dstport]++;
						fs->xstat->port_histogram->src_udp.count++;
						fs->xstat->port_histogram->dst_udp.count++;
					}
				}


				if ( verbose ) {
					master_record_t master_record;
					ExpandRecord_v2((common_record_t *)common_record, &v1_extension_info, &(exporter->info), &master_record);
				 	format_file_block_record(&master_record, &string, 0);
					printf("%s\n", string);
				}

				// advance to next input flow record
				v1_record		= (netflow_v1_record_t *)((pointer_addr_t)v1_record + flow_record_length);

				if ( ((pointer_addr_t)data_ptr - (pointer_addr_t)common_record) != v1_output_record_size ) {
					printf("Panic size check: ptr diff: %llu, record size: %u\n", (unsigned long long)((pointer_addr_t)data_ptr - (pointer_addr_t)common_record), v1_output_record_size ); 
					abort();
				}
				// advance to next output record
				common_record	= (common_record_t *)data_ptr;
				v1_block		= (v1_block_t *)common_record->data;
				
				// buffer size sanity check - should never happen, but check it anyway
				bsize = (pointer_addr_t)common_record - (pointer_addr_t)fs->nffile->block_header - sizeof(data_block_header_t);
				if ( bsize > BUFFSIZE ) {
					syslog(LOG_ERR,"### Software error ###: %s line %d", __FILE__, __LINE__);
					syslog(LOG_ERR,"Process_v1: Output buffer overflow! Flush buffer and skip records.");
					syslog(LOG_ERR,"Buffer size: size: %u, bsize: %llu > %u", fs->nffile->block_header->size, (unsigned long long)bsize, BUFFSIZE);
					// reset buffer
					fs->nffile->block_header->size 		= 0;
					fs->nffile->block_header->NumRecords = 0;
					fs->nffile->buff_ptr = (void *)((pointer_addr_t)fs->nffile->block_header + sizeof(data_block_header_t) );
					return;
				}

			} // End of foreach v1 record

		// update file record size ( -> output buffer size )
		fs->nffile->block_header->NumRecords += count;
		fs->nffile->block_header->size 		 += count * v1_output_record_size;
		fs->nffile->buff_ptr 				  = (void *)common_record;

		// still to go for this many input bytes
		size_left 	-= NETFLOW_V1_HEADER_LENGTH + count * flow_record_length;

		// next header
		v1_header	= (netflow_v1_header_t *)v1_record;

		// should never be < 0
		done = size_left <= 0;

	} // End of while !done

	return;

} /* End of Process_v1 */
Exemplo n.º 4
0
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