1 /* Shared library add-on to iptables to add byte tracking support. */
8 #include <linux/netfilter/nf_conntrack_common.h>
9 #include <linux/netfilter_ipv6/ip6_tables.h>
10 #include <linux/netfilter_ipv4/ipt_connbytes.h>
12 /* Function which prints out usage message. */
17 "connbytes v%s options:\n"
18 " [!] --connbytes from:[to]\n"
19 " --connbytes-dir [original, reply, both]\n"
20 " --connbytes-mode [packets, bytes, avgpkt]\n"
21 "\n", IPTABLES_VERSION
);
24 static struct option opts
[] = {
25 { "connbytes", 1, 0, '1' },
26 { "connbytes-dir", 1, 0, '2' },
27 { "connbytes-mode", 1, 0, '3' },
32 parse_range(const char *arg
, struct ipt_connbytes_info
*si
)
36 si
->count
.from
= strtoul(arg
,&colon
,10);
38 exit_error(PARAMETER_PROBLEM
, "Bad range `%s'", arg
);
39 si
->count
.to
= strtoul(colon
+1,&p
,10);
41 /* second number omited */
42 si
->count
.to
= 0xffffffff;
44 if (si
->count
.from
> si
->count
.to
)
45 exit_error(PARAMETER_PROBLEM
, "%llu should be less than %llu",
46 si
->count
.from
, si
->count
.to
);
49 /* Function which parses command options; returns true if it
52 parse(int c
, char **argv
, int invert
, unsigned int *flags
,
53 const struct ip6t_entry
*entry
,
54 unsigned int *nfcache
,
55 struct ip6t_entry_match
**match
)
57 struct ipt_connbytes_info
*sinfo
= (struct ipt_connbytes_info
*)(*match
)->data
;
62 if (check_inverse(optarg
, &invert
, &optind
, 0))
65 parse_range(argv
[optind
-1], sinfo
);
67 i
= sinfo
->count
.from
;
68 sinfo
->count
.from
= sinfo
->count
.to
;
74 if (!strcmp(optarg
, "original"))
75 sinfo
->direction
= IPT_CONNBYTES_DIR_ORIGINAL
;
76 else if (!strcmp(optarg
, "reply"))
77 sinfo
->direction
= IPT_CONNBYTES_DIR_REPLY
;
78 else if (!strcmp(optarg
, "both"))
79 sinfo
->direction
= IPT_CONNBYTES_DIR_BOTH
;
81 exit_error(PARAMETER_PROBLEM
,
82 "Unknown --connbytes-dir `%s'", optarg
);
87 if (!strcmp(optarg
, "packets"))
88 sinfo
->what
= IPT_CONNBYTES_PKTS
;
89 else if (!strcmp(optarg
, "bytes"))
90 sinfo
->what
= IPT_CONNBYTES_BYTES
;
91 else if (!strcmp(optarg
, "avgpkt"))
92 sinfo
->what
= IPT_CONNBYTES_AVGPKT
;
94 exit_error(PARAMETER_PROBLEM
,
95 "Unknown --connbytes-mode `%s'", optarg
);
105 static void final_check(unsigned int flags
)
108 exit_error(PARAMETER_PROBLEM
, "You must specify `--connbytes'"
109 "`--connbytes-dir' and `--connbytes-mode'");
112 static void print_mode(struct ipt_connbytes_info
*sinfo
)
114 switch (sinfo
->what
) {
115 case IPT_CONNBYTES_PKTS
:
116 fputs("packets ", stdout
);
118 case IPT_CONNBYTES_BYTES
:
119 fputs("bytes ", stdout
);
121 case IPT_CONNBYTES_AVGPKT
:
122 fputs("avgpkt ", stdout
);
125 fputs("unknown ", stdout
);
130 static void print_direction(struct ipt_connbytes_info
*sinfo
)
132 switch (sinfo
->direction
) {
133 case IPT_CONNBYTES_DIR_ORIGINAL
:
134 fputs("original ", stdout
);
136 case IPT_CONNBYTES_DIR_REPLY
:
137 fputs("reply ", stdout
);
139 case IPT_CONNBYTES_DIR_BOTH
:
140 fputs("both ", stdout
);
143 fputs("unknown ", stdout
);
148 /* Prints out the matchinfo. */
150 print(const struct ip6t_ip6
*ip
,
151 const struct ip6t_entry_match
*match
,
154 struct ipt_connbytes_info
*sinfo
= (struct ipt_connbytes_info
*)match
->data
;
156 if (sinfo
->count
.from
> sinfo
->count
.to
)
157 printf("connbytes ! %llu:%llu ", sinfo
->count
.to
,
160 printf("connbytes %llu:%llu ",sinfo
->count
.from
,
164 fputs("direction ", stdout
);
165 print_direction(sinfo
);
168 /* Saves the matchinfo in parsable form to stdout. */
169 static void save(const struct ip6t_ip6
*ip
, const struct ip6t_entry_match
*match
)
171 struct ipt_connbytes_info
*sinfo
= (struct ipt_connbytes_info
*)match
->data
;
173 if (sinfo
->count
.from
> sinfo
->count
.to
)
174 printf("! --connbytes %llu:%llu ", sinfo
->count
.to
,
177 printf("--connbytes %llu:%llu ", sinfo
->count
.from
,
180 fputs("--connbytes-mode ", stdout
);
183 fputs("--connbytes-dir ", stdout
);
184 print_direction(sinfo
);
187 static struct ip6tables_match state
= {
190 .version
= IPTABLES_VERSION
,
191 .size
= IP6T_ALIGN(sizeof(struct ipt_connbytes_info
)),
192 .userspacesize
= IP6T_ALIGN(sizeof(struct ipt_connbytes_info
)),
195 .final_check
= &final_check
,
203 register_match6(&state
);