libxt_TCPMSS.c revision 45e4c6946426785d30733701d1ee8112e58538a4
1/* Shared library add-on to iptables to add TCPMSS target support.
2 *
3 * Copyright (c) 2000 Marc Boucher
4*/
5#include <stdio.h>
6#include <string.h>
7#include <stdlib.h>
8#include <getopt.h>
9
10#include <xtables.h>
11#include <linux/netfilter/x_tables.h>
12#include <linux/netfilter/xt_TCPMSS.h>
13
14struct mssinfo {
15	struct xt_entry_target t;
16	struct xt_tcpmss_info mss;
17};
18
19/* Function which prints out usage message. */
20static void __help(int hdrsize)
21{
22	printf(
23"TCPMSS target v%s mutually-exclusive options:\n"
24"  --set-mss value               explicitly set MSS option to specified value\n"
25"  --clamp-mss-to-pmtu           automatically clamp MSS value to (path_MTU - %d)\n",
26IPTABLES_VERSION, hdrsize);
27}
28
29static void help(void)
30{
31	__help(40);
32}
33
34static void help6(void)
35{
36	__help(60);
37}
38
39static struct option opts[] = {
40	{ "set-mss", 1, 0, '1' },
41	{ "clamp-mss-to-pmtu", 0, 0, '2' },
42	{ 0 }
43};
44
45/* Initialize the target. */
46static void
47init(struct xt_entry_target *t, unsigned int *nfcache)
48{
49}
50
51/* Function which parses command options; returns true if it
52   ate an option */
53static int
54__parse(int c, char **argv, int invert, unsigned int *flags,
55      const void *entry,
56      struct xt_entry_target **target,
57      int hdrsize)
58{
59	struct xt_tcpmss_info *mssinfo
60		= (struct xt_tcpmss_info *)(*target)->data;
61
62	switch (c) {
63		unsigned int mssval;
64
65	case '1':
66		if (*flags)
67			exit_error(PARAMETER_PROBLEM,
68			           "TCPMSS target: Only one option may be specified");
69		if (string_to_number(optarg, 0, 65535 - hdrsize, &mssval) == -1)
70			exit_error(PARAMETER_PROBLEM, "Bad TCPMSS value `%s'", optarg);
71
72		mssinfo->mss = mssval;
73		*flags = 1;
74		break;
75
76	case '2':
77		if (*flags)
78			exit_error(PARAMETER_PROBLEM,
79			           "TCPMSS target: Only one option may be specified");
80		mssinfo->mss = XT_TCPMSS_CLAMP_PMTU;
81		*flags = 1;
82		break;
83
84	default:
85		return 0;
86	}
87
88	return 1;
89}
90
91static int
92parse(int c, char **argv, int invert, unsigned int *flags,
93      const void *entry,
94      struct xt_entry_target **target)
95{
96	return __parse(c, argv, invert, flags, entry, target, 40);
97}
98
99static int
100parse6(int c, char **argv, int invert, unsigned int *flags,
101      const void *entry,
102      struct xt_entry_target **target)
103{
104	return __parse(c, argv, invert, flags, entry, target, 60);
105}
106
107static void
108final_check(unsigned int flags)
109{
110	if (!flags)
111		exit_error(PARAMETER_PROBLEM,
112		           "TCPMSS target: At least one parameter is required");
113}
114
115/* Prints out the targinfo. */
116static void
117print(const void *ip,
118      const struct xt_entry_target *target,
119      int numeric)
120{
121	const struct xt_tcpmss_info *mssinfo =
122		(const struct xt_tcpmss_info *)target->data;
123	if(mssinfo->mss == XT_TCPMSS_CLAMP_PMTU)
124		printf("TCPMSS clamp to PMTU ");
125	else
126		printf("TCPMSS set %u ", mssinfo->mss);
127}
128
129/* Saves the union ipt_targinfo in parsable form to stdout. */
130static void
131save(const void *ip, const struct xt_entry_target *target)
132{
133	const struct xt_tcpmss_info *mssinfo =
134		(const struct xt_tcpmss_info *)target->data;
135
136	if(mssinfo->mss == XT_TCPMSS_CLAMP_PMTU)
137		printf("--clamp-mss-to-pmtu ");
138	else
139		printf("--set-mss %u ", mssinfo->mss);
140}
141
142static struct xtables_target mss = {
143	.next		= NULL,
144	.family		= AF_INET,
145	.name		= "TCPMSS",
146	.version	= IPTABLES_VERSION,
147	.size		= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
148	.userspacesize	= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
149	.help		= &help,
150	.init		= &init,
151	.parse		= &parse,
152	.final_check	= &final_check,
153	.print		= &print,
154	.save		= &save,
155	.extra_opts	= opts
156};
157
158static struct xtables_target mss6 = {
159	.next		= NULL,
160	.family		= AF_INET6,
161	.name		= "TCPMSS",
162	.version	= IPTABLES_VERSION,
163	.size		= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
164	.userspacesize	= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
165	.help		= &help6,
166	.init		= &init,
167	.parse		= &parse6,
168	.final_check	= &final_check,
169	.print		= &print,
170	.save		= &save,
171	.extra_opts	= opts
172};
173
174void _init(void)
175{
176	xtables_register_target(&mss);
177	xtables_register_target(&mss6);
178}
179