: prearation of removing skb_linearize()
Subsystems (2)
PATCH 3/19 : prearation of removing skb_linearize()
Use skb_header_pointer in ip6_tables.c, change argument order of matches/targets to match IPv4, multiple fixes.
# This is a BitKeeper generated diff -Nru style patch. #
# ChangeSet
# 2004/10/19 02:13:27+02:00 [email protected]
# [NETFILTER]: prearation of removing skb_linearize()
#
# This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules.
#
# Moreover ...
# - I deleted the optimization not to parse IPv6 extension header
# many time from previous patch. I'll send the patch to do this
# separately.
# - fixed the bug that "offset" argument of match functions are always 0.
# - deleted "hdr" and "datalen" argument and added "protoff" argument
# to match functions. "protoff" means the offset to Layer 4 protocol
# header.
# - the argument order of target function is changed likely IPv4 modules.
# This prevents user from meeting kernel panic when they use old
# match modules.
# - changed {tcp,udp,icmp6}_match(). These functions became very similar
# to codes in ip_tables.c again.
#
# Signed-off-by: Yasuyuki KOZAKAI <[email protected]>
# Signed-off-by: Patrick McHardy <[email protected]>
#
# net/ipv6/netfilter/ip6t_rt.c # 2004/10/19 02:13:00+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_owner.c # 2004/10/19 02:13:00+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_multiport.c # 2004/10/19 02:13:00+02:00 [email protected] +3 -4 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_mark.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_mac.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_limit.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_length.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_ipv6header.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_hl.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -1 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_hbh.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_frag.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_eui64.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_esp.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_dst.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_ah.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -2 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_MARK.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -1 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6t_LOG.c # 2004/10/19 02:12:59+02:00 [email protected] +1 -1 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # net/ipv6/netfilter/ip6_tables.c # 2004/10/19 02:12:59+02:00 [email protected] +122 -132 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # # include/linux/netfilter_ipv6/ip6_tables.h # 2004/10/19 02:12:59+02:00 [email protected] +8 -4 # [NETFILTER]: prearation of removing skb_linearize() # # This patch uses skb_header_pointer() so that packets can be parsed even though # skb_linearize() doesn't exist. But this patch doesn't remove skb_linearize() # yet. We can remove it after changing all match/target modules. # # Moreover ... # - I deleted the optimization not to parse IPv6 extension header # many time from previous patch. I'll send the patch to do this # separately. # - fixed the bug that "offset" argument of match functions are always 0. # - deleted "hdr" and "datalen" argument and added "protoff" argument # to match functions. "protoff" means the offset to Layer 4 protocol # header. # - the argument order of target function is changed likely IPv4 modules. # This prevents user from meeting kernel panic when they use old # match modules. # - changed {tcp,udp,icmp6}_match(). These functions became very similar # to codes in ip_tables.c again. # # Signed-off-by: Yasuyuki KOZAKAI <[email protected]> # Signed-off-by: Patrick McHardy <[email protected]> # diff -Nru a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h --- a/include/linux/netfilter_ipv6/ip6_tables.h 2004-10-22 03:37:28 +02:00 +++ b/include/linux/netfilter_ipv6/ip6_tables.h 2004-10-22 03:37:28 +02:00 @@ -355,13 +355,15 @@
/* Return true or false: return FALSE and set *hotdrop = 1 to
force immediate packet drop. */
+ /* Arguments changed since 2.6.9, as this must now handle
+ non-linear skb, using skb_header_pointer and
+ skb_ip_make_writable. */
int (*match)(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
- const void *hdr, - u_int16_t datalen, + unsigned int protoff,
int *hotdrop);
/* Called when user tries to insert an entry of this type. */
@@ -386,11 +388,13 @@
const char name[IP6T_FUNCTION_MAXNAMELEN];
- /* Returns verdict. */
+ /* Returns verdict. Argument order changed since 2.6.9, as this
+ must now handle non-linear skbs, using skb_copy_bits and
+ skb_ip_make_writable. */
unsigned int (*target)(struct sk_buff **pskb,
- unsigned int hooknum,
const struct net_device *in, const struct net_device *out,
+ unsigned int hooknum,
const void *targinfo, void *userdata);
net/ipv6/netfilter/ip6_tables.c +122 -132
@@ -158,14 +158,15 @@/* Returns whether matches rule or not. */ static inline int ip6_packet_match (const struct sk_buff *skb, -const struct ipv6hdr *ipv6,const char *indev,const char *outdev,const struct ip6t_ip6 *ip6info, -int isfrag) +unsigned int *protoff, +int *fragoff) {size_t i;unsigned long ret; +const struct ipv6hdr *ipv6 = skb->nh.ipv6h;#define FWINV (bool,invflg) ((bool) ^ !!(ip6info->invflags & invflg))
@@ -216,9 +217,10 @@/* look for the desired protocol header */ if ((ip6info->flags &IP6T_F_PROTO )) {u_int8_t currenthdr = ipv6->nexthdr; -struct ipv6_opt_hdr *hdrptr; +struct ipv6_opt_hdr _hdr, *hp;u_int16_t ptr;/* Header offset in skb */ u_int16_t hdrlen;/* Header */ +u_int16_t _fragoff =0 , *fp =NULL ; ptr =IPV6_HDR_LEN ;
@@ -234,23 +236,41 @@ (currenthdr == IPPROTO_ESP))return 0 ; - hdrptr = (struct ipv6_opt_hdr *)(skb->data + ptr); + hp =skb_header_pointer (skb, ptr,sizeof (_hdr), &_hdr); +BUG_ON (hp ==NULL );/* Size calculation */ if (currenthdr ==IPPROTO_FRAGMENT ) { + fp =skb_header_pointer (skb, + ptr+offsetof(struct frag_hdr , + frag_off), +sizeof (_fragoff), + &_fragoff); +if (fp ==NULL ) +return 0 ; + + _fragoff =ntohs (*fp) & ~0x7 ; hdrlen =8 ; }else if (currenthdr ==IPPROTO_AH ) - hdrlen = (hdrptr->hdrlen+2 )<<2 ; + hdrlen = (hp->hdrlen+2 )<<2 ;else - hdrlen =ipv6_optlen (hdrptr); + hdrlen =ipv6_optlen (hp); - currenthdr = hdrptr->nexthdr; + currenthdr = hp->nexthdr; ptr += hdrlen;/* ptr is too large */ if ( ptr > skb->len )return 0 ; +if (_fragoff) { +if (ip6t_ext_hdr (currenthdr)) +return 0 ; +break ; + } } + *protoff = ptr; + *fragoff = _fragoff; +/* currenthdr contains the protocol header */ dprintf("Packet protocol %hi ?= %s%hi.\n",
@@ -292,9 +312,9 @@static unsigned int ip6t_error (struct sk_buff **pskb, -unsigned int hooknum,const struct net_device *in,const struct net_device *out, +unsigned int hooknum,const void *targinfo,void *userinfo) {
@@ -310,13 +330,12 @@ const struct net_device *in, const struct net_device *out, int offset, - const void *hdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { /* Stop iteration if it doesn't match */ if (!m->u.kernel.match->match(skb, in, out, m->data, - offset, hdr, datalen, hotdrop)) + offset, protoff, hotdrop)) return 1; else return 0;
@@ -338,10 +357,8 @@ void *userdata) {static const char nulldevname[IFNAMSIZ ]; -u_int16_t offset =0 ; -struct ipv6hdr *ipv6; -void *protohdr; -u_int16_t datalen; +int offset =0 ; +unsigned int protoff =0 ;int hotdrop =0 ;/* Initializing verdict to NF_DROP keeps gcc happy. */ unsigned int verdict =NF_DROP ;
@@ -354,9 +371,6 @@return NF_DROP ;/* Initialization */ - ipv6 = (*pskb)->nh.ipv6h; - protohdr = (u_int32_t *)((char *)ipv6 +IPV6_HDR_LEN ); - datalen = (*pskb)->len -IPV6_HDR_LEN ; indev = in ? in->name : nulldevname; outdev = out ? out->name : nulldevname;
@@ -393,17 +407,19 @@IP_NF_ASSERT (e);IP_NF_ASSERT (back); (*pskb)->nfcache |= e->nfcache; -if (ip6_packet_match (*pskb, ipv6, indev, outdev, - &e->ipv6, offset)) { +if (ip6_packet_match (*pskb, indev, outdev, &e->ipv6, + &protoff, &offset)) {struct ip6t_entry_target *t;if (IP6T_MATCH_ITERATE (e, do_match, *pskb, in, out, - offset, protohdr, - datalen, &hotdrop) !=0 ) + offset, protoff, &hotdrop) !=0 ) goto no_match; -ADD_COUNTER (e->counters,ntohs (ipv6->payload_len) +IPV6_HDR_LEN ,1 ); +ADD_COUNTER (e->counters, +ntohs ((*pskb)->nh.ipv6h->payload_len) + +IPV6_HDR_LEN , +1 ); t =ip6t_get_target (e);IP_NF_ASSERT (t->u.kernel.target);
@@ -443,8 +459,8 @@ = 0xeeeeeeec;#endif verdict = t->u.kernel.target->target (pskb, - hook, in, out, + hook, t->data, userdata);
@@ -459,11 +475,6 @@ ((struct ip6t_entry *)table_base)->comefrom =0x57acc001 ;#endif -/* Target might have changed stuff. */ - ipv6 = (*pskb)->nh.ipv6h; - protohdr = (u_int32_t *)((void *)ipv6 +IPV6_HDR_LEN ); - datalen = (*pskb)->len -IPV6_HDR_LEN ; -if (verdict ==IP6T_CONTINUE ) e = (void *)e + e->next_offset;else
@@ -1535,26 +1546,31 @@static int tcp_find_option (u_int8_t option, -const struct tcphdr *tcp, -u_int16_t datalen, +const struct sk_buff *skb, +unsigned int tcpoff, +unsigned int optlen,int invert,int *hotdrop) { -unsigned int i =sizeof (struct tcphdr ); -const u_int8_t *opt = (u_int8_t *)tcp; +/* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ +u_int8_t _opt[60 -sizeof (struct tcphdr )], *op; +unsigned int i;duprintf ("tcp_match: finding option\n" ); +if (!optlen) +return invert;/* If we don't have the whole header, drop packet. */ -if (tcp->doff *4 <sizeof (struct tcphdr ) || - tcp->doff *4 > datalen) { + op =skb_header_pointer (skb, tcpoff +sizeof (struct tcphdr ), optlen, + _opt); +if (op ==NULL ) { *hotdrop =1 ;return 0 ; } -while (i < tcp->doff *4 ) { -if (opt[i] == option)return !invert; -if (opt[i] <2 ) i++; -else i += opt[i+1 ]?:1 ; +for (i =0 ; i < optlen; ) { +if (op[i] == option)return !invert; +if (op[i] <2 ) i++; +else i += op[i+1 ]?:1 ; }return invert;
@@ -1566,27 +1582,31 @@const struct net_device *out, const void *matchinfo, int offset, - const void *hdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { - const struct tcphdr *tcp; + struct tcphdr _tcph, *th;const struct ip6t_tcp *tcpinfo = matchinfo; -int tcpoff; -u8 nexthdr = skb->nh.ipv6h->nexthdr; -/* To quote Alan: +if (offset) { +/* To quote Alan: -Don't allow a fragment of TCP 8 bytes in. Nobody normal -causes this. Its a cracker trying to break in by doing a -flag overwrite to pass the direction checks. -*/ - -if (offset ==1 ) { -duprintf ("Dropping evil TCP offset=1 frag.\n" ); - *hotdrop =1 ; +Don't allow a fragment of TCP 8 bytes in. Nobody normal +causes this. Its a cracker trying to break in by doing a +flag overwrite to pass the direction checks. +*/ +if (offset ==1 ) { +duprintf ("Dropping evil TCP offset=1 frag.\n" ); + *hotdrop =1 ; + } +/* Must not be a fragment. */ return 0 ; - }else if (offset ==0 && datalen <sizeof (struct tcphdr )) { + } + +#define FWINVTCP (bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) + + th =skb_header_pointer (skb, protoff,sizeof (_tcph), &_tcph); +if (th ==NULL ) {/* We've been asked to examine this packet, and we can't. Hence, no choice but to drop. */ duprintf ("Dropping evil TCP offset=0 tinygram.\n" );
@@ -1594,45 +1614,30 @@return 0 ; } - tcpoff = (u8 *)(skb->nh.ipv6h +1 ) - skb->data; - tcpoff =ipv6_skip_exthdr (skb, tcpoff, &nexthdr, skb->len - tcpoff); -if (tcpoff <0 || tcpoff > skb->len) { -duprintf ("tcp_match: cannot skip exthdr. Dropping.\n" ); - *hotdrop =1 ; -return 0 ; - }else if (nexthdr ==IPPROTO_FRAGMENT ) -return 0 ; -else if (nexthdr !=IPPROTO_TCP || - skb->len - tcpoff <sizeof (struct tcphdr )) { -/* cannot be occured */ -duprintf ("tcp_match: cannot get TCP header. Dropping.\n" ); - *hotdrop =1 ; -return 0 ; +if (!port_match (tcpinfo->spts[0 ], tcpinfo->spts[1 ], +ntohs (th->source), + !!(tcpinfo->invflags &IP6T_TCP_INV_SRCPT ))) +return 0 ; +if (!port_match (tcpinfo->dpts[0 ], tcpinfo->dpts[1 ], +ntohs (th->dest), + !!(tcpinfo->invflags &IP6T_TCP_INV_DSTPT ))) +return 0 ; +if (!FWINVTCP ((((unsigned char *)th)[13 ] & tcpinfo->flg_mask) + == tcpinfo->flg_cmp, +IP6T_TCP_INV_FLAGS )) +return 0 ; +if (tcpinfo->option) { +if (th->doff *4 <sizeof (_tcph)) { + *hotdrop =1 ; +return 0 ; + } +if (!tcp_find_option (tcpinfo->option, skb, protoff, + th->doff*4 -sizeof (*th), + tcpinfo->invflags &IP6T_TCP_INV_OPTION , + hotdrop)) +return 0 ; } - - tcp = (struct tcphdr *)(skb->data + tcpoff); - -/* FIXME: Try tcp doff >> packet len against various stacks --RR */ - -#define FWINVTCP (bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) - -/* Must not be a fragment. */ -return !offset - &&port_match (tcpinfo->spts[0 ], tcpinfo->spts[1 ], -ntohs (tcp->source), - !!(tcpinfo->invflags &IP6T_TCP_INV_SRCPT )) - &&port_match (tcpinfo->dpts[0 ], tcpinfo->dpts[1 ], -ntohs (tcp->dest), - !!(tcpinfo->invflags &IP6T_TCP_INV_DSTPT )) - &&FWINVTCP ((((unsigned char *)tcp)[13 ] - & tcpinfo->flg_mask) - == tcpinfo->flg_cmp, -IP6T_TCP_INV_FLAGS ) - && (!tcpinfo->option - ||tcp_find_option (tcpinfo->option, tcp, datalen, - tcpinfo->invflags - &IP6T_TCP_INV_OPTION , - hotdrop)); +return 1 ; }/* Called when user tries to insert an entry of this type. */
@@ -1658,16 +1663,18 @@const struct net_device *out, const void *matchinfo, int offset, - const void *hdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { - const struct udphdr *udp; + struct udphdr _udph, *uh;const struct ip6t_udp *udpinfo = matchinfo; -int udpoff; -u8 nexthdr = skb->nh.ipv6h->nexthdr; -if (offset ==0 && datalen <sizeof (struct udphdr )) { +/* Must not be a fragment. */ +if (offset) +return 0 ; + + uh =skb_header_pointer (skb, protoff,sizeof (_udph), &_udph); +if (uh ==NULL ) {/* We've been asked to examine this packet, and we can't. Hence, no choice but to drop. */ duprintf ("Dropping evil UDP tinygram.\n" );
@@ -1675,30 +1682,11 @@return 0 ; } - udpoff = (u8 *)(skb->nh.ipv6h +1 ) - skb->data; - udpoff =ipv6_skip_exthdr (skb, udpoff, &nexthdr, skb->len - udpoff); -if (udpoff <0 || udpoff > skb->len) { -duprintf ("udp_match: cannot skip exthdr. Dropping.\n" ); - *hotdrop =1 ; -return 0 ; - }else if (nexthdr ==IPPROTO_FRAGMENT ) -return 0 ; -else if (nexthdr !=IPPROTO_UDP || - skb->len - udpoff <sizeof (struct udphdr )) { -duprintf ("udp_match: cannot get UDP header. Dropping.\n" ); - *hotdrop =1 ; -return 0 ; - } - - udp = (struct udphdr *)(skb->data + udpoff); - -/* Must not be a fragment. */ -return !offset - &&port_match (udpinfo->spts[0 ], udpinfo->spts[1 ], -ntohs (udp->source), - !!(udpinfo->invflags &IP6T_UDP_INV_SRCPT )) +return port_match (udpinfo->spts[0 ], udpinfo->spts[1 ], +ntohs (uh->source), + !!(udpinfo->invflags &IP6T_UDP_INV_SRCPT )) &&port_match (udpinfo->dpts[0 ], udpinfo->dpts[1 ], -ntohs (udp->dest), +ntohs (uh->dest), !!(udpinfo->invflags &IP6T_UDP_INV_DSTPT )); }
@@ -1748,14 +1736,18 @@const struct net_device *out, const void *matchinfo, int offset, - const void *hdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { - const struct icmp6hdr *icmp = hdr; + struct icmp6hdr _icmp, *ic;const struct ip6t_icmp *icmpinfo = matchinfo; -if (offset ==0 && datalen <2 ) { +/* Must not be a fragment. */ +if (offset) +return 0 ; + + ic =skb_header_pointer (skb, protoff,sizeof (_icmp), &_icmp); +if (ic ==NULL ) {/* We've been asked to examine this packet, and we can't. Hence, no choice but to drop. */ duprintf ("Dropping evil ICMP tinygram.\n" );
@@ -1763,13 +1755,11 @@return 0 ; } -/* Must not be a fragment. */ -return !offset - &&icmp6_type_code_match (icmpinfo->type, - icmpinfo->code[0 ], - icmpinfo->code[1 ], - icmp->icmp6_type, icmp->icmp6_code, - !!(icmpinfo->invflags&IP6T_ICMP_INV )); +return icmp6_type_code_match (icmpinfo->type, + icmpinfo->code[0 ], + icmpinfo->code[1 ], + ic->icmp6_type, ic->icmp6_code, + !!(icmpinfo->invflags&IP6T_ICMP_INV )); }/* Called when user tries to insert an entry of this type. */
net/ipv6/netfilter/ip6t_LOG.c +1 -1
@@ -335,9 +335,9 @@static unsigned int ip6t_log_target (struct sk_buff **pskb, -unsigned int hooknum,const struct net_device *in,const struct net_device *out, +unsigned int hooknum,const void *targinfo,void *userinfo) {
net/ipv6/netfilter/ip6t_MARK.c +1 -1
@@ -20,9 +20,9 @@static unsigned int target (struct sk_buff **pskb, -unsigned int hooknum,const struct net_device *in,const struct net_device *out, +unsigned int hooknum,const void *targinfo,void *userinfo) {
net/ipv6/netfilter/ip6t_ah.c +1 -2
@@ -45,8 +45,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *protohdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { struct ip_auth_hdr *ah = NULL;
net/ipv6/netfilter/ip6t_dst.c +1 -2
@@ -60,8 +60,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *protohdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { struct ipv6_opt_hdr *optsh = NULL;
net/ipv6/netfilter/ip6t_esp.c +1 -2
@@ -45,8 +45,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *protohdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { struct ip_esp_hdr *esp = NULL;
net/ipv6/netfilter/ip6t_eui64.c +1 -2
@@ -24,8 +24,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *hdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) {
net/ipv6/netfilter/ip6t_frag.c +1 -2
@@ -70,8 +70,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *protohdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { struct fraghdr *frag = NULL;
net/ipv6/netfilter/ip6t_hbh.c +1 -2
@@ -59,8 +59,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *protohdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { struct ipv6_opt_hdr *optsh = NULL;
net/ipv6/netfilter/ip6t_hl.c +1 -1
@@ -20,7 +20,7 @@static int match (const struct sk_buff *skb,const struct net_device *in,const struct net_device *out,const void *matchinfo, -int offset,const void *hdr,u_int16_t datalen, +int offset,unsigned int protoff,int *hotdrop) {const struct ip6t_hl_info *info = matchinfo;
net/ipv6/netfilter/ip6t_ipv6header.c +1 -2
@@ -31,8 +31,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *protohdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { const struct ip6t_ipv6header_info *info = matchinfo;
net/ipv6/netfilter/ip6t_length.c +1 -2
@@ -23,8 +23,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *hdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { const struct ip6t_length_info *info = matchinfo;
net/ipv6/netfilter/ip6t_limit.c +1 -2
@@ -57,8 +57,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *hdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { struct ip6t_rateinfo *r = ((struct ip6t_rateinfo *)matchinfo)->master;
net/ipv6/netfilter/ip6t_mac.c +1 -2
@@ -25,8 +25,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *hdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { const struct ip6t_mac_info *info = matchinfo;
net/ipv6/netfilter/ip6t_mark.c +1 -2
@@ -24,8 +24,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *hdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { const struct ip6t_mark_info *info = matchinfo;
net/ipv6/netfilter/ip6t_multiport.c +3 -4
@@ -53,15 +53,14 @@const struct net_device *out, const void *matchinfo, int offset, - const void *hdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { - const struct udphdr *udp = hdr; + const struct udphdr *udp = (const struct udphdr *)(skb->data + protoff);const struct ip6t_multiport *multiinfo = matchinfo;/* Must be big enough to read ports. */ -if (offset ==0 && datalen <sizeof (struct udphdr )) { +if (offset ==0 && skb->len - protoff <sizeof (struct udphdr )) {/* We've been asked to examine this packet, and we can't. Hence, no choice but to drop. */ duprintf("ip6t_multiport:"
net/ipv6/netfilter/ip6t_owner.c +1 -2
@@ -92,8 +92,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *hdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { const struct ip6t_owner_info *info = matchinfo;
net/ipv6/netfilter/ip6t_rt.c +1 -2
@@ -47,8 +47,7 @@const struct net_device *out, const void *matchinfo, int offset, - const void *protohdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { struct ipv6_rt_hdr *route = NULL;