-
Notifications
You must be signed in to change notification settings - Fork 2
/
peer.h
169 lines (147 loc) · 5.45 KB
/
peer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/* $Id$ */
/*
* Copyright (c) 2004,2005 Damien Miller <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Routines for tracking state from NetFlow sources. NetFlow v.9 / IPFIX
* requires this for their overcomplicated template stuff. Read below for the
* full horror.
*/
#ifndef _PEER_H
#define _PEER_H
#include <sys/types.h>
#include "flowd-common.h"
#include "sys-queue.h"
#include "sys-tree.h"
#include "addr.h"
/* NetFlow v.9 specific state */
/*
* NetFlow v.9 is really overcomplicated. Not only does it require you to
* maintain state for each NetFlow host, it requires you to retain disjoint
* state for different sources on each host. Managing this while considering
* some of the attacks that it enables on a collector is painful.
*
* So, we try to limit the amount of state that we hold on all peers to a
* maximum of max_peers hosts. Within each host, we can retain max_templates
* templates of maximum size max_template_len for max_sources distinct
* sources. So the total is:
* max_peers * max_templates * max_sources * (max_template_len + overheads)
*
* NB. The peer.c routines are not responsible for filling in the template
* record structures, just for housekeeping such as allocation and lookup.
* The filling-in is performed by the netflow v.9 template flowset handler
*
* XXX - share these structures with IPFIX in the future
*/
/* A record in a NetFlow v.9 template record */
struct peer_nf9_record {
u_int type;
u_int len;
};
/* A NetFlow v.9 template record */
struct peer_nf9_template {
TAILQ_ENTRY(peer_nf9_template) lp;
u_int16_t template_id;
u_int num_records;
u_int total_len;
struct peer_nf9_record *records;
};
TAILQ_HEAD(peer_nf9_template_list, peer_nf9_template);
/* A distinct NetFlow v.9 source */
struct peer_nf9_source {
TAILQ_ENTRY(peer_nf9_source) lp;
u_int32_t source_id;
u_int num_templates;
struct peer_nf9_template_list templates;
};
TAILQ_HEAD(peer_nf9_list, peer_nf9_source);
/* A record in a NetFlow v.10 template record */
struct peer_nf10_record {
u_int type;
u_int len;
};
/* A NetFlow v.10 template record */
struct peer_nf10_template {
TAILQ_ENTRY(peer_nf10_template) lp;
u_int16_t template_id;
u_int num_records;
u_int total_len;
struct peer_nf10_record *records;
};
TAILQ_HEAD(peer_nf10_template_list, peer_nf10_template);
/* A distinct NetFlow v.10 source */
struct peer_nf10_source {
TAILQ_ENTRY(peer_nf10_source) lp;
u_int32_t source_id;
u_int num_templates;
struct peer_nf10_template_list templates;
};
TAILQ_HEAD(peer_nf10_list, peer_nf10_source);
/* General per-peer state */
/*
* Structure to hold per-peer state. NetFlow v.9 / IPFIX will require that we
* hold state for each peer to retain templates. This peer state is stored in
* a splay tree for quick access by sender address and in a deque so we can
* do fast LRU deletions on overflow
*/
struct peer_state {
SPLAY_ENTRY(peer_state) tp;
TAILQ_ENTRY(peer_state) lp;
struct xaddr from;
u_int64_t npackets, nflows, ninvalid, no_template;
struct timeval firstseen, lastvalid;
u_int last_version;
/* NetFlow v.9 specific portions */
struct peer_nf9_list nf9;
u_int nf9_num_sources;
/* NetFlow v.10 specific portions */
struct peer_nf10_list nf10;
u_int nf10_num_sources;
};
/* Structures for top of peer state tree and head of list */
SPLAY_HEAD(peer_tree, peer_state);
TAILQ_HEAD(peer_list, peer_state);
/* Peer stateholding structure */
struct peers {
struct peer_tree peer_tree;
struct peer_list peer_list;
u_int max_peers, max_templates, max_sources, max_template_len;
u_int num_peers, num_forced;
};
/* Peer state handling functions */
struct peer_state *new_peer(struct peers *peers, struct flowd_config *conf,
struct xaddr *addr);
void scrub_peers(struct flowd_config *conf, struct peers *peers);
void update_peer(struct peers *peers, struct peer_state *peer, u_int nflows,
u_int netflow_version);
struct peer_state *find_peer(struct peers *peers, struct xaddr *addr);
void dump_peers(struct peers *peers);
/* NetFlow v.9 state handling functions */
struct peer_nf9_template *peer_nf9_find_template(struct peer_state *peer,
u_int32_t source_id, u_int16_t template_id);
struct peer_nf9_template *
peer_nf9_new_template(struct peer_state *peer, struct peers *peers,
u_int32_t source_id, u_int16_t template_id);
void peer_nf9_template_update(struct peer_state *peer,
u_int32_t source_id, u_int16_t template_id);
/* NetFlow v.10 state handling functions */
struct peer_nf10_template *peer_nf10_find_template(struct peer_state *peer,
u_int32_t source_id, u_int16_t template_id);
struct peer_nf10_template *
peer_nf10_new_template(struct peer_state *peer, struct peers *peers,
u_int32_t source_id, u_int16_t template_id);
void peer_nf10_template_update(struct peer_state *peer,
u_int32_t source_id, u_int16_t template_id);
#endif /* _PEER_H */