Home | History | Annotate | Download | only in extensions
      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