iptables-1.2.9-2.3.1.src.rpm
[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.6 2002/05/29 13:08:16 laforge 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 void init(struct ipt_entry_match *m, unsigned int *nfcache)
28 {
29         /* caching not yet implemented */
30         *nfcache |= NFC_UNKNOWN;
31 }
32
33 static int parse(int c, char **argv, int invert, unsigned int *flags,
34                 const struct ipt_entry *entry, unsigned int *nfcache,
35                 struct ipt_entry_match **match)
36 {
37         struct ipt_ttl_info *info = (struct ipt_ttl_info *) (*match)->data;
38         u_int8_t value;
39
40         check_inverse(optarg, &invert, &optind, 0);
41         value = atoi(argv[optind-1]);
42
43         if (*flags) 
44                 exit_error(PARAMETER_PROBLEM, 
45                                 "Can't specify TTL option twice");
46
47         if (!optarg)
48                 exit_error(PARAMETER_PROBLEM,
49                                 "ttl: You must specify a value");
50         switch (c) {
51                 case '2':
52                         if (invert)
53                                 info->mode = IPT_TTL_NE;
54                         else
55                                 info->mode = IPT_TTL_EQ;
56
57                         /* is 0 allowed? */
58                         info->ttl = value;
59                         *flags = 1;
60
61                         break;
62                 case '3':
63                         if (invert) 
64                                 exit_error(PARAMETER_PROBLEM,
65                                                 "ttl: unexpected `!'");
66
67                         info->mode = IPT_TTL_LT;
68                         info->ttl = value;
69                         *flags = 1;
70
71                         break;
72                 case '4':
73                         if (invert)
74                                 exit_error(PARAMETER_PROBLEM,
75                                                 "ttl: unexpected `!'");
76
77                         info->mode = IPT_TTL_GT;
78                         info->ttl = value;
79                         *flags = 1;
80
81                         break;
82                 default:
83                         return 0;
84
85         }
86
87         return 1;
88 }
89
90 static void final_check(unsigned int flags)
91 {
92         if (!flags) 
93                 exit_error(PARAMETER_PROBLEM,
94                         "TTL match: You must specify one of "
95                         "`--ttl-eq', `--ttl-lt', `--ttl-gt");
96 }
97
98 static void print(const struct ipt_ip *ip, 
99                 const struct ipt_entry_match *match,
100                 int numeric)
101 {
102         const struct ipt_ttl_info *info = 
103                 (struct ipt_ttl_info *) match->data;
104
105         printf("TTL match ");
106         switch (info->mode) {
107                 case IPT_TTL_EQ:
108                         printf("TTL == ");
109                         break;
110                 case IPT_TTL_NE:
111                         printf("TTL != ");
112                         break;
113                 case IPT_TTL_LT:
114                         printf("TTL < ");
115                         break;
116                 case IPT_TTL_GT:
117                         printf("TTL > ");
118                         break;
119         }
120         printf("%u ", info->ttl);
121 }
122
123 static void save(const struct ipt_ip *ip, 
124                 const struct ipt_entry_match *match)
125 {
126         const struct ipt_ttl_info *info =
127                 (struct ipt_ttl_info *) match->data;
128
129         switch (info->mode) {
130                 case IPT_TTL_EQ:
131                         printf("--ttl-eq ");
132                         break;
133                 case IPT_TTL_NE:
134                         printf("! --ttl-eq ");
135                         break;
136                 case IPT_TTL_LT:
137                         printf("--ttl-lt ");
138                         break;
139                 case IPT_TTL_GT:
140                         printf("--ttl-gt ");
141                         break;
142                 default:
143                         /* error */
144                         break;
145         }
146         printf("%u ", info->ttl);
147 }
148
149 static struct option opts[] = {
150         { "ttl", 1, 0, '2' },
151         { "ttl-eq", 1, 0, '2'},
152         { "ttl-lt", 1, 0, '3'},
153         { "ttl-gt", 1, 0, '4'},
154         { 0 }
155 };
156
157 static
158 struct iptables_match ttl = {
159         NULL,
160         "ttl",
161         IPTABLES_VERSION,
162         IPT_ALIGN(sizeof(struct ipt_ttl_info)),
163         IPT_ALIGN(sizeof(struct ipt_ttl_info)),
164         &help,
165         &init,
166         &parse,
167         &final_check,
168         &print,
169         &save,
170         opts
171 };
172
173
174 void _init(void) 
175 {
176         register_match(&ttl);
177 }