• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *	"quota2" match extension for iptables
3  *	Sam Johnston <samj [at] samj net>
4  *	Jan Engelhardt, 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 <linux/netfilter/xt_quota2.h>
18 
19 enum {
20 	FL_QUOTA     = 1 << 0,
21 	FL_NAME      = 1 << 1,
22 	FL_GROW      = 1 << 2,
23 	FL_PACKET    = 1 << 3,
24 	FL_NO_CHANGE = 1 << 4,
25 };
26 
27 enum {
28 	O_QUOTA     = 0,
29 	O_GROW,
30 	O_PACKET,
31 	O_NO_CHANGE,
32 	O_NAME,
33 };
34 
35 
36 static const struct xt_option_entry quota_mt2_opts[] = {
37 	{.name = "grow", .id = O_GROW, .type = XTTYPE_NONE},
38 	{.name = "no-change", .id = O_NO_CHANGE, .type = XTTYPE_NONE},
39 	{.name = "name", .id = O_NAME, .type = XTTYPE_STRING,
40 	 .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_quota_mtinfo2, name)},
41 	{.name = "quota", .id = O_QUOTA, .type = XTTYPE_UINT64,
42 	 .flags = XTOPT_INVERT | XTOPT_PUT,
43 	 XTOPT_POINTER(struct xt_quota_mtinfo2, quota)},
44 	{.name = "packets", .id = O_PACKET, .type = XTTYPE_NONE},
45 	XTOPT_TABLEEND,
46 };
47 
quota_mt2_help(void)48 static void quota_mt2_help(void)
49 {
50 	printf(
51 	"quota match options:\n"
52 	"    --grow           provide an increasing counter\n"
53 	"    --no-change      never change counter/quota value for matching packets\n"
54 	"    --name name      name for the file in sysfs\n"
55 	"[!] --quota quota    initial quota (bytes or packets)\n"
56 	"    --packets        count packets instead of bytes\n"
57 	);
58 }
59 
quota_mt2_parse(struct xt_option_call * cb)60 static void quota_mt2_parse(struct xt_option_call *cb)
61 {
62 	struct xt_quota_mtinfo2 *info = cb->data;
63 
64 	xtables_option_parse(cb);
65 	if (cb->entry->id == O_NAME || (cb->entry->id == O_QUOTA && !cb->invert))
66 		return;
67 	else
68 		info->flags |= 1 << (int)cb->entry->id;
69 }
70 
71 static void
quota_mt2_save(const void * ip,const struct xt_entry_match * match)72 quota_mt2_save(const void *ip, const struct xt_entry_match *match)
73 {
74 	const struct xt_quota_mtinfo2 *q = (void *)match->data;
75 
76 	if (q->flags & XT_QUOTA_INVERT)
77 		printf(" !");
78 	if (q->flags & XT_QUOTA_GROW)
79 		printf(" --grow ");
80 	if (q->flags & XT_QUOTA_NO_CHANGE)
81 		printf(" --no-change ");
82 	if (q->flags & XT_QUOTA_PACKET)
83 		printf(" --packets ");
84 	if (*q->name != '\0')
85 		printf(" --name %s ", q->name);
86 	printf(" --quota %llu ", (unsigned long long)q->quota);
87 }
88 
quota_mt2_print(const void * ip,const struct xt_entry_match * match,int numeric)89 static void quota_mt2_print(const void *ip, const struct xt_entry_match *match,
90                             int numeric)
91 {
92 	printf(" -m quota");
93 	quota_mt2_save(ip, match);
94 }
95 
96 static struct xtables_match quota_mt2_reg = {
97 	.family        = NFPROTO_UNSPEC,
98 	.revision      = 3,
99 	.name          = "quota2",
100 	.version       = XTABLES_VERSION,
101 	.size          = XT_ALIGN(sizeof (struct xt_quota_mtinfo2)),
102 	.userspacesize = offsetof(struct xt_quota_mtinfo2, quota),
103 	.help          = quota_mt2_help,
104 	.x6_parse      = quota_mt2_parse,
105 	.print         = quota_mt2_print,
106 	.save          = quota_mt2_save,
107 	.x6_options    = quota_mt2_opts,
108 };
109 
_init(void)110 void _init(void)
111 {
112 	xtables_register_match(&quota_mt2_reg);
113 }
114