Introduction
Python offers powerful capabilities for working with network interfaces, allowing developers to programmatically retrieve network information and configure network settings. This practical skill is valuable for network administrators, system engineers, and developers working on network-related applications.
In this lab, you will learn how to use Python to inspect and manage network interfaces on a Linux system. You will start with basic interface identification, move on to retrieving detailed network information, and finish by monitoring network traffic. By the end of this lab, you will have hands-on experience with Python's networking libraries and be able to apply these skills to real-world networking tasks.
Installing Required Python Packages
Before we can work with network interfaces in Python, we need to install the necessary packages. The two primary packages we will use are:
netifaces: A cross-platform library for retrieving network interface informationpsutil: A library for retrieving system information, including network statistics
Let's start by installing these packages using pip.
Installing the Packages
Open a terminal and run the following command to install the required packages:
pip install netifaces psutil
You should see output indicating the packages are being downloaded and installed. Wait until the installation completes before proceeding.
Verifying the Installation
Let's verify that the packages were installed correctly by creating a simple Python script. Create a new file called check_packages.py in the VSCode editor:
- Click on the "Explorer" icon in the left sidebar (or press Ctrl+E)
- Click the "New File" button
- Name the file
check_packages.py - Add the following code to the file:
try:
import netifaces
import psutil
print("Both packages installed successfully!")
print(f"netifaces version: {netifaces.__version__}")
print(f"psutil version: {psutil.__version__}")
except ImportError as e:
print(f"Error importing packages: {e}")
Save the file by pressing Ctrl+S or selecting "File > Save" from the menu.
Now, run the script by opening a terminal (if not already open) and executing:
python3 check_packages.py
You should see output similar to:
Both packages installed successfully!
netifaces version: 0.11.0
psutil version: 5.9.0
The exact version numbers might be different, but as long as you see the "installed successfully" message, you're ready to proceed to the next step.
Listing Network Interfaces
Now that we have the necessary packages installed, let's start exploring network interfaces. The first step is to identify all available network interfaces on your system.
Creating a Script to List Network Interfaces
Create a new file named list_interfaces.py in the VSCode editor:
- Click on the "Explorer" icon in the left sidebar if it's not already open
- Click the "New File" button
- Name the file
list_interfaces.py - Add the following code:
import netifaces
def list_network_interfaces():
"""List all network interfaces available on the system."""
interfaces = netifaces.interfaces()
print("Available network interfaces:")
for index, interface in enumerate(interfaces, 1):
print(f"{index}. {interface}")
if __name__ == "__main__":
list_network_interfaces()
Save the file by pressing Ctrl+S.
Running the Script
Now let's run the script to see the list of network interfaces on your system:
python3 list_interfaces.py
You should see output similar to:
Available network interfaces:
1. lo
2. eth0
3. docker0
The exact list will depend on your system configuration. Let's understand what these interfaces typically represent:
lo: The loopback interface (localhost)eth0: The primary Ethernet interfacewlan0: The primary wireless interface (if available)docker0: The Docker bridge network interface (if Docker is installed)
Understanding Network Interface Names
Network interface names can vary depending on the operating system and configuration:
- On traditional Linux systems, interfaces are named
eth0,eth1, etc., for Ethernet - On newer systems using predictable network interface names, you might see names like
enp0s3orens33 - Virtual interfaces might have names like
veth...orbr0for bridges
Let's modify our script to provide more details about each interface. Update the list_interfaces.py file with the following code:
import netifaces
def list_network_interfaces():
"""List all network interfaces available on the system with details."""
interfaces = netifaces.interfaces()
print("Available network interfaces:")
for index, interface in enumerate(interfaces, 1):
print(f"{index}. {interface}")
## Try to get addresses for this interface
try:
if netifaces.AF_INET in netifaces.ifaddresses(interface):
ip_info = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]
print(f" IPv4 Address: {ip_info.get('addr', 'None')}")
except ValueError:
print(" No IPv4 address assigned")
if __name__ == "__main__":
list_network_interfaces()
Save the file and run it again:
python3 list_interfaces.py
Now you should see more detailed output that includes the IPv4 address for each interface:
Available network interfaces:
1. lo
IPv4 Address: 127.0.0.1
2. eth0
IPv4 Address: 172.17.0.2
3. docker0
IPv4 Address: 172.17.0.1
This gives us a better understanding of the network interfaces available on the system and their current IP addresses.
Retrieving Detailed Network Interface Information
Now that we can list the available network interfaces, let's create a more comprehensive script to retrieve detailed information about a specific network interface.
Creating a Network Interface Details Script
Create a new file named interface_details.py in the VSCode editor:
- Click the "New File" button in the Explorer pane
- Name the file
interface_details.py - Add the following code:
import netifaces
import sys
def get_interface_details(interface_name):
"""
Retrieve detailed information about a specific network interface.
Args:
interface_name (str): The name of the network interface
Returns:
None: Prints interface details to console
"""
## Check if the interface exists
interfaces = netifaces.interfaces()
if interface_name not in interfaces:
print(f"Error: Interface '{interface_name}' does not exist.")
print(f"Available interfaces: {', '.join(interfaces)}")
return
print(f"\nDetails for interface '{interface_name}':")
print("-" * 50)
## Get addresses for all protocol families
try:
addresses = netifaces.ifaddresses(interface_name)
## IPv4 addresses (AF_INET)
if netifaces.AF_INET in addresses:
ipv4_info = addresses[netifaces.AF_INET][0]
print("IPv4 Information:")
print(f" Address: {ipv4_info.get('addr', 'Not available')}")
print(f" Netmask: {ipv4_info.get('netmask', 'Not available')}")
print(f" Broadcast: {ipv4_info.get('broadcast', 'Not available')}")
else:
print("IPv4 Information: Not available")
## IPv6 addresses (AF_INET6)
if netifaces.AF_INET6 in addresses:
ipv6_info = addresses[netifaces.AF_INET6][0]
print("\nIPv6 Information:")
print(f" Address: {ipv6_info.get('addr', 'Not available')}")
print(f" Netmask: {ipv6_info.get('netmask', 'Not available')}")
print(f" Scope: {ipv6_info.get('scope', 'Not available')}")
else:
print("\nIPv6 Information: Not available")
## MAC address (AF_LINK)
if netifaces.AF_LINK in addresses:
link_info = addresses[netifaces.AF_LINK][0]
print("\nMAC Address Information:")
print(f" Address: {link_info.get('addr', 'Not available')}")
print(f" Broadcast: {link_info.get('broadcast', 'Not available')}")
else:
print("\nMAC Address Information: Not available")
## Gateway information
gateways = netifaces.gateways()
print("\nGateway Information:")
if 'default' in gateways and netifaces.AF_INET in gateways['default']:
gw_addr, gw_interface = gateways['default'][netifaces.AF_INET]
if gw_interface == interface_name:
print(f" Default Gateway: {gw_addr}")
else:
print(" No default gateway for this interface")
else:
print(" No default gateway information available")
except Exception as e:
print(f"Error retrieving interface details: {e}")
if __name__ == "__main__":
## If an interface name is provided as a command-line argument, use it
## Otherwise, use the first interface from the list (excluding 'lo')
if len(sys.argv) > 1:
interface_name = sys.argv[1]
else:
interfaces = [i for i in netifaces.interfaces() if i != 'lo']
if interfaces:
interface_name = interfaces[0]
print(f"No interface specified, using {interface_name}")
else:
print("No network interfaces available")
sys.exit(1)
get_interface_details(interface_name)
Save the file by pressing Ctrl+S.
Running the Script
Now let's run the script to see detailed information about a specific network interface:
python3 interface_details.py eth0
Replace eth0 with one of the interfaces you saw in the previous step if needed.
You should see output similar to:
Details for interface 'eth0':
--------------------------------------------------
IPv4 Information:
Address: 172.17.0.2
Netmask: 255.255.0.0
Broadcast: 172.17.255.255
IPv6 Information: Not available
MAC Address Information:
Address: 02:42:ac:11:00:02
Broadcast: ff:ff:ff:ff:ff:ff
Gateway Information:
Default Gateway: 172.17.0.1
You can also run the script without specifying an interface name, and it will automatically select the first non-loopback interface:
python3 interface_details.py
This script provides a comprehensive view of the network interface's configuration, including:
- IPv4 address, netmask, and broadcast address
- IPv6 address (if available)
- MAC address
- Default gateway information
Understanding this detailed information is essential for network troubleshooting and configuration.
Exploring the netifaces Module Constants
The netifaces module uses constants to represent different address families. Let's create a quick script to understand these constants. Create a new file named netifaces_constants.py:
import netifaces
## Print all address family constants
print("Address Family Constants in netifaces module:")
print(f"AF_INET (IPv4): {netifaces.AF_INET}")
print(f"AF_INET6 (IPv6): {netifaces.AF_INET6}")
print(f"AF_LINK (MAC/Hardware): {netifaces.AF_LINK}")
## Additional constants that might be available
for name in dir(netifaces):
if name.startswith('AF_'):
print(f"{name}: {getattr(netifaces, name)}")
Save and run this script:
python3 netifaces_constants.py
You should see output like:
Address Family Constants in netifaces module:
AF_INET (IPv4): 2
AF_INET6 (IPv6): 10
AF_LINK (MAC/Hardware): 17
AF_APPLETALK: 5
AF_INET: 2
AF_INET6: 10
AF_IPX: 4
AF_LINK: 17
AF_UNIX: 1
These constants are used in the netifaces module to identify different types of network addresses. Understanding them is helpful when working with the module's functions.
Monitoring Network Interface Traffic
Now that we understand how to retrieve network interface information, let's take it a step further and create a script to monitor network traffic in real-time. This will allow us to see how much data is being sent and received through a specific interface.
Creating a Network Traffic Monitoring Script
Create a new file named monitor_traffic.py in the VSCode editor:
- Click the "New File" button in the Explorer pane
- Name the file
monitor_traffic.py - Add the following code:
import psutil
import time
import sys
import netifaces
def bytes_to_readable(bytes_count):
"""Convert bytes to a human-readable format (KB, MB, GB)"""
units = ['B', 'KB', 'MB', 'GB', 'TB']
unit_index = 0
converted_value = float(bytes_count)
while converted_value >= 1024 and unit_index < len(units) - 1:
converted_value /= 1024
unit_index += 1
return f"{converted_value:.2f} {units[unit_index]}"
def monitor_network_traffic(interface_name, interval=1, iterations=10):
"""
Monitor network traffic on a specific interface for a given number of iterations.
Args:
interface_name (str): Name of the network interface to monitor
interval (int): Time interval between measurements in seconds
iterations (int): Number of measurements to take
"""
## Verify interface exists
if interface_name not in netifaces.interfaces():
print(f"Error: Interface '{interface_name}' does not exist.")
print(f"Available interfaces: {', '.join(netifaces.interfaces())}")
return
print(f"Monitoring network traffic on {interface_name} (Ctrl+C to stop)")
print("-" * 80)
print(f"{'Time':<12} {'Bytes Sent':<15} {'Bytes Received':<15} {'Packets Sent':<15} {'Packets Received':<15}")
print("-" * 80)
try:
## Get initial stats
net_io_counters = psutil.net_io_counters(pernic=True)
if interface_name not in net_io_counters:
print(f"Error: Cannot get stats for interface '{interface_name}'")
return
prev_stats = net_io_counters[interface_name]
prev_bytes_sent = prev_stats.bytes_sent
prev_bytes_recv = prev_stats.bytes_recv
prev_packets_sent = prev_stats.packets_sent
prev_packets_recv = prev_stats.packets_recv
## Monitor for the specified number of iterations
for i in range(iterations):
## Wait for the specified interval
time.sleep(interval)
## Get new stats
net_io_counters = psutil.net_io_counters(pernic=True)
new_stats = net_io_counters[interface_name]
## Calculate differences
bytes_sent_diff = new_stats.bytes_sent - prev_bytes_sent
bytes_recv_diff = new_stats.bytes_recv - prev_bytes_recv
packets_sent_diff = new_stats.packets_sent - prev_packets_sent
packets_recv_diff = new_stats.packets_recv - prev_packets_recv
## Update previous values
prev_bytes_sent = new_stats.bytes_sent
prev_bytes_recv = new_stats.bytes_recv
prev_packets_sent = new_stats.packets_sent
prev_packets_recv = new_stats.packets_recv
## Print the current stats
current_time = time.strftime("%H:%M:%S")
print(f"{current_time:<12} {bytes_to_readable(bytes_sent_diff):<15} "
f"{bytes_to_readable(bytes_recv_diff):<15} {packets_sent_diff:<15} "
f"{packets_recv_diff:<15}")
except KeyboardInterrupt:
print("\nMonitoring stopped by user")
except Exception as e:
print(f"Error during monitoring: {e}")
print("\nTraffic summary for this session:")
print(f"Total monitored time: {iterations * interval} seconds")
if __name__ == "__main__":
## Get the interface name from command line arguments or use a default
if len(sys.argv) > 1:
interface_name = sys.argv[1]
else:
## Try to find a non-loopback interface
interfaces = [i for i in netifaces.interfaces() if i != 'lo']
if interfaces:
interface_name = interfaces[0]
print(f"No interface specified, using {interface_name}")
else:
print("No network interfaces available")
sys.exit(1)
## Get number of iterations from command line (default: 10)
iterations = 10
if len(sys.argv) > 2:
try:
iterations = int(sys.argv[2])
except ValueError:
print(f"Invalid iterations value: {sys.argv[2]}. Using default: 10")
## Monitor the network traffic
monitor_network_traffic(interface_name, iterations=iterations)
Save the file by pressing Ctrl+S.
Running the Traffic Monitoring Script
Now let's run the script to monitor network traffic on a specific interface:
python3 monitor_traffic.py eth0
Replace eth0 with the appropriate interface name from your system if needed.
The script will display a table showing the amount of data sent and received over the network interface, updating once per second for 10 iterations:
Monitoring network traffic on eth0 (Ctrl+C to stop)
--------------------------------------------------------------------------------
Time Bytes Sent Bytes Received Packets Sent Packets Received
--------------------------------------------------------------------------------
14:25:30 0.00 B 156.00 B 0 2
14:25:31 0.00 B 0.00 B 0 0
14:25:32 0.00 B 0.00 B 0 0
14:25:33 456.00 B 1.24 KB 3 5
14:25:34 0.00 B 0.00 B 0 0
14:25:35 0.00 B 0.00 B 0 0
14:25:36 66.00 B 102.00 B 1 1
14:25:37 0.00 B 0.00 B 0 0
14:25:38 0.00 B 0.00 B 0 0
14:25:39 0.00 B 0.00 B 0 0
Traffic summary for this session:
Total monitored time: 10 seconds
You can also specify the number of iterations as a second command-line argument:
python3 monitor_traffic.py eth0 5
This would monitor traffic for 5 iterations instead of the default 10.
Generating Some Network Traffic
To see the monitoring script in action with actual traffic, we can open a second terminal and generate some network traffic. Let's create a simple script to do this:
Create a new file named generate_traffic.py:
import requests
import time
import sys
def generate_traffic(iterations=5, delay=1):
"""Generate some network traffic by making HTTP requests"""
print(f"Generating network traffic over {iterations} iterations...")
for i in range(iterations):
try:
## Make a GET request to a public API
response = requests.get("https://httpbin.org/get")
print(f"Request {i+1}/{iterations}: Status {response.status_code}, "
f"Size {len(response.content)} bytes")
## Wait before the next request
if i < iterations - 1:
time.sleep(delay)
except Exception as e:
print(f"Error making request: {e}")
print("Traffic generation complete")
if __name__ == "__main__":
## Get number of iterations from command line (default: 5)
iterations = 5
if len(sys.argv) > 1:
try:
iterations = int(sys.argv[1])
except ValueError:
print(f"Invalid iterations value: {sys.argv[1]}. Using default: 5")
generate_traffic(iterations)
You'll need to install the requests library first:
pip install requests
Now run the monitoring script in one terminal:
python3 monitor_traffic.py eth0 15
And in a separate terminal, run the traffic generation script:
python3 generate_traffic.py
You should now see the network activity captured by the monitoring script as the traffic generation script makes HTTP requests.
This exercise demonstrates how you can use Python to monitor network interface activity in real-time, which is useful for diagnosing network issues, monitoring bandwidth usage, and understanding network traffic patterns.
Summary
In this lab, you have gained practical experience with Python's network interface management capabilities. Here's what you accomplished:
Set up the environment: You installed and configured the necessary Python packages (
netifacesandpsutil) for working with network interfaces.Listed network interfaces: You created a script to identify all available network interfaces on your system and display basic information about them.
Retrieved detailed interface information: You wrote a comprehensive script to extract detailed configuration information from network interfaces, including IP addresses, MAC addresses, and gateway information.
Monitored network traffic: You implemented a real-time network traffic monitoring tool that tracks data sent and received over a specific interface.
These skills form the foundation for more advanced network management tasks in Python, such as:
- Automating network configuration changes
- Building network monitoring dashboards
- Creating network diagnostics tools
- Developing network security applications
By understanding how to interact with network interfaces programmatically, you now have the capability to build custom networking tools tailored to your specific requirements. This knowledge is especially valuable for system administrators, network engineers, and developers working on networked applications.



