András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 1 | #include <stdio.h> |
Jan Engelhardt | 5d9678a | 2008-11-20 10:15:35 +0100 | [diff] [blame] | 2 | #include <xtables.h> |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 3 | #include <linux/netfilter_ipv6/ip6t_frag.h> |
Jan Engelhardt | ddac6c5 | 2008-09-01 14:22:19 +0200 | [diff] [blame] | 4 | |
Jan Engelhardt | 7c51e38 | 2011-02-18 02:17:54 +0100 | [diff] [blame] | 5 | enum { |
| 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 Engelhardt | 997045f | 2007-10-04 16:29:21 +0000 | [diff] [blame] | 16 | static void frag_help(void) |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 17 | { |
| 18 | printf( |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 19 | "frag match options:\n" |
Jan Engelhardt | 9672792 | 2008-08-13 14:42:41 +0200 | [diff] [blame] | 20 | "[!] --fragid id[:id] match the id (range)\n" |
| 21 | "[!] --fraglen length total length of this header\n" |
Jan Engelhardt | 12a18d6 | 2011-02-18 01:45:05 +0100 | [diff] [blame] | 22 | " --fragres check the reserved field too\n" |
András Kis-Szabó | d8a12a8 | 2002-04-24 09:36:30 +0000 | [diff] [blame] | 23 | " --fragfirst matches on the first fragment\n" |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 24 | " [--fragmore|--fraglast] there are more fragments or this\n" |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 25 | " is the last one\n"); |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 26 | } |
| 27 | |
Jan Engelhardt | 7c51e38 | 2011-02-18 02:17:54 +0100 | [diff] [blame] | 28 | #define s struct ip6t_frag |
| 29 | static 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ó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 41 | }; |
Jan Engelhardt | 7c51e38 | 2011-02-18 02:17:54 +0100 | [diff] [blame] | 42 | #undef s |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 43 | |
Jan Engelhardt | 997045f | 2007-10-04 16:29:21 +0000 | [diff] [blame] | 44 | static void frag_init(struct xt_entry_match *m) |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 45 | { |
| 46 | struct ip6t_frag *fraginfo = (struct ip6t_frag *)m->data; |
| 47 | |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 48 | fraginfo->ids[1] = 0xFFFFFFFF; |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 49 | } |
| 50 | |
Jan Engelhardt | 7c51e38 | 2011-02-18 02:17:54 +0100 | [diff] [blame] | 51 | static void frag_parse(struct xt_option_call *cb) |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 52 | { |
Jan Engelhardt | 7c51e38 | 2011-02-18 02:17:54 +0100 | [diff] [blame] | 53 | struct ip6t_frag *fraginfo = cb->data; |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 54 | |
Jan Engelhardt | 7c51e38 | 2011-02-18 02:17:54 +0100 | [diff] [blame] | 55 | xtables_option_parse(cb); |
| 56 | switch (cb->entry->id) { |
| 57 | case O_FRAGRES: |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 58 | fraginfo->flags |= IP6T_FRAG_RES; |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 59 | break; |
Jan Engelhardt | 7c51e38 | 2011-02-18 02:17:54 +0100 | [diff] [blame] | 60 | case O_FRAGFIRST: |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 61 | fraginfo->flags |= IP6T_FRAG_FST; |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 62 | break; |
Jan Engelhardt | 7c51e38 | 2011-02-18 02:17:54 +0100 | [diff] [blame] | 63 | case O_FRAGMORE: |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 64 | fraginfo->flags |= IP6T_FRAG_MF; |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 65 | break; |
Jan Engelhardt | 7c51e38 | 2011-02-18 02:17:54 +0100 | [diff] [blame] | 66 | case O_FRAGLAST: |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 67 | fraginfo->flags |= IP6T_FRAG_NMF; |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 68 | break; |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 69 | } |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 70 | } |
| 71 | |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 72 | static void |
Jan Engelhardt | 7ac4052 | 2011-01-07 12:34:04 +0100 | [diff] [blame] | 73 | print_ids(const char *name, uint32_t min, uint32_t max, |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 74 | int invert) |
| 75 | { |
| 76 | const char *inv = invert ? "!" : ""; |
| 77 | |
| 78 | if (min != 0 || max != 0xFFFFFFFF || invert) { |
| 79 | printf("%s", name); |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 80 | if (min == max) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 81 | printf(":%s%u", inv, min); |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 82 | else |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 83 | printf("s:%s%u:%u", inv, min, max); |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 84 | } |
| 85 | } |
| 86 | |
Jan Engelhardt | 997045f | 2007-10-04 16:29:21 +0000 | [diff] [blame] | 87 | static void frag_print(const void *ip, const struct xt_entry_match *match, |
| 88 | int numeric) |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 89 | { |
| 90 | const struct ip6t_frag *frag = (struct ip6t_frag *)match->data; |
| 91 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 92 | printf(" frag "); |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 93 | print_ids("id", frag->ids[0], frag->ids[1], |
| 94 | frag->invflags & IP6T_FRAG_INV_IDS); |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 95 | |
András Kis-Szabó | d8a12a8 | 2002-04-24 09:36:30 +0000 | [diff] [blame] | 96 | if (frag->flags & IP6T_FRAG_LEN) { |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 97 | printf(" length:%s%u", |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 98 | frag->invflags & IP6T_FRAG_INV_LEN ? "!" : "", |
| 99 | frag->hdrlen); |
András Kis-Szabó | d8a12a8 | 2002-04-24 09:36:30 +0000 | [diff] [blame] | 100 | } |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 101 | |
| 102 | if (frag->flags & IP6T_FRAG_RES) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 103 | printf(" reserved"); |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 104 | |
| 105 | if (frag->flags & IP6T_FRAG_FST) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 106 | printf(" first"); |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 107 | |
| 108 | if (frag->flags & IP6T_FRAG_MF) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 109 | printf(" more"); |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 110 | |
| 111 | if (frag->flags & IP6T_FRAG_NMF) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 112 | printf(" last"); |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 113 | |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 114 | if (frag->invflags & ~IP6T_FRAG_INV_MASK) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 115 | printf(" Unknown invflags: 0x%X", |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 116 | frag->invflags & ~IP6T_FRAG_INV_MASK); |
| 117 | } |
| 118 | |
Jan Engelhardt | 997045f | 2007-10-04 16:29:21 +0000 | [diff] [blame] | 119 | static void frag_save(const void *ip, const struct xt_entry_match *match) |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 120 | { |
| 121 | const struct ip6t_frag *fraginfo = (struct ip6t_frag *)match->data; |
| 122 | |
| 123 | if (!(fraginfo->ids[0] == 0 |
| 124 | && fraginfo->ids[1] == 0xFFFFFFFF)) { |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 125 | printf("%s --fragid ", |
| 126 | (fraginfo->invflags & IP6T_FRAG_INV_IDS) ? " !" : ""); |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 127 | if (fraginfo->ids[0] |
| 128 | != fraginfo->ids[1]) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 129 | printf("%u:%u", |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 130 | fraginfo->ids[0], |
| 131 | fraginfo->ids[1]); |
| 132 | else |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 133 | printf("%u", |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 134 | fraginfo->ids[0]); |
| 135 | } |
| 136 | |
András Kis-Szabó | d8a12a8 | 2002-04-24 09:36:30 +0000 | [diff] [blame] | 137 | if (fraginfo->flags & IP6T_FRAG_LEN) { |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 138 | printf("%s --fraglen %u", |
| 139 | (fraginfo->invflags & IP6T_FRAG_INV_LEN) ? " !" : "", |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 140 | fraginfo->hdrlen); |
| 141 | } |
| 142 | |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 143 | if (fraginfo->flags & IP6T_FRAG_RES) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 144 | printf(" --fragres"); |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 145 | |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 146 | if (fraginfo->flags & IP6T_FRAG_FST) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 147 | printf(" --fragfirst"); |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 148 | |
| 149 | if (fraginfo->flags & IP6T_FRAG_MF) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 150 | printf(" --fragmore"); |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 151 | |
| 152 | if (fraginfo->flags & IP6T_FRAG_NMF) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 153 | printf(" --fraglast"); |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 154 | } |
| 155 | |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 156 | static struct xtables_match frag_mt6_reg = { |
Harald Welte | 46a73cf | 2003-09-05 12:53:44 +0000 | [diff] [blame] | 157 | .name = "frag", |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 158 | .version = XTABLES_VERSION, |
Jan Engelhardt | 03d9948 | 2008-11-18 12:27:54 +0100 | [diff] [blame] | 159 | .family = NFPROTO_IPV6, |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 160 | .size = XT_ALIGN(sizeof(struct ip6t_frag)), |
| 161 | .userspacesize = XT_ALIGN(sizeof(struct ip6t_frag)), |
Jan Engelhardt | 997045f | 2007-10-04 16:29:21 +0000 | [diff] [blame] | 162 | .help = frag_help, |
| 163 | .init = frag_init, |
Jan Engelhardt | 997045f | 2007-10-04 16:29:21 +0000 | [diff] [blame] | 164 | .print = frag_print, |
| 165 | .save = frag_save, |
Jan Engelhardt | 7c51e38 | 2011-02-18 02:17:54 +0100 | [diff] [blame] | 166 | .x6_parse = frag_parse, |
| 167 | .x6_options = frag_opts, |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 168 | }; |
| 169 | |
| 170 | void |
| 171 | _init(void) |
| 172 | { |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 173 | xtables_register_match(&frag_mt6_reg); |
András Kis-Szabó | f1f447b | 2002-03-26 12:45:19 +0000 | [diff] [blame] | 174 | } |