libxt_quota2.c revision 5caed2aebebf7c72dfa982f247ac35ec67a1b852
1/* 2 * "quota2" match extension for iptables 3 * Sam Johnston <samj [at] samj net> 4 * Jan Engelhardt <jengelh [at] medozas de>, 2008 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License; either 8 * version 2 of the License, or any later version, as published by the 9 * Free Software Foundation. 10 */ 11#include <getopt.h> 12#include <stddef.h> 13#include <stdio.h> 14#include <stdlib.h> 15#include <string.h> 16#include <xtables.h> 17#include "xt_quota2.h" 18#include "compat_user.h" 19 20enum { 21 FL_QUOTA = 1 << 0, 22 FL_NAME = 1 << 1, 23 FL_GROW = 1 << 2, 24 FL_PACKET = 1 << 3, 25 FL_NO_CHANGE = 1 << 4, 26}; 27 28static const struct option quota_mt2_opts[] = { 29 {.name = "grow", .has_arg = false, .val = 'g'}, 30 {.name = "no-change", .has_arg = false, .val = 'c'}, 31 {.name = "name", .has_arg = true, .val = 'n'}, 32 {.name = "quota", .has_arg = true, .val = 'q'}, 33 {.name = "packets", .has_arg = false, .val = 'p'}, 34 {NULL}, 35}; 36 37static void quota_mt2_help(void) 38{ 39 printf( 40 "quota match options:\n" 41 " --grow provide an increasing counter\n" 42 " --no-change never change counter/quota value for matching packets\n" 43 " --name name name for the file in sysfs\n" 44 "[!] --quota quota initial quota (bytes or packets)\n" 45 " --packets count packets instead of bytes\n" 46 ); 47} 48 49static int 50quota_mt2_parse(int c, char **argv, int invert, unsigned int *flags, 51 const void *entry, struct xt_entry_match **match) 52{ 53 struct xt_quota_mtinfo2 *info = (void *)(*match)->data; 54 char *end; 55 56 switch (c) { 57 case 'g': 58 xtables_param_act(XTF_ONLY_ONCE, "quota", "--grow", *flags & FL_GROW); 59 xtables_param_act(XTF_NO_INVERT, "quota", "--grow", invert); 60 info->flags |= XT_QUOTA_GROW; 61 *flags |= FL_GROW; 62 return true; 63 case 'c': /* no-change */ 64 xtables_param_act(XTF_ONLY_ONCE, "quota", "--no-change", *flags & FL_NO_CHANGE); 65 xtables_param_act(XTF_NO_INVERT, "quota", "--no-change", invert); 66 info->flags |= XT_QUOTA_NO_CHANGE; 67 *flags |= FL_NO_CHANGE; 68 return true; 69 case 'n': 70 /* zero termination done on behalf of the kernel module */ 71 xtables_param_act(XTF_ONLY_ONCE, "quota", "--name", *flags & FL_NAME); 72 xtables_param_act(XTF_NO_INVERT, "quota", "--name", invert); 73 strncpy(info->name, optarg, sizeof(info->name)); 74 *flags |= FL_NAME; 75 return true; 76 case 'p': 77 xtables_param_act(XTF_ONLY_ONCE, "quota", "--packets", *flags & FL_PACKET); 78 xtables_param_act(XTF_NO_INVERT, "quota", "--packets", invert); 79 info->flags |= XT_QUOTA_PACKET; 80 *flags |= FL_PACKET; 81 return true; 82 case 'q': 83 xtables_param_act(XTF_ONLY_ONCE, "quota", "--quota", *flags & FL_QUOTA); 84 if (invert) 85 info->flags |= XT_QUOTA_INVERT; 86 info->quota = strtoull(optarg, &end, 0); 87 if (*end != '\0') 88 xtables_error(PARAMETER_PROBLEM, "quota match: " 89 "invalid value for --quota"); 90 *flags |= FL_QUOTA; 91 return true; 92 } 93 return false; 94} 95 96static void 97quota_mt2_save(const void *ip, const struct xt_entry_match *match) 98{ 99 const struct xt_quota_mtinfo2 *q = (void *)match->data; 100 101 if (q->flags & XT_QUOTA_INVERT) 102 printf(" !"); 103 if (q->flags & XT_QUOTA_GROW) 104 printf(" --grow "); 105 if (q->flags & XT_QUOTA_NO_CHANGE) 106 printf(" --no-change "); 107 if (q->flags & XT_QUOTA_PACKET) 108 printf(" --packets "); 109 if (*q->name != '\0') 110 printf(" --name %s ", q->name); 111 printf(" --quota %llu ", (unsigned long long)q->quota); 112} 113 114static void quota_mt2_print(const void *ip, const struct xt_entry_match *match, 115 int numeric) 116{ 117 const struct xt_quota_mtinfo2 *q = (const void *)match->data; 118 119 if (q->flags & XT_QUOTA_INVERT) 120 printf(" !"); 121 if (q->flags & XT_QUOTA_GROW) 122 printf(" counter"); 123 else 124 printf(" quota"); 125 if (*q->name != '\0') 126 printf(" %s:", q->name); 127 printf(" %llu ", (unsigned long long)q->quota); 128 if (q->flags & XT_QUOTA_PACKET) 129 printf("packets "); 130 else 131 printf("bytes "); 132 if (q->flags & XT_QUOTA_NO_CHANGE) 133 printf("(no-change mode) "); 134} 135 136static struct xtables_match quota_mt2_reg = { 137 .family = NFPROTO_UNSPEC, 138 .revision = 3, 139 .name = "quota2", 140 .version = XTABLES_VERSION, 141 .size = XT_ALIGN(sizeof (struct xt_quota_mtinfo2)), 142 .userspacesize = offsetof(struct xt_quota_mtinfo2, quota), 143 .help = quota_mt2_help, 144 .parse = quota_mt2_parse, 145 .print = quota_mt2_print, 146 .save = quota_mt2_save, 147 .extra_opts = quota_mt2_opts, 148}; 149 150static __attribute__((constructor)) void quota2_mt_ldr(void) 151{ 152 xtables_register_match("a_mt2_reg); 153} 154