libxt_TCPMSS.c revision 1829ed482efbc8b390cc760d012b3a4450494e1a
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 19static void __TCPMSS_help(int hdrsize) 20{ 21 printf( 22"TCPMSS target mutually-exclusive options:\n" 23" --set-mss value explicitly set MSS option to specified value\n" 24" --clamp-mss-to-pmtu automatically clamp MSS value to (path_MTU - %d)\n", 25hdrsize); 26} 27 28static void TCPMSS_help(void) 29{ 30 __TCPMSS_help(40); 31} 32 33static void TCPMSS_help6(void) 34{ 35 __TCPMSS_help(60); 36} 37 38static const struct option TCPMSS_opts[] = { 39 { "set-mss", 1, NULL, '1' }, 40 { "clamp-mss-to-pmtu", 0, NULL, '2' }, 41 { .name = NULL } 42}; 43 44static int __TCPMSS_parse(int c, char **argv, int invert, unsigned int *flags, 45 const void *entry, struct xt_entry_target **target, 46 int hdrsize) 47{ 48 struct xt_tcpmss_info *mssinfo 49 = (struct xt_tcpmss_info *)(*target)->data; 50 51 switch (c) { 52 unsigned int mssval; 53 54 case '1': 55 if (*flags) 56 xtables_error(PARAMETER_PROBLEM, 57 "TCPMSS target: Only one option may be specified"); 58 if (!xtables_strtoui(optarg, NULL, &mssval, 59 0, UINT16_MAX - hdrsize)) 60 xtables_error(PARAMETER_PROBLEM, "Bad TCPMSS value \"%s\"", optarg); 61 62 mssinfo->mss = mssval; 63 *flags = 1; 64 break; 65 66 case '2': 67 if (*flags) 68 xtables_error(PARAMETER_PROBLEM, 69 "TCPMSS target: Only one option may be specified"); 70 mssinfo->mss = XT_TCPMSS_CLAMP_PMTU; 71 *flags = 1; 72 break; 73 74 default: 75 return 0; 76 } 77 78 return 1; 79} 80 81static int TCPMSS_parse(int c, char **argv, int invert, unsigned int *flags, 82 const void *entry, struct xt_entry_target **target) 83{ 84 return __TCPMSS_parse(c, argv, invert, flags, entry, target, 40); 85} 86 87static int TCPMSS_parse6(int c, char **argv, int invert, unsigned int *flags, 88 const void *entry, struct xt_entry_target **target) 89{ 90 return __TCPMSS_parse(c, argv, invert, flags, entry, target, 60); 91} 92 93static void TCPMSS_check(unsigned int flags) 94{ 95 if (!flags) 96 xtables_error(PARAMETER_PROBLEM, 97 "TCPMSS target: At least one parameter is required"); 98} 99 100static void TCPMSS_print(const void *ip, const struct xt_entry_target *target, 101 int numeric) 102{ 103 const struct xt_tcpmss_info *mssinfo = 104 (const struct xt_tcpmss_info *)target->data; 105 if(mssinfo->mss == XT_TCPMSS_CLAMP_PMTU) 106 printf("TCPMSS clamp to PMTU "); 107 else 108 printf("TCPMSS set %u ", mssinfo->mss); 109} 110 111static void TCPMSS_save(const void *ip, const struct xt_entry_target *target) 112{ 113 const struct xt_tcpmss_info *mssinfo = 114 (const struct xt_tcpmss_info *)target->data; 115 116 if(mssinfo->mss == XT_TCPMSS_CLAMP_PMTU) 117 printf("--clamp-mss-to-pmtu "); 118 else 119 printf("--set-mss %u ", mssinfo->mss); 120} 121 122static struct xtables_target tcpmss_target = { 123 .family = NFPROTO_IPV4, 124 .name = "TCPMSS", 125 .version = XTABLES_VERSION, 126 .size = XT_ALIGN(sizeof(struct xt_tcpmss_info)), 127 .userspacesize = XT_ALIGN(sizeof(struct xt_tcpmss_info)), 128 .help = TCPMSS_help, 129 .parse = TCPMSS_parse, 130 .final_check = TCPMSS_check, 131 .print = TCPMSS_print, 132 .save = TCPMSS_save, 133 .extra_opts = TCPMSS_opts, 134}; 135 136static struct xtables_target tcpmss_target6 = { 137 .family = NFPROTO_IPV6, 138 .name = "TCPMSS", 139 .version = XTABLES_VERSION, 140 .size = XT_ALIGN(sizeof(struct xt_tcpmss_info)), 141 .userspacesize = XT_ALIGN(sizeof(struct xt_tcpmss_info)), 142 .help = TCPMSS_help6, 143 .parse = TCPMSS_parse6, 144 .final_check = TCPMSS_check, 145 .print = TCPMSS_print, 146 .save = TCPMSS_save, 147 .extra_opts = TCPMSS_opts, 148}; 149 150void _init(void) 151{ 152 xtables_register_target(&tcpmss_target); 153 xtables_register_target(&tcpmss_target6); 154} 155