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