1*a71a9546SAutomerger Merge Worker /* 2*a71a9546SAutomerger Merge Worker * IPv6 Hop Limit matching module 3*a71a9546SAutomerger Merge Worker * Maciej Soltysiak <[email protected]> 4*a71a9546SAutomerger Merge Worker * Based on HW's ttl match 5*a71a9546SAutomerger Merge Worker * This program is released under the terms of GNU GPL 6*a71a9546SAutomerger Merge Worker * Cleanups by Stephane Ouellette <[email protected]> 7*a71a9546SAutomerger Merge Worker */ 8*a71a9546SAutomerger Merge Worker #include <stdio.h> 9*a71a9546SAutomerger Merge Worker #include <xtables.h> 10*a71a9546SAutomerger Merge Worker #include <linux/netfilter_ipv6/ip6t_hl.h> 11*a71a9546SAutomerger Merge Worker 12*a71a9546SAutomerger Merge Worker enum { 13*a71a9546SAutomerger Merge Worker O_HL_EQ = 0, 14*a71a9546SAutomerger Merge Worker O_HL_LT, 15*a71a9546SAutomerger Merge Worker O_HL_GT, 16*a71a9546SAutomerger Merge Worker F_HL_EQ = 1 << O_HL_EQ, 17*a71a9546SAutomerger Merge Worker F_HL_LT = 1 << O_HL_LT, 18*a71a9546SAutomerger Merge Worker F_HL_GT = 1 << O_HL_GT, 19*a71a9546SAutomerger Merge Worker F_ANY = F_HL_EQ | F_HL_LT | F_HL_GT, 20*a71a9546SAutomerger Merge Worker }; 21*a71a9546SAutomerger Merge Worker 22*a71a9546SAutomerger Merge Worker static void hl_help(void) 23*a71a9546SAutomerger Merge Worker { 24*a71a9546SAutomerger Merge Worker printf( 25*a71a9546SAutomerger Merge Worker "hl match options:\n" 26*a71a9546SAutomerger Merge Worker "[!] --hl-eq value Match hop limit value\n" 27*a71a9546SAutomerger Merge Worker " --hl-lt value Match HL < value\n" 28*a71a9546SAutomerger Merge Worker " --hl-gt value Match HL > value\n"); 29*a71a9546SAutomerger Merge Worker } 30*a71a9546SAutomerger Merge Worker 31*a71a9546SAutomerger Merge Worker static void hl_parse(struct xt_option_call *cb) 32*a71a9546SAutomerger Merge Worker { 33*a71a9546SAutomerger Merge Worker struct ip6t_hl_info *info = cb->data; 34*a71a9546SAutomerger Merge Worker 35*a71a9546SAutomerger Merge Worker xtables_option_parse(cb); 36*a71a9546SAutomerger Merge Worker switch (cb->entry->id) { 37*a71a9546SAutomerger Merge Worker case O_HL_EQ: 38*a71a9546SAutomerger Merge Worker info->mode = cb->invert ? IP6T_HL_NE : IP6T_HL_EQ; 39*a71a9546SAutomerger Merge Worker break; 40*a71a9546SAutomerger Merge Worker case O_HL_LT: 41*a71a9546SAutomerger Merge Worker info->mode = IP6T_HL_LT; 42*a71a9546SAutomerger Merge Worker break; 43*a71a9546SAutomerger Merge Worker case O_HL_GT: 44*a71a9546SAutomerger Merge Worker info->mode = IP6T_HL_GT; 45*a71a9546SAutomerger Merge Worker break; 46*a71a9546SAutomerger Merge Worker } 47*a71a9546SAutomerger Merge Worker } 48*a71a9546SAutomerger Merge Worker 49*a71a9546SAutomerger Merge Worker static void hl_check(struct xt_fcheck_call *cb) 50*a71a9546SAutomerger Merge Worker { 51*a71a9546SAutomerger Merge Worker if (!(cb->xflags & F_ANY)) 52*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 53*a71a9546SAutomerger Merge Worker "HL match: You must specify one of " 54*a71a9546SAutomerger Merge Worker "`--hl-eq', `--hl-lt', `--hl-gt'"); 55*a71a9546SAutomerger Merge Worker } 56*a71a9546SAutomerger Merge Worker 57*a71a9546SAutomerger Merge Worker static void hl_print(const void *ip, const struct xt_entry_match *match, 58*a71a9546SAutomerger Merge Worker int numeric) 59*a71a9546SAutomerger Merge Worker { 60*a71a9546SAutomerger Merge Worker static const char *const op[] = { 61*a71a9546SAutomerger Merge Worker [IP6T_HL_EQ] = "==", 62*a71a9546SAutomerger Merge Worker [IP6T_HL_NE] = "!=", 63*a71a9546SAutomerger Merge Worker [IP6T_HL_LT] = "<", 64*a71a9546SAutomerger Merge Worker [IP6T_HL_GT] = ">" }; 65*a71a9546SAutomerger Merge Worker 66*a71a9546SAutomerger Merge Worker const struct ip6t_hl_info *info = 67*a71a9546SAutomerger Merge Worker (struct ip6t_hl_info *) match->data; 68*a71a9546SAutomerger Merge Worker 69*a71a9546SAutomerger Merge Worker printf(" HL match HL %s %u", op[info->mode], info->hop_limit); 70*a71a9546SAutomerger Merge Worker } 71*a71a9546SAutomerger Merge Worker 72*a71a9546SAutomerger Merge Worker static void hl_save(const void *ip, const struct xt_entry_match *match) 73*a71a9546SAutomerger Merge Worker { 74*a71a9546SAutomerger Merge Worker static const char *const op[] = { 75*a71a9546SAutomerger Merge Worker [IP6T_HL_EQ] = "--hl-eq", 76*a71a9546SAutomerger Merge Worker [IP6T_HL_NE] = "! --hl-eq", 77*a71a9546SAutomerger Merge Worker [IP6T_HL_LT] = "--hl-lt", 78*a71a9546SAutomerger Merge Worker [IP6T_HL_GT] = "--hl-gt" }; 79*a71a9546SAutomerger Merge Worker 80*a71a9546SAutomerger Merge Worker const struct ip6t_hl_info *info = 81*a71a9546SAutomerger Merge Worker (struct ip6t_hl_info *) match->data; 82*a71a9546SAutomerger Merge Worker 83*a71a9546SAutomerger Merge Worker printf(" %s %u", op[info->mode], info->hop_limit); 84*a71a9546SAutomerger Merge Worker } 85*a71a9546SAutomerger Merge Worker 86*a71a9546SAutomerger Merge Worker static const char *const op[] = { 87*a71a9546SAutomerger Merge Worker [IP6T_HL_EQ] = "", 88*a71a9546SAutomerger Merge Worker [IP6T_HL_NE] = "!= ", 89*a71a9546SAutomerger Merge Worker [IP6T_HL_LT] = "lt ", 90*a71a9546SAutomerger Merge Worker [IP6T_HL_GT] = "gt " 91*a71a9546SAutomerger Merge Worker }; 92*a71a9546SAutomerger Merge Worker 93*a71a9546SAutomerger Merge Worker static int hl_xlate(struct xt_xlate *xl, 94*a71a9546SAutomerger Merge Worker const struct xt_xlate_mt_params *params) 95*a71a9546SAutomerger Merge Worker { 96*a71a9546SAutomerger Merge Worker const struct ip6t_hl_info *info = 97*a71a9546SAutomerger Merge Worker (struct ip6t_hl_info *) params->match->data; 98*a71a9546SAutomerger Merge Worker 99*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip6 hoplimit %s%u", op[info->mode], info->hop_limit); 100*a71a9546SAutomerger Merge Worker 101*a71a9546SAutomerger Merge Worker return 1; 102*a71a9546SAutomerger Merge Worker } 103*a71a9546SAutomerger Merge Worker 104*a71a9546SAutomerger Merge Worker #define s struct ip6t_hl_info 105*a71a9546SAutomerger Merge Worker static const struct xt_option_entry hl_opts[] = { 106*a71a9546SAutomerger Merge Worker {.name = "hl-lt", .id = O_HL_LT, .excl = F_ANY, .type = XTTYPE_UINT8, 107*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)}, 108*a71a9546SAutomerger Merge Worker {.name = "hl-gt", .id = O_HL_GT, .excl = F_ANY, .type = XTTYPE_UINT8, 109*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)}, 110*a71a9546SAutomerger Merge Worker {.name = "hl-eq", .id = O_HL_EQ, .excl = F_ANY, .type = XTTYPE_UINT8, 111*a71a9546SAutomerger Merge Worker .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hop_limit)}, 112*a71a9546SAutomerger Merge Worker {.name = "hl", .id = O_HL_EQ, .excl = F_ANY, .type = XTTYPE_UINT8, 113*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)}, 114*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND, 115*a71a9546SAutomerger Merge Worker }; 116*a71a9546SAutomerger Merge Worker #undef s 117*a71a9546SAutomerger Merge Worker 118*a71a9546SAutomerger Merge Worker static struct xtables_match hl_mt6_reg = { 119*a71a9546SAutomerger Merge Worker .name = "hl", 120*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION, 121*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV6, 122*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct ip6t_hl_info)), 123*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct ip6t_hl_info)), 124*a71a9546SAutomerger Merge Worker .help = hl_help, 125*a71a9546SAutomerger Merge Worker .print = hl_print, 126*a71a9546SAutomerger Merge Worker .save = hl_save, 127*a71a9546SAutomerger Merge Worker .x6_parse = hl_parse, 128*a71a9546SAutomerger Merge Worker .x6_fcheck = hl_check, 129*a71a9546SAutomerger Merge Worker .x6_options = hl_opts, 130*a71a9546SAutomerger Merge Worker .xlate = hl_xlate, 131*a71a9546SAutomerger Merge Worker }; 132*a71a9546SAutomerger Merge Worker 133*a71a9546SAutomerger Merge Worker 134*a71a9546SAutomerger Merge Worker void _init(void) 135*a71a9546SAutomerger Merge Worker { 136*a71a9546SAutomerger Merge Worker xtables_register_match(&hl_mt6_reg); 137*a71a9546SAutomerger Merge Worker } 138