Networking 101: IP addressing and packets

Learn what an IP address is and how subnets, masks, and CIDR divide a network, then explore how a packet is structured and routed hop by hop to its destination.

19 minutes reading time

Written by

Jubril Oyetunji
Jubril Oyetunji

Technical Writer at Civo

Every machine on a network needs an address that other machines can use to reach it, and the data that travels between those machines is carried in IP packets that routers read and forward. An address says where data should go; a packet is what carries it there.

This article covers both. It starts with what an IP address is and how subnets, masks, and CIDR divide a network, then moves on to how a packet is structured and routed hop by hop to its destination. Every numeric example can be reproduced with a calculator like sipcalc or ipcalc, and the last section maps the concepts onto Civo's networking features.

What is IP addressing?

An IP address is how one host identifies another on a network, enabling communication targeted at a specific recipient. Each address must be unique within its network, functioning much like a phone number.

An IPv4 address appears as a series of digits like 10.2.3.4. Those are four 8-bit numbers, called octets, each ranging from 0 (binary 00000000) to 255 (binary 11111111). Stack four octets together and you get 32 bits, which means the whole space runs from 0.0.0.0 to 255.255.255.255, a total of 4,294,967,296 addresses (that is 2^32).

What is IP addressing?

How a dotted-decimal address maps to four octets and to 32 bits, with each octet shown in decimal and binary.

That 4.29 billion figure is the IPv4 address space. IPv6, covered later in this article, is far larger.

Public versus private addressing

Not every IP address is meant to be reachable from the public internet. Three ranges are set aside by RFC 1918 for private use, which means anyone can use them inside their own network and they are never routed on the public internet:

RangeCIDRAddressesCommon use

10.0.0.0 to 10.255.255.255

10.0.0.0/8

16,777,216

Large networks, cloud VPCs

172.16.0.0 to 172.31.255.255

172.16.0.0/12

1,048,576

Mid-size networks, Docker defaults

192.168.0.0 to 192.168.255.255

192.168.0.0/16

65,536

Home and small office networks

Every example in this article uses 10.0.0.0 because it is a private range, the same kind of address you would use inside a cloud network. Because these ranges are not globally unique, two different companies can both run 10.0.0.0/8 internally without any conflict. The trade-off is that a private address cannot be reached from the outside on its own; getting it to the internet requires NAT, covered later.

Cloud providers lean on private ranges because a virtual private network (a VPC, or on Civo simply a "network") gives each customer an isolated address space. Your 10.0.1.5 and another customer's 10.0.1.5 never collide because the two networks are isolated from each other.

IPv4 exhaustion and an IPv6 primer

The IPv4 space holds 4,294,967,296 addresses, and it has been exhausted. IANA handed out the last large IPv4 blocks in 2011 and the regional registries followed in the years after, which is why public IPv4 addresses now cost money and NAT became universal.

The long-term fix is IPv6, which uses 128-bit addresses instead of 32-bit. That is 2^128 addresses, large enough that exhaustion is no longer a concern. An IPv6 address is written as eight groups of four hex digits separated by colons:

2001:0db8:85a3:0000:0000:8a2e:0370:7334

Two shorthand rules make these shorter. Leading zeros in a group can be dropped, and one run of all-zero groups can be replaced with :: once per address. So the address above becomes:

2001:db8:85a3::8a2e:370:7334

A few things carry over from the IPv4 half of this article:

  • CIDR works the same way. A prefix length still counts bits from the left, so a /64 fixes the first 64 bits as the network and leaves 64 bits for hosts.
  • The standard subnet for a single LAN is a /64. That is the IPv6 equivalent of "your local segment," and it holds 2^64 addresses, far more than any one network needs.
  • Every IPv6 interface also gets a link-local address starting with fe80::. It is only valid on the local link and is used for housekeeping like neighbor discovery, the IPv6 replacement for ARP.

Large networks, mobile carriers, and many cloud services are now dual-stack or IPv6-first, so IPv6 is worth knowing from the start.

What is a subnet?

A subnet is a subnetwork, meaning a network divided into multiple smaller networks. Organizations split a network this way to separate it logically for different purposes, such as business functions (an Accounts network, a Sales network, and so on). Networks are also divided for security and access control, so that one group of hosts can be isolated or firewalled off from another.

Dividing a network lets a host or router decide, just by looking at an address, whether a destination is on the same subnet or has to be handed off elsewhere. To make that decision you need a way to mark which part of an address names the network and which part names the host, and that is what a subnet mask does.

Subnet masks, CIDR, and the binary AND

