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