blob: 0c90c66b199257dfd6123c1cc6a2ec904aa0053a [file] [log] [blame]
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -08001/*
2 * Copyright (C)2006 USAGI/WIDE Project
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Author:
9 * Masahide NAKAMURA @USAGI <masahide.nakamura.cz@hitachi.com>
10 *
11 * Based on net/netfilter/xt_tcpudp.c
12 *
13 */
Jan Engelhardtbe91fd52010-03-18 02:22:32 +010014#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080015#include <linux/types.h>
16#include <linux/module.h>
17#include <net/ip.h>
18#include <linux/ipv6.h>
19#include <net/ipv6.h>
20#include <net/mip6.h>
21
22#include <linux/netfilter/x_tables.h>
23#include <linux/netfilter_ipv6/ip6t_mh.h>
24
Jan Engelhardt2ae15b62008-01-14 23:42:28 -080025MODULE_DESCRIPTION("Xtables: IPv6 Mobility Header match");
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080026MODULE_LICENSE("GPL");
27
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080028/* Returns 1 if the type is matched by the range, 0 otherwise */
Jan Engelhardt1d93a9c2007-07-07 22:15:35 -070029static inline bool
30type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080031{
Jan Engelhardt1d93a9c2007-07-07 22:15:35 -070032 return (type >= min && type <= max) ^ invert;
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080033}
34
Jan Engelhardt62fc8052009-07-07 20:42:08 +020035static bool mh_mt6(const struct sk_buff *skb, struct xt_action_param *par)
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080036{
Jan Engelhardta47362a2007-07-07 22:16:55 -070037 struct ip6_mh _mh;
38 const struct ip6_mh *mh;
Jan Engelhardtf7108a22008-10-08 11:35:18 +020039 const struct ip6t_mh *mhinfo = par->matchinfo;
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080040
41 /* Must not be a fragment. */
Jan Engelhardtf7108a22008-10-08 11:35:18 +020042 if (par->fragoff != 0)
Jan Engelhardt1d93a9c2007-07-07 22:15:35 -070043 return false;
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080044
Jan Engelhardtf7108a22008-10-08 11:35:18 +020045 mh = skb_header_pointer(skb, par->thoff, sizeof(_mh), &_mh);
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080046 if (mh == NULL) {
47 /* We've been asked to examine this packet, and we
48 can't. Hence, no choice but to drop. */
Jan Engelhardtbe91fd52010-03-18 02:22:32 +010049 pr_debug("Dropping evil MH tinygram.\n");
Jan Engelhardtb4ba2612009-07-07 20:54:30 +020050 par->hotdrop = true;
Jan Engelhardt1d93a9c2007-07-07 22:15:35 -070051 return false;
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080052 }
53
Masahide NAKAMURA138939e2007-02-12 11:16:17 -080054 if (mh->ip6mh_proto != IPPROTO_NONE) {
Jan Engelhardtbe91fd52010-03-18 02:22:32 +010055 pr_debug("Dropping invalid MH Payload Proto: %u\n",
Masahide NAKAMURA138939e2007-02-12 11:16:17 -080056 mh->ip6mh_proto);
Jan Engelhardtb4ba2612009-07-07 20:54:30 +020057 par->hotdrop = true;
Jan Engelhardt1d93a9c2007-07-07 22:15:35 -070058 return false;
Masahide NAKAMURA138939e2007-02-12 11:16:17 -080059 }
60
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080061 return type_match(mhinfo->types[0], mhinfo->types[1], mh->ip6mh_type,
62 !!(mhinfo->invflags & IP6T_MH_INV_TYPE));
63}
64
Jan Engelhardtb0f38452010-03-19 17:16:42 +010065static int mh_mt6_check(const struct xt_mtchk_param *par)
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080066{
Jan Engelhardt9b4fce72008-10-08 11:35:18 +020067 const struct ip6t_mh *mhinfo = par->matchinfo;
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080068
69 /* Must specify no unknown invflags */
Jan Engelhardtbd414ee2010-03-23 16:35:56 +010070 return (mhinfo->invflags & ~IP6T_MH_INV_MASK) ? -EINVAL : 0;
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080071}
72
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080073static struct xt_match mh_mt6_reg __read_mostly = {
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080074 .name = "mh",
Jan Engelhardtee999d82008-10-08 11:35:01 +020075 .family = NFPROTO_IPV6,
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080076 .checkentry = mh_mt6_check,
77 .match = mh_mt6,
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080078 .matchsize = sizeof(struct ip6t_mh),
79 .proto = IPPROTO_MH,
80 .me = THIS_MODULE,
81};
82
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080083static int __init mh_mt6_init(void)
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080084{
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080085 return xt_register_match(&mh_mt6_reg);
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080086}
87
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080088static void __exit mh_mt6_exit(void)
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080089{
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080090 xt_unregister_match(&mh_mt6_reg);
Masahide NAKAMURAa0ca2152007-02-07 15:12:57 -080091}
92
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080093module_init(mh_mt6_init);
94module_exit(mh_mt6_exit);