Imagine you have 8 addresses and want to split them into two groups of 4. Without some marker that says where one group ends and the next begins, there is no way to tell which address belongs to which subnetwork. At the scale of a real network that problem becomes impossible by eye. A subnet mask is that marker.

The mask works by reserving some of the 32 bits, counting from the left, for the network portion. Those bits are fixed across every host in the subnet; the remaining bits are free to number individual hosts. For a typical small network the mask is 255.255.255.0, which in binary is 11111111.11111111.11111111.00000000: the first 24 bits are ones (network) and the last 8 bits are zeros (host).

CIDR notation is just a shorthand for "how many of those leading bits are the network." Instead of writing the full mask, you write the address followed by a slash and the count, like 10.0.0.0/24. The /24 says the first 24 bits out of 32 are the prefix. CIDR lets the entire address space be broken down into subnet sizes that are powers of 2.

Subnet masks, CIDR, and the binary AND

A /24 mask splitting 32 bits into a 24-bit network prefix and an 8-bit host portion, ANDed with the address to give the network address.

One common point of confusion: 10.0.0.1/24 does not describe a range starting at .1. The /24 describes the subnet, not the host boundary, so 10.0.0.1/24 is still a host inside the range 10.0.0.0 to 10.0.0.255.

How does a host actually find the network portion of an address? It performs a bitwise AND between the address and the mask. AND returns a 1 only where both inputs are 1, so the host bits (where the mask is 0) get zeroed out and the network bits survive:

10.0.0.255 address
& 255.255.255.0 mask
= 10.0.0.0 network address

The result, 10.0.0.0, is the network address, and the bits that were zeroed out are the host part. This AND operation is how a router decides, in one step, which network an address belongs to.

Usable address range

Within any subnet, not all addresses are usable. Two are reserved. The first address is the network address (also called the address prefix), which names the subnet itself, and the last address is the broadcast address, used to reach every host on the subnet at once.

For a /24 like 10.0.0.0/24, that means:

  • Network address: 10.0.0.0 (reserved)
  • Broadcast address: 10.0.0.255 (reserved)
  • Usable host addresses: 10.0.0.1 through 10.0.0.254

So a /24 holds 256 total addresses but only 254 usable ones. The same rule scales to any prefix: total addresses are 2^(32 minus prefix length), and you lose two to the network and broadcast addresses.

Calculating subnets with sipcalc and ipcalc

You rarely do this arithmetic by hand. sipcalc takes a CIDR block and prints everything: network address, broadcast, mask, and the usable host range. Start with the baseline /24:

sipcalc 10.0.0.0/24

Expected highlights:

/24 : 256 addresses, usable 10.0.0.1-10.0.0.254, broadcast 10.0.0.255
Calculating subnets with sipcalc and ipcalc

A /24 broken down: 256 addresses, usable .1 to .254, broadcast .255.

It can also split a block for you in one command. Carve a /24 into four /26 subnets:

sipcalc -s 26 10.0.0.0/24

Expected: four networks at 10.0.0.0/26, 10.0.0.64/26, 10.0.0.128/26, and 10.0.0.192/26, covering .0 to .63, .64 to .127, .128 to .191, and .192 to .255.

Calculating subnets with sipcalc and ipcalc

sipcalc -s 26 10.0.0.0/24 carving the block into four /26 subnets.

A /30 is the smallest practical subnet, used for point-to-point links, with only two usable addresses:

sipcalc 10.0.0.0/30

Expected highlights:

/30 : 4 addresses, usable 10.0.0.1-10.0.0.2

ipcalc is a friendly, colorized alternative that many people find easier to read. Install it with apt install ipcalc on Debian or Ubuntu, then:

ipcalc 10.0.0.0/24

It prints the address, netmask, network, broadcast, and host range, and it labels the address class and whether the range is private. For the split, ipcalc 10.0.0.0/24 --s 26 26 26 26 carves the block into four equal subnets.

CIDR aggregation and supernetting

The previous sections showed how to divide a block into smaller subnets. The same notation runs in reverse. If you control several adjacent networks, you can summarize them with one shorter prefix. That is aggregation, also called supernetting, and it is what keeps internet route tables at a manageable size.

Take four consecutive /24s:

10.0.0.0/24
10.0.1.0/24
10.0.2.0/24
10.0.3.0/24

Look at the third octet in binary: 0 is 00000000, 1 is 00000001, 2 is 00000010, 3 is 00000011. The first six bits of that octet are identical across all four (000000), only the last two vary. So the four blocks share the first 8 + 8 + 6 = 22 bits. Combine them and you get a single /22:

