mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-04 23:25:06 -05:00
Add IPv6 support
This commit is contained in:
177
clientlog.c
177
clientlog.c
@@ -53,7 +53,7 @@
|
||||
#define TABLE_SIZE (1UL<<NBITS)
|
||||
|
||||
typedef struct _Node {
|
||||
unsigned long ip_addr;
|
||||
IPAddr ip_addr;
|
||||
unsigned long client_hits;
|
||||
unsigned long peer_hits;
|
||||
unsigned long cmd_hits_bad;
|
||||
@@ -69,8 +69,10 @@ typedef struct _Subnet {
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Table for the class A subnet */
|
||||
static Subnet top_subnet;
|
||||
/* Table for the IPv4 class A subnet */
|
||||
static Subnet top_subnet4;
|
||||
/* Table for IPv6 */
|
||||
static Subnet top_subnet6;
|
||||
|
||||
/* Table containing pointers directly to all nodes that have been
|
||||
allocated. */
|
||||
@@ -89,6 +91,34 @@ static int active = 0;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
split_ip6(IPAddr *ip, uint32_t *dst)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
dst[i] = ip->addr.in6[i * 4 + 0] << 24 |
|
||||
ip->addr.in6[i * 4 + 1] << 16 |
|
||||
ip->addr.in6[i * 4 + 2] << 8 |
|
||||
ip->addr.in6[i * 4 + 3];
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
inline static uint32_t
|
||||
get_subnet(uint32_t *addr, unsigned int where)
|
||||
{
|
||||
int off;
|
||||
|
||||
off = where / 32;
|
||||
where %= 32;
|
||||
|
||||
return (addr[off] >> (32 - NBITS - where)) & ((1UL << NBITS) - 1);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
|
||||
static void
|
||||
clear_subnet(Subnet *subnet)
|
||||
{
|
||||
@@ -118,7 +148,8 @@ clear_node(Node *node)
|
||||
void
|
||||
CLG_Initialise(void)
|
||||
{
|
||||
clear_subnet(&top_subnet);
|
||||
clear_subnet(&top_subnet4);
|
||||
clear_subnet(&top_subnet6);
|
||||
if (CNF_GetNoClientLog()) {
|
||||
active = 0;
|
||||
} else {
|
||||
@@ -178,27 +209,18 @@ create_node(Subnet *parent_subnet, int the_entry)
|
||||
expanding subnet tables and node entries as we go if necessary. */
|
||||
|
||||
static void *
|
||||
find_subnet(Subnet *subnet, CLG_IP_Addr addr, int bits_left)
|
||||
find_subnet(Subnet *subnet, uint32_t *addr, int addr_len, int bits_consumed)
|
||||
{
|
||||
unsigned long this_subnet, new_subnet, mask, shift;
|
||||
unsigned long new_bits_left;
|
||||
|
||||
shift = 32 - NBITS;
|
||||
mask = (1UL<<shift) - 1;
|
||||
this_subnet = addr >> shift;
|
||||
new_subnet = (addr & mask) << NBITS;
|
||||
new_bits_left = bits_left - NBITS;
|
||||
uint32_t this_subnet;
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "fs addr=%08lx bl=%d ma=%08lx this=%08lx newsn=%08lx nbl=%d\n",
|
||||
addr, bits_left, mask, this_subnet, new_subnet, new_bits_left);
|
||||
#endif
|
||||
this_subnet = get_subnet(addr, bits_consumed);
|
||||
bits_consumed += NBITS;
|
||||
|
||||
if (new_bits_left > 0) {
|
||||
if (bits_consumed < 32 * addr_len) {
|
||||
if (!subnet->entry[this_subnet]) {
|
||||
create_subnet(subnet, this_subnet);
|
||||
}
|
||||
return find_subnet((Subnet *) subnet->entry[this_subnet], new_subnet, new_bits_left);
|
||||
return find_subnet((Subnet *) subnet->entry[this_subnet], addr, addr_len, bits_consumed);
|
||||
} else {
|
||||
if (!subnet->entry[this_subnet]) {
|
||||
create_node(subnet, this_subnet);
|
||||
@@ -213,30 +235,21 @@ find_subnet(Subnet *subnet, CLG_IP_Addr addr, int bits_left)
|
||||
one of the parents does not exist - never open a node out */
|
||||
|
||||
static void *
|
||||
find_subnet_dont_open(Subnet *subnet, CLG_IP_Addr addr, int bits_left)
|
||||
find_subnet_dont_open(Subnet *subnet, uint32_t *addr, int addr_len, int bits_consumed)
|
||||
{
|
||||
unsigned long this_subnet, new_subnet, mask, shift;
|
||||
unsigned long new_bits_left;
|
||||
uint32_t this_subnet;
|
||||
|
||||
if (bits_left == 0) {
|
||||
if (bits_consumed >= 32 * addr_len) {
|
||||
return subnet;
|
||||
} else {
|
||||
|
||||
shift = 32 - NBITS;
|
||||
mask = (1UL<<shift) - 1;
|
||||
this_subnet = addr >> shift;
|
||||
new_subnet = (addr & mask) << NBITS;
|
||||
new_bits_left = bits_left - NBITS;
|
||||
this_subnet = get_subnet(addr, bits_consumed);
|
||||
bits_consumed += NBITS;
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "fsdo addr=%08lx bl=%d this=%08lx newsn=%08lx nbl=%d\n",
|
||||
addr, bits_left, this_subnet, new_subnet, new_bits_left);
|
||||
#endif
|
||||
|
||||
if (!subnet->entry[this_subnet]) {
|
||||
return NULL;
|
||||
} else {
|
||||
return find_subnet_dont_open((Subnet *) subnet->entry[this_subnet], new_subnet, new_bits_left);
|
||||
return find_subnet_dont_open((Subnet *) subnet->entry[this_subnet], addr, addr_len, bits_consumed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,12 +257,25 @@ find_subnet_dont_open(Subnet *subnet, CLG_IP_Addr addr, int bits_left)
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
CLG_LogNTPClientAccess (CLG_IP_Addr client, time_t now)
|
||||
CLG_LogNTPClientAccess (IPAddr *client, time_t now)
|
||||
{
|
||||
uint32_t ip6[4];
|
||||
Node *node;
|
||||
|
||||
if (active) {
|
||||
node = (Node *) find_subnet(&top_subnet, client, 32);
|
||||
node->ip_addr = client;
|
||||
switch (client->family) {
|
||||
case IPADDR_INET4:
|
||||
node = (Node *) find_subnet(&top_subnet4, &client->addr.in4, 1, 0);
|
||||
break;
|
||||
case IPADDR_INET6:
|
||||
split_ip6(client, ip6);
|
||||
node = (Node *) find_subnet(&top_subnet6, ip6, 4, 0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
node->ip_addr = *client;
|
||||
++node->client_hits;
|
||||
node->last_ntp_hit = now;
|
||||
}
|
||||
@@ -258,12 +284,25 @@ CLG_LogNTPClientAccess (CLG_IP_Addr client, time_t now)
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
CLG_LogNTPPeerAccess(CLG_IP_Addr client, time_t now)
|
||||
CLG_LogNTPPeerAccess(IPAddr *client, time_t now)
|
||||
{
|
||||
uint32_t ip6[4];
|
||||
Node *node;
|
||||
|
||||
if (active) {
|
||||
node = (Node *) find_subnet(&top_subnet, client, 32);
|
||||
node->ip_addr = client;
|
||||
switch (client->family) {
|
||||
case IPADDR_INET4:
|
||||
node = (Node *) find_subnet(&top_subnet4, &client->addr.in4, 1, 0);
|
||||
break;
|
||||
case IPADDR_INET6:
|
||||
split_ip6(client, ip6);
|
||||
node = (Node *) find_subnet(&top_subnet6, ip6, 4, 0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
node->ip_addr = *client;
|
||||
++node->peer_hits;
|
||||
node->last_ntp_hit = now;
|
||||
}
|
||||
@@ -272,12 +311,25 @@ CLG_LogNTPPeerAccess(CLG_IP_Addr client, time_t now)
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
CLG_LogCommandAccess(CLG_IP_Addr client, CLG_Command_Type type, time_t now)
|
||||
CLG_LogCommandAccess(IPAddr *client, CLG_Command_Type type, time_t now)
|
||||
{
|
||||
uint32_t ip6[4];
|
||||
Node *node;
|
||||
|
||||
if (active) {
|
||||
node = (Node *) find_subnet(&top_subnet, client, 32);
|
||||
node->ip_addr = client;
|
||||
switch (client->family) {
|
||||
case IPADDR_INET4:
|
||||
node = (Node *) find_subnet(&top_subnet4, &client->addr.in4, 1, 0);
|
||||
break;
|
||||
case IPADDR_INET6:
|
||||
split_ip6(client, ip6);
|
||||
node = (Node *) find_subnet(&top_subnet6, ip6, 4, 0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
node->ip_addr = *client;
|
||||
node->last_cmd_hit = now;
|
||||
switch (type) {
|
||||
case CLG_CMD_AUTH:
|
||||
@@ -299,16 +351,32 @@ CLG_LogCommandAccess(CLG_IP_Addr client, CLG_Command_Type type, time_t now)
|
||||
/* ================================================== */
|
||||
|
||||
CLG_Status
|
||||
CLG_GetSubnetBitmap(CLG_IP_Addr subnet, int bits, CLG_Bitmap result)
|
||||
CLG_GetSubnetBitmap(IPAddr *subnet, int bits, CLG_Bitmap result)
|
||||
{
|
||||
Subnet *s;
|
||||
uint32_t ip6[4];
|
||||
unsigned long i;
|
||||
unsigned long word, bit, mask;
|
||||
|
||||
if ((bits == 0) || (bits == 8) || (bits == 16) || (bits == 24)) {
|
||||
if (bits >= 0 && bits % 8 == 0) {
|
||||
memset (result, 0, TABLE_SIZE/8);
|
||||
if (active) {
|
||||
s = find_subnet_dont_open(&top_subnet, subnet, bits);
|
||||
switch (subnet->family) {
|
||||
case IPADDR_INET4:
|
||||
if (bits >= 32)
|
||||
return CLG_BADSUBNET;
|
||||
s = find_subnet_dont_open(&top_subnet4, &subnet->addr.in4, 1, 32 - bits);
|
||||
break;
|
||||
case IPADDR_INET6:
|
||||
if (bits >= 128)
|
||||
return CLG_BADSUBNET;
|
||||
split_ip6(subnet, ip6);
|
||||
s = find_subnet_dont_open(&top_subnet6, ip6, 4, 128 - bits);
|
||||
break;
|
||||
default:
|
||||
return CLG_BADSUBNET;
|
||||
}
|
||||
|
||||
if (s) {
|
||||
for (i=0; i<256; i++) {
|
||||
if (s->entry[i]) {
|
||||
@@ -333,15 +401,26 @@ CLG_GetSubnetBitmap(CLG_IP_Addr subnet, int bits, CLG_Bitmap result)
|
||||
/* ================================================== */
|
||||
|
||||
CLG_Status
|
||||
CLG_GetClientAccessReportByIP(unsigned long ip, RPT_ClientAccess_Report *report, time_t now)
|
||||
CLG_GetClientAccessReportByIP(IPAddr *ip, RPT_ClientAccess_Report *report, time_t now)
|
||||
{
|
||||
uint32_t ip6[4];
|
||||
Node *node;
|
||||
|
||||
if (!active) {
|
||||
return CLG_INACTIVE;
|
||||
} else {
|
||||
node = (Node *) find_subnet_dont_open(&top_subnet, ip, 32);
|
||||
|
||||
switch (ip->family) {
|
||||
case IPADDR_INET4:
|
||||
node = (Node *) find_subnet_dont_open(&top_subnet4, &ip->addr.in4, 1, 0);
|
||||
break;
|
||||
case IPADDR_INET6:
|
||||
split_ip6(ip, ip6);
|
||||
node = (Node *) find_subnet_dont_open(&top_subnet6, ip6, 4, 0);
|
||||
break;
|
||||
default:
|
||||
return CLG_EMPTYSUBNET;
|
||||
}
|
||||
|
||||
if (!node) {
|
||||
return CLG_EMPTYSUBNET;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user