fix for f12, gcc4.4
[iptables.git] / extensions / libipt_TTL.c
1 /* Shared library add-on to iptables for the TTL target
2  * (C) 2000 by Harald Welte <laforge@gnumonks.org>
3  *
4  * $Id: libipt_TTL.c 3507 2004-12-28 13:11:59Z /C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=rusty/emailAddress=rusty@netfilter.org $
5  *
6  * This program is distributed under the terms of GNU GPL
7  */
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <getopt.h>
12 #include <iptables.h>
13
14 #include <linux/netfilter_ipv4/ip_tables.h>
15 #include <linux/netfilter_ipv4/ipt_TTL.h>
16
17 #define IPT_TTL_USED    1
18
19 static void init(struct ipt_entry_target *t, unsigned int *nfcache) 
20 {
21 }
22
23 static void help(void) 
24 {
25         printf(
26 "TTL target v%s options\n"
27 "  --ttl-set value              Set TTL to <value 0-255>\n"
28 "  --ttl-dec value              Decrement TTL by <value 1-255>\n"
29 "  --ttl-inc value              Increment TTL by <value 1-255>\n"
30 , IPTABLES_VERSION);
31 }
32
33 static int parse(int c, char **argv, int invert, unsigned int *flags,
34                 const struct ipt_entry *entry,
35                 struct ipt_entry_target **target)
36 {
37         struct ipt_TTL_info *info = (struct ipt_TTL_info *) (*target)->data;
38         unsigned int value;
39
40         if (*flags & IPT_TTL_USED) {
41                 exit_error(PARAMETER_PROBLEM, 
42                                 "Can't specify TTL option twice");
43         }
44
45         if (!optarg) 
46                 exit_error(PARAMETER_PROBLEM, 
47                                 "TTL: You must specify a value");
48
49         if (check_inverse(optarg, &invert, NULL, 0))
50                 exit_error(PARAMETER_PROBLEM,
51                                 "TTL: unexpected `!'");
52         
53         if (string_to_number(optarg, 0, 255, &value) == -1)
54                 exit_error(PARAMETER_PROBLEM,
55                            "TTL: Expected value between 0 and 255");
56
57         switch (c) {
58
59                 case '1':
60                         info->mode = IPT_TTL_SET;
61                         break;
62
63                 case '2':
64                         if (value == 0) {
65                                 exit_error(PARAMETER_PROBLEM,
66                                         "TTL: decreasing by 0?");
67                         }
68
69                         info->mode = IPT_TTL_DEC;
70                         break;
71
72                 case '3':
73                         if (value == 0) {
74                                 exit_error(PARAMETER_PROBLEM,
75                                         "TTL: increasing by 0?");
76                         }
77
78                         info->mode = IPT_TTL_INC;
79                         break;
80
81                 default:
82                         return 0;
83
84         }
85         
86         info->ttl = value;
87         *flags |= IPT_TTL_USED;
88
89         return 1;
90 }
91
92 static void final_check(unsigned int flags)
93 {
94         if (!(flags & IPT_TTL_USED))
95                 exit_error(PARAMETER_PROBLEM,
96                                 "TTL: You must specify an action");
97 }
98
99 static void save(const struct ipt_ip *ip,
100                 const struct ipt_entry_target *target)
101 {
102         const struct ipt_TTL_info *info = 
103                 (struct ipt_TTL_info *) target->data;
104
105         switch (info->mode) {
106                 case IPT_TTL_SET:
107                         printf("--ttl-set ");
108                         break;
109                 case IPT_TTL_DEC:
110                         printf("--ttl-dec ");
111                         break;
112
113                 case IPT_TTL_INC:
114                         printf("--ttl-inc ");
115                         break;
116         }
117         printf("%u ", info->ttl);
118 }
119
120 static void print(const struct ipt_ip *ip,
121                 const struct ipt_entry_target *target, int numeric)
122 {
123         const struct ipt_TTL_info *info =
124                 (struct ipt_TTL_info *) target->data;
125
126         printf("TTL ");
127         switch (info->mode) {
128                 case IPT_TTL_SET:
129                         printf("set to ");
130                         break;
131                 case IPT_TTL_DEC:
132                         printf("decrement by ");
133                         break;
134                 case IPT_TTL_INC:
135                         printf("increment by ");
136                         break;
137         }
138         printf("%u ", info->ttl);
139 }
140
141 static struct option opts[] = {
142         { "ttl-set", 1, 0, '1' },
143         { "ttl-dec", 1, 0, '2' },
144         { "ttl-inc", 1, 0, '3' },
145         { 0 }
146 };
147
148 static struct iptables_target TTL = {
149         .next           = NULL, 
150         .name           = "TTL",
151         .version        = IPTABLES_VERSION,
152         .size           = IPT_ALIGN(sizeof(struct ipt_TTL_info)),
153         .userspacesize  = IPT_ALIGN(sizeof(struct ipt_TTL_info)),
154         .help           = &help,
155         .init           = &init,
156         .parse          = &parse,
157         .final_check    = &final_check,
158         .print          = &print,
159         .save           = &save,
160         .extra_opts     = opts 
161 };
162
163 void _init(void)
164 {
165         register_target(&TTL);
166 }