1766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera#include <stdio.h> 2766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera#include <string.h> 36aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI#include <xtables.h> 46aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI#include <linux/netfilter/xt_connbytes.h> 5766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera 609631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardtenum { 709631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt O_CONNBYTES = 0, 809631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt O_CONNBYTES_DIR, 909631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt O_CONNBYTES_MODE, 1009631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt}; 1109631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt 12181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void connbytes_help(void) 13766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera{ 14766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera printf( 158b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"connbytes match options:\n" 16766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera" [!] --connbytes from:[to]\n" 1793f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte" --connbytes-dir [original, reply, both]\n" 188b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt" --connbytes-mode [packets, bytes, avgpkt]\n"); 19766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera} 20766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera 2109631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardtstatic const struct xt_option_entry connbytes_opts[] = { 2209631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt {.name = "connbytes", .id = O_CONNBYTES, .type = XTTYPE_UINT64RC, 2309631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt .flags = XTOPT_MAND | XTOPT_INVERT}, 2409631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt {.name = "connbytes-dir", .id = O_CONNBYTES_DIR, .type = XTTYPE_STRING, 2509631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt .flags = XTOPT_MAND}, 2609631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt {.name = "connbytes-mode", .id = O_CONNBYTES_MODE, 2709631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt .type = XTTYPE_STRING, .flags = XTOPT_MAND}, 2809631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt XTOPT_TABLEEND, 29766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera}; 30766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera 3109631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardtstatic void connbytes_parse(struct xt_option_call *cb) 32766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera{ 3309631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt struct xt_connbytes_info *sinfo = cb->data; 3409631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt unsigned long long i; 3509631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt 3609631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt xtables_option_parse(cb); 3709631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt switch (cb->entry->id) { 3809631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt case O_CONNBYTES: 3909631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt sinfo->count.from = cb->val.u64_range[0]; 4009631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt sinfo->count.to = cb->val.u64_range[0]; 4109631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt if (cb->nvals == 2) 4209631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt sinfo->count.to = cb->val.u64_range[1]; 4309631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt if (cb->invert) { 4493f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte i = sinfo->count.from; 457dc57e2933f0d6eeefb7c6d937c56655e5d1c9eaHarald Welte sinfo->count.from = sinfo->count.to; 4693f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte sinfo->count.to = i; 47766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera } 48766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera break; 4909631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt case O_CONNBYTES_DIR: 5009631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt if (strcmp(cb->arg, "original") == 0) 516aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI sinfo->direction = XT_CONNBYTES_DIR_ORIGINAL; 5209631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt else if (strcmp(cb->arg, "reply") == 0) 536aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI sinfo->direction = XT_CONNBYTES_DIR_REPLY; 5409631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt else if (strcmp(cb->arg, "both") == 0) 556aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI sinfo->direction = XT_CONNBYTES_DIR_BOTH; 5693f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte else 571829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 5809631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt "Unknown --connbytes-dir `%s'", cb->arg); 5993f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte break; 6009631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt case O_CONNBYTES_MODE: 6109631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt if (strcmp(cb->arg, "packets") == 0) 626aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI sinfo->what = XT_CONNBYTES_PKTS; 6309631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt else if (strcmp(cb->arg, "bytes") == 0) 646aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI sinfo->what = XT_CONNBYTES_BYTES; 6509631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt else if (strcmp(cb->arg, "avgpkt") == 0) 666aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI sinfo->what = XT_CONNBYTES_AVGPKT; 6793f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte else 681829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 6909631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt "Unknown --connbytes-mode `%s'", cb->arg); 701c0f2365ab7a884cc3e1aaed487ecdc2109fe0e2Piotrek Kaczmarek break; 71766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera } 7293f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte} 7393f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte 7469f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardtstatic void print_mode(const struct xt_connbytes_info *sinfo) 7593f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte{ 7693f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte switch (sinfo->what) { 776aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI case XT_CONNBYTES_PKTS: 7873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(" packets", stdout); 7993f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte break; 806aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI case XT_CONNBYTES_BYTES: 8173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(" bytes", stdout); 8293f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte break; 836aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI case XT_CONNBYTES_AVGPKT: 8473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(" avgpkt", stdout); 8593f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte break; 867dc57e2933f0d6eeefb7c6d937c56655e5d1c9eaHarald Welte default: 8773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(" unknown", stdout); 887dc57e2933f0d6eeefb7c6d937c56655e5d1c9eaHarald Welte break; 8993f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte } 9093f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte} 9193f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte 9269f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardtstatic void print_direction(const struct xt_connbytes_info *sinfo) 9393f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte{ 9493f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte switch (sinfo->direction) { 956aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI case XT_CONNBYTES_DIR_ORIGINAL: 9673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(" original", stdout); 9793f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte break; 986aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI case XT_CONNBYTES_DIR_REPLY: 9973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(" reply", stdout); 10093f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte break; 1016aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI case XT_CONNBYTES_DIR_BOTH: 10273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(" both", stdout); 1037dc57e2933f0d6eeefb7c6d937c56655e5d1c9eaHarald Welte break; 1047dc57e2933f0d6eeefb7c6d937c56655e5d1c9eaHarald Welte default: 10573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(" unknown", stdout); 10693f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte break; 10793f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte } 108766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera} 109766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera 110766113ac7457f4e14014d2accd5344a03bb6854fMartin Deverastatic void 111181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtconnbytes_print(const void *ip, const struct xt_entry_match *match, int numeric) 112766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera{ 11369f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt const struct xt_connbytes_info *sinfo = (const void *)match->data; 114766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera 1157dc57e2933f0d6eeefb7c6d937c56655e5d1c9eaHarald Welte if (sinfo->count.from > sinfo->count.to) 11673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" connbytes ! %llu:%llu", 117c329d6a7085e3123f3d5ca98a8e0ab37edca2dccPatrick McHardy (unsigned long long)sinfo->count.to, 118c329d6a7085e3123f3d5ca98a8e0ab37edca2dccPatrick McHardy (unsigned long long)sinfo->count.from); 119766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera else 12073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" connbytes %llu:%llu", 121c329d6a7085e3123f3d5ca98a8e0ab37edca2dccPatrick McHardy (unsigned long long)sinfo->count.from, 122c329d6a7085e3123f3d5ca98a8e0ab37edca2dccPatrick McHardy (unsigned long long)sinfo->count.to); 12393f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte 12473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(" connbytes mode", stdout); 12593f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte print_mode(sinfo); 12693f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte 12773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(" connbytes direction", stdout); 12893f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte print_direction(sinfo); 129766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera} 130766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera 131181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void connbytes_save(const void *ip, const struct xt_entry_match *match) 132766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera{ 13369f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt const struct xt_connbytes_info *sinfo = (const void *)match->data; 134766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera 13593f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte if (sinfo->count.from > sinfo->count.to) 13673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" ! --connbytes %llu:%llu", 137c329d6a7085e3123f3d5ca98a8e0ab37edca2dccPatrick McHardy (unsigned long long)sinfo->count.to, 138c329d6a7085e3123f3d5ca98a8e0ab37edca2dccPatrick McHardy (unsigned long long)sinfo->count.from); 139766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera else 14073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" --connbytes %llu:%llu", 141c329d6a7085e3123f3d5ca98a8e0ab37edca2dccPatrick McHardy (unsigned long long)sinfo->count.from, 142c329d6a7085e3123f3d5ca98a8e0ab37edca2dccPatrick McHardy (unsigned long long)sinfo->count.to); 14393f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte 14473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(" --connbytes-mode", stdout); 14593f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte print_mode(sinfo); 14693f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte 14773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(" --connbytes-dir", stdout); 14893f4a3d72ad082ea42d67787d43e25343890dcdcHarald Welte print_direction(sinfo); 149766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera} 150766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera 151181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic struct xtables_match connbytes_match = { 152c5e85736c207f211d82d2878a5781f512327dfceJan Engelhardt .family = NFPROTO_UNSPEC, 1536aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI .name = "connbytes", 1548b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt .version = XTABLES_VERSION, 1556aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI .size = XT_ALIGN(sizeof(struct xt_connbytes_info)), 1566aac50010e50aa42b42089110c8cf4d80b224f14Yasuyuki KOZAKAI .userspacesize = XT_ALIGN(sizeof(struct xt_connbytes_info)), 157181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .help = connbytes_help, 158181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .print = connbytes_print, 159181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .save = connbytes_save, 16009631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt .x6_parse = connbytes_parse, 16109631dc60ce41bc484a42fcf4d4ddf7036820bd1Jan Engelhardt .x6_options = connbytes_opts, 162766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera}; 163766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera 164766113ac7457f4e14014d2accd5344a03bb6854fMartin Deveravoid _init(void) 165766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera{ 166181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt xtables_register_match(&connbytes_match); 167766113ac7457f4e14014d2accd5344a03bb6854fMartin Devera} 168