libip6t_HL.c revision 0463ee1f28946cc49815737daa0ced0c68f39f0b
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 <stdio.h> 9#include <string.h> 10#include <stdlib.h> 11#include <getopt.h> 12#include <ip6tables.h> 13 14#include <linux/netfilter_ipv6/ip6_tables.h> 15#include <linux/netfilter_ipv6/ip6t_HL.h> 16 17#define IP6T_HL_USED 1 18 19static void help(void) 20{ 21 printf( 22"HL target v%s 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, IPTABLES_VERSION); 27} 28 29static int parse(int c, char **argv, int invert, unsigned int *flags, 30 const void *entry, 31 struct xt_entry_target **target) 32{ 33 struct ip6t_HL_info *info = (struct ip6t_HL_info *) (*target)->data; 34 unsigned int value; 35 36 if (*flags & IP6T_HL_USED) { 37 exit_error(PARAMETER_PROBLEM, 38 "Can't specify HL option twice"); 39 } 40 41 if (!optarg) 42 exit_error(PARAMETER_PROBLEM, 43 "HL: You must specify a value"); 44 45 if (check_inverse(optarg, &invert, NULL, 0)) 46 exit_error(PARAMETER_PROBLEM, 47 "HL: unexpected `!'"); 48 49 if (string_to_number(optarg, 0, 255, &value) == -1) 50 exit_error(PARAMETER_PROBLEM, 51 "HL: Expected value between 0 and 255"); 52 53 switch (c) { 54 55 case '1': 56 info->mode = IP6T_HL_SET; 57 break; 58 59 case '2': 60 if (value == 0) { 61 exit_error(PARAMETER_PROBLEM, 62 "HL: decreasing by 0?"); 63 } 64 65 info->mode = IP6T_HL_DEC; 66 break; 67 68 case '3': 69 if (value == 0) { 70 exit_error(PARAMETER_PROBLEM, 71 "HL: increasing by 0?"); 72 } 73 74 info->mode = IP6T_HL_INC; 75 break; 76 77 default: 78 return 0; 79 80 } 81 82 info->hop_limit = value; 83 *flags |= IP6T_HL_USED; 84 85 return 1; 86} 87 88static void final_check(unsigned int flags) 89{ 90 if (!(flags & IP6T_HL_USED)) 91 exit_error(PARAMETER_PROBLEM, 92 "HL: You must specify an action"); 93} 94 95static void save(const void *ip, 96 const struct xt_entry_target *target) 97{ 98 const struct ip6t_HL_info *info = 99 (struct ip6t_HL_info *) target->data; 100 101 switch (info->mode) { 102 case IP6T_HL_SET: 103 printf("--hl-set "); 104 break; 105 case IP6T_HL_DEC: 106 printf("--hl-dec "); 107 break; 108 109 case IP6T_HL_INC: 110 printf("--hl-inc "); 111 break; 112 } 113 printf("%u ", info->hop_limit); 114} 115 116static void print(const void *ip, 117 const struct xt_entry_target *target, int numeric) 118{ 119 const struct ip6t_HL_info *info = 120 (struct ip6t_HL_info *) target->data; 121 122 printf("HL "); 123 switch (info->mode) { 124 case IP6T_HL_SET: 125 printf("set to "); 126 break; 127 case IP6T_HL_DEC: 128 printf("decrement by "); 129 break; 130 case IP6T_HL_INC: 131 printf("increment by "); 132 break; 133 } 134 printf("%u ", info->hop_limit); 135} 136 137static const struct option opts[] = { 138 { "hl-set", 1, NULL, '1' }, 139 { "hl-dec", 1, NULL, '2' }, 140 { "hl-inc", 1, NULL, '3' }, 141 { } 142}; 143 144static 145struct ip6tables_target HL = { 146 .name = "HL", 147 .version = IPTABLES_VERSION, 148 .size = IP6T_ALIGN(sizeof(struct ip6t_HL_info)), 149 .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_HL_info)), 150 .help = &help, 151 .parse = &parse, 152 .final_check = &final_check, 153 .print = &print, 154 .save = &save, 155 .extra_opts = opts 156}; 157 158void _init(void) 159{ 160 register_target6(&HL); 161} 162