Introduction to packet structure
when data travels across a network (like the internet), it is not sent as one large block. instead, it is broken into smaller pieces called packets.
a packet is a small unit of data that contains:
- control information (where it is going, where it came from, error checking, etc.)
- the actual data being sent (called the payload)
you can think of a packet like a mailed package:
- the box = the packet
- the label (addresses, tracking info) = header
- the item inside = payload
understanding packet structure helps you understand how networks actually work behind the scenes.
Basic parts of a packet
most network packets have three main parts:
- header
- payload (data)
- trailer (sometimes)
header:
contains control information such as source address, destination address, protocol, and other metadata.
payload:
contains the actual message or data being transmitted (for example, part of a webpage).
trailer:
used mainly for error checking (for example, checksum in ethernet frames).
Packet structure in the tcp/ip model
the internet uses a layered design called the tcp/ip model. each layer adds its own header.
the main layers are:
- application layer
- transport layer
- internet layer
- network access layer
each layer wraps data from the layer above. this process is called encapsulation.
Encapsulation explained simply
imagine putting a letter into:
- a small envelope (application data)
- then into a bigger envelope (transport layer header added)
- then into a shipping box (internet layer header added)
- then labeled for delivery (network layer header added)
when the packet arrives, the receiver removes each layer in reverse order. this is called decapsulation.
Internet protocol (ip) packet structure
the Internet Protocol (ip) is responsible for delivering packets from one device to another using ip addresses.
an ipv4 header typically contains:
- version (4 bits)
- header length
- total length
- identification
- flags
- time to live (ttl)
- protocol (tcp or udp)
- source ip address
- destination ip address
- header checksum
after the ip header comes the transport layer data (tcp or udp).
example structure:
ip header | transport header | application data
Tcp segment structure
the Transmission Control Protocol (tcp) adds its own header before the data.
a tcp header contains:
- source port
- destination port
- sequence number
- acknowledgment number
- flags (syn, ack, fin, etc.)
- window size
- checksum
- urgent pointer
example layout:
tcp header | application data
when combined with ip:
ip header | tcp header | data
Udp datagram structure
the User Datagram Protocol (udp) has a much simpler header.
a udp header contains:
- source port
- destination port
- length
- checksum
example layout:
udp header | application data
when combined with ip:
ip header | udp header | data
udp packets are smaller and simpler than tcp packets.
Example of packet structure visually
a simplified representation:
| ip header | tcp header | application data |
or for udp:
| ip header | udp header | application data |
each header adds extra bytes. this extra information is called overhead.
Real-world example: visiting a website
when you visit a secure website:
- your browser creates http data.
- tcp adds its header (ports, sequence numbers).
- ip adds its header (source/destination ip).
- ethernet adds its frame header and trailer.
- the packet is sent across the network.
at the receiving server:
- ethernet header removed.
- ip header removed.
- tcp header removed.
- application receives the http data.
this layered process makes network communication organized and reliable.
Simple python example: building a fake packet
below is a simplified example of how a packet might be represented in code. this is only for understanding structure, not real packet transmission.
import struct
def create_fake_ip_header(source_ip, dest_ip):
version = 4
header_length = 5
ttl = 64
protocol = 6 # tcp
checksum = 0
return {
"version": version,
"header_length": header_length,
"ttl": ttl,
"protocol": protocol,
"source_ip": source_ip,
"dest_ip": dest_ip,
"checksum": checksum
}
def create_fake_tcp_header(source_port, dest_port):
sequence_number = 1
ack_number = 0
flags = "SYN"
return {
"source_port": source_port,
"dest_port": dest_port,
"sequence_number": sequence_number,
"ack_number": ack_number,
"flags": flags
}
def create_packet(source_ip, dest_ip, source_port, dest_port, data):
ip_header = create_fake_ip_header(source_ip, dest_ip)
tcp_header = create_fake_tcp_header(source_port, dest_port)
packet = {
"ip_header": ip_header,
"tcp_header": tcp_header,
"data": data
}
return packet
packet = create_packet("192.168.1.2", "93.184.216.34", 12345, 80, "GET / HTTP/1.1")
print(packet)
This example shows how headers and data are grouped together logically.
Why packet structure is important
packet structure is important because:
- routers use ip headers to forward packets.
- firewalls inspect headers to allow or block traffic.
- tcp uses sequence numbers to ensure correct order.
- checksums detect errors.
- ports allow correct application delivery.
without structured packets, network communication would be chaotic.
import struct
# =========================
# fake ip header
# =========================
def create_fake_ip_header(source_ip, dest_ip):
version = 4
header_length = 5
ttl = 64
protocol = 6 # tcp
checksum = 0
return {
"version": version,
"header_length": header_length,
"ttl": ttl,
"protocol": protocol,
"source_ip": source_ip,
"dest_ip": dest_ip,
"checksum": checksum
}
# =========================
# fake tcp header
# =========================
def create_fake_tcp_header(source_port, dest_port):
sequence_number = 1
ack_number = 0
flags = "SYN"
return {
"source_port": source_port,
"dest_port": dest_port,
"sequence_number": sequence_number,
"ack_number": ack_number,
"flags": flags
}
# =========================
# create full packet
# =========================
def create_packet(source_ip, dest_ip, source_port, dest_port, data):
ip_header = create_fake_ip_header(source_ip, dest_ip)
tcp_header = create_fake_tcp_header(source_port, dest_port)
packet = {
"ip_header": ip_header,
"tcp_header": tcp_header,
"data": data
}
return packet
packet = create_packet("192.168.1.2", "93.184.216.34", 12345, 80, "GET / HTTP/1.1")
print(packet)