OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / user / iptables / extensions / libip6t_HL.c
1 /*
2  * IPv6 Hop Limit Target module
3  * Maciej Soltysiak <solt@dns.toxicfilms.tv>
4  * Based on HW's ttl target
5  * This program is distributed under the terms of GNU GPL
6  */
7
8 #include <getopt.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <xtables.h>
13
14 #include <linux/netfilter_ipv6/ip6t_HL.h>
15
16 #define IP6T_HL_USED    1
17
18 static void HL_help(void)
19 {
20         printf(
21 "HL target options\n"
22 "  --hl-set value               Set HL to <value 0-255>\n"
23 "  --hl-dec value               Decrement HL by <value 1-255>\n"
24 "  --hl-inc value               Increment HL by <value 1-255>\n");
25 }
26
27 static int HL_parse(int c, char **argv, int invert, unsigned int *flags,
28                     const void *entry, struct xt_entry_target **target)
29 {
30         struct ip6t_HL_info *info = (struct ip6t_HL_info *) (*target)->data;
31         unsigned int value;
32
33         if (*flags & IP6T_HL_USED) {
34                 xtables_error(PARAMETER_PROBLEM,
35                                 "Can't specify HL option twice");
36         }
37
38         if (!optarg) 
39                 xtables_error(PARAMETER_PROBLEM,
40                                 "HL: You must specify a value");
41
42         if (xtables_check_inverse(optarg, &invert, NULL, 0))
43                 xtables_error(PARAMETER_PROBLEM,
44                                 "HL: unexpected `!'");
45         
46         if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX))
47                 xtables_error(PARAMETER_PROBLEM,
48                            "HL: Expected value between 0 and 255");
49
50         switch (c) {
51
52                 case '1':
53                         info->mode = IP6T_HL_SET;
54                         break;
55
56                 case '2':
57                         if (value == 0) {
58                                 xtables_error(PARAMETER_PROBLEM,
59                                         "HL: decreasing by 0?");
60                         }
61
62                         info->mode = IP6T_HL_DEC;
63                         break;
64
65                 case '3':
66                         if (value == 0) {
67                                 xtables_error(PARAMETER_PROBLEM,
68                                         "HL: increasing by 0?");
69                         }
70
71                         info->mode = IP6T_HL_INC;
72                         break;
73
74                 default:
75                         return 0;
76
77         }
78         
79         info->hop_limit = value;
80         *flags |= IP6T_HL_USED;
81
82         return 1;
83 }
84
85 static void HL_check(unsigned int flags)
86 {
87         if (!(flags & IP6T_HL_USED))
88                 xtables_error(PARAMETER_PROBLEM,
89                                 "HL: You must specify an action");
90 }
91
92 static void HL_save(const void *ip, const struct xt_entry_target *target)
93 {
94         const struct ip6t_HL_info *info = 
95                 (struct ip6t_HL_info *) target->data;
96
97         switch (info->mode) {
98                 case IP6T_HL_SET:
99                         printf("--hl-set ");
100                         break;
101                 case IP6T_HL_DEC:
102                         printf("--hl-dec ");
103                         break;
104
105                 case IP6T_HL_INC:
106                         printf("--hl-inc ");
107                         break;
108         }
109         printf("%u ", info->hop_limit);
110 }
111
112 static void HL_print(const void *ip, const struct xt_entry_target *target,
113                      int numeric)
114 {
115         const struct ip6t_HL_info *info =
116                 (struct ip6t_HL_info *) target->data;
117
118         printf("HL ");
119         switch (info->mode) {
120                 case IP6T_HL_SET:
121                         printf("set to ");
122                         break;
123                 case IP6T_HL_DEC:
124                         printf("decrement by ");
125                         break;
126                 case IP6T_HL_INC:
127                         printf("increment by ");
128                         break;
129         }
130         printf("%u ", info->hop_limit);
131 }
132
133 static const struct option HL_opts[] = {
134         { "hl-set", 1, NULL, '1' },
135         { "hl-dec", 1, NULL, '2' },
136         { "hl-inc", 1, NULL, '3' },
137         { .name = NULL }
138 };
139
140 static struct xtables_target hl_tg6_reg = {
141         .name           = "HL",
142         .version        = XTABLES_VERSION,
143         .family         = NFPROTO_IPV6,
144         .size           = XT_ALIGN(sizeof(struct ip6t_HL_info)),
145         .userspacesize  = XT_ALIGN(sizeof(struct ip6t_HL_info)),
146         .help           = HL_help,
147         .parse          = HL_parse,
148         .final_check    = HL_check,
149         .print          = HL_print,
150         .save           = HL_save,
151         .extra_opts     = HL_opts,
152 };
153
154 void _init(void)
155 {
156         xtables_register_target(&hl_tg6_reg);
157 }