123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- #include <stdio.h>
- #include <string.h>
- #include <xtables.h>
- #include <linux/netfilter/xt_connbytes.h>
- enum {
- O_CONNBYTES = 0,
- O_CONNBYTES_DIR,
- O_CONNBYTES_MODE,
- };
- static void connbytes_help(void)
- {
- printf(
- "connbytes match options:\n"
- " [!] --connbytes from:[to]\n"
- " --connbytes-dir [original, reply, both]\n"
- " --connbytes-mode [packets, bytes, avgpkt]\n");
- }
- static const struct xt_option_entry connbytes_opts[] = {
- {.name = "connbytes", .id = O_CONNBYTES, .type = XTTYPE_UINT64RC,
- .flags = XTOPT_MAND | XTOPT_INVERT},
- {.name = "connbytes-dir", .id = O_CONNBYTES_DIR, .type = XTTYPE_STRING,
- .flags = XTOPT_MAND},
- {.name = "connbytes-mode", .id = O_CONNBYTES_MODE,
- .type = XTTYPE_STRING, .flags = XTOPT_MAND},
- XTOPT_TABLEEND,
- };
- static void connbytes_parse(struct xt_option_call *cb)
- {
- struct xt_connbytes_info *sinfo = cb->data;
- unsigned long long i;
- xtables_option_parse(cb);
- switch (cb->entry->id) {
- case O_CONNBYTES:
- sinfo->count.from = cb->val.u64_range[0];
- sinfo->count.to = UINT64_MAX;
- if (cb->nvals == 2)
- sinfo->count.to = cb->val.u64_range[1];
- if (sinfo->count.to < sinfo->count.from)
- xtables_error(PARAMETER_PROBLEM, "%llu should be less than %llu",
- (unsigned long long)sinfo->count.from,
- (unsigned long long)sinfo->count.to);
- if (cb->invert) {
- i = sinfo->count.from;
- sinfo->count.from = sinfo->count.to;
- sinfo->count.to = i;
- }
- break;
- case O_CONNBYTES_DIR:
- if (strcmp(cb->arg, "original") == 0)
- sinfo->direction = XT_CONNBYTES_DIR_ORIGINAL;
- else if (strcmp(cb->arg, "reply") == 0)
- sinfo->direction = XT_CONNBYTES_DIR_REPLY;
- else if (strcmp(cb->arg, "both") == 0)
- sinfo->direction = XT_CONNBYTES_DIR_BOTH;
- else
- xtables_error(PARAMETER_PROBLEM,
- "Unknown --connbytes-dir `%s'", cb->arg);
- break;
- case O_CONNBYTES_MODE:
- if (strcmp(cb->arg, "packets") == 0)
- sinfo->what = XT_CONNBYTES_PKTS;
- else if (strcmp(cb->arg, "bytes") == 0)
- sinfo->what = XT_CONNBYTES_BYTES;
- else if (strcmp(cb->arg, "avgpkt") == 0)
- sinfo->what = XT_CONNBYTES_AVGPKT;
- else
- xtables_error(PARAMETER_PROBLEM,
- "Unknown --connbytes-mode `%s'", cb->arg);
- break;
- }
- }
- static void print_mode(const struct xt_connbytes_info *sinfo)
- {
- switch (sinfo->what) {
- case XT_CONNBYTES_PKTS:
- fputs(" packets", stdout);
- break;
- case XT_CONNBYTES_BYTES:
- fputs(" bytes", stdout);
- break;
- case XT_CONNBYTES_AVGPKT:
- fputs(" avgpkt", stdout);
- break;
- default:
- fputs(" unknown", stdout);
- break;
- }
- }
- static void print_direction(const struct xt_connbytes_info *sinfo)
- {
- switch (sinfo->direction) {
- case XT_CONNBYTES_DIR_ORIGINAL:
- fputs(" original", stdout);
- break;
- case XT_CONNBYTES_DIR_REPLY:
- fputs(" reply", stdout);
- break;
- case XT_CONNBYTES_DIR_BOTH:
- fputs(" both", stdout);
- break;
- default:
- fputs(" unknown", stdout);
- break;
- }
- }
- static void print_from_to(const struct xt_connbytes_info *sinfo, const char *prefix)
- {
- unsigned long long from, to;
- if (sinfo->count.from > sinfo->count.to) {
- fputs(" !", stdout);
- from = sinfo->count.to;
- to = sinfo->count.from;
- } else {
- to = sinfo->count.to;
- from = sinfo->count.from;
- }
- printf(" %sconnbytes %llu", prefix, from);
- if (to && to < UINT64_MAX)
- printf(":%llu", to);
- }
- static void
- connbytes_print(const void *ip, const struct xt_entry_match *match, int numeric)
- {
- const struct xt_connbytes_info *sinfo = (const void *)match->data;
- print_from_to(sinfo, "");
- fputs(" connbytes mode", stdout);
- print_mode(sinfo);
- fputs(" connbytes direction", stdout);
- print_direction(sinfo);
- }
- static void connbytes_save(const void *ip, const struct xt_entry_match *match)
- {
- const struct xt_connbytes_info *sinfo = (const void *)match->data;
- print_from_to(sinfo, "--");
- fputs(" --connbytes-mode", stdout);
- print_mode(sinfo);
- fputs(" --connbytes-dir", stdout);
- print_direction(sinfo);
- }
- static struct xtables_match connbytes_match = {
- .family = NFPROTO_UNSPEC,
- .name = "connbytes",
- .version = XTABLES_VERSION,
- .size = XT_ALIGN(sizeof(struct xt_connbytes_info)),
- .userspacesize = XT_ALIGN(sizeof(struct xt_connbytes_info)),
- .help = connbytes_help,
- .print = connbytes_print,
- .save = connbytes_save,
- .x6_parse = connbytes_parse,
- .x6_options = connbytes_opts,
- };
- void _init(void)
- {
- xtables_register_match(&connbytes_match);
- }
|