#include #include #include enum { O_compSPI = 0, O_compRES, }; static void comp_help(void) { printf( "comp match options:\n" "[!] --ipcompspi spi[:spi]\n" " match spi (range)\n"); } static const struct xt_option_entry comp_opts[] = { {.name = "ipcompspi", .id = O_compSPI, .type = XTTYPE_UINT32RC, .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(struct xt_ipcomp, spis)}, {.name = "compres", .id = O_compRES, .type = XTTYPE_NONE}, XTOPT_TABLEEND, }; #undef s static void comp_parse(struct xt_option_call *cb) { struct xt_ipcomp *compinfo = cb->data; xtables_option_parse(cb); switch (cb->entry->id) { case O_compSPI: if (cb->nvals == 1) compinfo->spis[1] = compinfo->spis[0]; if (cb->invert) compinfo->invflags |= XT_IPCOMP_INV_SPI; break; case O_compRES: compinfo->hdrres = 1; break; } } static void print_spis(const char *name, uint32_t min, uint32_t max, int invert) { const char *inv = invert ? "!" : ""; if (min != 0 || max != 0xFFFFFFFF || invert) { if (min == max) printf("%s:%s%u", name, inv, min); else printf("%ss:%s%u:%u", name, inv, min, max); } } static void comp_print(const void *ip, const struct xt_entry_match *match, int numeric) { const struct xt_ipcomp *comp = (struct xt_ipcomp *)match->data; printf(" comp "); print_spis("spi", comp->spis[0], comp->spis[1], comp->invflags & XT_IPCOMP_INV_SPI); if (comp->hdrres) printf(" reserved"); if (comp->invflags & ~XT_IPCOMP_INV_MASK) printf(" Unknown invflags: 0x%X", comp->invflags & ~XT_IPCOMP_INV_MASK); } static void comp_save(const void *ip, const struct xt_entry_match *match) { const struct xt_ipcomp *compinfo = (struct xt_ipcomp *)match->data; if (!(compinfo->spis[0] == 0 && compinfo->spis[1] == 0xFFFFFFFF)) { printf("%s --ipcompspi ", (compinfo->invflags & XT_IPCOMP_INV_SPI) ? " !" : ""); if (compinfo->spis[0] != compinfo->spis[1]) printf("%u:%u", compinfo->spis[0], compinfo->spis[1]); else printf("%u", compinfo->spis[0]); } if (compinfo->hdrres != 0 ) printf(" --compres"); } static int comp_xlate(struct xt_xlate *xl, const struct xt_xlate_mt_params *params) { const struct xt_ipcomp *compinfo = (struct xt_ipcomp *)params->match->data; xt_xlate_add(xl, "comp cpi %s", compinfo->invflags & XT_IPCOMP_INV_SPI ? "!= " : ""); if (compinfo->spis[0] != compinfo->spis[1]) xt_xlate_add(xl, "%u-%u", compinfo->spis[0], compinfo->spis[1]); else xt_xlate_add(xl, "%u", compinfo->spis[0]); return 1; } static struct xtables_match comp_mt_reg = { .name = "ipcomp", .version = XTABLES_VERSION, .family = NFPROTO_UNSPEC, .size = XT_ALIGN(sizeof(struct xt_ipcomp)), .userspacesize = XT_ALIGN(sizeof(struct xt_ipcomp)), .help = comp_help, .print = comp_print, .save = comp_save, .x6_parse = comp_parse, .x6_options = comp_opts, .xlate = comp_xlate, }; void _init(void) { xtables_register_match(&comp_mt_reg); };