示例#1
0
文件: conntrack.c 项目: 18SUN/ovs
static struct nf_conntrack_expect *
ovs_ct_expect_find(struct net *net, const struct nf_conntrack_zone *zone,
		   u16 proto, const struct sk_buff *skb)
{
	struct nf_conntrack_tuple tuple;

	if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, net, &tuple))
		return NULL;
	return __nf_ct_expect_find(net, zone, &tuple);
}
示例#2
0
static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
					       union nf_inet_addr *addr,
					       __be16 port)
{
	struct net *net = nf_ct_net(ct);
	struct nf_conntrack_expect *exp;
	struct nf_conntrack_tuple tuple;

	memset(&tuple.src.u3, 0, sizeof(tuple.src.u3));
	tuple.src.u.tcp.port = 0;
	memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3));
	tuple.dst.u.tcp.port = port;
	tuple.dst.protonum = IPPROTO_TCP;

	exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
	if (exp && exp->master == ct)
		return exp;
	return NULL;
}
示例#3
0
文件: ipt_CONENAT.c 项目: spfy/040005
static unsigned int
conenat_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
       struct net *net;
	struct nf_conn *ct;
       struct nf_conn_nat *nat;
	enum ip_conntrack_info ctinfo;
	struct nf_nat_range newrange;
       const struct nf_nat_multi_range_compat *mr;
	struct rtable *rt;
	__be32 newsrc;

	NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING);

	ct = nf_ct_get(skb, &ctinfo);
	nat = nfct_nat(ct);
   	net = nf_ct_net(ct);

	NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED
			    || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));


    /* Source address is 0.0.0.0 - locally generated packet that is
     * probably not supposed to be masqueraded.
     */
	 if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0)
	        return NF_ACCEPT;

    	mr = par->targinfo;
    	rt = skb->rtable;
    	newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
    	if (!newsrc) {
        	printk("CONENAT: %s ate my IP address\n", par->out->name);
        	return NF_DROP;
    	}

       write_lock_bh(&conenat_lock);
	nat->masq_index = par->out->ifindex;
	write_unlock_bh(&conenat_lock);

	if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum == IPPROTO_UDP)
	{
		unsigned int ret,expectcount = net->ct.expect_count;
		u_int16_t minport, maxport;
		u_int16_t newport, tmpport;
		struct nf_conntrack_expect *exp=NULL;
              struct nf_conntrack_tuple tuple;
              struct nf_conn_help *help = nfct_help(ct);

		/* Choose port */
		spin_lock_bh(&nf_conntrack_lock);

       		#if 0
		exp = LIST_FIND(&nf_conntrack_expect_list,
                exp_src_cmp,
				struct nf_conntrack_expect *,
				&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
        	#endif

		memset(&tuple,0,sizeof(tuple));

		//src
		tuple.src.l3num = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num;
		tuple.src.u3.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip;
		tuple.src.u.udp.port = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.udp.port;

        	//dst
              tuple.dst.u3.ip = newsrc;
		//tuple.dst.u.udp.port = htons(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port);
		newport = htons(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port);
		tuple.dst.protonum = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;

		pr_debug("tupple1 = %pI4:%hu\n", &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip,ntohs(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port));


		if(expectcount > 0){
			for(tmpport=0; (tmpport<=expectcount)&&(newport<=65535); tmpport++,newport++){
				tuple.dst.u.udp.port=newport;
				exp = __nf_ct_expect_find_bysave(net, &tuple, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
				if(exp)
					break;
			}
		}

		if (exp) {
			minport = maxport = exp->tuple.dst.u.udp.port;
			pr_debug("existing mapped port = %hu\n", ntohs(minport));
		} else {


			minport = mr->range[0].min.udp.port == 0 ?
				ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port :
				mr->range[0].min.udp.port;

			maxport = mr->range[0].max.udp.port == 0 ?
				htons(65535) :
				mr->range[0].max.udp.port;

			for (newport = ntohs(minport),tmpport = ntohs(maxport);
			     newport <= tmpport; newport++) {
                #if 0
                exp = LIST_FIND(&ip_conntrack_expect_list,
					       exp_cmp,
					       struct nf_conntrack_expect *,
					       newsrc, htons(newport), ct->tuplehash[IP_CT_DIR_ORIGINAL].
					       tuple.dst.protonum);
                #endif

				//dst
			tuple.dst.u.udp.port = htons(newport);

               	 exp = __nf_ct_expect_find(net, &tuple);
		        if (!exp)
			{
				pr_debug("new mapping: %pI4:%hu -> %pI4:%hu\n",
                    &(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip),
                    ntohs(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.udp.port),
                    &newsrc,  newport);
				minport = maxport = htons(newport);
				break;
			}
			}
		}
		spin_unlock_bh(&nf_conntrack_lock);

		newrange.flags = mr->range[0].flags | IP_NAT_RANGE_MAP_IPS |IP_NAT_RANGE_PROTO_SPECIFIED;
		newrange.min_ip = newrange.max_ip = newsrc;
		newrange.min.udp.port = minport;
		newrange.max.udp.port = maxport;

		/* Set ct helper */
		ret = nf_nat_setup_info(ct, &newrange, IP_NAT_MANIP_SRC);
		if (ret == NF_ACCEPT)
	        {
	            rcu_read_lock();
	            if (help == NULL) {
	                help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
	                if (help == NULL) {
	                    return NF_ACCEPT;
	                }
	            } else {
	                memset(&help->help, 0, sizeof(help->help));
	            }
	            rcu_assign_pointer(help->helper, &nf_conntrack_helper_cone_nat);
	            rcu_read_unlock();

		    pr_debug("helper setup, skb=%p\n", skb);
		}

		return ret;
	}
示例#4
0
文件: ipt_CONENAT.c 项目: spfy/040005
unsigned int rtl_find_appropriate_newrange(struct nf_conn *ct, __be32 newsrc, const struct nf_nat_multi_range_compat *mr)
{
	struct net *net;
	unsigned int ret,expectcount = net->ct.expect_count;
	u_int16_t minport, maxport;
	u_int16_t newport, tmpport;
	struct nf_conntrack_expect *exp=NULL;
	struct nf_conntrack_tuple tuple;
	struct nf_nat_range newrange;
	struct nf_conn_help *help = nfct_help(ct);

	net = nf_ct_net(ct);
	expectcount = net->ct.expect_count;
	/* Choose port */
	spin_lock_bh(&nf_conntrack_lock);

	#if 0
	exp = LIST_FIND(&nf_conntrack_expect_list,
			exp_src_cmp,
			struct nf_conntrack_expect *,
			&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
	#endif

	memset(&tuple,0,sizeof(tuple));

	//src
	tuple.src.l3num = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num;
	tuple.src.u3.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip;
	tuple.src.u.udp.port = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.udp.port;

	//dst
	tuple.dst.u3.ip = newsrc;
	//tuple.dst.u.udp.port = htons(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port);
	newport = htons(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port);
	tuple.dst.protonum = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;

	pr_debug("tupple1 = %pI4:%hu\n", &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip,ntohs(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port));

	if(expectcount > 0){
		for(tmpport=0; (tmpport<=expectcount)&&(newport<=65535); tmpport++,newport++){
			tuple.dst.u.udp.port=newport;
			exp = __nf_ct_expect_find_bysave(net, &tuple, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
			if(exp)
				break;
		}
	}

	if (exp) {
		minport = maxport = exp->tuple.dst.u.udp.port;
		pr_debug("existing mapped port = %hu\n", ntohs(minport));
	} else {


		minport = mr->range[0].min.udp.port == 0 ?
			ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port :
			mr->range[0].min.udp.port;

		maxport = mr->range[0].max.udp.port == 0 ?
			htons(65535) :
			mr->range[0].max.udp.port;

		for (newport = ntohs(minport),tmpport = ntohs(maxport);
			 newport <= tmpport; newport++) {
        #if 0
			exp = LIST_FIND(&ip_conntrack_expect_list,
					   exp_cmp,
					   struct nf_conntrack_expect *,
					   newsrc, htons(newport), ct->tuplehash[IP_CT_DIR_ORIGINAL].
					   tuple.dst.protonum);
        #endif

			//dst
		tuple.dst.u.udp.port = htons(newport);

			 exp = __nf_ct_expect_find(net, &tuple);
			if (!exp)
			{
				pr_debug("new mapping: %pI4:%hu -> %pI4:%hu\n",
					&(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip),
					ntohs(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.udp.port),
					&newsrc,  newport);
				minport = maxport = htons(newport);
				break;
			}
		}
	}
	spin_unlock_bh(&nf_conntrack_lock);

	newrange.flags = mr->range[0].flags | IP_NAT_RANGE_MAP_IPS |IP_NAT_RANGE_PROTO_SPECIFIED;
	newrange.min_ip = newrange.max_ip = newsrc;
	newrange.min.udp.port = minport;
	newrange.max.udp.port = maxport;

	/* Set ct helper */
	ret = nf_nat_setup_info(ct, &newrange, IP_NAT_MANIP_SRC);
	if (ret == NF_ACCEPT)
        {
            rcu_read_lock();
            if (help == NULL) {
                help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
                if (help == NULL) {
                    return NF_ACCEPT;
                }
            } else {
                memset(&help->help, 0, sizeof(help->help));
            }
            rcu_assign_pointer(help->helper, &nf_conntrack_helper_cone_nat);
            rcu_read_unlock();
	}

	return ret;
}