libxt_TCPMSS.c revision 932e648f38ac16b1ea14c1f66f23951388448c5a
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 __TCPMSS_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 TCPMSS_help(void) 30{ 31 __TCPMSS_help(40); 32} 33 34static void TCPMSS_help6(void) 35{ 36 __TCPMSS_help(60); 37} 38 39static const struct option TCPMSS_opts[] = { 40 { "set-mss", 1, NULL, '1' }, 41 { "clamp-mss-to-pmtu", 0, NULL, '2' }, 42 { } 43}; 44 45/* Function which parses command options; returns true if it 46 ate an option */ 47static int __TCPMSS_parse(int c, char **argv, int invert, unsigned int *flags, 48 const void *entry, struct xt_entry_target **target, 49 int hdrsize) 50{ 51 struct xt_tcpmss_info *mssinfo 52 = (struct xt_tcpmss_info *)(*target)->data; 53 54 switch (c) { 55 unsigned int mssval; 56 57 case '1': 58 if (*flags) 59 exit_error(PARAMETER_PROBLEM, 60 "TCPMSS target: Only one option may be specified"); 61 if (string_to_number(optarg, 0, 65535 - hdrsize, &mssval) == -1) 62 exit_error(PARAMETER_PROBLEM, "Bad TCPMSS value `%s'", optarg); 63 64 mssinfo->mss = mssval; 65 *flags = 1; 66 break; 67 68 case '2': 69 if (*flags) 70 exit_error(PARAMETER_PROBLEM, 71 "TCPMSS target: Only one option may be specified"); 72 mssinfo->mss = XT_TCPMSS_CLAMP_PMTU; 73 *flags = 1; 74 break; 75 76 default: 77 return 0; 78 } 79 80 return 1; 81} 82 83static int TCPMSS_parse(int c, char **argv, int invert, unsigned int *flags, 84 const void *entry, struct xt_entry_target **target) 85{ 86 return __TCPMSS_parse(c, argv, invert, flags, entry, target, 40); 87} 88 89static int TCPMSS_parse6(int c, char **argv, int invert, unsigned int *flags, 90 const void *entry, struct xt_entry_target **target) 91{ 92 return __TCPMSS_parse(c, argv, invert, flags, entry, target, 60); 93} 94 95static void TCPMSS_check(unsigned int flags) 96{ 97 if (!flags) 98 exit_error(PARAMETER_PROBLEM, 99 "TCPMSS target: At least one parameter is required"); 100} 101 102/* Prints out the targinfo. */ 103static void TCPMSS_print(const void *ip, const struct xt_entry_target *target, 104 int numeric) 105{ 106 const struct xt_tcpmss_info *mssinfo = 107 (const struct xt_tcpmss_info *)target->data; 108 if(mssinfo->mss == XT_TCPMSS_CLAMP_PMTU) 109 printf("TCPMSS clamp to PMTU "); 110 else 111 printf("TCPMSS set %u ", mssinfo->mss); 112} 113 114/* Saves the union ipt_targinfo in parsable form to stdout. */ 115static void TCPMSS_save(const void *ip, const struct xt_entry_target *target) 116{ 117 const struct xt_tcpmss_info *mssinfo = 118 (const struct xt_tcpmss_info *)target->data; 119 120 if(mssinfo->mss == XT_TCPMSS_CLAMP_PMTU) 121 printf("--clamp-mss-to-pmtu "); 122 else 123 printf("--set-mss %u ", mssinfo->mss); 124} 125 126static struct xtables_target tcpmss_target = { 127 .family = AF_INET, 128 .name = "TCPMSS", 129 .version = IPTABLES_VERSION, 130 .size = XT_ALIGN(sizeof(struct xt_tcpmss_info)), 131 .userspacesize = XT_ALIGN(sizeof(struct xt_tcpmss_info)), 132 .help = TCPMSS_help, 133 .parse = TCPMSS_parse, 134 .final_check = TCPMSS_check, 135 .print = TCPMSS_print, 136 .save = TCPMSS_save, 137 .extra_opts = TCPMSS_opts, 138}; 139 140static struct xtables_target tcpmss_target6 = { 141 .family = AF_INET6, 142 .name = "TCPMSS", 143 .version = IPTABLES_VERSION, 144 .size = XT_ALIGN(sizeof(struct xt_tcpmss_info)), 145 .userspacesize = XT_ALIGN(sizeof(struct xt_tcpmss_info)), 146 .help = TCPMSS_help6, 147 .parse = TCPMSS_parse6, 148 .final_check = TCPMSS_check, 149 .print = TCPMSS_print, 150 .save = TCPMSS_save, 151 .extra_opts = TCPMSS_opts, 152}; 153 154void _init(void) 155{ 156 xtables_register_target(&tcpmss_target); 157 xtables_register_target(&tcpmss_target6); 158} 159