]> mj.ucw.cz Git - pciutils.git/commitdiff
The first try at using DNS for resolving ID's.
authorMartin Mares <mj@ucw.cz>
Tue, 13 Feb 2007 22:38:50 +0000 (23:38 +0100)
committerMartin Mares <mj@ucw.cz>
Tue, 13 Feb 2007 22:38:50 +0000 (23:38 +0100)
ChangeLog
Makefile
lib/access.c
lib/configure
lib/names.c
lib/pci.h

index bebd7666428c29a7b40cdd7d0cfd0f20b32421ac..0a473a4fa519b7bf64f61de3b8c5d16b6a50db26 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2007-02-13  Martin Mares  <mj@ucw.cz>
+
+       * Very experimental resolving of PCI ID's using DNS.
+
 2007-02-09  Martin Mares  <mj@ucw.cz>
 
        * pci.ids: Updated to the current snapshot of the database.
index fc181e0368c4f60054db1e801b6f46047928cb12..aec6ccb2458fe613c39fda21bd5e9161ac8e5194 100644 (file)
--- 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)
index d4999d6d4184dd61b015f447ef91891d4204c9f9..4c21aaaa93df655fdb83255fe2ea4a2b879ae6e6 100644 (file)
@@ -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; i<PCI_ACCESS_MAX; i++)
     if (pci_methods[i] && pci_methods[i]->config)
       pci_methods[i]->config(a);
index a031ca79488b17746aadc89de346ab656bf9e333..ae38f43173706ea16344934b2ea2f72f7b46dfa0 100755 (executable)
@@ -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
index 6d671d102f6653c5408122f4ef7e2afa4ba659ca..22d050263c372715af55d4fd9f6daaf75d79dc32 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     The PCI Library -- ID to Name Translation
  *
- *     Copyright (c) 1997--2006 Martin Mares <mj@ucw.cz>
+ *     Copyright (c) 1997--2007 Martin Mares <mj@ucw.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -11,6 +11,8 @@
 #include <stdarg.h>
 #include <string.h>
 #include <errno.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
 
 #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);
index 8becd76d9b7ceb843658364854fb8ff7d7e33eec..37cb1be5440c84f2b3d65d753133cb4a8f753f4e 100644 (file)
--- a/lib/pci.h
+++ b/lib/pci.h
@@ -1,7 +1,7 @@
 /*
  *     The PCI Library
  *
- *     Copyright (c) 1997--2006 Martin Mares <mj@ucw.cz>
+ *     Copyright (c) 1997--2007 Martin Mares <mj@ucw.cz>
  *
  *     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: */