Esempio n. 1
0
File: ip.c Progetto: lehoon/bvrouter
static int icmp_dispatch(struct sk_buff *skb, const struct pal_dip *dip)
{
	struct ip_hdr *iph = (struct ip_hdr *)skb_ip_header(skb);
	struct icmp_hdr *icmph = skb_icmp_header(skb);
	unsigned icmp_len = pal_ntohs(iph->tot_len) - (iph->ihl * 4);

	pal_cur_thread_conf()->stats.ip.icmp.rx_pkts++;
	pal_cur_thread_conf()->stats.ip.icmp.rx_bytes += skb_l2_len(skb);

	/* icmp content must be more then 8 bytes */
	if (icmp_len >= 8 && icmp_len <= skb_len(skb)) {
		if (icmp_check_sum_correct((uint16_t *)icmph, icmp_len)) {
			return dispatch_pkt(skb, dip);
		} else {
			pal_cur_thread_conf()->stats.ip.icmp.csum_err++;
			PAL_DEBUG("Bad icmp checksum\n");
		}
	} else {
		pal_cur_thread_conf()->stats.ip.icmp.trunc_pkts++;
		PAL_DEBUG("icmp len < 8, invalid\n");
	}

	return -1;
}
Esempio n. 2
0
File: ip.c Progetto: lehoon/bvrouter
static int icmp_handler(struct sk_buff *skb)
{
	struct ip_hdr *iph = (struct ip_hdr *)skb_ip_header(skb);
	struct icmp_hdr *icmph = skb_icmp_header(skb);
	unsigned icmp_len = pal_htons(iph->tot_len) - (iph->ihl * 4);
	uint8_t *l2_dest_mac_p = skb_eth_header(skb)->dst;
	uint32_t tmp_addr;

	pal_cur_thread_conf()->stats.ip.icmp.rx_pkts++;
	pal_cur_thread_conf()->stats.ip.icmp.rx_bytes += skb_l2_len(skb);

	PAL_DEBUG("in icmp handler\n");
	/* icmp content must be more then 8 bytes */
	if (icmp_len >= 8 && icmp_len <= skb_len(skb)) {
		/* we only handle icmp echo request */
		if (icmph->type == ICMP_ECHO) {
			if (icmp_check_sum_correct((uint16_t *)icmph, icmp_len)) {
				icmph->type = ICMP_ECHOREPLY;

				/* update icmp check sum*/
				icmph->checksum = icmph->checksum + pal_htons_constant(0x0800);

				/* Exchange ip addresses */
				tmp_addr = iph->saddr;
				iph->saddr = iph->daddr;
				iph->daddr = tmp_addr;

				/**update ip ttl*/
				iph->ttl = 64;

				skb_ip_csum_offload(skb, iph->ihl * 4);

				swap_mac(l2_dest_mac_p);

				skb_push(skb, (unsigned long)skb_l4_header(skb) -
				              (unsigned long)skb_l2_header(skb));
				pal_cur_thread_conf()->stats.ip.icmp.reply_pkts++;
				if (pal_send_raw_pkt(skb, skb->recv_if) == 0) {
					PAL_DEBUG("sent icmp reply\n");
					return 0;
				}

				pal_cur_thread_conf()->stats.ip.icmp.reply_failure++;
				PAL_DEBUG("send icmp reply failed\n");

			} else {
				pal_cur_thread_conf()->stats.ip.icmp.csum_err++;
				PAL_DEBUG("Bad icmp checksum\n");
			}
		} else {
			pal_cur_thread_conf()->stats.ip.icmp.not_echo_pkts++;
			pal_cur_thread_conf()->stats.ip.icmp.not_echo_bytes += skb_l2_len(skb);
			PAL_DEBUG("icmp not echo request!\n");
		}
	} else {
		pal_cur_thread_conf()->stats.ip.icmp.trunc_pkts++;
		PAL_DEBUG("icmp len < 8, invalid\n");
	}

	return -1;
}
Esempio n. 3
0
int icmp_v4_proxy(struct rte_mbuf *mbuf,struct iphdr *iph)
{
    u32 lcore;
    s32 icmp_len;
    s32 ret ;
    u16 tot_len ;

    struct ether_hdr	*ethdr	= rte_pktmbuf_mtod(mbuf,struct ether_hdr *);
    struct icmphdr		*icmph =(struct icmphdr*)((u8*)iph) + ((iph->ihl)<<2);
    tot_len 			= iph->tot_len;
    icmp_len			= (s32)(ntohs(tot_len) - (iph->ihl*4));

    mbuf->pkt.vlan_macip.f.l2_len = sizeof(*ethdr);
    mbuf->pkt.vlan_macip.f.l3_len = iph->ihl << 2;

    if( (icmp_len >= 8) && icmp_check_sum_correct((u16*)icmph, icmp_len) ) {
        if(icmph->type == ICMP_ECHO) {
            //US_DEBUG_LINE();
            lcore = US_GET_LCORE();
            iph->daddr = glb_dest_ip;
            iph->saddr = us_nic_ports[0].if_ipv4_bip[lcore];
            iph->check = 0;
            iph->ttl--;
            swap_mac(ethdr);

            icmph->checksum = 0;
            icmph->checksum = icmp_check_sum((u8*)icmph,icmp_len);
            set_ipv4_csum_offload(mbuf);
            //recv_pkt_dump(&mbuf, 1);

            goto send_out;
        } else if(icmph->type == ICMP_ECHOREPLY) {
            //US_DEBUG_LINE();
            iph->daddr = glb_client_ip;
            iph->saddr = us_nic_ports[0].if_ipv4_vip[0];
            iph->check = 0;
            iph->ttl--;
            swap_mac(ethdr);

            icmph->checksum = 0;
            icmph->checksum = icmp_check_sum((u8*)icmph,icmp_len);
            set_ipv4_csum_offload(mbuf);
            //recv_pkt_dump(&mbuf, 1);

        } else {
            goto failed_out;
        }
    } else {
        goto failed_out;
    }
send_out:

    ret = rte_eth_tx_burst(us_nic_ports[0].port_id, 0,&mbuf, 1);
    if (ret < 1) {
        goto failed_out;
    }

    return US_RET_OK;
failed_out:
    rte_pktmbuf_free(mbuf);
    return US_EINVAL;

}