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