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