libip6t_hl.c revision 997045f536026c0d643bf884da5ff5de2605197f
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 hl_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 int hl_parse(int c, char **argv, int invert, unsigned int *flags, 29 const void *entry, struct xt_entry_match **match) 30{ 31 struct ip6t_hl_info *info = (struct ip6t_hl_info *) (*match)->data; 32 u_int8_t value; 33 34 check_inverse(optarg, &invert, &optind, 0); 35 value = atoi(argv[optind-1]); 36 37 if (*flags) 38 exit_error(PARAMETER_PROBLEM, 39 "Can't specify HL option twice"); 40 41 if (!optarg) 42 exit_error(PARAMETER_PROBLEM, 43 "hl: You must specify a value"); 44 switch (c) { 45 case '2': 46 if (invert) 47 info->mode = IP6T_HL_NE; 48 else 49 info->mode = IP6T_HL_EQ; 50 51 /* is 0 allowed? */ 52 info->hop_limit = value; 53 *flags = 1; 54 55 break; 56 case '3': 57 if (invert) 58 exit_error(PARAMETER_PROBLEM, 59 "hl: unexpected `!'"); 60 61 info->mode = IP6T_HL_LT; 62 info->hop_limit = value; 63 *flags = 1; 64 65 break; 66 case '4': 67 if (invert) 68 exit_error(PARAMETER_PROBLEM, 69 "hl: unexpected `!'"); 70 71 info->mode = IP6T_HL_GT; 72 info->hop_limit = value; 73 *flags = 1; 74 75 break; 76 default: 77 return 0; 78 } 79 80 return 1; 81} 82 83static void hl_check(unsigned int flags) 84{ 85 if (!flags) 86 exit_error(PARAMETER_PROBLEM, 87 "HL match: You must specify one of " 88 "`--hl-eq', `--hl-lt', `--hl-gt'"); 89} 90 91static void hl_print(const void *ip, const struct xt_entry_match *match, 92 int numeric) 93{ 94 static const char *op[] = { 95 [IP6T_HL_EQ] = "==", 96 [IP6T_HL_NE] = "!=", 97 [IP6T_HL_LT] = "<", 98 [IP6T_HL_GT] = ">" }; 99 100 const struct ip6t_hl_info *info = 101 (struct ip6t_hl_info *) match->data; 102 103 printf("HL match HL %s %u ", op[info->mode], info->hop_limit); 104} 105 106static void hl_save(const void *ip, const struct xt_entry_match *match) 107{ 108 static const char *op[] = { 109 [IP6T_HL_EQ] = "eq", 110 [IP6T_HL_NE] = "eq !", 111 [IP6T_HL_LT] = "lt", 112 [IP6T_HL_GT] = "gt" }; 113 114 const struct ip6t_hl_info *info = 115 (struct ip6t_hl_info *) match->data; 116 117 printf("--hl-%s %u ", op[info->mode], info->hop_limit); 118} 119 120static const struct option hl_opts[] = { 121 { .name = "hl", .has_arg = 1, .val = '2' }, 122 { .name = "hl-eq", .has_arg = 1, .val = '2' }, 123 { .name = "hl-lt", .has_arg = 1, .val = '3' }, 124 { .name = "hl-gt", .has_arg = 1, .val = '4' }, 125 { } 126}; 127 128static struct ip6tables_match hl_match6 = { 129 .name = "hl", 130 .version = IPTABLES_VERSION, 131 .size = IP6T_ALIGN(sizeof(struct ip6t_hl_info)), 132 .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_hl_info)), 133 .help = hl_help, 134 .parse = hl_parse, 135 .final_check = hl_check, 136 .print = hl_print, 137 .save = hl_save, 138 .extra_opts = hl_opts, 139}; 140 141 142void _init(void) 143{ 144 register_match6(&hl_match6); 145} 146