update_nl_seq(seq, ct_ftp_info,dir); 
update_nl_seq(seq, ct_ftp_info,dir, *pskb); 
static int help(struct sk_buff **pskb,		struct ip_conntrack *ct,		enum ip_conntrack_info ctinfo){	unsigned int dataoff, datalen;	struct tcphdr _tcph, *th;	char *fb_ptr;	int ret;	u32 seq, array[6] = { 0 };	int dir = CTINFO2DIR(ctinfo);	unsigned int matchlen, matchoff;	struct ip_ct_ftp_master *ct_ftp_info = &ct->help.ct_ftp_info;	struct ip_conntrack_expect *exp;	unsigned int i;	int found = 0, ends_in_nl;	/* Until there's been traffic both ways, don't look in packets. */	if (ctinfo != IP_CT_ESTABLISHED	    && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {		DEBUGP("ftp: Conntrackinfo = %u\n", ctinfo);		return NF_ACCEPT;	}	th = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,				sizeof(_tcph), &_tcph);	if (th == NULL)		return NF_ACCEPT;	dataoff = (*pskb)->nh.iph->ihl*4 + th->doff*4;	/* No data? */	if (dataoff >= (*pskb)->len) {		DEBUGP("ftp: pskblen = %u\n", (*pskb)->len);		return NF_ACCEPT;	}	datalen = (*pskb)->len - dataoff;	spin_lock_bh(&ip_ftp_lock);	fb_ptr = skb_header_pointer(*pskb, dataoff,				    (*pskb)->len - dataoff, ftp_buffer);	BUG_ON(fb_ptr == NULL);	ends_in_nl = (fb_ptr[datalen - 1] == '\n');	seq = ntohl(th->seq) + datalen;	/* Look up to see if we're just after a \n. */	if (!find_nl_seq(ntohl(th->seq), ct_ftp_info, dir)) {		/* Now if this ends in \n, update ftp info. */		DEBUGP("ip_conntrack_ftp_help: wrong seq pos %s(%u) or %s(%u)\n",		       ct_ftp_info->seq_aft_nl[0][dir] 		       old_seq_aft_nl_set ? "":"(UNSET) ", old_seq_aft_nl);		ret = NF_ACCEPT;		goto out_update_nl;	}	/* Initialize IP array to expected address (it's not mentioned           in EPSV responses) */	array[0] = (ntohl(ct->tuplehash[dir].tuple.src.ip) >> 24) & 0xFF;	array[1] = (ntohl(ct->tuplehash[dir].tuple.src.ip) >> 16) & 0xFF;	array[2] = (ntohl(ct->tuplehash[dir].tuple.src.ip) >> 8) & 0xFF;	array[3] = ntohl(ct->tuplehash[dir].tuple.src.ip) & 0xFF;	for (i = 0; i < ARRAY_SIZE(search); i++) {		if (search[i].dir != dir) continue;		found = find_pattern(fb_ptr, (*pskb)->len - dataoff,				     search[i].pattern,				     search[i].plen,				     search[i].skip,				     search[i].term,				     &matchoff, &matchlen,				     array,				     search[i].getnum);		if (found) break;	}	if (found == -1) {		/* We don't usually drop packets.  After all, this is		   connection tracking, not packet filtering.		   However, it is necessary for accurate tracking in		   this case. */		if (net_ratelimit())			printk("conntrack_ftp: partial %s %u+%u\n",			       search[i].pattern,			       ntohl(th->seq), datalen);		ret = NF_DROP;		goto out;	} else if (found == 0) { /* No match */		ret = NF_ACCEPT;		goto out_update_nl;	}	DEBUGP("conntrack_ftp: match `%s' (%u bytes at %u)\n",	       fb_ptr + matchoff, matchlen, ntohl(th->seq) + matchoff);			 	/* Allocate expectation which will be inserted */	exp = ip_conntrack_expect_alloc(ct);	if (exp == NULL) {		ret = NF_DROP;		goto out;	}	/* We refer to the reverse direction ("!dir") tuples here,	 * because we're expecting something in the other direction.	 * Doesn't matter unless NAT is happening.  */	exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;	if (htonl((array[0] << 24) | (array[1] << 16) | (array[2] << 8) | array[3])	    != ct->tuplehash[dir].tuple.src.ip) {		/* Enrico Scholz's passive FTP to partially RNAT'd ftp		   server: it really wants us to connect to a		   different IP address.  Simply don't record it for		   NAT. */		DEBUGP("conntrack_ftp: NOT RECORDING: %u,%u,%u,%u != %u.%u.%u.%u\n",		       array[0], array[1], array[2], array[3],		       NIPQUAD(ct->tuplehash[dir].tuple.src.ip));		/* Thanks to Cristiano Lincoln Mattos		   <lincoln@cesar.org.br> for reporting this potential		   problem (DMZ machines opening holes to internal		   networks, or the packet filter itself). */		if (!loose) {			ret = NF_ACCEPT;			goto out_put_expect;		}		exp->tuple.dst.ip = htonl((array[0] << 24) | (array[1] << 16)					 | (array[2] << 8) | array[3]);	}	exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;	exp->tuple.dst.u.tcp.port = htons(array[4] << 8 | array[5]);	exp->tuple.src.u.tcp.port = 0; /* Don't care. */	exp->tuple.dst.protonum = IPPROTO_TCP;	exp->mask = ((struct ip_conntrack_tuple)		{ { 0xFFFFFFFF, { 0 } },		  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});	exp->expectfn = NULL;	/* Now, NAT might want to mangle the packet, and register the	 * (possibly changed) expectation itself. */	if (ip_nat_ftp_hook)		ret = ip_nat_ftp_hook(pskb, ctinfo, search[i].ftptype,				      matchoff, matchlen, exp, &seq);	else {		/* Can't expect this?  Best to drop packet now. */		if (ip_conntrack_expect_related(exp) != 0)			ret = NF_DROP;		else			ret = NF_ACCEPT;	}out_put_expect:	ip_conntrack_expect_put(exp);out_update_nl:	/* Now if this ends in \n, update ftp info.  Seq may have been	 * adjusted by NAT code. */	if (ends_in_nl)		update_nl_seq(seq, ct_ftp_info,dir); out:	spin_unlock_bh(&ip_ftp_lock);	return ret;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/ac3247baf8ecadf168642e3898b0212c29c79715/ip_conntrack_ftp.c/buggy/net/ipv4/netfilter/ip_conntrack_ftp.c