Networking

Linux Networking Tools

The IP/TCP/UDP pages in this notebook describe the protocols. This page is the other half: the actual commands to run on a real Linux machine to see your own interfaces, addresses, ARP cache, open sockets, and link status — the tools you reach for the moment something isn't connecting.

Quick reference
What it is
The everyday Linux command set for inspecting network interfaces, addresses, neighbor/ARP state, connectivity, and open sockets.
Mental model
Each command reads one layer: ip link/ethtool for the wire, ip addr for IP addressing, ip neigh/arp for IP↔MAC mapping, ss/netstat for what's listening or connected above that.
Key numbers
iproute2 (ip, ss) has been the standard toolset for over a decade; ifconfig/netstat (net-tools) still work on most distros but are considered legacy.
Reach for it when
A device isn't showing up on the network, a service isn't reachable, or you need to know what's actually listening on a box.

Interfaces and addresses

ip addr show (short: ip a) is the first command to run on any box — it lists every network interface and every address bound to it.

$ ip addr show
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP
    link/ether 3c:97:0e:8a:1b:44 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.42/24 brd 192.168.1.255 scope global dynamic eth0
    inet6 fe80::3e97:eff:fe8a:1b44/64 scope link

3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN
    link/ether 9c:5c:8e:22:04:11 brd ff:ff:ff:ff:ff:ff

Reading this line by line: UP/DOWN in the flags is whether the interface is administratively enabled; LOWER_UP means a physical link is actually detected (cable plugged in, or associated to an AP); link/ether is the interface's MAC address; inet 192.168.1.42/24 is its IPv4 address and subnet mask in CIDR form. The older, still-common equivalent is ifconfig — functionally similar output, considered legacy but not going anywhere.

# bring an interface up/down, or set an address by hand
sudo ip link set eth0 up
sudo ip addr add 192.168.1.50/24 dev eth0

# what's this box's default route, and which interface does it use?
ip route show

MAC vs. IP: two addresses, two layers

These get confused because every packet you send carries both, but they answer different questions at different layers. A MAC address (e.g. 3c:97:0e:8a:1b:44) is a link-layer identifier — it means something only on the local physical segment (the same Ethernet/Wi-Fi broadcast domain) and normally never changes for a given NIC. An IP address is a network-layer identifier — it's what makes a device reachable across routers, from anywhere on the internet, and it can change (DHCP lease, moving networks) without the hardware changing at all. A frame only ever needs a MAC address for its next hop; an IP packet carries the same source/destination IP all the way to the final destination, however many hops that takes.

Each networking layer has its own Linux command for inspecting it: sockets and ports, IP addressing, the ARP/neighbor cache, and the physical link Sockets & ports ss -tunlp · netstat -tunlp IP addresses & routes ip addr · ip route ARP / neighbor cache ip neigh · arp -a Link layer (the NIC itself) ip link · ethtool eth0
Top to bottom is roughly "closer to the application" to "closer to the wire" — when something isn't working, checking from the bottom up (is the link even up?) usually finds the problem faster.

ARP: resolving IP to MAC on the local segment

Sending an IP packet to another host on the same subnet still requires an Ethernet frame, and an Ethernet frame needs a destination MAC address — but application code only ever deals in IP addresses. ARP (Address Resolution Protocol) is what bridges the two: to find the MAC address for an IP on the local segment, a host broadcasts "who has this IP?" to everyone on the LAN, and only the owner replies directly.

Host A broadcasts an ARP request that every host on the LAN receives; only the host owning that IP address replies directly with its MAC address Host A — 192.168.1.10 Host B — 192.168.1.20 ARP request — "who has 192.168.1.20?" (broadcast, ff:ff:ff:ff:ff:ff) ARP reply — "192.168.1.20 is at 9c:5c:8e:22:04:11" (unicast) Host A now caches this mapping — visible with ip neigh show
Every other host on the LAN also sees the broadcast request and silently ignores it — only the host whose address matches replies.
$ ip neigh show
192.168.1.20 dev eth0 lladdr 9c:5c:8e:22:04:11 REACHABLE
192.168.1.1  dev eth0 lladdr aa:bb:cc:00:11:22 STALE

# the older net-tools equivalent
$ arp -a

REACHABLE means the kernel has recently confirmed this entry is still good; STALE means it's cached but hasn't been re-verified — the kernel will re-ARP before relying on it again if traffic to that address resumes.

Checking connectivity: ping and traceroute

ping sends ICMP echo-request packets and waits for echo-reply — the simplest possible "is anyone there, and how far away" check. traceroute (or tracepath, which needs no special privileges) shows every router hop along the way, which narrows down where a connection is failing rather than just that it is.

$ ping -c 3 192.168.1.20
64 bytes from 192.168.1.20: icmp_seq=1 ttl=64 time=0.412 ms
64 bytes from 192.168.1.20: icmp_seq=2 ttl=64 time=0.389 ms
64 bytes from 192.168.1.20: icmp_seq=3 ttl=64 time=0.401 ms

$ traceroute 8.8.8.8
 1  192.168.1.1 (192.168.1.1)  1.203 ms
 2  10.20.0.1 (10.20.0.1)      8.771 ms
 3  8.8.8.8 (8.8.8.8)          14.902 ms

A shrinking ttl on the reply and a hop count that stops increasing partway through a traceroute are both signs of where to look next — a firewall dropping ICMP, a routing loop, or the actual point of failure on a multi-hop path.

Open sockets: ss and netstat

ss (socket statistics) lists sockets on the box — what's listening, what's connected, and to/from where — and is the modern, faster replacement for netstat, which still works identically for this purpose on most systems.

$ ss -tunlp
Netid  State   Local Address:Port   Peer Address:Port  Process
tcp    LISTEN  0.0.0.0:22           0.0.0.0:*           sshd
tcp    LISTEN  127.0.0.1:8143       0.0.0.0:*           python3
tcp    ESTAB   192.168.1.42:22      192.168.1.5:51422   sshd

# -t = TCP, -u = UDP, -n = numeric (skip DNS lookups), -l = listening only, -p = show process

LISTEN is a socket waiting for incoming connections; ESTAB (established) is an active, connected TCP session. A service that's "not reachable" but shows nothing here is usually the actual problem — it isn't running, or it bound to 127.0.0.1 instead of 0.0.0.0 and so isn't listening on the interface a remote client would reach it through.

ethtool reaches below IP entirely, into the NIC driver itself — link speed, duplex, and whether a physical link is even detected, independent of anything IP-layer tools can see.

$ ethtool eth0
Settings for eth0:
        Speed: 1000Mb/s
        Duplex: Full
        Auto-negotiation: on
        Link detected: yes

Link detected: no with a correct-looking ip addr configuration is a strong sign the problem is physical — a bad cable, an unplugged connector, or a switch port that's down — before anything in the IP or TCP layers even gets a chance to matter.

Real-world applications

Gotchas

Field notes