Commit 3c417db9 authored by Patrick McHardy's avatar Patrick McHardy

Merge coreworks.de:/home/kaber/src/bk-repos/linux-2.6

into coreworks.de:/home/kaber/src/nf/netfilter-2.6
parents beb0e5c2 4eb6a871
...@@ -250,8 +250,8 @@ struct sk_buff { ...@@ -250,8 +250,8 @@ struct sk_buff {
#ifdef CONFIG_NETFILTER #ifdef CONFIG_NETFILTER
unsigned long nfmark; unsigned long nfmark;
__u32 nfcache; __u32 nfcache;
struct nf_conntrack *nfct;
__u32 nfctinfo; __u32 nfctinfo;
struct nf_conntrack *nfct;
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
unsigned int nf_debug; unsigned int nf_debug;
#endif #endif
......
...@@ -139,7 +139,7 @@ icmp_error_message(struct sk_buff *skb, ...@@ -139,7 +139,7 @@ icmp_error_message(struct sk_buff *skb,
struct { struct {
struct icmphdr icmp; struct icmphdr icmp;
struct iphdr ip; struct iphdr ip;
} inside; } _in, *inside;
struct ip_conntrack_protocol *innerproto; struct ip_conntrack_protocol *innerproto;
struct ip_conntrack_tuple_hash *h; struct ip_conntrack_tuple_hash *h;
int dataoff; int dataoff;
...@@ -147,21 +147,22 @@ icmp_error_message(struct sk_buff *skb, ...@@ -147,21 +147,22 @@ icmp_error_message(struct sk_buff *skb,
IP_NF_ASSERT(skb->nfct == NULL); IP_NF_ASSERT(skb->nfct == NULL);
/* Not enough header? */ /* Not enough header? */
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &inside, sizeof(inside))!=0) inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in);
if (inside == NULL)
return NF_ACCEPT; return NF_ACCEPT;
/* Ignore ICMP's containing fragments (shouldn't happen) */ /* Ignore ICMP's containing fragments (shouldn't happen) */
if (inside.ip.frag_off & htons(IP_OFFSET)) { if (inside->ip.frag_off & htons(IP_OFFSET)) {
DEBUGP("icmp_error_track: fragment of proto %u\n", DEBUGP("icmp_error_track: fragment of proto %u\n",
inside.ip.protocol); inside->ip.protocol);
return NF_ACCEPT; return NF_ACCEPT;
} }
innerproto = ip_ct_find_proto(inside.ip.protocol); innerproto = ip_ct_find_proto(inside->ip.protocol);
dataoff = skb->nh.iph->ihl*4 + sizeof(inside.icmp) + inside.ip.ihl*4; dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp) + inside->ip.ihl*4;
/* Are they talking about one of our connections? */ /* Are they talking about one of our connections? */
if (!ip_ct_get_tuple(&inside.ip, skb, dataoff, &origtuple, innerproto)) { if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) {
DEBUGP("icmp_error: ! get_tuple p=%u", inside.ip.protocol); DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol);
return NF_ACCEPT; return NF_ACCEPT;
} }
...@@ -205,10 +206,11 @@ static int ...@@ -205,10 +206,11 @@ static int
icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
unsigned int hooknum) unsigned int hooknum)
{ {
struct icmphdr icmph; struct icmphdr _ih, *icmph;
/* Not enough header? */ /* Not enough header? */
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &icmph, sizeof(icmph))!=0) { icmph = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_ih), &_ih);
if (icmph == NULL) {
if (LOG_INVALID(IPPROTO_ICMP)) if (LOG_INVALID(IPPROTO_ICMP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL, nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_icmp: short packet "); "ip_ct_icmp: short packet ");
...@@ -245,7 +247,7 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, ...@@ -245,7 +247,7 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
* RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently * RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently
* discarded. * discarded.
*/ */
if (icmph.type > NR_ICMP_TYPES) { if (icmph->type > NR_ICMP_TYPES) {
if (LOG_INVALID(IPPROTO_ICMP)) if (LOG_INVALID(IPPROTO_ICMP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL, nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_icmp: invalid ICMP type "); "ip_ct_icmp: invalid ICMP type ");
...@@ -253,11 +255,11 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, ...@@ -253,11 +255,11 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
} }
/* Need to track icmp error message? */ /* Need to track icmp error message? */
if (icmph.type != ICMP_DEST_UNREACH if (icmph->type != ICMP_DEST_UNREACH
&& icmph.type != ICMP_SOURCE_QUENCH && icmph->type != ICMP_SOURCE_QUENCH
&& icmph.type != ICMP_TIME_EXCEEDED && icmph->type != ICMP_TIME_EXCEEDED
&& icmph.type != ICMP_PARAMETERPROB && icmph->type != ICMP_PARAMETERPROB
&& icmph.type != ICMP_REDIRECT) && icmph->type != ICMP_REDIRECT)
return NF_ACCEPT; return NF_ACCEPT;
return icmp_error_message(skb, ctinfo, hooknum); return icmp_error_message(skb, ctinfo, hooknum);
......
...@@ -152,18 +152,18 @@ static int sctp_pkt_to_tuple(const struct sk_buff *skb, ...@@ -152,18 +152,18 @@ static int sctp_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff, unsigned int dataoff,
struct ip_conntrack_tuple *tuple) struct ip_conntrack_tuple *tuple)
{ {
sctp_sctphdr_t hdr; sctp_sctphdr_t _hdr, *hp;
DEBUGP(__FUNCTION__); DEBUGP(__FUNCTION__);
DEBUGP("\n"); DEBUGP("\n");
/* Actually only need first 8 bytes. */ /* Actually only need first 8 bytes. */
if (skb_copy_bits(skb, dataoff, &hdr, 8) != 0) hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
if (hp == NULL)
return 0; return 0;
tuple->src.u.sctp.port = hdr.source; tuple->src.u.sctp.port = hp->source;
tuple->dst.u.sctp.port = hdr.dest; tuple->dst.u.sctp.port = hp->dest;
return 1; return 1;
} }
...@@ -206,10 +206,11 @@ static int sctp_print_conntrack(struct seq_file *s, ...@@ -206,10 +206,11 @@ static int sctp_print_conntrack(struct seq_file *s,
return seq_printf(s, "%s ", sctp_conntrack_names[state]); return seq_printf(s, "%s ", sctp_conntrack_names[state]);
} }
#define for_each_sctp_chunk(skb, sch, offset, count) \ #define for_each_sctp_chunk(skb, sch, _sch, offset, count) \
for (offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t), count = 0; \ for (offset = skb->nh.iph->ihl * 4 + sizeof(sctp_sctphdr_t), count = 0; \
offset < skb->len && !skb_copy_bits(skb, offset, &sch, sizeof(sch)); \ offset < skb->len && \
offset += (htons(sch.length) + 3) & ~3, count++) (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \
offset += (htons(sch->length) + 3) & ~3, count++)
/* Some validity checks to make sure the chunks are fine */ /* Some validity checks to make sure the chunks are fine */
static int do_basic_checks(struct ip_conntrack *conntrack, static int do_basic_checks(struct ip_conntrack *conntrack,
...@@ -217,7 +218,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack, ...@@ -217,7 +218,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
char *map) char *map)
{ {
u_int32_t offset, count; u_int32_t offset, count;
sctp_chunkhdr_t sch; sctp_chunkhdr_t _sch, *sch;
int flag; int flag;
DEBUGP(__FUNCTION__); DEBUGP(__FUNCTION__);
...@@ -225,19 +226,19 @@ static int do_basic_checks(struct ip_conntrack *conntrack, ...@@ -225,19 +226,19 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
flag = 0; flag = 0;
for_each_sctp_chunk (skb, sch, offset, count) { for_each_sctp_chunk (skb, sch, _sch, offset, count) {
DEBUGP("Chunk Num: %d Type: %d\n", count, sch.type); DEBUGP("Chunk Num: %d Type: %d\n", count, sch->type);
if (sch.type == SCTP_CID_INIT if (sch->type == SCTP_CID_INIT
|| sch.type == SCTP_CID_INIT_ACK || sch->type == SCTP_CID_INIT_ACK
|| sch.type == SCTP_CID_SHUTDOWN_COMPLETE) { || sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
flag = 1; flag = 1;
} }
/* Cookie Ack/Echo chunks not the first OR /* Cookie Ack/Echo chunks not the first OR
Init / Init Ack / Shutdown compl chunks not the only chunks */ Init / Init Ack / Shutdown compl chunks not the only chunks */
if ((sch.type == SCTP_CID_COOKIE_ACK if ((sch->type == SCTP_CID_COOKIE_ACK
|| sch.type == SCTP_CID_COOKIE_ECHO || sch->type == SCTP_CID_COOKIE_ECHO
|| flag) || flag)
&& count !=0 ) { && count !=0 ) {
DEBUGP("Basic checks failed\n"); DEBUGP("Basic checks failed\n");
...@@ -245,7 +246,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack, ...@@ -245,7 +246,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
} }
if (map) { if (map) {
set_bit (sch.type, (void *)map); set_bit(sch->type, (void *)map);
} }
} }
...@@ -313,15 +314,17 @@ static int sctp_packet(struct ip_conntrack *conntrack, ...@@ -313,15 +314,17 @@ static int sctp_packet(struct ip_conntrack *conntrack,
enum ip_conntrack_info ctinfo) enum ip_conntrack_info ctinfo)
{ {
enum sctp_conntrack newconntrack, oldsctpstate; enum sctp_conntrack newconntrack, oldsctpstate;
sctp_sctphdr_t sctph; struct iphdr *iph = skb->nh.iph;
sctp_chunkhdr_t sch; sctp_sctphdr_t _sctph, *sh;
sctp_chunkhdr_t _sch, *sch;
u_int32_t offset, count; u_int32_t offset, count;
char map[256 / sizeof (char)] = {0}; char map[256 / sizeof (char)] = {0};
DEBUGP(__FUNCTION__); DEBUGP(__FUNCTION__);
DEBUGP("\n"); DEBUGP("\n");
if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &sctph, sizeof(sctph)) != 0) sh = skb_header_pointer(skb, iph->ihl * 4, sizeof(_sctph), &_sctph);
if (sh == NULL)
return -1; return -1;
if (do_basic_checks(conntrack, skb, map) != 0) if (do_basic_checks(conntrack, skb, map) != 0)
...@@ -333,71 +336,72 @@ static int sctp_packet(struct ip_conntrack *conntrack, ...@@ -333,71 +336,72 @@ static int sctp_packet(struct ip_conntrack *conntrack,
&& !test_bit(SCTP_CID_COOKIE_ECHO, (void *)map) && !test_bit(SCTP_CID_COOKIE_ECHO, (void *)map)
&& !test_bit(SCTP_CID_ABORT, (void *)map) && !test_bit(SCTP_CID_ABORT, (void *)map)
&& !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map) && !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map)
&& (sctph.vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) { && (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
DEBUGP("Verification tag check failed\n"); DEBUGP("Verification tag check failed\n");
return -1; return -1;
} }
oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX; oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;
for_each_sctp_chunk (skb, sch, offset, count) { for_each_sctp_chunk (skb, sch, _sch, offset, count) {
WRITE_LOCK(&sctp_lock); WRITE_LOCK(&sctp_lock);
/* Special cases of Verification tag check (Sec 8.5.1) */ /* Special cases of Verification tag check (Sec 8.5.1) */
if (sch.type == SCTP_CID_INIT) { if (sch->type == SCTP_CID_INIT) {
/* Sec 8.5.1 (A) */ /* Sec 8.5.1 (A) */
if (sctph.vtag != 0) { if (sh->vtag != 0) {
WRITE_UNLOCK(&sctp_lock); WRITE_UNLOCK(&sctp_lock);
return -1; return -1;
} }
} else if (sch.type == SCTP_CID_ABORT) { } else if (sch->type == SCTP_CID_ABORT) {
/* Sec 8.5.1 (B) */ /* Sec 8.5.1 (B) */
if (!(sctph.vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)]) if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
&& !(sctph.vtag == conntrack->proto.sctp.vtag && !(sh->vtag == conntrack->proto.sctp.vtag
[1 - CTINFO2DIR(ctinfo)])) { [1 - CTINFO2DIR(ctinfo)])) {
WRITE_UNLOCK(&sctp_lock); WRITE_UNLOCK(&sctp_lock);
return -1; return -1;
} }
} else if (sch.type == SCTP_CID_SHUTDOWN_COMPLETE) { } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
/* Sec 8.5.1 (C) */ /* Sec 8.5.1 (C) */
if (!(sctph.vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)]) if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
&& !(sctph.vtag == conntrack->proto.sctp.vtag && !(sh->vtag == conntrack->proto.sctp.vtag
[1 - CTINFO2DIR(ctinfo)] [1 - CTINFO2DIR(ctinfo)]
&& (sch.flags & 1))) { && (sch->flags & 1))) {
WRITE_UNLOCK(&sctp_lock); WRITE_UNLOCK(&sctp_lock);
return -1; return -1;
} }
} else if (sch.type == SCTP_CID_COOKIE_ECHO) { } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
/* Sec 8.5.1 (D) */ /* Sec 8.5.1 (D) */
if (!(sctph.vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) { if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
WRITE_UNLOCK(&sctp_lock); WRITE_UNLOCK(&sctp_lock);
return -1; return -1;
} }
} }
oldsctpstate = conntrack->proto.sctp.state; oldsctpstate = conntrack->proto.sctp.state;
newconntrack = new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch.type); newconntrack = new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch->type);
/* Invalid */ /* Invalid */
if (newconntrack == SCTP_CONNTRACK_MAX) { if (newconntrack == SCTP_CONNTRACK_MAX) {
DEBUGP("ip_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n", DEBUGP("ip_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",
CTINFO2DIR(ctinfo), sch.type, oldsctpstate); CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
WRITE_UNLOCK(&sctp_lock); WRITE_UNLOCK(&sctp_lock);
return -1; return -1;
} }
/* If it is an INIT or an INIT ACK note down the vtag */ /* If it is an INIT or an INIT ACK note down the vtag */
if (sch.type == SCTP_CID_INIT if (sch->type == SCTP_CID_INIT
|| sch.type == SCTP_CID_INIT_ACK) { || sch->type == SCTP_CID_INIT_ACK) {
sctp_inithdr_t inithdr; sctp_inithdr_t _inithdr, *ih;
if (skb_copy_bits(skb, offset + sizeof (sctp_chunkhdr_t), ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
&inithdr, sizeof(inithdr)) != 0) { sizeof(_inithdr), &_inithdr);
if (ih == NULL) {
WRITE_UNLOCK(&sctp_lock); WRITE_UNLOCK(&sctp_lock);
return -1; return -1;
} }
DEBUGP("Setting vtag %x for dir %d\n", DEBUGP("Setting vtag %x for dir %d\n",
inithdr.init_tag, CTINFO2DIR(ctinfo)); ih->init_tag, CTINFO2DIR(ctinfo));
conntrack->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = inithdr.init_tag; conntrack->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = ih->init_tag;
} }
conntrack->proto.sctp.state = newconntrack; conntrack->proto.sctp.state = newconntrack;
...@@ -421,15 +425,17 @@ static int sctp_new(struct ip_conntrack *conntrack, ...@@ -421,15 +425,17 @@ static int sctp_new(struct ip_conntrack *conntrack,
const struct sk_buff *skb) const struct sk_buff *skb)
{ {
enum sctp_conntrack newconntrack; enum sctp_conntrack newconntrack;
sctp_sctphdr_t sctph; struct iphdr *iph = skb->nh.iph;
sctp_chunkhdr_t sch; sctp_sctphdr_t _sctph, *sh;
sctp_chunkhdr_t _sch, *sch;
u_int32_t offset, count; u_int32_t offset, count;
char map[256 / sizeof (char)] = {0}; char map[256 / sizeof (char)] = {0};
DEBUGP(__FUNCTION__); DEBUGP(__FUNCTION__);
DEBUGP("\n"); DEBUGP("\n");
if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &sctph, sizeof(sctph)) != 0) sh = skb_header_pointer(skb, iph->ihl * 4, sizeof(_sctph), &_sctph);
if (sh == NULL)
return 0; return 0;
if (do_basic_checks(conntrack, skb, map) != 0) if (do_basic_checks(conntrack, skb, map) != 0)
...@@ -443,10 +449,10 @@ static int sctp_new(struct ip_conntrack *conntrack, ...@@ -443,10 +449,10 @@ static int sctp_new(struct ip_conntrack *conntrack,
} }
newconntrack = SCTP_CONNTRACK_MAX; newconntrack = SCTP_CONNTRACK_MAX;
for_each_sctp_chunk (skb, sch, offset, count) { for_each_sctp_chunk (skb, sch, _sch, offset, count) {
/* Don't need lock here: this conntrack not in circulation yet */ /* Don't need lock here: this conntrack not in circulation yet */
newconntrack = new_state (IP_CT_DIR_ORIGINAL, newconntrack = new_state (IP_CT_DIR_ORIGINAL,
SCTP_CONNTRACK_NONE, sch.type); SCTP_CONNTRACK_NONE, sch->type);
/* Invalid: delete conntrack */ /* Invalid: delete conntrack */
if (newconntrack == SCTP_CONNTRACK_MAX) { if (newconntrack == SCTP_CONNTRACK_MAX) {
...@@ -455,20 +461,20 @@ static int sctp_new(struct ip_conntrack *conntrack, ...@@ -455,20 +461,20 @@ static int sctp_new(struct ip_conntrack *conntrack,
} }
/* Copy the vtag into the state info */ /* Copy the vtag into the state info */
if (sch.type == SCTP_CID_INIT) { if (sch->type == SCTP_CID_INIT) {
if (sctph.vtag == 0) { if (sh->vtag == 0) {
sctp_inithdr_t inithdr; sctp_inithdr_t _inithdr, *ih;
if (skb_copy_bits(skb, offset + sizeof (sctp_chunkhdr_t), ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
&inithdr, sizeof(inithdr)) != 0) { sizeof(_inithdr), &_inithdr);
return 0; if (ih == NULL)
} return 0;
DEBUGP("Setting vtag %x for new conn\n", DEBUGP("Setting vtag %x for new conn\n",
inithdr.init_tag); ih->init_tag);
conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =
inithdr.init_tag; ih->init_tag;
} else { } else {
/* Sec 8.5.1 (A) */ /* Sec 8.5.1 (A) */
return 0; return 0;
...@@ -478,8 +484,8 @@ static int sctp_new(struct ip_conntrack *conntrack, ...@@ -478,8 +484,8 @@ static int sctp_new(struct ip_conntrack *conntrack,
shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */ shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
else { else {
DEBUGP("Setting vtag %x for new conn OOTB\n", DEBUGP("Setting vtag %x for new conn OOTB\n",
sctph.vtag); sh->vtag);
conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sctph.vtag; conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
} }
conntrack->proto.sctp.state = newconntrack; conntrack->proto.sctp.state = newconntrack;
......
...@@ -91,10 +91,11 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, ...@@ -91,10 +91,11 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
{ {
struct iphdr *iph = skb->nh.iph; struct iphdr *iph = skb->nh.iph;
unsigned int udplen = skb->len - iph->ihl * 4; unsigned int udplen = skb->len - iph->ihl * 4;
struct udphdr hdr; struct udphdr _hdr, *hdr;
/* Header is too small? */ /* Header is too small? */
if (skb_copy_bits(skb, iph->ihl*4, &hdr, sizeof(hdr)) != 0) { hdr = skb_header_pointer(skb, iph->ihl*4, sizeof(_hdr), &_hdr);
if (hdr == NULL) {
if (LOG_INVALID(IPPROTO_UDP)) if (LOG_INVALID(IPPROTO_UDP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL, nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_udp: short packet "); "ip_ct_udp: short packet ");
...@@ -102,7 +103,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, ...@@ -102,7 +103,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
} }
/* Truncated/malformed packets */ /* Truncated/malformed packets */
if (ntohs(hdr.len) > udplen || ntohs(hdr.len) < sizeof(hdr)) { if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) {
if (LOG_INVALID(IPPROTO_UDP)) if (LOG_INVALID(IPPROTO_UDP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL, nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_udp: truncated/malformed packet "); "ip_ct_udp: truncated/malformed packet ");
...@@ -110,7 +111,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, ...@@ -110,7 +111,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
} }
/* Packet with no checksum */ /* Packet with no checksum */
if (!hdr.check) if (!hdr->check)
return NF_ACCEPT; return NF_ACCEPT;
/* Checksum invalid? Ignore. /* Checksum invalid? Ignore.
......
...@@ -871,7 +871,6 @@ EXPORT_SYMBOL(ip_conntrack_protocol_unregister); ...@@ -871,7 +871,6 @@ EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
EXPORT_SYMBOL(invert_tuplepr); EXPORT_SYMBOL(invert_tuplepr);
EXPORT_SYMBOL(ip_conntrack_alter_reply); EXPORT_SYMBOL(ip_conntrack_alter_reply);
EXPORT_SYMBOL(ip_conntrack_destroyed); EXPORT_SYMBOL(ip_conntrack_destroyed);
EXPORT_SYMBOL(ip_conntrack_get);
EXPORT_SYMBOL(need_ip_conntrack); EXPORT_SYMBOL(need_ip_conntrack);
EXPORT_SYMBOL(ip_conntrack_helper_register); EXPORT_SYMBOL(ip_conntrack_helper_register);
EXPORT_SYMBOL(ip_conntrack_helper_unregister); EXPORT_SYMBOL(ip_conntrack_helper_unregister);
......
...@@ -107,6 +107,7 @@ static struct ipt_match helper_match = { ...@@ -107,6 +107,7 @@ static struct ipt_match helper_match = {
static int __init init(void) static int __init init(void)
{ {
need_ip_conntrack();
return ipt_register_match(&helper_match); return ipt_register_match(&helper_match);
} }
......
...@@ -42,7 +42,7 @@ match_packet(const struct sk_buff *skb, ...@@ -42,7 +42,7 @@ match_packet(const struct sk_buff *skb,
{ {
int offset; int offset;
u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
sctp_chunkhdr_t sch; sctp_chunkhdr_t _sch, *sch;
#ifdef DEBUG_SCTP #ifdef DEBUG_SCTP
int i = 0; int i = 0;
...@@ -54,38 +54,39 @@ match_packet(const struct sk_buff *skb, ...@@ -54,38 +54,39 @@ match_packet(const struct sk_buff *skb,
offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t); offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t);
do { do {
if (skb_copy_bits(skb, offset, &sch, sizeof(sch)) < 0) { sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch);
if (sch == NULL) {
duprintf("Dropping invalid SCTP packet.\n"); duprintf("Dropping invalid SCTP packet.\n");
*hotdrop = 1; *hotdrop = 1;
return 0; return 0;
} }
duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n", duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
++i, offset, sch.type, htons(sch.length), sch.flags); ++i, offset, sch->type, htons(sch->length), sch->flags);
offset += (htons(sch.length) + 3) & ~3; offset += (htons(sch->length) + 3) & ~3;
duprintf("skb->len: %d\toffset: %d\n", skb->len, offset); duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch.type)) { if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch->type)) {
switch (chunk_match_type) { switch (chunk_match_type) {
case SCTP_CHUNK_MATCH_ANY: case SCTP_CHUNK_MATCH_ANY:
if (match_flags(flag_info, flag_count, if (match_flags(flag_info, flag_count,
sch.type, sch.flags)) { sch->type, sch->flags)) {
return 1; return 1;
} }
break; break;
case SCTP_CHUNK_MATCH_ALL: case SCTP_CHUNK_MATCH_ALL:
if (match_flags(flag_info, flag_count, if (match_flags(flag_info, flag_count,
sch.type, sch.flags)) { sch->type, sch->flags)) {
SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch.type); SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch->type);
} }
break; break;
case SCTP_CHUNK_MATCH_ONLY: case SCTP_CHUNK_MATCH_ONLY:
if (!match_flags(flag_info, flag_count, if (!match_flags(flag_info, flag_count,
sch.type, sch.flags)) { sch->type, sch->flags)) {
return 0; return 0;
} }
break; break;
...@@ -120,7 +121,7 @@ match(const struct sk_buff *skb, ...@@ -120,7 +121,7 @@ match(const struct sk_buff *skb,
int *hotdrop) int *hotdrop)
{ {
const struct ipt_sctp_info *info; const struct ipt_sctp_info *info;
sctp_sctphdr_t sh; sctp_sctphdr_t _sh, *sh;
info = (const struct ipt_sctp_info *)matchinfo; info = (const struct ipt_sctp_info *)matchinfo;
...@@ -129,18 +130,19 @@ match(const struct sk_buff *skb, ...@@ -129,18 +130,19 @@ match(const struct sk_buff *skb,
return 0; return 0;
} }
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &sh, sizeof(sh)) < 0) { sh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_sh), &_sh);
if (sh == NULL) {
duprintf("Dropping evil TCP offset=0 tinygram.\n"); duprintf("Dropping evil TCP offset=0 tinygram.\n");
*hotdrop = 1; *hotdrop = 1;
return 0; return 0;
} }
duprintf("spt: %d\tdpt: %d\n", ntohs(sh.source), ntohs(sh.dest)); duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest));
return SCCHECK(((ntohs(sh.source) >= info->spts[0]) return SCCHECK(((ntohs(sh->source) >= info->spts[0])
&& (ntohs(sh.source) <= info->spts[1])), && (ntohs(sh->source) <= info->spts[1])),
IPT_SCTP_SRC_PORTS, info->flags, info->invflags) IPT_SCTP_SRC_PORTS, info->flags, info->invflags)
&& SCCHECK(((ntohs(sh.dest) >= info->dpts[0]) && SCCHECK(((ntohs(sh->dest) >= info->dpts[0])
&& (ntohs(sh.dest) <= info->dpts[1])), && (ntohs(sh->dest) <= info->dpts[1])),
IPT_SCTP_DEST_PORTS, info->flags, info->invflags) IPT_SCTP_DEST_PORTS, info->flags, info->invflags)
&& SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type, && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type,
info->flag_info, info->flag_count, info->flag_info, info->flag_count,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment