diff options
Diffstat (limited to 'tools/make-pci-ids.py')
-rwxr-xr-x | tools/make-pci-ids.py | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/tools/make-pci-ids.py b/tools/make-pci-ids.py new file mode 100755 index 00000000..0a77f766 --- /dev/null +++ b/tools/make-pci-ids.py @@ -0,0 +1,252 @@ +#!/usr/bin/env python3 +# +# make-pci-ids - Creates a file containing PCI IDs. +# It use the databases from +# https://github.com/pciutils/pciids/raw/master/pci.ids +# to create our file epan/dissectors/pci-ids.c +# +# Wireshark - Network traffic analyzer +# +# By Caleb Chiu <caleb.chiu@macnica.com> +# Copyright 2021 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# + +import string +import sys +import urllib.request, urllib.error, urllib.parse + +OUTPUT_FILE = "epan/pci-ids.c" + +MIN_VENDOR_COUNT = 2250 # 2261 on 2021-11-01 +MIN_DEVICE_COUNT = 33000 # 33724 on 2021-11-01 + +CODE_PREFIX = """\ + * + * Generated by tools/make-pci-ids.py + * By Caleb Chiu <caleb.chiu@macnica.com> + * Copyright 2021 + * + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <config.h> + +#include <stddef.h> + +#include "pci-ids.h" + +typedef struct +{ + uint16_t vid; + uint16_t did; + uint16_t svid; + uint16_t ssid; + char *name; + +} pci_id_t; + +typedef struct +{ + uint16_t vid; + uint16_t count; + pci_id_t *ids_ptr; + +} pci_vid_index_t; + +""" + +CODE_POSTFIX = """ +static pci_vid_index_t *get_vid_index(uint16_t vid) +{ + uint32_t start_index = 0; + uint32_t end_index = 0; + uint32_t idx = 0; + + end_index = sizeof(pci_vid_index)/sizeof(pci_vid_index[0]); + + while(start_index != end_index) + { + if(end_index - start_index == 1) + { + if(pci_vid_index[start_index].vid == vid) + return &pci_vid_index[start_index]; + + break; + } + + idx = (start_index + end_index)/2; + + if(pci_vid_index[idx].vid < vid) + start_index = idx; + else + if(pci_vid_index[idx].vid > vid) + end_index = idx; + else + return &pci_vid_index[idx]; + + } + + return NULL; + +} + +const char *pci_id_str(uint16_t vid, uint16_t did, uint16_t svid, uint16_t ssid) +{ + unsigned int i; + static char *not_found = \"Not found\"; + pci_vid_index_t *index_ptr; + pci_id_t *ids_ptr; + + index_ptr = get_vid_index(vid); + + if(index_ptr == NULL) + return not_found; + + ids_ptr = index_ptr->ids_ptr; + for(i = 0; i < index_ptr->count; ids_ptr++, i++) + if(vid == ids_ptr->vid && + did == ids_ptr->did && + svid == ids_ptr->svid && + ssid == ids_ptr->ssid) + return ids_ptr->name; + return not_found; + +} +""" + + +id_list=[] +count_list=[] + + +def exit_msg(msg=None, status=1): + if msg is not None: + sys.stderr.write(msg + '\n') + sys.exit(status) + + +def main(): + req_headers = { 'User-Agent': 'Wireshark make-pci-ids' } + req = urllib.request.Request('https://github.com/pciutils/pciids/raw/master/pci.ids', headers=req_headers) + response = urllib.request.urlopen(req) + lines = response.read().decode('UTF-8', 'replace').splitlines() + + out_lines = '''\ +/* pci-ids.c + * + * pci-ids.c is based on the pci.ids of The PCI ID Repository at + * https://pci-ids.ucw.cz/, fetched indirectly via + * https://github.com/pciutils/pciids +''' + vid = -1 + did = -1 + svid = -1 + entries = 0 + line_num = 0 + + for line in lines: + line = line.strip('\n') + line_num += 1 + + if line_num <= 15: + line = line.replace('#', ' ', 1) + line = line.lstrip() + line = line.replace("GNU General Public License", "GPL") + if line: + line = ' * ' + line + else: + line = ' *' + line + out_lines += line + '\n' + if line_num == 15: + out_lines += CODE_PREFIX + + line = line.replace("\\","\\\\") + line = line.replace("\"","\\\"") + line = line.replace("?","?-") + tabs = len(line) - len(line.lstrip('\t')) + if tabs == 0: + #print line + words = line.split(" ", 1) + if len(words) < 2: + continue + if len(words[0]) != 4: + continue + if all(c in string.hexdigits for c in words[0]): + hex_int = int(words[0], 16) + if vid != -1: + out_lines += "}; /* pci_vid_%04X[] */\n\n" % (vid) + count_list.append(entries) + vid = hex_int + entries = 1 + did = -1 + svid = -1 + ssid = -1 + out_lines += "pci_id_t pci_vid_%04X[] = {\n" % (vid) + out_lines += "{0x%04X, 0xFFFF, 0xFFFF, 0xFFFF, \"%s(0x%04X)\"},\n" % (vid, words[1].strip(), vid) + id_list.append(vid) + continue + + if tabs == 1: + line = line.strip('\t') + words = line.split(" ", 1) + if len(words) < 2: + continue + if len(words[0]) != 4: + continue + if all(c in string.hexdigits for c in words[0]): + hex_int = int(words[0], 16) + did = hex_int + svid = -1 + ssid = -1 + out_lines += "{0x%04X, 0x%04X, 0xFFFF, 0xFFFF, \"%s(0x%04X)\"},\n" % (vid, did, words[1].strip(), did) + entries += 1 + continue + + if tabs == 2: + line = line.strip('\t') + words = line.split(" ", 2) + if len(words[0]) != 4: + continue + if all(c in string.hexdigits for c in words[0]): + hex_int = int(words[0], 16) + svid = hex_int + + if all(c in string.hexdigits for c in words[1]): + hex_int = int(words[1], 16) + ssid = hex_int + + out_lines += "{0x%04X, 0x%04X, 0x%04X, 0x%04X, \"%s(0x%04X-0x%04X)\"},\n" % (vid, did, svid, ssid, words[2].strip(), svid, ssid) + entries += 1 + svid = -1 + ssid = -1 + continue + + out_lines += "}; /* pci_vid_%04X[] */\n" % (vid) + count_list.append(entries) + + out_lines += "\npci_vid_index_t pci_vid_index[] = {\n" + + vendor_count = len(id_list) + device_count = 0 + for i in range(vendor_count): + out_lines += "{0x%04X, %d, pci_vid_%04X },\n" % (id_list[i], count_list[i], id_list[i]) + device_count += count_list[i] + + out_lines += "}; /* We have %d VIDs */\n" % (vendor_count) + + out_lines += CODE_POSTFIX + + if vendor_count < MIN_VENDOR_COUNT: + exit_msg(f'Too view vendors. Wanted {MIN_VENDOR_COUNT}, got {vendor_count}.') + + if device_count < MIN_DEVICE_COUNT: + exit_msg(f'Too view devices. Wanted {MIN_DEVICE_COUNT}, got {device_count}.') + + with open(OUTPUT_FILE, "w", encoding="utf-8") as pci_ids_f: + pci_ids_f.write(out_lines) + +if __name__ == '__main__': + main() |