libipt_ttl.c revision 6656e1378f432ab8690e7d22128793a1ddc5166b
1/* Shared library add-on to iptables to add TTL matching support 2 * (C) 2000 by Harald Welte <laforge@gnumonks.org> 3 * 4 * $Id$ 5 * 6 * This program is released under the terms of GNU GPL */ 7 8#include <stdio.h> 9#include <stdlib.h> 10#include <string.h> 11#include <getopt.h> 12#include <iptables.h> 13 14#include <linux/netfilter_ipv4/ip_tables.h> 15#include <linux/netfilter_ipv4/ipt_ttl.h> 16 17static void help(void) 18{ 19 printf( 20"TTL match v%s options:\n" 21" --ttl-eq value Match time to live value\n" 22" --ttl-lt value Match TTL < value\n" 23" --ttl-gt value Match TTL > value\n" 24, IPTABLES_VERSION); 25} 26 27static int parse(int c, char **argv, int invert, unsigned int *flags, 28 const struct ipt_entry *entry, unsigned int *nfcache, 29 struct ipt_entry_match **match) 30{ 31 struct ipt_ttl_info *info = (struct ipt_ttl_info *) (*match)->data; 32 unsigned int value; 33 34 check_inverse(optarg, &invert, &optind, 0); 35 36 switch (c) { 37 case '2': 38 if (string_to_number(optarg, 0, 255, &value) == -1) 39 exit_error(PARAMETER_PROBLEM, 40 "ttl: Expected value between 0 and 255"); 41 42 if (invert) 43 info->mode = IPT_TTL_NE; 44 else 45 info->mode = IPT_TTL_EQ; 46 47 /* is 0 allowed? */ 48 info->ttl = value; 49 break; 50 case '3': 51 if (string_to_number(optarg, 0, 255, &value) == -1) 52 exit_error(PARAMETER_PROBLEM, 53 "ttl: Expected value between 0 and 255"); 54 55 if (invert) 56 exit_error(PARAMETER_PROBLEM, 57 "ttl: unexpected `!'"); 58 59 info->mode = IPT_TTL_LT; 60 info->ttl = value; 61 break; 62 case '4': 63 if (string_to_number(optarg, 0, 255, &value) == -1) 64 exit_error(PARAMETER_PROBLEM, 65 "ttl: Expected value between 0 and 255"); 66 67 if (invert) 68 exit_error(PARAMETER_PROBLEM, 69 "ttl: unexpected `!'"); 70 71 info->mode = IPT_TTL_GT; 72 info->ttl = value; 73 break; 74 default: 75 return 0; 76 77 } 78 79 if (*flags) 80 exit_error(PARAMETER_PROBLEM, 81 "Can't specify TTL option twice"); 82 *flags = 1; 83 84 return 1; 85} 86 87static void final_check(unsigned int flags) 88{ 89 if (!flags) 90 exit_error(PARAMETER_PROBLEM, 91 "TTL match: You must specify one of " 92 "`--ttl-eq', `--ttl-lt', `--ttl-gt"); 93} 94 95static void print(const struct ipt_ip *ip, 96 const struct ipt_entry_match *match, 97 int numeric) 98{ 99 const struct ipt_ttl_info *info = 100 (struct ipt_ttl_info *) match->data; 101 102 printf("TTL match "); 103 switch (info->mode) { 104 case IPT_TTL_EQ: 105 printf("TTL == "); 106 break; 107 case IPT_TTL_NE: 108 printf("TTL != "); 109 break; 110 case IPT_TTL_LT: 111 printf("TTL < "); 112 break; 113 case IPT_TTL_GT: 114 printf("TTL > "); 115 break; 116 } 117 printf("%u ", info->ttl); 118} 119 120static void save(const struct ipt_ip *ip, 121 const struct ipt_entry_match *match) 122{ 123 const struct ipt_ttl_info *info = 124 (struct ipt_ttl_info *) match->data; 125 126 switch (info->mode) { 127 case IPT_TTL_EQ: 128 printf("--ttl-eq "); 129 break; 130 case IPT_TTL_NE: 131 printf("! --ttl-eq "); 132 break; 133 case IPT_TTL_LT: 134 printf("--ttl-lt "); 135 break; 136 case IPT_TTL_GT: 137 printf("--ttl-gt "); 138 break; 139 default: 140 /* error */ 141 break; 142 } 143 printf("%u ", info->ttl); 144} 145 146static struct option opts[] = { 147 { "ttl", 1, 0, '2' }, 148 { "ttl-eq", 1, 0, '2'}, 149 { "ttl-lt", 1, 0, '3'}, 150 { "ttl-gt", 1, 0, '4'}, 151 { 0 } 152}; 153 154static struct iptables_match ttl = { 155 .next = NULL, 156 .name = "ttl", 157 .version = IPTABLES_VERSION, 158 .size = IPT_ALIGN(sizeof(struct ipt_ttl_info)), 159 .userspacesize = IPT_ALIGN(sizeof(struct ipt_ttl_info)), 160 .help = &help, 161 .parse = &parse, 162 .final_check = &final_check, 163 .print = &print, 164 .save = &save, 165 .extra_opts = opts 166}; 167 168 169void _init(void) 170{ 171 register_match(&ttl); 172} 173