/* * IPv6 Hop Limit Target module * Maciej Soltysiak * Based on HW's ttl target * This program is distributed under the terms of GNU GPL */ #include #include #include #include #include #include #define IP6T_HL_USED 1 static void HL_help(void) { printf( "HL target options\n" " --hl-set value Set HL to \n" " --hl-dec value Decrement HL by \n" " --hl-inc value Increment HL by \n"); } static int HL_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct ip6t_HL_info *info = (struct ip6t_HL_info *) (*target)->data; unsigned int value; if (*flags & IP6T_HL_USED) { xtables_error(PARAMETER_PROBLEM, "Can't specify HL option twice"); } if (!optarg) xtables_error(PARAMETER_PROBLEM, "HL: You must specify a value"); if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) xtables_error(PARAMETER_PROBLEM, "HL: unexpected `!'"); if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX)) xtables_error(PARAMETER_PROBLEM, "HL: Expected value between 0 and 255"); switch (c) { case '1': info->mode = IP6T_HL_SET; break; case '2': if (value == 0) { xtables_error(PARAMETER_PROBLEM, "HL: decreasing by 0?"); } info->mode = IP6T_HL_DEC; break; case '3': if (value == 0) { xtables_error(PARAMETER_PROBLEM, "HL: increasing by 0?"); } info->mode = IP6T_HL_INC; break; default: return 0; } info->hop_limit = value; *flags |= IP6T_HL_USED; return 1; } static void HL_check(unsigned int flags) { if (!(flags & IP6T_HL_USED)) xtables_error(PARAMETER_PROBLEM, "HL: You must specify an action"); } static void HL_save(const void *ip, const struct xt_entry_target *target) { const struct ip6t_HL_info *info = (struct ip6t_HL_info *) target->data; switch (info->mode) { case IP6T_HL_SET: printf("--hl-set "); break; case IP6T_HL_DEC: printf("--hl-dec "); break; case IP6T_HL_INC: printf("--hl-inc "); break; } printf("%u ", info->hop_limit); } static void HL_print(const void *ip, const struct xt_entry_target *target, int numeric) { const struct ip6t_HL_info *info = (struct ip6t_HL_info *) target->data; printf("HL "); switch (info->mode) { case IP6T_HL_SET: printf("set to "); break; case IP6T_HL_DEC: printf("decrement by "); break; case IP6T_HL_INC: printf("increment by "); break; } printf("%u ", info->hop_limit); } static const struct option HL_opts[] = { { "hl-set", 1, NULL, '1' }, { "hl-dec", 1, NULL, '2' }, { "hl-inc", 1, NULL, '3' }, { .name = NULL } }; static struct xtables_target hl_tg6_reg = { .name = "HL", .version = XTABLES_VERSION, .family = NFPROTO_IPV6, .size = XT_ALIGN(sizeof(struct ip6t_HL_info)), .userspacesize = XT_ALIGN(sizeof(struct ip6t_HL_info)), .help = HL_help, .parse = HL_parse, .final_check = HL_check, .print = HL_print, .save = HL_save, .extra_opts = HL_opts, }; void _init(void) { xtables_register_target(&hl_tg6_reg); }