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