/* * 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); }