Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 1 | #include <stdio.h> |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 2 | #include <string.h> |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 3 | #include <xtables.h> |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 4 | #include <linux/netfilter/xt_connbytes.h> |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 5 | |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 6 | enum { |
| 7 | O_CONNBYTES = 0, |
| 8 | O_CONNBYTES_DIR, |
| 9 | O_CONNBYTES_MODE, |
| 10 | }; |
| 11 | |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 12 | static void connbytes_help(void) |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 13 | { |
| 14 | printf( |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 15 | "connbytes match options:\n" |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 16 | " [!] --connbytes from:[to]\n" |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 17 | " --connbytes-dir [original, reply, both]\n" |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 18 | " --connbytes-mode [packets, bytes, avgpkt]\n"); |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 19 | } |
| 20 | |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 21 | static 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 Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 29 | }; |
| 30 | |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 31 | static void connbytes_parse(struct xt_option_call *cb) |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 32 | { |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 33 | struct xt_connbytes_info *sinfo = cb->data; |
| 34 | unsigned long long i; |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 35 | |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 36 | 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 Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 44 | i = sinfo->count.from; |
Harald Welte | 7dc57e2 | 2004-11-18 22:59:36 +0000 | [diff] [blame] | 45 | sinfo->count.from = sinfo->count.to; |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 46 | sinfo->count.to = i; |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 47 | } |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 48 | break; |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 49 | case O_CONNBYTES_DIR: |
| 50 | if (strcmp(cb->arg, "original") == 0) |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 51 | sinfo->direction = XT_CONNBYTES_DIR_ORIGINAL; |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 52 | else if (strcmp(cb->arg, "reply") == 0) |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 53 | sinfo->direction = XT_CONNBYTES_DIR_REPLY; |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 54 | else if (strcmp(cb->arg, "both") == 0) |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 55 | sinfo->direction = XT_CONNBYTES_DIR_BOTH; |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 56 | else |
Jan Engelhardt | 1829ed4 | 2009-02-21 03:29:44 +0100 | [diff] [blame] | 57 | xtables_error(PARAMETER_PROBLEM, |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 58 | "Unknown --connbytes-dir `%s'", cb->arg); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 59 | break; |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 60 | case O_CONNBYTES_MODE: |
| 61 | if (strcmp(cb->arg, "packets") == 0) |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 62 | sinfo->what = XT_CONNBYTES_PKTS; |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 63 | else if (strcmp(cb->arg, "bytes") == 0) |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 64 | sinfo->what = XT_CONNBYTES_BYTES; |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 65 | else if (strcmp(cb->arg, "avgpkt") == 0) |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 66 | sinfo->what = XT_CONNBYTES_AVGPKT; |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 67 | else |
Jan Engelhardt | 1829ed4 | 2009-02-21 03:29:44 +0100 | [diff] [blame] | 68 | xtables_error(PARAMETER_PROBLEM, |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 69 | "Unknown --connbytes-mode `%s'", cb->arg); |
Piotrek Kaczmarek | 1c0f236 | 2005-04-24 16:19:51 +0000 | [diff] [blame] | 70 | break; |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 71 | } |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 72 | } |
| 73 | |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 74 | static void print_mode(const struct xt_connbytes_info *sinfo) |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 75 | { |
| 76 | switch (sinfo->what) { |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 77 | case XT_CONNBYTES_PKTS: |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 78 | fputs(" packets", stdout); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 79 | break; |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 80 | case XT_CONNBYTES_BYTES: |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 81 | fputs(" bytes", stdout); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 82 | break; |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 83 | case XT_CONNBYTES_AVGPKT: |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 84 | fputs(" avgpkt", stdout); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 85 | break; |
Harald Welte | 7dc57e2 | 2004-11-18 22:59:36 +0000 | [diff] [blame] | 86 | default: |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 87 | fputs(" unknown", stdout); |
Harald Welte | 7dc57e2 | 2004-11-18 22:59:36 +0000 | [diff] [blame] | 88 | break; |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 89 | } |
| 90 | } |
| 91 | |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 92 | static void print_direction(const struct xt_connbytes_info *sinfo) |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 93 | { |
| 94 | switch (sinfo->direction) { |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 95 | case XT_CONNBYTES_DIR_ORIGINAL: |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 96 | fputs(" original", stdout); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 97 | break; |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 98 | case XT_CONNBYTES_DIR_REPLY: |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 99 | fputs(" reply", stdout); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 100 | break; |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 101 | case XT_CONNBYTES_DIR_BOTH: |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 102 | fputs(" both", stdout); |
Harald Welte | 7dc57e2 | 2004-11-18 22:59:36 +0000 | [diff] [blame] | 103 | break; |
| 104 | default: |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 105 | fputs(" unknown", stdout); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 106 | break; |
| 107 | } |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 108 | } |
| 109 | |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 110 | static void |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 111 | connbytes_print(const void *ip, const struct xt_entry_match *match, int numeric) |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 112 | { |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 113 | const struct xt_connbytes_info *sinfo = (const void *)match->data; |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 114 | |
Harald Welte | 7dc57e2 | 2004-11-18 22:59:36 +0000 | [diff] [blame] | 115 | if (sinfo->count.from > sinfo->count.to) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 116 | printf(" connbytes ! %llu:%llu", |
Patrick McHardy | c329d6a | 2007-09-05 14:19:23 +0000 | [diff] [blame] | 117 | (unsigned long long)sinfo->count.to, |
| 118 | (unsigned long long)sinfo->count.from); |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 119 | else |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 120 | printf(" connbytes %llu:%llu", |
Patrick McHardy | c329d6a | 2007-09-05 14:19:23 +0000 | [diff] [blame] | 121 | (unsigned long long)sinfo->count.from, |
| 122 | (unsigned long long)sinfo->count.to); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 123 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 124 | fputs(" connbytes mode", stdout); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 125 | print_mode(sinfo); |
| 126 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 127 | fputs(" connbytes direction", stdout); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 128 | print_direction(sinfo); |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 129 | } |
| 130 | |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 131 | static void connbytes_save(const void *ip, const struct xt_entry_match *match) |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 132 | { |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 133 | const struct xt_connbytes_info *sinfo = (const void *)match->data; |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 134 | |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 135 | if (sinfo->count.from > sinfo->count.to) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 136 | printf(" ! --connbytes %llu:%llu", |
Patrick McHardy | c329d6a | 2007-09-05 14:19:23 +0000 | [diff] [blame] | 137 | (unsigned long long)sinfo->count.to, |
| 138 | (unsigned long long)sinfo->count.from); |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 139 | else |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 140 | printf(" --connbytes %llu:%llu", |
Patrick McHardy | c329d6a | 2007-09-05 14:19:23 +0000 | [diff] [blame] | 141 | (unsigned long long)sinfo->count.from, |
| 142 | (unsigned long long)sinfo->count.to); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 143 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 144 | fputs(" --connbytes-mode", stdout); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 145 | print_mode(sinfo); |
| 146 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 147 | fputs(" --connbytes-dir", stdout); |
Harald Welte | 93f4a3d | 2004-11-18 22:50:01 +0000 | [diff] [blame] | 148 | print_direction(sinfo); |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 149 | } |
| 150 | |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 151 | static struct xtables_match connbytes_match = { |
Jan Engelhardt | c5e8573 | 2009-06-12 20:55:44 +0200 | [diff] [blame] | 152 | .family = NFPROTO_UNSPEC, |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 153 | .name = "connbytes", |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 154 | .version = XTABLES_VERSION, |
Yasuyuki KOZAKAI | 6aac500 | 2007-08-04 08:25:43 +0000 | [diff] [blame] | 155 | .size = XT_ALIGN(sizeof(struct xt_connbytes_info)), |
| 156 | .userspacesize = XT_ALIGN(sizeof(struct xt_connbytes_info)), |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 157 | .help = connbytes_help, |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 158 | .print = connbytes_print, |
| 159 | .save = connbytes_save, |
Jan Engelhardt | 09631dc | 2011-03-06 17:19:10 +0100 | [diff] [blame] | 160 | .x6_parse = connbytes_parse, |
| 161 | .x6_options = connbytes_opts, |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 162 | }; |
| 163 | |
| 164 | void _init(void) |
| 165 | { |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 166 | xtables_register_match(&connbytes_match); |
Martin Devera | 766113a | 2003-06-19 12:23:37 +0000 | [diff] [blame] | 167 | } |