iptables-1.2.9-2.3.1.src.rpm
[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,v 1.6 2002/05/29 13:08:16 laforge Exp $
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>\n"
28 "  --ttl-dec value              Decrement TTL by <value>\n"
29 "  --ttl-inc value              Increment TTL by <value>\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         u_int8_t 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         value = atoi(optarg);
54
55         switch (c) {
56
57                 case '1':
58                         info->mode = IPT_TTL_SET;
59                         break;
60
61                 case '2':
62                         if (value == 0) {
63                                 exit_error(PARAMETER_PROBLEM,
64                                         "TTL: decreasing by 0?");
65                         }
66
67                         info->mode = IPT_TTL_DEC;
68                         break;
69
70                 case '3':
71                         if (value == 0) {
72                                 exit_error(PARAMETER_PROBLEM,
73                                         "TTL: increasing by 0?");
74                         }
75
76                         info->mode = IPT_TTL_INC;
77                         break;
78
79                 default:
80                         return 0;
81
82         }
83         
84         info->ttl = value;
85         *flags |= IPT_TTL_USED;
86
87         return 1;
88 }
89
90 static void final_check(unsigned int flags)
91 {
92         if (!(flags & IPT_TTL_USED))
93                 exit_error(PARAMETER_PROBLEM,
94                                 "TTL: You must specify an action");
95 }
96
97 static void save(const struct ipt_ip *ip,
98                 const struct ipt_entry_target *target)
99 {
100         const struct ipt_TTL_info *info = 
101                 (struct ipt_TTL_info *) target->data;
102
103         switch (info->mode) {
104                 case IPT_TTL_SET:
105                         printf("--ttl-set ");
106                         break;
107                 case IPT_TTL_DEC:
108                         printf("--ttl-dec ");
109                         break;
110
111                 case IPT_TTL_INC:
112                         printf("--ttl-inc ");
113                         break;
114         }
115         printf("%u ", info->ttl);
116 }
117
118 static void print(const struct ipt_ip *ip,
119                 const struct ipt_entry_target *target, int numeric)
120 {
121         const struct ipt_TTL_info *info =
122                 (struct ipt_TTL_info *) target->data;
123
124         printf("TTL ");
125         switch (info->mode) {
126                 case IPT_TTL_SET:
127                         printf("set to ");
128                         break;
129                 case IPT_TTL_DEC:
130                         printf("decrement by ");
131                         break;
132                 case IPT_TTL_INC:
133                         printf("increment by ");
134                         break;
135         }
136         printf("%u ", info->ttl);
137 }
138
139 static struct option opts[] = {
140         { "ttl-set", 1, 0, '1' },
141         { "ttl-dec", 1, 0, '2' },
142         { "ttl-inc", 1, 0, '3' },
143         { 0 }
144 };
145
146 static
147 struct iptables_target TTL = { NULL, 
148         "TTL",
149         IPTABLES_VERSION,
150         IPT_ALIGN(sizeof(struct ipt_TTL_info)),
151         IPT_ALIGN(sizeof(struct ipt_TTL_info)),
152         &help,
153         &init,
154         &parse,
155         &final_check,
156         &print,
157         &save,
158         opts 
159 };
160
161 void _init(void)
162 {
163         register_target(&TTL);
164 }