3 - IP and TCP, UDP

Review:

(See Dordal 1.15)

The intent behind this protocol was that, even if some of the network went down, it'd still work. They really focused on layers 3,4:

  • Layers 1 & 2: Network-to-Network layer (Network Ineterface Layer).
    • L1: Physical
    • L2: Data Link Layer
    • LAN protocols defined by IEEE
  • Layer 3: Internet Protocol (Network Layer, Routing)
  • Layer 4: TCP (transmit layer)
  • Layer 5+: Program layer

Recall from the OSI Seven Layer Model they argued so much about the higher layers that it really didn't matter. Here they focused on the lower layers where more of the decision needs to be made.

Let's look at each layer in depth.

Network to Host Layer (IP: Layer 3)

This is a Netowork-to-Host Layer or Network Interface Layer. Here the level 2 PDU is the frame, with header, data (and maybe trailer). But now at this layer (3) the PDU is called a datagram:

packet/datagram

A datagram (a level 3 PDU). A packet really is just the generic term for the payload of a level 3 PDU. Don't use packet since it's a generic term (we call many different things a packet).

What about layer 4 though?

segment

A segment is a level 4 PDU.

Just for completeness:

frame

A frame is a level 2 PDU.

Note that the TCP/IP Protocol suite does not really address or worry about these layers - they just assumes they work.

Now at this layer we have routing. It picks the path across the network. It's unreliable (when data is dropped on the wire, it doesn't care and leaves it be), and does error detection only on the header.

This layer is also Connection-Less (Protocol), and only runs on the hosts (not on the networking devices).

TCP: Transmission Control Protocol

Again, this is a segment now. It provides a reliable delivery of data:

reliable (networking)

We mean that something is reliable in networking when data within the payload needs to be sent and corrected to what it actually is.

The data is in-order and error free. It also does flow control between two devices.

It's also Handshake Protocol (Connection Oriented).

UDP?

Now UDP is the User Datagram Protocol, which is an unreliable layer 4. There's only optional error detection, and no flow control. UDP is Connection-Less (Protocol).
Now why use UDP? The reason is expense. Some things don't need UDP, like voice-calls. Another reason why some of the internet uses UDP is that TCP requires overhead, and thus requires hardware/software that uses it (it's more complicated, so more expensive).

Application Layer

This can really be anything, like HTTP(s), FTP, DNS, SNMP, SMTP, RIP, Ping, Traceroute, ...

Program 1: Networking Data Issues and the checksum()

For program 1, you're parsing these packets and seeing these headers. But part of the assignment is doing the Internet Checksum. But first, consider the following:


#include <stdio.h>
#include <inttypes.h>

void main()
{
	uint8_t anArray[100];
	int i = 0;

	for(i = 0; i < 100; i++)
		anArray[i] = i;

	printf("%s\n", anArray);
}

This outputs a newline, because it hits the null character first!

Why do we care? Well in the network we are just getting bytes, which can be 0! So using just strcpy won't work! The lesson here is to not use str functions unless you know it's a string. Use memcpy() instead. (Look it up in the man page if you don't know).

Example

What would happen if you used %s to print out the 6-byte MAC address of 0x00 0x02 0x2d 0x90 0x75 0x89?

uint8_t *srcMac = &buffer[6]
printf("Source Mac is: %s\n", srcMac);

The answer:

Pasted image 20250114160151.png

Endianness

Say we have 2 bytes. Byte 0 and Byte 1:

Instead, just use htonl, htons and ntohl, ntohs to convert to and from the network's endianness to the hosts (if it needs to).

You are given an in_cksum() function. This checks the IP and TCP headers and makes sure the data transmitted safely (ie: the payload is validates, or just the header in IP's case).

The field is a uint16_t. The sender filled this field and sent it to the destination. The receiver has to recreate this checksum and verify it with the checksum field in the header.

IP Checksum

To do this, we have the following function:

/**
* @ip_header_length: Header length is in the ip_header struct you decode. 99% of the time it's 20, but you need to get this programmatically. 
* Make sure this is 4 * the value actually in the header since this expects a number of words (not bytes). 
* @ip_header: The pointer to where the ip_header info starts. 
*/
int in_chksum(void* ip_header, ip_header_length);

You'll call this and store it somewhere, and check if it's 0 or not. If it's 0 then it's no error, and otherwise it is. Make sure you use 4 times the gotten length because we need to give it a number of words.

TCP Checksum

It works the same way in that you don't modify the checksum field. However, you need to make a new buffer, move the header information into there, and do a few other things. It namely checks:

  • The TCP header
  • The TCP Payload
    Overall just the TCP segment (see TCP, IP (and UDP) Protocol Suite for more info). It also checks the pseudo-header. It contains:
  • IP header info (not the whole header, just part of it)
    • It does this since it doesn't trust IP.
    • Contains:
      • Source IP address
      • Destination IP address
      • byte = 0
      • Protocol = 6 (from IP header)
      • 2-bytes of TCP segment length

In the new buffer you put:

  • The pseudo-header from above
  • TCP segment (with the TCP header)

Then you'll run the in_cksum using this buffer's pointer, and you need to calculate the length (again, you need to pass in the length in words, so multiply by 4 here).

This guide also talks a lot about it.