FreeBSD/sys/netgraph/netflow/netflow_v9.c
/* Add V9 record to dgram. */
Add V9 record to dgram.
Add V9 record to dgram .
int
export9_add(item_p item, struct netflow_v9_packet_opt *t, struct flow_entry *fle)
{
	size_t len = 0;
	struct netflow_v9_flowset_header fsh;
	struct netflow_v9_record_general rg;
	struct mbuf *m = NGI_M(item);
	uint16_t flow_type;
	struct flow_entry_data *fed;
#ifdef INET6	
	struct flow6_entry_data *fed6;
#endif
	if (t == NULL) {
		CTR0(KTR_NET, "ng_netflow: V9 export packet without tag!");
		return (0);
	}
	fed = (struct flow_entry_data *)&fle->f;
#ifdef INET6
	fed6 = (struct flow6_entry_data *)&fle->f;
#endif
	flow_type = fed->r.flow_type;
	switch (flow_type) {
	case NETFLOW_V9_FLOW_V4_L4:
	{
		struct netflow_v9_record_ipv4_tcp *rec = &rg.rec.v4_tcp;
		rec->src_addr = fed->r.r_src.s_addr;
		rec->dst_addr = fed->r.r_dst.s_addr;
		rec->next_hop = fed->next_hop.s_addr;
		rec->i_ifx    = htons(fed->fle_i_ifx);
		rec->o_ifx    = htons(fed->fle_o_ifx);
		rec->i_packets  = htonl(fed->packets);
		rec->i_octets   = htonl(fed->bytes);
		rec->o_packets  = htonl(0);
		rec->o_octets   = htonl(0);
		rec->first    = htonl(MILLIUPTIME(fed->first));
		rec->last     = htonl(MILLIUPTIME(fed->last));
		rec->s_port   = fed->r.r_sport;
		rec->d_port   = fed->r.r_dport;
		rec->flags    = fed->tcp_flags;
		rec->prot     = fed->r.r_ip_p;
		rec->tos      = fed->r.r_tos;
		rec->dst_mask = fed->dst_mask;
		rec->src_mask = fed->src_mask;
		rec->src_as = rec->dst_as = 0;
		len = sizeof(struct netflow_v9_record_ipv4_tcp);
		break;
	}
#ifdef INET6	
	case NETFLOW_V9_FLOW_V6_L4:
	{
		struct netflow_v9_record_ipv6_tcp *rec = &rg.rec.v6_tcp;
		rec->src_addr = fed6->r.src.r_src6;
		rec->dst_addr = fed6->r.dst.r_dst6;
		rec->next_hop = fed6->n.next_hop6;
		rec->i_ifx    = htons(fed6->fle_i_ifx);
		rec->o_ifx    = htons(fed6->fle_o_ifx);
		rec->i_packets  = htonl(fed6->packets);
		rec->i_octets   = htonl(fed6->bytes);
		rec->o_packets  = htonl(0);
		rec->o_octets   = htonl(0);
		rec->first    = htonl(MILLIUPTIME(fed6->first));
		rec->last     = htonl(MILLIUPTIME(fed6->last));
		rec->s_port   = fed6->r.r_sport;
		rec->d_port   = fed6->r.r_dport;
		rec->flags    = fed6->tcp_flags;
		rec->prot     = fed6->r.r_ip_p;
		rec->tos      = fed6->r.r_tos;
		rec->dst_mask = fed6->dst_mask;
		rec->src_mask = fed6->src_mask;
		rec->src_as = rec->dst_as = 0;
		len = sizeof(struct netflow_v9_record_ipv6_tcp);
		break;
	}
#endif	
	default:
	{
		CTR1(KTR_NET, "export9_add(): Don't know what to do with %d flow type!", flow_type);
		return (0);
	}
	}
	if (flow_type != t->flow_type) {
		if (t->flow_type != 0)
			close_flowset(m, t);
		t->flow_type = flow_type;
		t->flow_header = m_pktlen(m);
		fsh.id = htons(NETFLOW_V9_MAX_RESERVED_FLOWSET + flow_type);
		fsh.length = 0;
		if (m_append(m, sizeof(fsh), (void *)&fsh) != 1)
			panic("ng_netflow: m_append() failed");
	}
	if (m_append(m, len, (void *)&rg.rec) != 1)
		panic("ng_netflow: m_append() failed");
	t->count++;
	if (m_pktlen(m) + sizeof(struct netflow_v9_record_general) + sizeof(struct netflow_v9_flowset_header) >= _NETFLOW_V9_MAX_SIZE(t->mtu))
		return (1); 
	return (0);
}
int export9_add ( item_p item , struct netflow_v9_packet_opt * t , struct flow_entry * fle ) { size_t len = 0 ; struct netflow_v9_flowset_header fsh ; struct netflow_v9_record_general rg ; struct mbuf * m = NGI_M ( item ) ; uint16_t flow_type ; struct flow_entry_data * fed ; #ifdef INET6 struct flow6_entry_data * fed6 ; #endif if ( t == NULL ) { CTR0 ( KTR_NET , " " ) ; return ( 0 ) ; } fed = ( struct flow_entry_data * ) & fle -> f ; #ifdef INET6 fed6 = ( struct flow6_entry_data * ) & fle -> f ; #endif flow_type = fed -> r . flow_type ; switch ( flow_type ) { case NETFLOW_V9_FLOW_V4_L4 : { struct netflow_v9_record_ipv4_tcp * rec = & rg . rec . v4_tcp ; rec -> src_addr = fed -> r . r_src . s_addr ; rec -> dst_addr = fed -> r . r_dst . s_addr ; rec -> next_hop = fed -> next_hop . s_addr ; rec -> i_ifx = htons ( fed -> fle_i_ifx ) ; rec -> o_ifx = htons ( fed -> fle_o_ifx ) ; rec -> i_packets = htonl ( fed -> packets ) ; rec -> i_octets = htonl ( fed -> bytes ) ; rec -> o_packets = htonl ( 0 ) ; rec -> o_octets = htonl ( 0 ) ; rec -> first = htonl ( MILLIUPTIME ( fed -> first ) ) ; rec -> last = htonl ( MILLIUPTIME ( fed -> last ) ) ; rec -> s_port = fed -> r . r_sport ; rec -> d_port = fed -> r . r_dport ; rec -> flags = fed -> tcp_flags ; rec -> prot = fed -> r . r_ip_p ; rec -> tos = fed -> r . r_tos ; rec -> dst_mask = fed -> dst_mask ; rec -> src_mask = fed -> src_mask ; rec -> src_as = rec -> dst_as = 0 ; len = sizeof ( struct netflow_v9_record_ipv4_tcp ) ; break ; } #ifdef INET6 case NETFLOW_V9_FLOW_V6_L4 : { struct netflow_v9_record_ipv6_tcp * rec = & rg . rec . v6_tcp ; rec -> src_addr = fed6 -> r . src . r_src6 ; rec -> dst_addr = fed6 -> r . dst . r_dst6 ; rec -> next_hop = fed6 -> n . next_hop6 ; rec -> i_ifx = htons ( fed6 -> fle_i_ifx ) ; rec -> o_ifx = htons ( fed6 -> fle_o_ifx ) ; rec -> i_packets = htonl ( fed6 -> packets ) ; rec -> i_octets = htonl ( fed6 -> bytes ) ; rec -> o_packets = htonl ( 0 ) ; rec -> o_octets = htonl ( 0 ) ; rec -> first = htonl ( MILLIUPTIME ( fed6 -> first ) ) ; rec -> last = htonl ( MILLIUPTIME ( fed6 -> last ) ) ; rec -> s_port = fed6 -> r . r_sport ; rec -> d_port = fed6 -> r . r_dport ; rec -> flags = fed6 -> tcp_flags ; rec -> prot = fed6 -> r . r_ip_p ; rec -> tos = fed6 -> r . r_tos ; rec -> dst_mask = fed6 -> dst_mask ; rec -> src_mask = fed6 -> src_mask ; rec -> src_as = rec -> dst_as = 0 ; len = sizeof ( struct netflow_v9_record_ipv6_tcp ) ; break ; } #endif default : { CTR1 ( KTR_NET , " " , flow_type ) ; return ( 0 ) ; } } if ( flow_type != t -> flow_type ) { if ( t -> flow_type != 0 ) close_flowset ( m , t ) ; t -> flow_type = flow_type ; t -> flow_header = m_pktlen ( m ) ; fsh . id = htons ( NETFLOW_V9_MAX_RESERVED_FLOWSET + flow_type ) ; fsh . length = 0 ; if ( m_append ( m , sizeof ( fsh ) , ( void * ) & fsh ) != 1 ) panic ( " " ) ; } if ( m_append ( m , len , ( void * ) & rg . rec ) != 1 ) panic ( " " ) ; t -> count ++ ; if ( m_pktlen ( m ) + sizeof ( struct netflow_v9_record_general ) + sizeof ( struct netflow_v9_flowset_header ) >= _NETFLOW_V9_MAX_SIZE ( t -> mtu ) ) return ( 1 ) ; return ( 0 ) ; }
Add V9 record to dgram.
Add V9 record to dgram .
/* Prepare flow record */ /* We can use flow_type field since fle6 offset is equal to fle */ /* IPv4 TCP/UDP/[SCTP] */ /* Not supported fields. */ /* IPv6 TCP/UDP/[SCTP] */ /* Not supported fields. */ /* Check if new records has the same template */ /* close old flowset */ /* Generate data flowset ID */ /* m_append should not fail since all data is already allocated */ /* end of datagram */