libip6t_hl.c revision 46525cd3880d2b1aad0b049122a67c9e626ec6d9
1/* 2 * IPv6 Hop Limit matching module 3 * Maciej Soltysiak <solt@dns.toxicfilms.tv> 4 * Based on HW's ttl match 5 * This program is released under the terms of GNU GPL 6 * Cleanups by Stephane Ouellette <ouellettes@videotron.ca> 7 */ 8 9#include <stdio.h> 10#include <stdlib.h> 11#include <string.h> 12#include <getopt.h> 13#include <ip6tables.h> 14 15#include <linux/netfilter_ipv6/ip6_tables.h> 16#include <linux/netfilter_ipv6/ip6t_hl.h> 17 18static void help(void) 19{ 20 printf( 21"HL match v%s options:\n" 22" --hl-eq [!] value Match hop limit value\n" 23" --hl-lt value Match HL < value\n" 24" --hl-gt value Match HL > value\n" 25, IPTABLES_VERSION); 26} 27 28static void init(struct ip6t_entry_match *m, unsigned int *nfcache) 29{ 30 /* caching not yet implemented */ 31 *nfcache |= NFC_UNKNOWN; 32} 33 34static int parse(int c, char **argv, int invert, unsigned int *flags, 35 const struct ip6t_entry *entry, unsigned int *nfcache, 36 struct ip6t_entry_match **match) 37{ 38 struct ip6t_hl_info *info = (struct ip6t_hl_info *) (*match)->data; 39 u_int8_t value; 40 41 check_inverse(optarg, &invert, &optind, 0); 42 value = atoi(argv[optind-1]); 43 44 if (*flags) 45 exit_error(PARAMETER_PROBLEM, 46 "Can't specify HL option twice"); 47 48 if (!optarg) 49 exit_error(PARAMETER_PROBLEM, 50 "hl: You must specify a value"); 51 switch (c) { 52 case '2': 53 if (invert) 54 info->mode = IP6T_HL_NE; 55 else 56 info->mode = IP6T_HL_EQ; 57 58 /* is 0 allowed? */ 59 info->hop_limit = value; 60 *flags = 1; 61 62 break; 63 case '3': 64 if (invert) 65 exit_error(PARAMETER_PROBLEM, 66 "hl: unexpected `!'"); 67 68 info->mode = IP6T_HL_LT; 69 info->hop_limit = value; 70 *flags = 1; 71 72 break; 73 case '4': 74 if (invert) 75 exit_error(PARAMETER_PROBLEM, 76 "hl: unexpected `!'"); 77 78 info->mode = IP6T_HL_GT; 79 info->hop_limit = value; 80 *flags = 1; 81 82 break; 83 default: 84 return 0; 85 } 86 87 return 1; 88} 89 90static void final_check(unsigned int flags) 91{ 92 if (!flags) 93 exit_error(PARAMETER_PROBLEM, 94 "HL match: You must specify one of " 95 "`--hl-eq', `--hl-lt', `--hl-gt'"); 96} 97 98static void print(const struct ip6t_ip6 *ip, 99 const struct ip6t_entry_match *match, 100 int numeric) 101{ 102 static const char *op[] = { 103 [IP6T_HL_EQ] = "==", 104 [IP6T_HL_NE] = "!=", 105 [IP6T_HL_LT] = "<", 106 [IP6T_HL_GT] = ">" }; 107 108 const struct ip6t_hl_info *info = 109 (struct ip6t_hl_info *) match->data; 110 111 printf("HL match HL %s %u ", op[info->mode], info->hop_limit); 112} 113 114static void save(const struct ip6t_ip6 *ip, 115 const struct ip6t_entry_match *match) 116{ 117 static const char *op[] = { 118 [IP6T_HL_EQ] = "eq", 119 [IP6T_HL_NE] = "eq !", 120 [IP6T_HL_LT] = "lt", 121 [IP6T_HL_GT] = "gt" }; 122 123 const struct ip6t_hl_info *info = 124 (struct ip6t_hl_info *) match->data; 125 126 printf("--hl-%s %u ", op[info->mode], info->hop_limit); 127} 128 129static struct option opts[] = { 130 { .name = "hl", .has_arg = 1, .flag = 0, .val = '2' }, 131 { .name = "hl-eq", .has_arg = 1, .flag = 0, .val = '2' }, 132 { .name = "hl-lt", .has_arg = 1, .flag = 0, .val = '3' }, 133 { .name = "hl-gt", .has_arg = 1, .flag = 0, .val = '4' }, 134 { 0 } 135}; 136 137static 138struct ip6tables_match hl = { 139 .name = "hl", 140 .version = IPTABLES_VERSION, 141 .size = IP6T_ALIGN(sizeof(struct ip6t_hl_info)), 142 .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_hl_info)), 143 .help = &help, 144 .init = &init, 145 .parse = &parse, 146 .final_check = &final_check, 147 .print = &print, 148 .save = &save, 149 .extra_opts = opts 150}; 151 152 153void _init(void) 154{ 155 register_match6(&hl); 156} 157