How to use DPDK to implement ICMP Spoofing

When I was studying RYU controller, I created an article about how to implement ICMP Spoofing with RYU controller code. RYU controller could handle ICMP Echo Request and send the Echo Reply to the client. This is implemented by OpenFlow PacketIn and PacketOut. Now we are using DPDK to handle packets, you can add handling function to your code so that DPDK can do such thing.
In this article, I will provide an example for this scenario.

There are 2 hosts. Host1 has a DPDK network interface which receive ICMP Echo request and send Echo reply. Host2 sends the ICMP Echo request.

The main function of code is building ICMP Echo reply based on the ICMP Echo request and send the reply back to client.

I have uploaded the code to Github.

1.Parse the ICMP Echo request

struct rte_ether_hdr *ethhdr = rte_pktmbuf_mtod(mbufs[i], struct rte_ether_hdr*);
struct rte_ipv4_hdr *iphdr =  rte_pktmbuf_mtod_offset(mbufs[i], struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr));
struct rte_icmp_hdr *icmphdr = (struct rte_icmp_hdr *)(iphdr + 1);

Key fields

  • Total length of the packet
  • Mac address & IP address
  • identification(packet_id)
  • checksum
  • ICMP sequence number

2.Building ICMP Echo reply

  • We build packets in the mbuf. So make sure the mbuf has enough space for the packets. We request mbuf based on the ICMP Echo request length because Echo request and Echo reply have the same length.
struct rte_mbuf *icmpbuf  = rte_pktmbuf_alloc(mbuf_pool);
if (!icmpbuf) {
    rte_exit(EXIT_FAILURE, "rte_pktmbuf_alloc\n");
}
icmpbuf->pkt_len = total_length;
icmpbuf->data_len = total_length;

uint8_t *pkt_data = rte_pktmbuf_mtod(icmpbuf, uint8_t *);
  • Identification and ICMP sequence number in request and reply must be equal.
  • Before calculating the checksum, set the checksum field into 0.
  • Copy ICMP data from request to reply.

Sharing an interesting test:

[ec2-user@ip-172-31-27-54 ~]$ ping 10.0.0.67
PING 10.0.0.67 (10.0.0.67) 56(84) bytes of data.
64 bytes from 10.0.0.67: icmp_seq=1 ttl=63 time=1649306027610 ms
wrong data byte #16 should be 0x10 but was 0x0
#16     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
#48     0 0 0 0 0 0 0 0 
--- 10.0.0.67 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2037ms
rtt min/avg/max/mdev = 1649306027610.870/1649306028628.113/1649306029648.674/2479922.361 ms

The reason is I don't add data to the echo reply.

Now we should be able to ping the DPDK network interface on Host1 from Host2.

[ec2-user@ip-172-31-27-54 ~]$ ping 10.0.0.67
PING 10.0.0.67 (10.0.0.67) 56(84) bytes of data.
64 bytes from 10.0.0.67: icmp_seq=1 ttl=63 time=0.462 ms
64 bytes from 10.0.0.67: icmp_seq=2 ttl=63 time=0.325 ms
64 bytes from 10.0.0.67: icmp_seq=3 ttl=63 time=0.291 ms
64 bytes from 10.0.0.67: icmp_seq=4 ttl=63 time=0.358 ms


发表评论

  • OωO
  • |´・ω・)ノ
  • ヾ(≧∇≦*)ゝ
  • (☆ω☆)
  • (╯‵□′)╯︵┴─┴
  •  ̄﹃ ̄
  • (/ω\)
  • ∠(ᐛ」∠)_
  • (๑•̀ㅁ•́ฅ)
  • →_→
  • ୧(๑•̀⌄•́๑)૭
  • ٩(ˊᗜˋ*)و
  • (ノ°ο°)ノ
  • (´இ皿இ`)
  • ⌇●﹏●⌇
  • (ฅ´ω`ฅ)
  • (╯°A°)╯︵○○○
  • φ( ̄∇ ̄o)
  • (งᵒ̌皿ᵒ̌)ง⁼³₌₃
  • (ó﹏ò。)
  • Σ(っ°Д°;)っ
  • ╮(╯▽╰)╭
  • o(*
  • >﹏<
  • (。•ˇ‸ˇ•。)
  • 泡泡
  • 颜文字

*