blob: 46a7e4b9a1038125f2faf8c6e498eda5fc4f42ca [file] [log] [blame]
Martin Devera766113a2003-06-19 12:23:37 +00001#include <stdio.h>
Martin Devera766113a2003-06-19 12:23:37 +00002#include <string.h>
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +00003#include <xtables.h>
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +00004#include <linux/netfilter/xt_connbytes.h>
Martin Devera766113a2003-06-19 12:23:37 +00005
Jan Engelhardt09631dc2011-03-06 17:19:10 +01006enum {
7 O_CONNBYTES = 0,
8 O_CONNBYTES_DIR,
9 O_CONNBYTES_MODE,
10};
11
Jan Engelhardt181dead2007-10-04 16:27:07 +000012static void connbytes_help(void)
Martin Devera766113a2003-06-19 12:23:37 +000013{
14 printf(
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020015"connbytes match options:\n"
Martin Devera766113a2003-06-19 12:23:37 +000016" [!] --connbytes from:[to]\n"
Harald Welte93f4a3d2004-11-18 22:50:01 +000017" --connbytes-dir [original, reply, both]\n"
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020018" --connbytes-mode [packets, bytes, avgpkt]\n");
Martin Devera766113a2003-06-19 12:23:37 +000019}
20
Jan Engelhardt09631dc2011-03-06 17:19:10 +010021static const struct xt_option_entry connbytes_opts[] = {
22 {.name = "connbytes", .id = O_CONNBYTES, .type = XTTYPE_UINT64RC,
23 .flags = XTOPT_MAND | XTOPT_INVERT},
24 {.name = "connbytes-dir", .id = O_CONNBYTES_DIR, .type = XTTYPE_STRING,
25 .flags = XTOPT_MAND},
26 {.name = "connbytes-mode", .id = O_CONNBYTES_MODE,
27 .type = XTTYPE_STRING, .flags = XTOPT_MAND},
28 XTOPT_TABLEEND,
Martin Devera766113a2003-06-19 12:23:37 +000029};
30
Jan Engelhardt09631dc2011-03-06 17:19:10 +010031static void connbytes_parse(struct xt_option_call *cb)
Martin Devera766113a2003-06-19 12:23:37 +000032{
Jan Engelhardt09631dc2011-03-06 17:19:10 +010033 struct xt_connbytes_info *sinfo = cb->data;
34 unsigned long long i;
Martin Devera766113a2003-06-19 12:23:37 +000035
Jan Engelhardt09631dc2011-03-06 17:19:10 +010036 xtables_option_parse(cb);
37 switch (cb->entry->id) {
38 case O_CONNBYTES:
39 sinfo->count.from = cb->val.u64_range[0];
40 sinfo->count.to = cb->val.u64_range[0];
41 if (cb->nvals == 2)
42 sinfo->count.to = cb->val.u64_range[1];
43 if (cb->invert) {
Harald Welte93f4a3d2004-11-18 22:50:01 +000044 i = sinfo->count.from;
Harald Welte7dc57e22004-11-18 22:59:36 +000045 sinfo->count.from = sinfo->count.to;
Harald Welte93f4a3d2004-11-18 22:50:01 +000046 sinfo->count.to = i;
Martin Devera766113a2003-06-19 12:23:37 +000047 }
Martin Devera766113a2003-06-19 12:23:37 +000048 break;
Jan Engelhardt09631dc2011-03-06 17:19:10 +010049 case O_CONNBYTES_DIR:
50 if (strcmp(cb->arg, "original") == 0)
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +000051 sinfo->direction = XT_CONNBYTES_DIR_ORIGINAL;
Jan Engelhardt09631dc2011-03-06 17:19:10 +010052 else if (strcmp(cb->arg, "reply") == 0)
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +000053 sinfo->direction = XT_CONNBYTES_DIR_REPLY;
Jan Engelhardt09631dc2011-03-06 17:19:10 +010054 else if (strcmp(cb->arg, "both") == 0)
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +000055 sinfo->direction = XT_CONNBYTES_DIR_BOTH;
Harald Welte93f4a3d2004-11-18 22:50:01 +000056 else
Jan Engelhardt1829ed42009-02-21 03:29:44 +010057 xtables_error(PARAMETER_PROBLEM,
Jan Engelhardt09631dc2011-03-06 17:19:10 +010058 "Unknown --connbytes-dir `%s'", cb->arg);
Harald Welte93f4a3d2004-11-18 22:50:01 +000059 break;
Jan Engelhardt09631dc2011-03-06 17:19:10 +010060 case O_CONNBYTES_MODE:
61 if (strcmp(cb->arg, "packets") == 0)
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +000062 sinfo->what = XT_CONNBYTES_PKTS;
Jan Engelhardt09631dc2011-03-06 17:19:10 +010063 else if (strcmp(cb->arg, "bytes") == 0)
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +000064 sinfo->what = XT_CONNBYTES_BYTES;
Jan Engelhardt09631dc2011-03-06 17:19:10 +010065 else if (strcmp(cb->arg, "avgpkt") == 0)
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +000066 sinfo->what = XT_CONNBYTES_AVGPKT;
Harald Welte93f4a3d2004-11-18 22:50:01 +000067 else
Jan Engelhardt1829ed42009-02-21 03:29:44 +010068 xtables_error(PARAMETER_PROBLEM,
Jan Engelhardt09631dc2011-03-06 17:19:10 +010069 "Unknown --connbytes-mode `%s'", cb->arg);
Piotrek Kaczmarek1c0f2362005-04-24 16:19:51 +000070 break;
Martin Devera766113a2003-06-19 12:23:37 +000071 }
Harald Welte93f4a3d2004-11-18 22:50:01 +000072}
73
Jan Engelhardt69f564e2009-05-26 13:14:06 +020074static void print_mode(const struct xt_connbytes_info *sinfo)
Harald Welte93f4a3d2004-11-18 22:50:01 +000075{
76 switch (sinfo->what) {
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +000077 case XT_CONNBYTES_PKTS:
Jan Engelhardt73866352010-12-18 02:04:59 +010078 fputs(" packets", stdout);
Harald Welte93f4a3d2004-11-18 22:50:01 +000079 break;
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +000080 case XT_CONNBYTES_BYTES:
Jan Engelhardt73866352010-12-18 02:04:59 +010081 fputs(" bytes", stdout);
Harald Welte93f4a3d2004-11-18 22:50:01 +000082 break;
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +000083 case XT_CONNBYTES_AVGPKT:
Jan Engelhardt73866352010-12-18 02:04:59 +010084 fputs(" avgpkt", stdout);
Harald Welte93f4a3d2004-11-18 22:50:01 +000085 break;
Harald Welte7dc57e22004-11-18 22:59:36 +000086 default:
Jan Engelhardt73866352010-12-18 02:04:59 +010087 fputs(" unknown", stdout);
Harald Welte7dc57e22004-11-18 22:59:36 +000088 break;
Harald Welte93f4a3d2004-11-18 22:50:01 +000089 }
90}
91
Jan Engelhardt69f564e2009-05-26 13:14:06 +020092static void print_direction(const struct xt_connbytes_info *sinfo)
Harald Welte93f4a3d2004-11-18 22:50:01 +000093{
94 switch (sinfo->direction) {
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +000095 case XT_CONNBYTES_DIR_ORIGINAL:
Jan Engelhardt73866352010-12-18 02:04:59 +010096 fputs(" original", stdout);
Harald Welte93f4a3d2004-11-18 22:50:01 +000097 break;
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +000098 case XT_CONNBYTES_DIR_REPLY:
Jan Engelhardt73866352010-12-18 02:04:59 +010099 fputs(" reply", stdout);
Harald Welte93f4a3d2004-11-18 22:50:01 +0000100 break;
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +0000101 case XT_CONNBYTES_DIR_BOTH:
Jan Engelhardt73866352010-12-18 02:04:59 +0100102 fputs(" both", stdout);
Harald Welte7dc57e22004-11-18 22:59:36 +0000103 break;
104 default:
Jan Engelhardt73866352010-12-18 02:04:59 +0100105 fputs(" unknown", stdout);
Harald Welte93f4a3d2004-11-18 22:50:01 +0000106 break;
107 }
Martin Devera766113a2003-06-19 12:23:37 +0000108}
109
Martin Devera766113a2003-06-19 12:23:37 +0000110static void
Jan Engelhardt181dead2007-10-04 16:27:07 +0000111connbytes_print(const void *ip, const struct xt_entry_match *match, int numeric)
Martin Devera766113a2003-06-19 12:23:37 +0000112{
Jan Engelhardt69f564e2009-05-26 13:14:06 +0200113 const struct xt_connbytes_info *sinfo = (const void *)match->data;
Martin Devera766113a2003-06-19 12:23:37 +0000114
Harald Welte7dc57e22004-11-18 22:59:36 +0000115 if (sinfo->count.from > sinfo->count.to)
Jan Engelhardt73866352010-12-18 02:04:59 +0100116 printf(" connbytes ! %llu:%llu",
Patrick McHardyc329d6a2007-09-05 14:19:23 +0000117 (unsigned long long)sinfo->count.to,
118 (unsigned long long)sinfo->count.from);
Martin Devera766113a2003-06-19 12:23:37 +0000119 else
Jan Engelhardt73866352010-12-18 02:04:59 +0100120 printf(" connbytes %llu:%llu",
Patrick McHardyc329d6a2007-09-05 14:19:23 +0000121 (unsigned long long)sinfo->count.from,
122 (unsigned long long)sinfo->count.to);
Harald Welte93f4a3d2004-11-18 22:50:01 +0000123
Jan Engelhardt73866352010-12-18 02:04:59 +0100124 fputs(" connbytes mode", stdout);
Harald Welte93f4a3d2004-11-18 22:50:01 +0000125 print_mode(sinfo);
126
Jan Engelhardt73866352010-12-18 02:04:59 +0100127 fputs(" connbytes direction", stdout);
Harald Welte93f4a3d2004-11-18 22:50:01 +0000128 print_direction(sinfo);
Martin Devera766113a2003-06-19 12:23:37 +0000129}
130
Jan Engelhardt181dead2007-10-04 16:27:07 +0000131static void connbytes_save(const void *ip, const struct xt_entry_match *match)
Martin Devera766113a2003-06-19 12:23:37 +0000132{
Jan Engelhardt69f564e2009-05-26 13:14:06 +0200133 const struct xt_connbytes_info *sinfo = (const void *)match->data;
Martin Devera766113a2003-06-19 12:23:37 +0000134
Harald Welte93f4a3d2004-11-18 22:50:01 +0000135 if (sinfo->count.from > sinfo->count.to)
Jan Engelhardt73866352010-12-18 02:04:59 +0100136 printf(" ! --connbytes %llu:%llu",
Patrick McHardyc329d6a2007-09-05 14:19:23 +0000137 (unsigned long long)sinfo->count.to,
138 (unsigned long long)sinfo->count.from);
Martin Devera766113a2003-06-19 12:23:37 +0000139 else
Jan Engelhardt73866352010-12-18 02:04:59 +0100140 printf(" --connbytes %llu:%llu",
Patrick McHardyc329d6a2007-09-05 14:19:23 +0000141 (unsigned long long)sinfo->count.from,
142 (unsigned long long)sinfo->count.to);
Harald Welte93f4a3d2004-11-18 22:50:01 +0000143
Jan Engelhardt73866352010-12-18 02:04:59 +0100144 fputs(" --connbytes-mode", stdout);
Harald Welte93f4a3d2004-11-18 22:50:01 +0000145 print_mode(sinfo);
146
Jan Engelhardt73866352010-12-18 02:04:59 +0100147 fputs(" --connbytes-dir", stdout);
Harald Welte93f4a3d2004-11-18 22:50:01 +0000148 print_direction(sinfo);
Martin Devera766113a2003-06-19 12:23:37 +0000149}
150
Jan Engelhardt181dead2007-10-04 16:27:07 +0000151static struct xtables_match connbytes_match = {
Jan Engelhardtc5e85732009-06-12 20:55:44 +0200152 .family = NFPROTO_UNSPEC,
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +0000153 .name = "connbytes",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200154 .version = XTABLES_VERSION,
Yasuyuki KOZAKAI6aac5002007-08-04 08:25:43 +0000155 .size = XT_ALIGN(sizeof(struct xt_connbytes_info)),
156 .userspacesize = XT_ALIGN(sizeof(struct xt_connbytes_info)),
Jan Engelhardt181dead2007-10-04 16:27:07 +0000157 .help = connbytes_help,
Jan Engelhardt181dead2007-10-04 16:27:07 +0000158 .print = connbytes_print,
159 .save = connbytes_save,
Jan Engelhardt09631dc2011-03-06 17:19:10 +0100160 .x6_parse = connbytes_parse,
161 .x6_options = connbytes_opts,
Martin Devera766113a2003-06-19 12:23:37 +0000162};
163
164void _init(void)
165{
Jan Engelhardt181dead2007-10-04 16:27:07 +0000166 xtables_register_match(&connbytes_match);
Martin Devera766113a2003-06-19 12:23:37 +0000167}