Chapter 3: Network Configuration and Interfaces


From Theory to Practice

The previous chapters gave you the conceptual framework — OSI layers, IP addressing, IPv6. Now it’s time to get your hands dirty with real network configuration on Linux. This chapter covers the tools and concepts you’ll use daily as a network programmer: interfaces, routing, ARP, DNS, and the commands to manage them all.


Network Interfaces

A network interface is the point of connection between your machine and a network. It can be a physical device (Ethernet card, Wi-Fi adapter) or a virtual construct (loopback, bridge, VLAN interface, VPN tunnel).

Listing Interfaces

# Modern approach (iproute2)
ip link show

# Output example:
# 1: lo: <LOOPBACK,UP> mtu 65536 state UNKNOWN
#     link/loopback 00:00:00:00:00:00
# 2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 state UP
#     link/ether aa:bb:cc:dd:ee:ff
# 3: wlan0: <BROADCAST,MULTICAST> mtu 1500 state DOWN
#     link/ether 11:22:33:44:55:66

Key interface types:

Interface Description
lo Loopback — always 127.0.0.1, used for local-only communication
eth0 / enp3s0 Wired Ethernet (naming depends on system configuration)
wlan0 / wlp2s0 Wireless interface
docker0 Docker bridge network
br0 Network bridge
veth* Virtual Ethernet pair (used in containers)
tun0 / tap0 VPN tunnel interfaces

Interface Naming Conventions

Modern Linux uses Predictable Network Interface Names based on firmware, topology, or hardware properties:

You can revert to classic naming (eth0) by adding net.ifnames=0 to your kernel boot parameters.

Bringing Interfaces Up and Down

# Bring an interface up
sudo ip link set eth0 up

# Bring an interface down
sudo ip link set eth0 down

# Check interface status
ip link show eth0

Configuring IP Addresses

Viewing Addresses

# Show all addresses
ip addr show

# Show addresses for a specific interface
ip addr show dev eth0

# Show only IPv4
ip -4 addr show

# Show only IPv6
ip -6 addr show

Adding and Removing Addresses

# Add an IPv4 address
sudo ip addr add 192.168.1.100/24 dev eth0

# Add an IPv6 address
sudo ip addr add 2001:db8::1/64 dev eth0

# Remove an address
sudo ip addr del 192.168.1.100/24 dev eth0

These changes are temporary — they are lost on reboot. For persistent configuration, use your distribution’s network manager.

Persistent Configuration with NetworkManager

Most desktop Linux distributions use NetworkManager. The CLI tool is nmcli:

# Show all connections
nmcli connection show

# Show device status
nmcli device status

# Set a static IP
nmcli connection modify "Wired connection 1" \
  ipv4.method manual \
  ipv4.addresses 192.168.1.100/24 \
  ipv4.gateway 192.168.1.1 \
  ipv4.dns "8.8.8.8,8.8.4.4"

# Apply changes
nmcli connection up "Wired connection 1"

On servers, systemd-networkd or netplan (Ubuntu) are common alternatives:

# /etc/netplan/01-config.yaml (Ubuntu/netplan)
network:
  version: 2
  ethernets:
    eth0:
      addresses:
        - 192.168.1.100/24
      gateway4: 192.168.1.1
      nameservers:
        addresses:
          - 8.8.8.8
          - 8.8.4.4
sudo netplan apply

Routing

What is Routing?

Routing is the process of determining the path a packet takes from source to destination. Every host has a routing table that tells it where to send packets based on their destination address.

Viewing the Routing Table

# Show the routing table
ip route show

# Example output:
# default via 192.168.1.1 dev eth0 proto dhcp metric 100
# 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.42
# 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1

Reading the output:

Managing Routes

# Add a static route
sudo ip route add 10.0.0.0/8 via 192.168.1.254 dev eth0

# Add a default gateway
sudo ip route add default via 192.168.1.1

# Delete a route
sudo ip route del 10.0.0.0/8

# Show the route to a specific destination
ip route get 8.8.8.8

How Routing Decisions Work

