Skip to content

Instantly share code, notes, and snippets.

@naftulikay
Last active March 27, 2018 18:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save naftulikay/0b48e9236f9b91529296ecc5c9333dc1 to your computer and use it in GitHub Desktop.
Save naftulikay/0b48e9236f9b91529296ecc5c9333dc1 to your computer and use it in GitHub Desktop.
Validate an e1000e NVM Checksum from Userspace
#!/usr/bin/env python3
import argparse
import re
import subprocess
import sys
from numpy import uint16
NEWLINES = re.compile(r'\r?\n', re.I)
WHITESPACE = re.compile(r'\s+', re.I)
ETHTOOL_BYTES = re.compile(r'^0x[a-f0-9]+:\s+((?:[a-f0-9]{2}\s*)+)$', re.I)
def bytes_to_words(bytearr):
"""Convert a series of bytes into little-endian 16-bit unsigned integers."""
return [(bytearr[i + 1] << 8) | bytearr[i] for i in range(0, len(bytearr), 2)]
def validate_checksum(words):
"""Validates the NVM checksum to equal 0xBABA."""
checksum = uint16(words).sum(dtype=uint16)
return checksum == 0xbaba
def load_bytes(device):
"""Loads bytes 0x00-0x80 from the given ethernet device."""
p = subprocess.Popen(["ethtool", "-e", device, "offset", "0x00", "length", "0x80"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode != 0:
fail("Unable to execute ethtool: {}".format(stderr))
bytearr = []
for line in NEWLINES.split(stdout.decode('utf-8')):
if ETHTOOL_BYTES.match(line):
# we have a good line, stash all of its bytes in bytearr
bytearr.extend(filter(lambda s: len(s.strip()) > 0, WHITESPACE.split(ETHTOOL_BYTES.match(line).group(1))))
# convert them to integers
return list(map(lambda s: int(s, 16), bytearr))
def fail(message, rc=1):
"""Emit a message to stderr and exit with a given return code."""
sys.stderr.write("{}\n".format(message))
sys.stderr.flush()
sys.exit(rc)
def main():
"""Main entry point to the script."""
parser = argparse.ArgumentParser(description="Validates an e1000e card's NVM checksum using ethtool.")
parser.add_argument('device', help="The ethernet device name to validate.")
args = parser.parse_args()
byte_values = load_bytes(args.device)
word_values = bytes_to_words(byte_values)
checksum = hex(word_values[-1])
if validate_checksum(word_values):
print("SUCCESS: Your NVM Checksum is computed as equal to 0xbaba.")
else:
fail("FAILED: Your NVM Checksum for {} is invalid.".format(args.device))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment