From a3d33b940876d0d05d8fdd51f54957436a782823 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Tue, 13 Feb 2007 23:38:50 +0100 Subject: [PATCH] The first try at using DNS for resolving ID's. --- ChangeLog | 4 ++ Makefile | 8 ++-- lib/access.c | 2 + lib/configure | 1 + lib/names.c | 115 ++++++++++++++++++++++++++++++++++++++++++++------ lib/pci.h | 4 +- 6 files changed, 115 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index bebd766..0a473a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2007-02-13 Martin Mares + + * Very experimental resolving of PCI ID's using DNS. + 2007-02-09 Martin Mares * pci.ids: Updated to the current snapshot of the database. diff --git a/Makefile b/Makefile index fc181e0..aec6ccb 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,8 @@ OPT=-O2 CFLAGS=$(OPT) -Wall -W -Wno-parentheses -Wstrict-prototypes -Wmissing-prototypes -VERSION=2.2.5-test1 -DATE=2007-02-06 +VERSION=2.2.5-net1 +DATE=2007-02-13 PREFIX=/usr/local SBINDIR=$(PREFIX)/sbin @@ -34,8 +34,8 @@ force: lib/config.h lib/config.mk: cd lib && ./configure "$(IDSDIR)" "$(VERSION)" "$(HOST)" "$(RELEASE)" "$(ZLIB)" -lspci: lspci.o common.o $(PCILIB) -setpci: setpci.o common.o $(PCILIB) +lspci: lspci.o common.o $(PCILIB) /usr/lib/libresolv.a +setpci: setpci.o common.o $(PCILIB) /usr/lib/libresolv.a lspci.o: lspci.c pciutils.h $(PCIINC) setpci.o: setpci.c pciutils.h $(PCIINC) diff --git a/lib/access.c b/lib/access.c index d4999d6..4c21aaa 100644 --- a/lib/access.c +++ b/lib/access.c @@ -67,6 +67,8 @@ pci_alloc(void) memset(a, 0, sizeof(*a)); pci_set_name_list_path(a, PCI_PATH_IDS_DIR "/" PCI_IDS, 0); + a->id_domain = PCI_ID_DOMAIN; + a->network_ids = 1; /* FIXME */ for(i=0; iconfig) pci_methods[i]->config(a); diff --git a/lib/configure b/lib/configure index a031ca7..ae38f43 100755 --- a/lib/configure +++ b/lib/configure @@ -126,6 +126,7 @@ else echo >>$c '#define PCI_IDS "pci.ids"' fi echo >>$c "#define PCI_PATH_IDS_DIR \"$idsdir\"" +echo >>$c "#define PCI_ID_DOMAIN \"pci-id.ucw.cz\"" echo >>$c "#define PCILIB_VERSION \"$version\"" sed '/"/{s/^#define \([^ ]*\) "\(.*\)"$/\1=\2/;p;d;};s/^#define \(.*\)/\1=1/' <$c >>$m diff --git a/lib/names.c b/lib/names.c index 6d671d1..22d0502 100644 --- a/lib/names.c +++ b/lib/names.c @@ -1,7 +1,7 @@ /* * The PCI Library -- ID to Name Translation * - * Copyright (c) 1997--2006 Martin Mares + * Copyright (c) 1997--2007 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "internal.h" @@ -98,6 +100,13 @@ static void *id_alloc(struct pci_access *a, unsigned int size) { struct id_bucket *buck = a->current_id_bucket; unsigned int pos; + + if (!a->id_hash) + { + a->id_hash = pci_malloc(a, sizeof(struct id_entry *) * HASH_SIZE); + memset(a->id_hash, 0, sizeof(struct id_entry *) * HASH_SIZE); + } + if (!buck || buck->full + size > BUCKET_SIZE) { buck = pci_malloc(a, BUCKET_SIZE); @@ -123,18 +132,75 @@ static inline unsigned int id_hash(int cat, u32 id12, u32 id34) return h % HASH_SIZE; } -static char *id_lookup(struct pci_access *a, int cat, int id1, int id2, int id3, int id4) +static char *id_net_lookup(struct pci_access *a, int cat, int id1, int id2, int id3, int id4) { - struct id_entry *n; - u32 id12 = id_pair(id1, id2); - u32 id34 = id_pair(id3, id4); + byte name[256], dnsname[256], answer[4096], txt[256]; + const byte *data; + int res, i, j, dlen; + ns_msg m; + ns_rr rr; - if (!a->id_hash) - return NULL; - n = a->id_hash[id_hash(cat, id12, id34)]; - while (n && (n->id12 != id12 || n->id34 != id34 || n->cat != cat)) - n = n->next; - return n ? n->name : NULL; + switch (cat) + { + case ID_VENDOR: + sprintf(name, "%04x", id1); + break; + case ID_DEVICE: + sprintf(name, "%04x.%04x", id2, id1); + break; + case ID_SUBSYSTEM: + sprintf(name, "%04x.%04x.%04x.%04x", id4, id3, id2, id1); + break; + case ID_GEN_SUBSYSTEM: + sprintf(name, "%04x.%04x.s", id2, id1); + break; + case ID_CLASS: + sprintf(name, "%02x.c", id1); + break; + case ID_SUBCLASS: + sprintf(name, "%02x.%02x.c", id2, id1); + break; + case ID_PROGIF: + sprintf(name, "%02x.%02x.%02x.c", id3, id2, id1); + break; + default: + return NULL; + } + sprintf(dnsname, "%s.%s", name, a->id_domain); + + a->debug("Resolving %s\n", dnsname); + res_init(); + res = res_query(dnsname, ns_c_in, ns_t_txt, answer, sizeof(answer)); + if (res < 0) + { + a->debug("\tfailed, h_errno=%d\n", _res.res_h_errno); + return NULL; + } + if (ns_initparse(answer, res, &m) < 0) + { + a->debug("\tinitparse failed\n"); + return NULL; + } + for (i=0; ns_parserr(&m, ns_s_an, i, &rr) >= 0; i++) + { + a->debug("\tanswer %d (class %d, type %d)\n", i, ns_rr_class(rr), ns_rr_type(rr)); + if (ns_rr_class(rr) != ns_c_in || ns_rr_type(rr) != ns_t_txt) + continue; + data = ns_rr_rdata(rr); + dlen = ns_rr_rdlen(rr); + j = 0; + while (j < dlen && j+1+data[j] <= dlen) + { + memcpy(txt, &data[j+1], data[j]); + txt[data[j]] = 0; + j += 1+data[j]; + a->debug("\t\t%s\n", txt); + if (txt[0] == 'i' && txt[1] == '=') + return strdup(txt+2); /* FIXME */ + } + } + + return NULL; } static int id_insert(struct pci_access *a, int cat, int id1, int id2, int id3, int id4, char *text) @@ -142,7 +208,7 @@ static int id_insert(struct pci_access *a, int cat, int id1, int id2, int id3, i u32 id12 = id_pair(id1, id2); u32 id34 = id_pair(id3, id4); unsigned int h = id_hash(cat, id12, id34); - struct id_entry *n = a->id_hash[h]; + struct id_entry *n = a->id_hash ? a->id_hash[h] : NULL; int len = strlen(text); while (n && (n->id12 != id12 || n->id34 != id34 || n->cat != cat)) @@ -159,6 +225,29 @@ static int id_insert(struct pci_access *a, int cat, int id1, int id2, int id3, i return 0; } +static char *id_lookup(struct pci_access *a, int cat, int id1, int id2, int id3, int id4) +{ + struct id_entry *n; + u32 id12 = id_pair(id1, id2); + u32 id34 = id_pair(id3, id4); + char *name; + + if (a->id_hash) + { + n = a->id_hash[id_hash(cat, id12, id34)]; + while (n && (n->id12 != id12 || n->id34 != id34 || n->cat != cat)) + n = n->next; + if (n) + return n->name; + } + if (name = id_net_lookup(a, cat, id1, id2, id3, id4)) + { + id_insert(a, cat, id1, id2, id3, id4, name); + return name; + } + return NULL; +} + static int id_hex(char *p, int cnt) { int x = 0; @@ -325,8 +414,6 @@ pci_load_name_list(struct pci_access *a) a->hash_load_failed = 1; if (!(f = pci_open(a))) return 0; - a->id_hash = pci_malloc(a, sizeof(struct id_entry *) * HASH_SIZE); - memset(a->id_hash, 0, sizeof(struct id_entry *) * HASH_SIZE); err = id_parse_list(a, f, &lino); PCI_ERROR(f, err); pci_close(f); diff --git a/lib/pci.h b/lib/pci.h index 8becd76..37cb1be 100644 --- a/lib/pci.h +++ b/lib/pci.h @@ -1,7 +1,7 @@ /* * The PCI Library * - * Copyright (c) 1997--2006 Martin Mares + * Copyright (c) 1997--2007 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -45,6 +45,8 @@ struct pci_access { char *id_file_name; /* Name of ID list file */ int free_id_name; /* Set if id_file_name is malloced */ int numeric_ids; /* Enforce PCI_LOOKUP_NUMERIC (>1 => PCI_LOOKUP_MIXED) */ + int network_ids; /* Try DNS lookups on unknown ID's */ + char *id_domain; /* DNS domain used for the lookups */ /* FIXME: set function? */ int debugging; /* Turn on debugging messages */ /* Functions you can override: */ -- 2.39.5