1 /* Shared library add-on to iptables for ECN matching
3 * (C) 2002 by Harald Welte <laforge@gnumonks.org>
5 * This program is distributed under the terms of GNU GPL v2, 1991
7 * libipt_ecn.c borrowed heavily from libipt_dscp.c
16 #include <linux/netfilter_ipv4/ip_tables.h>
17 #include <linux/netfilter_ipv4/ipt_ecn.h>
19 static void help(void)
22 "ECN match v%s options\n"
23 "[!] --ecn-tcp-cwr Match CWR bit of TCP header\n"
24 "[!] --ecn-tcp-ece Match ECE bit of TCP header\n"
25 "[!] --ecn-ip-ect [0..3] Match ECN codepoint in IPv4 header\n",
29 static struct option opts
[] = {
30 { .name
= "ecn-tcp-cwr", .has_arg
= 0, .flag
= 0, .val
= 'F' },
31 { .name
= "ecn-tcp-ece", .has_arg
= 0, .flag
= 0, .val
= 'G' },
32 { .name
= "ecn-ip-ect", .has_arg
= 1, .flag
= 0, .val
= 'H' },
37 parse(int c
, char **argv
, int invert
, unsigned int *flags
,
38 const struct ipt_entry
*entry
,
39 unsigned int *nfcache
,
40 struct ipt_entry_match
**match
)
43 struct ipt_ecn_info
*einfo
44 = (struct ipt_ecn_info
*)(*match
)->data
;
48 if (*flags
& IPT_ECN_OP_MATCH_CWR
)
49 exit_error(PARAMETER_PROBLEM
,
50 "ECN match: can only use parameter ONCE!");
51 check_inverse(optarg
, &invert
, &optind
, 0);
52 einfo
->operation
|= IPT_ECN_OP_MATCH_CWR
;
54 einfo
->invert
|= IPT_ECN_OP_MATCH_CWR
;
55 *flags
|= IPT_ECN_OP_MATCH_CWR
;
59 if (*flags
& IPT_ECN_OP_MATCH_ECE
)
60 exit_error(PARAMETER_PROBLEM
,
61 "ECN match: can only use parameter ONCE!");
62 check_inverse(optarg
, &invert
, &optind
, 0);
63 einfo
->operation
|= IPT_ECN_OP_MATCH_ECE
;
65 einfo
->invert
|= IPT_ECN_OP_MATCH_ECE
;
66 *flags
|= IPT_ECN_OP_MATCH_ECE
;
70 if (*flags
& IPT_ECN_OP_MATCH_IP
)
71 exit_error(PARAMETER_PROBLEM
,
72 "ECN match: can only use parameter ONCE!");
73 check_inverse(optarg
, &invert
, &optind
, 0);
75 einfo
->invert
|= IPT_ECN_OP_MATCH_IP
;
76 *flags
|= IPT_ECN_OP_MATCH_IP
;
77 einfo
->operation
|= IPT_ECN_OP_MATCH_IP
;
78 if (string_to_number(optarg
, 0, 3, &result
))
79 exit_error(PARAMETER_PROBLEM
,
80 "ECN match: Value out of range");
81 einfo
->ip_ect
= result
;
91 final_check(unsigned int flags
)
94 exit_error(PARAMETER_PROBLEM
,
95 "ECN match: some option required");
98 /* Prints out the matchinfo. */
100 print(const struct ipt_ip
*ip
,
101 const struct ipt_entry_match
*match
,
104 const struct ipt_ecn_info
*einfo
=
105 (const struct ipt_ecn_info
*)match
->data
;
107 printf("ECN match ");
109 if (einfo
->operation
& IPT_ECN_OP_MATCH_ECE
) {
110 if (einfo
->invert
& IPT_ECN_OP_MATCH_ECE
)
115 if (einfo
->operation
& IPT_ECN_OP_MATCH_CWR
) {
116 if (einfo
->invert
& IPT_ECN_OP_MATCH_CWR
)
121 if (einfo
->operation
& IPT_ECN_OP_MATCH_IP
) {
122 if (einfo
->invert
& IPT_ECN_OP_MATCH_IP
)
124 printf("ECT=%d ", einfo
->ip_ect
);
128 /* Saves the union ipt_matchinfo in parsable form to stdout. */
130 save(const struct ipt_ip
*ip
, const struct ipt_entry_match
*match
)
132 const struct ipt_ecn_info
*einfo
=
133 (const struct ipt_ecn_info
*)match
->data
;
135 if (einfo
->operation
& IPT_ECN_OP_MATCH_ECE
) {
136 if (einfo
->invert
& IPT_ECN_OP_MATCH_ECE
)
138 printf("--ecn-tcp-ece ");
141 if (einfo
->operation
& IPT_ECN_OP_MATCH_CWR
) {
142 if (einfo
->invert
& IPT_ECN_OP_MATCH_CWR
)
144 printf("--ecn-tcp-cwr ");
147 if (einfo
->operation
& IPT_ECN_OP_MATCH_IP
) {
148 if (einfo
->invert
& IPT_ECN_OP_MATCH_IP
)
150 printf("--ecn-ip-ect %d", einfo
->ip_ect
);
155 struct iptables_match ecn
157 .version
= IPTABLES_VERSION
,
158 .size
= IPT_ALIGN(sizeof(struct ipt_ecn_info
)),
159 .userspacesize
= IPT_ALIGN(sizeof(struct ipt_ecn_info
)),
162 .final_check
= &final_check
,
170 register_match(&ecn
);