10.0.0.0/22
CIDR aggregation and supernetting

One /24 carved into four /26 subnets, the same operation aggregation runs in reverse.

That one route covers all 1024 addresses (4 times 256) and replaces four routes with one. Confirm it with the calculator:

sipcalc 10.0.0.0/22

Expected highlights:

/22 : 1024 addresses, usable 10.0.0.1-10.0.3.254, broadcast 10.0.3.255
CIDR aggregation and supernetting

A /22 supernet: 1024 addresses spanning 10.0.0.0 to 10.0.3.255.

The catch is that the blocks must be contiguous and aligned, which is why aggregation works for 10.0.0.0 to 10.0.3.0 but not for an arbitrary four blocks scattered around. The same private-range math holds for the larger RFC 1918 blocks too:

sipcalc 172.16.0.0/12

Expected highlights:

172.16/12 : 1,048,576 addresses, last address 172.31.255.255
CIDR aggregation and supernetting

The 172.16/12 private range: 1,048,576 addresses, last address 172.31.255.255.

Ports and the socket model

An IP address gets a packet to the right machine. A port gets it to the right program on that machine. A port is a 16-bit number, so it ranges from 0 to 65535. The pair of an IP address and a port is a socket, written address:port, for example 10.0.0.5:443.

Ports fall into rough bands:

RangeNameTypical use

0 to 1023

Well-known

Standard services: 22 SSH, 80 HTTP, 443 HTTPS, 53 DNS

1024 to 49151

Registered

Vendor and application services

49152 to 65535

Ephemeral

Short-lived client source ports, picked automatically

When your laptop opens a connection to a web server, the destination is something like 203.0.113.10:443, and your own side gets an ephemeral source port like 198.51.100.7:51544. The full connection is identified by both ends together, the four-tuple of source address, source port, destination address, destination port. That four-tuple is also exactly what a NAT gateway tracks to keep connections straight.

MAC addresses and ARP (L2 versus L3)

The addresses in this article so far are layer 3 (the network layer), the addresses routers use to move packets across networks. On a single local segment there is a second address underneath: the MAC address, a 48-bit hardware address burned into the network interface, written as six hex pairs like 00:1a:2b:3c:4d:5e. That is layer 2, the link layer.

When 10.0.0.5 wants to send to 10.0.0.9 on the same LAN, it knows the target IP but not the target MAC, and on the wire it can only deliver to a MAC. ARP (Address Resolution Protocol) fills the gap. The host broadcasts "who has 10.0.0.9?" and the owner replies "that is me, here is my MAC." The sender caches the answer and sends the frame to that MAC.

The rule of thumb: IP addresses are how you reach something on another network, MAC addresses are how you reach something on your own segment, and ARP is the lookup that connects the two. IPv6 does the same job with Neighbor Discovery over those fe80:: link-local addresses instead of ARP. This split matters later, because a packet travels inside a frame addressed by MAC.

Routing basics

A host or router decides where to send a packet by consulting a route table. Each entry pairs a destination network (a CIDR) with a next hop. When a packet needs to go somewhere, the device compares the destination address against every route and picks the most specific match. That last rule is longest-prefix match: if both 10.0.0.0/24 and 10.0.0.0/16 match, the /24 wins because it is more specific.

A tiny route table:

DestinationNext hopMeaning

10.0.0.0/24

direct

On my own segment, deliver locally

10.0.0.0/8

10.0.0.1

Rest of the private network, via the router

0.0.0.0/0

10.0.0.1

Everything else, via the default gateway

The 0.0.0.0/0 entry is the default route, the catch-all that matches any destination with a prefix length of zero. It is the lowest-priority match, so it only wins when nothing more specific does.

On any Linux host or Civo instance you can see the real table and the decision it makes:

ip route
ip route get 203.0.113.10

The second command shows exactly which route a given destination matches, which is longest-prefix match in action.

What is an IP packet?

An IP packet is a unit of data in a network that contains information about the source and destination addresses, along with other control information needed to transport the packet over a network. The addresses from the earlier sections are not sent on their own; they are carried inside the packet's header.

When a packet enters a router, the router reads the destination address, consults its routing table (the longest-prefix match from the previous section), and forwards the packet toward its next hop. That repeats, router by router, until the packet reaches the network that owns the destination address and is delivered.

Because each packet is self-describing and independently routable, the network can route traffic efficiently across multiple paths, scale services more easily, load-balance across replicas, and give operators better observability for monitoring and debugging.

The structure of an IP packet (header fields)

