fix for f12, gcc4.4
[iptables.git] / extensions / libip6t_TCPMSS.c
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 <ip6tables.h>
11 #include <linux/netfilter_ipv6/ip6_tables.h>
12 #include <linux/netfilter_ipv6/ip6t_TCPMSS.h>
13
14 struct mssinfo {
15         struct ip6t_entry_target t;
16         struct ip6t_tcpmss_info mss;
17 };
18
19 /* Function which prints out usage message. */
20 static void
21 help(void)
22 {
23         printf(
24 "TCPMSS target v%s mutually-exclusive options:\n"
25 "  --set-mss value               explicitly set MSS option to specified value\n"
26 "  --clamp-mss-to-pmtu           automatically clamp MSS value to (path_MTU - 60)\n",
27 IPTABLES_VERSION);
28 }
29
30 static struct option opts[] = {
31         { "set-mss", 1, 0, '1' },
32         { "clamp-mss-to-pmtu", 0, 0, '2' },
33         { 0 }
34 };
35
36 /* Initialize the target. */
37 static void
38 init(struct ip6t_entry_target *t, unsigned int *nfcache)
39 {
40 }
41
42 /* Function which parses command options; returns true if it
43    ate an option */
44 static int
45 parse(int c, char **argv, int invert, unsigned int *flags,
46       const struct ip6t_entry *entry,
47       struct ip6t_entry_target **target)
48 {
49         struct ip6t_tcpmss_info *mssinfo
50                 = (struct ip6t_tcpmss_info *)(*target)->data;
51
52         switch (c) {
53                 unsigned int mssval;
54
55         case '1':
56                 if (*flags)
57                         exit_error(PARAMETER_PROBLEM,
58                                    "TCPMSS target: Only one option may be specified");
59                 if (string_to_number(optarg, 0, 65535 - 60, &mssval) == -1)
60                         exit_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                         exit_error(PARAMETER_PROBLEM,
69                                    "TCPMSS target: Only one option may be specified");
70                 mssinfo->mss = IP6T_TCPMSS_CLAMP_PMTU;
71                 *flags = 1;
72                 break;
73
74         default:
75                 return 0;
76         }
77
78         return 1;
79 }
80
81 static void
82 final_check(unsigned int flags)
83 {
84         if (!flags)
85                 exit_error(PARAMETER_PROBLEM,
86                            "TCPMSS target: At least one parameter is required");
87 }
88
89 /* Prints out the targinfo. */
90 static void
91 print(const struct ip6t_ip6 *ip6,
92       const struct ip6t_entry_target *target,
93       int numeric)
94 {
95         const struct ip6t_tcpmss_info *mssinfo =
96                 (const struct ip6t_tcpmss_info *)target->data;
97         if(mssinfo->mss == IP6T_TCPMSS_CLAMP_PMTU)
98                 printf("TCPMSS clamp to PMTU ");
99         else
100                 printf("TCPMSS set %u ", mssinfo->mss);
101 }
102
103 /* Saves the union ip6t_targinfo in parsable form to stdout. */
104 static void
105 save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target)
106 {
107         const struct ip6t_tcpmss_info *mssinfo =
108                 (const struct ip6t_tcpmss_info *)target->data;
109
110         if(mssinfo->mss == IP6T_TCPMSS_CLAMP_PMTU)
111                 printf("--clamp-mss-to-pmtu ");
112         else
113                 printf("--set-mss %u ", mssinfo->mss);
114 }
115
116 static struct ip6tables_target mss = {
117         .next           = NULL,
118         .name           = "TCPMSS",
119         .version        = IPTABLES_VERSION,
120         .size           = IP6T_ALIGN(sizeof(struct ip6t_tcpmss_info)),
121         .userspacesize  = IP6T_ALIGN(sizeof(struct ip6t_tcpmss_info)),
122         .help           = &help,
123         .init           = &init,
124         .parse          = &parse,
125         .final_check    = &final_check,
126         .print          = &print,
127         .save           = &save,
128         .extra_opts     = opts
129 };
130
131 void _init(void)
132 {
133         register_target6(&mss);
134 }