コード例 #1
0
ファイル: netflow1.c プロジェクト: hbhzwj/imalse
/*
 * Given an array of expired flows, send netflow v1 report packets
 * Returns number of packets sent or -1 on error
 */
int
send_netflow_v1(struct FLOW **flows, int num_flows, int nfsock,
    u_int64_t *flows_exported, struct timeval *system_boot_time, 
    int verbose_flag)
{
	struct timeval now;
	u_int32_t uptime_ms;
	u_int8_t packet[NF1_MAXPACKET_SIZE];	/* Maximum allowed packet size (24 flows) */
	struct NF1_HEADER *hdr = NULL;
	struct NF1_FLOW *flw = NULL;
	int i, j, offset, num_packets, err;
	socklen_t errsz;
	
	gettimeofday(&now, NULL);
	uptime_ms = timeval_sub_ms(&now, system_boot_time);

	hdr = (struct NF1_HEADER *)packet;
	for(num_packets = offset = j = i = 0; i < num_flows; i++) {
		if (j >= NF1_MAXFLOWS - 1) {
			if (verbose_flag)
				logit(LOG_DEBUG, "Sending flow packet len = %d", offset);
			hdr->flows = htons(hdr->flows);
			errsz = sizeof(err);
			getsockopt(nfsock, SOL_SOCKET, SO_ERROR,
			    &err, &errsz); /* Clear ICMP errors */
			if (send(nfsock, packet, (size_t)offset, 0) == -1)
				return (-1);
			*flows_exported += j;
			j = 0;
			num_packets++;
		}
		if (j == 0) {
			memset(&packet, '\0', sizeof(packet));
			hdr->version = htons(1);
			hdr->flows = 0; /* Filled in as we go */
			hdr->uptime_ms = htonl(uptime_ms);
			hdr->time_sec = htonl(now.tv_sec);
			hdr->time_nanosec = htonl(now.tv_usec * 1000);
			offset = sizeof(*hdr);
		}		
		flw = (struct NF1_FLOW *)(packet + offset);
		
		/* NetFlow v.1 doesn't do IPv6 */
		if (flows[i]->af != AF_INET)
			continue;
		if (flows[i]->octets[0] > 0) {
			flw->src_ip = flows[i]->addr[0].v4.s_addr;
			flw->dest_ip = flows[i]->addr[1].v4.s_addr;
			flw->src_port = flows[i]->port[0];
			flw->dest_port = flows[i]->port[1];
			flw->flow_packets = htonl(flows[i]->packets[0]);
			flw->flow_octets = htonl(flows[i]->octets[0]);
			flw->flow_start =
			    htonl(timeval_sub_ms(&flows[i]->flow_start,
			    system_boot_time));
			flw->flow_finish = 
			    htonl(timeval_sub_ms(&flows[i]->flow_last,
			    system_boot_time));
			flw->protocol = flows[i]->protocol;
			flw->tcp_flags = flows[i]->tcp_flags[0];
			offset += sizeof(*flw);
			j++;
			hdr->flows++;
		}
		flw = (struct NF1_FLOW *)(packet + offset);

		if (flows[i]->octets[1] > 0) {
			flw->src_ip = flows[i]->addr[1].v4.s_addr;
			flw->dest_ip = flows[i]->addr[0].v4.s_addr;
			flw->src_port = flows[i]->port[1];
			flw->dest_port = flows[i]->port[0];
			flw->flow_packets = htonl(flows[i]->packets[1]);
			flw->flow_octets = htonl(flows[i]->octets[1]);
			flw->flow_start =
			    htonl(timeval_sub_ms(&flows[i]->flow_start,
			    system_boot_time));
			flw->flow_finish =
			    htonl(timeval_sub_ms(&flows[i]->flow_last,
			    system_boot_time));
			flw->protocol = flows[i]->protocol;
			flw->tcp_flags = flows[i]->tcp_flags[1];
			offset += sizeof(*flw);
			j++;
			hdr->flows++;
		}
	}

	/* Send any leftovers */
	if (j != 0) {
		if (verbose_flag)
			logit(LOG_DEBUG, "Sending flow packet len = %d", offset);
		hdr->flows = htons(hdr->flows);
		errsz = sizeof(err);
		getsockopt(nfsock, SOL_SOCKET, SO_ERROR,
		    &err, &errsz); /* Clear ICMP errors */
		if (send(nfsock, packet, (size_t)offset, 0) == -1)
			return (-1);
		num_packets++;
	}

	*flows_exported += j;
	return (num_packets);
}
コード例 #2
0
ファイル: pfflowd.c プロジェクト: Klaws--/pfsense-tools
static int
  send_netflow_v5(const struct pfsync_state *st, u_int n, u_int *flows_exp)
{

   char now_s[64];
   int i, j, offset, num_packets, err;
   socklen_t errsz;
   struct NF5_FLOW *flw = NULL;
   struct NF5_HEADER *hdr = NULL;
   struct timeval now_tv;
   struct tm now_tm;
   time_t now;
   u_int32_t uptime_ms;
   u_int8_t packet[NF5_MAXPACKET_SIZE];
#ifdef NF9
   int src_idx, dst_idx;
#endif
#if __FreeBSD_version > 900000
   const struct pfsync_state_key *nk;
#endif

   if (verbose_flag)
     {
	now = time(NULL);
	localtime_r(&now, &now_tm);
	strftime(now_s, sizeof(now_s), "%Y-%m-%dT%H:%M:%S", &now_tm);
     }

   gettimeofday(&now_tv, NULL);
   uptime_ms = timeval_sub_ms(&now_tv, &start_time);

   hdr = (struct NF5_HEADER *)packet;
   for(num_packets = offset = j = i = 0; i < n; i++)
     {
	struct pf_state_host src, dst;
	u_int32_t bytes_in, bytes_out, packets_in, packets_out;
	u_int32_t creation;
	char src_s[64], dst_s[64], rt_s[64], pbuf[16], creation_s[64];
	time_t creation_tt;
	struct tm creation_tm;

	if (netflow_socket != -1 && j >= NF5_MAXFLOWS - 1)
	  {
	     if (verbose_flag)
	       {
		  syslog(LOG_DEBUG,
			 "Sending flow packet len = %d", offset);
	       }
	     hdr->flows = htons(hdr->flows);
	     errsz = sizeof(err);
	     getsockopt(netflow_socket, SOL_SOCKET, SO_ERROR,
			&err, &errsz); /* Clear ICMP errors */
	     if (send(netflow_socket, packet,
		      (size_t)offset, 0) == -1)
	       {
		  syslog(LOG_DEBUG, "send: %s", strerror(errno));
		  return -1;
	       }
	     j = 0;
	     num_packets++;
	  }

	if (netflow_socket != -1 && j == 0)
	  {
	     memset(&packet, '\0', sizeof(packet));
	     hdr->version = htons(5);
	     hdr->flows = 0; /* Filled in as we go */
	     hdr->uptime_ms = htonl(uptime_ms);
	     hdr->time_sec = htonl(now_tv.tv_sec);
	     hdr->time_nanosec = htonl(now_tv.tv_usec * 1000);
	     hdr->flow_sequence = htonl(*flows_exp);
			/* Other fields are left zero */
	     offset = sizeof(*hdr);
	  }

	if (st[i].af != AF_INET)
	  continue;
        if (direction != 0 && st[i].direction != direction)
	  continue;

		/* Copy/convert only what we can eat */
	creation = ntohl(st[i].creation) * 1000;
	if (creation > uptime_ms)
	  creation = uptime_ms; /* Avoid u_int wrap */

#if __FreeBSD_version > 900000
	if (st[i].direction == PF_OUT)
	  {
	     nk = &st[i].key[PF_SK_WIRE];
	  }
	else
	  {
	     nk = &st[i].key[PF_SK_STACK];
	  }
	src.addr = nk->addr[1];
	src.port = nk->port[1];
	dst.addr = nk->addr[0];
	dst.port = nk->port[0];
#else
	if (st[i].direction == PF_OUT)
	  {
	     memcpy(&src, &st[i].lan, sizeof(src));
	     memcpy(&dst, &st[i].ext, sizeof(dst));
	  }
	else
	  {
	     memcpy(&src, &st[i].ext, sizeof(src));
	     memcpy(&dst, &st[i].lan, sizeof(dst));
	  }
#endif
#ifdef NF9
	src_idx = resolve_interface(&src.addr, st[i].af);
	dst_idx = resolve_interface(&dst.addr, st[i].af);
#endif

	flw = (struct NF5_FLOW *)(packet + offset);
#ifdef NF9
	if (netflow_socket != -1 && st[i].packets[0][1] != 0)
#else
	  if (netflow_socket != -1 && st[i].packets[0][0] != 0)
#endif
	    {
	       flw->src_ip = src.addr.v4.s_addr;
	       flw->dest_ip = dst.addr.v4.s_addr;
	       flw->src_port = src.port;
	       flw->dest_port = dst.port;
#ifdef NF9
	       flw->flow_packets = st[i].packets[0][1];
	       flw->flow_octets = st[i].bytes[0][1];
	       flw->if_index_in = htons(src_idx);
	       flw->if_index_out= htons(dst_idx);

#else
	       flw->flow_packets = st[i].packets[0][0];
	       flw->flow_octets = st[i].bytes[0][0];
#endif
	       flw->flow_start = htonl(uptime_ms - creation);
	       flw->flow_finish = htonl(uptime_ms);
	       flw->tcp_flags = 0;
	       flw->protocol = st[i].proto;
	       offset += sizeof(*flw);
	       j++;
	       hdr->flows++;
	    }
	flw = (struct NF5_FLOW *)(packet + offset);
#ifdef NF9
	if (netflow_socket != -1 && st[i].packets[1][1] != 0)
#else
	  if (netflow_socket != -1 && st[i].packets[1][0] != 0)
#endif
	    {
	       flw->src_ip = dst.addr.v4.s_addr;
	       flw->dest_ip = src.addr.v4.s_addr;
	       flw->src_port = dst.port;
	       flw->dest_port = src.port;
#ifdef NF9
	       flw->flow_packets = st[i].packets[1][1];
	       flw->flow_octets = st[i].bytes[1][1];

	       flw->if_index_in = htons(dst_idx);
	       flw->if_index_out= htons(src_idx);

#else
	       flw->flow_packets = st[i].packets[1][0];
	       flw->flow_octets = st[i].bytes[1][0];
#endif

	       flw->flow_start = htonl(uptime_ms - creation);
	       flw->flow_finish = htonl(uptime_ms);
	       flw->tcp_flags = 0;
	       flw->protocol = st[i].proto;
	       offset += sizeof(*flw);
	       j++;
	       hdr->flows++;
	    }
	flw = (struct NF5_FLOW *)(packet + offset);

	if (verbose_flag)
	  {

#ifdef NF9
	     packets_out = ntohl(st[i].packets[0][1]);
	     packets_in = ntohl(st[i].packets[1][1]);
	     bytes_out = ntohl(st[i].bytes[0][1]);
	     bytes_in = ntohl(st[i].bytes[1][1]);
#else
	     packets_out = ntohl(st[i].packets[0][0]);
	     packets_in = ntohl(st[i].packets[1][0]);
	     bytes_out = ntohl(st[i].bytes[0][0]);
	     bytes_in = ntohl(st[i].bytes[1][0]);
#endif
	     creation_tt = now - (creation / 1000);
	     localtime_r(&creation_tt, &creation_tm);
	     strftime(creation_s, sizeof(creation_s),
		      "%Y-%m-%dT%H:%M:%S", &creation_tm);

	     format_pf_host(src_s, sizeof(src_s), &src, st[i].af);
	     format_pf_host(dst_s, sizeof(dst_s), &dst, st[i].af);
	     inet_ntop(st[i].af, &st[i].rt_addr, rt_s, sizeof(rt_s));

	     if (st[i].proto == IPPROTO_TCP ||
		 st[i].proto == IPPROTO_UDP)
	       {
		  snprintf(pbuf, sizeof(pbuf), ":%d",
			   ntohs(src.port));
		  strlcat(src_s, pbuf, sizeof(src_s));
		  snprintf(pbuf, sizeof(pbuf), ":%d",
			   ntohs(dst.port));
		  strlcat(dst_s, pbuf, sizeof(dst_s));
	       }

	     syslog(LOG_DEBUG, "IFACE %s", st[i].ifname);
	     syslog(LOG_DEBUG, "GWY %s", rt_s);
	     syslog(LOG_DEBUG, "FLOW proto %d direction %d",
		    st[i].proto, st[i].direction);
	     syslog(LOG_DEBUG, "\tstart %s(%u) finish %s(%u)",
		    creation_s, uptime_ms - creation,
		    now_s, uptime_ms);
	     syslog(LOG_DEBUG, "\t%s -> %s %d bytes %d packets",
		    src_s, dst_s, bytes_out, packets_out);
	     syslog(LOG_DEBUG, "\t%s -> %s %d bytes %d packets",
		    dst_s, src_s, bytes_in, packets_in);
	  }
     }
	/* Send any leftovers */
   if (netflow_socket != -1 && j != 0)
     {
	if (verbose_flag)
	  {
	     syslog(LOG_DEBUG, "Sending flow packet len = %d",
		    offset);
	  }
	hdr->flows = htons(hdr->flows);
	errsz = sizeof(err);
	getsockopt(netflow_socket, SOL_SOCKET, SO_ERROR,
		   &err, &errsz); /* Clear ICMP errors */
	if (send(netflow_socket, packet, (size_t)offset, 0) == -1)
	  {
	     syslog(LOG_DEBUG, "send: %s", strerror(errno));
	     return -1;
	  }

	num_packets++;
     }

   return (ntohs(hdr->flows));
}
コード例 #3
0
ファイル: netflow9.c プロジェクト: Evan0524/softflowd
static int
nf_flow_to_flowset(const struct FLOW *flow, u_char *packet, u_int len,
    u_int16_t ifidx, const struct timeval *system_boot_time, u_int *len_used)
{
	union {
		struct NF9_SOFTFLOWD_DATA_V4 d4;
		struct NF9_SOFTFLOWD_DATA_V6 d6;
	} d[2];
	struct NF9_SOFTFLOWD_DATA_COMMON *dc[2];
	u_int freclen, ret_len, nflows;

	bzero(d, sizeof(d));
	*len_used = nflows = ret_len = 0;
	switch (flow->af) {
	case AF_INET:
		freclen = sizeof(struct NF9_SOFTFLOWD_DATA_V4);
		memcpy(&d[0].d4.src_addr, &flow->addr[0].v4, 4);
		memcpy(&d[0].d4.dst_addr, &flow->addr[1].v4, 4);
		memcpy(&d[1].d4.src_addr, &flow->addr[1].v4, 4);
		memcpy(&d[1].d4.dst_addr, &flow->addr[0].v4, 4);
		dc[0] = &d[0].d4.c;
		dc[1] = &d[1].d4.c;
		dc[0]->ipproto = dc[1]->ipproto = 4;
		break;
	case AF_INET6:
		freclen = sizeof(struct NF9_SOFTFLOWD_DATA_V6);
		memcpy(&d[0].d6.src_addr, &flow->addr[0].v6, 16);
		memcpy(&d[0].d6.dst_addr, &flow->addr[1].v6, 16);
		memcpy(&d[1].d6.src_addr, &flow->addr[1].v6, 16);
		memcpy(&d[1].d6.dst_addr, &flow->addr[0].v6, 16);
		dc[0] = &d[0].d6.c;
		dc[1] = &d[1].d6.c;
		dc[0]->ipproto = dc[1]->ipproto = 6;
		break;
	default:
		return (-1);
	}

	dc[0]->first_switched = dc[1]->first_switched = 
	    htonl(timeval_sub_ms(&flow->flow_start, system_boot_time));
	dc[0]->last_switched = dc[1]->last_switched = 
	    htonl(timeval_sub_ms(&flow->flow_last, system_boot_time));
	dc[0]->bytes = htonl(flow->octets[0]);
	dc[1]->bytes = htonl(flow->octets[1]);
	dc[0]->packets = htonl(flow->packets[0]);
	dc[1]->packets = htonl(flow->packets[1]);
	dc[0]->if_index_in = dc[0]->if_index_out = htonl(ifidx);
	dc[1]->if_index_in = dc[1]->if_index_out = htonl(ifidx);
	dc[0]->src_port = dc[1]->dst_port = flow->port[0];
	dc[1]->src_port = dc[0]->dst_port = flow->port[1];
	dc[0]->protocol = dc[1]->protocol = flow->protocol;
	dc[0]->tcp_flags = flow->tcp_flags[0];
	dc[1]->tcp_flags = flow->tcp_flags[1];
	dc[0]->tos = flow->tos[0];
	dc[1]->tos = flow->tos[1];
#ifdef ENABLE_NF9_VLAN
	if (flow->protocol == IPPROTO_ICMP || flow->protocol == IPPROTO_ICMPV6) {
	  dc[0]->icmp_type = dc[0]->dst_port;
	  dc[1]->icmp_type = dc[1]->dst_port;
	}
	dc[0]->vlanid = dc[1]->vlanid = htons(flow->vlanid);
#endif /* ENABLE_NF9_VLAN */
	if (flow->octets[0] > 0) {
		if (ret_len + freclen > len)
			return (-1);
		memcpy(packet + ret_len, &d[0], freclen);
		ret_len += freclen;
		nflows++;
	}
	if (flow->octets[1] > 0) {
		if (ret_len + freclen > len)
			return (-1);
		memcpy(packet + ret_len, &d[1], freclen);
		ret_len += freclen;
		nflows++;
	}

	*len_used = ret_len;
	return (nflows);
}
コード例 #4
0
ファイル: netflow9.c プロジェクト: Evan0524/softflowd
/*
 * Given an array of expired flows, send netflow v9 report packets
 * Returns number of packets sent or -1 on error
 */
