libipt_ECN.c revision 385a1dd0f3b01fc0fbd6bcdee9796e0240ea77c1
1/* Shared library add-on to iptables for ECN, $Version$
2 *
3 * (C) 2002 by Harald Welte <laforge@gnumonks.org>
4 *
5 * This program is distributed under the terms of GNU GPL v2, 1991
6 *
7 * libipt_ECN.c borrowed heavily from libipt_DSCP.c
8 *
9 * $Id$
10 */
11#include <stdio.h>
12#include <string.h>
13#include <stdlib.h>
14#include <getopt.h>
15
16#include <iptables.h>
17#include <linux/netfilter_ipv4/ip_tables.h>
18#include <linux/netfilter_ipv4/ipt_ECN.h>
19
20static void init(struct ipt_entry_target *t, unsigned int *nfcache)
21{
22}
23
24static void help(void)
25{
26	printf(
27"ECN target options\n"
28"  --ecn-remove			Remove all ECN bits which may be present\n"
29"  		                in the IPv4 header\n"
30);
31}
32
33static struct option opts[] = {
34	{ "ecn-remove", 1, 0, 'F' },
35	{ 0 }
36};
37
38static int
39parse(int c, char **argv, int invert, unsigned int *flags,
40      const struct ipt_entry *entry,
41      struct ipt_entry_target **target)
42{
43	struct ipt_ECN_info *finfo
44		= (struct ipt_ECN_info *)(*target)->data;
45
46	switch (c) {
47	case 'F':
48		if (*flags)
49			exit_error(PARAMETER_PROBLEM,
50			           "ECN target: Only use --ecn-remove ONCE!");
51		einfo->operation = IPT_ECN_OP_REMOVE;
52		*flags = 1;
53		break;
54
55	default:
56		return 0;
57	}
58
59	return 1;
60}
61
62static void
63final_check(unsigned int flags)
64{
65	if (!flags)
66		exit_error(PARAMETER_PROBLEM,
67		           "ECN target: Parameter --ecn-remove is required");
68}
69
70/* Prints out the targinfo. */
71static void
72print(const struct ipt_ip *ip,
73      const struct ipt_entry_target *target,
74      int numeric)
75{
76	const struct ipt_ECN_info *einfo =
77		(const struct ipt_ECN_info *)target->data;
78
79	printf("ECN ");
80
81	switch (einfo->operation) {
82		case IPT_ECN_OP_REMOVE:
83			printf("remove ");
84			break;
85		default:
86			printf("unsupported_ecn_operation ");
87			break;
88	}
89}
90
91/* Saves the union ipt_targinfo in parsable form to stdout. */
92static void
93save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
94{
95	const struct ipt_ECN_info *einfo =
96		(const struct ipt_ECN_info *)target->data;
97
98	switch (einfo->operation) {
99		case IPT_ECN_OP_REMOVE:
100			printf("--ecn-remove ");
101			break;
102		default:
103	}
104}
105
106static
107struct iptables_target ecn
108= { NULL,
109    "ECN",
110    NETFILTER_VERSION,
111    IPT_ALIGN(sizeof(struct ipt_ECN_info)),
112    IPT_ALIGN(sizeof(struct ipt_ECN_info)),
113    &help,
114    &init,
115    &parse,
116    &final_check,
117    &print,
118    &save,
119    opts
120};
121
122void _init(void)
123{
124	register_target(&ecn);
125}
126