Saturday, January 2, 2016

Crafting your first IPv6 ICMPv6 Echo Request packet, with a taste of scapy

This post is a quick attempt to show how you can use scapy to craft an IPv6 packet.

To verify that this works we will first configure a host running Windows 10 to use a site local address "fec0::4/64" and our Linux host to use site local "fec0::2/64"

The image below shows our Windows 10 site local configuration

Image below shows our Linux host IPv6 site local configuration
Now that we have our two hosts configured let's go ahead and craft our packet to test connectivity.

Moving along!!

Let's craft our own ICMPv6 echo request, so that we can received an echo reply packet from our target.

Let's first build our IPv6 layer. However, before we move ahead, let's see what fields we have available to us for the IPv6 header in scapy.

Now that we know our fields, let's build our IPv6 header out by specifying our source of "fec0::02", our destination "fec0::04" and a "nh" or next header field of "58" which represents ICMPv6.

With our built out IPv6 header, let's now build our ICMPv6 echo request.

Let's first look at the fields which scapy provides for us to use to create our own ICMPv6 echo request.

Now that we know what we need to use, let's fill out our fields.

Now that we have filled our fields out, let's send our packet along its merry way. Wireshark will be running simultaneously on the target.

Above we see we sent one packet. Let's see if our target accepted and sent a reply.

Awesome! It looks like we've successfully crafted and sent an ICMPv6 echo request packet along its merry way. We also see that the host at "fec0::4" replied to our request with a reply.

See this post if you would like to craft an IPv6 TCP packet and this post if you would like to craft an IPv6 UDP packet.


  1. I am generating an ICMPv6 packet (actually 4 of them) using
    ans, unans = . srloop(IPv6(dst="fdda:cfd2:28e3:4328:216:25ff:FFFF:FFFE")/ ICMPv6EchoRequest(), count=4, inter=4, timeout=5)
    and then I measure the length of ans. This works for IPv4, if ans is length 0, then I have 100% failure. However, this does not work for ICMPv6 because ans is full of packet that contain... something... that has ICMPv6DestUnreach in it. I use Unfortunately, this output goes to stdout, whereas I want to look at it using a program.
    Do you have a suggestion? Thank you.

    1. Jeff,
      You may have to try using the python subprocess module to redirect that output from stdout to stdin.

  2. Nik, the reason why I am going this route is precisely because I didn't want to use subprocess. The code that I am replacing forks a call to the ping command.

    1. Hmmmm, do you wish to send me a sample code to my gmail? Maybe I can help. No promises though as I'm quite busy over the next few weeks.