1

I am trying to use Libnet11 function:

int libnet_write_raw_ipv6 (libnet_t *l, u_int8_t *packet, u_int32_t size)

to inject IPv6 packet on network layer. I had created IPv6 packet and captured it with Wireshark. Wireshark reported: malformed packet(wireshark says that next header value in IPv6 is wrong and payload size is too big in my opinion)

I hope, someone could help me with minimal code example, showing how to manually build IPv6 packet (with ICMPv6 extension header) with libnet11 (libnet_write_raw_ipv6()).

I assume that the minimal code might look like this:

packet_len = 40 + 16; // 40B ~ IPv6 packet, 16B ~ ICMPv6 header
u_char *buf = NULL;

struct ip6_hdr *ip6 = NULL;
struct icmp6_hdr *icmp6 = NULL;

l = libnet_init();
if ( (buf = malloc(packet_len)) == NULL ) {
    // error
}

// create IPv6 header
ip6 = (struct ip6_hdr *) buf;
ip6->ip6_flow   = 0;
ip6->ip6_vfc    = 6 << 4;
ip6->ip6_plen   = 16;              // ICMPv6 packet size
ip6->ip6_nxt    = IPPROTO_ICMPV6;  // 0x3a
ip6->ip6_hlim   = 64;
memcpy(&(ip6->ip6_src), &src_addr, sizeof(struct in6_addr));
memcpy(&(ip6->ip6_dst), &dst_addr, sizeof(struct in6_addr));

// create ICMPv6 header
icmp6 = (struct icmp6_hdr *) (buf + 40); // 40B ~ IPv6 packet size
icmp6->icmp6_type = ICMP6_ECHO_REQUEST;
icmp6->icmp6_code = 0;
icmp6->icmp6_cksum= 0;
icmp6->icmp6_data32[0] = 0;

libnet_do_checksum(l, (u_int8_t *)buf, IPPROTO_ICMPV6, packet_len);

written = libnet_write_raw_ipv6(l, buf, packet_len);
if ( written != packet_len )
    perror("Failed to send packet");

libnet_destroy(l);
free(buf);

I tried to find code examples but with no success. Thank you in advance.

Martin

  • What does wireshark show for the next header? You might need to call htnos() to flip the byte order if it's coming up as 0x3A00 instead of 0x003A. – PherricOxide Nov 14 '12 at 19:59
  • The payload length in your ip header needs to be converted to big-endian order. That's why you are getting a 'payload size too big' warning. – Lucas Aschenbach Jul 03 '22 at 16:36

2 Answers2

0

If you're using C++, then I'd recommend you libtins, a packet crafting a sniffing library. This short snippet does exactly what you want:

#include <tins/tins.h>

using namespace Tins;

void test(const IPv6Address &dst, const IPv6Address &src) {
    PacketSender sender;
    IPv6 ipv6 = IPv6(dst, src) / ICMPv6();
    ipv6.hop_limit(64);
    sender.send(ipv6);
}

int main() {
    // now use it
    test("f0ef:1234::1", "f000::1");
}
mfontanini
  • 21,410
  • 4
  • 65
  • 73
0

You can create it with raw sockets though. I also had to do something similar but couldn't find anything as a reference.

To do it with raw sockets, this link gives you a nice explanation

Akshay
  • 329
  • 1
  • 7
  • 19