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