libipt_ttl.c revision 32b8e61e4e5bd405d9ad07bf9468498dfbb19f9e
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/* Shared library add-on to iptables to add TTL matching support 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * (C) 2000 by Harald Welte <laforge@gnumonks.org> 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * $Id$ 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * This program is released under the terms of GNU GPL */ 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <stdbool.h> 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <stdio.h> 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <stdlib.h> 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <string.h> 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <getopt.h> 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <xtables.h> 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <linux/netfilter_ipv4/ipt_ttl.h> 1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void ttl_help(void) 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf( 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)"ttl match options:\n" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)" --ttl-eq value Match time to live value\n" 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)" --ttl-lt value Match TTL < value\n" 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)" --ttl-gt value Match TTL > value\n"); 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static int ttl_parse(int c, char **argv, int invert, unsigned int *flags, 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const void *entry, struct xt_entry_match **match) 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) struct ipt_ttl_info *info = (struct ipt_ttl_info *) (*match)->data; 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) unsigned int value; 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) xtables_check_inverse(optarg, &invert, &optind, 0, argv); 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (c) { 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case '2': 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX)) 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) xtables_error(PARAMETER_PROBLEM, 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "ttl: Expected value between 0 and 255"); 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (invert) 400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch info->mode = IPT_TTL_NE; 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch else 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch info->mode = IPT_TTL_EQ; 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /* is 0 allowed? */ 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) info->ttl = value; 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch case '3': 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX)) 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) xtables_error(PARAMETER_PROBLEM, 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "ttl: Expected value between 0 and 255"); 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (invert) 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) xtables_error(PARAMETER_PROBLEM, 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "ttl: unexpected `!'"); 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) info->mode = IPT_TTL_LT; 5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) info->ttl = value; 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case '4': 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX)) 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) xtables_error(PARAMETER_PROBLEM, 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "ttl: Expected value between 0 and 255"); 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (invert) 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) xtables_error(PARAMETER_PROBLEM, 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "ttl: unexpected `!'"); 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) info->mode = IPT_TTL_GT; 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) info->ttl = value; 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default: 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 0; 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (*flags) 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) xtables_error(PARAMETER_PROBLEM, 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "Can't specify TTL option twice"); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *flags = 1; 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 1; 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void ttl_check(unsigned int flags) 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!flags) 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) xtables_error(PARAMETER_PROBLEM, 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "TTL match: You must specify one of " 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "`--ttl-eq', `--ttl-lt', `--ttl-gt"); 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void ttl_print(const void *ip, const struct xt_entry_match *match, 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int numeric) 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const struct ipt_ttl_info *info = 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (struct ipt_ttl_info *) match->data; 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("TTL match "); 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (info->mode) { 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case IPT_TTL_EQ: 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("TTL == "); 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case IPT_TTL_NE: 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("TTL != "); 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case IPT_TTL_LT: 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("TTL < "); 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case IPT_TTL_GT: 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("TTL > "); 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("%u ", info->ttl); 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void ttl_save(const void *ip, const struct xt_entry_match *match) 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const struct ipt_ttl_info *info = 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (struct ipt_ttl_info *) match->data; 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (info->mode) { 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case IPT_TTL_EQ: 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("--ttl-eq "); 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case IPT_TTL_NE: 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("! --ttl-eq "); 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case IPT_TTL_LT: 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("--ttl-lt "); 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case IPT_TTL_GT: 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("--ttl-gt "); 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default: 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /* error */ 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("%u ", info->ttl); 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static const struct option ttl_opts[] = { 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) {.name = "ttl", .has_arg = true, .val = '2'}, 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) {.name = "ttl-eq", .has_arg = true, .val = '2'}, 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) {.name = "ttl-lt", .has_arg = true, .val = '3'}, 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) {.name = "ttl-gt", .has_arg = true, .val = '4'}, 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) XT_GETOPT_TABLEEND, 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static struct xtables_match ttl_mt_reg = { 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .name = "ttl", 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .version = XTABLES_VERSION, 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .family = NFPROTO_IPV4, 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .size = XT_ALIGN(sizeof(struct ipt_ttl_info)), 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .userspacesize = XT_ALIGN(sizeof(struct ipt_ttl_info)), 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .help = ttl_help, 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .parse = ttl_parse, 157 .final_check = ttl_check, 158 .print = ttl_print, 159 .save = ttl_save, 160 .extra_opts = ttl_opts, 161}; 162 163 164void _init(void) 165{ 166 xtables_register_match(&ttl_mt_reg); 167} 168