1d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte#include <stdio.h> 25d9678ad3eabc34ac40dfe055d7f6a8e44445a5aJan Engelhardt#include <xtables.h> 3d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte#include <linux/netfilter_ipv6/ip6t_ah.h> 4ddac6c5bc636003d664d25c08ea3fe176565096cJan Engelhardt 54d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardtenum { 64d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt O_AHSPI = 0, 74d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt O_AHLEN, 84d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt O_AHRES, 94d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt}; 104d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt 11997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void ah_help(void) 12d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{ 13d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte printf( 148b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"ah match options:\n" 15967279231a9ecfa99f26694a954afc535c63db1dJan Engelhardt"[!] --ahspi spi[:spi] match spi (range)\n" 16967279231a9ecfa99f26694a954afc535c63db1dJan Engelhardt"[!] --ahlen length total length of this header\n" 1712a18d6043092bd2574b2bced635259b16317e57Jan Engelhardt" --ahres check the reserved field too\n"); 18d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte} 19d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 204d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt#define s struct ip6t_ah 214d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardtstatic const struct xt_option_entry ah_opts[] = { 224d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt {.name = "ahspi", .id = O_AHSPI, .type = XTTYPE_UINT32RC, 234d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, spis)}, 244d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt {.name = "ahlen", .id = O_AHLEN, .type = XTTYPE_UINT32, 254d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdrlen)}, 264d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt {.name = "ahres", .id = O_AHRES, .type = XTTYPE_NONE}, 274d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt XTOPT_TABLEEND, 28d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}; 294d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt#undef s 30d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 314d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardtstatic void ah_parse(struct xt_option_call *cb) 32d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{ 334d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt struct ip6t_ah *ahinfo = cb->data; 344d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt 354d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt xtables_option_parse(cb); 364d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt switch (cb->entry->id) { 374d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt case O_AHSPI: 386944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt if (cb->nvals == 1) 396944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt ahinfo->spis[1] = ahinfo->spis[0]; 404d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt if (cb->invert) 41d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte ahinfo->invflags |= IP6T_AH_INV_SPI; 42d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte break; 434d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt case O_AHLEN: 444d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt if (cb->invert) 45d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte ahinfo->invflags |= IP6T_AH_INV_LEN; 46d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte break; 474d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt case O_AHRES: 48d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte ahinfo->hdrres = 1; 49d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte break; 50d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte } 51d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte} 52d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 53d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltestatic void 547ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtprint_spis(const char *name, uint32_t min, uint32_t max, 55d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte int invert) 56d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{ 57d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte const char *inv = invert ? "!" : ""; 58d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 59d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte if (min != 0 || max != 0xFFFFFFFF || invert) { 60703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette if (min == max) 6173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("%s:%s%u", name, inv, min); 62703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette else 6373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("%ss:%s%u:%u", name, inv, min, max); 64d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte } 65d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte} 66d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 67d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltestatic void 687ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtprint_len(const char *name, uint32_t len, int invert) 69d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{ 70d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte const char *inv = invert ? "!" : ""; 71d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 72703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette if (len != 0 || invert) 7373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("%s:%s%u", name, inv, len); 74d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte} 75d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 76997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void ah_print(const void *ip, const struct xt_entry_match *match, 77997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt int numeric) 78d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{ 79d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte const struct ip6t_ah *ah = (struct ip6t_ah *)match->data; 80d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 8173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" ah "); 82d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte print_spis("spi", ah->spis[0], ah->spis[1], 83d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte ah->invflags & IP6T_AH_INV_SPI); 84d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte print_len("length", ah->hdrlen, 85d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte ah->invflags & IP6T_AH_INV_LEN); 86703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette 87703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette if (ah->hdrres) 8873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" reserved"); 89703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette 90d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte if (ah->invflags & ~IP6T_AH_INV_MASK) 9173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" Unknown invflags: 0x%X", 92d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte ah->invflags & ~IP6T_AH_INV_MASK); 93d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte} 94d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 95997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void ah_save(const void *ip, const struct xt_entry_match *match) 96d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{ 97d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte const struct ip6t_ah *ahinfo = (struct ip6t_ah *)match->data; 98d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 99d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte if (!(ahinfo->spis[0] == 0 100d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte && ahinfo->spis[1] == 0xFFFFFFFF)) { 10173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("%s --ahspi ", 10273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt (ahinfo->invflags & IP6T_AH_INV_SPI) ? " !" : ""); 103d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte if (ahinfo->spis[0] 104d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte != ahinfo->spis[1]) 10573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("%u:%u", 106d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte ahinfo->spis[0], 107d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte ahinfo->spis[1]); 108d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte else 10973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("%u", 110d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte ahinfo->spis[0]); 111d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte } 112d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 113d8a12a841de648bd38dc52ba624d1ed1810a6333András Kis-Szabó if (ahinfo->hdrlen != 0 || (ahinfo->invflags & IP6T_AH_INV_LEN) ) { 11473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("%s --ahlen %u", 11573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt (ahinfo->invflags & IP6T_AH_INV_LEN) ? " !" : "", 116d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte ahinfo->hdrlen); 117d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte } 118d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 119703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette if (ahinfo->hdrres != 0 ) 12073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" --ahres"); 121d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte} 122d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 1238b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardtstatic struct xtables_match ah_mt6_reg = { 124703575d4b45d15996ee2ca0b13d958a22cd78f4fStephane Ouellette .name = "ah", 1258b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt .version = XTABLES_VERSION, 12603d99486d8283552705b58dc55b6085dffc38792Jan Engelhardt .family = NFPROTO_IPV6, 1278b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt .size = XT_ALIGN(sizeof(struct ip6t_ah)), 1288b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt .userspacesize = XT_ALIGN(sizeof(struct ip6t_ah)), 129997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt .help = ah_help, 130997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt .print = ah_print, 131997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt .save = ah_save, 1324d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt .x6_parse = ah_parse, 1334d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt .x6_options = ah_opts, 134d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte}; 135d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte 136d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Weltevoid 137d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte_init(void) 138d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte{ 1398b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt xtables_register_match(&ah_mt6_reg); 140d32980df1da9d81a93280b4f0e023c58055c4b0cHarald Welte} 141