libxt_TCPMSS.c revision 18992db3bfdb3b695cae12b53434f560cbf8e2ae
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	.family		= AF_INET,
144	.name		= "TCPMSS",
145	.version	= IPTABLES_VERSION,
146	.size		= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
147	.userspacesize	= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
148	.help		= &help,
149	.init		= &init,
150	.parse		= &parse,
151	.final_check	= &final_check,
152	.print		= &print,
153	.save		= &save,
154	.extra_opts	= opts
155};
156
157static struct xtables_target mss6 = {
158	.family		= AF_INET6,
159	.name		= "TCPMSS",
160	.version	= IPTABLES_VERSION,
161	.size		= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
162	.userspacesize	= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
163	.help		= &help6,
164	.init		= &init,
165	.parse		= &parse6,
166	.final_check	= &final_check,
167	.print		= &print,
168	.save		= &save,
169	.extra_opts	= opts
170};
171
172void _init(void)
173{
174	xtables_register_target(&mss);
175	xtables_register_target(&mss6);
176}
177