COMP3301/COMP7308 2019 Assignment 1 (DRAFT)
• Due: During pracs on 21st and 23rd of August 2019
• Revision : 222 (DRAFT)
1 RFC 8086 - GRE-in-UDP Encapsulation
This assignment asks you to write a simplified implementation of RFC 8086 - GRE in UDP encapsulation
called greu. The implementation will support multiplexing multiple IP or Ethernet tunnels over a single
UDP socket.
The purpose this assignment is to expose you to event driven programming, working against existing APIs
and libraries, and the use of the OpenBSD code style and tool chain.
This is an individual assignment. You should feel free to discuss aspects of C programming and the
assignment specification with fellow students. You should not actively help (or seek help from) other
students with the actual coding of your assignment solution. It is cheating to look at another student’s
code and it is cheating to allow your code to be seen or shared in printed or electronic form. You should
note that all submitted code may be subject to automated checks for plagiarism and collusion. If we detect
plagiarism or collusion, formal misconduct proceedings will be initiated against you. If you’re having
trouble, seek help from a member of the teaching staff. Don’t be tempted to copy another student’s code.
You should read and understand the statements on student misconduct in the course profile and on the
school web-site:
2 Specifications
greu is used to tunnel multiple network connections over a single UDP connection. It supports tunnelling
both IP (layer 3) and Ethernet (layer 2) packets inside the GRE protocol.
Each network tunnel is connected to the kernel via the tun(4) and tap(4) device drivers. Packets read
from the kernel are encapsulated in GRE before being sent on the UDP socket. GRE packets received
from the socket are decapsulated and written to the appropriate device.
2.1 Code Style
Your code is to be written according to OpenBSD’s style guide, as per the style(9) man page.
2.2 Compilation
Your code is to be built on an amd64 OpenBSD 6.5 system. It must compile as a result of running make(8)
in the root directory of your submitted assignment. Compilation must produce a binary called greu in
either the same directory, or in the obj directory if it exists.
Compilation of greu must succeed with -Wall passed as a flag to the compiler.
2.3 Invocation
When run with no arguments, or extra or unknown options, greu should print a usage message to stderr:
usage: greu [-46d] [-l address] [-p port]
[-e /dev/tapX[@key]] [-i /dev/tunX[@key]]
server [port]
and terminate with a non-zero exit code.
greu takes the following command line arguments:
-4 Force greu to use IPv4 addresses only.
-6 Force greu to use IPv6 addresses only.
-d Do not daemonise. If this option is specified, greu will run in the foreground and log to stderr. By
default greu will daemonise.
-l address Bind to the specified local address. By default greu does not bind to a local address.
-p port Use the specified source port. By default greu should use the destination port as the source
-e /dev/tapX[@key] Tunnel Ethernet traffic for the specified tunnel device. If @key is specified, enable
the use of the GRE Key extension header. This option may be specified multiple times to add
Ethernet tunnels.
-i /dev/tunX[@key] Tunnel IPv4 and IPv6 traffic for the specified tunnel device. If @key is specified,
enable the use of the GRE Key extension header. This option may be specified multiple times to
add IP tunnels.
server The IP address or host name of the remote tunnel endpoint.
port Use the specified port on the server as the remote tunnel endpoint. By default greu should use
port 4754 as per the RFC.
At least one IP or Ethernet tunnel must be configured.
If greu is unable to bind to the specified local address and port, connect to the remote server and port, or
open the specified tunnel interfaces, it should generate an appropriate error and terminate with a non-zero
exit status.
2.4 Functionality
• greu should use a single UDP socket to connect to the address specified by the command line
arguments for exchange of GRE-in-UDP packets
– it must support both IPv4 and IPv6 sockets
– addresses may be numeric IP addresses or host names
– ports may be numeric or a name listed in /etc/services
• Repeated specification of command line options may overwrite previously set values
• greu is only required to implemented a simplified RFC8086:
– DTLS support is not required
– it only has to create a single UDP connection to the server
– it can expect to receive replies to the local port it transmits from
– encoding entropy by using multiple source ports is not required
– it will act as a client talking to a server
• It only needs to support GRE Version 0 encapsulation
• It does not need to implement any GRE extensions apart from the GRE Key Extension header
• It must support tunnelling Ethernet and IP packets
– Ethernet packets are identified by the Transparent Ethernet protocol identifier (0x6558)
– IPv4 and IPv6 packets are identified by their respective Ethernet protocol identifierss (0x0800
and 0x86dd).
• Tunnels are uniquely identified by their type (Ethernet or IP) and the Key (no key, or a 32bit
– The same Key may be used by IP and Ethernet tunnels
– The same Key must not be reused by the same type of tunnel
2.5 Required Dependencies
greu must only use the following libraries and the APIs they provide to implement the above functionality.
2.5.1 libc
libc refers to the ISO or POSIX standard C library provided by UNIX and UNIX like operating systems.
A libc contains the APIs required by greu for such tasks as resolving host and service names to IP
addresses and ports, creating network sockets and connections, and opening and reading files.
2.5.2 libevent
According to, libevent:
. . . provides a mechanism to execute a callback function when a specific event occurs on a file
descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks
due to signals or regular timeouts.
OpenBSD ships with libevent 1.4 with local patches. It is this version of libevent in the base system
what you are required to write greu against.
2.5.3 tun(4)
According to the tun(4) manual page:
The tun driver provides a network interface pseudo-device. Packets sent to this interface
can be read by a userland process and processed as desired. Packets written by the userland
process are injected back into the kernel networking subsystem.
It is important to note that the type of IP packet is included as a 4 byte prefix on packets read from or
written to the device.
2.5.4 tap(4)
According to the tap(4) manual page:
The tap driver provides an Ethernet interface pseudo-device. Packets sent to this interface
can be read by a userland process and processed as desired. Packets written by the userland
process are injected back into the kernel networking subsystem.
2.6 Logging API
greu may use the log.c and log.h file supplied by the course, rather than implementing this functionality
The API and documentation is provided at If used, the code should
copied into the submitted assignment.
2.7 Restrictions
• greu must operate as a single process/thread, therefore it may not fork (after daemonising) or create
2.8 Recommendations
The focus of this assignment is event driven programming, not on creating new implementations of common
functionality. It is strongly recommended that the following APIs are used as part of your program:
• getopt(3) - get option character from command line argument list
• err(3), warn(3), etc - formatted error messages
• getaddrinfo(3) - host and service name to socket address structure
• gai_strerror(3) - get error message string from EAI_xxx error code
• strtonum(3) - reliably convert string value to an integer
• daemon(3) - run in the background
• ioctl(2) - control device, used to configure non-blocking file descriptor operation
3 Submission
Submission must be made electronically by committing to your Subversion repository on In order to mark your assignment the markers will check out ass1
from your repository. Code checked in to any other part of your repository will not be marked.
As per the usage guidelines, you should only commit source code and Makefiles
The due date for the code submission is the beggining of your prac session, either 2pm on Wednesday the
21st, or 12pm on Friday the 23rd of August 2019. Note that no submissions can be made more than 120
hours past the deadline under any circumstances.
4 Testing
4.1 Ethernet
A server is running on the IPv4 address of on port 3301 that implements
a GRE-in-UDP server. This server implements a virtual Ethernet switch, allowing GRE-in-UDP tunnels
to communicate, but has no support for IPv4 and IPv6 tunnels. The server has the following Keys and
IPv4 subnets configured:
• No Key:
• Key 0:
• Key 3301:
• Key 7308:
IPv4 addresses can be requested via DHCP on all four networks. The server should support communication
between tunnels connected to the same networks.
4.2 IP
IP tunnel connectivity may be tested by using greu on different computers, using each other as the remote
4.3 Packet Inspection
Several tools are available that are capture and disect network packets for inspection. These may be used
to verify that the packets on the wire conform to the expected format. tcpdump(8) is available in the
OpenBSD base system, and supports disection of GRE inside UDP. An example of it’s usage:
# tcpdump -v -e -i em0 -Tgre host and port 3301
tcpdump: listening on em0, link-type EN10MB
10:57:34.583486 bc:2c:55:36:7f:fb 74:88:2a:d4:b2:00 ip 88:
.3301 > [udp sum ok] gre [] 6558 fe:e1:ba:dd:8c
:f9 fe:e1:ba:da:ab:9c ip 42: > icmp: echo request (id:00
00 seq:0) [icmp cksum ok] (ttl 64, id 1, len 28) (ttl 64, id 1, len 74)



添加客服微信: abby12468