libipt_ttl.c revision 8115e5425721cd610b6390c3d4c24540773b0520
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 int value; 33 34 check_inverse(optarg, &invert, &optind, 0); 35 36 if (string_to_number(optarg, 0, 255, &value) == -1) 37 exit_error(PARAMETER_PROBLEM, 38 "ttl: Expected value between 0 and 255"); 39 40 switch (c) { 41 case '2': 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 (invert) 52 exit_error(PARAMETER_PROBLEM, 53 "ttl: unexpected `!'"); 54 55 info->mode = IPT_TTL_LT; 56 info->ttl = value; 57 break; 58 case '4': 59 if (invert) 60 exit_error(PARAMETER_PROBLEM, 61 "ttl: unexpected `!'"); 62 63 info->mode = IPT_TTL_GT; 64 info->ttl = value; 65 break; 66 default: 67 return 0; 68 69 } 70 71 if (*flags) 72 exit_error(PARAMETER_PROBLEM, 73 "Can't specify TTL option twice"); 74 *flags = 1; 75 76 return 1; 77} 78 79static void final_check(unsigned int flags) 80{ 81 if (!flags) 82 exit_error(PARAMETER_PROBLEM, 83 "TTL match: You must specify one of " 84 "`--ttl-eq', `--ttl-lt', `--ttl-gt"); 85} 86 87static void print(const struct ipt_ip *ip, 88 const struct ipt_entry_match *match, 89 int numeric) 90{ 91 const struct ipt_ttl_info *info = 92 (struct ipt_ttl_info *) match->data; 93 94 printf("TTL match "); 95 switch (info->mode) { 96 case IPT_TTL_EQ: 97 printf("TTL == "); 98 break; 99 case IPT_TTL_NE: 100 printf("TTL != "); 101 break; 102 case IPT_TTL_LT: 103 printf("TTL < "); 104 break; 105 case IPT_TTL_GT: 106 printf("TTL > "); 107 break; 108 } 109 printf("%u ", info->ttl); 110} 111 112static void save(const struct ipt_ip *ip, 113 const struct ipt_entry_match *match) 114{ 115 const struct ipt_ttl_info *info = 116 (struct ipt_ttl_info *) match->data; 117 118 switch (info->mode) { 119 case IPT_TTL_EQ: 120 printf("--ttl-eq "); 121 break; 122 case IPT_TTL_NE: 123 printf("! --ttl-eq "); 124 break; 125 case IPT_TTL_LT: 126 printf("--ttl-lt "); 127 break; 128 case IPT_TTL_GT: 129 printf("--ttl-gt "); 130 break; 131 default: 132 /* error */ 133 break; 134 } 135 printf("%u ", info->ttl); 136} 137 138static struct option opts[] = { 139 { "ttl", 1, 0, '2' }, 140 { "ttl-eq", 1, 0, '2'}, 141 { "ttl-lt", 1, 0, '3'}, 142 { "ttl-gt", 1, 0, '4'}, 143 { 0 } 144}; 145 146static struct iptables_match ttl = { 147 .next = NULL, 148 .name = "ttl", 149 .version = IPTABLES_VERSION, 150 .size = IPT_ALIGN(sizeof(struct ipt_ttl_info)), 151 .userspacesize = IPT_ALIGN(sizeof(struct ipt_ttl_info)), 152 .help = &help, 153 .parse = &parse, 154 .final_check = &final_check, 155 .print = &print, 156 .save = &save, 157 .extra_opts = opts 158}; 159 160 161void _init(void) 162{ 163 register_match(&ttl); 164} 165