Sync with IOU tools (nvram import/export).

pull/239/head
grossmj 9 years ago
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…
Cancel
Save