From 815b7d226cdf177b925f577029a48b4e32efec2a Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 8 Jun 2015 10:07:54 -0600 Subject: [PATCH] Sync with IOU tools (nvram import/export). --- gns3server/modules/iou/iou_vm.py | 6 ++-- gns3server/modules/iou/utils/iou_export.py | 35 ++++++++++------------ gns3server/modules/iou/utils/iou_import.py | 26 +++++++++------- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/gns3server/modules/iou/iou_vm.py b/gns3server/modules/iou/iou_vm.py index a025c9ad..3c8bdaf4 100644 --- a/gns3server/modules/iou/iou_vm.py +++ b/gns3server/modules/iou/iou_vm.py @@ -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)) diff --git a/gns3server/modules/iou/utils/iou_export.py b/gns3server/modules/iou/utils/iou_export.py index 7ac4c614..42dcd1f2 100644 --- a/gns3server/modules/iou/utils/iou_export.py +++ b/gns3server/modules/iou/utils/iou_export.py @@ -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) diff --git a/gns3server/modules/iou/utils/iou_import.py b/gns3server/modules/iou/utils/iou_import.py index cb3396fe..5f54ad35 100644 --- a/gns3server/modules/iou/utils/iou_import.py +++ b/gns3server/modules/iou/utils/iou_import.py @@ -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__':