1 /* Shared library add-on to iptables for ECN, $Version$
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
17 #include <linux/netfilter_ipv4/ipt_ECN.h>
19 static void ECN_help(void)
22 "ECN target options\n"
23 " --ecn-tcp-remove Remove all ECN bits from TCP header\n");
27 "ECN target v%s EXPERIMENTAL options (use with extreme care!)\n"
28 " --ecn-ip-ect Set the IPv4 ECT codepoint (0 to 3)\n"
29 " --ecn-tcp-cwr Set the IPv4 CWR bit (0 or 1)\n"
30 " --ecn-tcp-ece Set the IPv4 ECE bit (0 or 1)\n",
34 static const struct option ECN_opts[] = {
35 { "ecn-tcp-remove", 0, NULL, 'F' },
36 { "ecn-tcp-cwr", 1, NULL, 'G' },
37 { "ecn-tcp-ece", 1, NULL, 'H' },
38 { "ecn-ip-ect", 1, NULL, '9' },
42 static int ECN_parse(int c, char **argv, int invert, unsigned int *flags,
43 const void *entry, struct xt_entry_target **target)
46 struct ipt_ECN_info *einfo
47 = (struct ipt_ECN_info *)(*target)->data;
52 xtables_error(PARAMETER_PROBLEM,
53 "ECN target: Only use --ecn-tcp-remove ONCE!");
54 einfo->operation = IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR;
55 einfo->proto.tcp.ece = 0;
56 einfo->proto.tcp.cwr = 0;
60 if (*flags & IPT_ECN_OP_SET_CWR)
61 xtables_error(PARAMETER_PROBLEM,
62 "ECN target: Only use --ecn-tcp-cwr ONCE!");
63 if (!xtables_strtoui(optarg, NULL, &result, 0, 1))
64 xtables_error(PARAMETER_PROBLEM,
65 "ECN target: Value out of range");
66 einfo->operation |= IPT_ECN_OP_SET_CWR;
67 einfo->proto.tcp.cwr = result;
68 *flags |= IPT_ECN_OP_SET_CWR;
71 if (*flags & IPT_ECN_OP_SET_ECE)
72 xtables_error(PARAMETER_PROBLEM,
73 "ECN target: Only use --ecn-tcp-ece ONCE!");
74 if (!xtables_strtoui(optarg, NULL, &result, 0, 1))
75 xtables_error(PARAMETER_PROBLEM,
76 "ECN target: Value out of range");
77 einfo->operation |= IPT_ECN_OP_SET_ECE;
78 einfo->proto.tcp.ece = result;
79 *flags |= IPT_ECN_OP_SET_ECE;
82 if (*flags & IPT_ECN_OP_SET_IP)
83 xtables_error(PARAMETER_PROBLEM,
84 "ECN target: Only use --ecn-ip-ect ONCE!");
85 if (!xtables_strtoui(optarg, NULL, &result, 0, 3))
86 xtables_error(PARAMETER_PROBLEM,
87 "ECN target: Value out of range");
88 einfo->operation |= IPT_ECN_OP_SET_IP;
89 einfo->ip_ect = result;
90 *flags |= IPT_ECN_OP_SET_IP;
99 static void ECN_check(unsigned int flags)
102 xtables_error(PARAMETER_PROBLEM,
103 "ECN target: Parameter --ecn-tcp-remove is required");
106 static void ECN_print(const void *ip, const struct xt_entry_target *target,
109 const struct ipt_ECN_info *einfo =
110 (const struct ipt_ECN_info *)target->data;
114 if (einfo->operation == (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)
115 && einfo->proto.tcp.ece == 0
116 && einfo->proto.tcp.cwr == 0)
117 printf("TCP remove ");
119 if (einfo->operation & IPT_ECN_OP_SET_ECE)
120 printf("ECE=%u ", einfo->proto.tcp.ece);
122 if (einfo->operation & IPT_ECN_OP_SET_CWR)
123 printf("CWR=%u ", einfo->proto.tcp.cwr);
125 if (einfo->operation & IPT_ECN_OP_SET_IP)
126 printf("ECT codepoint=%u ", einfo->ip_ect);
130 static void ECN_save(const void *ip, const struct xt_entry_target *target)
132 const struct ipt_ECN_info *einfo =
133 (const struct ipt_ECN_info *)target->data;
135 if (einfo->operation == (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)
136 && einfo->proto.tcp.ece == 0
137 && einfo->proto.tcp.cwr == 0)
138 printf("--ecn-tcp-remove ");
141 if (einfo->operation & IPT_ECN_OP_SET_ECE)
142 printf("--ecn-tcp-ece %d ", einfo->proto.tcp.ece);
144 if (einfo->operation & IPT_ECN_OP_SET_CWR)
145 printf("--ecn-tcp-cwr %d ", einfo->proto.tcp.cwr);
147 if (einfo->operation & IPT_ECN_OP_SET_IP)
148 printf("--ecn-ip-ect %d ", einfo->ip_ect);
152 static struct xtables_target ecn_tg_reg = {
154 .version = XTABLES_VERSION,
155 .family = NFPROTO_IPV4,
156 .size = XT_ALIGN(sizeof(struct ipt_ECN_info)),
157 .userspacesize = XT_ALIGN(sizeof(struct ipt_ECN_info)),
160 .final_check = ECN_check,
163 .extra_opts = ECN_opts,
168 xtables_register_target(&ecn_tg_reg);