Busybox: Upgrade to 1.21.1 (stable). lsof active.
[tomato.git] / release / src / router / iptables / extensions / libipt_ecn.c
blob97e839da5539101badf39382b93616854050fe42
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
9 */
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <getopt.h>
15 #include <iptables.h>
16 #include <linux/netfilter_ipv4/ip_tables.h>
17 #include <linux/netfilter_ipv4/ipt_ecn.h>
19 static void help(void)
21 printf(
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",
26 IPTABLES_VERSION);
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' },
33 { .name = 0 }
36 static int
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)
42 unsigned int result;
43 struct ipt_ecn_info *einfo
44 = (struct ipt_ecn_info *)(*match)->data;
46 switch (c) {
47 case 'F':
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;
53 if (invert)
54 einfo->invert |= IPT_ECN_OP_MATCH_CWR;
55 *flags |= IPT_ECN_OP_MATCH_CWR;
56 break;
58 case 'G':
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;
64 if (invert)
65 einfo->invert |= IPT_ECN_OP_MATCH_ECE;
66 *flags |= IPT_ECN_OP_MATCH_ECE;
67 break;
69 case 'H':
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);
74 if (invert)
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;
82 break;
83 default:
84 return 0;
87 return 1;
90 static void
91 final_check(unsigned int flags)
93 if (!flags)
94 exit_error(PARAMETER_PROBLEM,
95 "ECN match: some option required");
98 /* Prints out the matchinfo. */
99 static void
100 print(const struct ipt_ip *ip,
101 const struct ipt_entry_match *match,
102 int numeric)
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)
111 fputc('!', stdout);
112 printf("ECE ");
115 if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
116 if (einfo->invert & IPT_ECN_OP_MATCH_CWR)
117 fputc('!', stdout);
118 printf("CWR ");
121 if (einfo->operation & IPT_ECN_OP_MATCH_IP) {
122 if (einfo->invert & IPT_ECN_OP_MATCH_IP)
123 fputc('!', stdout);
124 printf("ECT=%d ", einfo->ip_ect);
128 /* Saves the union ipt_matchinfo in parsable form to stdout. */
129 static void
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)
137 printf("! ");
138 printf("--ecn-tcp-ece ");
141 if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
142 if (einfo->invert & IPT_ECN_OP_MATCH_CWR)
143 printf("! ");
144 printf("--ecn-tcp-cwr ");
147 if (einfo->operation & IPT_ECN_OP_MATCH_IP) {
148 if (einfo->invert & IPT_ECN_OP_MATCH_IP)
149 printf("! ");
150 printf("--ecn-ip-ect %d", einfo->ip_ect);
154 static
155 struct iptables_match ecn
156 = { .name = "ecn",
157 .version = IPTABLES_VERSION,
158 .size = IPT_ALIGN(sizeof(struct ipt_ecn_info)),
159 .userspacesize = IPT_ALIGN(sizeof(struct ipt_ecn_info)),
160 .help = &help,
161 .parse = &parse,
162 .final_check = &final_check,
163 .print = &print,
164 .save = &save,
165 .extra_opts = opts
168 void _init(void)
170 register_match(&ecn);