170 lines
5.2 KiB
C
170 lines
5.2 KiB
C
/*
|
|
* src/f_ct.c Conntrack Filter
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation version 2.1
|
|
* of the License.
|
|
*
|
|
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
|
|
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
|
|
* Copyright (c) 2007 Secure Computing Corporation
|
|
*/
|
|
|
|
static void get_filter(struct nfnl_ct *ct, int argc, char **argv, int idx)
|
|
{
|
|
struct nl_addr *a;
|
|
|
|
while (argc > idx) {
|
|
if (arg_match("family")) {
|
|
if (argc > ++idx) {
|
|
int family = nl_str2af(argv[idx++]);
|
|
if (family == AF_UNSPEC)
|
|
goto err_invaf;
|
|
nfnl_ct_set_family(ct, family);
|
|
}
|
|
} else if (arg_match("proto")) {
|
|
if (argc > ++idx) {
|
|
int proto = nl_str2ip_proto(argv[idx++]);
|
|
if (proto < 0)
|
|
goto err_invproto;
|
|
nfnl_ct_set_proto(ct, proto);
|
|
}
|
|
} else if (arg_match("tcpstate")) {
|
|
if (argc > ++idx) {
|
|
int state = nfnl_ct_str2tcp_state(argv[idx++]);
|
|
if (state < 0)
|
|
goto err_invtcpstate;
|
|
nfnl_ct_set_tcp_state(ct, state);
|
|
}
|
|
} else if (arg_match("status")) {
|
|
if (argc > ++idx) {
|
|
int status = strtoul(argv[idx++], NULL, 0);
|
|
nfnl_ct_set_status(ct, status);
|
|
nfnl_ct_unset_status(ct, ~status);
|
|
}
|
|
} else if (arg_match("timeout")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_timeout(ct, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("mark")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_mark(ct, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("use")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_use(ct, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("id")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_id(ct, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("origsrc")) {
|
|
if (argc > ++idx) {
|
|
a = nl_addr_parse(argv[idx++],
|
|
nfnl_ct_get_family(ct));
|
|
if (!a)
|
|
goto err_invaddr;
|
|
nfnl_ct_set_src(ct, 0, a);
|
|
nl_addr_put(a);
|
|
}
|
|
} else if (arg_match("origdst")) {
|
|
if (argc > ++idx) {
|
|
a = nl_addr_parse(argv[idx++],
|
|
nfnl_ct_get_family(ct));
|
|
if (!a)
|
|
goto err_invaddr;
|
|
nfnl_ct_set_dst(ct, 0, a);
|
|
nl_addr_put(a);
|
|
}
|
|
} else if (arg_match("origsrcport")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_src_port(ct, 0, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("origdstport")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_dst_port(ct, 0, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("origicmpid")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_icmp_id(ct, 0, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("origicmptype")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_icmp_type(ct, 0, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("origicmpcode")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_icmp_code(ct, 0, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("origpackets")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_packets(ct, 0, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("origbytes")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_bytes(ct, 0, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("replysrc")) {
|
|
if (argc > ++idx) {
|
|
a = nl_addr_parse(argv[idx++],
|
|
nfnl_ct_get_family(ct));
|
|
if (!a)
|
|
goto err_invaddr;
|
|
nfnl_ct_set_src(ct, 1, a);
|
|
nl_addr_put(a);
|
|
}
|
|
} else if (arg_match("replydst")) {
|
|
if (argc > ++idx) {
|
|
a = nl_addr_parse(argv[idx++],
|
|
nfnl_ct_get_family(ct));
|
|
if (!a)
|
|
goto err_invaddr;
|
|
nfnl_ct_set_dst(ct, 1, a);
|
|
nl_addr_put(a);
|
|
}
|
|
} else if (arg_match("replysrcport")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_src_port(ct, 1, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("replydstport")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_dst_port(ct, 1, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("replyicmpid")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_icmp_id(ct, 1, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("replyicmptype")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_icmp_type(ct, 1, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("replyicmpcode")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_icmp_code(ct, 1, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("replypackets")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_packets(ct, 1, strtoul(argv[idx++], NULL, 0));
|
|
} else if (arg_match("replybytes")) {
|
|
if (argc > ++idx)
|
|
nfnl_ct_set_bytes(ct, 1, strtoul(argv[idx++], NULL, 0));
|
|
}
|
|
#define MSTATUS(STR, STATUS) \
|
|
else if (!strcasecmp(argv[idx], STR)) { \
|
|
nfnl_ct_set_status(ct, STATUS); idx++; }
|
|
#define MNOSTATUS(STR, STATUS) \
|
|
else if (!strcasecmp(argv[idx], STR)) { \
|
|
nfnl_ct_unset_status(ct, STATUS); idx++; }
|
|
|
|
MSTATUS("replied", IPS_SEEN_REPLY)
|
|
MNOSTATUS("unreplied", IPS_SEEN_REPLY)
|
|
MSTATUS("assured", IPS_ASSURED)
|
|
MNOSTATUS("unassured", IPS_ASSURED)
|
|
#undef MSTATUS
|
|
#undef MNOSTATUS
|
|
else {
|
|
fprintf(stderr, "What is '%s'?\n", argv[idx]);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
return;
|
|
|
|
err_invproto:
|
|
fprintf(stderr, "Invalid IP protocol \"%s\".\n", argv[idx-1]);
|
|
exit(1);
|
|
err_invtcpstate:
|
|
fprintf(stderr, "Invalid TCP state \"%s\".\n", argv[idx-1]);
|
|
exit(1);
|
|
err_invaf:
|
|
fprintf(stderr, "Invalid address family \"%s\"\n", argv[idx-1]);
|
|
exit(1);
|
|
err_invaddr:
|
|
fprintf(stderr, "Invalid address \"%s\": %s\n", argv[idx-1], nl_geterror());
|
|
exit(1);
|
|
}
|