ICS 451 Assignment 9:
IPv6 Packet Generation and Routing Table Lookup

Assigned March 17th, to be completed by March 31st.

Turn in this assignment by e-mailing to jmoroney@hawaii.edu your code specified below.

You may do this assignment in groups of up to two, as long as your partner did not work with you on assignment 8.

This assignment asks you to implement two programs. The second program is similar to assignment 8, but for IPv6 instead of IPv4 (you may re-use and adapt any code either of you created for assignment 8).

The first program creates an IPv6 packet and sends it to your second program. As in assignment 8, the forwarding function of your second program is limited to printing the next hop and interface to which the packet would be forwarded in a router or host (as well as printing the source and destination address of the packet).

Also as in assignment 8, the routing tables for this assignment are static and specified in the command-line arguments, so you do not need to implement any routing protocol, or indeed, even a routing table.

Creating an IPv6 packet

Write a C program, ipgen, to create a valid IPv6 packet as described in RFC 2460. In particular, your packet must have:

ipgen6 takes three command-line arguments: a port number and two IPv6 addresses. It then creates a packet as described above, and sends it to ::1 (localhost) at the UDP port number given on the command line. That is, you are sending the IPv6 packet (consisting only of an IPv6 header) over IPv6 and UDP to your rlookup6 program described below.

For example,

   $ ./ipgen6  12345  1:2:3::4  5:6:7:8:9:a:b:c

creates an IPv6 (header-only) packet with source address 1:2:3::4 (the same as 1:2:3:0:0:0:0:4) and destination address 5:6:7:8:9:a:b:c. It sends this packet to the IPv6 localhost address (::1) on UDP port 12345.

I suggest using inet_pton to convert strings to IP addresses. For example,

  char src [16];
  if (inet_pton (AF_INET6, argv [2], src) != 1) {
    printf ("usage: %s udp-port ipv6-source ipv6-dest\n", argv [0]);
    printf ("       source address %s is not a valid IPv6 address", argv [2]);
    return 1;

Instructor's ipgen6

The instructor has created Linux binaries for ipgen6 (for 32-bit or 64-bit architectures) which you are welcome to use to test your code.

Your own code should generate the same bytes as the instructor's when you run wireshark on the loopback interface (after downloading the binary, you probably have to make it executable with chmod +x instructor-ipgen6).

Routing Table Lookup

Each address in IPv6 is 128 bits long (16 bytes).

Each routing table entry stores:

  1. a Destination, which is an IP address.
  2. a Gateway or Next Hop, which is also an IP address.
  3. a mask, which is a 128-bit string, but not an IP address.
  4. various flags, which for this assignment may be ignored
  5. a metric, which for this assignment may be ignored
  6. an interface, which is an arbitrary string

Most routers use automated methods such as routing protocols or DHCP to build their routing table. For this assignment, the routing table will be specified as a series of command-line arguments, each of the form:


Each destination and gateway are given in the colon-separated-hex notation supported by inet_pton. The mask is a number between 0 and 128 inclusive (note, this is different from assignment 8). The interface is an arbitrary string (not longer than 100 characters).

Each such argument is used to build a routing table entry, in the order given on the command line.

To search the routing table, IP uses an algorithm called longest match. Of all the matching routing table entries, the one with the longest mask is used. If there are multiple matching entries with masks of the same length, the first one is used.

A route matches an IP address when its destination ANDed with the mask is the same as the IP address ANDed with the mask, or

   (route[i].dest & route[i].mask) == (ip->dest & route[i].mask)

Both the all-zeros mask and the all-ones mask are legal. The first is a default route, used if no other route matches. The second is a host route, used only if the destination of the packet is the same as the destination in the routing table.

The very first parameter is a UDP port number to listen on for incoming packets (again, this is different from assignment 8).

I suggest using inet_ntop to convert IP addresses to strings. For example,

  char prtsrc [INET6_ADDRSTRLEN];
  inet_ntop (AF_INET6, src, prtsrc, sizeof (prtsrc));
  printf ("source address is %s\n", prtsrc);


All these examples assume your program is called as follows:

   $ ./rlookup6  12345  ::/1:2:3::99/0/eth1  1::/1:2:3::abcd/16/eth1  1::/2:4:6::8/16/eth0  1:2::/2:4:6::9/32/eth0  1:2:3::0/1:2:3::1/48/eth1  1:2:3::4/1:2:3::4/128/eth1

The port number in all the examples below is 12345. The source address is ignored in forwarding, but must still be set correctly in your ipgen6 and printed by rlookup6.

  1.    $ ./ipgen6  12345  1::2  1:2:3::4

    This matches all the routes. The longest is the last route, which is a host route, so rlookup6 should print:

       packet from 1::2 to 1:2:3::4, forwarding to 1:2:3::4 over eth1
  2.    $ ./ipgen6  12345  2::3  1:2:3::99

    The first 48 bits of 1:2:3::99 match the first 48 bits of the fifth route (as well as earlier routes), so rlookup6 should print:

       packet from 2::3 to 1:2:3::99, forwarding to 1:2:3::1 over eth1
  3.    $ ./ipgen6  12345  3::4  1:3:5:7:9:b:d:f

    1:3:5:7:9:b:d:f matches the second and third routes, so rlookup6 should use the second route and print:

       packet from 3::4 to 1:3:5:7:9:b:d:f, forwarding to 1:2:3::abcd over eth1
  4.    $ ./ipgen6  12345  4::5  8:7:6:5:4:3:2:1

    8:7:6:5:4:3:2:1 only matches the first (default) route, so rlookup6 should print:

       packet from 4::5 to 8:7:6:5:4:3:2:1, forwarding to 1:2:3::99 over eth1
  5.    $ ./ipgen6  12345  1::2  1:2:3::4

    rlookup6 should print:

       packet from 1::2 to 1:2:3::4, forwarding to 1:2:3::4 over eth1
  6. If there is no match (only possible if there is no default route), rlookup6 should print:
       destination 9:8:7::6 not found in routing table, dropping packet


Please follow the examples above in reporting the results of your routing table lookup. This makes it easier for the TA to grade a large number of assignments.

Turn in your source code ipgen6.c and rlookup6.c.


If you have extra time, you are welcome to send valid IP packets, for example, ICMPv6 ping packets.

Computer Networks, ICS 451
Instructor: Edo Biagioni