1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* Kernel module to match EUI64 address parameters. */ |
3 | |
4 | /* (C) 2001-2002 Andras Kis-Szabo <kisza@sch.bme.hu> |
5 | */ |
6 | |
7 | #include <linux/module.h> |
8 | #include <linux/skbuff.h> |
9 | #include <linux/ipv6.h> |
10 | #include <linux/if_ether.h> |
11 | |
12 | #include <linux/netfilter/x_tables.h> |
13 | #include <linux/netfilter_ipv6/ip6_tables.h> |
14 | |
15 | MODULE_DESCRIPTION("Xtables: IPv6 EUI64 address match" ); |
16 | MODULE_LICENSE("GPL" ); |
17 | MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>" ); |
18 | |
19 | static bool |
20 | eui64_mt6(const struct sk_buff *skb, struct xt_action_param *par) |
21 | { |
22 | unsigned char eui64[8]; |
23 | |
24 | if (!(skb_mac_header(skb) >= skb->head && |
25 | skb_mac_header(skb) + ETH_HLEN <= skb->data) && |
26 | par->fragoff != 0) { |
27 | par->hotdrop = true; |
28 | return false; |
29 | } |
30 | |
31 | memset(eui64, 0, sizeof(eui64)); |
32 | |
33 | if (eth_hdr(skb)->h_proto == htons(ETH_P_IPV6)) { |
34 | if (ipv6_hdr(skb)->version == 0x6) { |
35 | memcpy(eui64, eth_hdr(skb)->h_source, 3); |
36 | memcpy(eui64 + 5, eth_hdr(skb)->h_source + 3, 3); |
37 | eui64[3] = 0xff; |
38 | eui64[4] = 0xfe; |
39 | eui64[0] ^= 0x02; |
40 | |
41 | if (!memcmp(p: ipv6_hdr(skb)->saddr.s6_addr + 8, q: eui64, |
42 | size: sizeof(eui64))) |
43 | return true; |
44 | } |
45 | } |
46 | |
47 | return false; |
48 | } |
49 | |
50 | static struct xt_match eui64_mt6_reg __read_mostly = { |
51 | .name = "eui64" , |
52 | .family = NFPROTO_IPV6, |
53 | .match = eui64_mt6, |
54 | .matchsize = sizeof(int), |
55 | .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) | |
56 | (1 << NF_INET_FORWARD), |
57 | .me = THIS_MODULE, |
58 | }; |
59 | |
60 | static int __init eui64_mt6_init(void) |
61 | { |
62 | return xt_register_match(target: &eui64_mt6_reg); |
63 | } |
64 | |
65 | static void __exit eui64_mt6_exit(void) |
66 | { |
67 | xt_unregister_match(target: &eui64_mt6_reg); |
68 | } |
69 | |
70 | module_init(eui64_mt6_init); |
71 | module_exit(eui64_mt6_exit); |
72 | |