Skip to content

Commit

Permalink
Check if clients are public IP addresses
Browse files Browse the repository at this point in the history
Signed-off-by: DL6ER <[email protected]>
  • Loading branch information
DL6ER committed Nov 17, 2024
1 parent 988a3c3 commit 79ab06f
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ set(sources
datastructure.h
dnsmasq_interface.c
dnsmasq_interface.h
dnsmasq_net.h
edns0.c
edns0.h
enums.h
Expand Down
3 changes: 2 additions & 1 deletion src/dnsmasq/rfc1035.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "dnsmasq.h"
#include "dnsmasq_interface.h"
#include "dnsmasq_net.h"

int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
char *name, int isExtract, int extrabytes)
Expand Down Expand Up @@ -366,7 +367,7 @@ int private_net(struct in_addr addr, int ban_localhost)
((ip_addr & 0xFFFFFFFF) == 0xFFFFFFFF) /* 255.255.255.255/32 (broadcast)*/ ;
}

static int private_net6(struct in6_addr *a, int ban_localhost)
int private_net6(struct in6_addr *a, int ban_localhost)
{
/* Block IPv4-mapped IPv6 addresses in private IPv4 address space */
if (IN6_IS_ADDR_V4MAPPED(a))
Expand Down
20 changes: 20 additions & 0 deletions src/dnsmasq_net.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* Pi-hole: A black hole for Internet advertisements
* (c) 2024 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* FTL Engine
* Private network detection
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */

#ifndef DNSMASQ_NET_H
#define DNSMASQ_NET_H

#include <arpa/inet.h>

// defined in src/dnsmasq/rfc1035.c
extern int private_net(struct in_addr addr, int ban_localhost);
extern int private_net6(struct in6_addr *a, int ban_localhost);

#endif
42 changes: 40 additions & 2 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#include "lookup-table.h"
// get_and_clear_event()
#include "events.h"
// private_net(6)()
#include "dnsmasq_net.h"

// Resource checking interval
// default: 300 seconds
Expand Down Expand Up @@ -236,22 +238,54 @@ static void recycle(void)
}
}

/**
* @brief Check if the given IP address is a public IP address.
*
* This function determines whether the provided IP address is a public IP address.
* It first checks if the address is a private IPv4 address, and if not, it checks
* if it is a private IPv6 address. If the address is neither a private IPv4 nor
* a private IPv6 address, it is considered a public IP address.
*
* @param addr The IP address to check, as a null-terminated string.
* @return true if the IP address is public, false if it is private or invalid.
*/
static bool is_public_ip(const char *addr)
{
// Check if the IP address is a private IPv4 address
struct in_addr ip;
if(inet_pton(AF_INET, addr, &ip) == 1)
return private_net(ip, 1) == 0;

// Check if the IP address is a private IPv6 address
struct in6_addr ip6;
if(inet_pton(AF_INET6, addr, &ip6) == 1)
return private_net6(&ip6, 1) == 0;

return false;
}

// Subtract rate-limitation count from individual client counters
// As long as client->rate_limit is still larger than the allowed
// maximum count, the rate-limitation will just continue
static void reset_rate_limiting(void)
{
unsigned int public_clients = 0;
for(unsigned int clientID = 0; clientID < counters->clients; clientID++)
{
clientsData *client = getClient(clientID, true);
if(!client)
continue;

// Get client's IP address
const char *clientIP = getstr(client->ippos);

// Check if client is a public IP address
if(is_public_ip(clientIP))
public_clients++;

// Check if we are currently rate-limiting this client
if(client->flags.rate_limited)
{
const char *clientIP = getstr(client->ippos);

// Check if we want to continue rate limiting
if(client->rate_limit > config.dns.rateLimit.count.v.ui)
{
Expand All @@ -268,6 +302,10 @@ static void reset_rate_limiting(void)
// Reset counter
client->rate_limit = 0;
}

// Print warning if we have public clients
if(public_clients > 0)
log_warn("Found %u public client%s! Check your firewall!", public_clients, public_clients == 1 ? "" : "s");
}

static time_t lastRateLimitCleaner = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/tools/netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
#include <string.h>
#include <errno.h>

// defined in src/dnsmasq/rfc1035.c
extern int private_net(struct in_addr addr, int ban_localhost);
// private_net()
#include "dnsmasq_net.h"

static bool nlrequest(int fd, struct sockaddr_nl *sa, int nlmsg_type)
{
Expand Down

0 comments on commit 79ab06f

Please sign in to comment.