Use black with -l 120 param.

This commit is contained in:
grossmj committed 2021-04-13 18:46:50 +09:30
1 parent f928738bd5
commit c021e21309
194 files changed
+6034 -4564

No files matched your search

+1
View File
@@ -26,6 +26,7 @@ from .iou_error import IOUError
from .iou_vm import IOUVM
import logging
log = logging.getLogger(__name__)
+230 -154
View File
@@ -48,11 +48,12 @@ import gns3server.utils.images
import logging
import sys
log = logging.getLogger(__name__)
class IOUVM(BaseNode):
module_name = 'iou'
module_name = "iou"
"""
IOU VM implementation.
@@ -65,13 +66,17 @@ class IOUVM(BaseNode):
:param console_type: console type
"""
def __init__(self, name, node_id, project, manager, application_id=None, path=None, console=None, console_type="telnet"):
def __init__(
self, name, node_id, project, manager, application_id=None, path=None, console=None, console_type="telnet"
):
super().__init__(name, node_id, project, manager, console=console, console_type=console_type)
log.info('IOU "{name}" [{id}]: assigned with application ID {application_id}'.format(name=self._name,
id=self._id,
application_id=application_id))
log.info(
'IOU "{name}" [{id}]: assigned with application ID {application_id}'.format(
name=self._name, id=self._id, application_id=application_id
)
)
self._iou_process = None
self._telnet_server = None
@@ -170,7 +175,9 @@ class IOUVM(BaseNode):
"""
try:
output = await gns3server.utils.asyncio.subprocess_check_output(self._path, "-h", cwd=self.working_dir, stderr=True)
output = await gns3server.utils.asyncio.subprocess_check_output(
self._path, "-h", cwd=self.working_dir, stderr=True
)
match = re.search(r"-n <n>\s+Size of nvram in Kb \(default ([0-9]+)KB\)", output)
if match:
self.nvram = int(match.group(1))
@@ -206,7 +213,7 @@ class IOUVM(BaseNode):
# IOU images must start with the ELF magic number, be 32-bit or 64-bit, little endian
# and have an ELF version of 1 normal IOS image are big endian!
if elf_header_start != b'\x7fELF\x01\x01\x01' and elf_header_start != b'\x7fELF\x02\x01\x01':
if elf_header_start != b"\x7fELF\x01\x01\x01" and elf_header_start != b"\x7fELF\x02\x01\x01":
raise IOUError(f"'{self._path}' is not a valid IOU image")
if not os.access(self._path, os.X_OK):
@@ -214,24 +221,26 @@ class IOUVM(BaseNode):
def __json__(self):
iou_vm_info = {"name": self.name,
"usage": self.usage,
"node_id": self.id,
"node_directory": self.working_path,
"console": self._console,
"console_type": self._console_type,
"status": self.status,
"project_id": self.project.id,
"path": self.path,
"md5sum": gns3server.utils.images.md5sum(self.path),
"ethernet_adapters": len(self._ethernet_adapters),
"serial_adapters": len(self._serial_adapters),
"ram": self._ram,
"nvram": self._nvram,
"l1_keepalives": self._l1_keepalives,
"use_default_iou_values": self._use_default_iou_values,
"command_line": self.command_line,
"application_id": self.application_id}
iou_vm_info = {
"name": self.name,
"usage": self.usage,
"node_id": self.id,
"node_directory": self.working_path,
"console": self._console,
"console_type": self._console_type,
"status": self.status,
"project_id": self.project.id,
"path": self.path,
"md5sum": gns3server.utils.images.md5sum(self.path),
"ethernet_adapters": len(self._ethernet_adapters),
"serial_adapters": len(self._serial_adapters),
"ram": self._ram,
"nvram": self._nvram,
"l1_keepalives": self._l1_keepalives,
"use_default_iou_values": self._use_default_iou_values,
"command_line": self.command_line,
"application_id": self.application_id,
}
iou_vm_info["path"] = self.manager.get_relative_image_path(self.path, self.project.path)
return iou_vm_info
@@ -281,10 +290,11 @@ class IOUVM(BaseNode):
if self._ram == ram:
return
log.info('IOU "{name}" [{id}]: RAM updated from {old_ram}MB to {new_ram}MB'.format(name=self._name,
id=self._id,
old_ram=self._ram,
new_ram=ram))
log.info(
'IOU "{name}" [{id}]: RAM updated from {old_ram}MB to {new_ram}MB'.format(
name=self._name, id=self._id, old_ram=self._ram, new_ram=ram
)
)
self._ram = ram
@@ -309,10 +319,11 @@ class IOUVM(BaseNode):
if self._nvram == nvram:
return
log.info('IOU "{name}" [{id}]: NVRAM updated from {old_nvram}KB to {new_nvram}KB'.format(name=self._name,
id=self._id,
old_nvram=self._nvram,
new_nvram=nvram))
log.info(
'IOU "{name}" [{id}]: NVRAM updated from {old_nvram}KB to {new_nvram}KB'.format(
name=self._name, id=self._id, old_nvram=self._nvram, new_nvram=nvram
)
)
self._nvram = nvram
@BaseNode.name.setter
@@ -383,8 +394,11 @@ class IOUVM(BaseNode):
p = re.compile(r"([\.\w]+)\s=>\s+not found")
missing_libs = p.findall(output)
if missing_libs:
raise IOUError("The following shared library dependencies cannot be found for IOU image {}: {}".format(self._path,
", ".join(missing_libs)))
raise IOUError(
"The following shared library dependencies cannot be found for IOU image {}: {}".format(
self._path, ", ".join(missing_libs)
)
)
async def _check_iou_licence(self):
"""
@@ -422,9 +436,9 @@ class IOUVM(BaseNode):
if len(hostname) > 15:
log.warning(f"Older IOU images may not boot because hostname '{hostname}' length is above 15 characters")
if hostname not in config["license"]:
raise IOUError(f"Hostname \"{hostname}\" not found in iourc file {self.iourc_path}")
raise IOUError(f'Hostname "{hostname}" not found in iourc file {self.iourc_path}')
user_ioukey = config["license"][hostname]
if user_ioukey[-1:] != ';':
if user_ioukey[-1:] != ";":
raise IOUError(f"IOU key not ending with ; in iourc file {self.iourc_path}")
if len(user_ioukey) != 17:
raise IOUError(f"IOU key length is not 16 characters in iourc file {self.iourc_path}")
@@ -446,13 +460,15 @@ class IOUVM(BaseNode):
raise IOUError(f"Invalid hostid detected: {hostid}")
for x in hostname:
ioukey += ord(x)
pad1 = b'\x4B\x58\x21\x81\x56\x7B\x0D\xF3\x21\x43\x9B\x7E\xAC\x1D\xE6\x8A'
pad2 = b'\x80' + 39 * b'\0'
ioukey = hashlib.md5(pad1 + pad2 + struct.pack('!I', ioukey) + pad1).hexdigest()[:16]
pad1 = b"\x4B\x58\x21\x81\x56\x7B\x0D\xF3\x21\x43\x9B\x7E\xAC\x1D\xE6\x8A"
pad2 = b"\x80" + 39 * b"\0"
ioukey = hashlib.md5(pad1 + pad2 + struct.pack("!I", ioukey) + pad1).hexdigest()[:16]
if ioukey != user_ioukey:
raise IOUError("Invalid IOU license key {} detected in iourc file {} for host {}".format(user_ioukey,
self.iourc_path,
hostname))
raise IOUError(
"Invalid IOU license key {} detected in iourc file {} for host {}".format(
user_ioukey, self.iourc_path, hostname
)
)
def _nvram_file(self):
"""
@@ -545,14 +561,15 @@ class IOUVM(BaseNode):
command = await self._build_command()
try:
log.info(f"Starting IOU: {command}")
self.command_line = ' '.join(command)
self.command_line = " ".join(command)
self._iou_process = await asyncio.create_subprocess_exec(
*command,
stdout=asyncio.subprocess.PIPE,
stdin=asyncio.subprocess.PIPE,
stderr=subprocess.STDOUT,
cwd=self.working_dir,
env=env)
env=env,
)
log.info(f"IOU instance {self._id} started PID={self._iou_process.pid}")
self._started = True
self.status = "started"
@@ -576,16 +593,20 @@ class IOUVM(BaseNode):
"""
if self.console and self.console_type == "telnet":
server = AsyncioTelnetServer(reader=self._iou_process.stdout, writer=self._iou_process.stdin, binary=True,
echo=True)
server = AsyncioTelnetServer(
reader=self._iou_process.stdout, writer=self._iou_process.stdin, binary=True, echo=True
)
try:
self._telnet_server = await asyncio.start_server(server.run, self._manager.port_manager.console_host,
self.console)
self._telnet_server = await asyncio.start_server(
server.run, self._manager.port_manager.console_host, self.console
)
except OSError as e:
await self.stop()
raise IOUError(
"Could not start Telnet server on socket {}:{}: {}".format(self._manager.port_manager.console_host,
self.console, e))
"Could not start Telnet server on socket {}:{}: {}".format(
self._manager.port_manager.console_host, self.console, e
)
)
async def reset_console(self):
"""
@@ -618,17 +639,25 @@ class IOUVM(BaseNode):
for unit in adapter.ports.keys():
nio = adapter.get_nio(unit)
if nio and isinstance(nio, NIOUDP):
await self._ubridge_send("iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format(name=bridge_name,
iol_id=self.application_id,
bay=bay_id,
unit=unit_id,
lport=nio.lport,
rhost=nio.rhost,
rport=nio.rport))
await self._ubridge_send(
"iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format(
name=bridge_name,
iol_id=self.application_id,
bay=bay_id,
unit=unit_id,
lport=nio.lport,
rhost=nio.rhost,
rport=nio.rport,
)
)
if nio.capturing:
await self._ubridge_send('iol_bridge start_capture {name} "{output_file}" {data_link_type}'.format(name=bridge_name,
output_file=nio.pcap_output_file,
data_link_type=re.sub(r"^DLT_", "", nio.pcap_data_link_type)))
await self._ubridge_send(
'iol_bridge start_capture {name} "{output_file}" {data_link_type}'.format(
name=bridge_name,
output_file=nio.pcap_output_file,
data_link_type=re.sub(r"^DLT_", "", nio.pcap_data_link_type),
)
)
await self._ubridge_apply_filters(bay_id, unit_id, nio.filters)
unit_id += 1
@@ -646,11 +675,13 @@ class IOUVM(BaseNode):
self._terminate_process_iou()
if returncode != 0:
if returncode == -11:
message = 'IOU VM "{}" process has stopped with return code: {} (segfault). This could be an issue with the IOU image, using a different image may fix this.\n{}'.format(self.name,
returncode,
self.read_iou_stdout())
message = 'IOU VM "{}" process has stopped with return code: {} (segfault). This could be an issue with the IOU image, using a different image may fix this.\n{}'.format(
self.name, returncode, self.read_iou_stdout()
)
else:
message = f'IOU VM "{self.name}" process has stopped with return code: {returncode}\n{self.read_iou_stdout()}'
message = (
f'IOU VM "{self.name}" process has stopped with return code: {returncode}\n{self.read_iou_stdout()}'
)
log.warning(message)
self.project.emit("log.error", {"message": message})
if self._telnet_server:
@@ -764,12 +795,15 @@ class IOUVM(BaseNode):
with open(netmap_path, "w", encoding="utf-8") as f:
for bay in range(0, 16):
for unit in range(0, 4):
f.write("{ubridge_id}:{bay}/{unit}{iou_id:>5d}:{bay}/{unit}\n".format(ubridge_id=str(self.application_id + 512),
bay=bay,
unit=unit,
iou_id=self.application_id))
log.info("IOU {name} [id={id}]: NETMAP file created".format(name=self._name,
id=self._id))
f.write(
"{ubridge_id}:{bay}/{unit}{iou_id:>5d}:{bay}/{unit}\n".format(
ubridge_id=str(self.application_id + 512),
bay=bay,
unit=unit,
iou_id=self.application_id,
)
)
log.info("IOU {name} [id={id}]: NETMAP file created".format(name=self._name, id=self._id))
except OSError as e:
raise IOUError(f"Could not create {netmap_path}: {e}")
@@ -813,7 +847,7 @@ class IOUVM(BaseNode):
command.extend(["-m", str(self._ram)])
# do not let IOU create the NVRAM anymore
#startup_config_file = self.startup_config_file
# startup_config_file = self.startup_config_file
# if startup_config_file:
# command.extend(["-c", os.path.basename(startup_config_file)])
@@ -863,9 +897,11 @@ class IOUVM(BaseNode):
for _ in range(0, ethernet_adapters):
self._ethernet_adapters.append(EthernetAdapter(interfaces=4))
log.info('IOU "{name}" [{id}]: number of Ethernet adapters changed to {adapters}'.format(name=self._name,
id=self._id,
adapters=len(self._ethernet_adapters)))
log.info(
'IOU "{name}" [{id}]: number of Ethernet adapters changed to {adapters}'.format(
name=self._name, id=self._id, adapters=len(self._ethernet_adapters)
)
)
self._adapters = self._ethernet_adapters + self._serial_adapters
@@ -891,9 +927,11 @@ class IOUVM(BaseNode):
for _ in range(0, serial_adapters):
self._serial_adapters.append(SerialAdapter(interfaces=4))
log.info('IOU "{name}" [{id}]: number of Serial adapters changed to {adapters}'.format(name=self._name,
id=self._id,
adapters=len(self._serial_adapters)))
log.info(
'IOU "{name}" [{id}]: number of Serial adapters changed to {adapters}'.format(
name=self._name, id=self._id, adapters=len(self._serial_adapters)
)
)
self._adapters = self._ethernet_adapters + self._serial_adapters
@@ -909,29 +947,39 @@ class IOUVM(BaseNode):
try:
adapter = self._adapters[adapter_number]
except IndexError:
raise IOUError('Adapter {adapter_number} does not exist for IOU "{name}"'.format(name=self._name,
adapter_number=adapter_number))
raise IOUError(
'Adapter {adapter_number} does not exist for IOU "{name}"'.format(
name=self._name, adapter_number=adapter_number
)
)
if not adapter.port_exists(port_number):
raise IOUError("Port {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
port_number=port_number))
raise IOUError(
"Port {port_number} does not exist on adapter {adapter}".format(
adapter=adapter, port_number=port_number
)
)
adapter.add_nio(port_number, nio)
log.info('IOU "{name}" [{id}]: {nio} added to {adapter_number}/{port_number}'.format(name=self._name,
id=self._id,
nio=nio,
adapter_number=adapter_number,
port_number=port_number))
log.info(
'IOU "{name}" [{id}]: {nio} added to {adapter_number}/{port_number}'.format(
name=self._name, id=self._id, nio=nio, adapter_number=adapter_number, port_number=port_number
)
)
if self.ubridge:
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
await self._ubridge_send("iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format(name=bridge_name,
iol_id=self.application_id,
bay=adapter_number,
unit=port_number,
lport=nio.lport,
rhost=nio.rhost,
rport=nio.rport))
await self._ubridge_send(
"iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format(
name=bridge_name,
iol_id=self.application_id,
bay=adapter_number,
unit=port_number,
lport=nio.lport,
rhost=nio.rhost,
rport=nio.rport,
)
)
await self._ubridge_apply_filters(adapter_number, port_number, nio.filters)
async def adapter_update_nio_binding(self, adapter_number, port_number, nio):
@@ -955,15 +1003,10 @@ class IOUVM(BaseNode):
:param filters: Array of filter dictionnary
"""
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
location = '{bridge_name} {bay} {unit}'.format(
bridge_name=bridge_name,
bay=adapter_number,
unit=port_number)
await self._ubridge_send('iol_bridge reset_packet_filters ' + location)
location = "{bridge_name} {bay} {unit}".format(bridge_name=bridge_name, bay=adapter_number, unit=port_number)
await self._ubridge_send("iol_bridge reset_packet_filters " + location)
for filter in self._build_filter_list(filters):
cmd = 'iol_bridge add_packet_filter {} {}'.format(
location,
filter)
cmd = "iol_bridge add_packet_filter {} {}".format(location, filter)
await self._ubridge_send(cmd)
async def adapter_remove_nio_binding(self, adapter_number, port_number):
@@ -979,28 +1022,36 @@ class IOUVM(BaseNode):
try:
adapter = self._adapters[adapter_number]
except IndexError:
raise IOUError('Adapter {adapter_number} does not exist on IOU "{name}"'.format(name=self._name,
adapter_number=adapter_number))
raise IOUError(
'Adapter {adapter_number} does not exist on IOU "{name}"'.format(
name=self._name, adapter_number=adapter_number
)
)
if not adapter.port_exists(port_number):
raise IOUError("Port {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
port_number=port_number))
raise IOUError(
"Port {port_number} does not exist on adapter {adapter}".format(
adapter=adapter, port_number=port_number
)
)
nio = adapter.get_nio(port_number)
if isinstance(nio, NIOUDP):
self.manager.port_manager.release_udp_port(nio.lport, self._project)
adapter.remove_nio(port_number)
log.info('IOU "{name}" [{id}]: {nio} removed from {adapter_number}/{port_number}'.format(name=self._name,
id=self._id,
nio=nio,
adapter_number=adapter_number,
port_number=port_number))
log.info(
'IOU "{name}" [{id}]: {nio} removed from {adapter_number}/{port_number}'.format(
name=self._name, id=self._id, nio=nio, adapter_number=adapter_number, port_number=port_number
)
)
if self.ubridge:
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
await self._ubridge_send("iol_bridge delete_nio_udp {name} {bay} {unit}".format(name=bridge_name,
bay=adapter_number,
unit=port_number))
await self._ubridge_send(
"iol_bridge delete_nio_udp {name} {bay} {unit}".format(
name=bridge_name, bay=adapter_number, unit=port_number
)
)
return nio
@@ -1017,18 +1068,25 @@ class IOUVM(BaseNode):
try:
adapter = self._adapters[adapter_number]
except IndexError:
raise IOUError('Adapter {adapter_number} does not exist on IOU "{name}"'.format(name=self._name,
adapter_number=adapter_number))
raise IOUError(
'Adapter {adapter_number} does not exist on IOU "{name}"'.format(
name=self._name, adapter_number=adapter_number
)
)
if not adapter.port_exists(port_number):
raise IOUError("Port {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
port_number=port_number))
raise IOUError(
"Port {port_number} does not exist on adapter {adapter}".format(
adapter=adapter, port_number=port_number
)
)
nio = adapter.get_nio(port_number)
if not nio:
raise IOUError("NIO {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
port_number=port_number))
raise IOUError(
"NIO {port_number} does not exist on adapter {adapter}".format(adapter=adapter, port_number=port_number)
)
return nio
@property
@@ -1066,13 +1124,17 @@ class IOUVM(BaseNode):
if "IOURC" not in os.environ:
env["IOURC"] = self.iourc_path
try:
output = await gns3server.utils.asyncio.subprocess_check_output(self._path, "-h", cwd=self.working_dir, env=env, stderr=True)
output = await gns3server.utils.asyncio.subprocess_check_output(
self._path, "-h", cwd=self.working_dir, env=env, stderr=True
)
if re.search(r"-l\s+Enable Layer 1 keepalive messages", output):
command.extend(["-l"])
else:
raise IOUError(f"layer 1 keepalive messages are not supported by {os.path.basename(self._path)}")
except (OSError, subprocess.SubprocessError) as e:
log.warning(f"could not determine if layer 1 keepalive messages are supported by {os.path.basename(self._path)}: {e}")
log.warning(
f"could not determine if layer 1 keepalive messages are supported by {os.path.basename(self._path)}: {e}"
)
@property
def startup_config_content(self):
@@ -1102,15 +1164,15 @@ class IOUVM(BaseNode):
startup_config_path = os.path.join(self.working_dir, "startup-config.cfg")
if startup_config is None:
startup_config = ''
startup_config = ""
# We disallow erasing the startup config file
if len(startup_config) == 0 and os.path.exists(startup_config_path):
return
with open(startup_config_path, 'w+', encoding='utf-8') as f:
with open(startup_config_path, "w+", encoding="utf-8") as f:
if len(startup_config) == 0:
f.write('')
f.write("")
else:
startup_config = startup_config.replace("%h", self._name)
f.write(startup_config)
@@ -1153,15 +1215,15 @@ class IOUVM(BaseNode):
private_config_path = os.path.join(self.working_dir, "private-config.cfg")
if private_config is None:
private_config = ''
private_config = ""
# We disallow erasing the private config file
if len(private_config) == 0 and os.path.exists(private_config_path):
return
with open(private_config_path, 'w+', encoding='utf-8') as f:
with open(private_config_path, "w+", encoding="utf-8") as f:
if len(private_config) == 0:
f.write('')
f.write("")
else:
private_config = private_config.replace("%h", self._name)
f.write(private_config)
@@ -1176,7 +1238,7 @@ class IOUVM(BaseNode):
:returns: path to config file. None if the file doesn't exist
"""
path = os.path.join(self.working_dir, 'startup-config.cfg')
path = os.path.join(self.working_dir, "startup-config.cfg")
if os.path.exists(path):
return path
else:
@@ -1190,7 +1252,7 @@ class IOUVM(BaseNode):
:returns: path to config file. None if the file doesn't exist
"""
path = os.path.join(self.working_dir, 'private-config.cfg')
path = os.path.join(self.working_dir, "private-config.cfg")
if os.path.exists(path):
return path
else:
@@ -1205,9 +1267,9 @@ class IOUVM(BaseNode):
:returns: path to startup-config file. None if the file doesn't exist
"""
path = os.path.join(self.working_dir, 'startup-config.cfg')
path = os.path.join(self.working_dir, "startup-config.cfg")
if os.path.exists(path):
return 'startup-config.cfg'
return "startup-config.cfg"
else:
return None
@@ -1219,9 +1281,9 @@ class IOUVM(BaseNode):
:returns: path to private-config file. None if the file doesn't exist
"""
path = os.path.join(self.working_dir, 'private-config.cfg')
path = os.path.join(self.working_dir, "private-config.cfg")
if os.path.exists(path):
return 'private-config.cfg'
return "private-config.cfg"
else:
return None
@@ -1288,7 +1350,7 @@ class IOUVM(BaseNode):
except (binascii.Error, OSError) as e:
raise IOUError(f"Could not save the startup configuration {config_path}: {e}")
if private_config_content and private_config_content != b'\nend\n':
if private_config_content and private_config_content != b"\nend\n":
config_path = os.path.join(self.working_dir, "private-config.cfg")
try:
config = private_config_content.decode("utf-8", errors="replace")
@@ -1310,23 +1372,34 @@ class IOUVM(BaseNode):
nio = self.get_nio(adapter_number, port_number)
if nio.capturing:
raise IOUError("Packet capture is already activated on {adapter_number}/{port_number}".format(adapter_number=adapter_number,
port_number=port_number))
raise IOUError(
"Packet capture is already activated on {adapter_number}/{port_number}".format(
adapter_number=adapter_number, port_number=port_number
)
)
nio.start_packet_capture(output_file, data_link_type)
log.info('IOU "{name}" [{id}]: starting packet capture on {adapter_number}/{port_number} to {output_file}'.format(name=self._name,
id=self._id,
adapter_number=adapter_number,
port_number=port_number,
output_file=output_file))
log.info(
'IOU "{name}" [{id}]: starting packet capture on {adapter_number}/{port_number} to {output_file}'.format(
name=self._name,
id=self._id,
adapter_number=adapter_number,
port_number=port_number,
output_file=output_file,
)
)
if self.ubridge:
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
await self._ubridge_send('iol_bridge start_capture {name} {bay} {unit} "{output_file}" {data_link_type}'.format(name=bridge_name,
bay=adapter_number,
unit=port_number,
output_file=output_file,
data_link_type=re.sub(r"^DLT_", "", data_link_type)))
await self._ubridge_send(
'iol_bridge start_capture {name} {bay} {unit} "{output_file}" {data_link_type}'.format(
name=bridge_name,
bay=adapter_number,
unit=port_number,
output_file=output_file,
data_link_type=re.sub(r"^DLT_", "", data_link_type),
)
)
async def stop_capture(self, adapter_number, port_number):
"""
@@ -1340,12 +1413,15 @@ class IOUVM(BaseNode):
if not nio.capturing:
return
nio.stop_packet_capture()
log.info('IOU "{name}" [{id}]: stopping packet capture on {adapter_number}/{port_number}'.format(name=self._name,
id=self._id,
adapter_number=adapter_number,
port_number=port_number))
log.info(
'IOU "{name}" [{id}]: stopping packet capture on {adapter_number}/{port_number}'.format(
name=self._name, id=self._id, adapter_number=adapter_number, port_number=port_number
)
)
if self.ubridge:
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
await self._ubridge_send('iol_bridge stop_capture {name} {bay} {unit}'.format(name=bridge_name,
bay=adapter_number,
unit=port_number))
await self._ubridge_send(
"iol_bridge stop_capture {name} {bay} {unit}".format(
name=bridge_name, bay=adapter_number, unit=port_number
)
)
+34 -37
View File
@@ -47,28 +47,28 @@ def uncompress_LZC(data):
LZC_NUM_BITS_MIN = 9
LZC_NUM_BITS_MAX = 16
in_data = bytearray(data)
in_len = len(in_data)
in_data = bytearray(data)
in_len = len(in_data)
out_data = bytearray()
if in_len == 0:
return out_data
if in_len < 3:
raise ValueError('invalid length')
raise ValueError("invalid length")
if in_data[0] != 0x1F or in_data[1] != 0x9D:
raise ValueError('invalid header')
raise ValueError("invalid header")
max_bits = in_data[2] & 0x1F
if max_bits < LZC_NUM_BITS_MIN or max_bits > LZC_NUM_BITS_MAX:
raise ValueError('not supported')
raise ValueError("not supported")
num_items = 1 << max_bits
blockmode = (in_data[2] & 0x80) != 0
in_pos = 3
in_pos = 3
start_pos = in_pos
num_bits = LZC_NUM_BITS_MIN
num_bits = LZC_NUM_BITS_MIN
dict_size = 1 << num_bits
head = 256
head = 256
if blockmode:
head += 1
first_sym = True
@@ -89,7 +89,7 @@ def uncompress_LZC(data):
buf, symbol = divmod(buf, dict_size)
buf_bits -= num_bits
except IndexError:
raise ValueError('invalid data')
raise ValueError("invalid data")
# re-initialize dictionary
if blockmode and symbol == 256:
@@ -108,7 +108,7 @@ def uncompress_LZC(data):
if first_sym:
first_sym = False
if symbol >= 256:
raise ValueError('invalid data')
raise ValueError("invalid data")
prev = symbol
out_data.extend(comp_dict[symbol])
continue
@@ -124,7 +124,7 @@ def uncompress_LZC(data):
elif symbol == head:
comp_dict[head] = comp_dict[prev] + comp_dict[prev][0:1]
else:
raise ValueError('invalid data')
raise ValueError("invalid data")
prev = symbol
# output symbol
@@ -148,42 +148,42 @@ def nvram_export(nvram):
offset = 0
# extract startup config
try:
(magic, data_format, _, _, _, _, length, _, _, _, _, _) = \
struct.unpack_from('>HHHHIIIIIHHI', nvram, offset=offset)
(magic, data_format, _, _, _, _, length, _, _, _, _, _) = struct.unpack_from(
">HHHHIIIIIHHI", nvram, offset=offset
)
offset += 36
if magic != 0xABCD:
raise ValueError('no startup config')
if len(nvram) < offset+length:
raise ValueError('invalid length')
startup = nvram[offset:offset+length]
raise ValueError("no startup config")
if len(nvram) < offset + length:
raise ValueError("invalid length")
startup = nvram[offset : offset + length]
except struct.error:
raise ValueError('invalid length')
raise ValueError("invalid length")
# uncompress startup config
if data_format == 2:
try:
startup = uncompress_LZC(startup)
except ValueError as err:
raise ValueError('uncompress startup: ' + str(err))
raise ValueError("uncompress startup: " + str(err))
private = None
try:
# calculate offset of private header
length += (4 - length % 4) % 4 # alignment to multiple of 4
length += (4 - length % 4) % 4 # alignment to multiple of 4
offset += length
# check for additonal offset of 4
(magic, data_format) = struct.unpack_from('>HH', nvram, offset=offset+4)
(magic, data_format) = struct.unpack_from(">HH", nvram, offset=offset + 4)
if magic == 0xFEDC and data_format == 1:
offset += 4
# extract private config
(magic, data_format, _, _, length) = \
struct.unpack_from('>HHIII', nvram, offset=offset)
(magic, data_format, _, _, length) = struct.unpack_from(">HHIII", nvram, offset=offset)
offset += 16
if magic == 0xFEDC and data_format == 1:
if len(nvram) < offset+length:
raise ValueError('invalid length')
private = nvram[offset:offset+length]
if len(nvram) < offset + length:
raise ValueError("invalid length")
private = nvram[offset : offset + length]
# missing private header is not an error
except struct.error:
@@ -192,22 +192,19 @@ def nvram_export(nvram):
return (startup, private)
if __name__ == '__main__':
if __name__ == "__main__":
# Main program
import argparse
import sys
parser = argparse.ArgumentParser(description='%(prog)s exports startup/private configuration from IOU NVRAM file.')
parser.add_argument('nvram', metavar='NVRAM',
help='NVRAM file')
parser.add_argument('startup', metavar='startup-config',
help='startup configuration')
parser.add_argument('private', metavar='private-config', nargs='?',
help='private configuration')
parser = argparse.ArgumentParser(description="%(prog)s exports startup/private configuration from IOU NVRAM file.")
parser.add_argument("nvram", metavar="NVRAM", help="NVRAM file")
parser.add_argument("startup", metavar="startup-config", help="startup configuration")
parser.add_argument("private", metavar="private-config", nargs="?", help="private configuration")
args = parser.parse_args()
try:
fd = open(args.nvram, 'rb')
fd = open(args.nvram, "rb")
nvram = fd.read()
fd.close()
except OSError as err:
@@ -221,14 +218,14 @@ if __name__ == '__main__':
sys.exit(3)
try:
fd = open(args.startup, 'wb')
fd = open(args.startup, "wb")
fd.write(startup)
fd.close()
if args.private is not None:
if private is None:
sys.stderr.write("Warning: No private config\n")
else:
fd = open(args.private, 'wb')
fd = open(args.private, "wb")
fd.write(private)
fd.close()
except OSError as err:
+62 -57
View File
@@ -39,7 +39,7 @@ import struct
# calculate padding
def padding(length, start_address):
pad = -length % 4 # padding to alignment of 4
pad = -length % 4 # padding to alignment of 4
# extra padding if pad != 0 and big start_address
if pad != 0 and (start_address & 0x80000000) != 0:
pad += 4
@@ -50,66 +50,64 @@ def padding(length, start_address):
def checksum(data, start, end):
chk = 0
# calculate checksum of first two words
for word in struct.unpack_from('>2H', data, start):
for word in struct.unpack_from(">2H", data, start):
chk += word
# add remaining words, ignoring old checksum at offset 4
struct_format = f'>{(end - start - 6) // 2:d}H'
for word in struct.unpack_from(struct_format, data, start+6):
struct_format = f">{(end - start - 6) // 2:d}H"
for word in struct.unpack_from(struct_format, data, start + 6):
chk += word
# handle 16 bit overflow
while chk >> 16:
chk = (chk & 0xffff) + (chk >> 16)
chk = chk ^ 0xffff
chk = (chk & 0xFFFF) + (chk >> 16)
chk = chk ^ 0xFFFF
# save checksum
struct.pack_into('>H', data, start+4, chk)
struct.pack_into(">H", data, start + 4, chk)
# import IOU NVRAM
# NVRAM format: https://github.com/ehlers/IOUtools/blob/master/NVRAM.md
def nvram_import(nvram, startup, private, size):
DEFAULT_IOS = 0x0F04 # IOS 15.4
DEFAULT_IOS = 0x0F04 # IOS 15.4
base_address = 0x10000000
# check size parameter
if size is not None and (size < 8 or size > 1024):
raise ValueError('invalid size')
raise ValueError("invalid size")
# create new nvram if nvram is empty or has wrong size
if nvram is None or (size is not None and len(nvram) != size*1024):
nvram = bytearray([0] * (size*1024))
if nvram is None or (size is not None and len(nvram) != size * 1024):
nvram = bytearray([0] * (size * 1024))
else:
nvram = bytearray(nvram)
# check nvram size
nvram_len = len(nvram)
if nvram_len < 8*1024 or nvram_len > 1024*1024 or nvram_len % 1024 != 0:
raise ValueError('invalid NVRAM length')
if nvram_len < 8 * 1024 or nvram_len > 1024 * 1024 or nvram_len % 1024 != 0:
raise ValueError("invalid NVRAM length")
nvram_len = nvram_len // 2
# get size of current config
config_len = 0
try:
(magic, _, _, ios, start_addr, _, length, _, _, _, _, _) = \
struct.unpack_from('>HHHHIIIIIHHI', nvram, offset=0)
(magic, _, _, ios, start_addr, _, length, _, _, _, _, _) = struct.unpack_from(">HHHHIIIIIHHI", nvram, offset=0)
if magic == 0xABCD:
base_address = start_addr - 36
config_len = 36 + length + padding(length, base_address)
(magic, _, _, _, length) = \
struct.unpack_from('>HHIII', nvram, offset=config_len)
(magic, _, _, _, length) = struct.unpack_from(">HHIII", nvram, offset=config_len)
if magic == 0xFEDC:
config_len += 16 + length
else:
ios = None
except struct.error:
raise ValueError('unknown nvram format')
raise ValueError("unknown nvram format")
if config_len > nvram_len:
raise ValueError('unknown nvram format')
raise ValueError("unknown nvram format")
# calculate max. config size
max_config = nvram_len - 2*1024 # reserve 2k for files
max_config = nvram_len - 2 * 1024 # reserve 2k for files
idx = max_config
empty_sector = bytearray([0] * 1024)
while True:
@@ -117,11 +115,10 @@ def nvram_import(nvram, startup, private, size):
if idx < config_len:
break
# if valid file header:
(magic, _, flags, length, _) = \
struct.unpack_from('>HHHH24s', nvram, offset=idx)
(magic, _, flags, length, _) = struct.unpack_from(">HHHH24s", nvram, offset=idx)
if magic == 0xDCBA and flags < 8 and length <= 992:
max_config = idx
elif nvram[idx:idx+1024] != empty_sector:
elif nvram[idx : idx + 1024] != empty_sector:
break
# import startup config
@@ -131,34 +128,46 @@ def nvram_import(nvram, startup, private, size):
# the padding of a different version, the startup config is padded
# with '\n' to the alignment of 4.
ios = DEFAULT_IOS
startup += b'\n' * (-len(startup) % 4)
new_nvram.extend(struct.pack('>HHHHIIIIIHHI',
0xABCD, # magic
1, # raw data
0, # checksum, not yet calculated
ios, # IOS version
base_address + 36, # start address
base_address + 36 + len(startup), # end address
len(startup), # length
0, 0, 0, 0, 0))
startup += b"\n" * (-len(startup) % 4)
new_nvram.extend(
struct.pack(
">HHHHIIIIIHHI",
0xABCD, # magic
1, # raw data
0, # checksum, not yet calculated
ios, # IOS version
base_address + 36, # start address
base_address + 36 + len(startup), # end address
len(startup), # length
0,
0,
0,
0,
0,
)
)
new_nvram.extend(startup)
new_nvram.extend([0] * padding(len(new_nvram), base_address))
# import private config
if private is None:
private = b''
private = b""
offset = len(new_nvram)
new_nvram.extend(struct.pack('>HHIII',
0xFEDC, # magic
1, # raw data
base_address + offset + 16, # start address
base_address + offset + 16 + len(private), # end address
len(private) )) # length
new_nvram.extend(
struct.pack(
">HHIII",
0xFEDC, # magic
1, # raw data
base_address + offset + 16, # start address
base_address + offset + 16 + len(private), # end address
len(private),
)
) # length
new_nvram.extend(private)
# add rest
if len(new_nvram) > max_config:
raise ValueError('NVRAM size too small')
raise ValueError("NVRAM size too small")
new_nvram.extend([0] * (max_config - len(new_nvram)))
new_nvram.extend(nvram[max_config:])
@@ -167,7 +176,7 @@ def nvram_import(nvram, startup, private, size):
return new_nvram
if __name__ == '__main__':
if __name__ == "__main__":
# Main program
import argparse
import sys
@@ -176,36 +185,32 @@ if __name__ == '__main__':
try:
value = int(string)
except ValueError:
raise argparse.ArgumentTypeError('invalid int value: ' + string)
raise argparse.ArgumentTypeError("invalid int value: " + string)
if value < 8 or value > 1024:
raise argparse.ArgumentTypeError('size must be 8..1024')
raise argparse.ArgumentTypeError("size must be 8..1024")
return value
parser = argparse.ArgumentParser(description='%(prog)s imports startup/private configuration into IOU NVRAM file.')
parser.add_argument('-c', '--create', metavar='size', type=check_size,
help='create NVRAM file, size in kByte')
parser.add_argument('nvram', metavar='NVRAM',
help='NVRAM file')
parser.add_argument('startup', metavar='startup-config',
help='startup configuration')
parser.add_argument('private', metavar='private-config', nargs='?',
help='private configuration')
parser = argparse.ArgumentParser(description="%(prog)s imports startup/private configuration into IOU NVRAM file.")
parser.add_argument("-c", "--create", metavar="size", type=check_size, help="create NVRAM file, size in kByte")
parser.add_argument("nvram", metavar="NVRAM", help="NVRAM file")
parser.add_argument("startup", metavar="startup-config", help="startup configuration")
parser.add_argument("private", metavar="private-config", nargs="?", help="private configuration")
args = parser.parse_args()
try:
if args.create is None:
fd = open(args.nvram, 'rb')
fd = open(args.nvram, "rb")
nvram = fd.read()
fd.close()
else:
nvram = None
fd = open(args.startup, 'rb')
fd = open(args.startup, "rb")
startup = fd.read()
fd.close()
if args.private is None:
private = None
else:
fd = open(args.private, 'rb')
fd = open(args.private, "rb")
private = fd.read()
fd.close()
except OSError as err:
@@ -219,7 +224,7 @@ if __name__ == '__main__':
sys.exit(3)
try:
fd = open(args.nvram, 'wb')
fd = open(args.nvram, "wb")
fd.write(nvram)
fd.close()
except OSError as err: