ipconfig 0.9.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ipconfig-0.9.9/PKG-INFO +7 -0
- ipconfig-0.9.9/ipconfig/__init__.py +0 -0
- ipconfig-0.9.9/ipconfig/adapter.py +130 -0
- ipconfig-0.9.9/ipconfig/main.py +92 -0
- ipconfig-0.9.9/ipconfig.egg-info/PKG-INFO +7 -0
- ipconfig-0.9.9/ipconfig.egg-info/SOURCES.txt +9 -0
- ipconfig-0.9.9/ipconfig.egg-info/dependency_links.txt +1 -0
- ipconfig-0.9.9/ipconfig.egg-info/entry_points.txt +2 -0
- ipconfig-0.9.9/ipconfig.egg-info/top_level.txt +1 -0
- ipconfig-0.9.9/pyproject.toml +14 -0
- ipconfig-0.9.9/setup.cfg +4 -0
ipconfig-0.9.9/PKG-INFO
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ipconfig
|
|
3
|
+
Version: 0.9.9
|
|
4
|
+
Summary: Netowrk information in ipconfig format
|
|
5
|
+
Author-email: Daniel Hollarek <daniel.hollarek@googlemail.com>
|
|
6
|
+
Project-URL: Repository, https://github.com/Somerandomguy10111/ipconfig
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
File without changes
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
class Adapter:
|
|
5
|
+
|
|
6
|
+
@classmethod
|
|
7
|
+
def from_nmcli_output(cls,section: str) -> Adapter:
|
|
8
|
+
the_adapter = Adapter()
|
|
9
|
+
for line in section.split('\n'):
|
|
10
|
+
if ':' not in line:
|
|
11
|
+
continue
|
|
12
|
+
key, value = line.split(':', 1)
|
|
13
|
+
value = value.strip()
|
|
14
|
+
|
|
15
|
+
if key == "GENERAL.DEVICE":
|
|
16
|
+
the_adapter.name = value
|
|
17
|
+
elif key == "GENERAL.TYPE":
|
|
18
|
+
the_adapter.adapter_type = value
|
|
19
|
+
elif key == "IP4.ADDRESS[1]":
|
|
20
|
+
the_adapter.ipv4_address = value.split('/')[0]
|
|
21
|
+
the_adapter.subnet_mask = value.split('/')[1] if '/' in value else None
|
|
22
|
+
elif key == "IP4.GATEWAY":
|
|
23
|
+
the_adapter.default_gateway = value
|
|
24
|
+
elif key == "IP6.ADDRESS[1]":
|
|
25
|
+
the_adapter.ipv6_address = value.split('/')[0]
|
|
26
|
+
elif key == "IP4.DOMAIN[1]":
|
|
27
|
+
the_adapter.dns_suffix = value
|
|
28
|
+
|
|
29
|
+
return the_adapter
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
technical_name: Optional[str] = None,
|
|
34
|
+
adapter_type: Optional[str] = None,
|
|
35
|
+
dns_suffix: Optional[str] = None,
|
|
36
|
+
ipv4_address: Optional[str] = None,
|
|
37
|
+
ipv6_address: Optional[str] = None,
|
|
38
|
+
subnet_mask: Optional[str] = None,
|
|
39
|
+
default_gateway: Optional[str] = None
|
|
40
|
+
) -> None:
|
|
41
|
+
self.name: Optional[str] = technical_name
|
|
42
|
+
self.adapter_type: Optional[str] = adapter_type
|
|
43
|
+
self.dns_suffix: Optional[str] = dns_suffix
|
|
44
|
+
self.ipv4_address: Optional[str] = ipv4_address
|
|
45
|
+
self.ipv6_address: Optional[str] = ipv6_address
|
|
46
|
+
self.subnet_mask: Optional[str] = subnet_mask
|
|
47
|
+
self.default_gateway: Optional[str] = default_gateway
|
|
48
|
+
|
|
49
|
+
def __str__(self):
|
|
50
|
+
indent = 2 * ' '
|
|
51
|
+
formatted_info = [
|
|
52
|
+
self.get_heading(),
|
|
53
|
+
'',
|
|
54
|
+
f'{indent}{self.get_interface_type()}' if self.name is not None else '',
|
|
55
|
+
f'{indent}{self.get_dns_suffix()}' if self.dns_suffix is not None else '',
|
|
56
|
+
f'{indent}{self.get_ipv4_addr()}' if self.ipv4_address is not None else '',
|
|
57
|
+
f'{indent}{self.get_ipv6_addr()}' if self.ipv6_address is not None else '',
|
|
58
|
+
f'{indent}{self.get_subnet_mask()}' if self.subnet_mask is not None else '',
|
|
59
|
+
f'{indent}{self.get_formatted_default_gateway()}' if self.default_gateway is not None else ''
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
non_empty_info = filter(lambda x: x != '', formatted_info)
|
|
64
|
+
|
|
65
|
+
return "\n".join(non_empty_info)
|
|
66
|
+
|
|
67
|
+
def get_heading(self):
|
|
68
|
+
friendly_name = self.get_friendly_interface_name(self.name)
|
|
69
|
+
return friendly_name
|
|
70
|
+
|
|
71
|
+
def get_interface_type(self):
|
|
72
|
+
return f"{self.get_formatted_label('Type')}{self.adapter_type}"
|
|
73
|
+
|
|
74
|
+
def get_dns_suffix(self):
|
|
75
|
+
return f"{self.get_formatted_label('DNS Suffix')}{self.dns_suffix}"
|
|
76
|
+
|
|
77
|
+
def get_ipv4_addr(self):
|
|
78
|
+
return f"{self.get_formatted_label('IPv4 Address')}{self.ipv4_address}"
|
|
79
|
+
|
|
80
|
+
def get_ipv6_addr(self):
|
|
81
|
+
return f"{self.get_formatted_label('IPv6 Address')}{self.ipv6_address}"
|
|
82
|
+
|
|
83
|
+
def get_subnet_mask(self):
|
|
84
|
+
try:
|
|
85
|
+
the_int = int(self.subnet_mask)
|
|
86
|
+
self.subnet_mask = self.cidr_to_netmask(the_int)
|
|
87
|
+
except:
|
|
88
|
+
return ''
|
|
89
|
+
return f"{self.get_formatted_label('Subnet Mask')}{self.subnet_mask}"
|
|
90
|
+
|
|
91
|
+
def get_formatted_default_gateway(self):
|
|
92
|
+
return f"{self.get_formatted_label('Default Gateway')}{self.default_gateway}"
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@staticmethod
|
|
96
|
+
def get_formatted_label(label):
|
|
97
|
+
target_size = 30
|
|
98
|
+
blank_padding = " " * (target_size - len(label))
|
|
99
|
+
dotted_padding = ''.join([c if (i+len(label)) % 2 == 0 else '.' for i, c in enumerate(blank_padding)])
|
|
100
|
+
adjusted_label = f"{label}{dotted_padding}"[:target_size] + " : "
|
|
101
|
+
return adjusted_label
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def get_friendly_interface_name(interface_name : str) -> str:
|
|
105
|
+
if interface_name.startswith('en'):
|
|
106
|
+
return "Ethernet Adapter"
|
|
107
|
+
elif interface_name.startswith('wl'):
|
|
108
|
+
return "Wireless LAN Adapter"
|
|
109
|
+
elif interface_name.startswith('virbr'):
|
|
110
|
+
return "Virtual Bridge Interface"
|
|
111
|
+
elif interface_name.startswith('veth'):
|
|
112
|
+
return "Virtual Ethernet Interface"
|
|
113
|
+
elif interface_name.startswith('tun') or interface_name.startswith('tap'):
|
|
114
|
+
return "VPN Tunnel Interface"
|
|
115
|
+
elif interface_name.startswith('bond'):
|
|
116
|
+
return "Bonding Interface"
|
|
117
|
+
elif '.' in interface_name:
|
|
118
|
+
return "VLAN Interface"
|
|
119
|
+
elif interface_name == 'lo':
|
|
120
|
+
return "Loopback Interface"
|
|
121
|
+
elif interface_name.startswith('br'):
|
|
122
|
+
return "Bridge Interface"
|
|
123
|
+
else:
|
|
124
|
+
return f"Unknown Adapter ({interface_name})"
|
|
125
|
+
|
|
126
|
+
@staticmethod
|
|
127
|
+
def cidr_to_netmask(cidr_bits: int) -> str:
|
|
128
|
+
mask = ('1' * cidr_bits).ljust(32, '0')
|
|
129
|
+
octets = [str(int(mask[i:i + 8], 2)) for i in range(0, 32, 8)]
|
|
130
|
+
return '.'.join(octets)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
import subprocess
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from ipconfig.adapter import Adapter
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class NetworkArea(Enum):
|
|
8
|
+
LOCALHOST = 'LOCALHOST'
|
|
9
|
+
HOME = 'HOME'
|
|
10
|
+
GLOBAL = 'WAN'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class IpProvider:
|
|
14
|
+
@classmethod
|
|
15
|
+
def get_localhost(cls) -> str:
|
|
16
|
+
return cls.get_ip(area=NetworkArea.LOCALHOST)
|
|
17
|
+
|
|
18
|
+
@classmethod
|
|
19
|
+
def get_ip(cls, area: NetworkArea) -> str:
|
|
20
|
+
if area == NetworkArea.LOCALHOST:
|
|
21
|
+
return '127.0.0.1'
|
|
22
|
+
elif area == NetworkArea.HOME:
|
|
23
|
+
return cls.get_private_ip()
|
|
24
|
+
elif area == NetworkArea.GLOBAL:
|
|
25
|
+
raise PermissionError("Unable to retrieve Global IP automatically. Please check manually")
|
|
26
|
+
else:
|
|
27
|
+
raise ValueError(f"Invalid network area: {area.value}")
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def get_private_ip() -> str:
|
|
31
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
32
|
+
s.settimeout(0)
|
|
33
|
+
try:
|
|
34
|
+
random_ip = '10.254.254.254'
|
|
35
|
+
s.connect((random_ip, 1))
|
|
36
|
+
IP = s.getsockname()[0]
|
|
37
|
+
except Exception:
|
|
38
|
+
IP = '127.0.0.1'
|
|
39
|
+
s.close()
|
|
40
|
+
return IP
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def get_public_ip() -> str:
|
|
44
|
+
import requests
|
|
45
|
+
err, public_ip = None, None
|
|
46
|
+
try:
|
|
47
|
+
response = requests.get('https://api.ipify.org')
|
|
48
|
+
if response.status_code == 200:
|
|
49
|
+
public_ip = response.text
|
|
50
|
+
else:
|
|
51
|
+
err = ConnectionError(f'Unable to retrieve public IP: {response.status_code}')
|
|
52
|
+
except Exception as e:
|
|
53
|
+
err = e
|
|
54
|
+
if err:
|
|
55
|
+
raise err
|
|
56
|
+
return public_ip
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def get_ipconfig() -> str:
|
|
61
|
+
command = "nmcli device show"
|
|
62
|
+
process = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
63
|
+
output, error = process.communicate()
|
|
64
|
+
|
|
65
|
+
if error:
|
|
66
|
+
raise Exception(f"Error executing nmcli: {error.decode()}")
|
|
67
|
+
|
|
68
|
+
ipconfig_view = ''
|
|
69
|
+
sections = "".join(output.decode()).split("\n\n")
|
|
70
|
+
|
|
71
|
+
for section in sections:
|
|
72
|
+
if section.strip():
|
|
73
|
+
new_adapter = Adapter.from_nmcli_output(section)
|
|
74
|
+
ipconfig_view += f'{new_adapter}\n\n'
|
|
75
|
+
|
|
76
|
+
ipconfig_view = ipconfig_view.rstrip()
|
|
77
|
+
|
|
78
|
+
return ipconfig_view
|
|
79
|
+
|
|
80
|
+
@staticmethod
|
|
81
|
+
def get_free_port() -> int:
|
|
82
|
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
83
|
+
s.bind(('', 0))
|
|
84
|
+
socknum = s.getsockname()[1]
|
|
85
|
+
return socknum
|
|
86
|
+
|
|
87
|
+
def printconfigs():
|
|
88
|
+
print(IpProvider.get_ipconfig())
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
if __name__ == "__main__":
|
|
92
|
+
printconfigs()
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ipconfig
|
|
3
|
+
Version: 0.9.9
|
|
4
|
+
Summary: Netowrk information in ipconfig format
|
|
5
|
+
Author-email: Daniel Hollarek <daniel.hollarek@googlemail.com>
|
|
6
|
+
Project-URL: Repository, https://github.com/Somerandomguy10111/ipconfig
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ipconfig
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ipconfig"
|
|
3
|
+
version = "0.9.9"
|
|
4
|
+
authors = [{name = "Daniel Hollarek", email = "daniel.hollarek@googlemail.com"}]
|
|
5
|
+
description = "Netowrk information in ipconfig format"
|
|
6
|
+
readme = "readme.md"
|
|
7
|
+
dependencies = []
|
|
8
|
+
urls = { "Repository" = "https://github.com/Somerandomguy10111/ipconfig" }
|
|
9
|
+
|
|
10
|
+
[tool.setuptools.packages.find]
|
|
11
|
+
include = ["ipconfig*"]
|
|
12
|
+
|
|
13
|
+
[project.scripts]
|
|
14
|
+
ipconfig = "ipconfig.main:printconfigs"
|
ipconfig-0.9.9/setup.cfg
ADDED