1 /* Shared library add-on to ip6tables to add mobility header support. */
3 * Copyright (C)2006 USAGI/WIDE Project
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
10 * Masahide NAKAMURA @USAGI <masahide.nakamura.cz@hitachi.com>
12 * Based on libip6t_{icmpv6,udp}.c
19 #include <ip6tables.h>
20 #include <linux/netfilter_ipv6/ip6_tables.h>
21 #include <linux/netfilter_ipv6/ip6t_mh.h>
28 static const struct mh_name mh_names
[] = {
29 { "binding-refresh-request", 0, },
30 /* Alias */ { "brr", 0, },
31 { "home-test-init", 1, },
32 /* Alias */ { "hoti", 1, },
33 { "careof-test-init", 2, },
34 /* Alias */ { "coti", 2, },
36 /* Alias */ { "hot", 3, },
37 { "careof-test", 4, },
38 /* Alias */ { "cot", 4, },
39 { "binding-update", 5, },
40 /* Alias */ { "bu", 5, },
41 { "binding-acknowledgement", 6, },
42 /* Alias */ { "ba", 6, },
43 { "binding-error", 7, },
44 /* Alias */ { "be", 7, },
47 static void print_types_all(void)
50 printf("Valid MH types:");
52 for (i
= 0; i
< sizeof(mh_names
)/sizeof(struct mh_name
); i
++) {
53 if (i
&& mh_names
[i
].type
== mh_names
[i
-1].type
)
54 printf(" (%s)", mh_names
[i
].name
);
56 printf("\n%s", mh_names
[i
].name
);
61 static void help(void)
65 " --mh-type [!] type[:type] match mh type\n",
70 static void init(struct ip6t_entry_match
*m
, unsigned int *nfcache
)
72 struct ip6t_mh
*mhinfo
= (struct ip6t_mh
*)m
->data
;
74 mhinfo
->types
[1] = 0xFF;
77 static unsigned int name_to_type(const char *name
)
79 int namelen
= strlen(name
);
80 unsigned int limit
= sizeof(mh_names
)/sizeof(struct mh_name
);
81 unsigned int match
= limit
;
84 for (i
= 0; i
< limit
; i
++) {
85 if (strncasecmp(mh_names
[i
].name
, name
, namelen
) == 0) {
86 int len
= strlen(mh_names
[i
].name
);
87 if (match
== limit
|| len
== namelen
)
93 return mh_names
[match
].type
;
97 if (string_to_number(name
, 0, 255, &number
) == -1)
98 exit_error(PARAMETER_PROBLEM
,
99 "Invalid MH type `%s'\n", name
);
104 static void parse_mh_types(const char *mhtype
, u_int8_t
*types
)
109 buffer
= strdup(mhtype
);
110 if ((cp
= strchr(buffer
, ':')) == NULL
)
111 types
[0] = types
[1] = name_to_type(buffer
);
116 types
[0] = buffer
[0] ? name_to_type(buffer
) : 0;
117 types
[1] = cp
[0] ? name_to_type(cp
) : 0xFF;
119 if (types
[0] > types
[1])
120 exit_error(PARAMETER_PROBLEM
,
121 "Invalid MH type range (min > max)");
126 #define MH_TYPES 0x01
128 static int parse(int c
, char **argv
, int invert
, unsigned int *flags
,
129 const struct ip6t_entry
*entry
,
130 unsigned int *nfcache
,
131 struct ip6t_entry_match
**match
)
133 struct ip6t_mh
*mhinfo
= (struct ip6t_mh
*)(*match
)->data
;
137 if (*flags
& MH_TYPES
)
138 exit_error(PARAMETER_PROBLEM
,
139 "Only one `--mh-type' allowed");
140 check_inverse(optarg
, &invert
, &optind
, 0);
141 parse_mh_types(argv
[optind
-1], mhinfo
->types
);
143 mhinfo
->invflags
|= IP6T_MH_INV_TYPE
;
154 /* Final check; we don't care. */
155 static void final_check(unsigned int flags
)
159 static const char *type_to_name(u_int8_t type
)
163 for (i
= 0; i
< sizeof(mh_names
)/sizeof(struct mh_name
); i
++) {
164 if (mh_names
[i
].type
== type
)
165 return mh_names
[i
].name
;
171 static void print_type(u_int8_t type
, int numeric
)
174 if (numeric
|| !(name
= type_to_name(type
)))
180 static void print_types(u_int8_t min
, u_int8_t max
, int invert
, int numeric
)
182 const char *inv
= invert
? "!" : "";
184 if (min
!= 0 || max
!= 0xFF || invert
) {
187 print_type(min
, numeric
);
190 print_type(min
, numeric
);
192 print_type(max
, numeric
);
198 static void print(const struct ip6t_ip6
*ip
,
199 const struct ip6t_entry_match
*match
,
202 const struct ip6t_mh
*mhinfo
= (struct ip6t_mh
*)match
->data
;
205 print_types(mhinfo
->types
[0], mhinfo
->types
[1],
206 mhinfo
->invflags
& IP6T_MH_INV_TYPE
,
208 if (mhinfo
->invflags
& ~IP6T_MH_INV_MASK
)
209 printf("Unknown invflags: 0x%X ",
210 mhinfo
->invflags
& ~IP6T_MH_INV_MASK
);
213 static void save(const struct ip6t_ip6
*ip
,
214 const struct ip6t_entry_match
*match
)
216 const struct ip6t_mh
*mhinfo
= (struct ip6t_mh
*)match
->data
;
218 if (mhinfo
->types
[0] == 0 && mhinfo
->types
[1] == 0xFF)
221 if (mhinfo
->invflags
& IP6T_MH_INV_TYPE
)
224 if (mhinfo
->types
[0] != mhinfo
->types
[1])
225 printf("--mh-type %u:%u ", mhinfo
->types
[0], mhinfo
->types
[1]);
227 printf("--mh-type %u ", mhinfo
->types
[0]);
230 static struct option opts
[] = {
231 { "mh-type", 1, 0, '1' },
235 static struct ip6tables_match mh
= {
237 .version
= IPTABLES_VERSION
,
238 .size
= IP6T_ALIGN(sizeof(struct ip6t_mh
)),
239 .userspacesize
= IP6T_ALIGN(sizeof(struct ip6t_mh
)),
243 .final_check
= &final_check
,
251 register_match6(&mh
);