diff options
Diffstat (limited to 'modules-available/statistics/inc/pciid.inc.php')
-rw-r--r-- | modules-available/statistics/inc/pciid.inc.php | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/modules-available/statistics/inc/pciid.inc.php b/modules-available/statistics/inc/pciid.inc.php new file mode 100644 index 00000000..38a2c56d --- /dev/null +++ b/modules-available/statistics/inc/pciid.inc.php @@ -0,0 +1,82 @@ +<?php + +class PciId +{ + + const DEVICE = 'DEVICE'; + const VENDOR = 'VENDOR'; + const DEVCLASS = 'CLASS'; + const AUTO = 'AUTO'; + + + /** + * @param string $cat type of query - self::DEVICE, self::VENDOR, self::DEVCLASS or self::AUTO for auto detection + * @param string $id the id to query - depends on $cat + * @return string|false Name of Class/Vendor/Device, false if not found + */ + public static function getPciId(string $cat, string $id, bool $dnsQuery = false) + { + static $cache = []; + if ($cat === self::DEVCLASS && $id[1] === '.') { + $id = substr($id, 2); + } + if ($cat === self::AUTO) { + if (preg_match('/^([a-f0-9]{4})[:._-]?([a-f0-9]{4})$/', $id, $out)) { + $cat = 'DEVICE'; + $host = $out[2] . '.' . $out[1]; + $id = $out[1] . ':' . $out[2]; + } elseif (preg_match('/^[a-f0-9]{4}$/', $id)) { + $cat = 'VENDOR'; + $host = $id; + } elseif (preg_match('/^c[.-]([a-f0-9]{2})([a-f0-9]{2})$/', $id)) { + $cat = 'CLASS'; + $host = $out[2] . '.' . $out[1] . '.c'; + $id = substr($id, 2); + } else { + error_log('Invalid PCIID lookup format: ' . $id); + return false; + } + } elseif ($cat === self::DEVICE && preg_match('/^([a-f0-9]{4})[:._-]?([a-f0-9]{4})$/', $id, $out)) { + $host = $out[2] . '.' . $out[1]; + $id = $out[1] . ':' . $out[2]; + } elseif ($cat === self::VENDOR && preg_match('/^([a-f0-9]{4})$/', $id)) { + $host = $id; + } elseif ($cat === self::DEVCLASS && preg_match('/^(?:c[.-])?([a-f0-9]{2})([a-f0-9]{2})$/', $id, $out)) { + $host = $out[2] . '.' . $out[1] . '.c'; + $id = 'c.' . $out[1] . $out[2]; + } else { + error_log("getPciId called with unknown format: ($cat) ($id)"); + return false; + } + $key = $cat . '-' . $id; + if (isset($cache[$key])) + return $cache[$key]; + $row = Database::queryFirst('SELECT value, dateline FROM pciid WHERE category = :cat AND id = :id LIMIT 1', + array('cat' => $cat, 'id' => $id)); + if ($row !== false && $row['dateline'] >= time()) { + return $cache[$key] = $row['value']; + } + if (!$dnsQuery) + return false; + // Unknown, query + $res = dns_get_record($host . '.pci.id.ucw.cz', DNS_TXT); + if (!is_array($res)) + return false; + foreach ($res as $entry) { + if (isset($entry['txt']) && substr($entry['txt'], 0, 2) === 'i=') { + $string = substr($entry['txt'], 2); + Database::exec('INSERT INTO pciid (category, id, value, dateline) VALUES (:cat, :id, :value, :timeout)' + . ' ON DUPLICATE KEY UPDATE value = VALUES(value), dateline = VALUES(dateline)', + array( + 'cat' => $cat, + 'id' => $id, + 'value' => $string, + 'timeout' => time() + mt_rand(10, 30) * 86400, + ), true); + return $cache[$key] = $string; + } + } + return $cache[$key] = ($row['value'] ?? false); + } + +}
\ No newline at end of file |