mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
81f72c3d11
Signed-off-by: DL6ER <dl6er@dl6er.de>
129 lines
3.2 KiB
C
129 lines
3.2 KiB
C
/* Pi-hole: A black hole for Internet advertisements
|
|
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
|
* Network-wide ad blocking via your own hardware.
|
|
*
|
|
* FTL Engine
|
|
* DNS Client Implementation
|
|
*
|
|
* This file is copyright under the latest version of the EUPL.
|
|
* Please see LICENSE file for your rights under this license. */
|
|
|
|
#include "FTL.h"
|
|
|
|
char *resolveHostname(const char *addr)
|
|
{
|
|
// Get host name
|
|
struct hostent *he = NULL;
|
|
char *hostname = NULL;;
|
|
bool IPv6 = false;
|
|
|
|
// Check if this is a hidden client
|
|
// if so, return "hidden" as hostname
|
|
if(strcmp(addr, "0.0.0.0") == 0)
|
|
{
|
|
hostname = strdup("hidden");
|
|
//if(hostname == NULL) return NULL;
|
|
return hostname;
|
|
}
|
|
|
|
// Test if we want to resolve an IPv6 address
|
|
if(strstr(addr,":") != NULL)
|
|
{
|
|
IPv6 = true;
|
|
}
|
|
|
|
if(IPv6 && config.resolveIPv6) // Resolve IPv6 address only if requested
|
|
{
|
|
struct in6_addr ipaddr;
|
|
inet_pton(AF_INET6, addr, &ipaddr);
|
|
he = gethostbyaddr(&ipaddr, sizeof ipaddr, AF_INET6);
|
|
}
|
|
else if(!IPv6 && config.resolveIPv4) // Resolve IPv4 address only if requested
|
|
{
|
|
struct in_addr ipaddr;
|
|
inet_pton(AF_INET, addr, &ipaddr);
|
|
he = gethostbyaddr(&ipaddr, sizeof ipaddr, AF_INET);
|
|
}
|
|
|
|
if(he == NULL)
|
|
{
|
|
// No hostname found
|
|
hostname = strdup("");
|
|
//if(hostname == NULL) return NULL;
|
|
}
|
|
else
|
|
{
|
|
// Return hostname copied to new memory location
|
|
hostname = strdup(he->h_name);
|
|
if(hostname == NULL) return NULL;
|
|
// Convert hostname to lower case
|
|
strtolower(hostname);
|
|
}
|
|
return hostname;
|
|
}
|
|
|
|
// This routine is run *after* garbage cleaning (default interval is once per hour)
|
|
// to account for possibly updated hostnames
|
|
void reresolveHostnames(void)
|
|
{
|
|
int clientID;
|
|
for(clientID = 0; clientID < counters.clients; clientID++)
|
|
{
|
|
// Memory validation
|
|
validate_access("clients", clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
|
|
|
// Process this client only if it has at least one active query in the log
|
|
if(clients[clientID].count < 1)
|
|
continue;
|
|
|
|
// Get client hostname
|
|
char *hostname = resolveHostname(clients[clientID].ip);
|
|
if(strlen(hostname) > 0)
|
|
{
|
|
// Delete possibly already existing hostname pointer before storing new data
|
|
if(clients[clientID].name != NULL)
|
|
{
|
|
free(clients[clientID].name);
|
|
clients[clientID].name = NULL;
|
|
}
|
|
|
|
// Store client hostname
|
|
clients[clientID].name = strdup(hostname);
|
|
}
|
|
free(hostname);
|
|
}
|
|
}
|
|
|
|
// This routine is run *before* saving to the database (default interval is once per minute)
|
|
// to account for new clients (and forward destinations)
|
|
void resolveNewClients(void)
|
|
{
|
|
int i;
|
|
for(i = 0; i < counters.clients; i++)
|
|
{
|
|
// Memory validation
|
|
validate_access("clients", i, true, __LINE__, __FUNCTION__, __FILE__);
|
|
|
|
// Only try to resolve new clients
|
|
// Note that it can happen that we are not able to find hostnames but we don't
|
|
// want to try to resolve them every minute in this case.
|
|
if(clients[i].new)
|
|
{
|
|
clients[i].name = resolveHostname(clients[i].ip);
|
|
clients[i].new = false;
|
|
}
|
|
}
|
|
for(i = 0; i < counters.forwarded; i++)
|
|
{
|
|
// Memory validation
|
|
validate_access("forwarded", i, true, __LINE__, __FUNCTION__, __FILE__);
|
|
|
|
// Only try to resolve new forward destinations
|
|
if(forwarded[i].new)
|
|
{
|
|
forwarded[i].name = resolveHostname(forwarded[i].ip);
|
|
forwarded[i].new = false;
|
|
}
|
|
}
|
|
}
|