mirror of
https://github.com/GNS3/gns3-server
synced 2024-12-25 16:28:11 +00:00
Sync with IOU tools (nvram import/export).
This commit is contained in:
parent
65e7f61f96
commit
815b7d226c
@ -439,8 +439,10 @@ class IOUVM(BaseVM):
|
||||
try:
|
||||
if not os.path.exists(nvram_file):
|
||||
open(nvram_file, "a").close()
|
||||
with open(nvram_file, "rb") as file:
|
||||
nvram_content = file.read()
|
||||
nvram_content = None
|
||||
else:
|
||||
with open(nvram_file, "rb") as file:
|
||||
nvram_content = file.read()
|
||||
except OSError as e:
|
||||
raise IOUError("Cannot read nvram file {}: {}".format(nvram_file, e))
|
||||
|
||||
|
@ -39,7 +39,6 @@ optional arguments:
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from array import array
|
||||
|
||||
|
||||
# Uncompress data in .Z file format.
|
||||
@ -49,12 +48,12 @@ def uncompress_LZC(data):
|
||||
LZC_NUM_BITS_MIN = 9
|
||||
LZC_NUM_BITS_MAX = 16
|
||||
|
||||
in_data = array('B', data)
|
||||
in_data = bytearray(data)
|
||||
in_len = len(in_data)
|
||||
out_data = array('B')
|
||||
out_data = bytearray()
|
||||
|
||||
if in_len == 0:
|
||||
return out_data.tostring()
|
||||
return out_data
|
||||
if in_len < 3:
|
||||
raise ValueError('invalid length')
|
||||
if in_data[0] != 0x1F or in_data[1] != 0x9D:
|
||||
@ -66,9 +65,8 @@ def uncompress_LZC(data):
|
||||
if maxbits < LZC_NUM_BITS_MIN or maxbits > LZC_NUM_BITS_MAX:
|
||||
raise ValueError('not supported')
|
||||
|
||||
parents = array('H', [0] * numItems)
|
||||
suffixes = array('B', [0] * numItems)
|
||||
stack = array('B', [0] * numItems)
|
||||
parents = [0] * numItems
|
||||
suffixes = [0] * numItems
|
||||
|
||||
in_pos = 3
|
||||
numBits = LZC_NUM_BITS_MIN
|
||||
@ -83,7 +81,7 @@ def uncompress_LZC(data):
|
||||
parents[256] = 0
|
||||
suffixes[256] = 0
|
||||
|
||||
buf_extend = array('B', [0] * 3)
|
||||
buf_extend = bytearray([0] * 3)
|
||||
|
||||
while True:
|
||||
# fill buffer, when empty
|
||||
@ -114,19 +112,18 @@ def uncompress_LZC(data):
|
||||
continue
|
||||
|
||||
# convert symbol to string
|
||||
stack = []
|
||||
cur = symbol
|
||||
i = len(stack)
|
||||
while cur >= 256:
|
||||
i -= 1
|
||||
stack[i] = suffixes[cur]
|
||||
stack.append(suffixes[cur])
|
||||
cur = parents[cur]
|
||||
i -= 1
|
||||
stack[i] = cur
|
||||
stack.append(cur)
|
||||
if needPrev:
|
||||
suffixes[head - 1] = cur
|
||||
if symbol == head - 1:
|
||||
stack[-1] = cur
|
||||
out_data.extend(stack[i:])
|
||||
stack[0] = cur
|
||||
stack.reverse()
|
||||
out_data.extend(stack)
|
||||
|
||||
# update parents, check for numBits change
|
||||
if head < numItems:
|
||||
@ -140,7 +137,7 @@ def uncompress_LZC(data):
|
||||
else:
|
||||
needPrev = 0
|
||||
|
||||
return out_data.tostring()
|
||||
return out_data
|
||||
|
||||
|
||||
# extract 16 bit unsigned int from data
|
||||
@ -155,7 +152,7 @@ def get_uint32(data, off):
|
||||
|
||||
# export IOU NVRAM
|
||||
def nvram_export(nvram):
|
||||
nvram = array('B', nvram)
|
||||
nvram = bytearray(nvram)
|
||||
|
||||
# extract startup config
|
||||
offset = 0
|
||||
@ -168,7 +165,7 @@ def nvram_export(nvram):
|
||||
offset += 36
|
||||
if len(nvram) < offset + length:
|
||||
raise ValueError('invalid length')
|
||||
startup = nvram[offset:offset+length].tostring()
|
||||
startup = nvram[offset:offset+length]
|
||||
|
||||
# compressed startup config
|
||||
if format == 2:
|
||||
@ -192,7 +189,7 @@ def nvram_export(nvram):
|
||||
length = get_uint32(nvram, offset + 12)
|
||||
offset += 16
|
||||
if len(nvram) >= offset + length:
|
||||
private = nvram[offset:offset+length].tostring()
|
||||
private = nvram[offset:offset+length]
|
||||
|
||||
return (startup, private)
|
||||
|
||||
|
@ -37,7 +37,6 @@ optional arguments:
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from array import array
|
||||
|
||||
|
||||
# extract 16 bit unsigned int from data
|
||||
@ -96,15 +95,20 @@ def nvram_import(nvram, startup, private, size):
|
||||
BASE_ADDRESS = 0x10000000
|
||||
DEFAULT_IOS = 0x0F04 # IOS 15.4
|
||||
|
||||
if size is None:
|
||||
nvram = array('B', nvram)
|
||||
# check size parameter
|
||||
if size is not None and (size < 8 or size > 1024):
|
||||
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))
|
||||
else:
|
||||
nvram = array('B', [0] * (size*1024))
|
||||
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 length')
|
||||
raise ValueError('invalid NVRAM length')
|
||||
nvram_len = nvram_len // 2
|
||||
|
||||
# get size of current config
|
||||
@ -125,7 +129,7 @@ def nvram_import(nvram, startup, private, size):
|
||||
# calculate max. config size
|
||||
max_config = nvram_len - 2*1024 # reserve 2k for files
|
||||
idx = max_config
|
||||
empty_sector = array('B', [0] * 1024)
|
||||
empty_sector = bytearray([0] * 1024)
|
||||
while True:
|
||||
idx -= 1024
|
||||
if idx < config_len:
|
||||
@ -139,14 +143,14 @@ def nvram_import(nvram, startup, private, size):
|
||||
break
|
||||
|
||||
# import startup config
|
||||
startup = array('B', startup)
|
||||
startup = bytearray(startup)
|
||||
if ios is None:
|
||||
# Target IOS version is unknown. As some IOU don't work nicely with
|
||||
# the padding of a different version, the startup config is padded
|
||||
# with '\n' to the alignment of 4.
|
||||
ios = DEFAULT_IOS
|
||||
startup.extend([ord('\n')] * ((4 - len(startup) % 4) % 4))
|
||||
new_nvram = array('B', [0] * 36) # startup hdr
|
||||
new_nvram = bytearray([0] * 36) # startup hdr
|
||||
put_uint16(new_nvram, 0, 0xABCD) # magic
|
||||
put_uint16(new_nvram, 2, 1) # raw data
|
||||
put_uint16(new_nvram, 6, ios) # IOS version
|
||||
@ -158,9 +162,9 @@ def nvram_import(nvram, startup, private, size):
|
||||
|
||||
# import private config
|
||||
if private is None:
|
||||
private = array('B')
|
||||
private = bytearray()
|
||||
else:
|
||||
private = array('B', private)
|
||||
private = bytearray(private)
|
||||
offset = len(new_nvram)
|
||||
new_nvram.extend([0] * 16) # private hdr
|
||||
put_uint16(new_nvram, 0 + offset, 0xFEDC) # magic
|
||||
@ -180,7 +184,7 @@ def nvram_import(nvram, startup, private, size):
|
||||
|
||||
checksum(new_nvram, 0, nvram_len)
|
||||
|
||||
return new_nvram.tostring()
|
||||
return new_nvram
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
Reference in New Issue
Block a user