Merge to iptables-1.3.5
[iptables.git] / extensions / libipt_ttl.c
1 /* Shared library add-on to iptables to add TTL matching support 
2  * (C) 2000 by Harald Welte <laforge@gnumonks.org>
3  *
4  * $Id: libipt_ttl.c,v 1.1.1.3 2006/07/28 14:34:27 mlhuang Exp $
5  *
6  * This program is released under the terms of GNU GPL */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.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 static void help(void) 
18 {
19         printf(
20 "TTL match v%s options:\n"
21 "  --ttl-eq value       Match time to live value\n"
22 "  --ttl-lt value       Match TTL < value\n"
23 "  --ttl-gt value       Match TTL > value\n"
24 , IPTABLES_VERSION);
25 }
26
27 static int parse(int c, char **argv, int invert, unsigned int *flags,
28                 const struct ipt_entry *entry, unsigned int *nfcache,
29                 struct ipt_entry_match **match)
30 {
31         struct ipt_ttl_info *info = (struct ipt_ttl_info *) (*match)->data;
32         unsigned int value;
33
34         check_inverse(optarg, &invert, &optind, 0);
35
36         switch (c) {
37                 case '2':
38                         if (string_to_number(optarg, 0, 255, &value) == -1)
39                                 exit_error(PARAMETER_PROBLEM,
40                                            "ttl: Expected value between 0 and 255");
41
42                         if (invert)
43                                 info->mode = IPT_TTL_NE;
44                         else
45                                 info->mode = IPT_TTL_EQ;
46
47                         /* is 0 allowed? */
48                         info->ttl = value;
49                         break;
50                 case '3':
51                         if (string_to_number(optarg, 0, 255, &value) == -1)
52                                 exit_error(PARAMETER_PROBLEM,
53                                            "ttl: Expected value between 0 and 255");
54
55                         if (invert) 
56                                 exit_error(PARAMETER_PROBLEM,
57                                                 "ttl: unexpected `!'");
58
59                         info->mode = IPT_TTL_LT;
60                         info->ttl = value;
61                         break;
62                 case '4':
63                         if (string_to_number(optarg, 0, 255, &value) == -1)
64                                 exit_error(PARAMETER_PROBLEM,
65                                            "ttl: Expected value between 0 and 255");
66
67                         if (invert)
68                                 exit_error(PARAMETER_PROBLEM,
69                                                 "ttl: unexpected `!'");
70
71                         info->mode = IPT_TTL_GT;
72                         info->ttl = value;
73                         break;
74                 default:
75                         return 0;
76
77         }
78
79         if (*flags) 
80                 exit_error(PARAMETER_PROBLEM, 
81                                 "Can't specify TTL option twice");
82         *flags = 1;
83
84         return 1;
85 }
86
87 static void final_check(unsigned int flags)
88 {
89         if (!flags) 
90                 exit_error(PARAMETER_PROBLEM,
91                         "TTL match: You must specify one of "
92                         "`--ttl-eq', `--ttl-lt', `--ttl-gt");
93 }
94
95 static void print(const struct ipt_ip *ip, 
96                 const struct ipt_entry_match *match,
97                 int numeric)
98 {
99         const struct ipt_ttl_info *info = 
100                 (struct ipt_ttl_info *) match->data;
101
102         printf("TTL match ");
103         switch (info->mode) {
104                 case IPT_TTL_EQ:
105                         printf("TTL == ");
106                         break;
107                 case IPT_TTL_NE:
108                         printf("TTL != ");
109                         break;
110                 case IPT_TTL_LT:
111                         printf("TTL < ");
112                         break;
113                 case IPT_TTL_GT:
114                         printf("TTL > ");
115                         break;
116         }
117         printf("%u ", info->ttl);
118 }
119
120 static void save(const struct ipt_ip *ip, 
121                 const struct ipt_entry_match *match)
122 {
123         const struct ipt_ttl_info *info =
124                 (struct ipt_ttl_info *) match->data;
125
126         switch (info->mode) {
127                 case IPT_TTL_EQ:
128                         printf("--ttl-eq ");
129                         break;
130                 case IPT_TTL_NE:
131                         printf("! --ttl-eq ");
132                         break;
133                 case IPT_TTL_LT:
134                         printf("--ttl-lt ");
135                         break;
136                 case IPT_TTL_GT:
137                         printf("--ttl-gt ");
138                         break;
139                 default:
140                         /* error */
141                         break;
142         }
143         printf("%u ", info->ttl);
144 }
145
146 static struct option opts[] = {
147         { "ttl", 1, 0, '2' },
148         { "ttl-eq", 1, 0, '2'},
149         { "ttl-lt", 1, 0, '3'},
150         { "ttl-gt", 1, 0, '4'},
151         { 0 }
152 };
153
154 static struct iptables_match ttl = {
155         .next           = NULL,
156         .name           = "ttl",
157         .version        = IPTABLES_VERSION,
158         .size           = IPT_ALIGN(sizeof(struct ipt_ttl_info)),
159         .userspacesize  = IPT_ALIGN(sizeof(struct ipt_ttl_info)),
160         .help           = &help,
161         .parse          = &parse,
162         .final_check    = &final_check,
163         .print          = &print,
164         .save           = &save,
165         .extra_opts     = opts
166 };
167
168
169 void _init(void) 
170 {
171         register_match(&ttl);
172 }