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