1/*
2 * IP tables module for matching the value of the TTL
3 * (C) 2000,2001 by Harald Welte <laforge@netfilter.org>
4 *
5 * Hop Limit matching module
6 * (C) 2001-2002 Maciej Soltysiak <solt@dns.toxicfilms.tv>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/ip.h>
14#include <linux/ipv6.h>
15#include <linux/module.h>
16#include <linux/skbuff.h>
17
18#include <linux/netfilter/x_tables.h>
19#include <linux/netfilter_ipv4/ipt_ttl.h>
20#include <linux/netfilter_ipv6/ip6t_hl.h>
21
22MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
23MODULE_DESCRIPTION("Xtables: Hoplimit/TTL field match");
24MODULE_LICENSE("GPL");
25MODULE_ALIAS("ipt_ttl");
26MODULE_ALIAS("ip6t_hl");
27
28static bool ttl_mt(const struct sk_buff *skb, struct xt_action_param *par)
29{
30	const struct ipt_ttl_info *info = par->matchinfo;
31	const u8 ttl = ip_hdr(skb)->ttl;
32
33	switch (info->mode) {
34	case IPT_TTL_EQ:
35		return ttl == info->ttl;
36	case IPT_TTL_NE:
37		return ttl != info->ttl;
38	case IPT_TTL_LT:
39		return ttl < info->ttl;
40	case IPT_TTL_GT:
41		return ttl > info->ttl;
42	}
43
44	return false;
45}
46
47static bool hl_mt6(const struct sk_buff *skb, struct xt_action_param *par)
48{
49	const struct ip6t_hl_info *info = par->matchinfo;
50	const struct ipv6hdr *ip6h = ipv6_hdr(skb);
51
52	switch (info->mode) {
53	case IP6T_HL_EQ:
54		return ip6h->hop_limit == info->hop_limit;
55	case IP6T_HL_NE:
56		return ip6h->hop_limit != info->hop_limit;
57	case IP6T_HL_LT:
58		return ip6h->hop_limit < info->hop_limit;
59	case IP6T_HL_GT:
60		return ip6h->hop_limit > info->hop_limit;
61	}
62
63	return false;
64}
65
66static struct xt_match hl_mt_reg[] __read_mostly = {
67	{
68		.name       = "ttl",
69		.revision   = 0,
70		.family     = NFPROTO_IPV4,
71		.match      = ttl_mt,
72		.matchsize  = sizeof(struct ipt_ttl_info),
73		.me         = THIS_MODULE,
74	},
75	{
76		.name       = "hl",
77		.revision   = 0,
78		.family     = NFPROTO_IPV6,
79		.match      = hl_mt6,
80		.matchsize  = sizeof(struct ip6t_hl_info),
81		.me         = THIS_MODULE,
82	},
83};
84
85static int __init hl_mt_init(void)
86{
87	return xt_register_matches(hl_mt_reg, ARRAY_SIZE(hl_mt_reg));
88}
89
90static void __exit hl_mt_exit(void)
91{
92	xt_unregister_matches(hl_mt_reg, ARRAY_SIZE(hl_mt_reg));
93}
94
95module_init(hl_mt_init);
96module_exit(hl_mt_exit);
97