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