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