1*a71a9546SAutomerger Merge Worker /* Shared library add-on to iptables to add TTL matching support 2*a71a9546SAutomerger Merge Worker * (C) 2000 by Harald Welte <[email protected]> 3*a71a9546SAutomerger Merge Worker * 4*a71a9546SAutomerger Merge Worker * This program is released under the terms of GNU GPL */ 5*a71a9546SAutomerger Merge Worker #include <stdio.h> 6*a71a9546SAutomerger Merge Worker #include <xtables.h> 7*a71a9546SAutomerger Merge Worker #include <linux/netfilter_ipv4/ipt_ttl.h> 8*a71a9546SAutomerger Merge Worker 9*a71a9546SAutomerger Merge Worker enum { 10*a71a9546SAutomerger Merge Worker O_TTL_EQ = 0, 11*a71a9546SAutomerger Merge Worker O_TTL_LT, 12*a71a9546SAutomerger Merge Worker O_TTL_GT, 13*a71a9546SAutomerger Merge Worker F_TTL_EQ = 1 << O_TTL_EQ, 14*a71a9546SAutomerger Merge Worker F_TTL_LT = 1 << O_TTL_LT, 15*a71a9546SAutomerger Merge Worker F_TTL_GT = 1 << O_TTL_GT, 16*a71a9546SAutomerger Merge Worker F_ANY = F_TTL_EQ | F_TTL_LT | F_TTL_GT, 17*a71a9546SAutomerger Merge Worker }; 18*a71a9546SAutomerger Merge Worker 19*a71a9546SAutomerger Merge Worker static void ttl_help(void) 20*a71a9546SAutomerger Merge Worker { 21*a71a9546SAutomerger Merge Worker printf( 22*a71a9546SAutomerger Merge Worker "ttl match options:\n" 23*a71a9546SAutomerger Merge Worker "[!] --ttl-eq value Match time to live value\n" 24*a71a9546SAutomerger Merge Worker " --ttl-lt value Match TTL < value\n" 25*a71a9546SAutomerger Merge Worker " --ttl-gt value Match TTL > value\n"); 26*a71a9546SAutomerger Merge Worker } 27*a71a9546SAutomerger Merge Worker 28*a71a9546SAutomerger Merge Worker static void ttl_parse(struct xt_option_call *cb) 29*a71a9546SAutomerger Merge Worker { 30*a71a9546SAutomerger Merge Worker struct ipt_ttl_info *info = cb->data; 31*a71a9546SAutomerger Merge Worker 32*a71a9546SAutomerger Merge Worker xtables_option_parse(cb); 33*a71a9546SAutomerger Merge Worker switch (cb->entry->id) { 34*a71a9546SAutomerger Merge Worker case O_TTL_EQ: 35*a71a9546SAutomerger Merge Worker info->mode = cb->invert ? IPT_TTL_NE : IPT_TTL_EQ; 36*a71a9546SAutomerger Merge Worker break; 37*a71a9546SAutomerger Merge Worker case O_TTL_LT: 38*a71a9546SAutomerger Merge Worker info->mode = IPT_TTL_LT; 39*a71a9546SAutomerger Merge Worker break; 40*a71a9546SAutomerger Merge Worker case O_TTL_GT: 41*a71a9546SAutomerger Merge Worker info->mode = IPT_TTL_GT; 42*a71a9546SAutomerger Merge Worker break; 43*a71a9546SAutomerger Merge Worker } 44*a71a9546SAutomerger Merge Worker } 45*a71a9546SAutomerger Merge Worker 46*a71a9546SAutomerger Merge Worker static void ttl_check(struct xt_fcheck_call *cb) 47*a71a9546SAutomerger Merge Worker { 48*a71a9546SAutomerger Merge Worker if (!(cb->xflags & F_ANY)) 49*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 50*a71a9546SAutomerger Merge Worker "TTL match: You must specify one of " 51*a71a9546SAutomerger Merge Worker "`--ttl-eq', `--ttl-lt', `--ttl-gt"); 52*a71a9546SAutomerger Merge Worker } 53*a71a9546SAutomerger Merge Worker 54*a71a9546SAutomerger Merge Worker static void ttl_print(const void *ip, const struct xt_entry_match *match, 55*a71a9546SAutomerger Merge Worker int numeric) 56*a71a9546SAutomerger Merge Worker { 57*a71a9546SAutomerger Merge Worker const struct ipt_ttl_info *info = 58*a71a9546SAutomerger Merge Worker (struct ipt_ttl_info *) match->data; 59*a71a9546SAutomerger Merge Worker 60*a71a9546SAutomerger Merge Worker printf(" TTL match "); 61*a71a9546SAutomerger Merge Worker switch (info->mode) { 62*a71a9546SAutomerger Merge Worker case IPT_TTL_EQ: 63*a71a9546SAutomerger Merge Worker printf("TTL =="); 64*a71a9546SAutomerger Merge Worker break; 65*a71a9546SAutomerger Merge Worker case IPT_TTL_NE: 66*a71a9546SAutomerger Merge Worker printf("TTL !="); 67*a71a9546SAutomerger Merge Worker break; 68*a71a9546SAutomerger Merge Worker case IPT_TTL_LT: 69*a71a9546SAutomerger Merge Worker printf("TTL <"); 70*a71a9546SAutomerger Merge Worker break; 71*a71a9546SAutomerger Merge Worker case IPT_TTL_GT: 72*a71a9546SAutomerger Merge Worker printf("TTL >"); 73*a71a9546SAutomerger Merge Worker break; 74*a71a9546SAutomerger Merge Worker } 75*a71a9546SAutomerger Merge Worker printf(" %u", info->ttl); 76*a71a9546SAutomerger Merge Worker } 77*a71a9546SAutomerger Merge Worker 78*a71a9546SAutomerger Merge Worker static void ttl_save(const void *ip, const struct xt_entry_match *match) 79*a71a9546SAutomerger Merge Worker { 80*a71a9546SAutomerger Merge Worker const struct ipt_ttl_info *info = 81*a71a9546SAutomerger Merge Worker (struct ipt_ttl_info *) match->data; 82*a71a9546SAutomerger Merge Worker 83*a71a9546SAutomerger Merge Worker switch (info->mode) { 84*a71a9546SAutomerger Merge Worker case IPT_TTL_EQ: 85*a71a9546SAutomerger Merge Worker printf(" --ttl-eq"); 86*a71a9546SAutomerger Merge Worker break; 87*a71a9546SAutomerger Merge Worker case IPT_TTL_NE: 88*a71a9546SAutomerger Merge Worker printf(" ! --ttl-eq"); 89*a71a9546SAutomerger Merge Worker break; 90*a71a9546SAutomerger Merge Worker case IPT_TTL_LT: 91*a71a9546SAutomerger Merge Worker printf(" --ttl-lt"); 92*a71a9546SAutomerger Merge Worker break; 93*a71a9546SAutomerger Merge Worker case IPT_TTL_GT: 94*a71a9546SAutomerger Merge Worker printf(" --ttl-gt"); 95*a71a9546SAutomerger Merge Worker break; 96*a71a9546SAutomerger Merge Worker default: 97*a71a9546SAutomerger Merge Worker /* error */ 98*a71a9546SAutomerger Merge Worker break; 99*a71a9546SAutomerger Merge Worker } 100*a71a9546SAutomerger Merge Worker printf(" %u", info->ttl); 101*a71a9546SAutomerger Merge Worker } 102*a71a9546SAutomerger Merge Worker 103*a71a9546SAutomerger Merge Worker static int ttl_xlate(struct xt_xlate *xl, 104*a71a9546SAutomerger Merge Worker const struct xt_xlate_mt_params *params) 105*a71a9546SAutomerger Merge Worker { 106*a71a9546SAutomerger Merge Worker const struct ipt_ttl_info *info = 107*a71a9546SAutomerger Merge Worker (struct ipt_ttl_info *) params->match->data; 108*a71a9546SAutomerger Merge Worker 109*a71a9546SAutomerger Merge Worker switch (info->mode) { 110*a71a9546SAutomerger Merge Worker case IPT_TTL_EQ: 111*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip ttl"); 112*a71a9546SAutomerger Merge Worker break; 113*a71a9546SAutomerger Merge Worker case IPT_TTL_NE: 114*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip ttl !="); 115*a71a9546SAutomerger Merge Worker break; 116*a71a9546SAutomerger Merge Worker case IPT_TTL_LT: 117*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip ttl lt"); 118*a71a9546SAutomerger Merge Worker break; 119*a71a9546SAutomerger Merge Worker case IPT_TTL_GT: 120*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip ttl gt"); 121*a71a9546SAutomerger Merge Worker break; 122*a71a9546SAutomerger Merge Worker default: 123*a71a9546SAutomerger Merge Worker /* Should not happen. */ 124*a71a9546SAutomerger Merge Worker return 0; 125*a71a9546SAutomerger Merge Worker } 126*a71a9546SAutomerger Merge Worker 127*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, " %u", info->ttl); 128*a71a9546SAutomerger Merge Worker 129*a71a9546SAutomerger Merge Worker return 1; 130*a71a9546SAutomerger Merge Worker } 131*a71a9546SAutomerger Merge Worker 132*a71a9546SAutomerger Merge Worker #define s struct ipt_ttl_info 133*a71a9546SAutomerger Merge Worker static const struct xt_option_entry ttl_opts[] = { 134*a71a9546SAutomerger Merge Worker {.name = "ttl-lt", .id = O_TTL_LT, .excl = F_ANY, .type = XTTYPE_UINT8, 135*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(s, ttl)}, 136*a71a9546SAutomerger Merge Worker {.name = "ttl-gt", .id = O_TTL_GT, .excl = F_ANY, .type = XTTYPE_UINT8, 137*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(s, ttl)}, 138*a71a9546SAutomerger Merge Worker {.name = "ttl-eq", .id = O_TTL_EQ, .excl = F_ANY, .type = XTTYPE_UINT8, 139*a71a9546SAutomerger Merge Worker .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, ttl)}, 140*a71a9546SAutomerger Merge Worker {.name = "ttl", .id = O_TTL_EQ, .excl = F_ANY, .type = XTTYPE_UINT8, 141*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(s, ttl)}, 142*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND, 143*a71a9546SAutomerger Merge Worker }; 144*a71a9546SAutomerger Merge Worker #undef s 145*a71a9546SAutomerger Merge Worker 146*a71a9546SAutomerger Merge Worker static struct xtables_match ttl_mt_reg = { 147*a71a9546SAutomerger Merge Worker .name = "ttl", 148*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION, 149*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV4, 150*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct ipt_ttl_info)), 151*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct ipt_ttl_info)), 152*a71a9546SAutomerger Merge Worker .help = ttl_help, 153*a71a9546SAutomerger Merge Worker .print = ttl_print, 154*a71a9546SAutomerger Merge Worker .save = ttl_save, 155*a71a9546SAutomerger Merge Worker .x6_parse = ttl_parse, 156*a71a9546SAutomerger Merge Worker .x6_fcheck = ttl_check, 157*a71a9546SAutomerger Merge Worker .x6_options = ttl_opts, 158*a71a9546SAutomerger Merge Worker .xlate = ttl_xlate, 159*a71a9546SAutomerger Merge Worker }; 160*a71a9546SAutomerger Merge Worker 161*a71a9546SAutomerger Merge Worker 162*a71a9546SAutomerger Merge Worker void _init(void) 163*a71a9546SAutomerger Merge Worker { 164*a71a9546SAutomerger Merge Worker xtables_register_match(&ttl_mt_reg); 165*a71a9546SAutomerger Merge Worker } 166