libxt_TCPMSS.c revision 03d99486d8283552705b58dc55b6085dffc38792
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 exit_error(PARAMETER_PROBLEM, 57 "TCPMSS target: Only one option may be specified"); 58 if (string_to_number(optarg, 0, 65535 - hdrsize, &mssval) == -1) 59 exit_error(PARAMETER_PROBLEM, "Bad TCPMSS value `%s'", optarg); 60 61 mssinfo->mss = mssval; 62 *flags = 1; 63 break; 64 65 case '2': 66 if (*flags) 67 exit_error(PARAMETER_PROBLEM, 68 "TCPMSS target: Only one option may be specified"); 69 mssinfo->mss = XT_TCPMSS_CLAMP_PMTU; 70 *flags = 1; 71 break; 72 73 default: 74 return 0; 75 } 76 77 return 1; 78} 79 80static int TCPMSS_parse(int c, char **argv, int invert, unsigned int *flags, 81 const void *entry, struct xt_entry_target **target) 82{ 83 return __TCPMSS_parse(c, argv, invert, flags, entry, target, 40); 84} 85 86static int TCPMSS_parse6(int c, char **argv, int invert, unsigned int *flags, 87 const void *entry, struct xt_entry_target **target) 88{ 89 return __TCPMSS_parse(c, argv, invert, flags, entry, target, 60); 90} 91 92static void TCPMSS_check(unsigned int flags) 93{ 94 if (!flags) 95 exit_error(PARAMETER_PROBLEM, 96 "TCPMSS target: At least one parameter is required"); 97} 98 99static void TCPMSS_print(const void *ip, const struct xt_entry_target *target, 100 int numeric) 101{ 102 const struct xt_tcpmss_info *mssinfo = 103 (const struct xt_tcpmss_info *)target->data; 104 if(mssinfo->mss == XT_TCPMSS_CLAMP_PMTU) 105 printf("TCPMSS clamp to PMTU "); 106 else 107 printf("TCPMSS set %u ", mssinfo->mss); 108} 109 110static void TCPMSS_save(const void *ip, const struct xt_entry_target *target) 111{ 112 const struct xt_tcpmss_info *mssinfo = 113 (const struct xt_tcpmss_info *)target->data; 114 115 if(mssinfo->mss == XT_TCPMSS_CLAMP_PMTU) 116 printf("--clamp-mss-to-pmtu "); 117 else 118 printf("--set-mss %u ", mssinfo->mss); 119} 120 121static struct xtables_target tcpmss_target = { 122 .family = NFPROTO_IPV4, 123 .name = "TCPMSS", 124 .version = XTABLES_VERSION, 125 .size = XT_ALIGN(sizeof(struct xt_tcpmss_info)), 126 .userspacesize = XT_ALIGN(sizeof(struct xt_tcpmss_info)), 127 .help = TCPMSS_help, 128 .parse = TCPMSS_parse, 129 .final_check = TCPMSS_check, 130 .print = TCPMSS_print, 131 .save = TCPMSS_save, 132 .extra_opts = TCPMSS_opts, 133}; 134 135static struct xtables_target tcpmss_target6 = { 136 .family = NFPROTO_IPV6, 137 .name = "TCPMSS", 138 .version = XTABLES_VERSION, 139 .size = XT_ALIGN(sizeof(struct xt_tcpmss_info)), 140 .userspacesize = XT_ALIGN(sizeof(struct xt_tcpmss_info)), 141 .help = TCPMSS_help6, 142 .parse = TCPMSS_parse6, 143 .final_check = TCPMSS_check, 144 .print = TCPMSS_print, 145 .save = TCPMSS_save, 146 .extra_opts = TCPMSS_opts, 147}; 148 149void _init(void) 150{ 151 xtables_register_target(&tcpmss_target); 152 xtables_register_target(&tcpmss_target6); 153} 154