libip6t_ah.c revision 500f483fff529dcd88ec96b9d5054be6cd6363a0
1d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte/* Shared library add-on to ip6tables to add AH support. */
2d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte#include <stdio.h>
3d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte#include <netdb.h>
4d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte#include <string.h>
5d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte#include <stdlib.h>
6d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte#include <getopt.h>
7d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte#include <errno.h>
8d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte#include <ip6tables.h>
9d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte#include <linux/netfilter_ipv6/ip6t_ah.h>
10d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
11d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte/* Function which prints out usage message. */
12d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltestatic void
13d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltehelp(void)
14d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{
15d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	printf(
16d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte"AH v%s options:\n"
17d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte" --ahspi [!] spi[:spi]         match spi (range)\n"
18d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte" --ahlen [!] length            total length of this header\n"
19d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte" --ahres                       check the reserved filed, too\n",
2080fe35d6339b53a12ddaec41885613e4e37ed031Harald WelteIPTABLES_VERSION);
21d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}
22d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
23661f112072bc13a1625c4eb5983695e122ea97daJan Engelhardtstatic const struct option opts[] = {
24500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy	{ .name = "ahspi", .has_arg = 1, .val = '1' },
25500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy	{ .name = "ahlen", .has_arg = 1, .val = '2' },
26500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy	{ .name = "ahres", .has_arg = 0, .val = '3' },
27500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy	{ }
28d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte};
29d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
30d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltestatic u_int32_t
31d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welteparse_ah_spi(const char *spistr, const char *typestr)
32d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{
33d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	unsigned long int spi;
34d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	char* ep;
35d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
36703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	spi = strtoul(spistr, &ep, 0);
37d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
38703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	if ( spistr == ep )
39d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		exit_error(PARAMETER_PROBLEM,
40d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			   "AH no valid digits in %s `%s'", typestr, spistr);
41703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette
42703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	if ( spi == ULONG_MAX  && errno == ERANGE )
43d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		exit_error(PARAMETER_PROBLEM,
44d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			   "%s `%s' specified too big: would overflow",
45d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			   typestr, spistr);
46703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette
47703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	if ( *spistr != '\0'  && *ep != '\0' )
48d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		exit_error(PARAMETER_PROBLEM,
49d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			   "AH error parsing %s `%s'", typestr, spistr);
50703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette
51d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	return (u_int32_t) spi;
52d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}
53d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
54d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltestatic void
55d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welteparse_ah_spis(const char *spistring, u_int32_t *spis)
56d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{
57d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	char *buffer;
58d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	char *cp;
59d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
60d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	buffer = strdup(spistring);
61d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	if ((cp = strchr(buffer, ':')) == NULL)
62703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette		spis[0] = spis[1] = parse_ah_spi(buffer, "spi");
63d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	else {
64d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		*cp = '\0';
65d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		cp++;
66d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
67703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette		spis[0] = buffer[0] ? parse_ah_spi(buffer, "spi") : 0;
68703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette		spis[1] = cp[0] ? parse_ah_spi(cp, "spi") : 0xFFFFFFFF;
69d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	}
70d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	free(buffer);
71d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}
72d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
73d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte/* Initialize the match. */
74d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltestatic void
75ea146a982e26c42f9954f140276f8deeb2edbe98Peter Rileyinit(struct xt_entry_match *m)
76d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{
77d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	struct ip6t_ah *ahinfo = (struct ip6t_ah *)m->data;
78d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
79d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	ahinfo->spis[1] = 0xFFFFFFFF;
80d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	ahinfo->hdrlen = 0;
81d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	ahinfo->hdrres = 0;
82d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}
83d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
84d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte/* Function which parses command options; returns true if it
85d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte   ate an option */
86d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltestatic int
87d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welteparse(int c, char **argv, int invert, unsigned int *flags,
88a620c61d441b931bc4a52ec07f1b906318ee4069Yasuyuki KOZAKAI      const void *entry,
89b85256b07a2939d712a2547bc151653eae511909Yasuyuki KOZAKAI      struct xt_entry_match **match)
90d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{
91d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	struct ip6t_ah *ahinfo = (struct ip6t_ah *)(*match)->data;
92d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
93d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	switch (c) {
94d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	case '1':
95d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		if (*flags & IP6T_AH_SPI)
96d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			exit_error(PARAMETER_PROBLEM,
97d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte				   "Only one `--ahspi' allowed");
98d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		check_inverse(optarg, &invert, &optind, 0);
99d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		parse_ah_spis(argv[optind-1], ahinfo->spis);
100d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		if (invert)
101d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			ahinfo->invflags |= IP6T_AH_INV_SPI;
102d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		*flags |= IP6T_AH_SPI;
103d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		break;
104d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	case '2':
105d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		if (*flags & IP6T_AH_LEN)
106d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			exit_error(PARAMETER_PROBLEM,
107d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte				   "Only one `--ahlen' allowed");
108d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		check_inverse(optarg, &invert, &optind, 0);
109d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		ahinfo->hdrlen = parse_ah_spi(argv[optind-1], "length");
110d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		if (invert)
111d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			ahinfo->invflags |= IP6T_AH_INV_LEN;
112d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		*flags |= IP6T_AH_LEN;
113d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		break;
114d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	case '3':
115d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		if (*flags & IP6T_AH_RES)
116d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			exit_error(PARAMETER_PROBLEM,
117d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte				   "Only one `--ahres' allowed");
118d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		ahinfo->hdrres = 1;
119d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		*flags |= IP6T_AH_RES;
120d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		break;
121d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	default:
122d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		return 0;
123d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	}
124d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
125d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	return 1;
126d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}
127d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
128d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte/* Final check; we don't care. */
129d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltestatic void
130d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltefinal_check(unsigned int flags)
131d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{
132d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}
133d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
134d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltestatic void
135d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welteprint_spis(const char *name, u_int32_t min, u_int32_t max,
136d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	    int invert)
137d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{
138d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	const char *inv = invert ? "!" : "";
139d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
140d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	if (min != 0 || max != 0xFFFFFFFF || invert) {
141703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette		if (min == max)
142703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette			printf("%s:%s%u ", name, inv, min);
143703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette		else
144703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette			printf("%ss:%s%u:%u ", name, inv, min, max);
145d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	}
146d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}
147d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
148d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltestatic void
149d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welteprint_len(const char *name, u_int32_t len, int invert)
150d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{
151d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	const char *inv = invert ? "!" : "";
152d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
153703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	if (len != 0 || invert)
154703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette		printf("%s:%s%u ", name, inv, len);
155d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}
156d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
157d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte/* Prints out the union ip6t_matchinfo. */
158d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltestatic void
159a620c61d441b931bc4a52ec07f1b906318ee4069Yasuyuki KOZAKAIprint(const void *ip,
160b85256b07a2939d712a2547bc151653eae511909Yasuyuki KOZAKAI      const struct xt_entry_match *match, int numeric)
161d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{
162d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	const struct ip6t_ah *ah = (struct ip6t_ah *)match->data;
163d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
164d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	printf("ah ");
165d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	print_spis("spi", ah->spis[0], ah->spis[1],
166d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		    ah->invflags & IP6T_AH_INV_SPI);
167d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	print_len("length", ah->hdrlen,
168d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		    ah->invflags & IP6T_AH_INV_LEN);
169703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette
170703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	if (ah->hdrres)
171703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette		printf("reserved ");
172703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette
173d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	if (ah->invflags & ~IP6T_AH_INV_MASK)
174d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		printf("Unknown invflags: 0x%X ",
175d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		       ah->invflags & ~IP6T_AH_INV_MASK);
176d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}
177d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
178d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte/* Saves the union ip6t_matchinfo in parsable form to stdout. */
179a620c61d441b931bc4a52ec07f1b906318ee4069Yasuyuki KOZAKAIstatic void save(const void *ip, const struct xt_entry_match *match)
180d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{
181d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	const struct ip6t_ah *ahinfo = (struct ip6t_ah *)match->data;
182d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
183d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	if (!(ahinfo->spis[0] == 0
184d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	    && ahinfo->spis[1] == 0xFFFFFFFF)) {
185d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		printf("--ahspi %s",
186d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			(ahinfo->invflags & IP6T_AH_INV_SPI) ? "! " : "");
187d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		if (ahinfo->spis[0]
188d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		    != ahinfo->spis[1])
189d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			printf("%u:%u ",
190d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			       ahinfo->spis[0],
191d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			       ahinfo->spis[1]);
192d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		else
193d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			printf("%u ",
194d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			       ahinfo->spis[0]);
195d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	}
196d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
197d8a12a841de648bd38dc52ba624d1ed1810a6333András Kis-Szabó	if (ahinfo->hdrlen != 0 || (ahinfo->invflags & IP6T_AH_INV_LEN) ) {
198d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		printf("--ahlen %s%u ",
199d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			(ahinfo->invflags & IP6T_AH_INV_LEN) ? "! " : "",
200d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte			ahinfo->hdrlen);
201d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	}
202d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
203703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	if (ahinfo->hdrres != 0 )
204d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte		printf("--ahres ");
205d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}
206d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
207d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltestatic
208703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellettestruct ip6tables_match ah = {
209703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	.name          = "ah",
210703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	.version       = IPTABLES_VERSION,
211703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	.size          = IP6T_ALIGN(sizeof(struct ip6t_ah)),
212703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	.userspacesize = IP6T_ALIGN(sizeof(struct ip6t_ah)),
213703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	.help          = &help,
214703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	.init          = &init,
215703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	.parse         = &parse,
216703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	.final_check   = &final_check,
217703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	.print         = &print,
218703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	.save          = &save,
219703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette	.extra_opts    = opts
220d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte};
221d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte
222d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltevoid
223d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte_init(void)
224d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{
225d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte	register_match6(&ah);
226d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}
227