IPv4 Addresses & Subnetting TCP/IP Networking Fundamentals for Linux Socket Programming

 

Chapter 58 – Part 1: IPv4 Addresses & Subnetting
TCP/IP Networking Fundamentals for Linux Socket Programming
Topic
IPv4 Addressing
Level
Beginner to Intermediate
Part
1 of 5

What is an IPv4 Address?

Every device connected to an IP network needs a unique identifier — this is the IP address. IPv4 (Internet Protocol version 4) uses a 32-bit address, which means there are 232 = about 4.3 billion possible addresses. These 32 bits are split into 4 groups of 8 bits each, written in dotted-decimal notation like 192.168.1.10.

Every IPv4 address has two logical parts: a Network ID (identifies which network the device belongs to) and a Host ID (identifies the specific device within that network). A subnet mask tells you where the network part ends and the host part begins.

Key Terms:

IPv4 Network ID Host ID Subnet Mask Subnetting CIDR Notation Loopback Address Wildcard Address Broadcast Address INADDR_ANY INADDR_LOOPBACK

1. Structure of an IPv4 Address

An IPv4 address is 32 bits wide. It is divided into a Network ID portion and a Host ID portion. The split point is determined by the subnet mask.

Network ID (24 bits) Host ID (8 bits)
192 168 1 10
Full Address: 192.168.1.10  |  Subnet Mask: /24 = 255.255.255.0

In CIDR notation (Classless Inter-Domain Routing), the address is written as 192.168.1.10/24 where /24 means the first 24 bits form the Network ID. This gives 254 usable host addresses (256 minus 2 reserved).

2. Reserved Addresses in a Subnet

In any subnet, two addresses are always reserved and cannot be assigned to any host:

Address Example (in /24 network) Meaning
Network Address
(Host ID = all 0s)
204.152.189.0 Identifies the network itself. Cannot be assigned to a host.
Broadcast Address
(Host ID = all 1s)
204.152.189.255 Sends a packet to ALL hosts on the subnet simultaneously.

For the network 204.152.189.0/24, valid host addresses run from 204.152.189.1 to 204.152.189.254 — that is 254 usable addresses.

3. Special IPv4 Addresses

Address C Constant Purpose Use Case
127.0.0.1 INADDR_LOOPBACK Loopback address (localhost) Test client-server on same machine. Packet never leaves the host.
0.0.0.0 INADDR_ANY Wildcard address Server listens on ALL network interfaces of a multihomed host.
x.x.x.255 Broadcast address Send to all hosts on a subnet simultaneously.

Loopback Address in Action

When you send data to 127.0.0.1, the kernel never places the packet on the wire. It loops it back internally. This is extremely useful when developing and testing socket programs — both the client and server run on the same machine.

Wildcard Address — INADDR_ANY

A multihomed host is a computer with multiple network interfaces (e.g., eth0 with 192.168.1.5 and eth1 with 10.0.0.5). If a server binds to a specific IP, it only receives packets arriving on that interface. Binding to INADDR_ANY (0.0.0.0) allows the server to receive packets from any of the host’s network interfaces.

Client A
192.168.1.100
Multihomed Server

eth0: 192.168.1.5
eth1: 10.0.0.5

Bound to INADDR_ANY
Accepts from BOTH

Client B
10.0.0.20

4. Subnetting — Dividing a Network

Subnetting allows an organization to divide its assigned IP block into smaller sub-networks. Instead of having one big flat network, you create multiple smaller segments (subnets), each identified by an extended network ID = Network ID + Subnet ID.

Network ID (24 bits) Subnet ID (4 bits) Host ID (4 bits)
204 152 189 0001 0000
Extended Network ID = 204.152.189.16/28  (Subnet 1 = 0001, Host part = 0000) Host

In this example, we took the assigned block 204.152.189.0/24 and split the 8-bit Host ID into a 4-bit Subnet ID and a 4-bit Host ID. The subnet mask becomes /28 (28 leading 1s = 255.255.255.240).

Subnets Created

Subnet ID (4 bits) Network Address Usable Range Broadcast
0001 (1) 204.152.189.16/28 .17 – .30 204.152.189.31
0010 (2) 204.152.189.32/28 .33 – .46 204.152.189.47
… (up to 14)

