-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmain.py
195 lines (162 loc) · 8.09 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
import ipaddress
import argparse
from os import system
from typing import Tuple
# Create the parser
parser = argparse.ArgumentParser(description='SubnetWizard')
# Add the arguments
ip_help = "The IPv4 address to calculate\nExample: 192.168.0.100/24 or 10.0.0.1/255.255.255.0\nSupports both CIDR and Subnet Mask after the slash"
parser.add_argument('-i', dest='ip', type=str, help=ip_help)
subnet_help = "The netmask to subnet (optional)\nExample: 255.255.255.0 or /24"
parser.add_argument('-s', dest='subnet', type=str, help=subnet_help)
def display_logo() -> None:
print("\033[H\033[2J\033[1m\033[36m ")
print(" ( ")
print(" )\ ) ) ) ( ")
print("(()/( ( ( /( ( ( /( ( ( ( ) ( )\ ) ")
print(" /(_)) ))\ )\()) ( ))\ )\()) )\))( )\ ( ( /( )( (()/( ")
print("(_)) /((_) ((_)\ )\ ) /((_) (_))/ ((_)()\ ((_) )\ )(_)) (()\ ((_)) ")
print(" / __| (_))( | |(_) _(_/( (_)) | |_ _(()((_) (_) ((_) ((_)_ ((_) _| | ")
print(" \__ \ | || | | '_ \ | ' \)) / -_) | _| \ V V / | | |_ / / _` | | '_| / _` | ")
print(" |___/ \_,_| |_.__/ |_||_| \___| \__| \_/\_/ |_| /__| \__,_| |_| \__,_| ")
print("\033[0m", end="")
def get_network(ip: str = None) -> Tuple[ipaddress.IPv4Network, str]:
# Get an IPv4 address from the user.
if ip:
try:
if ip.count("/") == 0: ip += "/24"
net = ipaddress.IPv4Network(ip, strict=False)
ip = ip.split("/")[0]
return (net, ip)
except ValueError:
print("\n\033[36m[\033[31m!\033[36m]\033[0m Invalid IP Address!\n")
exit(1)
print()
while True:
try:
in_ = input("\033[36m[\033[31m?\033[36m]\033[0m Enter an IP Address (192.168.0.100/24): \033[36m")
if in_ == "": in_ = "192.168.0.100/24"
if in_.count("/") == 0: in_ += "/24"
net = ipaddress.IPv4Network(in_, strict=False)
ip = in_.split("/")[0]
return (net, ip)
except ValueError:
print("\n\033[36m[\033[31m!\033[36m]\033[0m Invalid IP Address!\n")
continue
def get_subnet(subnet: str = None) -> str:
# Get a netmask from the user to subnet given network.
if subnet:
if subnet == "0":
print("\n\033[36m[\033[31m!\033[36m]\033[0m Invalid Netmask!\n")
exit(1)
try:
net = ipaddress.IPv4Network(f"10.0.0.0/{subnet}", strict=False)
return net.prefixlen
except ValueError:
print("\n\033[36m[\033[31m!\033[36m]\033[0m Invalid Netmask!\n")
exit(1)
print()
while True:
try:
in_ = input("\033[36m[\033[31m?\033[36m]\033[0m Enter a Netmask to subnet (optional): \033[36m")
if in_ == "0":
print("\n\033[36m[\033[31m!\033[36m]\033[0m Invalid Netmask!\n")
continue
if in_ == "": return None
net = ipaddress.IPv4Network(f"10.0.0.0/{in_.strip('/')}", strict=False)
return net.prefixlen
except ValueError:
print("\n\033[36m[\033[31m!\033[36m]\033[0m Invalid Netmask!\n")
continue
def calculate(network: Tuple[ipaddress.IPv4Network, str], subnet: str) -> None:
# Calculate the network and other information.
ip = network[1]
network = network[0]
# Get the network and broadcast addresses
network_address = network.network_address
broadcast_address = network.broadcast_address
usable_hosts = list(network.hosts())
# Calculate the number of usable hosts
num_usable_hosts = len(usable_hosts)
# Format the usable hosts
usable_hosts = f"{usable_hosts[0]} - {usable_hosts[-1]}" if usable_hosts[0] != usable_hosts[-1] else "NA"
# Convert the IP address to binary
octets = str(ip).split('.')
binary_octets = [bin(int(octet))[2:].zfill(8) for octet in octets]
bin_ip = '.'.join(binary_octets)
bin_addr = str(bin(int(network_address))[2:].zfill(32))
bin_addr = '.'.join([bin_addr[i:i+8] for i in range(0, len(bin_addr), 8)])
bin_mask = str(bin(int(network.netmask))[2:].zfill(32))
bin_mask = '.'.join([bin_mask[i:i+8] for i in range(0, len(bin_mask), 8)])
# Print the results
print(f"\033[0mIP Address: \033[36m{ip}")
print(f"\033[0mIP Address (bin): \033[36m{bin_ip}")
print(f"\033[0mNetwork Address: \033[36m{network_address}")
print(f"\033[0mNetwork Address (bin): \033[36m{bin_addr}")
print(f"\033[0mNetmask: \033[36m{network.netmask}")
print(f"\033[0mNetmask (bin): \033[36m{bin_mask}")
print(f"\033[0mCIDR Notation: \033[36m/{network.prefixlen}")
print(f"\033[0mBroadcast Address: \033[36m{broadcast_address}")
print(f"\033[0mUsable IP Range: \033[36m{usable_hosts}")
print(f"\033[0mNumber of Hosts: \033[36m{network.num_addresses:,d}")
print(f"\033[0mNumber of Usable Hosts: \033[36m{num_usable_hosts:,d}")
print(f"\033[0mWildcard Mask: \033[36m{network.hostmask}")
print(f"\033[0mPrivate IP: \033[36m{network.is_private}")
print()
# Display subnets if present
if subnet is None or int(subnet) == int(network.prefixlen):
return
# if CIDR is greater than current network, subnet it, else supernet it.
if int(subnet) > int(network.prefixlen):
print("\033[0mSubneted Network Details:\n")
subnets = list(network.subnets(new_prefix=int(subnet)))
print(f"\033[0mNetmask: \033[36m{subnets[0].netmask}")
print(f"\033[0mWildcard Mask: \033[36m{subnets[0].hostmask}")
print(f"\033[0mCIDR Notation: \033[36m/{int(subnet)}")
print(f"\033[0mHosts per network: \033[36m{2 ** (32 - int(subnet)) - 2:,d}")
# if CIDR is 32, do not print subnets
if int(subnet) == 32:
return
print("\n\033[0m{:<15} | {:^31} | {:<15}".format(
"Network Address", "Host Range", "Broadcast Address"))
print("-" * 72)
for subnet in subnets:
host_range = list(subnet.hosts())
host_range = host_range if len(host_range) > 1 else [host_range[0], host_range[0]]
# print(host_range)
print("{:<24} | {:<22} - {:>24} | {:<24}".format(
f"\033[36m{subnet.network_address}\033[0m", f"\033[36m{host_range[0]}\033[0m",
f"\033[36m{host_range[-1]}\033[0m", f"\033[36m{subnet.broadcast_address}\033[0m"
))
else:
print("\033[0mSuperneted Network Details:\n")
subnets = network.supernet(new_prefix=int(subnet))
print(f"\033[0mNetmask: \033[36m{subnets.netmask}")
print(f"\033[0mWildcard Mask: \033[36m{subnets.hostmask}")
print(f"\033[0mCIDR Notation: \033[36m/{int(subnet)}")
print(f"\033[0mHosts/Network: \033[36m{2 ** (32 - int(subnet)) - 2:,d}")
print("\n\033[0m{:<15} | {:^31} | {:<15}".format(
"Network Address", "Host Range", "Broadcast Address"))
print("-" * 72)
print("{:<24} | {:<22} - {:>24} | {:<24}".format(
f"\033[36m{subnets[0]}\033[0m", f"\033[36m{subnets[1]}\033[0m",
f"\033[36m{subnets[-2]}\033[0m", f"\033[36m{subnets.broadcast_address}\033[0m"
))
print()
def main():
system("") # Fix for ANSI escape codes on Windows
display_logo()
print(" \033[36mMade by: Azam\033[0m")
args = parser.parse_args()
ip = None
if args.ip:
ip = args.ip
subnet = None
if args.subnet:
subnet = args.subnet
network = get_network(ip)
subnet = get_subnet(subnet)
print()
calculate(network, subnet)
if __name__ == "__main__":
main()