A TCP client/server pair that collects a Linux host's network interface
configuration and returns it as structured JSON.
A complete exchange captured in Wireshark — three-way handshake, a single 415-byte push of JSON, then a clean four-way teardown.
Programming for Networks — BSc (Hons) Cloud Computing, TU Dublin. Cathal Flood
The server listens on a TCP port. When a client connects, it enumerates every network
interface on the host, shells out to ifconfig for each one, parses the output for the
values that matter, and sends the whole lot back as a single JSON document before closing
the connection.
The point of the exercise was to work at the socket layer directly — no HTTP library, no framework — and to be able to prove what went over the wire.
- Interface discovery —
socket.if_nameindex()enumerates interfaces at runtime, so the server adapts to whatever host it runs on rather than using a hardcoded list. - Structured extraction — regular expressions pull MTU, IPv4 address and MAC address
out of unstructured
ifconfigtext. - Fault isolation — an interface that fails to parse returns
"unknown"for its fields instead of taking down the response for every other interface. - JSON over raw sockets — the payload is serialised, encoded and sent with
sendall(), so a partial write can't silently truncate the response.
Server (left) and client (right).
The server holds the connection open only as long as it takes to gather and send the data,
then closes it — visible in the capture above as the FIN, ACK immediately following the
415-byte PSH, ACK. Detailed flowcharts for each side are in docs/.
The server needs pexpect, and expects ifconfig to be available:
pip install -r requirements.txtStart the server on the machine you want to inspect — it binds to 0.0.0.0:6794:
python3 server.pyThen query it from anywhere that can reach that port:
python3 client.py --ip 10.156.5.146 --port 6794{
"hostname": "cathal-VirtualBox",
"Platform": "Linux-4.4.0-142-generic-x86_64-with-Ubuntu-14.04-trusty",
"interfaces": [
{ "interface": "lo", "MTU": "65536", "ip address": "127.0.0.1", "mac address": "unknown" },
{ "interface": "eth0", "MTU": "1500", "ip address": "10.0.2.15", "mac address": "unknown" },
{ "interface": "eth1", "MTU": "1500", "ip address": "192.168.0.235", "mac address": "unknown" }
]
}examples/interface.json holds a response captured from the
running server on the lab VM. It predates the current key names — that iteration emitted
Hostname / IPv4 / MAC where the code above emits hostname / ip address /
mac address — but the values are genuine, and it shows the MAC regex falling through to
unknown on the virtual adapters.
The parsing targets the legacy net-tools format, where ifconfig prints
inet addr:10.0.2.15 and HWaddr 08:00:27:.... That is what shipped on the Ubuntu 14.04
lab image this was written against.
Modern distributions print inet 10.0.2.15 with no addr: prefix, and report the MAC as
ether rather than HWaddr — so on a current system the IPv4 and MAC regexes fall through
to "unknown" while MTU still matches. Supporting both would mean widening the patterns to
accept either spelling; iproute2 or psutil would be the better foundation for anything
beyond this exercise.
server.py TCP server - interface discovery, parsing, JSON response
client.py CLI client - argparse, connect, receive, pretty-print
requirements.txt pexpect
examples/
interface.json A captured server response
docs/
server-block.png Server block diagram
client-block.png Client block diagram
server-flow.png Server flowchart
client-flow.png Client flowchart
tcp-flow.png Wireshark flow graph of a full exchange


