1 /* Shared library add-on to iptables to add byte tracking support. */
8 #include <linux/netfilter/nf_conntrack_common.h>
9 #include <linux/netfilter/xt_connbytes.h>
11 static void connbytes_help(void)
14 "connbytes match options:\n"
15 " [!] --connbytes from:[to]\n"
16 " --connbytes-dir [original, reply, both]\n"
17 " --connbytes-mode [packets, bytes, avgpkt]\n");
20 static const struct option connbytes_opts
[] = {
21 { "connbytes", 1, NULL
, '1' },
22 { "connbytes-dir", 1, NULL
, '2' },
23 { "connbytes-mode", 1, NULL
, '3' },
28 parse_range(const char *arg
, struct xt_connbytes_info
*si
)
32 si
->count
.from
= strtoul(arg
,&colon
,10);
34 xtables_error(PARAMETER_PROBLEM
, "Bad range \"%s\"", arg
);
35 si
->count
.to
= strtoul(colon
+1,&p
,10);
37 /* second number omited */
38 si
->count
.to
= 0xffffffff;
40 if (si
->count
.from
> si
->count
.to
)
41 xtables_error(PARAMETER_PROBLEM
, "%llu should be less than %llu",
42 (unsigned long long)si
->count
.from
,
43 (unsigned long long)si
->count
.to
);
47 connbytes_parse(int c
, char **argv
, int invert
, unsigned int *flags
,
48 const void *entry
, struct xt_entry_match
**match
)
50 struct xt_connbytes_info
*sinfo
= (struct xt_connbytes_info
*)(*match
)->data
;
55 if (xtables_check_inverse(optarg
, &invert
, &optind
, 0))
58 parse_range(argv
[optind
-1], sinfo
);
60 i
= sinfo
->count
.from
;
61 sinfo
->count
.from
= sinfo
->count
.to
;
67 if (!strcmp(optarg
, "original"))
68 sinfo
->direction
= XT_CONNBYTES_DIR_ORIGINAL
;
69 else if (!strcmp(optarg
, "reply"))
70 sinfo
->direction
= XT_CONNBYTES_DIR_REPLY
;
71 else if (!strcmp(optarg
, "both"))
72 sinfo
->direction
= XT_CONNBYTES_DIR_BOTH
;
74 xtables_error(PARAMETER_PROBLEM
,
75 "Unknown --connbytes-dir `%s'", optarg
);
80 if (!strcmp(optarg
, "packets"))
81 sinfo
->what
= XT_CONNBYTES_PKTS
;
82 else if (!strcmp(optarg
, "bytes"))
83 sinfo
->what
= XT_CONNBYTES_BYTES
;
84 else if (!strcmp(optarg
, "avgpkt"))
85 sinfo
->what
= XT_CONNBYTES_AVGPKT
;
87 xtables_error(PARAMETER_PROBLEM
,
88 "Unknown --connbytes-mode `%s'", optarg
);
98 static void connbytes_check(unsigned int flags
)
101 xtables_error(PARAMETER_PROBLEM
, "You must specify `--connbytes'"
102 "`--connbytes-dir' and `--connbytes-mode'");
105 static void print_mode(const struct xt_connbytes_info
*sinfo
)
107 switch (sinfo
->what
) {
108 case XT_CONNBYTES_PKTS
:
109 fputs("packets ", stdout
);
111 case XT_CONNBYTES_BYTES
:
112 fputs("bytes ", stdout
);
114 case XT_CONNBYTES_AVGPKT
:
115 fputs("avgpkt ", stdout
);
118 fputs("unknown ", stdout
);
123 static void print_direction(const struct xt_connbytes_info
*sinfo
)
125 switch (sinfo
->direction
) {
126 case XT_CONNBYTES_DIR_ORIGINAL
:
127 fputs("original ", stdout
);
129 case XT_CONNBYTES_DIR_REPLY
:
130 fputs("reply ", stdout
);
132 case XT_CONNBYTES_DIR_BOTH
:
133 fputs("both ", stdout
);
136 fputs("unknown ", stdout
);
142 connbytes_print(const void *ip
, const struct xt_entry_match
*match
, int numeric
)
144 const struct xt_connbytes_info
*sinfo
= (const void *)match
->data
;
146 if (sinfo
->count
.from
> sinfo
->count
.to
)
147 printf("connbytes ! %llu:%llu ",
148 (unsigned long long)sinfo
->count
.to
,
149 (unsigned long long)sinfo
->count
.from
);
151 printf("connbytes %llu:%llu ",
152 (unsigned long long)sinfo
->count
.from
,
153 (unsigned long long)sinfo
->count
.to
);
155 fputs("connbytes mode ", stdout
);
158 fputs("connbytes direction ", stdout
);
159 print_direction(sinfo
);
162 static void connbytes_save(const void *ip
, const struct xt_entry_match
*match
)
164 const struct xt_connbytes_info
*sinfo
= (const void *)match
->data
;
166 if (sinfo
->count
.from
> sinfo
->count
.to
)
167 printf("! --connbytes %llu:%llu ",
168 (unsigned long long)sinfo
->count
.to
,
169 (unsigned long long)sinfo
->count
.from
);
171 printf("--connbytes %llu:%llu ",
172 (unsigned long long)sinfo
->count
.from
,
173 (unsigned long long)sinfo
->count
.to
);
175 fputs("--connbytes-mode ", stdout
);
178 fputs("--connbytes-dir ", stdout
);
179 print_direction(sinfo
);
182 static struct xtables_match connbytes_match
= {
183 .family
= NFPROTO_IPV4
,
185 .version
= XTABLES_VERSION
,
186 .size
= XT_ALIGN(sizeof(struct xt_connbytes_info
)),
187 .userspacesize
= XT_ALIGN(sizeof(struct xt_connbytes_info
)),
188 .help
= connbytes_help
,
189 .parse
= connbytes_parse
,
190 .final_check
= connbytes_check
,
191 .print
= connbytes_print
,
192 .save
= connbytes_save
,
193 .extra_opts
= connbytes_opts
,
196 static struct xtables_match connbytes_match6
= {
197 .family
= NFPROTO_IPV6
,
199 .version
= XTABLES_VERSION
,
200 .size
= XT_ALIGN(sizeof(struct xt_connbytes_info
)),
201 .userspacesize
= XT_ALIGN(sizeof(struct xt_connbytes_info
)),
202 .help
= connbytes_help
,
203 .parse
= connbytes_parse
,
204 .final_check
= connbytes_check
,
205 .print
= connbytes_print
,
206 .save
= connbytes_save
,
207 .extra_opts
= connbytes_opts
,
212 xtables_register_match(&connbytes_match
);
213 xtables_register_match(&connbytes_match6
);