diff options
author | Kibum Kim <kb0929.kim@samsung.com> | 2012-01-07 00:47:33 +0900 |
---|---|---|
committer | Kibum Kim <kb0929.kim@samsung.com> | 2012-01-07 00:47:33 +0900 |
commit | 8df0096515fc2575560e13982f9edf76bf39555e (patch) | |
tree | 0d683bc1583f241ae5675f5fbdccb7260212b35b /extensions/libxt_CT.c | |
parent | dbc5ef4889caa206f4d47d83345357780ceef73e (diff) | |
download | iptables-8df0096515fc2575560e13982f9edf76bf39555e.tar.gz iptables-8df0096515fc2575560e13982f9edf76bf39555e.tar.bz2 iptables-8df0096515fc2575560e13982f9edf76bf39555e.zip |
Git init
Diffstat (limited to 'extensions/libxt_CT.c')
-rw-r--r-- | extensions/libxt_CT.c | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/extensions/libxt_CT.c b/extensions/libxt_CT.c new file mode 100644 index 0000000..6be6ea0 --- /dev/null +++ b/extensions/libxt_CT.c @@ -0,0 +1,192 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include <getopt.h> +#include <xtables.h> +#include <linux/netfilter/nf_conntrack_common.h> +#include <linux/netfilter/xt_CT.h> + +static void ct_help(void) +{ + printf( +"CT target options:\n" +" --notrack Don't track connection\n" +" --helper name Use conntrack helper 'name' for connection\n" +" --ctevents event[,event...] Generate specified conntrack events for connection\n" +" --expevents event[,event...] Generate specified expectation events for connection\n" +" --zone ID Assign/Lookup connection in zone ID\n" + ); +} + +enum ct_options { + CT_OPT_NOTRACK = 0x1, + CT_OPT_HELPER = 0x2, + CT_OPT_CTEVENTS = 0x4, + CT_OPT_EXPEVENTS = 0x8, + CT_OPT_ZONE = 0x10, +}; + +static const struct option ct_opts[] = { + { "notrack", 0, NULL, CT_OPT_NOTRACK }, + { "helper", 1, NULL, CT_OPT_HELPER }, + { "ctevents", 1, NULL, CT_OPT_CTEVENTS }, + { "expevents", 1, NULL, CT_OPT_EXPEVENTS }, + { "zone", 1, NULL, CT_OPT_ZONE }, + { .name = NULL }, +}; + +struct event_tbl { + const char *name; + unsigned int event; +}; + +static const struct event_tbl ct_event_tbl[] = { + { "new", IPCT_NEW }, + { "related", IPCT_RELATED }, + { "destroy", IPCT_DESTROY }, + { "reply", IPCT_REPLY }, + { "assured", IPCT_ASSURED }, + { "protoinfo", IPCT_PROTOINFO }, + { "helper", IPCT_HELPER }, + { "mark", IPCT_MARK }, + { "natseqinfo", IPCT_NATSEQADJ }, + { "secmark", IPCT_SECMARK }, +}; + +static const struct event_tbl exp_event_tbl[] = { + { "new", IPEXP_NEW }, +}; + +static uint32_t ct_parse_events(const struct event_tbl *tbl, unsigned int size, + const char *events) +{ + char str[strlen(events) + 1], *e = str, *t; + unsigned int mask = 0, i; + + strcpy(str, events); + while ((t = strsep(&e, ","))) { + for (i = 0; i < size; i++) { + if (strcmp(t, tbl[i].name)) + continue; + mask |= 1 << tbl[i].event; + break; + } + + if (i == size) + xtables_error(PARAMETER_PROBLEM, "Unknown event type \"%s\"", t); + } + + return mask; +} + +static void ct_print_events(const char *pfx, const struct event_tbl *tbl, + unsigned int size, uint32_t mask) +{ + const char *sep = ""; + unsigned int i; + + printf("%s ", pfx); + for (i = 0; i < size; i++) { + if (mask & (1 << tbl[i].event)) { + printf("%s%s", sep, tbl[i].name); + sep = ","; + } + } + printf(" "); +} + +static int ct_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_target **target) +{ + struct xt_ct_target_info *info = (struct xt_ct_target_info *)(*target)->data; + unsigned int zone; + + switch (c) { + case CT_OPT_NOTRACK: + xtables_param_act(XTF_ONLY_ONCE, "CT", "--notrack", *flags & CT_OPT_NOTRACK); + info->flags |= XT_CT_NOTRACK; + break; + case CT_OPT_HELPER: + xtables_param_act(XTF_ONLY_ONCE, "CT", "--helper", *flags & CT_OPT_HELPER); + strncpy(info->helper, optarg, sizeof(info->helper)); + info->helper[sizeof(info->helper) - 1] = '\0'; + break; + case CT_OPT_CTEVENTS: + xtables_param_act(XTF_ONLY_ONCE, "CT", "--ctevents", *flags & CT_OPT_CTEVENTS); + info->ct_events = ct_parse_events(ct_event_tbl, ARRAY_SIZE(ct_event_tbl), optarg); + break; + case CT_OPT_EXPEVENTS: + xtables_param_act(XTF_ONLY_ONCE, "CT", "--expevents", *flags & CT_OPT_EXPEVENTS); + info->exp_events = ct_parse_events(exp_event_tbl, ARRAY_SIZE(exp_event_tbl), optarg); + break; + case CT_OPT_ZONE: + xtables_param_act(XTF_ONLY_ONCE, "CT", "--zone", *flags & CT_OPT_ZONE); + if (!xtables_strtoui(optarg, NULL, &zone, 0, UINT16_MAX)) + xtables_error(PARAMETER_PROBLEM, "Bad zone value \"%s\"", optarg); + info->zone = zone; + break; + default: + return 0; + } + + *flags |= c; + return 1; +} + +static void ct_print(const void *ip, const struct xt_entry_target *target, int numeric) +{ + const struct xt_ct_target_info *info = + (const struct xt_ct_target_info *)target->data; + + printf("CT "); + if (info->flags & XT_CT_NOTRACK) + printf("notrack "); + if (info->helper[0]) + printf("helper %s ", info->helper); + if (info->ct_events) + ct_print_events("ctevents", ct_event_tbl, + ARRAY_SIZE(ct_event_tbl), info->ct_events); + if (info->exp_events) + ct_print_events("expevents", exp_event_tbl, + ARRAY_SIZE(exp_event_tbl), info->exp_events); + if (info->zone) + printf("zone %u ", info->zone); +} + +static void ct_save(const void *ip, const struct xt_entry_target *target) +{ + const struct xt_ct_target_info *info = + (const struct xt_ct_target_info *)target->data; + + if (info->flags & XT_CT_NOTRACK) + printf("--notrack "); + if (info->helper[0]) + printf("--helper %s ", info->helper); + if (info->ct_events) + ct_print_events("--ctevents", ct_event_tbl, + ARRAY_SIZE(ct_event_tbl), info->ct_events); + if (info->exp_events) + ct_print_events("--expevents", exp_event_tbl, + ARRAY_SIZE(exp_event_tbl), info->exp_events); + if (info->zone) + printf("--zone %u ", info->zone); +} + +static struct xtables_target ct_target = { + .family = NFPROTO_UNSPEC, + .name = "CT", + .version = XTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_ct_target_info)), + .userspacesize = offsetof(struct xt_ct_target_info, ct), + .help = ct_help, + .parse = ct_parse, + .print = ct_print, + .save = ct_save, + .extra_opts = ct_opts, +}; + +void _init(void) +{ + xtables_register_target(&ct_target); +} |