1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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);
}
}
|