atomicshop 2.21.1__py3-none-any.whl → 3.0.1__py3-none-any.whl
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.
Potentially problematic release.
This version of atomicshop might be problematic. Click here for more details.
- atomicshop/__init__.py +1 -1
- atomicshop/basics/multiprocesses.py +228 -30
- atomicshop/dns.py +2 -0
- atomicshop/mitm/config_static.py +2 -1
- atomicshop/mitm/engines/create_module_template.py +2 -7
- atomicshop/mitm/import_config.py +36 -44
- atomicshop/mitm/initialize_engines.py +9 -24
- atomicshop/mitm/mitm_main.py +187 -59
- atomicshop/networks.py +448 -0
- atomicshop/wrappers/ctyping/setup_device.py +466 -0
- atomicshop/wrappers/dockerw/dockerw.py +17 -21
- atomicshop/wrappers/mongodbw/mongodbw.py +1 -0
- atomicshop/wrappers/psutilw/{networks.py → psutil_networks.py} +3 -1
- atomicshop/wrappers/pywin32w/wmis/msft_netipaddress.py +76 -0
- atomicshop/wrappers/pywin32w/wmis/win32_networkadapterconfiguration.py +262 -0
- atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +51 -82
- atomicshop/wrappers/pywin32w/wmis/wmi_helpers.py +235 -0
- atomicshop/wrappers/socketw/accepter.py +15 -1
- atomicshop/wrappers/socketw/creator.py +7 -1
- atomicshop/wrappers/socketw/dns_server.py +33 -39
- atomicshop/wrappers/socketw/exception_wrapper.py +20 -11
- atomicshop/wrappers/socketw/socket_wrapper.py +29 -78
- atomicshop/wrappers/winregw/winreg_network.py +20 -0
- {atomicshop-2.21.1.dist-info → atomicshop-3.0.1.dist-info}/METADATA +2 -1
- {atomicshop-2.21.1.dist-info → atomicshop-3.0.1.dist-info}/RECORD +28 -24
- atomicshop/wrappers/pywin32w/wmis/helpers.py +0 -131
- {atomicshop-2.21.1.dist-info → atomicshop-3.0.1.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.21.1.dist-info → atomicshop-3.0.1.dist-info}/WHEEL +0 -0
- {atomicshop-2.21.1.dist-info → atomicshop-3.0.1.dist-info}/top_level.txt +0 -0
atomicshop/networks.py
ADDED
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
import time
|
|
3
|
+
from typing import Union
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
from icmplib import ping
|
|
7
|
+
from icmplib.models import Host
|
|
8
|
+
from win32com.client import CDispatch
|
|
9
|
+
|
|
10
|
+
from .wrappers.pywin32w.wmis import win32networkadapter, win32_networkadapterconfiguration, wmi_helpers, msft_netipaddress
|
|
11
|
+
from .wrappers.ctyping import setup_device
|
|
12
|
+
from .wrappers.winregw import winreg_network
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
MICROSOFT_LOOPBACK_DEVICE_NAME: str = 'Microsoft KM-TEST Loopback Adapter'
|
|
16
|
+
MICROSOFT_LOOPBACK_DEVICE_INF_PATH = os.path.join(os.environ["WINDIR"], "INF", "netloop.inf")
|
|
17
|
+
MICROSOFT_LOOPBACK_DEVICE_HARDWARE_ID = "*MSLOOP"
|
|
18
|
+
GUID_DEVCLASS_NET: str = '{4d36e972-e325-11ce-bfc1-08002be10318}'
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def is_ip_alive(ip_address: str, timeout: int = 1) -> bool:
|
|
22
|
+
"""
|
|
23
|
+
Returns True if icmplib.models.Host.is_alive returns True.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
host_object: Host = ping(ip_address, count=1, timeout=timeout)
|
|
27
|
+
|
|
28
|
+
return host_object.is_alive
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def get_default_internet_ipv4() -> str:
|
|
32
|
+
"""
|
|
33
|
+
Get the default IPv4 address of the interface that is being used for internet.
|
|
34
|
+
:return: string, default IPv4 address.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
return socket.gethostbyname(socket.gethostname())
|
|
38
|
+
|
|
39
|
+
def get_default_internet_ipv4_by_connect(target: str = "8.8.8.8") -> str:
|
|
40
|
+
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
|
41
|
+
s.connect((target, 80)) # no packet sent; OS just chooses a route
|
|
42
|
+
return s.getsockname()[0] # local address of that route
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_default_internet_interface_name() -> str:
|
|
46
|
+
"""
|
|
47
|
+
Get the default network interface name that is being used for internet.
|
|
48
|
+
:return: string, default network interface name.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
return socket.gethostname()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def get_microsoft_loopback_device_network_configuration(
|
|
55
|
+
wmi_instance: CDispatch = None,
|
|
56
|
+
timeout: int = 1,
|
|
57
|
+
) -> Union[
|
|
58
|
+
tuple[CDispatch, str],
|
|
59
|
+
tuple[None, None]
|
|
60
|
+
]:
|
|
61
|
+
"""
|
|
62
|
+
Get the WMI Win32_NetworkAdapterConfiguration object of the Microsoft Loopback device.
|
|
63
|
+
|
|
64
|
+
:param wmi_instance: WMI instance. You can get it from:
|
|
65
|
+
wrappers.pywin32s.wmis.wmi_helpers.get_wmi_instance()
|
|
66
|
+
If not specified the default WMI instance will be used '.'.
|
|
67
|
+
:param timeout: int, timeout in seconds. Default is 1 second.
|
|
68
|
+
:return: tuple(Win32_NetworkAdapterConfiguration, Win32_NetworkAdapter.PNPDeviceID)
|
|
69
|
+
If the adapter is not found, it will return (None, None).
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
if not wmi_instance:
|
|
73
|
+
wmi_instance, _ = wmi_helpers.get_wmi_instance()
|
|
74
|
+
|
|
75
|
+
for _ in range(timeout):
|
|
76
|
+
adapter: CDispatch = win32networkadapter.get_network_adapter_by_device_name(
|
|
77
|
+
MICROSOFT_LOOPBACK_DEVICE_NAME, wmi_instance)
|
|
78
|
+
if not adapter:
|
|
79
|
+
# noinspection PyTypeChecker
|
|
80
|
+
network_config = None
|
|
81
|
+
else:
|
|
82
|
+
network_config: CDispatch = win32_networkadapterconfiguration.get_network_configuration_by_adapter(
|
|
83
|
+
adapter, wmi_instance=wmi_instance)
|
|
84
|
+
|
|
85
|
+
if network_config:
|
|
86
|
+
return network_config, adapter.PNPDeviceID
|
|
87
|
+
time.sleep(1)
|
|
88
|
+
|
|
89
|
+
return None, None
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def create_microsoft_loopback_device():
|
|
93
|
+
"""
|
|
94
|
+
Create a Microsoft Loopback device using the setupapi.dll.
|
|
95
|
+
"""
|
|
96
|
+
setup_device.add_device(
|
|
97
|
+
class_guid=GUID_DEVCLASS_NET,
|
|
98
|
+
friendly_name=MICROSOFT_LOOPBACK_DEVICE_NAME,
|
|
99
|
+
hardware_ids=MICROSOFT_LOOPBACK_DEVICE_HARDWARE_ID,
|
|
100
|
+
inf_path=MICROSOFT_LOOPBACK_DEVICE_INF_PATH,
|
|
101
|
+
force_install=True,
|
|
102
|
+
quiet=True,
|
|
103
|
+
existing_ok=True
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def get_create_microsoft_loopback_device_network_configuration(
|
|
108
|
+
wmi_instance: CDispatch = None
|
|
109
|
+
) -> Union[
|
|
110
|
+
tuple[CDispatch, str],
|
|
111
|
+
tuple[None, None]
|
|
112
|
+
]:
|
|
113
|
+
"""
|
|
114
|
+
Get the WMI Win32_NetworkAdapterConfiguration object of the Microsoft Loopback device.
|
|
115
|
+
If it does not exist, create it.
|
|
116
|
+
|
|
117
|
+
:param wmi_instance: WMI instance. You can get it from:
|
|
118
|
+
wrappers.pywin32s.wmis.wmi_helpers.get_wmi_instance()
|
|
119
|
+
If not specified the default WMI instance will be used '.'.
|
|
120
|
+
:return: tuple(Win32_NetworkAdapterConfiguration, Win32_NetworkAdapter.PNPDeviceID)
|
|
121
|
+
If the adapter is not found, it will return (None, None).
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
if not wmi_instance:
|
|
125
|
+
wmi_instance, _ = wmi_helpers.get_wmi_instance()
|
|
126
|
+
|
|
127
|
+
network_config, pnp_device_id = get_microsoft_loopback_device_network_configuration(wmi_instance=wmi_instance)
|
|
128
|
+
|
|
129
|
+
if network_config:
|
|
130
|
+
return network_config, pnp_device_id
|
|
131
|
+
|
|
132
|
+
create_microsoft_loopback_device()
|
|
133
|
+
|
|
134
|
+
network_config, pnp_device_id = get_microsoft_loopback_device_network_configuration(
|
|
135
|
+
wmi_instance=wmi_instance, timeout=20)
|
|
136
|
+
|
|
137
|
+
return network_config, pnp_device_id
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def remove_microsoft_loopback_device(
|
|
141
|
+
pnp_device_id: str
|
|
142
|
+
) -> bool:
|
|
143
|
+
"""
|
|
144
|
+
Remove the Microsoft Loopback device using the setupapi.dll.
|
|
145
|
+
|
|
146
|
+
:param pnp_device_id: string, PNPDeviceID of the device to remove.
|
|
147
|
+
:return: bool, True if the device was removed successfully.
|
|
148
|
+
"""
|
|
149
|
+
return setup_device.remove_device(
|
|
150
|
+
pnp_device_id=pnp_device_id,
|
|
151
|
+
class_guid=GUID_DEVCLASS_NET
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def change_interface_metric_restart_device(
|
|
156
|
+
network_config: CDispatch,
|
|
157
|
+
metric: int = 9999,
|
|
158
|
+
wmi_instance: CDispatch = None
|
|
159
|
+
):
|
|
160
|
+
"""
|
|
161
|
+
Change the interface metric and restart the device.
|
|
162
|
+
You can check the metric in CMD with:
|
|
163
|
+
route print
|
|
164
|
+
|
|
165
|
+
:param network_config: CDispatch, Win32_NetworkAdapterConfiguration object.
|
|
166
|
+
:param metric: int, new metric value.
|
|
167
|
+
:param wmi_instance: WMI instance. You can get it from:
|
|
168
|
+
wrappers.pywin32s.wmis.wmi_helpers.get_wmi_instance()
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
if not wmi_instance:
|
|
172
|
+
wmi_instance, _ = wmi_helpers.get_wmi_instance()
|
|
173
|
+
|
|
174
|
+
# 1) Registry tweak
|
|
175
|
+
guid = network_config.SettingID
|
|
176
|
+
winreg_network.change_metric_of_network_adapter(adapter_guid=guid, metric=metric)
|
|
177
|
+
|
|
178
|
+
# 2) Bounce the NIC so TCP/IP re‑reads the new metric
|
|
179
|
+
idx = network_config.Index
|
|
180
|
+
adapter = wmi_instance.ExecQuery(f"SELECT * FROM Win32_NetworkAdapter WHERE Index={idx}")[0]
|
|
181
|
+
|
|
182
|
+
adapter.ExecMethod_("Disable")
|
|
183
|
+
time.sleep(1.0)
|
|
184
|
+
adapter.ExecMethod_("Enable")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def get_wmi_network_adapter_configuration(
|
|
188
|
+
use_default_interface: bool = False,
|
|
189
|
+
connection_name: str = None,
|
|
190
|
+
mac_address: str = None,
|
|
191
|
+
wmi_instance: CDispatch = None,
|
|
192
|
+
get_info_from_network_config: bool = True
|
|
193
|
+
) -> tuple:
|
|
194
|
+
"""
|
|
195
|
+
Get the WMI network configuration for a network adapter.
|
|
196
|
+
:param use_default_interface: bool, if True, the default network interface will be used.
|
|
197
|
+
This is the adapter that your internet is being used from.
|
|
198
|
+
:param connection_name: string, adapter name as shown in the network settings.
|
|
199
|
+
:param mac_address: string, MAC address of the adapter. Format: '00:00:00:00:00:00'.
|
|
200
|
+
:param wmi_instance: WMI instance. You can get it from:
|
|
201
|
+
wrappers.pywin32s.wmis.wmi_helpers.get_wmi_instance()
|
|
202
|
+
or default will be used.
|
|
203
|
+
:param get_info_from_network_config: bool, if True, the function will return the network configuration info
|
|
204
|
+
on the third position of the tuple. On False, it will return an empty dictionary.
|
|
205
|
+
:return: tuple(Win32_NetworkAdapterConfiguration, Win32_NetworkAdapter, dict)
|
|
206
|
+
"""
|
|
207
|
+
|
|
208
|
+
wmi_network_config, wmi_network_adapter = win32_networkadapterconfiguration.get_adapter_network_configuration(
|
|
209
|
+
use_default_interface=use_default_interface,
|
|
210
|
+
connection_name=connection_name,
|
|
211
|
+
mac_address=mac_address,
|
|
212
|
+
wmi_instance=wmi_instance
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
if get_info_from_network_config:
|
|
216
|
+
adapter_info: dict = win32_networkadapterconfiguration.get_info_from_network_config(wmi_network_config)
|
|
217
|
+
else:
|
|
218
|
+
adapter_info: dict = {}
|
|
219
|
+
|
|
220
|
+
return wmi_network_config, wmi_network_adapter, adapter_info
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def generate_unused_ipv4_addresses_by_vlan(
|
|
224
|
+
vlan: str,
|
|
225
|
+
number_of_ips: int,
|
|
226
|
+
skip_ips: list[str] = None
|
|
227
|
+
) -> list[str]:
|
|
228
|
+
"""
|
|
229
|
+
Generate a list of unused IPv4 addresses in the given VLAN.
|
|
230
|
+
|
|
231
|
+
:param vlan: string, VLAN in the format '192.168.0'.
|
|
232
|
+
:param number_of_ips: int, number of IPs to generate.
|
|
233
|
+
:param skip_ips: list of strings, IPs to skip.
|
|
234
|
+
:return: list of strings, free IPv4 addresses.
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
generated_ips: list[str] = []
|
|
238
|
+
counter: int = 1
|
|
239
|
+
for i in range(number_of_ips):
|
|
240
|
+
# Create the IP address.
|
|
241
|
+
while True:
|
|
242
|
+
ip_address = f"{vlan}.{counter}"
|
|
243
|
+
counter += 1
|
|
244
|
+
is_ip_in_use: bool = is_ip_alive(ip_address)
|
|
245
|
+
if not is_ip_in_use and not ip_address in skip_ips:
|
|
246
|
+
# print("[+] Found IP to assign: ", ip_address)
|
|
247
|
+
generated_ips.append(ip_address)
|
|
248
|
+
break
|
|
249
|
+
else:
|
|
250
|
+
# print(f"[!] IP {ip_address} is already in use or assigned to the adapter.")
|
|
251
|
+
continue
|
|
252
|
+
|
|
253
|
+
return generated_ips
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def generate_unused_ipv4_addresses_from_ip(
|
|
257
|
+
ip_address: str,
|
|
258
|
+
mask: str,
|
|
259
|
+
number_of_ips: int,
|
|
260
|
+
skip_ips: list[str] = None
|
|
261
|
+
) -> tuple[list[str], list[str]]:
|
|
262
|
+
"""
|
|
263
|
+
Generate a list of unused IPv4 addresses in the given VLAN.
|
|
264
|
+
|
|
265
|
+
:param ip_address: string, IP address, example: '192.168.0.1'.
|
|
266
|
+
This address will be a part of skip_ips list, even if an empty list is passed.
|
|
267
|
+
:param mask: string, subnet mask, example: '255.255.255.0'.
|
|
268
|
+
:param number_of_ips: int, number of IPs to generate.
|
|
269
|
+
:param skip_ips: list of strings, IPs to skip.
|
|
270
|
+
:return: list of strings, unused IPv4 addresses.
|
|
271
|
+
"""
|
|
272
|
+
|
|
273
|
+
if not skip_ips:
|
|
274
|
+
skip_ips = []
|
|
275
|
+
|
|
276
|
+
# Add the IP address to the list of IPs to skip.
|
|
277
|
+
if ip_address not in skip_ips:
|
|
278
|
+
skip_ips = [ip_address] + skip_ips
|
|
279
|
+
|
|
280
|
+
# Get the VLAN of the default IPv4 address.
|
|
281
|
+
default_vlan: str = ip_address.rsplit(".", 1)[0]
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
# Find IPs to assign.
|
|
285
|
+
generated_ips: list[str] = generate_unused_ipv4_addresses_by_vlan(
|
|
286
|
+
vlan=default_vlan, number_of_ips=number_of_ips, skip_ips=skip_ips)
|
|
287
|
+
|
|
288
|
+
# Add subnet masks to the IPs to assign.
|
|
289
|
+
masks_for_ips: list[str] = []
|
|
290
|
+
for ip_address in generated_ips:
|
|
291
|
+
print(f"[+] Found IP to assign: {ip_address}")
|
|
292
|
+
masks_for_ips.append(mask)
|
|
293
|
+
|
|
294
|
+
return generated_ips, masks_for_ips
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def set_dynamic_ip_for_adapter(
|
|
298
|
+
network_config: CDispatch,
|
|
299
|
+
reset_dns: bool = True,
|
|
300
|
+
reset_wins: bool = True
|
|
301
|
+
):
|
|
302
|
+
"""
|
|
303
|
+
Set the IP address of the network adapter to dynamic from DHCP.
|
|
304
|
+
:param network_config: CDispatch, Win32_NetworkAdapterConfiguration object.
|
|
305
|
+
:param reset_dns: bool, if True, the DNS servers will be reset to automatic.
|
|
306
|
+
:param reset_wins: bool, if True, the WINS servers will be reset to automatic.
|
|
307
|
+
"""
|
|
308
|
+
|
|
309
|
+
win32_networkadapterconfiguration.set_dynamic_ip(
|
|
310
|
+
nic_cfg=network_config, reset_dns=reset_dns, reset_wins=reset_wins)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def set_static_ip_for_adapter(
|
|
314
|
+
network_config: CDispatch,
|
|
315
|
+
ips: list[str],
|
|
316
|
+
masks: list[str],
|
|
317
|
+
gateways: list[str] = None,
|
|
318
|
+
dns_gateways: list[str] = None,
|
|
319
|
+
availability_wait_seconds: int = 0
|
|
320
|
+
):
|
|
321
|
+
"""
|
|
322
|
+
Set the IP address of the network adapter to static.
|
|
323
|
+
:param network_config: CDispatch, Win32_NetworkAdapterConfiguration object.
|
|
324
|
+
:param ips: list of strings, IP addresses to assign.
|
|
325
|
+
:param masks: list of strings, subnet masks to assign.
|
|
326
|
+
:param gateways: list of strings, default gateways to assign.
|
|
327
|
+
:param dns_gateways: list of strings, DNS servers to assign.
|
|
328
|
+
:param availability_wait_seconds: int, seconds to wait for the adapter to be available after setting the IP address.
|
|
329
|
+
"""
|
|
330
|
+
|
|
331
|
+
win32_networkadapterconfiguration.set_static_ips(
|
|
332
|
+
network_config=network_config,
|
|
333
|
+
ips=ips,
|
|
334
|
+
masks=masks,
|
|
335
|
+
gateways=gateways,
|
|
336
|
+
dns_gateways=dns_gateways,
|
|
337
|
+
availability_wait_seconds=availability_wait_seconds
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def add_virtual_ips_to_default_adapter_by_current_setting(
|
|
342
|
+
number_of_ips: int = 0,
|
|
343
|
+
virtual_ipv4s_to_add: list[str] = None,
|
|
344
|
+
virtual_ipv4_masks_to_add: list[str] = None,
|
|
345
|
+
set_virtual_ips_skip_as_source: bool = True,
|
|
346
|
+
gateways: list[str] | None = None,
|
|
347
|
+
dns_gateways: list[str] | None = None,
|
|
348
|
+
availability_wait_seconds: int = 15,
|
|
349
|
+
simulate_only: bool = False,
|
|
350
|
+
locator: CDispatch = None,
|
|
351
|
+
) -> tuple[list[str], list[str], list[str], list[str]]:
|
|
352
|
+
"""
|
|
353
|
+
Add virtual IP addresses to the default network adapter.
|
|
354
|
+
The adapter will set to static IP and DNS gateway, instead of dynamic DHCP.
|
|
355
|
+
The first IPv4 address of the network_config will be used as VLAN and the unused IP addresses
|
|
356
|
+
will be generated from it. Unused addresses decided by pinging them.
|
|
357
|
+
Same for the subnet mask.
|
|
358
|
+
|
|
359
|
+
:param number_of_ips: int, number of IPs to generate in addition to the IPv4s that already exist in the adapter.
|
|
360
|
+
Or you add the IPs and masks to the adapter with the parameters virtual_ipv4s_to_add and virtual_ipv4_masks_to_add.
|
|
361
|
+
|
|
362
|
+
:param virtual_ipv4s_to_add: list of strings, Add this IPv4 addresses to the current IPs of the adapter.
|
|
363
|
+
:param virtual_ipv4_masks_to_add: list of strings, Add this subnet masks to the current subnet masks of the adapter.
|
|
364
|
+
Or you generate the IPs and masks by specifying the number_of_ips parameter.
|
|
365
|
+
|
|
366
|
+
:param set_virtual_ips_skip_as_source: bool, if True, the SkipAsSource flag will be set for the virtual IPs.
|
|
367
|
+
This is needed to avoid the endless accept() loop.
|
|
368
|
+
:param gateways: list of strings, default IPv4 gateways to assign.
|
|
369
|
+
None: The already existing gateways in the adapter will be used.
|
|
370
|
+
[]: No gateways will be assigned.
|
|
371
|
+
:param dns_gateways: list of strings, IPv4 DNS servers to assign.
|
|
372
|
+
None: The already existing DNS servers in the adapter will be used.
|
|
373
|
+
[]: No DNS servers will be assigned.
|
|
374
|
+
:param availability_wait_seconds: int, seconds to wait for the adapter to be available after setting the IP address.
|
|
375
|
+
:param simulate_only: bool, if True, the function will only prepare the ip addresses and return them without changing anything.
|
|
376
|
+
:param locator: CDispatch, WMI locator object. If not specified, it will be created.
|
|
377
|
+
|
|
378
|
+
:return: tuple of lists, (current_ipv4s, current_ipv4_masks, ips_to_assign, masks_to_assign)
|
|
379
|
+
"""
|
|
380
|
+
|
|
381
|
+
if virtual_ipv4s_to_add and not virtual_ipv4_masks_to_add:
|
|
382
|
+
raise ValueError("If you specify virtual_ipv4s_to_add, you must also specify virtual_ipv4_masks_to_add.")
|
|
383
|
+
if virtual_ipv4_masks_to_add and not virtual_ipv4s_to_add:
|
|
384
|
+
raise ValueError("If you specify virtual_ipv4_masks_to_add, you must also specify virtual_ipv4s_to_add.")
|
|
385
|
+
|
|
386
|
+
if virtual_ipv4s_to_add and len(virtual_ipv4s_to_add) != len(virtual_ipv4_masks_to_add):
|
|
387
|
+
raise ValueError("If you specify virtual_ipv4s_to_add, the number of IPs must be equal to the number of masks.")
|
|
388
|
+
|
|
389
|
+
if number_of_ips > 0 and (virtual_ipv4s_to_add or virtual_ipv4_masks_to_add):
|
|
390
|
+
raise ValueError("If you specify number_of_ips, you cannot specify virtual_ipv4s_to_add or virtual_ipv4_masks_to_add.")
|
|
391
|
+
|
|
392
|
+
# Connect to WMi.
|
|
393
|
+
wmi_civ2_instance, locator = wmi_helpers.get_wmi_instance(locator=locator)
|
|
394
|
+
|
|
395
|
+
# initial_default_ipv4: str = socket.gethostbyname(socket.gethostname())
|
|
396
|
+
|
|
397
|
+
# Get the default network adapter configuration.
|
|
398
|
+
default_network_adapter_config, default_network_adapter, default_adapter_info = get_wmi_network_adapter_configuration(
|
|
399
|
+
use_default_interface=True, wmi_instance=wmi_civ2_instance, get_info_from_network_config=True)
|
|
400
|
+
|
|
401
|
+
current_ipv4s: list[str] = default_adapter_info['ipv4s']
|
|
402
|
+
current_ipv4_masks: list[str] = default_adapter_info['ipv4_subnet_masks']
|
|
403
|
+
|
|
404
|
+
# print(f"Current IPs: {current_ipv4s}")
|
|
405
|
+
# current_ips_count: int = len(current_ipv4s)
|
|
406
|
+
|
|
407
|
+
if number_of_ips > 0:
|
|
408
|
+
ips_to_assign, masks_to_assign = generate_unused_ipv4_addresses_from_ip(
|
|
409
|
+
ip_address=current_ipv4s[0],
|
|
410
|
+
mask=current_ipv4_masks[0],
|
|
411
|
+
number_of_ips=number_of_ips,
|
|
412
|
+
skip_ips=current_ipv4s
|
|
413
|
+
)
|
|
414
|
+
elif virtual_ipv4s_to_add and virtual_ipv4_masks_to_add:
|
|
415
|
+
ips_to_assign = virtual_ipv4s_to_add
|
|
416
|
+
masks_to_assign = virtual_ipv4_masks_to_add
|
|
417
|
+
else:
|
|
418
|
+
ips_to_assign = []
|
|
419
|
+
masks_to_assign = []
|
|
420
|
+
|
|
421
|
+
if not simulate_only:
|
|
422
|
+
# Final list of IPs to assign.
|
|
423
|
+
ips: list[str] = current_ipv4s + ips_to_assign
|
|
424
|
+
masks: list[str] = current_ipv4_masks + masks_to_assign
|
|
425
|
+
|
|
426
|
+
# ---------- IP assignment --------------------------------------------
|
|
427
|
+
if ips != current_ipv4s:
|
|
428
|
+
# print("[+] Setting static IPv4 addresses …")
|
|
429
|
+
if gateways is None:
|
|
430
|
+
gateways = default_adapter_info['default_gateways']
|
|
431
|
+
|
|
432
|
+
if dns_gateways is None:
|
|
433
|
+
dns_gateways = default_adapter_info['dns_gateways']
|
|
434
|
+
|
|
435
|
+
win32_networkadapterconfiguration.set_static_ips(
|
|
436
|
+
default_network_adapter_config, ips=ips, masks=masks,
|
|
437
|
+
gateways=gateways, dns_gateways=dns_gateways,
|
|
438
|
+
availability_wait_seconds=availability_wait_seconds)
|
|
439
|
+
|
|
440
|
+
if set_virtual_ips_skip_as_source:
|
|
441
|
+
wmi_standard_cimv2_instance, _ = wmi_helpers.get_wmi_instance(
|
|
442
|
+
namespace='root\\StandardCimv2', wmi_instance=wmi_civ2_instance, locator=locator)
|
|
443
|
+
msft_netipaddress.set_skip_as_source(ips_to_assign, enable=True, wmi_instance=wmi_standard_cimv2_instance)
|
|
444
|
+
else:
|
|
445
|
+
# print("[!] No new IPs to assign.")
|
|
446
|
+
pass
|
|
447
|
+
|
|
448
|
+
return current_ipv4s, current_ipv4_masks, ips_to_assign, masks_to_assign
|