2
* (C) 2006 by Pablo Neira Ayuso <pablo@netfilter.org>
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
#include "conntrackd.h"
21
#include "traffic_stats.h"
26
int ignore_conntrack(struct nf_conntrack *ct)
28
/* ignore a certain protocol */
29
if (CONFIG(ignore_protocol)[nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO)])
32
/* Accept DNAT'ed traffic: not really coming to the local machine */
33
if (nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT)) {
38
/* Accept SNAT'ed traffic: not really coming to the local machine */
39
if (nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT)) {
45
if (ignore_pool_test(STATE(ignore_pool), ct)) {
46
debug_ct(ct, "ignore traffic");
53
static int event_handler(enum nf_conntrack_msg_type type,
54
struct nf_conntrack *ct,
58
* Ignore this conntrack: it talks about a
59
* connection that is not interesting for us.
61
if (ignore_conntrack(ct))
66
STATE(mode)->event_new(ct);
69
STATE(mode)->event_upd(ct);
72
if (STATE(mode)->event_dst(ct))
73
update_traffic_stats(ct);
76
dlog(LOG_WARNING, "unknown msg from ctnetlink\n");
80
return NFCT_CB_CONTINUE;
83
#include <sys/types.h>
84
#include <sys/socket.h>
85
#include <sys/fcntl.h>
87
int nl_init_event_handler(void)
89
STATE(event) = nfct_open(CONNTRACK, NFCT_ALL_CT_GROUPS);
93
fcntl(nfct_fd(STATE(event)), F_SETFL, O_NONBLOCK);
95
/* set up socket buffer size */
96
if (CONFIG(netlink_buffer_size))
97
nfnl_rcvbufsiz(nfct_nfnlh(STATE(event)),
98
CONFIG(netlink_buffer_size));
100
socklen_t socklen = sizeof(unsigned int);
101
unsigned int read_size;
103
/* get current buffer size */
104
getsockopt(nfct_fd(STATE(event)), SOL_SOCKET,
105
SO_RCVBUF, &read_size, &socklen);
107
CONFIG(netlink_buffer_size) = read_size;
110
/* ensure that maximum grown size is >= than maximum size */
111
if (CONFIG(netlink_buffer_size_max_grown) < CONFIG(netlink_buffer_size))
112
CONFIG(netlink_buffer_size_max_grown) =
113
CONFIG(netlink_buffer_size);
115
/* register callback for events */
116
nfct_callback_register(STATE(event), NFCT_T_ALL, event_handler, NULL);
121
static int dump_handler(enum nf_conntrack_msg_type type,
122
struct nf_conntrack *ct,
126
* Ignore this conntrack: it talks about a
127
* connection that is not interesting for us.
129
if (ignore_conntrack(ct))
130
return NFCT_CB_CONTINUE;
134
STATE(mode)->dump(ct);
137
dlog(LOG_WARNING, "unknown msg from ctnetlink");
140
return NFCT_CB_CONTINUE;
143
int nl_init_dump_handler(void)
145
/* open dump netlink socket */
146
STATE(dump) = nfct_open(CONNTRACK, 0);
150
/* register callback for dumped entries */
151
nfct_callback_register(STATE(dump), NFCT_T_ALL, dump_handler, NULL);
153
if (nl_dump_conntrack_table() == -1)
159
static int warned = 0;
161
void nl_resize_socket_buffer(struct nfct_handle *h)
163
unsigned int s = CONFIG(netlink_buffer_size) * 2;
165
/* already warned that we have reached the maximum buffer size */
169
if (s > CONFIG(netlink_buffer_size_max_grown)) {
171
"maximum netlink socket buffer "
172
"size has been reached. We are likely to "
173
"be losing events, this may lead to "
174
"unsynchronized replicas. Please, consider "
175
"increasing netlink socket buffer size via "
176
"SocketBufferSize and "
177
"SocketBufferSizeMaxGrown clauses in "
179
s = CONFIG(netlink_buffer_size_max_grown);
183
CONFIG(netlink_buffer_size) = nfnl_rcvbufsiz(nfct_nfnlh(h), s);
185
/* notify the sysadmin */
186
dlog(LOG_NOTICE, "netlink socket buffer size "
187
"has been set to %u bytes",
188
CONFIG(netlink_buffer_size));
191
int nl_dump_conntrack_table(void)
193
return nfct_query(STATE(dump), NFCT_Q_DUMP, &CONFIG(family));
196
/* This function modifies the conntrack passed as argument! */
197
int nl_create_conntrack(struct nf_conntrack *ct)
201
/* XXX: related connections */
202
if (nfct_attr_is_set(ct, ATTR_STATUS)) {
203
uint32_t status = nfct_get_attr_u32(ct, ATTR_STATUS);
204
status &= ~IPS_EXPECTED;
205
nfct_set_attr_u32(ct, ATTR_STATUS, status);
208
nfct_setobjopt(ct, NFCT_SOPT_SETUP_REPLY);
211
* TCP flags to overpass window tracking for recovered connections
213
flags = IP_CT_TCP_FLAG_BE_LIBERAL | IP_CT_TCP_FLAG_SACK_PERM;
214
nfct_set_attr_u8(ct, ATTR_TCP_FLAGS_ORIG, flags);
215
nfct_set_attr_u8(ct, ATTR_TCP_MASK_ORIG, flags);
216
nfct_set_attr_u8(ct, ATTR_TCP_FLAGS_REPL, flags);
217
nfct_set_attr_u8(ct, ATTR_TCP_MASK_REPL, flags);
219
return nfct_query(STATE(dump), NFCT_Q_CREATE_UPDATE, ct);
222
int nl_destroy_conntrack(struct nf_conntrack *ct)
224
return nfct_query(STATE(dump), NFCT_Q_DESTROY, ct);