From 7fb8f94ea3efa0b154cbd2b78072e56167dcc2a8 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Sun, 15 May 2022 19:11:26 -0300 Subject: [PATCH 1/9] Add missing columns `reply_type`, `reply_time`, `dnssec` Signed-off-by: RD WebDesign --- api_db.php | 15 ++++-- db_queries.php | 2 + scripts/pi-hole/js/db_queries.js | 83 ++++++++++++++++++++++++++++---- 3 files changed, 86 insertions(+), 14 deletions(-) diff --git a/api_db.php b/api_db.php index a10212a72..3649b7685 100644 --- a/api_db.php +++ b/api_db.php @@ -64,7 +64,7 @@ { $from = intval($_GET["from"]); $until = intval($_GET["until"]); - $dbquery = "SELECT timestamp, type, domain, client, status, forward FROM queries WHERE timestamp >= :from AND timestamp <= :until "; + $dbquery = "SELECT timestamp, type, domain, client, status, forward, reply_type, reply_time, dnssec FROM queries WHERE timestamp >= :from AND timestamp <= :until "; if(isset($_GET["types"])) { $types = $_GET["types"]; @@ -101,14 +101,19 @@ $first = false; } - // Convert query type ID to name, encode domain, encode destination - $query_type = getQueryTypeStr($row[1]); + // Format, encode, transform each field (if necessary). + $time = $row[0]; + $query_type = getQueryTypeStr($row[1]); // Convert query type ID to name $domain = utf8_encode(str_replace("~"," ",$row[2])); + $client = $row[3]; + $status = $row[4]; $destination = utf8_encode($row[5]); + $reply_type = $row[6]; + $reply_time = $row[7]; + $dnssec = $row[8]; // Insert into array and output it in JSON format - // array: time type domain client status upstream destination - echo json_encode([$row[0], $query_type, $domain, $row[3], $row[4], $destination]); + echo json_encode([$time, $query_type, $domain, $client, $status, $destination, $reply_type, $reply_time, $dnssec]); } } diff --git a/db_queries.php b/db_queries.php index e283b01ca..8d6ccaa99 100644 --- a/db_queries.php +++ b/db_queries.php @@ -180,6 +180,7 @@ Domain Client Status + Reply Action @@ -190,6 +191,7 @@ Domain Client Status + Reply Action diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index f502dff49..eb9478a42 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -20,6 +20,23 @@ var datepickerManuallySelected = false; var dateformat = "MMMM Do YYYY, HH:mm"; +var replyTypes = [ + "N/A", + "NODATA", + "NXDOMAIN", + "CNAME", + "IP", + "DOMAIN", + "RRNAME", + "SERVFAIL", + "REFUSED", + "NOTIMP", + "upstream error", + "DNSSEC", + "NONE", + "BLOB", +]; + // Do we want to filter queries? var GETDict = {}; window.location.search @@ -210,6 +227,34 @@ $(function () { tableApi = $("#all-queries").DataTable({ rowCallback: function (row, data) { + var replyid = parseInt(data[6], 10); + var dnssecStatus; + switch (data[8]) { + case "1": + dnssecStatus = '
SECURE'; + break; + case "2": + dnssecStatus = '
INSECURE'; + break; + case "3": + dnssecStatus = '
BOGUS'; + break; + case "4": + dnssecStatus = '
ABANDONED'; + break; + case "5": + dnssecStatus = '
UNKNOWN'; + break; + default: + // No DNSSEC + dnssecStatus = ""; + } + + if (dnssecStatus.length > 0) { + if (replyid === 7) dnssecStatus += " (refused upstream)"; + dnssecStatus += ""; + } + var fieldtext, buttontext = "", blocked = false; @@ -222,14 +267,18 @@ $(function () { break; case 2: fieldtext = - "OK (forwarded to " + + replyid === 0 + ? "OK (sent to " + : "OK (answered by "; + fieldtext += (data.length > 5 && data[5] !== "N/A" ? data[5] : "") + + dnssecStatus + ")"; buttontext = ''; break; case 3: - fieldtext = "OK (cache)"; + fieldtext = "OK (cache)" + dnssecStatus; buttontext = ''; break; @@ -305,13 +354,28 @@ $(function () { fieldtext = "Unknown (" + parseInt(data[4], 10) + ")"; } + // Cannot block internal queries of this type + if ((data[1] === "DNSKEY" || data[1] === "DS") && data[3] === "pi.hole") buttontext = ""; + $(row).addClass(blocked === true ? "blocked-row" : "allowed-row"); if (localStorage && localStorage.getItem("colorfulQueryLog_chkbox") === "true") { $(row).addClass(blocked === true ? "text-red" : "text-green"); } + // Check for existence of sixth column and display only if not Pi-holed + var replytext = + replyid >= 0 && replyid < replyTypes.length ? replyTypes[replyid] : "? (" + replyid + ")"; + + replytext += ''; + $("td:eq(4)", row).html(fieldtext); - $("td:eq(5)", row).html(buttontext); + $("td:eq(5)", row).html(replytext); + $("td:eq(6)", row).html(buttontext); + + // Show response time only when reply is not N/A + if (data.length > 7 && replyid !== 0) { + $("td:eq(5)", row).append(" (" + (0.1 * data[7]).toFixed(1) + "ms)"); + } // Substitute domain by "." if empty var domain = data[2]; @@ -343,7 +407,7 @@ $(function () { order: [[0, "desc"]], columns: [ { - width: "15%", + width: "12%", render: function (data, type) { if (type === "display") { return moment @@ -354,11 +418,12 @@ $(function () { return data; }, }, - { width: "10%" }, - { width: "40%" }, - { width: "20%", type: "ip-address" }, - { width: "10%" }, - { width: "5%" }, + { width: "9%" }, + { width: "36%" }, + { width: "10%", type: "ip-address" }, + { width: "15%" }, + { width: "9%" }, + { width: "9%" }, ], lengthMenu: [ [10, 25, 50, 100, -1], From ba18ece9d805bdc27f8dad4c8a64e6c91df42f5c Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Sun, 15 May 2022 19:49:23 -0300 Subject: [PATCH 2/9] Fix multiplier (`reply_time` field unit is second) Signed-off-by: RD WebDesign --- scripts/pi-hole/js/db_queries.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index eb9478a42..2fa05f607 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -374,7 +374,7 @@ $(function () { // Show response time only when reply is not N/A if (data.length > 7 && replyid !== 0) { - $("td:eq(5)", row).append(" (" + (0.1 * data[7]).toFixed(1) + "ms)"); + $("td:eq(5)", row).append(" (" + (1000 * data[7]).toFixed(1) + "ms)"); } // Substitute domain by "." if empty From 9d225ed8e436dfd670a84f9944ab36249283db1d Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Sun, 15 May 2022 19:55:38 -0300 Subject: [PATCH 3/9] Fix prettier Signed-off-by: RD WebDesign --- scripts/pi-hole/js/db_queries.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index 2fa05f607..7b9c6dc42 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -270,15 +270,13 @@ $(function () { replyid === 0 ? "OK (sent to " : "OK (answered by "; - fieldtext += - (data.length > 5 && data[5] !== "N/A" ? data[5] : "") + - dnssecStatus + - ")"; + fieldtext += (data.length > 5 && data[5] !== "N/A" ? data[5] : "") + dnssecStatus + ")"; buttontext = ''; break; case 3: - fieldtext = "OK (cache)" + dnssecStatus; + fieldtext = + "OK (cache)" + dnssecStatus; buttontext = ''; break; From 98a0e82946f678e664f0849ea8c5eb077039b8b9 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Sat, 28 May 2022 18:40:23 -0300 Subject: [PATCH 4/9] Replace `queries` with `query_storage` - use client names, when available; - use column names instead of indexes; Signed-off-by: RD WebDesign --- api_db.php | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/api_db.php b/api_db.php index 3649b7685..9309721d2 100644 --- a/api_db.php +++ b/api_db.php @@ -64,7 +64,18 @@ { $from = intval($_GET["from"]); $until = intval($_GET["until"]); - $dbquery = "SELECT timestamp, type, domain, client, status, forward, reply_type, reply_time, dnssec FROM queries WHERE timestamp >= :from AND timestamp <= :until "; + + // Use table "query_storage" + // - replace domain ID with domain + // - replace client ID with client name + // - replace forward ID with forward destination + $dbquery = "SELECT timestamp, type,"; + $dbquery .= " CASE typeof(domain) WHEN 'integer' THEN (SELECT domain FROM domain_by_id d WHERE d.id = q.domain) ELSE domain END domain,"; + $dbquery .= " CASE typeof(client) WHEN 'integer' THEN (SELECT name FROM client_by_id c WHERE c.id = q.client) ELSE client END client,"; + $dbquery .= " CASE typeof(forward) WHEN 'integer' THEN (SELECT forward FROM forward_by_id f WHERE f.id = q.forward) ELSE forward END forward,"; + $dbquery .= " status, reply_type, reply_time, dnssec"; + $dbquery .= " FROM query_storage q"; + $dbquery .= " WHERE timestamp >= :from AND timestamp <= :until "; if(isset($_GET["types"])) { $types = $_GET["types"]; @@ -93,7 +104,7 @@ if (!is_bool($results)) { $first = true; - while ($row = $results->fetchArray()) { + while ($row = $results->fetchArray(SQLITE3_ASSOC)) { // Insert a comma before the next record (except on the first one) if (!$first) { echo ","; @@ -102,15 +113,16 @@ } // Format, encode, transform each field (if necessary). - $time = $row[0]; - $query_type = getQueryTypeStr($row[1]); // Convert query type ID to name - $domain = utf8_encode(str_replace("~"," ",$row[2])); - $client = $row[3]; - $status = $row[4]; - $destination = utf8_encode($row[5]); - $reply_type = $row[6]; - $reply_time = $row[7]; - $dnssec = $row[8]; + $time = $row["timestamp"]; + $query_type = getQueryTypeStr($row["type"]); // Convert query type ID to name + $domain = utf8_encode(str_replace("~"," ",$row["domain"])); + $client = $row["client"]; + $status = $row["status"]; + $destination = utf8_encode($row["forward"]); + $reply_type = $row["reply_type"]; + $reply_time = $row["reply_time"]; + $dnssec = $row["dnssec"]; + $client_id = $row["client_id"]; // Insert into array and output it in JSON format echo json_encode([$time, $query_type, $domain, $client, $status, $destination, $reply_type, $reply_time, $dnssec]); From da85d1b4e7d1f567dad33f134d2abf2f23e62bf0 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Sun, 29 May 2022 17:48:59 -0300 Subject: [PATCH 5/9] Use IP if there is no client name Signed-off-by: RD WebDesign --- api_db.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api_db.php b/api_db.php index 9309721d2..20a4a0aca 100644 --- a/api_db.php +++ b/api_db.php @@ -71,7 +71,9 @@ // - replace forward ID with forward destination $dbquery = "SELECT timestamp, type,"; $dbquery .= " CASE typeof(domain) WHEN 'integer' THEN (SELECT domain FROM domain_by_id d WHERE d.id = q.domain) ELSE domain END domain,"; - $dbquery .= " CASE typeof(client) WHEN 'integer' THEN (SELECT name FROM client_by_id c WHERE c.id = q.client) ELSE client END client,"; + $dbquery .= " CASE typeof(client) WHEN 'integer' THEN ("; + $dbquery .= " SELECT CASE TRIM(name) WHEN '' THEN c.ip ELSE c.name END name FROM client_by_id c WHERE c.id = q.client"; + $dbquery .= " ) ELSE client END client,"; $dbquery .= " CASE typeof(forward) WHEN 'integer' THEN (SELECT forward FROM forward_by_id f WHERE f.id = q.forward) ELSE forward END forward,"; $dbquery .= " status, reply_type, reply_time, dnssec"; $dbquery .= " FROM query_storage q"; From 2dd5fb816bafb6f4e00dbf0e7338f4531bf8e941 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Sun, 29 May 2022 19:14:44 -0300 Subject: [PATCH 6/9] Fix DNSSEC info Signed-off-by: RD WebDesign --- scripts/pi-hole/js/db_queries.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index 7b9c6dc42..708c26e4c 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -230,19 +230,19 @@ $(function () { var replyid = parseInt(data[6], 10); var dnssecStatus; switch (data[8]) { - case "1": + case 1: dnssecStatus = '
SECURE'; break; - case "2": + case 2: dnssecStatus = '
INSECURE'; break; - case "3": + case 3: dnssecStatus = '
BOGUS'; break; - case "4": + case 4: dnssecStatus = '
ABANDONED'; break; - case "5": + case 5: dnssecStatus = '
UNKNOWN'; break; default: @@ -270,7 +270,7 @@ $(function () { replyid === 0 ? "OK (sent to " : "OK (answered by "; - fieldtext += (data.length > 5 && data[5] !== "N/A" ? data[5] : "") + dnssecStatus + ")"; + fieldtext += (data.length > 5 && data[5] !== "N/A" ? data[5] : "") + ")" + dnssecStatus; buttontext = ''; break; @@ -334,7 +334,7 @@ $(function () { break; case 14: fieldtext = - "OK (already forwarded)"; + "OK (already forwarded)" + dnssecStatus; buttontext = ''; break; From fad13b11517e93e6af1628f4afd47603210e1160 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 30 May 2022 01:11:52 -0300 Subject: [PATCH 7/9] Fixing prettier line break Signed-off-by: RD WebDesign --- scripts/pi-hole/js/db_queries.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index 708c26e4c..7dcae4b06 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -334,7 +334,8 @@ $(function () { break; case 14: fieldtext = - "OK (already forwarded)" + dnssecStatus; + "OK (already forwarded)" + + dnssecStatus; buttontext = ''; break; From cd4152058b011625f66fe7c436c232dacda662d6 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 30 May 2022 13:14:03 -0300 Subject: [PATCH 8/9] Use the same types, as returned by FTL Signed-off-by: RD WebDesign --- scripts/pi-hole/php/func.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pi-hole/php/func.php b/scripts/pi-hole/php/func.php index c60433244..f4e0274c3 100644 --- a/scripts/pi-hole/php/func.php +++ b/scripts/pi-hole/php/func.php @@ -475,7 +475,7 @@ function returnError($message = "", $json = true) function getQueryTypeStr($querytype) { - $qtypes = ["A (IPv4)", "AAAA (IPv6)", "ANY", "SRV", "SOA", "PTR", "TXT", "NAPTR", "MX", "DS", "RRSIG", "DNSKEY", "NS", "OTHER", "SVCB", "HTTPS"]; + $qtypes = ["A", "AAAA", "ANY", "SRV", "SOA", "PTR", "TXT", "NAPTR", "MX", "DS", "RRSIG", "DNSKEY", "NS", "OTHER", "SVCB", "HTTPS"]; $qtype = intval($querytype); if($qtype > 0 && $qtype <= count($qtypes)) return $qtypes[$qtype-1]; From 33c5450ba4c0ef61e0c7b75f697a97e1c00cfaed Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Tue, 31 May 2022 15:16:04 -0300 Subject: [PATCH 9/9] Use consistent output for both query lists Signed-off-by: RD WebDesign --- scripts/pi-hole/js/db_queries.js | 3 ++- scripts/pi-hole/js/queries.js | 11 +++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index 7dcae4b06..004004693 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -307,7 +307,8 @@ $(function () { blocked = true; break; case 9: - fieldtext = "Blocked (gravity, CNAME)"; + fieldtext = + "Blocked (gravity, CNAME)"; buttontext = ''; blocked = true; diff --git a/scripts/pi-hole/js/queries.js b/scripts/pi-hole/js/queries.js index b603db661..18f09d729 100644 --- a/scripts/pi-hole/js/queries.js +++ b/scripts/pi-hole/js/queries.js @@ -125,12 +125,10 @@ $(function () { case "2": fieldtext = replyid === 0 - ? "OK, sent to " - : "OK, answered by "; + ? "OK (sent to " + : "OK (answered by "; fieldtext += - "" + - (data.length > 10 && data[10] !== "N/A" ? data[10] : "") + - dnssecStatus; + (data.length > 10 && data[10] !== "N/A" ? data[10] : "") + ")" + dnssecStatus; buttontext = ''; break; @@ -174,7 +172,8 @@ $(function () { buttontext = ""; break; case "9": - fieldtext = "Blocked (gravity, CNAME)"; + fieldtext = + "Blocked (gravity, CNAME)"; blocked = true; buttontext = '';