libxt_TCPMSS.c revision e37d45ce390c2f5a7f1e64742b9100ecef0def54
181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org/* Shared library add-on to iptables to add TCPMSS target support.
281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org *
381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * Copyright (c) 2000 Marc Boucher
481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org*/
581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include <stdio.h>
681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include <xtables.h>
781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include <netinet/ip.h>
881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include <netinet/ip6.h>
981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include <linux/netfilter/xt_TCPMSS.h>
1081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
1181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgenum {
1281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	O_SET_MSS = 0,
1381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	O_CLAMP_MSS,
1481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org};
1581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
1681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstruct mssinfo {
1781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	struct xt_entry_target t;
1881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	struct xt_tcpmss_info mss;
1981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org};
2081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
2181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatic void __TCPMSS_help(int hdrsize)
2281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
2381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	printf(
2481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org"TCPMSS target mutually-exclusive options:\n"
2581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org"  --set-mss value               explicitly set MSS option to specified value\n"
2681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org"  --clamp-mss-to-pmtu           automatically clamp MSS value to (path_MTU - %d)\n",
2781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orghdrsize);
2881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
2981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
3081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatic void TCPMSS_help(void)
3181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
3281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	__TCPMSS_help(sizeof(struct iphdr));
3381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
3481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
3581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatic void TCPMSS_help6(void)
3681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
3781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	__TCPMSS_help(sizeof(struct ip6_hdr));
3881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
3981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
4081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatic const struct xt_option_entry TCPMSS4_opts[] = {
4181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{.name = "set-mss", .id = O_SET_MSS, .type = XTTYPE_UINT16,
4281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	 .min = 0, .max = UINT16_MAX - sizeof(struct iphdr),
4381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	 .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_tcpmss_info, mss)},
4481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{.name = "clamp-mss-to-pmtu", .id = O_CLAMP_MSS, .type = XTTYPE_NONE},
4581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	XTOPT_TABLEEND,
4681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org};
4781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
4881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatic const struct xt_option_entry TCPMSS6_opts[] = {
4981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{.name = "set-mss", .id = O_SET_MSS, .type = XTTYPE_UINT16,
5081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	 .min = 0, .max = UINT16_MAX - sizeof(struct ip6_hdr),
5181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	 .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_tcpmss_info, mss)},
5281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{.name = "clamp-mss-to-pmtu", .id = O_CLAMP_MSS, .type = XTTYPE_NONE},
5381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	XTOPT_TABLEEND,
5481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org};
5581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
5681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatic void TCPMSS_parse(struct xt_option_call *cb)
5781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
5881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	struct xt_tcpmss_info *mssinfo = cb->data;
5981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
6081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	xtables_option_parse(cb);
6181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	if (cb->entry->id == O_CLAMP_MSS)
6281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		mssinfo->mss = XT_TCPMSS_CLAMP_PMTU;
6381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
6481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
6581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatic void TCPMSS_check(struct xt_fcheck_call *cb)
6681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
6781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	if (cb->xflags == 0)
6881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		xtables_error(PARAMETER_PROBLEM,
6981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		           "TCPMSS target: At least one parameter is required");
7081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
7181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
7281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatic void TCPMSS_print(const void *ip, const struct xt_entry_target *target,
7381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org                         int numeric)
7481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
7581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const struct xt_tcpmss_info *mssinfo =
7681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		(const struct xt_tcpmss_info *)target->data;
7781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	if(mssinfo->mss == XT_TCPMSS_CLAMP_PMTU)
7881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		printf(" TCPMSS clamp to PMTU");
7981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	else
8081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		printf(" TCPMSS set %u", mssinfo->mss);
8181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
8281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
8381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatic void TCPMSS_save(const void *ip, const struct xt_entry_target *target)
8481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
8581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const struct xt_tcpmss_info *mssinfo =
8681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		(const struct xt_tcpmss_info *)target->data;
8781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
8881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	if(mssinfo->mss == XT_TCPMSS_CLAMP_PMTU)
8981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		printf(" --clamp-mss-to-pmtu");
9081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	else
9181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		printf(" --set-mss %u", mssinfo->mss);
9281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
9381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
9481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatic struct xtables_target tcpmss_target = {
9581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.family		= NFPROTO_IPV4,
9681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.name		= "TCPMSS",
9781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.version	= XTABLES_VERSION,
9881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.size		= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
9981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.userspacesize	= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
10081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.help		= TCPMSS_help,
10181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.print		= TCPMSS_print,
10281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.save		= TCPMSS_save,
10381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.x6_parse	= TCPMSS_parse,
10481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.x6_fcheck	= TCPMSS_check,
10581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.x6_options	= TCPMSS4_opts,
10681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org};
10781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
10881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatic struct xtables_target tcpmss_target6 = {
10981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.family		= NFPROTO_IPV6,
11081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.name		= "TCPMSS",
11181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.version	= XTABLES_VERSION,
11281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.size		= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
11381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.userspacesize	= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
11481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.help		= TCPMSS_help6,
11581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.print		= TCPMSS_print,
11681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.save		= TCPMSS_save,
11781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.x6_parse	= TCPMSS_parse,
11881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.x6_fcheck	= TCPMSS_check,
11981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	.x6_options	= TCPMSS6_opts,
12081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org};
12181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
12281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgvoid _init(void)
12381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
12481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	xtables_register_target(&tcpmss_target);
12581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	xtables_register_target(&tcpmss_target6);
12681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
12781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org