| 1 | /*- |
| 2 | * SPDX-License-Identifier: BSD-2-Clause |
| 3 | * |
| 4 | * Copyright (c) 2010 Alexander V. Chernikov <melifaro@ipfw.ru> |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions |
| 9 | * are met: |
| 10 | * 1. Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 26 | * SUCH DAMAGE. |
| 27 | */ |
| 28 | |
| 29 | #ifndef	_NETFLOW_V9_H_ |
| 30 | #define	_NETFLOW_V9_H_ |
| 31 | |
| 32 | #ifdef COUNTERS_64 |
| 33 | #define CNTR		uint64_t |
| 34 | #define CNTR_MAX	UINT64_MAX |
| 35 | #else |
| 36 | #define CNTR		uint32_t |
| 37 | #define CNTR_MAX	UINT_MAX |
| 38 | #endif |
| 39 | |
| 40 | struct netflow_v9_template |
| 41 | { |
| 42 | 	int	field_id; |
| 43 | 	int	field_length; |
| 44 | }; |
| 45 | |
| 46 | /* Template ID for tcp/udp v4 streams ID:257 (0x100 + NETFLOW_V9_FLOW_V4_L4) */ |
| 47 | struct netflow_v9_record_ipv4_tcp |
| 48 | { |
| 49 | 	uint32_t	src_addr;	/* Source IPv4 address (IPV4_SRC_ADDR) */ |
| 50 | 	uint32_t	dst_addr;	/* Destination IPv4 address (IPV4_DST_ADDR) */ |
| 51 | 	uint32_t	next_hop;	/* Next hop IPv4 address (IPV4_NEXT_HOP) */ |
| 52 | 	uint16_t	i_ifx;	/* Source interface index (INPUT_SNMP) */ |
| 53 | 	uint16_t	o_ifx;	/* Destination interface index (OUTPUT_SNMP) */ |
| 54 | 	CNTR		i_packets;	/* Number of incoming packets in a flow (IN_PKTS) */ |
| 55 | 	CNTR		i_octets;	/* Number of incoming octets in a flow (IN_BYTES) */ |
| 56 | 	CNTR		o_packets;	/* Number of outgoing packets in a flow (OUT_PKTS) */ |
| 57 | 	CNTR		o_octets;	/* Number of outgoing octets in a flow (OUT_BYTES) */ |
| 58 | 	uint32_t	first;	/* System uptime at start of a flow (FIRST_SWITCHED) */ |
| 59 | 	uint32_t	last;	/* System uptime at end of a flow (LAST_SWITCHED) */ |
| 60 | 	uint16_t	s_port;	/* Source port (L4_SRC_PORT) */ |
| 61 | 	uint16_t	d_port;	/* Destination port (L4_DST_PORT) */ |
| 62 | 	uint8_t		flags;	/* Cumulative OR of tcp flags (TCP_FLAGS) */ |
| 63 | 	uint8_t		prot;		/* IP protocol */ |
| 64 | 	uint8_t		tos;		/* IP type of service IN (or OUT) (TOS) */ |
| 65 | 	uint32_t	src_as;	/* Src peer/origin Autonomous System (SRC_AS) */ |
| 66 | 	uint32_t	dst_as;	/* Dst peer/origin Autonomous System (DST_AS) */ |
| 67 | 	uint8_t		src_mask;	/* Source route's mask bits (SRC_MASK) */ |
| 68 | 	uint8_t		dst_mask; 	/* Destination route's mask bits (DST_MASK) */ |
| 69 | } __attribute__((__packed__)); |
| 70 | |
| 71 | /* Template ID for tcp/udp v6 streams ID: 260 (0x100 + NETFLOW_V9_FLOW_V6_L4) */ |
| 72 | struct netflow_v9_record_ipv6_tcp |
| 73 | { |
| 74 | 	struct in6_addr	src_addr;	/* Source IPv6 address (IPV6_SRC_ADDR) */ |
| 75 | 	struct in6_addr	dst_addr;	/* Destination IPv6 address (IPV6_DST_ADDR) */ |
| 76 | 	struct in6_addr	next_hop;	/* Next hop IPv6 address (IPV6_NEXT_HOP) */ |
| 77 | 	uint16_t	i_ifx;	/* Source interface index (INPUT_SNMP) */ |
| 78 | 	uint16_t	o_ifx;	/* Destination interface index (OUTPUT_SNMP) */ |
| 79 | 	CNTR		i_packets;	/* Number of incoming packets in a flow (IN_PKTS) */ |
| 80 | 	CNTR		i_octets;	/* Number of incoming octets in a flow (IN_BYTES) */ |
| 81 | 	CNTR		o_packets;	/* Number of outgoing packets in a flow (OUT_PKTS) */ |
| 82 | 	CNTR		o_octets;	/* Number of outgoing octets in a flow (OUT_BYTES) */ |
| 83 | 	uint32_t	first;	/* System uptime at start of a flow (FIRST_SWITCHED) */ |
| 84 | 	uint32_t	last;	/* System uptime at end of a flow (LAST_SWITCHED) */ |
| 85 | 	uint16_t	s_port;	/* Source port (L4_SRC_PORT) */ |
| 86 | 	uint16_t	d_port;	/* Destination port (L4_DST_PORT) */ |
| 87 | 	uint8_t		flags;	/* Cumulative OR of tcp flags (TCP_FLAGS) */ |
| 88 | 	uint8_t		prot;		/* IP protocol */ |
| 89 | 	uint8_t		tos;		/* IP type of service IN (or OUT) (TOS) */ |
| 90 | 	uint32_t	src_as;	/* Src peer/origin Autonomous System (SRC_AS) */ |
| 91 | 	uint32_t	dst_as;	/* Dst peer/origin Autonomous System (DST_AS) */ |
| 92 | 	uint8_t		src_mask;	/* Source route's mask bits (SRC_MASK) */ |
| 93 | 	uint8_t		dst_mask; 	/* Destination route's mask bits (DST_MASK) */ |
| 94 | } __attribute__((__packed__)); |
| 95 | |
| 96 | /* Used in export9_add to determine max record size */ |
| 97 | struct netflow_v9_record_general |
| 98 | { |
| 99 | 	union { |
| 100 | 		struct netflow_v9_record_ipv4_tcp v4_tcp; |
| 101 | 		struct netflow_v9_record_ipv6_tcp v6_tcp; |
| 102 | 	} rec; |
| 103 | }; |
| 104 | |
| 105 | #define BASE_MTU	1500 |
| 106 | #define MIN_MTU		sizeof(struct netflow_v5_header) |
| 107 | #define MAX_MTU		16384 |
| 108 | #define NETFLOW_V9_MAX_SIZE	_NETFLOW_V9_MAX_SIZE(BASE_MTU) |
| 109 | /* Decrease MSS by 16 since there can be some IPv[46] header options */ |
| 110 | #define _NETFLOW_V9_MAX_SIZE(x)	(x) - sizeof(struct ip6_hdr) - sizeof(struct udphdr) - 16 |
| 111 | |
| 112 | /* #define NETFLOW_V9_MAX_FLOWSETS	2 */ |
| 113 | |
| 114 | #define NETFLOW_V9_MAX_RECORD_SIZE	sizeof(struct netflow_v9_record_ipv6_tcp) |
| 115 | #define NETFLOW_V9_MAX_PACKETS_TEMPL	500	/* Send data templates every ... packets */ |
| 116 | #define NETFLOW_V9_MAX_TIME_TEMPL	600	/* Send data templates every ... seconds */ |
| 117 | #define NETFLOW_V9_MAX_TEMPLATES	16	/* Not a real value */ |
| 118 | #define _NETFLOW_V9_TEMPLATE_SIZE(x)	(sizeof(x) / sizeof(struct netflow_v9_template)) * 4 |
| 119 | //#define _NETFLOW_V9_TEMPLATE_SIZE(x)	((x) + 1) * 4 |
| 120 | |
| 121 | /* Flow Templates */ |
| 122 | #define NETFLOW_V9_FLOW_V4_L4	1 /* IPv4 TCP/UDP packet */ |
| 123 | #define NETFLOW_V9_FLOW_V4_ICMP	2 /* IPv4 ICMP packet, currently unused */ |
| 124 | #define NETFLOW_V9_FLOW_V4_L3	3 /* IPv4 IP packet */ |
| 125 | #define NETFLOW_V9_FLOW_V6_L4	4 /* IPv6 TCP/UDP packet */ |
| 126 | #define NETFLOW_V9_FLOW_V6_ICMP	5 /* IPv6 ICMP packet, currently unused */ |
| 127 | #define NETFLOW_V9_FLOW_V6_L3	6 /* IPv6 IP packet */ |
| 128 | |
| 129 | #define NETFLOW_V9_FLOW_FAKE	65535 /* Not uset used in real flowsets! */ |
| 130 | |
| 131 | struct netflow_v9_export_dgram { |
| 132 | 	struct netflow_v9_header	header; |
| 133 | 	char				*data; /* MTU can change, record length is dynamic */ |
| 134 | }; |
| 135 | |
| 136 | struct netflow_v9_flowset_header { |
| 137 | 	uint16_t	id; /* FlowSet id */ |
| 138 | 	uint16_t	length; /* FlowSet length */ |
| 139 | } __attribute__((__packed__)); |
| 140 | |
| 141 | struct netflow_v9_packet_opt { |
| 142 | 	uint16_t	length; /* current packet length */ |
| 143 | 	uint16_t	count; /* current records count */ |
| 144 | 	uint16_t	mtu; /* max MTU snapshot */ |
| 145 | 	uint16_t	flow_type; /* current flowset */ |
| 146 | 	uint16_t	flow_header; /* offset pointing to current flow header */ |
| 147 | }; |
| 148 | #endif |