The most popular protocol for modern networking is called Internet Protocol (IP). This protocol is different from direct end-to-end systems in two ways. Firstly, it is a "best-effort" system, when a message is sent towards a particular destination, there is no guarantee that the message will reach its intended target. Secondly, IP is packet switched, every data transfer is broken down into small packets of data, the size of which is limited by the machines between the source and the destination. Packets are forwarded along between machines, using simplistic routing logic to send each packet towards its goal.
IP Packets have a well-defined format, shown here:
The Packet Header consists of all of the fields preceding the Data field. The Packet Data consists only of the Data field. To learn more about the IP protocol view this page.
The input to this assignment is an IP packet. You can generate packets
to use as input with the C program packetGenerator.c
. More
information on packetGenerator.c
can be found in the
Testing section.
The table below defines an example IP packet, using markers A-O to label each of the fields.
Marker | Field | Value |
---|---|---|
A | IP Version | 4 |
B | Packet Header Length | 6 |
C | Differentiated Services Code Point | 10 |
D | ECN (Explicit Congestion Notification) | 0 |
E | Total Packet Length | 28 |
F | Identification | 38923 |
G | Flags | 1 |
H | Fragment Offset | 0 |
I | Time To Live | 99 |
J | Protocol | 6 |
K | Header Checksum | 0x0481 |
L | Source IP Address | 6.23.180.9 |
M | Destination IP Address | 40.79.2.5 |
N | Options | 'j', 'f', 'j', 'k' |
O | Data | 'g', 'k', 'r', 'f' |
The following image demonstrates both how the above example packet is stored in the memory of a RISC-V program and how you can locate the different fields of an IP packet in RARS's Data Segment. Networking uses an agreed-upon standard of big-endian byte order but RARS is little-endian. Therefore, any time you are using a number larger than a byte you will need to first swap the byte order. Converting each word to big-endian can make it easier to understand how each of the packet's fields is stored.
Another way to view a packet file is with the command:
xxd -ps -c 4 PATH_OF_PACKET_FILE
This command will
print the data of the file, in hexadecimal, one big-endian word per
line. The following image demonstrates this command being used on the
example packet defined by the table above.
Write a RISC-V program that, given an IP packet, calculates its checksum.
When an IP packet arrives at a router, the router calculates the checksum of its header and compares it to the Header Checksum field of the packet. If the values do not match, the router discards the packet.
The Packet Header Length field stores an unsigned integer that specifies the number of words in the header. This length is used to calculate exactly how much of the packet must be summed in the header checksum.
The algorithm for calculating the checksum of a packet's header is as follows:
Where Hi is the ith halfword, Sum is a 16-bit value and Carryout is the carry-out bit for the 16-bit addition of Accumulator and Hi.
This algorithm is sometimes referred to as the
one-complement sum. For the purposes of calculating the checksum,
the field containing the checksum itself is assumed to be zero.
Therefore, you must skip the Header Checksum field when
computing the checksum. You will also need to switch the order of the
two bytes in each halfword before adding them to the sum. For example,
the halfwords used to calculate the header checksum of the example
packet described in the
Example Packet subsection of the
Input section would be 0x460a
,
0x001c
, 0x980b
, etc... The halfword
0x0481
should not be used in the checksum calculation
because it is the Header Checksum field.
Here is an example of steps 4 and 5 of the above algorithm with some arbitrary values for Accumulator and Hi:
Write assembly code for the following functions in
checksum.s
:
checksum:
a0
: starting address of an IP packet in memory.
a0
: calculated checksum of the packet in the lower
halfword in big-endian byte order.
flipHalfwordBytes:
a0
: two bytes stored in the lower halfword.a0
: the reverse order of the input bytes in the lower
halfword.
getHeaderLength:
a0
: starting address of an IP packet in memory.
a0
: the value of the packet's
Packet Header Length field in the lowest four bits.
Your program should not alter the packet in memory.
Download the code to get started!
The Code
zip file contains the following files and
directories:
checksum.s
: this is where you will write the code for the
checksum
, flipHalfwordBytes
, and
getHeaderLength
functions.
common.s
: loads a packet file from the path provided as a
program argument; calls your checksum
function; and then
prints the returned value.
packetGenerator.c
: a C program that you may use to
generate IP packet files for your own testing. Compile the program
using the command:
gcc packetGenerator.c -o packetGenerator
, and run using
the command ./packetGenerator
.
examplePacket.in
: The example packet described in the
Example Packet subsection of the
Input section.
Assignments too short to be adequately judged for code quality will be given a zero for that portion of the evaluation.
There is a single file to be submitted for this lab:
checksum.s
should contain the code for the functions
checksum
, flipHalfwordBytes
, and
getHeaderLength
main
label to this file.include "common.s"
checksum.s