Every IPv4 packet starts with a header, a minimum of 20 bytes, that carries the control information a router needs. The fields, in order:

FieldPurpose

Version

The IP version, 4 or 6, so the receiver knows how to parse the rest

IHL (header length)

Header length in 32-bit words, so the receiver knows where the data begins

ToS (Type of Service)

Desired handling, for example low delay or high throughput

Total length

Size of the whole packet, header plus data

Identification

An ID shared by all fragments of one original packet, used to reassemble them

Flags

Fragmentation control, including Don't Fragment (DF) and More Fragments (MF)

Fragment offset

Where this fragment sits within the original packet

TTL (Time to Live)

A hop counter, decremented by one at each router

Protocol

The next-layer protocol, for example TCP or UDP

Header checksum

An error check over the header fields

Source address

The sender's IP address, used for replies and error reporting

Destination address

The recipient's IP address, used for every routing decision

The structure of an IP packet (header fields)

The IPv4 header laid out as a 32-bit-wide field grid showing relative field sizes, with TTL, source, and destination highlighted. 20 bytes minimum.

A note on IPv6. The Version field is where IPv4 and IPv6 part ways. An IPv6 header is a different, fixed 40-byte layout: it drops IHL, Identification, Flags, Fragment offset, and the header checksum, and it moves fragmentation out to extension headers. The Version field tells the router which header format follows.

Encapsulation: How a packet rides inside a frame

Each layer of the network stack wraps the one above it, like nested envelopes. The application's data is wrapped in a layer 4 segment (TCP or UDP, which carries the ports from the socket section). That segment is wrapped in the layer 3 IP packet (which carries the source and destination IP addresses from the header section). And on each physical hop, that packet is wrapped in a layer 2 frame (which carries the MAC addresses from the ARP section).

Encapsulation: how a packet rides inside a frame

Nested headers: an L2 Ethernet frame (MAC src/dst) wrapping an L3 IP packet (IP src/dst) wrapping an L4 segment (port src/dst) wrapping the data, with an "on the wire" arrow.

The layers serve different scopes. The L2 frame and its MAC addresses are rewritten at every hop, because each hop is a fresh local delivery between two adjacent interfaces. The L3 packet and its IP addresses stay the same end to end, because they name the original source and final destination. So as a packet crosses the network, the IP addresses ride unchanged inside while the MAC addresses on the outside change at each router.

TTL and how packets hop across networks

The TTL field is what stops a packet from circling the network forever. It is a hop counter, not a clock: every router that forwards the packet decrements TTL by one, and when it hits zero the packet is dropped and discarded. Without it, a routing loop would trap packets indefinitely.

Each of those hops is a routing decision, the longest-prefix match from the routing section. The router reads the destination address, finds the most specific matching route, rewrites the layer 2 frame for the next link, decrements TTL, and forwards. Repeat until the packet lands on the destination's network.

This behavior is directly observable. ping shows the TTL in each reply, and traceroute deliberately sends packets with small, increasing TTL values so each router along the path is forced to report itself when the TTL expires, giving you one row per hop:

ping 203.0.113.10
traceroute 203.0.113.10
TTL and how packets hop across networks

The socket four-tuple on top, and below it a packet hopping Host to Router to Server with the route table's default route matched by longest-prefix and a TTL counter decrementing per hop.

Fragmentation and MTU

A link can only carry frames up to a certain size, the MTU (Maximum Transmission Unit), which on most Ethernet networks is 1500 bytes. If a packet is larger than the MTU of a link it must cross, it gets fragmented: split into pieces that each fit, sent separately, and reassembled at the destination.

Three header fields make that work. Identification carries an ID shared by every fragment of the original packet, so the receiver knows which pieces belong together. The Flags field includes Don't Fragment (DF), which forbids splitting, and More Fragments (MF), which is set on every fragment except the last so the receiver knows when it has them all. Fragment offset records where each piece sits in the original, so they can be put back in order.

You can read a link's MTU directly:

ip link

Fragmentation is best avoided, because a single lost fragment forces the whole packet to be resent. Modern stacks lean on Path MTU Discovery (RFC 1191) instead: the sender sets DF, and if a router along the path cannot forward the packet without splitting it, the router reports back the MTU it can handle, so the sender shrinks its packets to fit the smallest link on the path.

NAT and gateways

A private host with a 10.x address cannot appear on the public internet directly, because that address is not globally routable. Network Address Translation (NAT) is the trick that bridges the gap. A gateway device sits at the edge of the private network with one foot in the private range and one public address. As packets leave, it rewrites the private source address in the packet header (the same source field from the structure section) to its own public address, and it remembers the mapping so replies find their way back.