int
send_netflow_v9(struct FLOW **flows, int num_flows, int nfsock,
		u_int16_t ifidx, struct FLOWTRACKPARAMETERS *param,
		int verbose_flag)
{
	struct NF9_HEADER *nf9;
	struct NF9_DATA_FLOWSET_HEADER *dh;
	struct timeval now;
	u_int offset, last_af, i, j, num_packets, inc, last_valid;
	socklen_t errsz;
	int err, r;
	u_char packet[NF9_SOFTFLOWD_MAX_PACKET_SIZE];
	struct timeval *system_boot_time = &param->system_boot_time;
	u_int64_t *flows_exported = &param->flows_exported;
	u_int64_t *packets_sent = &param->packets_sent;
	struct OPTION *option = &param->option;

	gettimeofday(&now, NULL);

	if (nf9_pkts_until_template == -1) {
		nf9_init_template();
		nf9_pkts_until_template = 0;
		if (option != NULL && option->sample > 1){
			nf9_init_option(ifidx, option);
		}
	}		

	last_valid = num_packets = 0;
	for (j = 0; j < num_flows;) {
		bzero(packet, sizeof(packet));
		nf9 = (struct NF9_HEADER *)packet;

		nf9->version = htons(9);
		nf9->flows = 0; /* Filled as we go, htons at end */
		nf9->uptime_ms = htonl(timeval_sub_ms(&now, system_boot_time));
		nf9->time_sec = htonl(time(NULL));
		nf9->source_id = 0;
		offset = sizeof(*nf9);

		/* Refresh template headers if we need to */
		if (nf9_pkts_until_template <= 0) {
			memcpy(packet + offset, &v4_template,
			    sizeof(v4_template));
			offset += sizeof(v4_template);
			nf9->flows++;
			memcpy(packet + offset, &v6_template,
			    sizeof(v6_template));
			offset += sizeof(v6_template);
			nf9->flows++;
			if (option != NULL && option->sample > 1){
				memcpy(packet + offset, &option_template,
				       sizeof(option_template));
				offset += sizeof(option_template);
				nf9->flows++;
				memcpy(packet + offset, &option_data,
				       sizeof(option_data));
				offset += sizeof(option_data);
				nf9->flows++;
			}

			nf9_pkts_until_template = NF9_DEFAULT_TEMPLATE_INTERVAL;
		}

		dh = NULL;
		last_af = 0;
		for (i = 0; i + j < num_flows; i++) {
			if (dh == NULL || flows[i + j]->af != last_af) {
				if (dh != NULL) {
					if (offset % 4 != 0) {
						/* Pad to multiple of 4 */
						dh->c.length += 4 - (offset % 4);
						offset += 4 - (offset % 4);
					}
					/* Finalise last header */
					dh->c.length = htons(dh->c.length);
				}
				if (offset + sizeof(*dh) > sizeof(packet)) {
					/* Mark header is finished */
					dh = NULL;
					break;
				}
				dh = (struct NF9_DATA_FLOWSET_HEADER *)
				    (packet + offset);
				dh->c.flowset_id =
				    (flows[i + j]->af == AF_INET) ?
				    v4_template.h.template_id : 
				    v6_template.h.template_id;
				last_af = flows[i + j]->af;
				last_valid = offset;
				dh->c.length = sizeof(*dh); /* Filled as we go */
				offset += sizeof(*dh);
			}

			r = nf_flow_to_flowset(flows[i + j], packet + offset,
			    sizeof(packet) - offset, ifidx, system_boot_time, &inc);
			if (r <= 0) {
				/* yank off data header, if we had to go back */
				if (last_valid)
					offset = last_valid;
				break;
			}
			offset += inc;
			dh->c.length += inc;
			nf9->flows += r;
			last_valid = 0; /* Don't clobber this header now */
			if (verbose_flag) {
				logit(LOG_DEBUG, "Flow %d/%d: "
				    "r %d offset %d type %04x len %d(0x%04x) "
				    "flows %d", r, i, j, offset, 
				    dh->c.flowset_id, dh->c.length, 
				    dh->c.length, nf9->flows);
			}
		}
		/* Don't finish header if it has already been done */
		if (dh != NULL) {
			if (offset % 4 != 0) {
				/* Pad to multiple of 4 */
				dh->c.length += 4 - (offset % 4);
				offset += 4 - (offset % 4);
			}
			/* Finalise last header */
			dh->c.length = htons(dh->c.length);
		}
		param->records_sent += nf9->flows;
		nf9->flows = htons(nf9->flows);
		nf9->package_sequence = htonl((u_int32_t)((*packets_sent + num_packets + 1) & 0x00000000ffffffff));

		if (verbose_flag)
			logit(LOG_DEBUG, "Sending flow packet len = %d", offset);
		errsz = sizeof(err);
		/* Clear ICMP errors */
		getsockopt(nfsock, SOL_SOCKET, SO_ERROR, &err, &errsz); 
		if (send(nfsock, packet, (size_t)offset, 0) == -1)
			return (-1);
		num_packets++;
		nf9_pkts_until_template--;

		j += i;
	}

	*flows_exported += j;
	return (num_packets);
}
コード例 #5
0
/*
 * Given an array of expired flows, send netflow v5 report packets
 * Returns number of packets sent or -1 on error
 */
