15caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall/* 25caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall * "quota2" match extension for iptables 35caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall * Sam Johnston <samj [at] samj net> 45caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall * Jan Engelhardt <jengelh [at] medozas de>, 2008 55caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall * 65caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall * This program is free software; you can redistribute it and/or 75caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall * modify it under the terms of the GNU General Public License; either 85caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall * version 2 of the License, or any later version, as published by the 95caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall * Free Software Foundation. 105caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall */ 115caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall#include <getopt.h> 125caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall#include <stddef.h> 135caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall#include <stdio.h> 145caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall#include <stdlib.h> 155caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall#include <string.h> 165caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall#include <xtables.h> 1736574090407b87fbb72c752698c805ef87046ae8JP Abgrall#include <linux/netfilter/xt_quota2.h> 185caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall 195caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrallenum { 205caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall FL_QUOTA = 1 << 0, 215caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall FL_NAME = 1 << 1, 225caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall FL_GROW = 1 << 2, 235caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall FL_PACKET = 1 << 3, 245caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall FL_NO_CHANGE = 1 << 4, 255caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall}; 265caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall 2736574090407b87fbb72c752698c805ef87046ae8JP Abgrallenum { 2836574090407b87fbb72c752698c805ef87046ae8JP Abgrall O_QUOTA = 0, 2936574090407b87fbb72c752698c805ef87046ae8JP Abgrall O_NAME, 3036574090407b87fbb72c752698c805ef87046ae8JP Abgrall O_GROW, 3136574090407b87fbb72c752698c805ef87046ae8JP Abgrall O_PACKET, 3236574090407b87fbb72c752698c805ef87046ae8JP Abgrall O_NO_CHANGE, 3336574090407b87fbb72c752698c805ef87046ae8JP Abgrall}; 3436574090407b87fbb72c752698c805ef87046ae8JP Abgrall 3536574090407b87fbb72c752698c805ef87046ae8JP Abgrall 3636574090407b87fbb72c752698c805ef87046ae8JP Abgrallstatic const struct xt_option_entry quota_mt2_opts[] = { 3736574090407b87fbb72c752698c805ef87046ae8JP Abgrall {.name = "grow", .id = O_GROW, .type = XTTYPE_NONE}, 3836574090407b87fbb72c752698c805ef87046ae8JP Abgrall {.name = "no-change", .id = O_NO_CHANGE, .type = XTTYPE_NONE}, 3936574090407b87fbb72c752698c805ef87046ae8JP Abgrall {.name = "name", .id = O_NAME, .type = XTTYPE_STRING, 4036574090407b87fbb72c752698c805ef87046ae8JP Abgrall .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_quota_mtinfo2, name)}, 4136574090407b87fbb72c752698c805ef87046ae8JP Abgrall {.name = "quota", .id = O_QUOTA, .type = XTTYPE_UINT64, 4236574090407b87fbb72c752698c805ef87046ae8JP Abgrall .flags = XTOPT_INVERT | XTOPT_PUT, 4336574090407b87fbb72c752698c805ef87046ae8JP Abgrall XTOPT_POINTER(struct xt_quota_mtinfo2, quota)}, 4436574090407b87fbb72c752698c805ef87046ae8JP Abgrall {.name = "packets", .id = O_PACKET, .type = XTTYPE_NONE}, 4536574090407b87fbb72c752698c805ef87046ae8JP Abgrall XTOPT_TABLEEND, 465caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall}; 475caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall 485caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrallstatic void quota_mt2_help(void) 495caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall{ 505caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf( 515caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall "quota match options:\n" 525caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall " --grow provide an increasing counter\n" 535caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall " --no-change never change counter/quota value for matching packets\n" 545caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall " --name name name for the file in sysfs\n" 555caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall "[!] --quota quota initial quota (bytes or packets)\n" 565caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall " --packets count packets instead of bytes\n" 575caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall ); 585caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall} 595caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall 6036574090407b87fbb72c752698c805ef87046ae8JP Abgrallstatic void quota_mt2_parse(struct xt_option_call *cb) 615caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall{ 6236574090407b87fbb72c752698c805ef87046ae8JP Abgrall struct xt_quota_mtinfo2 *info = cb->data; 635caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall 6436574090407b87fbb72c752698c805ef87046ae8JP Abgrall xtables_option_parse(cb); 6536574090407b87fbb72c752698c805ef87046ae8JP Abgrall switch (cb->entry->id) { 6636574090407b87fbb72c752698c805ef87046ae8JP Abgrall case O_GROW: 675caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall info->flags |= XT_QUOTA_GROW; 6836574090407b87fbb72c752698c805ef87046ae8JP Abgrall break; 6936574090407b87fbb72c752698c805ef87046ae8JP Abgrall case O_NO_CHANGE: 705caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall info->flags |= XT_QUOTA_NO_CHANGE; 7136574090407b87fbb72c752698c805ef87046ae8JP Abgrall break; 7236574090407b87fbb72c752698c805ef87046ae8JP Abgrall case O_NAME: 7336574090407b87fbb72c752698c805ef87046ae8JP Abgrall break; 7436574090407b87fbb72c752698c805ef87046ae8JP Abgrall case O_PACKET: 755caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall info->flags |= XT_QUOTA_PACKET; 7636574090407b87fbb72c752698c805ef87046ae8JP Abgrall break; 7736574090407b87fbb72c752698c805ef87046ae8JP Abgrall case O_QUOTA: 7892556c7047257284cc8659c769b800219cff47a5JP Abgrall if (cb->invert) 7992556c7047257284cc8659c769b800219cff47a5JP Abgrall info->flags |= XT_QUOTA_INVERT; 8036574090407b87fbb72c752698c805ef87046ae8JP Abgrall break; 815caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall } 825caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall} 835caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall 845caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrallstatic void 855caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrallquota_mt2_save(const void *ip, const struct xt_entry_match *match) 865caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall{ 875caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall const struct xt_quota_mtinfo2 *q = (void *)match->data; 885caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall 895caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall if (q->flags & XT_QUOTA_INVERT) 905caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf(" !"); 915caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall if (q->flags & XT_QUOTA_GROW) 925caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf(" --grow "); 935caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall if (q->flags & XT_QUOTA_NO_CHANGE) 945caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf(" --no-change "); 955caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall if (q->flags & XT_QUOTA_PACKET) 965caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf(" --packets "); 975caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall if (*q->name != '\0') 985caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf(" --name %s ", q->name); 995caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf(" --quota %llu ", (unsigned long long)q->quota); 1005caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall} 1015caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall 1025caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrallstatic void quota_mt2_print(const void *ip, const struct xt_entry_match *match, 1035caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall int numeric) 1045caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall{ 1055caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall const struct xt_quota_mtinfo2 *q = (const void *)match->data; 1065caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall 1075caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall if (q->flags & XT_QUOTA_INVERT) 1085caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf(" !"); 1095caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall if (q->flags & XT_QUOTA_GROW) 1105caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf(" counter"); 1115caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall else 1125caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf(" quota"); 1135caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall if (*q->name != '\0') 1145caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf(" %s:", q->name); 1155caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf(" %llu ", (unsigned long long)q->quota); 1165caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall if (q->flags & XT_QUOTA_PACKET) 1175caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf("packets "); 1185caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall else 1195caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf("bytes "); 1205caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall if (q->flags & XT_QUOTA_NO_CHANGE) 1215caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall printf("(no-change mode) "); 1225caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall} 1235caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall 1245caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrallstatic struct xtables_match quota_mt2_reg = { 1255caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall .family = NFPROTO_UNSPEC, 1265caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall .revision = 3, 1275caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall .name = "quota2", 1285caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall .version = XTABLES_VERSION, 1295caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall .size = XT_ALIGN(sizeof (struct xt_quota_mtinfo2)), 1305caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall .userspacesize = offsetof(struct xt_quota_mtinfo2, quota), 1315caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall .help = quota_mt2_help, 13236574090407b87fbb72c752698c805ef87046ae8JP Abgrall .x6_parse = quota_mt2_parse, 1335caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall .print = quota_mt2_print, 1345caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall .save = quota_mt2_save, 13536574090407b87fbb72c752698c805ef87046ae8JP Abgrall .x6_options = quota_mt2_opts, 1365caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall}; 1375caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall 13836574090407b87fbb72c752698c805ef87046ae8JP Abgrallvoid _init(void) 1395caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall{ 1405caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall xtables_register_match("a_mt2_reg); 1415caed2aebebf7c72dfa982f247ac35ec67a1b852JP Abgrall} 142