From a598022a9f9a9f944db5724302c37f9e52bec811 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 31 Aug 2020 18:58:29 +0200 Subject: [PATCH 1/5] Try to obtain host names from another address of the same device when there is none for the exact address (may happen, e.g., for IPv6 addresses) Signed-off-by: DL6ER --- src/database/network-table.c | 62 +++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/src/database/network-table.c b/src/database/network-table.c index dd350aef1..f9b7a22a4 100644 --- a/src/database/network-table.c +++ b/src/database/network-table.c @@ -1732,7 +1732,7 @@ char *__attribute__((malloc)) getNameFromIP(const char *ipaddr) return NULL; } - // Prepare SQLite statement + // Check for a host name associated with the same IP address sqlite3_stmt *stmt = NULL; const char *querystr = "SELECT name FROM network_addresses WHERE name IS NOT NULL AND ip = ?;"; int rc = sqlite3_prepare_v2(FTL_db, querystr, -1, &stmt, NULL); @@ -1762,16 +1762,70 @@ char *__attribute__((malloc)) getNameFromIP(const char *ipaddr) { // Database record found (result might be empty) name = strdup((char*)sqlite3_column_text(stmt, 0)); + + if(config.debug & DEBUG_DATABASE) + logg("Found database host name (same address) %s -> %s", ipaddr, name); } else { // Not found or error (will be logged automatically through our SQLite3 hook) - name = NULL; } - if(config.debug & DEBUG_DATABASE && name != NULL) - logg("Found database host name %s -> %s", ipaddr, name); + // Finalize statement + sqlite3_reset(stmt); + sqlite3_finalize(stmt); + + // Return here if we found the name + if(name != NULL) + { + if(!db_already_open) + dbclose(); + + return name; + } + + // Nothing found for the exact IP address + // Check for a host name associated with the same device (but another IP address) + querystr = "SELECT name FROM network_addresses " + "WHERE name IS NOT NULL AND " + "network_id = (SELECT network_id FROM network_addresses" + "WHERE ip = ?) " + "ORDER BY lastSeen DESC LIMIT 1"; + rc = sqlite3_prepare_v2(FTL_db, querystr, -1, &stmt, NULL); + if( rc != SQLITE_OK ){ + logg("getNameFromIP(\"%s\") - SQL error prepare: %s", + ipaddr, sqlite3_errstr(rc)); + if(!db_already_open) + dbclose(); + return NULL; + } + + // Bind ipaddr to prepared statement + if((rc = sqlite3_bind_text(stmt, 1, ipaddr, -1, SQLITE_STATIC)) != SQLITE_OK) + { + logg("getNameFromIP(\"%s\"): Failed to bind ip: %s", + ipaddr, sqlite3_errstr(rc)); + sqlite3_reset(stmt); + sqlite3_finalize(stmt); + if(!db_already_open) + dbclose(); + return NULL; + } + + rc = sqlite3_step(stmt); + if(rc == SQLITE_ROW) + { + // Database record found (result might be empty) + name = strdup((char*)sqlite3_column_text(stmt, 0)); + if(config.debug & DEBUG_DATABASE) + logg("Found database host name (same device) %s -> %s", ipaddr, name); + } + else + { + // Not found or error (will be logged automatically through our SQLite3 hook) + name = NULL; + } // Finalize statement and close database handle sqlite3_reset(stmt); sqlite3_finalize(stmt); From 693aa46319f3259d858f24c84a816c20b7060045 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 31 Aug 2020 19:50:47 +0200 Subject: [PATCH 2/5] Fix syntax error Signed-off-by: DL6ER --- src/database/network-table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/database/network-table.c b/src/database/network-table.c index f9b7a22a4..561331e42 100644 --- a/src/database/network-table.c +++ b/src/database/network-table.c @@ -1788,7 +1788,7 @@ char *__attribute__((malloc)) getNameFromIP(const char *ipaddr) // Check for a host name associated with the same device (but another IP address) querystr = "SELECT name FROM network_addresses " "WHERE name IS NOT NULL AND " - "network_id = (SELECT network_id FROM network_addresses" + "network_id = (SELECT network_id FROM network_addresses " "WHERE ip = ?) " "ORDER BY lastSeen DESC LIMIT 1"; rc = sqlite3_prepare_v2(FTL_db, querystr, -1, &stmt, NULL); From 9bdfee2e1937a17e8d4d212dbceef3f4ae083cc4 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 31 Aug 2020 20:35:46 +0200 Subject: [PATCH 3/5] Remove duplicate function getDatabaseHostname() Signed-off-by: DL6ER --- src/database/network-table.c | 76 ------------------------------------ src/database/network-table.h | 7 ++-- src/resolve.c | 31 +++++++++------ 3 files changed, 22 insertions(+), 92 deletions(-) diff --git a/src/database/network-table.c b/src/database/network-table.c index 561331e42..40c648b00 100644 --- a/src/database/network-table.c +++ b/src/database/network-table.c @@ -1581,82 +1581,6 @@ void updateMACVendorRecords(void) dbclose(); } -char *__attribute__((malloc)) getDatabaseHostname(const char *ipaddr) -{ - // Test if this is an IPv6 address - bool IPv6 = false; - if(ipaddr != NULL && strstr(ipaddr,":") != NULL) - { - IPv6 = true; - } - - // Do we want to resolve IPv4/IPv6 names at all? - if( (IPv6 && !config.resolveIPv6) || - (!IPv6 && !config.resolveIPv4)) - { - if(config.debug & DEBUG_RESOLVER) - { - logg(" ---> \"\" (configured to not resolve %s host names)", - IPv6 ? "IPv6" : "IPv4"); - } - return strdup(""); - } - - // Open pihole-FTL.db database file if needed - const bool db_already_open = FTL_DB_avail(); - if(!db_already_open && !dbopen()) - { - logg("getDatabaseHostname(\"%s\") - Failed to open DB", ipaddr); - return NULL; - } - - // Prepare SQLite statement - sqlite3_stmt *stmt = NULL; - const char *querystr = "SELECT name FROM network_addresses " - "WHERE name IS NOT NULL AND ip = ?;"; - int rc = sqlite3_prepare_v2(FTL_db, querystr, -1, &stmt, NULL); - if( rc != SQLITE_OK ){ - logg("getDatabaseHostname(\"%s\") - SQL error prepare: %s", - ipaddr, sqlite3_errstr(rc)); - if(!db_already_open) - dbclose(); - return strdup(""); - } - - // Bind ipaddr to prepared statement - if((rc = sqlite3_bind_text(stmt, 1, ipaddr, -1, SQLITE_STATIC)) != SQLITE_OK) - { - logg("getDatabaseHostname(\"%s\"): Failed to bind ip: %s", - ipaddr, sqlite3_errstr(rc)); - sqlite3_reset(stmt); - sqlite3_finalize(stmt); - if(!db_already_open) - dbclose(); - return strdup(""); - } - - char *hostname = NULL; - rc = sqlite3_step(stmt); - if(rc == SQLITE_ROW) - { - // Database record found (result might be empty) - hostname = strdup((char*)sqlite3_column_text(stmt, 0)); - } - else - { - // Not found or error (will be logged automatically through our SQLite3 hook) - hostname = strdup(""); - } - - // Finalize statement and close database handle - sqlite3_reset(stmt); - sqlite3_finalize(stmt); - if(!db_already_open) - dbclose(); - - return hostname; -} - // Get hardware address of device identified by IP address char *__attribute__((malloc)) getMACfromIP(const char *ipaddr) { diff --git a/src/database/network-table.h b/src/database/network-table.h index ebe0a272d..1c958435a 100644 --- a/src/database/network-table.h +++ b/src/database/network-table.h @@ -16,10 +16,9 @@ bool create_network_addresses_with_names_table(void); void parse_neighbor_cache(void); void updateMACVendorRecords(void); bool unify_hwaddr(void); -char* getDatabaseHostname(const char* ipaddr) __attribute__((malloc)); -char* __attribute__((malloc)) getMACfromIP(const char* ipaddr); -char* __attribute__((malloc)) getNameFromIP(const char* ipaddr); -char* __attribute__((malloc)) getIfaceFromIP(const char* ipaddr); +char *getMACfromIP(const char* ipaddr) __attribute__((malloc)); +char *getNameFromIP(const char* ipaddr) __attribute__((malloc)); +char *getIfaceFromIP(const char* ipaddr) __attribute__((malloc)); void resolveNetworkTableNames(void); #endif //NETWORKTABLE_H diff --git a/src/resolve.c b/src/resolve.c index a63909015..871492e0d 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -134,17 +134,6 @@ char *resolveHostname(const char *addr) IPv6 = true; } - if( (IPv6 && !config.resolveIPv6) || - (!IPv6 && !config.resolveIPv4)) - { - if(config.debug & DEBUG_RESOLVER) - { - logg(" ---> \"\" (configured to not resolve %s host names)", - IPv6 ? "IPv6" : "IPv4"); - } - return strdup(""); - } - // Initialize resolver subroutines if trying to resolve for the first time // res_init() reads resolv.conf to get the default domain name and name server // address(es). If no server is given, the local host is tried. If no domain @@ -285,6 +274,24 @@ static size_t resolveAndAddHostname(size_t ippos, size_t oldnamepos) char* oldname = strdup(getstr(oldnamepos)); unlock_shm(); + // Test if we want to resolve an IPv6 address + bool IPv6 = false; + if(strstr(ipaddr,":") != NULL) + { + IPv6 = true; + } + + if( (IPv6 && !config.resolveIPv6) || + (!IPv6 && !config.resolveIPv4)) + { + if(config.debug & DEBUG_RESOLVER) + { + logg(" ---> \"\" (configured to not resolve %s host names)", + IPv6 ? "IPv6" : "IPv4"); + } + return 0; + } + // Important: Don't hold a lock while resolving as the main thread // (dnsmasq) needs to be operable during the call to resolveHostname() char* newname = resolveHostname(ipaddr); @@ -294,7 +301,7 @@ static size_t resolveAndAddHostname(size_t ippos, size_t oldnamepos) if(strlen(newname) == 0 && config.names_from_netdb) { free(newname); - newname = getDatabaseHostname(ipaddr); + newname = getNameFromIP(ipaddr); } // Only store new newname if it is valid and differs from oldname From 5c2e24227dd3efcae44467230ac78af5affa4c92 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Thu, 10 Sep 2020 21:23:24 +0200 Subject: [PATCH 4/5] Do not try to free NULL pointer in resolveAndAddHostname Signed-off-by: DL6ER --- src/resolve.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/resolve.c b/src/resolve.c index 871492e0d..7bea2be7e 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -325,7 +325,8 @@ static size_t resolveAndAddHostname(size_t ippos, size_t oldnamepos) logg("Not adding \"%s\" to buffer (unchanged)", oldname); } - free(newname); + if(newname != NULL) + free(newname); free(ipaddr); free(oldname); From 1123a21390f03997319e4c645705ae2f2c45f1be Mon Sep 17 00:00:00 2001 From: DL6ER Date: Thu, 10 Sep 2020 21:25:27 +0200 Subject: [PATCH 5/5] Show debug messages only in debug mode Signed-off-by: DL6ER --- src/database/gravity-db.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/database/gravity-db.c b/src/database/gravity-db.c index 786569e33..cc7159f3c 100644 --- a/src/database/gravity-db.c +++ b/src/database/gravity-db.c @@ -337,7 +337,9 @@ static bool get_client_groupids(clientsData* client) { free(hwaddr); hwaddr = NULL; - logg("Skipping mock-device hardware address lookup"); + + if(config.debug & DEBUG_CLIENTS) + logg("Skipping mock-device hardware address lookup"); } // MAC address fallback: Try to synthesize MAC address from internal buffer @@ -348,7 +350,9 @@ static bool get_client_groupids(clientsData* client) snprintf(hwaddr, strlen, "%02X:%02X:%02X:%02X:%02X:%02X", client->hwaddr[0], client->hwaddr[1], client->hwaddr[2], client->hwaddr[3], client->hwaddr[4], client->hwaddr[5]); - logg("--> Obtained %s from internal ARP cache", hwaddr); + + if(config.debug & DEBUG_CLIENTS) + logg("--> Obtained %s from internal ARP cache", hwaddr); } } @@ -432,7 +436,8 @@ static bool get_client_groupids(clientsData* client) { free(hostname); hostname = NULL; - logg("Skipping empty host name lookup"); + if(config.debug & DEBUG_CLIENTS) + logg("Skipping empty host name lookup"); } } @@ -517,7 +522,8 @@ static bool get_client_groupids(clientsData* client) { free(interface); interface = 0; - logg("Skipping empty interface lookup"); + if(config.debug & DEBUG_CLIENTS) + logg("Skipping empty interface lookup"); } }