libip6t_frag.c revision 73866357e4a7a0fdc1b293bf8863fee2bd56da9e
1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Shared library add-on to ip6tables to add Fragmentation header support. */
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdbool.h>
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdio.h>
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <netdb.h>
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <string.h>
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdlib.h>
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <getopt.h>
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <errno.h>
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <xtables.h>
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <linux/netfilter_ipv6/ip6t_frag.h>
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void frag_help(void)
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	printf(
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org"frag match options:\n"
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org"[!] --fragid id[:id]           match the id (range)\n"
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org"[!] --fraglen length           total length of this header\n"
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org" --fragres                     check the reserved filed, too\n"
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org" --fragfirst                   matches on the first fragment\n"
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org" [--fragmore|--fraglast]       there are more fragments or this\n"
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org"                               is the last one\n");
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct option frag_opts[] = {
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{.name = "fragid",    .has_arg = true,  .val = '1'},
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{.name = "fraglen",   .has_arg = true,  .val = '2'},
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{.name = "fragres",   .has_arg = false, .val = '3'},
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{.name = "fragfirst", .has_arg = false, .val = '4'},
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{.name = "fragmore",  .has_arg = false, .val = '5'},
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{.name = "fraglast",  .has_arg = false, .val = '6'},
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	XT_GETOPT_TABLEEND,
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic uint32_t
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgparse_frag_id(const char *idstr, const char *typestr)
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned long int id;
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	char* ep;
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	id = strtoul(idstr, &ep, 0);
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ( idstr == ep ) {
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		xtables_error(PARAMETER_PROBLEM,
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   "FRAG no valid digits in %s `%s'", typestr, idstr);
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ( id == ULONG_MAX  && errno == ERANGE ) {
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		xtables_error(PARAMETER_PROBLEM,
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   "%s `%s' specified too big: would overflow",
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   typestr, idstr);
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ( *idstr != '\0'  && *ep != '\0' ) {
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		xtables_error(PARAMETER_PROBLEM,
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   "FRAG error parsing %s `%s'", typestr, idstr);
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return id;
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgparse_frag_ids(const char *idstring, uint32_t *ids)
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	char *buffer;
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	char *cp;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	buffer = strdup(idstring);
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ((cp = strchr(buffer, ':')) == NULL)
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ids[0] = ids[1] = parse_frag_id(buffer,"id");
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else {
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*cp = '\0';
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cp++;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ids[0] = buffer[0] ? parse_frag_id(buffer,"id") : 0;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ids[1] = cp[0] ? parse_frag_id(cp,"id") : 0xFFFFFFFF;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	free(buffer);
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void frag_init(struct xt_entry_match *m)
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct ip6t_frag *fraginfo = (struct ip6t_frag *)m->data;
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	fraginfo->ids[0] = 0x0L;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	fraginfo->ids[1] = 0xFFFFFFFF;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	fraginfo->hdrlen = 0;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	fraginfo->flags = 0;
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	fraginfo->invflags = 0;
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int frag_parse(int c, char **argv, int invert, unsigned int *flags,
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      const void *entry, struct xt_entry_match **match)
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct ip6t_frag *fraginfo = (struct ip6t_frag *)(*match)->data;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (c) {
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case '1':
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (*flags & IP6T_FRAG_IDS)
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			xtables_error(PARAMETER_PROBLEM,
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   "Only one `--fragid' allowed");
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		parse_frag_ids(optarg, fraginfo->ids);
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (invert)
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			fraginfo->invflags |= IP6T_FRAG_INV_IDS;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fraginfo->flags |= IP6T_FRAG_IDS;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*flags |= IP6T_FRAG_IDS;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case '2':
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (*flags & IP6T_FRAG_LEN)
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			xtables_error(PARAMETER_PROBLEM,
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   "Only one `--fraglen' allowed");
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fraginfo->hdrlen = parse_frag_id(optarg, "length");
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (invert)
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			fraginfo->invflags |= IP6T_FRAG_INV_LEN;
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fraginfo->flags |= IP6T_FRAG_LEN;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*flags |= IP6T_FRAG_LEN;
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case '3':
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (*flags & IP6T_FRAG_RES)
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			xtables_error(PARAMETER_PROBLEM,
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   "Only one `--fragres' allowed");
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fraginfo->flags |= IP6T_FRAG_RES;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*flags |= IP6T_FRAG_RES;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case '4':
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (*flags & IP6T_FRAG_FST)
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			xtables_error(PARAMETER_PROBLEM,
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   "Only one `--fragfirst' allowed");
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fraginfo->flags |= IP6T_FRAG_FST;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*flags |= IP6T_FRAG_FST;
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case '5':
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (*flags & (IP6T_FRAG_MF|IP6T_FRAG_NMF))
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			xtables_error(PARAMETER_PROBLEM,
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   "Only one `--fragmore' or `--fraglast' allowed");
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fraginfo->flags |= IP6T_FRAG_MF;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*flags |= IP6T_FRAG_MF;
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case '6':
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (*flags & (IP6T_FRAG_MF|IP6T_FRAG_NMF))
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			xtables_error(PARAMETER_PROBLEM,
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   "Only one `--fragmore' or `--fraglast' allowed");
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fraginfo->flags |= IP6T_FRAG_NMF;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*flags |= IP6T_FRAG_NMF;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 1;
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprint_ids(const char *name, uint32_t min, uint32_t max,
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    int invert)
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const char *inv = invert ? "!" : "";
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (min != 0 || max != 0xFFFFFFFF || invert) {
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf("%s", name);
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (min == max)
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			printf(":%s%u", inv, min);
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			printf("s:%s%u:%u", inv, min, max);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void frag_print(const void *ip, const struct xt_entry_match *match,
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       int numeric)
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct ip6t_frag *frag = (struct ip6t_frag *)match->data;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	printf(" frag ");
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	print_ids("id", frag->ids[0], frag->ids[1],
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    frag->invflags & IP6T_FRAG_INV_IDS);
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (frag->flags & IP6T_FRAG_LEN) {
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf(" length:%s%u",
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			frag->invflags & IP6T_FRAG_INV_LEN ? "!" : "",
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			frag->hdrlen);
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (frag->flags & IP6T_FRAG_RES)
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf(" reserved");
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (frag->flags & IP6T_FRAG_FST)
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf(" first");
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (frag->flags & IP6T_FRAG_MF)
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf(" more");
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (frag->flags & IP6T_FRAG_NMF)
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf(" last");
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (frag->invflags & ~IP6T_FRAG_INV_MASK)
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf(" Unknown invflags: 0x%X",
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       frag->invflags & ~IP6T_FRAG_INV_MASK);
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void frag_save(const void *ip, const struct xt_entry_match *match)
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct ip6t_frag *fraginfo = (struct ip6t_frag *)match->data;
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!(fraginfo->ids[0] == 0
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    && fraginfo->ids[1] == 0xFFFFFFFF)) {
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf("%s --fragid ",
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			(fraginfo->invflags & IP6T_FRAG_INV_IDS) ? " !" : "");
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (fraginfo->ids[0]
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    != fraginfo->ids[1])
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			printf("%u:%u",
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       fraginfo->ids[0],
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       fraginfo->ids[1]);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			printf("%u",
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       fraginfo->ids[0]);
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (fraginfo->flags & IP6T_FRAG_LEN) {
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf("%s --fraglen %u",
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			(fraginfo->invflags & IP6T_FRAG_INV_LEN) ? " !" : "",
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			fraginfo->hdrlen);
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (fraginfo->flags & IP6T_FRAG_RES)
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf(" --fragres");
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (fraginfo->flags & IP6T_FRAG_FST)
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf(" --fragfirst");
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (fraginfo->flags & IP6T_FRAG_MF)
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf(" --fragmore");
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (fraginfo->flags & IP6T_FRAG_NMF)
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		printf(" --fraglast");
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct xtables_match frag_mt6_reg = {
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	.name          = "frag",
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	.version       = XTABLES_VERSION,
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	.family        = NFPROTO_IPV6,
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	.size          = XT_ALIGN(sizeof(struct ip6t_frag)),
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	.userspacesize = XT_ALIGN(sizeof(struct ip6t_frag)),
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	.help          = frag_help,
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	.init          = frag_init,
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	.parse         = frag_parse,
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	.print         = frag_print,
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	.save          = frag_save,
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	.extra_opts    = frag_opts,
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_init(void)
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	xtables_register_match(&frag_mt6_reg);
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org