Home | History | Annotate | Download | only in extensions
      1 #include <stdio.h>
      2 #include <xtables.h>
      3 #include <linux/netfilter_ipv6/ip6t_ah.h>
      4 
      5 enum {
      6 	O_AHSPI = 0,
      7 	O_AHLEN,
      8 	O_AHRES,
      9 };
     10 
     11 static void ah_help(void)
     12 {
     13 	printf(
     14 "ah match options:\n"
     15 "[!] --ahspi spi[:spi]          match spi (range)\n"
     16 "[!] --ahlen length             total length of this header\n"
     17 " --ahres                       check the reserved field too\n");
     18 }
     19 
     20 #define s struct ip6t_ah
     21 static const struct xt_option_entry ah_opts[] = {
     22 	{.name = "ahspi", .id = O_AHSPI, .type = XTTYPE_UINT32RC,
     23 	 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, spis)},
     24 	{.name = "ahlen", .id = O_AHLEN, .type = XTTYPE_UINT32,
     25 	 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdrlen)},
     26 	{.name = "ahres", .id = O_AHRES, .type = XTTYPE_NONE},
     27 	XTOPT_TABLEEND,
     28 };
     29 #undef s
     30 
     31 static void ah_parse(struct xt_option_call *cb)
     32 {
     33 	struct ip6t_ah *ahinfo = cb->data;
     34 
     35 	xtables_option_parse(cb);
     36 	switch (cb->entry->id) {
     37 	case O_AHSPI:
     38 		if (cb->nvals == 1)
     39 			ahinfo->spis[1] = ahinfo->spis[0];
     40 		if (cb->invert)
     41 			ahinfo->invflags |= IP6T_AH_INV_SPI;
     42 		break;
     43 	case O_AHLEN:
     44 		if (cb->invert)
     45 			ahinfo->invflags |= IP6T_AH_INV_LEN;
     46 		break;
     47 	case O_AHRES:
     48 		ahinfo->hdrres = 1;
     49 		break;
     50 	}
     51 }
     52 
     53 static void
     54 print_spis(const char *name, uint32_t min, uint32_t max,
     55 	    int invert)
     56 {
     57 	const char *inv = invert ? "!" : "";
     58 
     59 	if (min != 0 || max != 0xFFFFFFFF || invert) {
     60 		if (min == max)
     61 			printf("%s:%s%u", name, inv, min);
     62 		else
     63 			printf("%ss:%s%u:%u", name, inv, min, max);
     64 	}
     65 }
     66 
     67 static void
     68 print_len(const char *name, uint32_t len, int invert)
     69 {
     70 	const char *inv = invert ? "!" : "";
     71 
     72 	if (len != 0 || invert)
     73 		printf("%s:%s%u", name, inv, len);
     74 }
     75 
     76 static void ah_print(const void *ip, const struct xt_entry_match *match,
     77                      int numeric)
     78 {
     79 	const struct ip6t_ah *ah = (struct ip6t_ah *)match->data;
     80 
     81 	printf(" ah ");
     82 	print_spis("spi", ah->spis[0], ah->spis[1],
     83 		    ah->invflags & IP6T_AH_INV_SPI);
     84 	print_len("length", ah->hdrlen,
     85 		    ah->invflags & IP6T_AH_INV_LEN);
     86 
     87 	if (ah->hdrres)
     88 		printf(" reserved");
     89 
     90 	if (ah->invflags & ~IP6T_AH_INV_MASK)
     91 		printf(" Unknown invflags: 0x%X",
     92 		       ah->invflags & ~IP6T_AH_INV_MASK);
     93 }
     94 
     95 static void ah_save(const void *ip, const struct xt_entry_match *match)
     96 {
     97 	const struct ip6t_ah *ahinfo = (struct ip6t_ah *)match->data;
     98 
     99 	if (!(ahinfo->spis[0] == 0
    100 	    && ahinfo->spis[1] == 0xFFFFFFFF)) {
    101 		printf("%s --ahspi ",
    102 			(ahinfo->invflags & IP6T_AH_INV_SPI) ? " !" : "");
    103 		if (ahinfo->spis[0]
    104 		    != ahinfo->spis[1])
    105 			printf("%u:%u",
    106 			       ahinfo->spis[0],
    107 			       ahinfo->spis[1]);
    108 		else
    109 			printf("%u",
    110 			       ahinfo->spis[0]);
    111 	}
    112 
    113 	if (ahinfo->hdrlen != 0 || (ahinfo->invflags & IP6T_AH_INV_LEN) ) {
    114 		printf("%s --ahlen %u",
    115 			(ahinfo->invflags & IP6T_AH_INV_LEN) ? " !" : "",
    116 			ahinfo->hdrlen);
    117 	}
    118 
    119 	if (ahinfo->hdrres != 0 )
    120 		printf(" --ahres");
    121 }
    122 
    123 static struct xtables_match ah_mt6_reg = {
    124 	.name          = "ah",
    125 	.version       = XTABLES_VERSION,
    126 	.family        = NFPROTO_IPV6,
    127 	.size          = XT_ALIGN(sizeof(struct ip6t_ah)),
    128 	.userspacesize = XT_ALIGN(sizeof(struct ip6t_ah)),
    129 	.help          = ah_help,
    130 	.print         = ah_print,
    131 	.save          = ah_save,
    132 	.x6_parse      = ah_parse,
    133 	.x6_options    = ah_opts,
    134 };
    135 
    136 void
    137 _init(void)
    138 {
    139 	xtables_register_match(&ah_mt6_reg);
    140 }
    141