Unverified Commit 3b930c4d authored by Dan Schaper's avatar Dan Schaper Committed by GitHub
Browse files

Merge branch 'development' into tweak/moveloglocation

parents 052c8350 ea151441
......@@ -112,11 +112,15 @@ set(sources
daemon.h
datastructure.c
datastructure.h
dhcp-discover.c
dhcp-discover.h
dnsmasq_interface.c
dnsmasq_interface.h
edns0.c
edns0.h
enums.h
events.c
events.h
files.c
files.h
FTL.h
......
......@@ -8,26 +8,32 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "FTL.h"
#include "enums.h"
#include "memory.h"
#include "shmem.h"
#include "datastructure.h"
#include "setupVars.h"
#include "../FTL.h"
#include "api.h"
#include "../enums.h"
// getstr()
#include "../shmem.h"
// read_setupVarsconf()
#include "../setupVars.h"
// istelnet()
#include "socket.h"
#include "files.h"
#include "log.h"
// get_FTL_db_filesize()
#include "../files.h"
// logg()
#include "../log.h"
#include "request.h"
#include "config.h"
#include "database/common.h"
#include "database/query-table.h"
// struct config
#include "../config.h"
// get_sqlite3_version()
#include "../database/common.h"
// get_number_of_queries_in_DB()
#include "../database/query-table.h"
// in_auditlist()
#include "database/gravity-db.h"
#include "overTime.h"
#include "api.h"
#include "version.h"
// enum REGEX
#include "regex_r.h"
#include "../database/gravity-db.h"
// struct overTime
#include "../overTime.h"
// Version information
#include "../version.h"
#define min(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
......@@ -849,8 +855,29 @@ void getAllQueries(const char *client_message, const int *sock)
continue;
// Skip if domain is not identical with what the user wants to see
if(filterdomainname && query->domainID != domainid)
continue;
if(filterdomainname)
{
// Check direct match
if(query->domainID == domainid)
{
// Get this query
}
// If the domain of this query did not match, the CNAME
// domain may still match - we have to check it in
// addition if this query is of CNAME blocked type
else if((query->status == QUERY_GRAVITY_CNAME ||
query->status == QUERY_BLACKLIST_CNAME ||
query->status == QUERY_REGEX_CNAME) &&
query->CNAME_domainID == domainid)
{
// Get this query
}
else
{
// Skip this query
continue;
}
}
// Skip if client name and IP are not identical with what the user wants to see
if(filterclientname && query->clientID != clientid)
......
......@@ -8,16 +8,18 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "FTL.h"
#include "../FTL.h"
#include "api.h"
#include "shmem.h"
#include "timers.h"
#include "../shmem.h"
#include "../timers.h"
#include "request.h"
#include "socket.h"
#include "resolve.h"
#include "regex_r.h"
#include "database/network-table.h"
#include "log.h"
#include "../resolve.h"
#include "../regex_r.h"
#include "../database/network-table.h"
#include "../log.h"
// Eventqueue routines
#include "../events.h"
bool __attribute__((pure)) command(const char *client_message, const char* cmd) {
return strstr(client_message, cmd) != NULL;
......@@ -152,12 +154,7 @@ void process_request(const char *client_message, int *sock)
{
processed = true;
logg("Received API request to re-resolve host names");
// Important: Don't obtain a lock for this request
// Locking will be done internally when needed
// onlynew=false -> reresolve all host names
resolveClients(false);
resolveForwardDestinations(false);
logg("Done re-resolving host names");
set_event(RELOAD_PRIVACY_LEVEL);
}
else if(command(client_message, ">recompile-regex"))
{
......
......@@ -20,6 +20,10 @@
#include "regex_r.h"
// init_shmem()
#include "shmem.h"
// run_dhcp_discover()
#include "dhcp-discover.h"
// defined in dnsmasq.c
extern void print_dnsmasq_version(void);
bool dnsmasq_debug = false;
bool daemonmode = true, cli_mode = false;
......@@ -134,6 +138,32 @@ void parse_args(int argc, char* argv[])
exit(EXIT_SUCCESS);
}
// Extended version output
if(strcmp(argv[i], "-vv") == 0)
{
// Print FTL version
printf("****************************** FTL **********************************\n");
printf("Version: %s\n\n", get_FTL_version());
// Print dnsmasq version and compile time options
print_dnsmasq_version();
// Print SQLite3 version and compile time options
printf("****************************** SQLite3 ******************************\n");
printf("Version: %s\n", sqlite3_libversion());
printf("Compile options: ");
unsigned int o = 0;
const char *opt = NULL;
while((opt = sqlite3_compileoption_get(o++)) != NULL)
{
if(o != 1)
printf(" ");
printf("%s", opt);
}
printf("\n");
exit(EXIT_SUCCESS);
}
if(strcmp(argv[i], "-t") == 0 ||
strcmp(argv[i], "tag") == 0)
{
......@@ -179,6 +209,14 @@ void parse_args(int argc, char* argv[])
}
}
// Regex test mode
if(strcmp(argv[i], "dhcp-discover") == 0)
{
// Enable stdout printing
cli_mode = true;
exit(run_dhcp_discover());
}
// List of implemented arguments
if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "help") == 0 || strcmp(argv[i], "--help") == 0)
{
......@@ -190,7 +228,8 @@ void parse_args(int argc, char* argv[])
printf("\t don't go into daemon mode\n");
printf("\t test Don't start pihole-FTL but\n");
printf("\t instead quit immediately\n");
printf("\t-v, version Return version\n");
printf("\t-v, version Return FTL version\n");
printf("\t-vv Return more version information\n");
printf("\t-t, tag Return git tag\n");
printf("\t-b, branch Return git branch\n");
printf("\t-f, no-daemon Don't go into daemon mode\n");
......@@ -201,6 +240,8 @@ void parse_args(int argc, char* argv[])
printf("\t expressions in the database\n");
printf("\tregex-test str rgx Test str against regular expression\n");
printf("\t given by rgx\n");
printf("\tdhcp-discover Discover DHCP servers in the local\n");
printf("\t network\n");
printf("\n\nOnline help: https://github.com/pi-hole/FTL\n");
exit(EXIT_SUCCESS);
}
......
......@@ -376,20 +376,20 @@ void read_FTLconf(void)
// MAXNETAGE
// IP addresses (and associated host names) older than the specified number
// of hours are removed to avoid dead entries in the network overview table
// defaults to: disabled (0.0 hours)
config.network_expire = 0u;
// of days are removed to avoid dead entries in the network overview table
// defaults to: the same value as MAXDBDAYS
config.network_expire = config.maxDBdays;
buffer = parse_FTLconf(fp, "MAXNETAGE");
fvalue = 0;
int ivalue = 0;
if(buffer != NULL &&
sscanf(buffer, "%f", &fvalue) &&
fvalue >= 0.0f && fvalue <= 8760.0f) // 8760 = 24 * 365
config.network_expire = (unsigned int)(fvalue * 3600);
sscanf(buffer, "%i", &ivalue) &&
ivalue > 0 && ivalue <= 8760) // 8760 days = 24 years
config.network_expire = ivalue;
if(config.network_expire > 0u)
logg(" MAXNETAGE: Removing IP addresses and host names from network table after %.1f hours",
(float)config.network_expire/3600.0f);
logg(" MAXNETAGE: Removing IP addresses and host names from network table after %u days",
config.network_expire);
else
logg(" MAXNETAGE: No automated removal of IP addresses and host names from the network table");
......@@ -712,6 +712,10 @@ void read_debuging_settings(FILE *fp)
// defaults to: false
setDebugOption(fp, "DEBUG_CLIENTS", DEBUG_CLIENTS);
// DEBUG_EVENTS
// defaults to: false
setDebugOption(fp, "DEBUG_EVENTS", DEBUG_EVENTS);
if(config.debug)
{
logg("*****************************");
......@@ -734,6 +738,7 @@ void read_debuging_settings(FILE *fp)
logg("* DEBUG_RESOLVER %s *", (config.debug & DEBUG_RESOLVER)? "YES":"NO ");
logg("* DEBUG_EDNS0 %s *", (config.debug & DEBUG_EDNS0)? "YES":"NO ");
logg("* DEBUG_CLIENTS %s *", (config.debug & DEBUG_CLIENTS)? "YES":"NO ");
logg("* DEBUG_EVENTS %s *", (config.debug & DEBUG_EVENTS)? "YES":"NO ");
logg("*****************************");
}
......
......@@ -8,17 +8,20 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "FTL.h"
#include "database/common.h"
#include "database/network-table.h"
#include "database/message-table.h"
#include "shmem.h"
#include "memory.h"
#include "config.h"
#include "log.h"
#include "timers.h"
#include "files.h"
#include "database/sqlite3-ext.h"
#include "../FTL.h"
#include "common.h"
#include "network-table.h"
#include "message-table.h"
#include "../shmem.h"
#include "../memory.h"
// struct config
#include "../config.h"
// logg()
#include "../log.h"
#include "../timers.h"
// file_exists()
#include "../files.h"
#include "sqlite3-ext.h"
sqlite3 *FTL_db = NULL;
bool database = true;
......
......@@ -8,20 +8,22 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "FTL.h"
#include "../FTL.h"
#include "database-thread.h"
#include "common.h"
// [un]lock_shm();
#include "shmem.h"
#include "../shmem.h"
// parse_neighbor_cache()
#include "network-table.h"
// DB_save_queries()
#include "query-table.h"
#include "config.h"
#include "log.h"
#include "timers.h"
#include "../config.h"
#include "../log.h"
#include "../timers.h"
// global variable killed
#include "signals.h"
#include "../signals.h"
// Eventqueue routines
#include "../events.h"
void *DB_thread(void *val)
{
......@@ -38,42 +40,56 @@ void *DB_thread(void *val)
// to the database
time_t lastDBsave = time(NULL) - time(NULL)%config.DBinterval;
while(!killed && database)
while(!killed)
{
time_t now = time(NULL);
if(now - lastDBsave >= config.DBinterval)
if(database)
{
// Update lastDBsave timer
lastDBsave = time(NULL) - time(NULL)%config.DBinterval;
time_t now = time(NULL);
if(now - lastDBsave >= config.DBinterval)
{
// Update lastDBsave timer
lastDBsave = time(NULL) - time(NULL)%config.DBinterval;
// Lock FTL's data structures, since it is
// likely that they will be changed here
lock_shm();
// Lock FTL's data structures, since it is
// likely that they will be changed here
lock_shm();
// Save data to database
DB_save_queries();
// Save data to database
DB_save_queries();
// Release data lock
unlock_shm();
// Release data lock
unlock_shm();
// Check if GC should be done on the database
if(DBdeleteoldqueries)
{
// No thread locks needed
delete_old_queries_in_DB();
DBdeleteoldqueries = false;
// Check if GC should be done on the database
if(DBdeleteoldqueries)
{
// No thread locks needed
delete_old_queries_in_DB();
DBdeleteoldqueries = false;
}
// Parse neighbor cache (fill network table) if enabled
if (config.parse_arp_cache)
set_event(PARSE_NEIGHBOR_CACHE);
}
// Parse neighbor cache (fill network table) if enabled
if (config.parse_arp_cache)
parse_neighbor_cache();
// Update MAC vendor strings once a month (the MAC vendor
// database is not updated very often)
if(now % 2592000L == 0)
updateMACVendorRecords();
}
// Update MAC vendor strings once a month (the MAC vendor
// database is not updated very often)
if(now % 2592000L == 0)
updateMACVendorRecords();
// Process database related event queue elements
if(get_and_clear_event(RELOAD_GRAVITY))
FTL_reload_all_domainlists();
if(get_and_clear_event(RELOAD_PRIVACY_LEVEL))
get_privacy_level(NULL);
if(get_and_clear_event(PARSE_NEIGHBOR_CACHE))
parse_neighbor_cache();
// Sleep 0.1 seconds
sleepms(100);
}
......
......@@ -8,21 +8,23 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "FTL.h"
#include "../FTL.h"
#include "sqlite3.h"
#include "gravity-db.h"
#include "config.h"
#include "log.h"
// struct config
#include "../config.h"
// logg()
#include "../log.h"
// match_regex()
#include "regex_r.h"
#include "../regex_r.h"
// getstr()
#include "shmem.h"
#include "../shmem.h"
// SQLite3 prepared statement vectors
#include "../vector.h"
// log_subnet_warning()
#include "database/message-table.h"
#include "message-table.h"
// getMACfromIP()
#include "database/network-table.h"
#include "network-table.h"
// struct DNSCacheData
#include "../datastructure.h"
......@@ -337,7 +339,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 +352,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 +438,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 +524,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");
}
}
......
......@@ -8,12 +8,13 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "FTL.h"
#include "database/message-table.h"
#include "database/common.h"
#include "log.h"
#include "../FTL.h"
#include "message-table.h"
#include "common.h"
// logg()
#include "../log.h"
// get_group_names()
#include "database/gravity-db.h"
#include "gravity-db.h"
// cli_mode
#include "../args.h"
......
......@@ -8,17 +8,20 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "FTL.h"
#include "database/network-table.h"
#include "database/common.h"
#include "shmem.h"
#include "memory.h"
#include "log.h"
#include "timers.h"
#include "config.h"
#include "datastructure.h"
#include "../FTL.h"
#include "network-table.h"
#include "common.h"
#include "../shmem.h"
// strdup()
#include "../memory.h"
#include "../log.h"
// timer_elapsed_msec()
#include "../timers.h"
// struct config
#include "../config.h"
//#include "../datastructure.h"
// resolveHostname()
#include "resolve.h"
#include "../resolve.h"
// Private prototypes
static char *getMACVendor(const char *hwaddr);
......@@ -1100,11 +1103,11 @@ void parse_neighbor_cache(void)
// Remove all but the most recent IP addresses not seen for more than a certain time
if(config.network_expire > 0u)
{
const time_t limit = time(NULL)-24*3600*config.network_expire;
dbquery("DELETE FROM network_addresses "
"WHERE lastSeen < cast(strftime('%%s', 'now') as int)-%u;",
config.network_expire);
"WHERE lastSeen < %u;", limit);
dbquery("UPDATE network_addresses SET name = NULL "
"WHERE nameUpdated < cast(strftime('%%s', 'now') as int)-%u;", config.network_expire);
"WHERE nameUpdated < %u;", limit);
}
// Start collecting database commands
......@@ -1581,103 +1584,87 @@ void updateMACVendorRecords(void)
dbclose();
}
char *__attribute__((malloc)) getDatabaseHostname(const char *ipaddr)
// Get hardware address of device identified by IP address
char *__attribute__((malloc)) getMACfromIP(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);
logg("getMACfromIP(\"%s\") - Failed to open DB", ipaddr);
return NULL;
}
// Prepare SQLite statement
// We request the most recent IP entry in case there an IP appears
// multiple times in the network_addresses table
sqlite3_stmt *stmt = NULL;
const char *querystr = "SELECT name FROM network_addresses "
"WHERE name IS NOT NULL AND ip = ?;";
const char *querystr = "SELECT hwaddr FROM network WHERE id = "
"(SELECT network_id FROM network_addresses "
"WHERE ip = ? GROUP BY ip HAVING max(lastSeen));";
int rc = sqlite3_prepare_v2(FTL_db, querystr, -1, &stmt, NULL);
if( rc != SQLITE_OK ){
logg("getDatabaseHostname(\"%s\") - SQL error prepare: %s",
logg("getMACfromIP(\"%s\") - SQL error prepare: %s",
ipaddr, sqlite3_errstr(rc));
if(!db_already_open)
dbclose();
return strdup("");
return NULL;
}
// 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",
logg("getMACfromIP(\"%s\"): Failed to bind ip: %s",
ipaddr, sqlite3_errstr(rc));
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
if(!db_already_open)
dbclose();
return strdup("");
return NULL;
}
char *hostname = NULL;
char *hwaddr = NULL;
rc = sqlite3_step(stmt);
if(rc == SQLITE_ROW)
{
// Database record found (result might be empty)
hostname = strdup((char*)sqlite3_column_text(stmt, 0));
hwaddr = strdup((char*)sqlite3_column_text(stmt, 0));
}
else
{
// Not found or error (will be logged automatically through our SQLite3 hook)
hostname = strdup("");
hwaddr = NULL;
}
if(config.debug & DEBUG_DATABASE && hwaddr != NULL)
logg("Found database hardware address %s -> %s", ipaddr, hwaddr);
// Finalize statement and close database handle
sqlite3_reset(stmt);