int
send_netflow_v5(struct FLOW **flows, int num_flows, int nfsock,
                u_int64_t *flows_exported, struct timeval *system_boot_time,
                int verbose_flag, int inOut)
{
    struct timeval now;
    u_int32_t uptime_ms;
    u_int8_t packet[NF5_MAXPACKET_SIZE];	/* Maximum allowed packet size (24 flows) */
    struct NF5_HEADER *hdr = NULL;
    struct NF5_FLOW *flw = NULL;
    int i, j, offset, num_packets, err;
    socklen_t errsz;

    gettimeofday(&now, NULL);
    uptime_ms = timeval_sub_ms(&now, system_boot_time);
    hdr = (struct NF5_HEADER *)packet;
    for (num_packets = offset = j = i = 0; i < num_flows; i++) {
        if (j >= NF5_MAXFLOWS - 1) {
            if (verbose_flag)
                logit(LOG_DEBUG, "Sending flow packet len = %d", offset);
            hdr->flows = htons(hdr->flows);
            errsz = sizeof(err);
            getsockopt(nfsock, SOL_SOCKET, SO_ERROR,
                       &err, &errsz); /* Clear ICMP errors */
            if (send(nfsock, packet, (size_t)offset, 0) == -1)
                return (-1);
            *flows_exported += j;
            j = 0;
            num_packets++;
        }
        if (j == 0) {
            memset(&packet, '\0', sizeof(packet));
            hdr->version = htons(5);
            hdr->flows = 0; /* Filled in as we go */
            hdr->uptime_ms = htonl(uptime_ms);
            hdr->time_sec = htonl(now.tv_sec);
            hdr->time_nanosec = htonl(now.tv_usec * 1000);
            hdr->flow_sequence = htonl(*flows_exported);
            // Copy the emulator monitor source adr
            hdr->emulator_monitor_adr = 0;
            /* Other fields are left zero */
            offset = sizeof(*hdr);
        }
        flw = (struct NF5_FLOW *)(packet + offset);

        /* NetFlow v.5 doesn't do IPv6 */
        if (flows[i]->af != AF_INET)
            continue;
        // Copy the emulator monitor source adr
        if(j == 0 && using_emulator)
        {
            hdr->emulator_monitor_adr = flows[i]->selected_monitor.s_addr;
        }

        if(!using_emulator)
        {
            if (flows[i]->octets[0] > 0 ) {

                flw->src_as = flows[i]->as_src[0];
                flw->dest_as = flows[i]->as_dst[1];
                flw->src_ip = flows[i]->addr[0].v4.s_addr;
                flw->dest_ip = flows[i]->addr[1].v4.s_addr;
                flw->src_port = flows[i]->port[0];
                flw->dest_port = flows[i]->port[1];
                flw->flow_packets = htonl(flows[i]->packets[0]);
                flw->flow_octets = htonl(flows[i]->octets[0]);
                flw->flow_start =
                    htonl(timeval_sub_ms(&flows[i]->flow_start,
                                         system_boot_time));
                flw->flow_finish =
                    htonl(timeval_sub_ms(&flows[i]->flow_last,
                                         system_boot_time));
                flw->tcp_flags = flows[i]->tcp_flags[0];
                flw->protocol = flows[i]->protocol;
                offset += sizeof(*flw);
                j++;
                hdr->flows++;
            }
        } else
        {

            if (flows[i]->monitor_stat_0[flows[i]->selected_monitor_index].octets > 0 && inOut == 0 ) {

                flw->emulator_monitor_adr = flows[i]->selected_monitor.s_addr;

                flw->src_as = flows[i]->as_src[0];
                flw->dest_as = flows[i]->as_dst[1];
                flw->src_ip = flows[i]->addr[0].v4.s_addr;
                flw->dest_ip = flows[i]->addr[1].v4.s_addr;
                flw->src_port = flows[i]->port[0];
                flw->dest_port = flows[i]->port[1];
                flw->flow_packets = htonl(flows[i]->monitor_stat_0[flows[i]->selected_monitor_index].packets);
                flw->flow_octets = htonl(flows[i]->monitor_stat_0[flows[i]->selected_monitor_index].octets);
                flw->flow_start =
                    htonl(timeval_sub_ms(&flows[i]->flow_start,
                                         system_boot_time));
                flw->flow_finish =
                    htonl(timeval_sub_ms(&flows[i]->flow_last,
                                         system_boot_time));
                flw->tcp_flags = flows[i]->tcp_flags[0];
                flw->protocol = flows[i]->protocol;
                offset += sizeof(*flw);
                j++;
                hdr->flows++;
            }

        }
        flw = (struct NF5_FLOW *)(packet + offset);

        if(!using_emulator)
        {

            if (flows[i]->octets[1] > 0 ) {

                flw->src_as = flows[i]->as_src[1];
                flw->dest_as = flows[i]->as_dst[0];
                flw->src_ip = flows[i]->addr[1].v4.s_addr;
                flw->dest_ip = flows[i]->addr[0].v4.s_addr;
                flw->src_port = flows[i]->port[1];
                flw->dest_port = flows[i]->port[0];
                flw->flow_packets = htonl(flows[i]->packets[1]);
                flw->flow_octets = htonl(flows[i]->octets[1]);
                flw->flow_start =
                    htonl(timeval_sub_ms(&flows[i]->flow_start,
                                         system_boot_time));
                flw->flow_finish =
                    htonl(timeval_sub_ms(&flows[i]->flow_last,
                                         system_boot_time));
                flw->tcp_flags = flows[i]->tcp_flags[1];
                flw->protocol = flows[i]->protocol;
                offset += sizeof(*flw);
                j++;
                hdr->flows++;
            }
        } else
        {

            if (flows[i]->monitor_stat_1[flows[i]->selected_monitor_index].octets > 0 && inOut == 1 ) {

                flw->emulator_monitor_adr = flows[i]->selected_monitor.s_addr;

                flw->src_as = flows[i]->as_src[1];
                flw->dest_as = flows[i]->as_dst[0];
                flw->src_ip = flows[i]->addr[1].v4.s_addr;
                flw->dest_ip = flows[i]->addr[0].v4.s_addr;
                flw->src_port = flows[i]->port[1];
                flw->dest_port = flows[i]->port[0];
                flw->flow_packets = htonl(flows[i]->monitor_stat_1[flows[i]->selected_monitor_index].packets);
                flw->flow_octets = htonl(flows[i]->monitor_stat_1[flows[i]->selected_monitor_index].octets);
                flw->flow_start =
                    htonl(timeval_sub_ms(&flows[i]->flow_start,
                                         system_boot_time));
                flw->flow_finish = htonl(timeval_sub_ms(&flows[i]->flow_last,system_boot_time));
                flw->tcp_flags = flows[i]->tcp_flags[1];
                flw->protocol = flows[i]->protocol;
                offset += sizeof(*flw);
                j++;
                hdr->flows++;
            }
        }
    }
    /* Send any leftovers */
    if (j != 0) {
        if (verbose_flag)
            logit(LOG_DEBUG, "Sending v5 flow packet len = %d",
                  offset);
        hdr->flows = htons(hdr->flows);
        errsz = sizeof(err);
        getsockopt(nfsock, SOL_SOCKET, SO_ERROR,
                   &err, &errsz); /* Clear ICMP errors */
        if (send(nfsock, packet, (size_t)offset, 0) == -1)
            return (-1);
        num_packets++;
    }

    *flows_exported += j;
    return (num_packets);
}