2391986841d37b65b85cfd527f5ba5ce5335f6c3
[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 3687 2005-02-14 13:13:04Z /C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=kaber/emailAddress=kaber@netfilter.org $
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         int value;
33
34         check_inverse(optarg, &invert, &optind, 0);
35
36         if (string_to_number(optarg, 0, 255, &value) == -1)
37                 exit_error(PARAMETER_PROBLEM,
38                            "ttl: Expected value between 0 and 255");
39
40         switch (c) {
41                 case '2':
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 (invert) 
52                                 exit_error(PARAMETER_PROBLEM,
53                                                 "ttl: unexpected `!'");
54
55                         info->mode = IPT_TTL_LT;
56                         info->ttl = value;
57                         break;
58                 case '4':
59                         if (invert)
60                                 exit_error(PARAMETER_PROBLEM,
61                                                 "ttl: unexpected `!'");
62
63                         info->mode = IPT_TTL_GT;
64                         info->ttl = value;
65                         break;
66                 default:
67                         return 0;
68
69         }
70
71         if (*flags) 
72                 exit_error(PARAMETER_PROBLEM, 
73                                 "Can't specify TTL option twice");
74         *flags = 1;
75
76         return 1;
77 }
78
79 static void final_check(unsigned int flags)
80 {
81         if (!flags) 
82                 exit_error(PARAMETER_PROBLEM,
83                         "TTL match: You must specify one of "
84                         "`--ttl-eq', `--ttl-lt', `--ttl-gt");
85 }
86
87 static void print(const struct ipt_ip *ip, 
88                 const struct ipt_entry_match *match,
89                 int numeric)
90 {
91         const struct ipt_ttl_info *info = 
92                 (struct ipt_ttl_info *) match->data;
93
94         printf("TTL match ");
95         switch (info->mode) {
96                 case IPT_TTL_EQ:
97                         printf("TTL == ");
98                         break;
99                 case IPT_TTL_NE:
100                         printf("TTL != ");
101                         break;
102                 case IPT_TTL_LT:
103                         printf("TTL < ");
104                         break;
105                 case IPT_TTL_GT:
106                         printf("TTL > ");
107                         break;
108         }
109         printf("%u ", info->ttl);
110 }
111
112 static void save(const struct ipt_ip *ip, 
113                 const struct ipt_entry_match *match)
114 {
115         const struct ipt_ttl_info *info =
116                 (struct ipt_ttl_info *) match->data;
117
118         switch (info->mode) {
119                 case IPT_TTL_EQ:
120                         printf("--ttl-eq ");
121                         break;
122                 case IPT_TTL_NE:
123                         printf("! --ttl-eq ");
124                         break;
125                 case IPT_TTL_LT:
126                         printf("--ttl-lt ");
127                         break;
128                 case IPT_TTL_GT:
129                         printf("--ttl-gt ");
130                         break;
131                 default:
132                         /* error */
133                         break;
134         }
135         printf("%u ", info->ttl);
136 }
137
138 static struct option opts[] = {
139         { "ttl", 1, 0, '2' },
140         { "ttl-eq", 1, 0, '2'},
141         { "ttl-lt", 1, 0, '3'},
142         { "ttl-gt", 1, 0, '4'},
143         { 0 }
144 };
145
146 static struct iptables_match ttl = {
147         .next           = NULL,
148         .name           = "ttl",
149         .version        = IPTABLES_VERSION,
150         .size           = IPT_ALIGN(sizeof(struct ipt_ttl_info)),
151         .userspacesize  = IPT_ALIGN(sizeof(struct ipt_ttl_info)),
152         .help           = &help,
153         .parse          = &parse,
154         .final_check    = &final_check,
155         .print          = &print,
156         .save           = &save,
157         .extra_opts     = opts
158 };
159
160
161 void _init(void) 
162 {
163         register_match(&ttl);
164 }