libip6t_HL.c revision d09b6d591ca7d7d7575cb6aa20384c9830f777ab
1/* 2 * IPv6 Hop Limit Target module 3 * Maciej Soltysiak <solt@dns.toxicfilms.tv> 4 * Based on HW's ttl target 5 * This program is distributed under the terms of GNU GPL 6 */ 7 8#include <getopt.h> 9#include <stdbool.h> 10#include <stdio.h> 11#include <string.h> 12#include <stdlib.h> 13#include <xtables.h> 14 15#include <linux/netfilter_ipv6/ip6t_HL.h> 16 17#define IP6T_HL_USED 1 18 19static void HL_help(void) 20{ 21 printf( 22"HL target options\n" 23" --hl-set value Set HL to <value 0-255>\n" 24" --hl-dec value Decrement HL by <value 1-255>\n" 25" --hl-inc value Increment HL by <value 1-255>\n"); 26} 27 28static int HL_parse(int c, char **argv, int invert, unsigned int *flags, 29 const void *entry, struct xt_entry_target **target) 30{ 31 struct ip6t_HL_info *info = (struct ip6t_HL_info *) (*target)->data; 32 unsigned int value; 33 34 if (*flags & IP6T_HL_USED) { 35 xtables_error(PARAMETER_PROBLEM, 36 "Can't specify HL option twice"); 37 } 38 39 if (!optarg) 40 xtables_error(PARAMETER_PROBLEM, 41 "HL: You must specify a value"); 42 43 if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) 44 xtables_error(PARAMETER_PROBLEM, 45 "HL: unexpected `!'"); 46 47 if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX)) 48 xtables_error(PARAMETER_PROBLEM, 49 "HL: Expected value between 0 and 255"); 50 51 switch (c) { 52 53 case '1': 54 info->mode = IP6T_HL_SET; 55 break; 56 57 case '2': 58 if (value == 0) { 59 xtables_error(PARAMETER_PROBLEM, 60 "HL: decreasing by 0?"); 61 } 62 63 info->mode = IP6T_HL_DEC; 64 break; 65 66 case '3': 67 if (value == 0) { 68 xtables_error(PARAMETER_PROBLEM, 69 "HL: increasing by 0?"); 70 } 71 72 info->mode = IP6T_HL_INC; 73 break; 74 } 75 76 info->hop_limit = value; 77 *flags |= IP6T_HL_USED; 78 79 return 1; 80} 81 82static void HL_check(unsigned int flags) 83{ 84 if (!(flags & IP6T_HL_USED)) 85 xtables_error(PARAMETER_PROBLEM, 86 "HL: You must specify an action"); 87} 88 89static void HL_save(const void *ip, const struct xt_entry_target *target) 90{ 91 const struct ip6t_HL_info *info = 92 (struct ip6t_HL_info *) target->data; 93 94 switch (info->mode) { 95 case IP6T_HL_SET: 96 printf("--hl-set "); 97 break; 98 case IP6T_HL_DEC: 99 printf("--hl-dec "); 100 break; 101 102 case IP6T_HL_INC: 103 printf("--hl-inc "); 104 break; 105 } 106 printf("%u ", info->hop_limit); 107} 108 109static void HL_print(const void *ip, const struct xt_entry_target *target, 110 int numeric) 111{ 112 const struct ip6t_HL_info *info = 113 (struct ip6t_HL_info *) target->data; 114 115 printf("HL "); 116 switch (info->mode) { 117 case IP6T_HL_SET: 118 printf("set to "); 119 break; 120 case IP6T_HL_DEC: 121 printf("decrement by "); 122 break; 123 case IP6T_HL_INC: 124 printf("increment by "); 125 break; 126 } 127 printf("%u ", info->hop_limit); 128} 129 130static const struct option HL_opts[] = { 131 {.name = "hl-set", .has_arg = true, .val = '1'}, 132 {.name = "hl-dec", .has_arg = true, .val = '2'}, 133 {.name = "hl-inc", .has_arg = true, .val = '3'}, 134 XT_GETOPT_TABLEEND, 135}; 136 137static struct xtables_target hl_tg6_reg = { 138 .name = "HL", 139 .version = XTABLES_VERSION, 140 .family = NFPROTO_IPV6, 141 .size = XT_ALIGN(sizeof(struct ip6t_HL_info)), 142 .userspacesize = XT_ALIGN(sizeof(struct ip6t_HL_info)), 143 .help = HL_help, 144 .parse = HL_parse, 145 .final_check = HL_check, 146 .print = HL_print, 147 .save = HL_save, 148 .extra_opts = HL_opts, 149}; 150 151void _init(void) 152{ 153 xtables_register_target(&hl_tg6_reg); 154} 155