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