Skip to content

Instantly share code, notes, and snippets.

@rifatdinc
Last active September 19, 2023 21:35
Show Gist options
  • Save rifatdinc/26c8d5c12e2228e696059b025338450b to your computer and use it in GitHub Desktop.
Save rifatdinc/26c8d5c12e2228e696059b025338450b to your computer and use it in GitHub Desktop.
Mikrotik Carrier-grade NAT (Cgnat) Algorithms
import ipaddress
def calculate_ports(public_ip: str, port_interval: int, port_start: int, port_end: int) -> list:
"""
Calculates a list of port ranges based on the provided parameters.
Args:
public_ip (str): The public IP address.
port_interval (int): The interval between port ranges.
port_start (int): The starting port.
port_end (int): The ending port.
Returns:
list: A list of dictionaries representing port ranges.
"""
if port_start > port_end:
raise ValueError("Start port cannot be greater than End port")
if not ipaddress.ip_address(public_ip).is_private:
if port_end > 65535:
raise ValueError("End port cannot be greater than 65535.")
if port_start <= 0 or port_start >= 65535:
raise ValueError("Start port must be between 1 and 65534.")
if port_interval <= 0 or port_interval >= 65535:
raise ValueError("Port interval must be between 1 and 65534.")
port_ranges = []
current_port = port_start
customer_counter = 1
while current_port < port_end:
end_port = min(current_port + port_interval, port_end)
port_range = {
"PublicIp": public_ip,
"StartPort": current_port,
"EndPort": end_port,
"CustomerCounter": customer_counter
}
port_ranges.append(port_range)
current_port = end_port + 1
customer_counter += 1
return port_ranges
else:
raise ValueError("Entered IP is a private IP")
# Example usage:
if __name__ == "__main__":
result = calculate_ports("171.161.1.2", 1000, 1000, 10000)
for x in result:
print(x)
@rifatdinc
Copy link
Author

rifatdinc commented Nov 28, 2021

Output ->
{'PublicIp': '171.161.1.2', 'Startport': 2001, 'EndPort': 3000, 'CustomerCounter': 1}
{'PublicIp': '171.161.1.2', 'Startport': 3002, 'EndPort': 4001, 'CustomerCounter': 2}
{'PublicIp': '171.161.1.2', 'Startport': 4003, 'EndPort': 5002, 'CustomerCounter': 3}
{'PublicIp': '171.161.1.2', 'Startport': 5004, 'EndPort': 6003, 'CustomerCounter': 4}
{'PublicIp': '171.161.1.2', 'Startport': 6005, 'EndPort': 7004, 'CustomerCounter': 5}
{'PublicIp': '171.161.1.2', 'Startport': 7006, 'EndPort': 8005, 'CustomerCounter': 6}
{'PublicIp': '171.161.1.2', 'Startport': 8007, 'EndPort': 9006, 'CustomerCounter': 7}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment