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