blob: 12794e4280701e254f25e4e1aed95df716146fc4 [file] [log] [blame]
András Kis-Szabóf1f447b2002-03-26 12:45:19 +00001#include <stdio.h>
Jan Engelhardt5d9678a2008-11-20 10:15:35 +01002#include <xtables.h>
András Kis-Szabóf1f447b2002-03-26 12:45:19 +00003#include <linux/netfilter_ipv6/ip6t_frag.h>
Jan Engelhardtddac6c52008-09-01 14:22:19 +02004
Jan Engelhardt7c51e382011-02-18 02:17:54 +01005enum {
6 O_FRAGID = 0,
7 O_FRAGLEN,
8 O_FRAGRES,
9 O_FRAGFIRST,
10 O_FRAGMORE,
11 O_FRAGLAST,
12 F_FRAGMORE = 1 << O_FRAGMORE,
13 F_FRAGLAST = 1 << O_FRAGLAST,
14};
15
Jan Engelhardt997045f2007-10-04 16:29:21 +000016static void frag_help(void)
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000017{
18 printf(
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020019"frag match options:\n"
Jan Engelhardt96727922008-08-13 14:42:41 +020020"[!] --fragid id[:id] match the id (range)\n"
21"[!] --fraglen length total length of this header\n"
Jan Engelhardt12a18d62011-02-18 01:45:05 +010022" --fragres check the reserved field too\n"
András Kis-Szabód8a12a82002-04-24 09:36:30 +000023" --fragfirst matches on the first fragment\n"
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000024" [--fragmore|--fraglast] there are more fragments or this\n"
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020025" is the last one\n");
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000026}
27
Jan Engelhardt7c51e382011-02-18 02:17:54 +010028#define s struct ip6t_frag
29static const struct xt_option_entry frag_opts[] = {
30 {.name = "fragid", .id = O_FRAGID, .type = XTTYPE_UINT32RC,
31 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, ids)},
32 {.name = "fraglen", .id = O_FRAGLEN, .type = XTTYPE_UINT32,
33 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdrlen)},
34 {.name = "fragres", .id = O_FRAGRES, .type = XTTYPE_NONE},
35 {.name = "fragfirst", .id = O_FRAGFIRST, .type = XTTYPE_NONE},
36 {.name = "fragmore", .id = O_FRAGMORE, .type = XTTYPE_NONE,
37 .excl = F_FRAGLAST},
38 {.name = "fraglast", .id = O_FRAGLAST, .type = XTTYPE_NONE,
39 .excl = F_FRAGMORE},
40 XTOPT_TABLEEND,
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000041};
Jan Engelhardt7c51e382011-02-18 02:17:54 +010042#undef s
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000043
Jan Engelhardt997045f2007-10-04 16:29:21 +000044static void frag_init(struct xt_entry_match *m)
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000045{
46 struct ip6t_frag *fraginfo = (struct ip6t_frag *)m->data;
47
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000048 fraginfo->ids[1] = 0xFFFFFFFF;
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000049}
50
Jan Engelhardt7c51e382011-02-18 02:17:54 +010051static void frag_parse(struct xt_option_call *cb)
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000052{
Jan Engelhardt7c51e382011-02-18 02:17:54 +010053 struct ip6t_frag *fraginfo = cb->data;
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000054
Jan Engelhardt7c51e382011-02-18 02:17:54 +010055 xtables_option_parse(cb);
56 switch (cb->entry->id) {
57 case O_FRAGRES:
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000058 fraginfo->flags |= IP6T_FRAG_RES;
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000059 break;
Jan Engelhardt7c51e382011-02-18 02:17:54 +010060 case O_FRAGFIRST:
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000061 fraginfo->flags |= IP6T_FRAG_FST;
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000062 break;
Jan Engelhardt7c51e382011-02-18 02:17:54 +010063 case O_FRAGMORE:
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000064 fraginfo->flags |= IP6T_FRAG_MF;
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000065 break;
Jan Engelhardt7c51e382011-02-18 02:17:54 +010066 case O_FRAGLAST:
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000067 fraginfo->flags |= IP6T_FRAG_NMF;
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000068 break;
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000069 }
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000070}
71
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000072static void
Jan Engelhardt7ac40522011-01-07 12:34:04 +010073print_ids(const char *name, uint32_t min, uint32_t max,
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000074 int invert)
75{
76 const char *inv = invert ? "!" : "";
77
78 if (min != 0 || max != 0xFFFFFFFF || invert) {
79 printf("%s", name);
Harald Welte46a73cf2003-09-05 12:53:44 +000080 if (min == max)
Jan Engelhardt73866352010-12-18 02:04:59 +010081 printf(":%s%u", inv, min);
Harald Welte46a73cf2003-09-05 12:53:44 +000082 else
Jan Engelhardt73866352010-12-18 02:04:59 +010083 printf("s:%s%u:%u", inv, min, max);
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000084 }
85}
86
Jan Engelhardt997045f2007-10-04 16:29:21 +000087static void frag_print(const void *ip, const struct xt_entry_match *match,
88 int numeric)
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000089{
90 const struct ip6t_frag *frag = (struct ip6t_frag *)match->data;
91
Jan Engelhardt73866352010-12-18 02:04:59 +010092 printf(" frag ");
András Kis-Szabóf1f447b2002-03-26 12:45:19 +000093 print_ids("id", frag->ids[0], frag->ids[1],
94 frag->invflags & IP6T_FRAG_INV_IDS);
Harald Welte46a73cf2003-09-05 12:53:44 +000095
András Kis-Szabód8a12a82002-04-24 09:36:30 +000096 if (frag->flags & IP6T_FRAG_LEN) {
Jan Engelhardt73866352010-12-18 02:04:59 +010097 printf(" length:%s%u",
Harald Welte46a73cf2003-09-05 12:53:44 +000098 frag->invflags & IP6T_FRAG_INV_LEN ? "!" : "",
99 frag->hdrlen);
András Kis-Szabód8a12a82002-04-24 09:36:30 +0000100 }
Harald Welte46a73cf2003-09-05 12:53:44 +0000101
102 if (frag->flags & IP6T_FRAG_RES)
Jan Engelhardt73866352010-12-18 02:04:59 +0100103 printf(" reserved");
Harald Welte46a73cf2003-09-05 12:53:44 +0000104
105 if (frag->flags & IP6T_FRAG_FST)
Jan Engelhardt73866352010-12-18 02:04:59 +0100106 printf(" first");
Harald Welte46a73cf2003-09-05 12:53:44 +0000107
108 if (frag->flags & IP6T_FRAG_MF)
Jan Engelhardt73866352010-12-18 02:04:59 +0100109 printf(" more");
Harald Welte46a73cf2003-09-05 12:53:44 +0000110
111 if (frag->flags & IP6T_FRAG_NMF)
Jan Engelhardt73866352010-12-18 02:04:59 +0100112 printf(" last");
Harald Welte46a73cf2003-09-05 12:53:44 +0000113
András Kis-Szabóf1f447b2002-03-26 12:45:19 +0000114 if (frag->invflags & ~IP6T_FRAG_INV_MASK)
Jan Engelhardt73866352010-12-18 02:04:59 +0100115 printf(" Unknown invflags: 0x%X",
András Kis-Szabóf1f447b2002-03-26 12:45:19 +0000116 frag->invflags & ~IP6T_FRAG_INV_MASK);
117}
118
Jan Engelhardt997045f2007-10-04 16:29:21 +0000119static void frag_save(const void *ip, const struct xt_entry_match *match)
András Kis-Szabóf1f447b2002-03-26 12:45:19 +0000120{
121 const struct ip6t_frag *fraginfo = (struct ip6t_frag *)match->data;
122
123 if (!(fraginfo->ids[0] == 0
124 && fraginfo->ids[1] == 0xFFFFFFFF)) {
Jan Engelhardt73866352010-12-18 02:04:59 +0100125 printf("%s --fragid ",
126 (fraginfo->invflags & IP6T_FRAG_INV_IDS) ? " !" : "");
András Kis-Szabóf1f447b2002-03-26 12:45:19 +0000127 if (fraginfo->ids[0]
128 != fraginfo->ids[1])
Jan Engelhardt73866352010-12-18 02:04:59 +0100129 printf("%u:%u",
András Kis-Szabóf1f447b2002-03-26 12:45:19 +0000130 fraginfo->ids[0],
131 fraginfo->ids[1]);
132 else
Jan Engelhardt73866352010-12-18 02:04:59 +0100133 printf("%u",
András Kis-Szabóf1f447b2002-03-26 12:45:19 +0000134 fraginfo->ids[0]);
135 }
136
András Kis-Szabód8a12a82002-04-24 09:36:30 +0000137 if (fraginfo->flags & IP6T_FRAG_LEN) {
Jan Engelhardt73866352010-12-18 02:04:59 +0100138 printf("%s --fraglen %u",
139 (fraginfo->invflags & IP6T_FRAG_INV_LEN) ? " !" : "",
András Kis-Szabóf1f447b2002-03-26 12:45:19 +0000140 fraginfo->hdrlen);
141 }
142
Harald Welte46a73cf2003-09-05 12:53:44 +0000143 if (fraginfo->flags & IP6T_FRAG_RES)
Jan Engelhardt73866352010-12-18 02:04:59 +0100144 printf(" --fragres");
András Kis-Szabóf1f447b2002-03-26 12:45:19 +0000145
Harald Welte46a73cf2003-09-05 12:53:44 +0000146 if (fraginfo->flags & IP6T_FRAG_FST)
Jan Engelhardt73866352010-12-18 02:04:59 +0100147 printf(" --fragfirst");
Harald Welte46a73cf2003-09-05 12:53:44 +0000148
149 if (fraginfo->flags & IP6T_FRAG_MF)
Jan Engelhardt73866352010-12-18 02:04:59 +0100150 printf(" --fragmore");
Harald Welte46a73cf2003-09-05 12:53:44 +0000151
152 if (fraginfo->flags & IP6T_FRAG_NMF)
Jan Engelhardt73866352010-12-18 02:04:59 +0100153 printf(" --fraglast");
András Kis-Szabóf1f447b2002-03-26 12:45:19 +0000154}
155
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200156static struct xtables_match frag_mt6_reg = {
Harald Welte46a73cf2003-09-05 12:53:44 +0000157 .name = "frag",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200158 .version = XTABLES_VERSION,
Jan Engelhardt03d99482008-11-18 12:27:54 +0100159 .family = NFPROTO_IPV6,
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200160 .size = XT_ALIGN(sizeof(struct ip6t_frag)),
161 .userspacesize = XT_ALIGN(sizeof(struct ip6t_frag)),
Jan Engelhardt997045f2007-10-04 16:29:21 +0000162 .help = frag_help,
163 .init = frag_init,
Jan Engelhardt997045f2007-10-04 16:29:21 +0000164 .print = frag_print,
165 .save = frag_save,
Jan Engelhardt7c51e382011-02-18 02:17:54 +0100166 .x6_parse = frag_parse,
167 .x6_options = frag_opts,
András Kis-Szabóf1f447b2002-03-26 12:45:19 +0000168};
169
170void
171_init(void)
172{
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200173 xtables_register_match(&frag_mt6_reg);
András Kis-Szabóf1f447b2002-03-26 12:45:19 +0000174}