Deleted Added
sdiff udiff text old ( 135332 ) new ( 135400 )
full compact
1/*-
2 * Copyright (c) 2004 Gleb Smirnoff <glebius@cell.sick.ru>
3 * Copyright (c) 2001-2003 Roman V. Palagin <romanp@unshadow.net>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Gleb Smirnoff and
17 * contributors.
18 * 4. Neither the name of the author nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * $SourceForge: ng_netflow.h,v 1.26 2004/09/04 15:44:55 glebius Exp $
35 * $FreeBSD: head/sys/netgraph/netflow/ng_netflow.h 135332 2004-09-16 20:24:23Z glebius $
36 */
37
38#ifndef _NG_NETFLOW_H_
39#define _NG_NETFLOW_H_
40
41#define NG_NETFLOW_NODE_TYPE "netflow"
42#define NGM_NETFLOW_COOKIE 1095355665
43
44#define NG_NETFLOW_MAXIFACES 64
45
46/* Hook names */
47
48#define NG_NETFLOW_HOOK_DATA "iface"
49#define NG_NETFLOW_HOOK_EXPORT "export"
50
51/* Netgraph commands understood by netflow node */
52enum {
53 NGM_NETFLOW_INFO = 1, /* get node info */
54 NGM_NETFLOW_IFINFO, /* get iface info */
55 NGM_NETFLOW_SHOW, /* show ip cache flow */
56 NGM_NETFLOW_SETDLT, /* set data-link type */
57 NGM_NETFLOW_SETIFINDEX, /* set interface index */
58 NGM_NETFLOW_SETTIMEOUTS, /* set active/inactive flow timeouts */
59};
60
61/* This structure is returned by the NGM_NETFLOW_INFO message */
62struct ng_netflow_info {
63 uint64_t nfinfo_bytes; /* total number of accounted bytes */
64 uint32_t nfinfo_packets; /* total number of accounted packets */
65 uint32_t nfinfo_used; /* number of used cache records */
66 uint32_t nfinfo_free; /* number of free records */
67 uint32_t nfinfo_inact_t; /* flow inactive timeout */
68 uint32_t nfinfo_act_t; /* flow active timeout */
69};
70
71/* This structure is returned by the NGM_NETFLOW_IFINFO message */
72struct ng_netflow_ifinfo {
73 uint32_t ifinfo_packets; /* number of packets for this iface */
74 uint8_t ifinfo_dlt; /* Data Link Type, DLT_XXX */
75#define MAXDLTNAMELEN 20
76 u_int16_t ifinfo_index; /* connected iface index */
77};
78
79
80/* This structure is passed to NGM_NETFLOW_SETDLT message */
81struct ng_netflow_setdlt {
82 uint16_t iface; /* which iface dlt change */
83 uint8_t dlt; /* DLT_XXX from bpf.h */
84};
85
86/* This structure is passed to NGM_NETFLOW_SETIFINDEX */
87struct ng_netflow_setifindex {
88 u_int16_t iface; /* which iface index change */
89 u_int16_t index; /* new index */
90};
91
92/* This structure is passed to NGM_NETFLOW_SETTIMEOUTS */
93struct ng_netflow_settimeouts {
94 uint32_t inactive_timeout; /* flow inactive timeout */
95 uint32_t active_timeout; /* flow active timeout */
96};
97
98/* This is unique data, which identifies flow */
99struct flow_rec {
100 struct in_addr r_src;
101 struct in_addr r_dst;
102 union {
103 struct {
104 uint16_t s_port; /* source TCP/UDP port */
105 uint16_t d_port; /* destination TCP/UDP port */
106 } dir;
107 uint32_t both;
108 } ports;
109 union {
110 struct {
111 u_char prot; /* IP protocol */
112 u_char tos; /* IP TOS */
113 uint16_t i_ifx; /* input interface index */
114 } i;
115 uint32_t all;
116 } misc;
117};
118
119#define r_ip_p misc.i.prot
120#define r_tos misc.i.tos
121#define r_i_ifx misc.i.i_ifx
122#define r_misc misc.all
123#define r_ports ports.both
124#define r_sport ports.dir.s_port
125#define r_dport ports.dir.d_port
126
127/* A flow entry which accumulates statistics */
128struct flow_entry_data {
129 struct flow_rec r;
130 struct in_addr next_hop;
131 uint16_t fle_o_ifx; /* output interface index */
132#define fle_i_ifx r.misc.i.i_ifx
133 uint8_t dst_mask; /* destination route mask bits */
134 uint8_t src_mask; /* source route mask bits */
135 u_long packets;
136 u_long bytes;
137 long first; /* uptime on first packet */
138 long last; /* uptime on last packet */
139 u_char tcp_flags; /* cumulative OR */
140};
141
142/*
143 * How many flow records we will transfer at once
144 * without overflowing socket receive buffer
145 */
146#define NREC_AT_ONCE 1000
147#define NGRESP_SIZE (sizeof(struct ngnf_flows) + (NREC_AT_ONCE * \
148 sizeof(struct flow_entry_data)))
149#define SORCVBUF_SIZE (NGRESP_SIZE + 2 * sizeof(struct ng_mesg))
150
151/* This struct is returned to userland, when "show cache ip flow" */
152struct ngnf_flows {
153 uint32_t nentries;
154 uint32_t last;
155 struct flow_entry_data entries[0];
156};
157
158/* Everything below is for kernel */
159
160#ifdef _KERNEL
161
162struct flow_entry {
163 struct flow_entry_data f;
164
165 LIST_ENTRY(flow_entry) fle_hash; /* entries in one hash item */
166 TAILQ_ENTRY(flow_entry) fle_work; /* entries in work queue*/
167 SLIST_ENTRY(flow_entry) fle_free; /* entries in free stack */
168};
169
170/* Parsing declarations */
171
172/* Parse the info structure */
173#define NG_NETFLOW_INFO_TYPE { \
174 { "Bytes", &ng_parse_uint64_type }, \
175 { "Packets", &ng_parse_uint32_type }, \
176 { "Records used", &ng_parse_uint32_type },\
177 { "Records free", &ng_parse_uint32_type },\
178 { "Inactive timeout", &ng_parse_uint32_type },\
179 { "Active timeout", &ng_parse_uint32_type },\
180 { NULL } \
181}
182
183/* Parse the ifinfo structure */
184#define NG_NETFLOW_IFINFO_TYPE { \
185 { "packets", &ng_parse_uint32_type }, \
186 { "data link type", &ng_parse_uint8_type }, \
187 { "index", &ng_parse_uint16_type }, \
188 { NULL } \
189}
190
191/* Parse the setdlt structure */
192#define NG_NETFLOW_SETDLT_TYPE { \
193 { "iface", &ng_parse_uint16_type }, \
194 { "dlt", &ng_parse_uint8_type }, \
195 { NULL } \
196}
197
198/* Parse the setifindex structure */
199#define NG_NETFLOW_SETIFINDEX_TYPE { \
200 { "iface", &ng_parse_uint16_type }, \
201 { "index", &ng_parse_uint16_type }, \
202 { NULL } \
203}
204
205/* Parse the settimeouts structure */
206#define NG_NETFLOW_SETTIMEOUTS_TYPE { \
207 { "inactive", &ng_parse_uint32_type }, \
208 { "active", &ng_parse_uint32_type }, \
209 { NULL } \
210}
211
212/* Private hook data */
213struct ng_netflow_iface {
214 hook_p hook; /* NULL when disconnected */
215 struct ng_netflow_ifinfo info;
216};
217
218typedef struct ng_netflow_iface *iface_p;
219typedef struct ng_netflow_ifinfo *ifinfo_p;
220
221/* Structure describing our flow engine */
222struct netflow {
223 node_p node; /* link to the node itself */
224
225 struct ng_netflow_iface ifaces[NG_NETFLOW_MAXIFACES]; /* incoming */
226 hook_p export; /* export data goes there */
227
228 struct ng_netflow_info info;
229 uint32_t flow_seq; /* current flow sequence */
230
231 struct callout exp_callout;
232
233 /* Flow cache is a big chunk of memory referenced by 'cache'.
234 * Accounting engine searches for its record using hashing index
235 * 'hash'. Expiry engine searches for its record from begining of
236 * tail queue 'expire_q'. Allocation is performed using last free
237 * stack held in singly linked list 'free_l' */
238#define CACHESIZE 65536
239#define CACHELOWAT (CACHESIZE * 3/4)
240#define CACHEHIGHWAT (CACHESIZE * 9/10)
241 struct flow_entry *cache;
242 struct flow_hash_entry *hash;
243 TAILQ_HEAD( , flow_entry) work_queue;
244 SLIST_HEAD( , flow_entry) free_list;
245 SLIST_HEAD( , flow_entry) expire_list;
246
247 /* Mutexes to protect above lists */
248 struct mtx work_mtx;
249 struct mtx free_mtx;
250 struct mtx expire_mtx;
251
252 /* ng_netflow_export_send() forms its datagram here. */
253 struct netflow_export_dgram {
254 struct netflow_v5_header header;
255 struct netflow_v5_record r[NETFLOW_V5_MAX_RECORDS];
256 } __attribute__((__packed__)) dgram;
257};
258
259typedef struct netflow *priv_p;
260
261/* Header of a small list in hash cell */
262struct flow_hash_entry {
263 LIST_HEAD( ,flow_entry) head;
264};
265
266/* Make sure packet large enough to contain len bytes */
267#define CHECK_MLEN(m, length) ((m)->m_pkthdr.len < (length))
268#define CHECK_PULLUP(m, length) ((m)->m_len < (length) && \
269 (((m) = m_pullup((m),(length))) == NULL))
270
271#define ERROUT(x) { error = (x); goto done; }
272
273/* Prototypes for netflow.c */
274int ng_netflow_cache_init(priv_p);
275void ng_netflow_cache_flush(priv_p);
276void ng_netflow_copyinfo(priv_p, struct ng_netflow_info *);
277timeout_t ng_netflow_expire;
278int ng_netflow_flow_add(priv_p, struct mbuf **, iface_p);
279int ng_netflow_flow_show(priv_p, uint32_t last, struct ng_mesg *);
280
281#endif /* _KERNEL */
282#endif /* _NG_NETFLOW_H_ */