Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
ipv6
netfilter
ip6t_ipv6header.c
Go to the documentation of this file.
1
/* ipv6header match - matches IPv6 packets based
2
on whether they contain certain headers */
3
4
/* Original idea: Brad Chapman
5
* Rewritten by: Andras Kis-Szabo <
[email protected]
> */
6
7
/* (C) 2001-2002 Andras Kis-Szabo <
[email protected]
>
8
*
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License version 2 as
11
* published by the Free Software Foundation.
12
*/
13
14
#include <linux/module.h>
15
#include <
linux/skbuff.h
>
16
#include <linux/ipv6.h>
17
#include <linux/types.h>
18
#include <
net/checksum.h
>
19
#include <
net/ipv6.h
>
20
21
#include <linux/netfilter/x_tables.h>
22
#include <linux/netfilter_ipv6/ip6_tables.h>
23
#include <
linux/netfilter_ipv6/ip6t_ipv6header.h
>
24
25
MODULE_LICENSE
(
"GPL"
);
26
MODULE_DESCRIPTION
(
"Xtables: IPv6 header types match"
);
27
MODULE_AUTHOR
(
"Andras Kis-Szabo <
[email protected]
>"
);
28
29
static
bool
30
ipv6header_mt6(
const
struct
sk_buff
*
skb
,
struct
xt_action_param
*par)
31
{
32
const
struct
ip6t_ipv6header_info
*
info
= par->
matchinfo
;
33
unsigned
int
temp
;
34
int
len
;
35
u8
nexthdr
;
36
unsigned
int
ptr
;
37
38
/* Make sure this isn't an evil packet */
39
40
/* type of the 1st exthdr */
41
nexthdr = ipv6_hdr(skb)->nexthdr;
42
/* pointer to the 1st exthdr */
43
ptr =
sizeof
(
struct
ipv6hdr
);
44
/* available length */
45
len = skb->
len
-
ptr
;
46
temp = 0;
47
48
while
(ip6t_ext_hdr(nexthdr)) {
49
const
struct
ipv6_opt_hdr
*hp;
50
struct
ipv6_opt_hdr
_hdr;
51
int
hdrlen
;
52
53
/* No more exthdr -> evaluate */
54
if
(nexthdr ==
NEXTHDR_NONE
) {
55
temp |=
MASK_NONE
;
56
break
;
57
}
58
/* Is there enough space for the next ext header? */
59
if
(len < (
int
)
sizeof
(
struct
ipv6_opt_hdr
))
60
return
false
;
61
/* ESP -> evaluate */
62
if
(nexthdr ==
NEXTHDR_ESP
) {
63
temp |=
MASK_ESP
;
64
break
;
65
}
66
67
hp = skb_header_pointer(skb, ptr,
sizeof
(_hdr), &_hdr);
68
BUG_ON
(hp ==
NULL
);
69
70
/* Calculate the header length */
71
if
(nexthdr ==
NEXTHDR_FRAGMENT
)
72
hdrlen = 8;
73
else
if
(nexthdr ==
NEXTHDR_AUTH
)
74
hdrlen = (hp->
hdrlen
+ 2) << 2;
75
else
76
hdrlen =
ipv6_optlen
(hp);
77
78
/* set the flag */
79
switch
(nexthdr) {
80
case
NEXTHDR_HOP
:
81
temp |=
MASK_HOPOPTS
;
82
break
;
83
case
NEXTHDR_ROUTING
:
84
temp |=
MASK_ROUTING
;
85
break
;
86
case
NEXTHDR_FRAGMENT
:
87
temp |=
MASK_FRAGMENT
;
88
break
;
89
case
NEXTHDR_AUTH
:
90
temp |=
MASK_AH
;
91
break
;
92
case
NEXTHDR_DEST
:
93
temp |=
MASK_DSTOPTS
;
94
break
;
95
default
:
96
return
false
;
97
break
;
98
}
99
100
nexthdr = hp->
nexthdr
;
101
len -=
hdrlen
;
102
ptr +=
hdrlen
;
103
if
(ptr > skb->
len
)
104
break
;
105
}
106
107
if
(nexthdr !=
NEXTHDR_NONE
&& nexthdr !=
NEXTHDR_ESP
)
108
temp |=
MASK_PROTO
;
109
110
if
(info->
modeflag
)
111
return
!((temp ^ info->
matchflags
^ info->
invflags
)
112
& info->
matchflags
);
113
else
{
114
if
(info->
invflags
)
115
return
temp != info->
matchflags
;
116
else
117
return
temp == info->
matchflags
;
118
}
119
}
120
121
static
int
ipv6header_mt6_check(
const
struct
xt_mtchk_param
*par)
122
{
123
const
struct
ip6t_ipv6header_info
*info = par->
matchinfo
;
124
125
/* invflags is 0 or 0xff in hard mode */
126
if
((!info->
modeflag
) && info->
invflags
!= 0x00 &&
127
info->
invflags
!= 0xFF)
128
return
-
EINVAL
;
129
130
return
0;
131
}
132
133
static
struct
xt_match
ipv6header_mt6_reg
__read_mostly
= {
134
.name =
"ipv6header"
,
135
.family =
NFPROTO_IPV6
,
136
.match = ipv6header_mt6,
137
.matchsize =
sizeof
(
struct
ip6t_ipv6header_info
),
138
.checkentry = ipv6header_mt6_check,
139
.destroy =
NULL
,
140
.me =
THIS_MODULE
,
141
};
142
143
static
int
__init
ipv6header_mt6_init(
void
)
144
{
145
return
xt_register_match
(&ipv6header_mt6_reg);
146
}
147
148
static
void
__exit
ipv6header_mt6_exit(
void
)
149
{
150
xt_unregister_match
(&ipv6header_mt6_reg);
151
}
152
153
module_init
(ipv6header_mt6_init);
154
module_exit
(ipv6header_mt6_exit);
Generated on Thu Jan 10 2013 14:59:23 for Linux Kernel by
1.8.2