X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=extensions%2Flibipt_connbytes.c;h=7274194b5c49f1e00483bfb7661b29b27d2a2467;hb=6afea0b41dfbc3824956d11d960ad80097218feb;hp=abc37be033969a42b5c0de1ed9481aea0c4b63eb;hpb=f7b70cf9e00324b89b02de213bcd0dde7044d035;p=iptables.git diff --git a/extensions/libipt_connbytes.c b/extensions/libipt_connbytes.c index abc37be..7274194 100644 --- a/extensions/libipt_connbytes.c +++ b/extensions/libipt_connbytes.c @@ -15,38 +15,34 @@ help(void) printf( "connbytes v%s options:\n" " [!] --connbytes from:[to]\n" -" Transfered byte range to match\n" +" --connbytes-dir [original, reply, both]\n" +" --connbytes-mode [packets, bytes, avgpkt]\n" "\n", IPTABLES_VERSION); } static struct option opts[] = { { "connbytes", 1, 0, '1' }, + { "connbytes-dir", 1, 0, '2' }, + { "connbytes-mode", 1, 0, '3' }, {0} }; -/* Initialize the match. */ -static void -init(struct ipt_entry_match *m, unsigned int *nfcache) -{ - /* Can't cache this */ - *nfcache |= NFC_UNKNOWN; -} - static void parse_range(const char *arg, struct ipt_connbytes_info *si) { char *colon,*p; - si->from = strtol(arg,&colon,10); + si->count.from = strtoul(arg,&colon,10); if (*colon != ':') exit_error(PARAMETER_PROBLEM, "Bad range `%s'", arg); - si->to = strtol(colon+1,&p,10); + si->count.to = strtoul(colon+1,&p,10); if (p == colon+1) { /* second number omited */ - si->to = 0xffffffff; + si->count.to = 0xffffffff; } - if (si->from > si->to) - exit_error(PARAMETER_PROBLEM, "%lu should be less than %lu", si->from,si->to); + if (si->count.from > si->count.to) + exit_error(PARAMETER_PROBLEM, "%llu should be less than %llu", + si->count.from, si->count.to); } /* Function which parses command options; returns true if it @@ -58,22 +54,46 @@ parse(int c, char **argv, int invert, unsigned int *flags, struct ipt_entry_match **match) { struct ipt_connbytes_info *sinfo = (struct ipt_connbytes_info *)(*match)->data; - int i; + unsigned long i; switch (c) { case '1': - if (check_inverse(optarg, &invert, optind, 0)) + if (check_inverse(optarg, &invert, &optind, 0)) optind++; parse_range(argv[optind-1], sinfo); if (invert) { - i = sinfo->from; - sinfo->from = sinfo->to; - sinfo->to = i; + i = sinfo->count.from; + sinfo->count.from = sinfo->count.to; + sinfo->count.to = i; } - *flags = 1; + *flags |= 1; + break; + case '2': + if (!strcmp(optarg, "original")) + sinfo->direction = IPT_CONNBYTES_DIR_ORIGINAL; + else if (!strcmp(optarg, "reply")) + sinfo->direction = IPT_CONNBYTES_DIR_REPLY; + else if (!strcmp(optarg, "both")) + sinfo->direction = IPT_CONNBYTES_DIR_BOTH; + else + exit_error(PARAMETER_PROBLEM, + "Unknown --connbytes-dir `%s'", optarg); + + *flags |= 2; + break; + case '3': + if (!strcmp(optarg, "packets")) + sinfo->what = IPT_CONNBYTES_WHAT_PKTS; + else if (!strcmp(optarg, "bytes")) + sinfo->what = IPT_CONNBYTES_WHAT_BYTES; + else if (!strcmp(optarg, "avgpkt")) + sinfo->what = IPT_CONNBYTES_WHAT_AVGPKT; + else + exit_error(PARAMETER_PROBLEM, + "Unknown --connbytes-mode `%s'", optarg); + *flags |= 4; break; - default: return 0; } @@ -83,8 +103,45 @@ parse(int c, char **argv, int invert, unsigned int *flags, static void final_check(unsigned int flags) { - if (!flags) - exit_error(PARAMETER_PROBLEM, "You must specify `--connbytes'"); + if (flags != 7) + exit_error(PARAMETER_PROBLEM, "You must specify `--connbytes'" + "`--connbytes-direction' and `--connbytes-mode'"); +} + +static void print_mode(struct ipt_connbytes_info *sinfo) +{ + switch (sinfo->what) { + case IPT_CONNBYTES_WHAT_PKTS: + fputs("packets ", stdout); + break; + case IPT_CONNBYTES_WHAT_BYTES: + fputs("bytes ", stdout); + break; + case IPT_CONNBYTES_WHAT_AVGPKT: + fputs("avgpkt ", stdout); + break; + default: + fputs("unknown ", stdout); + break; + } +} + +static void print_direction(struct ipt_connbytes_info *sinfo) +{ + switch (sinfo->direction) { + case IPT_CONNBYTES_DIR_ORIGINAL: + fputs("original ", stdout); + break; + case IPT_CONNBYTES_DIR_REPLY: + fputs("reply ", stdout); + break; + case IPT_CONNBYTES_DIR_BOTH: + fputs("both ", stdout); + break; + default: + fputs("unknown ", stdout); + break; + } } /* Prints out the matchinfo. */ @@ -95,10 +152,18 @@ print(const struct ipt_ip *ip, { struct ipt_connbytes_info *sinfo = (struct ipt_connbytes_info *)match->data; - if (sinfo->from > sinfo->to) - printf("connbytes ! %lu:%lu",sinfo->to,sinfo->from); + if (sinfo->count.from > sinfo->count.to) + printf("connbytes ! %llu:%llu ", sinfo->count.to, + sinfo->count.from); else - printf("connbytes %lu:%lu",sinfo->from,sinfo->to); + printf("connbytes %llu:%llu ",sinfo->count.from, + sinfo->count.to); + + fputs("connbytes mode ", stdout); + print_mode(sinfo); + + fputs("connbytes direction ", stdout); + print_direction(sinfo); } /* Saves the matchinfo in parsable form to stdout. */ @@ -106,26 +171,32 @@ static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) { struct ipt_connbytes_info *sinfo = (struct ipt_connbytes_info *)match->data; - if (sinfo->from > sinfo->to) - printf("! --connbytes %lu:%lu",sinfo->to,sinfo->from); + if (sinfo->count.from > sinfo->count.to) + printf("! --connbytes %llu:%llu ", sinfo->count.to, + sinfo->count.from); else - printf("--connbytes %lu:%lu",sinfo->from,sinfo->to); + printf("--connbytes %llu:%llu ", sinfo->count.from, + sinfo->count.to); + + fputs("--connbytes-mode ", stdout); + print_mode(sinfo); + + fputs("--connbytes-direction ", stdout); + print_direction(sinfo); } -static -struct iptables_match state -= { NULL, - "connbytes", - IPTABLES_VERSION, - IPT_ALIGN(sizeof(struct ipt_connbytes_info)), - IPT_ALIGN(sizeof(struct ipt_connbytes_info)), - &help, - &init, - &parse, - &final_check, - &print, - &save, - opts +static struct iptables_match state = { + .next = NULL, + .name = "connbytes", + .version = IPTABLES_VERSION, + .size = IPT_ALIGN(sizeof(struct ipt_connbytes_info)), + .userspacesize = IPT_ALIGN(sizeof(struct ipt_connbytes_info)), + .help = &help, + .parse = &parse, + .final_check = &final_check, + .print = &print, + .save = &save, + .extra_opts = opts }; void _init(void)