Home | History | Annotate | Download | only in extensions
      1 /*
      2  * IPv6 Hop Limit matching module
      3  * Maciej Soltysiak <solt (at) dns.toxicfilms.tv>
      4  * Based on HW's ttl match
      5  * This program is released under the terms of GNU GPL
      6  * Cleanups by Stephane Ouellette <ouellettes (at) videotron.ca>
      7  */
      8 #include <stdio.h>
      9 #include <xtables.h>
     10 #include <linux/netfilter_ipv6/ip6t_hl.h>
     11 
     12 enum {
     13 	O_HL_EQ = 0,
     14 	O_HL_LT,
     15 	O_HL_GT,
     16 	F_HL_EQ = 1 << O_HL_EQ,
     17 	F_HL_LT = 1 << O_HL_LT,
     18 	F_HL_GT = 1 << O_HL_GT,
     19 	F_ANY  = F_HL_EQ | F_HL_LT | F_HL_GT,
     20 };
     21 
     22 static void hl_help(void)
     23 {
     24 	printf(
     25 "hl match options:\n"
     26 "[!] --hl-eq value	Match hop limit value\n"
     27 "  --hl-lt value	Match HL < value\n"
     28 "  --hl-gt value	Match HL > value\n");
     29 }
     30 
     31 static void hl_parse(struct xt_option_call *cb)
     32 {
     33 	struct ip6t_hl_info *info = cb->data;
     34 
     35 	xtables_option_parse(cb);
     36 	switch (cb->entry->id) {
     37 	case O_HL_EQ:
     38 		info->mode = cb->invert ? IP6T_HL_NE : IP6T_HL_EQ;
     39 		break;
     40 	case O_HL_LT:
     41 		info->mode = IP6T_HL_LT;
     42 		break;
     43 	case O_HL_GT:
     44 		info->mode = IP6T_HL_GT;
     45 		break;
     46 	}
     47 }
     48 
     49 static void hl_check(struct xt_fcheck_call *cb)
     50 {
     51 	if (!(cb->xflags & F_ANY))
     52 		xtables_error(PARAMETER_PROBLEM,
     53 			"HL match: You must specify one of "
     54 			"`--hl-eq', `--hl-lt', `--hl-gt'");
     55 }
     56 
     57 static void hl_print(const void *ip, const struct xt_entry_match *match,
     58                      int numeric)
     59 {
     60 	static const char *const op[] = {
     61 		[IP6T_HL_EQ] = "==",
     62 		[IP6T_HL_NE] = "!=",
     63 		[IP6T_HL_LT] = "<",
     64 		[IP6T_HL_GT] = ">" };
     65 
     66 	const struct ip6t_hl_info *info =
     67 		(struct ip6t_hl_info *) match->data;
     68 
     69 	printf(" HL match HL %s %u", op[info->mode], info->hop_limit);
     70 }
     71 
     72 static void hl_save(const void *ip, const struct xt_entry_match *match)
     73 {
     74 	static const char *const op[] = {
     75 		[IP6T_HL_EQ] = "--hl-eq",
     76 		[IP6T_HL_NE] = "! --hl-eq",
     77 		[IP6T_HL_LT] = "--hl-lt",
     78 		[IP6T_HL_GT] = "--hl-gt" };
     79 
     80 	const struct ip6t_hl_info *info =
     81 		(struct ip6t_hl_info *) match->data;
     82 
     83 	printf(" %s %u", op[info->mode], info->hop_limit);
     84 }
     85 
     86 static const char *const op[] = {
     87 	[IP6T_HL_EQ] = "",
     88 	[IP6T_HL_NE] = "!= ",
     89 	[IP6T_HL_LT] = "lt ",
     90 	[IP6T_HL_GT] = "gt "
     91 };
     92 
     93 static int hl_xlate(struct xt_xlate *xl,
     94 		    const struct xt_xlate_mt_params *params)
     95 {
     96 	const struct ip6t_hl_info *info =
     97 		(struct ip6t_hl_info *) params->match->data;
     98 
     99 	xt_xlate_add(xl, "ip6 hoplimit %s%u", op[info->mode], info->hop_limit);
    100 
    101 	return 1;
    102 }
    103 
    104 #define s struct ip6t_hl_info
    105 static const struct xt_option_entry hl_opts[] = {
    106 	{.name = "hl-lt", .id = O_HL_LT, .excl = F_ANY, .type = XTTYPE_UINT8,
    107 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
    108 	{.name = "hl-gt", .id = O_HL_GT, .excl = F_ANY, .type = XTTYPE_UINT8,
    109 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
    110 	{.name = "hl-eq", .id = O_HL_EQ, .excl = F_ANY, .type = XTTYPE_UINT8,
    111 	 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
    112 	{.name = "hl", .id = O_HL_EQ, .excl = F_ANY, .type = XTTYPE_UINT8,
    113 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
    114 	XTOPT_TABLEEND,
    115 };
    116 #undef s
    117 
    118 static struct xtables_match hl_mt6_reg = {
    119 	.name          = "hl",
    120 	.version       = XTABLES_VERSION,
    121 	.family        = NFPROTO_IPV6,
    122 	.size          = XT_ALIGN(sizeof(struct ip6t_hl_info)),
    123 	.userspacesize = XT_ALIGN(sizeof(struct ip6t_hl_info)),
    124 	.help          = hl_help,
    125 	.print         = hl_print,
    126 	.save          = hl_save,
    127 	.x6_parse      = hl_parse,
    128 	.x6_fcheck     = hl_check,
    129 	.x6_options    = hl_opts,
    130 	.xlate	       = hl_xlate,
    131 };
    132 
    133 
    134 void _init(void)
    135 {
    136 	xtables_register_match(&hl_mt6_reg);
    137 }
    138