Two directions are worth naming:

  • SNAT (source NAT) rewrites the source address on the way out. This is how many private hosts share one public address to reach the internet. Outbound is initiated from inside.
  • DNAT (destination NAT) rewrites the destination address on the way in. This is how you publish an internal service, by forwarding a public address and port to a private host. Inbound is initiated from outside.
NAT and gateways

A private host reaching the internet through a NAT gateway, with the packet's source address rewritten from 10.0.0.5 to the gateway's public 198.51.100.7 on the way out.

Worked example. A host at 10.0.0.5 wants to reach a web server at 203.0.113.10. Its packet leaves with source 10.0.0.5. The gateway, holding public address 198.51.100.7, rewrites the source to 198.51.100.7 and notes the mapping. The reply comes back to 198.51.100.7, the gateway looks up the mapping, rewrites the destination back to 10.0.0.5, and delivers it. The web server never saw the private address at all.

DNS at a glance

People do not type addresses, they type names. DNS (the Domain Name System) is the directory that turns a name like www.civo.com into an IP address. It sits one layer above everything in this article. When you open a site, your machine first asks a DNS resolver for the address, gets back something like 203.0.113.10, and only then builds a packet and opens a socket to that address on port 443. IP addressing is the destination; DNS is how you look the destination up.

How this maps to Civo networking

The concepts in this article map directly onto Civo's networking features:

  • Private networks: On Civo a "network" is an isolated private address space, the same idea as a VPC. Each region has a Default network, and you can create additional networks to separate workloads. The network API accepts an optional cidr_v4 field that must be an RFC 1918 CIDR, so you can hand it something like 10.0.0.0/24 straight out of this article. Omit it and Civo allocates a private range for you. Network assignment is permanent for a resource and networks are region-specific.
  • Firewalls: A Civo firewall controls inbound and outbound traffic for your instances and clusters, the practical version of the port rules from the ports section. The Default firewall has all ports open, and you add rules to lock it down to just the ports your services use.
  • Reserved IPs: These are public IP addresses that stay yours even as you change the resource behind them, so you can rebuild an instance or a load balancer without the public address moving. They are region-specific. This is the public side of the public-versus-private split, the address a NAT or load balancer presents to the internet.

Example CLI flow for a reserved IP:

civo ip reserve -n web-frontend
civo ip ls
civo ip assign <address> --instance <instance>

This model shows up clearly in Kubernetes, which Civo runs as managed clusters. A pod gets its own IP from the cluster's private range, nodes carry pods across the network, and a Service gets a stable virtual IP that load-balances across the pods behind it. When two pods on different nodes talk, their packets ride across the node network using a CNI plugin such as Cilium, Calico, or Flannel to carry pod traffic between nodes.

A packet reaching a Civo workload follows the model this article describes: a private 10.x address inside a Civo network, the data wrapped in a packet and addressed to that host, a firewall deciding which ports are open, and a reserved public IP plus NAT presenting the service to the internet.

Summary

An IP address names a host, a subnet mask and CIDR split that address into network and host portions, and the bitwise AND is how a router decides in one step which network an address belongs to. Once you can name a destination, the IP packet is the thing that actually carries data there: a header full of control fields, a TTL that counts hops, encapsulation that wraps the packet in a frame for each physical link, and routing by longest-prefix match that moves it forward one hop at a time. NAT bridges private addresses to the public internet, DNS turns names into the addresses you start from, and on Civo all of this lands as private networks, firewalls, and reserved IPs.

Where to go next:

  • Reproduce every number here offline with sipcalc <cidr> and ipcalc <cidr>.
  • Watch packets hop in real time with ping, traceroute, and ip route get <dest>.
  • See live header fields with tcpdump -v or Wireshark.
  • Build it for real: create a Civo network with a custom RFC 1918 CIDR, lock it down with a firewall, and attach a reserved IP.
Jubril Oyetunji
Jubril Oyetunji

Technical Writer at Civo

Jubril Oyetunji is a DevOps engineer and technical writer with a strong focus on cloud-native technologies and open-source tools. His work centers on creating practical tutorials that help developers better understand platforms such as Kubernetes, NGINX, Rust, and Go.

As a contract technical writer, Jubril authored an extensive library of technical guides covering cloud-native infrastructure and modern development workflows. Many of his tutorials achieved strong search rankings, helping developers around the world learn and adopt emerging technologies.

View author profile

Further Reading

Read more
Slide 1 of 2