-
-
Save naftulikay/0b48e9236f9b91529296ecc5c9333dc1 to your computer and use it in GitHub Desktop.
Validate an e1000e NVM Checksum from Userspace
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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