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);