Supercharge Your Network Operations with Netutils
Supercharge Your Network Operations with Netutils
Introduction
Netutils is a Python library built to simplify everyday network automation. It provides a set of utilities and classes that take care of tedious tasks engineers would rather avoid—like using regular expressions to match and standardize interface names—so you can focus on more valuable work.
What Is Netutils?
Netutils is a Python package that offers:
- Interface name standardization (i.e., it standardizes network interface names across different platforms)
- MAC address formatting and validation
- IP address calculation and subnet operations (more lightweight than the ipaddress standard library and more network automation focused)
- Network protocol helpers that convert port numbers to protocol names, protocol names to port numbers, and other helper functions
- Reliable network utility functions without reinventing the wheel
- And much more!
Check out common use cases in the Netutils Documentation
Who Is Netutils For?
Netutils is designed for:
- Network Engineers who are automating their infrastructure
- DevOps Engineers working with network automation
- Python Developers building network tools
- Anyone who needs to perform common network operations in Python
Installation
Let’s work on some simple examples using netutils. Of course, we need to install netutils, preferably in a virtual environment:
#pip install netutils
Examples
1. Interface name standardization
As engineers, we know that Gi0/1 and GigabitEthernet0/1, or Eth1 and Ethernet1 refer to the same interface. Computers, however, treat them as different values. In this example, we’ll show how Netutils can standardize interface names, converting shorthand variations into a consistent format.
#interface_example.py
#!/usr/bin/env python3
"""Examples of using netutils interface name standardization functions.
This script demonstrates how to use netutils to standardize and abbreviate
network interface names across different platforms.
"""
from netutils.interface import canonical_interface_name, abbreviated_interface_name
def main():
"""Run interface name standardization examples."""
print("Interface Name Standardization Examples:")
print("-" * 40)
# Convert interface names to canonical form
print("\nCanonical Interface Names:")
print(f"Gi0/1 -> {canonical_interface_name('Gi0/1')}")
print(f"Eth1 -> {canonical_interface_name('Eth1')}")
print(f"Po40 -> {canonical_interface_name('Po40')}")
print(f"Lo10 -> {canonical_interface_name('Lo10')}")
# Convert to abbreviated form
print("\nAbbreviated Interface Names:")
print(f"GigabitEthernet0/1 -> {abbreviated_interface_name('GigabitEthernet0/1')}")
print(f"Port-channel40 -> {abbreviated_interface_name('Port-channel40')}")
if __name__ == "__main__":
main()
Here is the output of the example
# python interface_examples.py
Interface Name Standardization Examples:
----------------------------------------
Canonical Interface Names:
Gi0/1 -> GigabitEthernet0/1
Eth1 -> Ethernet1
Po40 -> Port-channel40
Lo10 -> Loopback10
Abbreviated Interface Names:
GigabitEthernet0/1 -> Gi0/1
Port-channel40 -> Po40
2. IP address operations
The following example demonstrates various common IP address operations using the netutils library, including:
- Testing whether or not strings are valid IP addresses for both IPv4 and IPv6
- Converting IP addresses to different formats between binary and hexadecimal representations
- Finding a usable IP address range within a network
- Checking if a string represents valid IP ranges in formats such as 10.1.1.1 – 10.1.1.10
- Determining whether a specific IP address falls within a network subnet
#ip_examples.py
#!/usr/bin/env python3
"""Examples of using netutils IP address operations.
This script demonstrates various IP address operations using the netutils library.
"""
import ipaddress
from netutils.ip import (
is_ip,
ip_to_bin,
ip_to_hex,
get_usable_range,
get_first_usable,
is_network,
is_ip_range,
is_ip_within,
)
def main():
"""Run IP address operation examples."""
print("IP Address Operations Examples:")
print("-" * 40)
# IP address validation
print("\nIP Address Validation:")
test_ips = [
"10.1.1.1",
"2001:db8::1",
"256.1.1.1", # Invalid IPv4
"not.an.ip",
]
for ip in test_ips:
if is_ip(ip):
ip_obj = ipaddress.ip_address(ip)
version = "IPv4" if ip_obj.version == 4 else "IPv6"
print(f"{ip} is a valid {version} address")
else:
print(f"{ip} is not a valid IP address")
# IP address conversion
print("\nIP Address Conversion:")
ip = "10.1.1.1"
print(f"IP: {ip}")
print(f"Binary: {ip_to_bin(ip)}")
print(f"Hexadecimal: {ip_to_hex(ip)}")
# Network range operations
print("\nNetwork Range Operations:")
network = "10.1.1.0/24"
print(f"Network: {network}")
print(f"Usable range: {get_usable_range(network)}")
print(f"First usable IP: {get_first_usable(network)}")
# IP range validation
print("\nIP Range Validation:")
ranges = [
"10.1.1.1-10.1.1.10",
"10.1.1.10-10.1.1.1", # Invalid (end < start)
"not.a.range",
]
for ip_range in ranges:
if is_ip_range(ip_range):
print(f"{ip_range} is a valid IP range")
else:
print(f"{ip_range} is not a valid IP range")
# IP within range check
print("\nIP Within Range Check:")
ip = "10.1.1.5"
ranges = [
"10.1.1.0/24",
"10.1.1.1-10.1.1.10",
"10.1.2.0/24",
]
for range_str in ranges:
if is_ip_within(ip, range_str):
print(f"{ip} is within {range_str}")
else:
print(f"{ip} is not within {range_str}")
if __name__ == "__main__":
main()
Below is the executed output from the script above:
# python ip_examples.py
IP Address Operations Examples:
----------------------------------------
IP Address Validation:
10.1.1.1 is a valid IPv4 address
2001:db8::1 is a valid IPv6 address
256.1.1.1 is not a valid IP address
not.an.ip is not a valid IP address
IP Address Conversion:
IP: 10.1.1.1
Binary: 00001010000000010000000100000001
Hexadecimal: 0a010101
Network Range Operations:
Network: 10.1.1.0/24
Usable range: 10.1.1.1 - 10.1.1.254
First usable IP: 10.1.1.1
IP Range Validation:
10.1.1.1-10.1.1.10 is a valid IP range
10.1.1.10-10.1.1.1 is not a valid IP range
not.a.range is not a valid IP range
IP Within Range Check:
10.1.1.5 is within 10.1.1.0/24
10.1.1.5 is within 10.1.1.1-10.1.1.10
10.1.1.5 is not within 10.1.2.0/24
3. MAC address operations
The following example demonstrates various common MAC address operations using the netutils library, including:
- Testing if a string is a valid MAC address in different formats, for example, colon-separated, dash-separated, dot-separated, etc.
- Converting MAC addresses between different formats, such as from 00:11:22:33:44:55 to 00-11-22-33-44-55
- Using the Organizational Unique Identifier (OUI) within the MAC address to look up the manufacturer
#mac_examples.py
#!/usr/bin/env python3
"""Examples of using netutils MAC address operations.
This script demonstrates various MAC address operations including validation,
formatting, and vendor lookup using netutils.
"""
from netutils.mac import is_valid_mac, mac_to_format, mac_normalize, get_oui
def main():
"""Run MAC address operation examples."""
print("MAC Address Operations Examples:")
print("-" * 40)
# MAC address validation
print("\nMAC Address Validation:")
print(f"is_valid_mac('00:11:22:33:44:55') -> {is_valid_mac('00:11:22:33:44:55')}")
print(f"is_valid_mac('00-11-22-33-44-55') -> {is_valid_mac('00-11-22-33-44-55')}")
print(f"is_valid_mac('0011.2233.4455') -> {is_valid_mac('0011.2233.4455')}")
# MAC address formatting
print("\nMAC Address Formatting:")
mac = "0011.2233.4455"
print(f"Original MAC: {mac}")
print(f"MAC_COLON_TWO -> {mac_to_format(mac, 'MAC_COLON_TWO')}")
print(f"MAC_DASH_TWO -> {mac_to_format(mac, 'MAC_DASH_TWO')}")
print(f"MAC_DOT_TWO -> {mac_to_format(mac, 'MAC_DOT_TWO')}")
print(f"MAC_COLON_FOUR -> {mac_to_format(mac, 'MAC_COLON_FOUR')}")
# MAC address normalization
print("\nMAC Address Normalization:")
print(f"mac_normalize('00:11:22:33:44:55') -> {mac_normalize('00:11:22:33:44:55')}")
# MAC address vendor lookup
print("\nMAC Address Vendor Lookup:")
try:
print(f"get_oui('cc:79:d7:dd:ee:ff') -> {get_oui('cc:79:d7:dd:ee:ff')}")
except ValueError as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()
Here is the output from the script above:
# python mac_examples.py
MAC Address Operations Examples:
----------------------------------------
MAC Address Validation:
is_valid_mac('00:11:22:33:44:55') -> True
is_valid_mac('00-11-22-33-44-55') -> True
is_valid_mac('0011.2233.4455') -> True
MAC Address Formatting:
Original MAC: 0011.2233.4455
MAC_COLON_TWO -> 00:11:22:33:44:55
MAC_DASH_TWO -> 00-11-22-33-44-55
MAC_DOT_TWO -> 00.11.22.33.44.55
MAC_COLON_FOUR -> 0011:2233:4455
MAC Address Normalization:
mac_normalize('00:11:22:33:44:55') -> 001122334455
MAC Address Vendor Lookup:
get_oui('cc:79:d7:dd:ee:ff') -> Cisco Systems, Inc
4. Network protocol helpers
The following example demonstrates various common operations regarding network protocols using the netutils library, including:
- Converting protocol names, such as TCP and UDP, to their respective IP protocol numbers, and vice versa
- Converting well-known TCP/UDP service names to port numbers, and vice versa
#protocol_examples.py
#!/usr/bin/env python3
"""Examples of using netutils protocol helpers.
This script demonstrates how to use netutils protocol mapping functions
to convert between protocol names and numbers.
"""
from netutils.protocol_mapper import (
PROTO_NAME_TO_NUM,
PROTO_NUM_TO_NAME,
TCP_NAME_TO_NUM,
TCP_NUM_TO_NAME,
UDP_NAME_TO_NUM,
UDP_NUM_TO_NAME,
)
def main():
"""Run protocol helper examples."""
print("Protocol Helper Examples:")
print("-" * 40)
# Get IP protocol numbers
print("\nIP Protocol Name to Number:")
protocols = ["TCP", "UDP", "ICMP", "OSPF", "BGP"]
for protocol in protocols:
try:
number = PROTO_NAME_TO_NUM[protocol]
print(f"{protocol} -> {number}")
except KeyError:
print(f"{protocol} -> Not found")
# Get IP protocol names
print("\nIP Protocol Number to Name:")
numbers = [6, 17, 1, 89, 179]
for number in numbers:
try:
name = PROTO_NUM_TO_NAME[number]
print(f"{number} -> {name}")
except KeyError:
print(f"{number} -> Not found")
# Get TCP port numbers
print("\nTCP Port Name to Number:")
tcp_ports = ["HTTP", "HTTPS", "SSH", "FTP", "SMTP"]
for port in tcp_ports:
try:
number = TCP_NAME_TO_NUM[port]
print(f"{port} -> {number}")
except KeyError:
print(f"{port} -> Not found")
# Get TCP port names
print("\nTCP Port Number to Name:")
tcp_numbers = [80, 443, 22, 21, 25]
for number in tcp_numbers:
try:
name = TCP_NUM_TO_NAME[number]
print(f"{number} -> {name}")
except KeyError:
print(f"{number} -> Not found")
# Get UDP port numbers
print("\nUDP Port Name to Number:")
udp_ports = ["DNS", "DHCP", "SNMP", "TFTP", "NTP"]
for port in udp_ports:
try:
number = UDP_NAME_TO_NUM[port]
print(f"{port} -> {number}")
except KeyError:
print(f"{port} -> Not found")
# Get UDP port names
print("\nUDP Port Number to Name:")
udp_numbers = [53, 67, 161, 69, 123]
for number in udp_numbers:
try:
name = UDP_NUM_TO_NAME[number]
print(f"{number} -> {name}")
except KeyError:
print(f"{number} -> Not found")
if __name__ == "__main__":
main()
Here is the output from the script above:
# python protocol_examples.py
Protocol Helper Examples:
----------------------------------------
IP Protocol Name to Number:
TCP -> 6
UDP -> 17
ICMP -> 1
OSPF -> Not found
BGP -> Not found
IP Protocol Number to Name:
6 -> TCP
17 -> UDP
1 -> ICMP
89 -> OSPFIGP
179 -> Not found
TCP Port Name to Number:
HTTP -> Not found
HTTPS -> 443
SSH -> 22
FTP -> 21
SMTP -> 25
TCP Port Number to Name:
80 -> WWW-HTTP
443 -> HTTPS
22 -> SSH
21 -> FTP
25 -> SMTP
UDP Port Name to Number:
DNS -> Not found
DHCP -> Not found
SNMP -> 161
TFTP -> 69
NTP -> 123
UDP Port Number to Name:
53 -> DOMAIN
67 -> BOOTPS
161 -> SNMP
69 -> TFTP
123 -> NTP
Conclusion
Netutils offers a reliable platform-agnostic toolkit for network automation. Built on Python best practices and thoroughly tested, it’s designed to simplify your work whether you’re writing a quick script or developing a full-scale automation system. Instead of reinventing the wheel, let Netutils handle the fundamentals so you can focus on delivering results.
Additional Resources:
- Netutils GitHub repository: https://github.com/networktocode/netutils
- Netutils Readthedoc: https://netutils.readthedocs.io/en/latest/
– Eric Chou