5. Coding Example – Using INADDR_ANY and INADDR_LOOPBACK

In Linux socket programming, these constants are defined in <netinet/in.h>. Here is how they are used when creating a TCP server:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PORT 8080

int main() {
    int server_fd;
    struct sockaddr_in addr;

    /* Step 1: Create a TCP socket */
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    /* Step 2: Fill in address structure */
    memset(&addr, 0, sizeof(addr));
    addr.sin_family      = AF_INET;
    addr.sin_port        = htons(PORT);

    /*
     * INADDR_ANY = 0.0.0.0
     * The server will accept connections on ALL interfaces.
     * Change to INADDR_LOOPBACK (127.0.0.1) to accept
     * only local (loopback) connections.
     */
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    /* OR: addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); */

    /* Step 3: Bind the socket to the address */
    if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
        perror("bind");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    printf("Server listening on ALL interfaces, port %d\n", PORT);

    /* Step 4: Listen and accept (simplified) */
    listen(server_fd, 5);

    /* ... accept() loop goes here ... */

    close(server_fd);
    return 0;
}

Key points:

  • htonl() converts the constant from host byte order to network byte order (big-endian).
  • AF_INET specifies IPv4. Use AF_INET6 for IPv6.
  • INADDR_ANY binds to all interfaces — ideal for production servers.
  • INADDR_LOOPBACK restricts to local connections — ideal for testing.

Interview Questions – IPv4 Addresses & Subnetting
Q1. What is the difference between Network ID and Host ID in an IPv4 address?The Network ID identifies which network a device belongs to. The Host ID identifies the specific device within that network. The subnet mask determines how many bits are used for each part. For example, in 192.168.1.10/24, the first 24 bits (192.168.1) are the Network ID and the last 8 bits (.10) are the Host ID.

Q2. Why are two addresses in every subnet reserved and cannot be assigned to hosts?The first address (Host ID all zeros) is the network address — it identifies the subnet itself in routing tables. The last address (Host ID all ones) is the broadcast address — sending to this address delivers the packet to all hosts on the subnet. Neither can be used for actual host communication.

Q3. What is INADDR_ANY and why is it important for a server socket?INADDR_ANY (0.0.0.0) is the IPv4 wildcard address. When a server binds to it, the server accepts incoming connections on all network interfaces of the host. This is important on multihomed hosts (multiple NICs) so clients connecting via any interface can be served. Without it, the server would only listen on one specific IP address.

Q4. What is the loopback address and what happens when you send a packet to it?The loopback address is 127.0.0.1 (hostname: localhost), defined by constant INADDR_LOOPBACK. When a packet is sent to this address, the Linux kernel never transmits it on the wire — it immediately loops the data back as input to the same host. This allows testing client-server applications without any physical network.

Q5. What is subnetting and what problem does it solve?Subnetting divides an organization’s IP block into smaller sub-networks by splitting the Host ID portion of the address into a Subnet ID and a smaller Host ID. It solves the problem of an organization operating multiple separate internal networks — each subnet gets its own identity (extended network ID = Network ID + Subnet ID) and can be routed independently, improving security and organization.

Q6. What does the /28 mask in 204.152.189.16/28 mean?The /28 means the first 28 bits of the address are the extended network ID (24 bits Network + 4 bits Subnet). Only 4 bits remain for host addressing, giving 24 = 16 addresses per subnet, with 14 usable (minus network and broadcast). The subnet mask in dotted decimal is 255.255.255.240.

Q7. In a C program, how do you convert INADDR_ANY for use in sockaddr_in?You must use htonl(INADDR_ANY) to convert it to network byte order (big-endian). The sin_addr.s_addr field in struct sockaddr_in expects a 32-bit value in network byte order. Although INADDR_ANY is 0 (and byte order doesn’t matter for zero), always using htonl() is correct practice.

Continue Learning

Next up: IPv6 Addressing — 128-bit addresses, compressed notation, and IPv4-mapped addresses.

Part 2: IPv6 Addresses → EmbeddedPathashala Home

Leave a Reply

Your email address will not be published. Required fields are marked *