1 #include <stdio.h> 2 #include <xtables.h> 3 #include <linux/netfilter/xt_ipcomp.h> 4 5 enum { 6 O_compSPI = 0, 7 O_compRES, 8 }; 9 10 static void comp_help(void) 11 { 12 printf( 13 "comp match options:\n" 14 "[!] --ipcompspi spi[:spi]\n" 15 " match spi (range)\n"); 16 } 17 18 static const struct xt_option_entry comp_opts[] = { 19 {.name = "ipcompspi", .id = O_compSPI, .type = XTTYPE_UINT32RC, 20 .flags = XTOPT_INVERT | XTOPT_PUT, 21 XTOPT_POINTER(struct xt_ipcomp, spis)}, 22 {.name = "compres", .id = O_compRES, .type = XTTYPE_NONE}, 23 XTOPT_TABLEEND, 24 }; 25 #undef s 26 27 static void comp_parse(struct xt_option_call *cb) 28 { 29 struct xt_ipcomp *compinfo = cb->data; 30 31 xtables_option_parse(cb); 32 switch (cb->entry->id) { 33 case O_compSPI: 34 if (cb->nvals == 1) 35 compinfo->spis[1] = compinfo->spis[0]; 36 if (cb->invert) 37 compinfo->invflags |= XT_IPCOMP_INV_SPI; 38 break; 39 case O_compRES: 40 compinfo->hdrres = 1; 41 break; 42 } 43 } 44 45 static void 46 print_spis(const char *name, uint32_t min, uint32_t max, 47 int invert) 48 { 49 const char *inv = invert ? "!" : ""; 50 51 if (min != 0 || max != 0xFFFFFFFF || invert) { 52 if (min == max) 53 printf("%s:%s%u", name, inv, min); 54 else 55 printf("%ss:%s%u:%u", name, inv, min, max); 56 } 57 } 58 59 static void comp_print(const void *ip, const struct xt_entry_match *match, 60 int numeric) 61 { 62 const struct xt_ipcomp *comp = (struct xt_ipcomp *)match->data; 63 64 printf(" comp "); 65 print_spis("spi", comp->spis[0], comp->spis[1], 66 comp->invflags & XT_IPCOMP_INV_SPI); 67 68 if (comp->hdrres) 69 printf(" reserved"); 70 71 if (comp->invflags & ~XT_IPCOMP_INV_MASK) 72 printf(" Unknown invflags: 0x%X", 73 comp->invflags & ~XT_IPCOMP_INV_MASK); 74 } 75 76 static void comp_save(const void *ip, const struct xt_entry_match *match) 77 { 78 const struct xt_ipcomp *compinfo = (struct xt_ipcomp *)match->data; 79 80 if (!(compinfo->spis[0] == 0 81 && compinfo->spis[1] == 0xFFFFFFFF)) { 82 printf("%s --ipcompspi ", 83 (compinfo->invflags & XT_IPCOMP_INV_SPI) ? " !" : ""); 84 if (compinfo->spis[0] 85 != compinfo->spis[1]) 86 printf("%u:%u", 87 compinfo->spis[0], 88 compinfo->spis[1]); 89 else 90 printf("%u", 91 compinfo->spis[0]); 92 } 93 94 if (compinfo->hdrres != 0 ) 95 printf(" --compres"); 96 } 97 98 static int comp_xlate(struct xt_xlate *xl, 99 const struct xt_xlate_mt_params *params) 100 { 101 const struct xt_ipcomp *compinfo = 102 (struct xt_ipcomp *)params->match->data; 103 104 xt_xlate_add(xl, "comp cpi %s", 105 compinfo->invflags & XT_IPCOMP_INV_SPI ? "!= " : ""); 106 if (compinfo->spis[0] != compinfo->spis[1]) 107 xt_xlate_add(xl, "%u-%u", compinfo->spis[0], 108 compinfo->spis[1]); 109 else 110 xt_xlate_add(xl, "%u", compinfo->spis[0]); 111 112 return 1; 113 } 114 115 static struct xtables_match comp_mt_reg = { 116 .name = "ipcomp", 117 .version = XTABLES_VERSION, 118 .family = NFPROTO_UNSPEC, 119 .size = XT_ALIGN(sizeof(struct xt_ipcomp)), 120 .userspacesize = XT_ALIGN(sizeof(struct xt_ipcomp)), 121 .help = comp_help, 122 .print = comp_print, 123 .save = comp_save, 124 .x6_parse = comp_parse, 125 .x6_options = comp_opts, 126 .xlate = comp_xlate, 127 }; 128 129 void 130 _init(void) 131 { 132 xtables_register_match(&comp_mt_reg); 133 }; 134 135