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 init(struct ipt_entry_match *m, unsigned int *nfcache)
21 *nfcache |= NFC_IP_TOS;
24 static void help(void)
27 "ECN match v%s options\n"
28 "[!] --ecn-tcp-cwr Match CWR bit of TCP header\n"
29 "[!] --ecn-tcp-ece Match ECE bit of TCP header\n"
30 "[!] --ecn-ip-ect [0..3] Match ECN codepoint in IPv4 header\n",
34 static struct option opts[] = {
35 { .name = "ecn-tcp-cwr", .has_arg = 0, .flag = 0, .val = 'F' },
36 { .name = "ecn-tcp-ece", .has_arg = 0, .flag = 0, .val = 'G' },
37 { .name = "ecn-ip-ect", .has_arg = 1, .flag = 0, .val = 'H' },
42 parse(int c, char **argv, int invert, unsigned int *flags,
43 const struct ipt_entry *entry,
44 unsigned int *nfcache,
45 struct ipt_entry_match **match)
48 struct ipt_ecn_info *einfo
49 = (struct ipt_ecn_info *)(*match)->data;
53 if (*flags & IPT_ECN_OP_MATCH_CWR)
54 exit_error(PARAMETER_PROBLEM,
55 "ECN match: can only use parameter ONCE!");
56 check_inverse(optarg, &invert, &optind, 0);
57 einfo->operation |= IPT_ECN_OP_MATCH_CWR;
59 einfo->invert |= IPT_ECN_OP_MATCH_CWR;
60 *flags |= IPT_ECN_OP_MATCH_CWR;
64 if (*flags & IPT_ECN_OP_MATCH_ECE)
65 exit_error(PARAMETER_PROBLEM,
66 "ECN match: can only use parameter ONCE!");
67 check_inverse(optarg, &invert, &optind, 0);
68 einfo->operation |= IPT_ECN_OP_MATCH_ECE;
70 einfo->invert |= IPT_ECN_OP_MATCH_ECE;
71 *flags |= IPT_ECN_OP_MATCH_ECE;
75 if (*flags & IPT_ECN_OP_MATCH_IP)
76 exit_error(PARAMETER_PROBLEM,
77 "ECN match: can only use parameter ONCE!");
78 check_inverse(optarg, &invert, &optind, 0);
80 einfo->invert |= IPT_ECN_OP_MATCH_IP;
81 *flags |= IPT_ECN_OP_MATCH_IP;
82 einfo->operation |= IPT_ECN_OP_MATCH_IP;
83 if (string_to_number(optarg, 0, 3, &result))
84 exit_error(PARAMETER_PROBLEM,
85 "ECN match: Value out of range");
86 einfo->ip_ect = result;
96 final_check(unsigned int flags)
99 exit_error(PARAMETER_PROBLEM,
100 "ECN match: some option required");
103 /* Prints out the matchinfo. */
105 print(const struct ipt_ip *ip,
106 const struct ipt_entry_match *match,
109 const struct ipt_ecn_info *einfo =
110 (const struct ipt_ecn_info *)match->data;
112 printf("ECN match ");
114 if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
115 if (einfo->invert & IPT_ECN_OP_MATCH_ECE)
120 if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
121 if (einfo->invert & IPT_ECN_OP_MATCH_CWR)
126 if (einfo->operation & IPT_ECN_OP_MATCH_IP) {
127 if (einfo->invert & IPT_ECN_OP_MATCH_IP)
129 printf("ECT=%d ", einfo->ip_ect);
133 /* Saves the union ipt_matchinfo in parsable form to stdout. */
135 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
137 const struct ipt_ecn_info *einfo =
138 (const struct ipt_ecn_info *)match->data;
140 if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
141 if (einfo->invert & IPT_ECN_OP_MATCH_ECE)
143 printf("--ecn-tcp-ece ");
146 if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
147 if (einfo->invert & IPT_ECN_OP_MATCH_CWR)
149 printf("--ecn-tcp-cwr ");
152 if (einfo->operation & IPT_ECN_OP_MATCH_IP) {
153 if (einfo->invert & IPT_ECN_OP_MATCH_IP)
155 printf("--ecn-ip-ect %d", einfo->ip_ect);
160 struct iptables_match ecn
162 .version = IPTABLES_VERSION,
163 .size = IPT_ALIGN(sizeof(struct ipt_ecn_info)),
164 .userspacesize = IPT_ALIGN(sizeof(struct ipt_ecn_info)),
168 .final_check = &final_check,
176 register_match(&ecn);