When your machine sends a packet, the kernel follows this process:

  1. Check the routing table for the most specific match (longest prefix) for the destination IP
  2. If a match is found, send the packet to the specified next-hop gateway or directly to the destination via the specified interface
  3. If no match is found, use the default route
  4. If no default route exists, return a “network unreachable” error

ARP — Address Resolution Protocol

ARP maps Layer 3 addresses (IP) to Layer 2 addresses (MAC) on the local network. When your machine wants to send a packet to 192.168.1.1, it needs to know the MAC address of that device.

ARP Process

  1. Host sends an ARP Request broadcast: “Who has 192.168.1.1? Tell 192.168.1.42”
  2. The device with IP 192.168.1.1 responds with an ARP Reply: “192.168.1.1 is at aa:bb:cc:dd:ee:ff”
  3. The host caches this mapping in its ARP table

Viewing and Managing the ARP Table

# Show ARP table
ip neigh show

# Example output:
# 192.168.1.1 dev eth0 lladdr aa:bb:cc:dd:ee:ff REACHABLE
# 192.168.1.5 dev eth0 lladdr 11:22:33:44:55:66 STALE

# Add a static ARP entry
sudo ip neigh add 192.168.1.200 lladdr 00:aa:bb:cc:dd:ee dev eth0

# Delete an ARP entry
sudo ip neigh del 192.168.1.200 dev eth0

# Flush the ARP cache
sudo ip neigh flush all

ARP entries have states: REACHABLE (recently confirmed), STALE (not recently confirmed), DELAY (confirmation pending), FAILED (resolution failed).


DNS Resolution

The Domain Name System (DNS) translates human-readable hostnames (example.com) to IP addresses (93.184.216.34). As a network programmer, you’ll interact with DNS constantly.

How DNS Resolution Works

  1. Application calls getaddrinfo("example.com")
  2. The system checks /etc/hosts for a static mapping
  3. If not found, it queries the DNS resolver configured in /etc/resolv.conf
  4. The resolver contacts DNS servers (recursive query), walking the hierarchy: root → TLD (.com) → authoritative server
  5. The IP address is returned and cached

DNS Configuration Files

# View DNS resolver configuration
cat /etc/resolv.conf

# Example:
# nameserver 8.8.8.8
# nameserver 8.8.4.4
# search mycompany.local

# View static hostname mappings
cat /etc/hosts

# Example:
# 127.0.0.1   localhost
# 192.168.1.10 devserver.local devserver

DNS Lookup Tools

# Simple lookup
host example.com

# Detailed lookup
dig example.com

# Query a specific DNS server
dig @8.8.8.8 example.com

# Reverse DNS lookup
dig -x 93.184.216.34

# Trace the full resolution path
dig +trace example.com

DNS Resolution in Python

import socket

# Resolve hostname to IP
result = socket.getaddrinfo("example.com", 80)
for family, socktype, proto, canonname, addr in result:
    print(f"{socket.AddressFamily(family).name}: {addr}")

Full example: code/dns_resolver.py


Network Diagnostics Primer

Here’s a quick reference for the essential diagnostic commands you’ll use throughout the book:

Command Purpose Layer
ip link show Interface status and MAC addresses L2
ip addr show IP addresses on interfaces L3
ip route show Routing table L3
ip neigh show ARP/NDP neighbor table L2–L3
ping Test reachability (ICMP echo) L3
traceroute / tracepath Show the path to a destination L3
ss -tuln List listening TCP/UDP ports L4
dig / host / nslookup DNS queries L7
curl HTTP requests L7
tcpdump Capture packets All

Querying Network Info from Python

Python gives you programmatic access to most of this information:

import socket
import struct
import fcntl

def get_ip_address(ifname: str) -> str:
    """Get the IPv4 address of a network interface."""
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(), 0x8915,  # SIOCGIFADDR
        struct.pack('256s', ifname.encode()[:15])
    )[20:24])

For a more portable approach, the netifaces or psutil libraries are recommended:

import psutil

for name, addrs in psutil.net_if_addrs().items():
    for addr in addrs:
        if addr.family == socket.AF_INET:
            print(f"{name}: {addr.address}/{addr.netmask}")

Full example: code/network_info.py


Key Takeaways


← Previous: IP Addressing and IPv6 Table of Contents Next: Switching, Routing, and VLANs →