libip6t_hl.c revision 997045f536026c0d643bf884da5ff5de2605197f
160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak/* 260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak * IPv6 Hop Limit matching module 360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak * Maciej Soltysiak <solt@dns.toxicfilms.tv> 460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak * Based on HW's ttl match 560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak * This program is released under the terms of GNU GPL 646525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette * Cleanups by Stephane Ouellette <ouellettes@videotron.ca> 760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak */ 860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <stdio.h> 1060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <stdlib.h> 1160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <string.h> 1260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <getopt.h> 1360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <ip6tables.h> 1460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 1560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <linux/netfilter_ipv6/ip6_tables.h> 1660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <linux/netfilter_ipv6/ip6t_hl.h> 1760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 18997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void hl_help(void) 1960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{ 2060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak printf( 2160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak"HL match v%s options:\n" 2246525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette" --hl-eq [!] value Match hop limit value\n" 2360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak" --hl-lt value Match HL < value\n" 2460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak" --hl-gt value Match HL > value\n" 2560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak, IPTABLES_VERSION); 2660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak} 2760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 28997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic int hl_parse(int c, char **argv, int invert, unsigned int *flags, 29997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt const void *entry, struct xt_entry_match **match) 3060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{ 3160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak struct ip6t_hl_info *info = (struct ip6t_hl_info *) (*match)->data; 3260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak u_int8_t value; 3360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 3460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak check_inverse(optarg, &invert, &optind, 0); 3560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak value = atoi(argv[optind-1]); 3660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 3760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak if (*flags) 3860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak exit_error(PARAMETER_PROBLEM, 3960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak "Can't specify HL option twice"); 4060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 4160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak if (!optarg) 4260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak exit_error(PARAMETER_PROBLEM, 4360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak "hl: You must specify a value"); 4460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak switch (c) { 4560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak case '2': 4660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak if (invert) 4760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak info->mode = IP6T_HL_NE; 4860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak else 4960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak info->mode = IP6T_HL_EQ; 5060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 5160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak /* is 0 allowed? */ 5260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak info->hop_limit = value; 5360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak *flags = 1; 5460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 5560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak break; 5660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak case '3': 5760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak if (invert) 5860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak exit_error(PARAMETER_PROBLEM, 5960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak "hl: unexpected `!'"); 6060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 6160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak info->mode = IP6T_HL_LT; 6260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak info->hop_limit = value; 6360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak *flags = 1; 6460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 6560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak break; 6660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak case '4': 6760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak if (invert) 6860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak exit_error(PARAMETER_PROBLEM, 6960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak "hl: unexpected `!'"); 7060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 7160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak info->mode = IP6T_HL_GT; 7260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak info->hop_limit = value; 7360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak *flags = 1; 7460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 7560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak break; 7660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak default: 7760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak return 0; 7860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak } 7960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 8060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak return 1; 8160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak} 8260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 83997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void hl_check(unsigned int flags) 8460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{ 8560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak if (!flags) 8660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak exit_error(PARAMETER_PROBLEM, 8760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak "HL match: You must specify one of " 8846525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette "`--hl-eq', `--hl-lt', `--hl-gt'"); 8960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak} 9060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 91997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void hl_print(const void *ip, const struct xt_entry_match *match, 92997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt int numeric) 9360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{ 9446525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette static const char *op[] = { 9546525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette [IP6T_HL_EQ] = "==", 9646525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette [IP6T_HL_NE] = "!=", 9746525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette [IP6T_HL_LT] = "<", 9846525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette [IP6T_HL_GT] = ">" }; 9946525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette 10060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak const struct ip6t_hl_info *info = 10160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak (struct ip6t_hl_info *) match->data; 10260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 10346525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette printf("HL match HL %s %u ", op[info->mode], info->hop_limit); 10460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak} 10560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 106997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void hl_save(const void *ip, const struct xt_entry_match *match) 10760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{ 10846525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette static const char *op[] = { 10946525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette [IP6T_HL_EQ] = "eq", 11046525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette [IP6T_HL_NE] = "eq !", 11146525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette [IP6T_HL_LT] = "lt", 11246525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette [IP6T_HL_GT] = "gt" }; 11346525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette 11460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak const struct ip6t_hl_info *info = 11560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak (struct ip6t_hl_info *) match->data; 11660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 11746525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette printf("--hl-%s %u ", op[info->mode], info->hop_limit); 11860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak} 11960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 120997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic const struct option hl_opts[] = { 121500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy { .name = "hl", .has_arg = 1, .val = '2' }, 122500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy { .name = "hl-eq", .has_arg = 1, .val = '2' }, 123500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy { .name = "hl-lt", .has_arg = 1, .val = '3' }, 124500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy { .name = "hl-gt", .has_arg = 1, .val = '4' }, 125500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy { } 12660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}; 12760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 128997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic struct ip6tables_match hl_match6 = { 12946525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette .name = "hl", 13046525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette .version = IPTABLES_VERSION, 13146525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette .size = IP6T_ALIGN(sizeof(struct ip6t_hl_info)), 13246525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_hl_info)), 133997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt .help = hl_help, 134997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt .parse = hl_parse, 135997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt .final_check = hl_check, 136997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt .print = hl_print, 137997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt .save = hl_save, 138997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt .extra_opts = hl_opts, 13960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}; 14060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 14160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak 14260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiakvoid _init(void) 14360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{ 144997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt register_match6(&hl_match6); 14560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak} 146