Add IPv6 support
This commit is contained in:
parent
183d56fd40
commit
8265ff2890
32 changed files with 1709 additions and 770 deletions
163
acquire.c
163
acquire.c
|
@ -65,7 +65,8 @@
|
|||
|
||||
#define RETRANSMISSION_TIMEOUT (1.0)
|
||||
|
||||
typedef struct { unsigned long ip_addr;
|
||||
typedef struct {
|
||||
IPAddr ip_addr; /* Address of the server */
|
||||
int sanity; /* Flag indicating whether source
|
||||
looks sane or not */
|
||||
int n_dead_probes; /* Number of probes sent to the server
|
||||
|
@ -93,7 +94,18 @@ static int n_completed_sources;
|
|||
|
||||
static int init_slew_threshold = -1;
|
||||
|
||||
static int sock_fd = -1;
|
||||
union sockaddr_in46 {
|
||||
struct sockaddr_in in4;
|
||||
#ifdef HAVE_IPV6
|
||||
struct sockaddr_in6 in6;
|
||||
#endif
|
||||
struct sockaddr u;
|
||||
};
|
||||
|
||||
static int sock_fd4 = -1;
|
||||
#ifdef HAVE_IPV6
|
||||
static int sock_fd6 = -1;
|
||||
#endif
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
|
@ -143,12 +155,13 @@ ACQ_Finalise(void)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
initialise_io(void)
|
||||
static int
|
||||
prepare_socket(int family)
|
||||
{
|
||||
unsigned short port_number = CNF_GetAcquisitionPort();
|
||||
int sock_fd;
|
||||
|
||||
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
sock_fd = socket(family, SOCK_DGRAM, 0);
|
||||
|
||||
if (sock_fd < 0) {
|
||||
LOG_FATAL(LOGF_Acquire, "Could not open socket : %s", strerror(errno));
|
||||
|
@ -158,18 +171,48 @@ initialise_io(void)
|
|||
/* Don't bother binding this socket - we're not fussed what port
|
||||
number it gets */
|
||||
} else {
|
||||
struct sockaddr_in my_addr;
|
||||
my_addr.sin_family = AF_INET;
|
||||
my_addr.sin_port = htons(port_number);
|
||||
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
if (bind(sock_fd, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) {
|
||||
union sockaddr_in46 my_addr;
|
||||
|
||||
memset(&my_addr, 0, sizeof (my_addr));
|
||||
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
my_addr.in4.sin_family = family;
|
||||
my_addr.in4.sin_port = htons(port_number);
|
||||
my_addr.in4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
my_addr.in6.sin6_family = family;
|
||||
my_addr.in6.sin6_port = htons(port_number);
|
||||
my_addr.in6.sin6_addr = in6addr_any;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (bind(sock_fd, &my_addr.u, sizeof(my_addr)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_Acquire, "Could not bind socket : %s\n", strerror(errno));
|
||||
/* but keep running */
|
||||
}
|
||||
}
|
||||
|
||||
SCH_AddInputFileHandler(sock_fd, read_from_socket, NULL);
|
||||
SCH_AddInputFileHandler(sock_fd, read_from_socket, (void *)(long)sock_fd);
|
||||
|
||||
return sock_fd;
|
||||
}
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
initialise_io(int family)
|
||||
{
|
||||
if (family == IPADDR_INET4 || family == IPADDR_UNSPEC)
|
||||
sock_fd4 = prepare_socket(AF_INET);
|
||||
#ifdef HAVE_IPV6
|
||||
if (family == IPADDR_INET6 || family == IPADDR_UNSPEC)
|
||||
sock_fd6 = prepare_socket(AF_INET6);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -177,10 +220,18 @@ initialise_io(void)
|
|||
static void
|
||||
finalise_io(void)
|
||||
{
|
||||
if (sock_fd >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd);
|
||||
close(sock_fd);
|
||||
if (sock_fd4 >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd4);
|
||||
close(sock_fd4);
|
||||
}
|
||||
sock_fd4 = -1;
|
||||
#ifdef HAVE_IPV6
|
||||
if (sock_fd6 >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd6);
|
||||
close(sock_fd6);
|
||||
}
|
||||
sock_fd6 = -1;
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -195,10 +246,11 @@ probe_source(SourceRecord *src)
|
|||
NTP_Mode my_mode = MODE_CLIENT;
|
||||
struct timeval cooked;
|
||||
double local_time_err;
|
||||
struct sockaddr_in his_addr;
|
||||
union sockaddr_in46 his_addr;
|
||||
int sock_fd;
|
||||
|
||||
#if 0
|
||||
printf("Sending probe to %08lx sent=%d samples=%d\n", src->ip_addr, src->n_probes_sent, src->n_samples);
|
||||
printf("Sending probe to %s sent=%d samples=%d\n", UTI_IPToString(&src->ip_addr), src->n_probes_sent, src->n_samples);
|
||||
#endif
|
||||
|
||||
pkt.lvm = (((LEAP_Unsynchronised << 6) & 0xc0) |
|
||||
|
@ -219,18 +271,37 @@ probe_source(SourceRecord *src)
|
|||
pkt.receive_ts.lo = 0; /* Set to 0 */
|
||||
|
||||
/* And do transmission */
|
||||
his_addr.sin_addr.s_addr = htonl(src->ip_addr);
|
||||
his_addr.sin_port = htons(123); /* Fixed for now */
|
||||
his_addr.sin_family = AF_INET;
|
||||
|
||||
memset(&his_addr, 0, sizeof (his_addr));
|
||||
switch (src->ip_addr.family) {
|
||||
case IPADDR_INET4:
|
||||
his_addr.in4.sin_addr.s_addr = htonl(src->ip_addr.addr.in4);
|
||||
his_addr.in4.sin_port = htons(123); /* Fixed for now */
|
||||
his_addr.in4.sin_family = AF_INET;
|
||||
sock_fd = sock_fd4;
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case IPADDR_INET6:
|
||||
memcpy(&his_addr.in6.sin6_addr.s6_addr, &src->ip_addr.addr.in6,
|
||||
sizeof (his_addr.in6.sin6_addr.s6_addr));
|
||||
his_addr.in6.sin6_port = htons(123); /* Fixed for now */
|
||||
his_addr.in6.sin6_family = AF_INET6;
|
||||
sock_fd = sock_fd6;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
LCL_ReadCookedTime(&cooked, &local_time_err);
|
||||
UTI_TimevalToInt64(&cooked, &pkt.transmit_ts);
|
||||
|
||||
if (sendto(sock_fd, (void *) &pkt, NTP_NORMAL_PACKET_SIZE,
|
||||
0,
|
||||
(struct sockaddr *) &his_addr, sizeof(his_addr)) < 0) {
|
||||
&his_addr.u, sizeof(his_addr)) < 0) {
|
||||
LOG(LOGS_WARN, LOGF_Acquire, "Could not send to %s : %s",
|
||||
UTI_IPToDottedQuad(src->ip_addr),
|
||||
UTI_IPToString(&src->ip_addr),
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
|
@ -253,7 +324,7 @@ transmit_timeout(void *x)
|
|||
src->timer_running = 0;
|
||||
|
||||
#if 0
|
||||
printf("Timeout expired for server %08lx\n", src->ip_addr);
|
||||
printf("Timeout expired for server %s\n", UTI_IPToString(&src->ip_addr));
|
||||
#endif
|
||||
|
||||
if (src->n_dead_probes < MAX_DEAD_PROBES) {
|
||||
|
@ -357,11 +428,12 @@ read_from_socket(void *anything)
|
|||
{
|
||||
int status;
|
||||
ReceiveBuffer msg;
|
||||
struct sockaddr_in his_addr;
|
||||
union sockaddr_in46 his_addr;
|
||||
int sock_fd;
|
||||
socklen_t his_addr_len;
|
||||
int flags;
|
||||
int message_length;
|
||||
unsigned long remote_ip;
|
||||
IPAddr remote_ip;
|
||||
int i, ok;
|
||||
struct timeval now;
|
||||
double local_time_err;
|
||||
|
@ -374,24 +446,39 @@ read_from_socket(void *anything)
|
|||
/* Get timestamp */
|
||||
LCL_ReadCookedTime(&now, &local_time_err);
|
||||
|
||||
sock_fd = (long)anything;
|
||||
status = recvfrom (sock_fd, (char *)&msg, message_length, flags,
|
||||
(struct sockaddr *) &his_addr, &his_addr_len);
|
||||
&his_addr.u, &his_addr_len);
|
||||
|
||||
if (status < 0) {
|
||||
LOG(LOGS_WARN, LOGF_Acquire, "Error reading from socket, %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
remote_ip = ntohl(his_addr.sin_addr.s_addr);
|
||||
switch (his_addr.u.sa_family) {
|
||||
case AF_INET:
|
||||
remote_ip.family = IPADDR_INET4;
|
||||
remote_ip.addr.in4 = ntohl(his_addr.in4.sin_addr.s_addr);
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
remote_ip.family = IPADDR_INET6;
|
||||
memcpy(&remote_ip.addr.in6, his_addr.in6.sin6_addr.s6_addr,
|
||||
sizeof (remote_ip.addr.in6));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("Got message from %08lx\n", remote_ip);
|
||||
printf("Got message from %s\n", UTI_IPToString(&remote_ip));
|
||||
#endif
|
||||
|
||||
/* Find matching host */
|
||||
ok = 0;
|
||||
for (i=0; i<n_sources; i++) {
|
||||
if (remote_ip == sources[i].ip_addr) {
|
||||
if (UTI_CompareIPs(&remote_ip, &sources[i].ip_addr, NULL) == 0) {
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -418,7 +505,7 @@ read_from_socket(void *anything)
|
|||
(src->n_total_samples >= MAX_SAMPLES)) {
|
||||
++n_completed_sources;
|
||||
#if 0
|
||||
printf("Source %08lx completed\n", src->ip_addr);
|
||||
printf("Source %s completed\n", UTI_IPToString(&src->ip_addr));
|
||||
#endif
|
||||
if (n_completed_sources == n_sources) {
|
||||
wind_up_acquisition();
|
||||
|
@ -440,7 +527,7 @@ start_next_source(void)
|
|||
{
|
||||
probe_source(sources + n_started_sources);
|
||||
#if 0
|
||||
printf("Trying to start source %08lx\n", sources[n_started_sources].ip_addr);
|
||||
printf("Trying to start source %s\n", UTI_IPToString(&sources[n_started_sources].ip_addr));
|
||||
#endif
|
||||
n_started_sources++;
|
||||
|
||||
|
@ -552,10 +639,10 @@ process_measurements(void)
|
|||
for (i=0; i<2*n_sane_sources; i++) {
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "Endpoint type %s source index %d [ip=%08lx] offset=%.6f\n",
|
||||
fprintf(stderr, "Endpoint type %s source index %d [ip=%s] offset=%.6f\n",
|
||||
(eps[i].type == LO) ? "LO" : "HIGH",
|
||||
eps[i].index,
|
||||
sources[eps[i].index].ip_addr,
|
||||
UTI_IPToString(&sources[eps[i].index].ip_addr),
|
||||
eps[i].offset);
|
||||
#endif
|
||||
|
||||
|
@ -655,10 +742,10 @@ start_source_timeout_handler(void *not_used)
|
|||
/* ================================================== */
|
||||
|
||||
void
|
||||
ACQ_StartAcquisition(int n, unsigned long *ip_addrs, int threshold, void (*after_hook)(void *), void *anything)
|
||||
ACQ_StartAcquisition(int n, IPAddr *ip_addrs, int threshold, void (*after_hook)(void *), void *anything)
|
||||
{
|
||||
|
||||
int i;
|
||||
int i, ip4, ip6;
|
||||
|
||||
saved_after_hook = after_hook;
|
||||
saved_after_hook_anything = anything;
|
||||
|
@ -670,14 +757,18 @@ ACQ_StartAcquisition(int n, unsigned long *ip_addrs, int threshold, void (*after
|
|||
n_sources = n;
|
||||
sources = MallocArray(SourceRecord, n);
|
||||
|
||||
for (i=0; i<n; i++) {
|
||||
for (i = ip4 = ip6 = 0; i < n; i++) {
|
||||
sources[i].ip_addr = ip_addrs[i];
|
||||
sources[i].n_samples = 0;
|
||||
sources[i].n_total_samples = 0;
|
||||
sources[i].n_dead_probes = 0;
|
||||
if (ip_addrs[i].family == IPADDR_INET4)
|
||||
ip4++;
|
||||
else if (ip_addrs[i].family == IPADDR_INET6)
|
||||
ip6++;
|
||||
}
|
||||
|
||||
initialise_io();
|
||||
initialise_io((ip4 && ip6) ? IPADDR_UNSPEC : (ip4 ? IPADDR_INET4 : IPADDR_INET6));
|
||||
|
||||
/* Start sampling first source */
|
||||
start_next_source();
|
||||
|
|
|
@ -31,13 +31,15 @@
|
|||
#ifndef GOT_ACQUIRE_H
|
||||
#define GOT_ACQUIRE_H
|
||||
|
||||
#include "addressing.h"
|
||||
|
||||
typedef struct ACQ_SourceRecord *ACQ_Source;
|
||||
|
||||
extern void ACQ_Initialise(void);
|
||||
|
||||
extern void ACQ_Finalise(void);
|
||||
|
||||
extern void ACQ_StartAcquisition(int n, unsigned long *ip_addrs, int init_slew_threshold,
|
||||
extern void ACQ_StartAcquisition(int n, IPAddr *ip_addrs, int init_slew_threshold,
|
||||
void (*after_hook)(void *), void *anything);
|
||||
|
||||
extern void ACQ_AccumulateSample(ACQ_Source acq_source, double offset, double root_distance);
|
||||
|
|
27
addressing.h
27
addressing.h
|
@ -31,17 +31,28 @@
|
|||
#ifndef GOT_ADDRESSING_H
|
||||
#define GOT_ADDRESSING_H
|
||||
|
||||
/* This type is used to represent an IPv4 address and port
|
||||
number. Both parts are in HOST order, NOT network order. */
|
||||
#include "sysincl.h"
|
||||
|
||||
/* This type is used to represent an IPv4 address or IPv6 address.
|
||||
All parts are in HOST order, NOT network order. */
|
||||
|
||||
#define IPADDR_UNSPEC 0
|
||||
#define IPADDR_INET4 1
|
||||
#define IPADDR_INET6 2
|
||||
|
||||
typedef struct {
|
||||
unsigned long ip_addr;
|
||||
unsigned long local_ip_addr;
|
||||
union {
|
||||
uint32_t in4;
|
||||
uint8_t in6[16];
|
||||
} addr;
|
||||
uint16_t family;
|
||||
} IPAddr;
|
||||
|
||||
typedef struct {
|
||||
IPAddr ip_addr;
|
||||
IPAddr local_ip_addr;
|
||||
unsigned short port;
|
||||
} NTP_Remote_Address;
|
||||
|
||||
#if 0
|
||||
unsigned long NTP_IP_Address;
|
||||
#endif
|
||||
|
||||
#endif /* GOT_ADDRESSING_H */
|
||||
|
||||
|
|
209
addrfilt.c
209
addrfilt.c
|
@ -51,23 +51,35 @@ typedef struct _TableNode {
|
|||
} TableNode;
|
||||
|
||||
struct ADF_AuthTableInst {
|
||||
TableNode base;
|
||||
TableNode base4; /* IPv4 node */
|
||||
TableNode base6; /* IPv6 node */
|
||||
};
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
inline static unsigned long
|
||||
get_subnet(unsigned long addr)
|
||||
static void
|
||||
split_ip6(IPAddr *ip, uint32_t *dst)
|
||||
{
|
||||
return (addr >> (32-NBITS)) & ((1UL<<NBITS) - 1);
|
||||
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 unsigned long
|
||||
get_residual(unsigned long addr)
|
||||
inline static uint32_t
|
||||
get_subnet(uint32_t *addr, unsigned int where)
|
||||
{
|
||||
return (addr << NBITS);
|
||||
int off;
|
||||
|
||||
off = where / 32;
|
||||
where %= 32;
|
||||
|
||||
return (addr[off] >> (32 - NBITS - where)) & ((1UL << NBITS) - 1);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -79,8 +91,10 @@ ADF_CreateTable(void)
|
|||
result = MallocNew(struct ADF_AuthTableInst);
|
||||
|
||||
/* Default is that nothing is allowed */
|
||||
result->base.state = DENY;
|
||||
result->base.extended = NULL;
|
||||
result->base4.state = DENY;
|
||||
result->base4.extended = NULL;
|
||||
result->base6.state = DENY;
|
||||
result->base6.extended = NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -135,22 +149,22 @@ open_node(TableNode *node)
|
|||
|
||||
static ADF_Status
|
||||
set_subnet(TableNode *start_node,
|
||||
unsigned long ip,
|
||||
uint32_t *ip,
|
||||
int ip_len,
|
||||
int subnet_bits,
|
||||
State new_state,
|
||||
int delete_children)
|
||||
{
|
||||
int bits_to_go;
|
||||
unsigned long residual;
|
||||
unsigned long subnet;
|
||||
int bits_to_go, bits_consumed;
|
||||
uint32_t subnet;
|
||||
TableNode *node;
|
||||
|
||||
bits_consumed = 0;
|
||||
bits_to_go = subnet_bits;
|
||||
residual = ip;
|
||||
node = start_node;
|
||||
|
||||
if ((subnet_bits < 0) ||
|
||||
(subnet_bits > 32)) {
|
||||
(subnet_bits > 32 * ip_len)) {
|
||||
|
||||
return ADF_BADSUBNET;
|
||||
|
||||
|
@ -159,13 +173,13 @@ set_subnet(TableNode *start_node,
|
|||
if ((bits_to_go & (NBITS-1)) == 0) {
|
||||
|
||||
while (bits_to_go > 0) {
|
||||
subnet = get_subnet(residual);
|
||||
residual = get_residual(residual);
|
||||
subnet = get_subnet(ip, bits_consumed);
|
||||
if (!(node->extended)) {
|
||||
open_node(node);
|
||||
}
|
||||
node = &(node->extended[subnet]);
|
||||
bits_to_go -= NBITS;
|
||||
bits_consumed += NBITS;
|
||||
}
|
||||
|
||||
if (delete_children) {
|
||||
|
@ -178,18 +192,18 @@ set_subnet(TableNode *start_node,
|
|||
TableNode *this_node;
|
||||
|
||||
while (bits_to_go >= NBITS) {
|
||||
subnet = get_subnet(residual);
|
||||
residual = get_residual(residual);
|
||||
subnet = get_subnet(ip, bits_consumed);
|
||||
if (!(node->extended)) {
|
||||
open_node(node);
|
||||
}
|
||||
node = &(node->extended[subnet]);
|
||||
bits_to_go -= NBITS;
|
||||
bits_consumed += NBITS;
|
||||
}
|
||||
|
||||
/* How many subnet entries to set : 1->8, 2->4, 3->2 */
|
||||
N = 1 << (NBITS-bits_to_go);
|
||||
subnet = get_subnet(residual);
|
||||
subnet = get_subnet(ip, bits_consumed);
|
||||
if (!(node->extended)) {
|
||||
open_node(node);
|
||||
}
|
||||
|
@ -210,12 +224,41 @@ set_subnet(TableNode *start_node,
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static ADF_Status
|
||||
set_subnet_(ADF_AuthTable table,
|
||||
IPAddr *ip_addr,
|
||||
int subnet_bits,
|
||||
State new_state,
|
||||
int delete_children)
|
||||
{
|
||||
uint32_t ip6[4];
|
||||
|
||||
switch (ip_addr->family) {
|
||||
case IPADDR_INET4:
|
||||
return set_subnet(&table->base4, &ip_addr->addr.in4, 1, subnet_bits, new_state, delete_children);
|
||||
case IPADDR_INET6:
|
||||
split_ip6(ip_addr, ip6);
|
||||
return set_subnet(&table->base6, ip6, 4, subnet_bits, new_state, delete_children);
|
||||
case IPADDR_UNSPEC:
|
||||
/* Apply to both, subnet_bits has to be 0 */
|
||||
if (subnet_bits != 0)
|
||||
return ADF_BADSUBNET;
|
||||
memset(ip6, 0, sizeof (ip6));
|
||||
if (set_subnet(&table->base4, ip6, 1, 0, new_state, delete_children) == ADF_SUCCESS &&
|
||||
set_subnet(&table->base6, ip6, 4, 0, new_state, delete_children) == ADF_SUCCESS)
|
||||
return ADF_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
return ADF_BADSUBNET;
|
||||
}
|
||||
|
||||
ADF_Status
|
||||
ADF_Allow(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits)
|
||||
{
|
||||
return set_subnet(&(table->base), ip, subnet_bits, ALLOW, 0);
|
||||
return set_subnet_(table, ip, subnet_bits, ALLOW, 0);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -223,30 +266,30 @@ ADF_Allow(ADF_AuthTable table,
|
|||
|
||||
ADF_Status
|
||||
ADF_AllowAll(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits)
|
||||
{
|
||||
return set_subnet(&(table->base), ip, subnet_bits, ALLOW, 1);
|
||||
return set_subnet_(table, ip, subnet_bits, ALLOW, 1);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
ADF_Status
|
||||
ADF_Deny(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits)
|
||||
{
|
||||
return set_subnet(&(table->base), ip, subnet_bits, DENY, 0);
|
||||
return set_subnet_(table, ip, subnet_bits, DENY, 0);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
ADF_Status
|
||||
ADF_DenyAll(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits)
|
||||
{
|
||||
return set_subnet(&(table->base), ip, subnet_bits, DENY, 1);
|
||||
return set_subnet_(table, ip, subnet_bits, DENY, 1);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -254,32 +297,33 @@ ADF_DenyAll(ADF_AuthTable table,
|
|||
void
|
||||
ADF_DestroyTable(ADF_AuthTable table)
|
||||
{
|
||||
close_node(&(table->base));
|
||||
close_node(&table->base4);
|
||||
close_node(&table->base6);
|
||||
Free(table);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
check_ip_in_node(TableNode *start_node, unsigned long ip)
|
||||
check_ip_in_node(TableNode *start_node, uint32_t *ip)
|
||||
{
|
||||
unsigned long residual, subnet;
|
||||
uint32_t subnet;
|
||||
int bits_consumed = 0;
|
||||
int result = 0;
|
||||
int finished = 0;
|
||||
TableNode *node;
|
||||
State state=DENY;
|
||||
|
||||
node = start_node;
|
||||
residual = ip;
|
||||
|
||||
do {
|
||||
if (node->state != AS_PARENT) {
|
||||
state = node->state;
|
||||
}
|
||||
if (node->extended) {
|
||||
subnet = get_subnet(residual);
|
||||
residual = get_residual(residual);
|
||||
subnet = get_subnet(ip, bits_consumed);
|
||||
node = &(node->extended[subnet]);
|
||||
bits_consumed += NBITS;
|
||||
} else {
|
||||
/* Make decision on this node */
|
||||
finished = 1;
|
||||
|
@ -306,38 +350,63 @@ check_ip_in_node(TableNode *start_node, unsigned long ip)
|
|||
|
||||
int
|
||||
ADF_IsAllowed(ADF_AuthTable table,
|
||||
unsigned long ip)
|
||||
IPAddr *ip_addr)
|
||||
{
|
||||
uint32_t ip6[4];
|
||||
|
||||
return check_ip_in_node(&(table->base), ip);
|
||||
switch (ip_addr->family) {
|
||||
case IPADDR_INET4:
|
||||
return check_ip_in_node(&table->base4, &ip_addr->addr.in4);
|
||||
case IPADDR_INET6:
|
||||
split_ip6(ip_addr, ip6);
|
||||
return check_ip_in_node(&table->base6, ip6);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#if defined TEST
|
||||
|
||||
static void print_node(TableNode *node, unsigned long addr, int shift, int subnet_bits)
|
||||
static void print_node(TableNode *node, uint32_t *addr, int ip_len, int shift, int subnet_bits)
|
||||
{
|
||||
unsigned long new_addr;
|
||||
uint32_t new_addr[4];
|
||||
int i;
|
||||
TableNode *sub_node;
|
||||
|
||||
for (i=0; i<subnet_bits; i++) putchar(' ');
|
||||
|
||||
printf("%d.%d.%d.%d/%d : %s\n",
|
||||
((addr >> 24) & 255),
|
||||
((addr >> 16) & 255),
|
||||
((addr >> 8) & 255),
|
||||
((addr ) & 255),
|
||||
if (ip_len == 1)
|
||||
printf("%d.%d.%d.%d",
|
||||
((addr[0] >> 24) & 255),
|
||||
((addr[0] >> 16) & 255),
|
||||
((addr[0] >> 8) & 255),
|
||||
((addr[0] ) & 255));
|
||||
else {
|
||||
for (i=0; i<4; i++) {
|
||||
if (addr[i])
|
||||
printf("%d.%d.%d.%d",
|
||||
((addr[i] >> 24) & 255),
|
||||
((addr[i] >> 16) & 255),
|
||||
((addr[i] >> 8) & 255),
|
||||
((addr[i] ) & 255));
|
||||
putchar(i < 3 ? ':' : '\0');
|
||||
}
|
||||
}
|
||||
printf("/%d : %s\n",
|
||||
subnet_bits,
|
||||
(node->state == ALLOW) ? "allow" :
|
||||
(node->state == DENY) ? "deny" : "as parent");
|
||||
if (node->extended) {
|
||||
for (i=0; i<16; i++) {
|
||||
sub_node = &((*(node->extended))[i]);
|
||||
new_addr = addr | ((unsigned long) i << shift);
|
||||
print_node(sub_node, new_addr, shift - 4, subnet_bits + 4);
|
||||
sub_node = &(node->extended[i]);
|
||||
new_addr[0] = addr[0];
|
||||
new_addr[1] = addr[1];
|
||||
new_addr[2] = addr[2];
|
||||
new_addr[3] = addr[3];
|
||||
new_addr[ip_len - 1 - shift / 32] |= ((uint32_t)i << (shift % 32));
|
||||
print_node(sub_node, new_addr, ip_len, shift - 4, subnet_bits + 4);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -346,11 +415,15 @@ static void print_node(TableNode *node, unsigned long addr, int shift, int subne
|
|||
|
||||
static void print_table(ADF_AuthTable table)
|
||||
{
|
||||
unsigned long addr = 0;
|
||||
int shift = 28;
|
||||
int subnet_bits = 0;
|
||||
uint32_t addr[4];
|
||||
|
||||
print_node(&table->base, addr, shift, subnet_bits);
|
||||
memset(addr, 0, sizeof (addr));
|
||||
printf("IPv4 table:\n");
|
||||
print_node(&table->base4, addr, 1, 28, 0);
|
||||
|
||||
memset(addr, 0, sizeof (addr));
|
||||
printf("IPv6 table:\n");
|
||||
print_node(&table->base6, addr, 4, 124, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -358,13 +431,41 @@ static void print_table(ADF_AuthTable table)
|
|||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
IPAddr ip;
|
||||
ADF_AuthTable table;
|
||||
table = ADF_CreateTable();
|
||||
|
||||
ADF_Allow(table, 0x7e800000, 9);
|
||||
ADF_Deny(table, 0x7ecc0000, 14);
|
||||
/* ADF_Deny(table, 0x7f000001, 32); */
|
||||
/* ADF_Allow(table, 0x7f000000, 8); */
|
||||
ip.family = IPADDR_INET4;
|
||||
|
||||
ip.addr.in4 = 0x7e800000;
|
||||
ADF_Allow(table, &ip, 9);
|
||||
ip.addr.in4 = 0x7ecc0000;
|
||||
ADF_Deny(table, &ip, 14);
|
||||
#if 0
|
||||
ip.addr.in4 = 0x7f000001;
|
||||
ADF_Deny(table, &ip, 32);
|
||||
ip.addr.in4 = 0x7f000000;
|
||||
ADF_Allow(table, &ip, 8);
|
||||
#endif
|
||||
|
||||
printf("allowed: %d\n", ADF_IsAllowed(table, &ip));
|
||||
ip.addr.in4 ^= 1;
|
||||
printf("allowed: %d\n", ADF_IsAllowed(table, &ip));
|
||||
|
||||
ip.family = IPADDR_INET6;
|
||||
|
||||
memcpy(ip.addr.in6, "abcdefghijklmnop", 16);
|
||||
ADF_Deny(table, &ip, 66);
|
||||
ADF_Allow(table, &ip, 59);
|
||||
|
||||
memcpy(ip.addr.in6, "xbcdefghijklmnop", 16);
|
||||
ADF_Deny(table, &ip, 128);
|
||||
ip.addr.in6[15] ^= 3;
|
||||
ADF_Allow(table, &ip, 127);
|
||||
|
||||
printf("allowed: %d\n", ADF_IsAllowed(table, &ip));
|
||||
ip.addr.in4 ^= 1;
|
||||
printf("allowed: %d\n", ADF_IsAllowed(table, &ip));
|
||||
|
||||
print_table(table);
|
||||
|
||||
|
|
12
addrfilt.h
12
addrfilt.h
|
@ -31,6 +31,8 @@
|
|||
#ifndef GOT_ADDRFILT_H
|
||||
#define GOT_ADDRFILT_H
|
||||
|
||||
#include "addressing.h"
|
||||
|
||||
typedef struct ADF_AuthTableInst *ADF_AuthTable;
|
||||
|
||||
typedef enum {
|
||||
|
@ -45,25 +47,25 @@ extern ADF_AuthTable ADF_CreateTable(void);
|
|||
/* Allow anything in the supplied subnet, EXCEPT for any more specific
|
||||
subnets that are already defined */
|
||||
extern ADF_Status ADF_Allow(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits);
|
||||
|
||||
/* Allow anything in the supplied subnet, overwriting existing
|
||||
definitions for any more specific subnets */
|
||||
extern ADF_Status ADF_AllowAll(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits);
|
||||
|
||||
/* Deny anything in the supplied subnet, EXCEPT for any more specific
|
||||
subnets that are already defined */
|
||||
extern ADF_Status ADF_Deny(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits);
|
||||
|
||||
/* Deny anything in the supplied subnet, overwriting existing
|
||||
definitions for any more specific subnets */
|
||||
extern ADF_Status ADF_DenyAll(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits);
|
||||
|
||||
/* Clear up the table */
|
||||
|
@ -72,6 +74,6 @@ extern void ADF_DestroyTable(ADF_AuthTable table);
|
|||
/* Check whether a given IP address is allowed by the rules in
|
||||
the table */
|
||||
extern int ADF_IsAllowed(ADF_AuthTable table,
|
||||
unsigned long ip);
|
||||
IPAddr *ip);
|
||||
|
||||
#endif /* GOT_ADDRFILT_H */
|
||||
|
|
|
@ -132,7 +132,7 @@ timeout_handler(void *arbitrary)
|
|||
/* ================================================== */
|
||||
|
||||
void
|
||||
BRD_AddDestination(unsigned long addr, unsigned short port, int interval)
|
||||
BRD_AddDestination(IPAddr *addr, unsigned short port, int interval)
|
||||
{
|
||||
if (max_destinations == n_destinations) {
|
||||
/* Expand array */
|
||||
|
@ -144,8 +144,8 @@ BRD_AddDestination(unsigned long addr, unsigned short port, int interval)
|
|||
}
|
||||
}
|
||||
|
||||
destinations[n_destinations].addr.ip_addr = addr;
|
||||
destinations[n_destinations].addr.local_ip_addr = 0;
|
||||
destinations[n_destinations].addr.ip_addr = *addr;
|
||||
destinations[n_destinations].addr.local_ip_addr.family = IPADDR_UNSPEC;
|
||||
destinations[n_destinations].addr.port = port;
|
||||
destinations[n_destinations].interval = interval;
|
||||
|
||||
|
|
|
@ -31,9 +31,11 @@
|
|||
#ifndef GOT_BROADCAST_H
|
||||
#define GOT_BROADCAST_H
|
||||
|
||||
#include "addressing.h"
|
||||
|
||||
extern void BRD_Initialise(void);
|
||||
extern void BRD_Finalise(void);
|
||||
extern void BRD_AddDestination(unsigned long addr, unsigned short port, int interval);
|
||||
extern void BRD_AddDestination(IPAddr *addr, unsigned short port, int interval);
|
||||
|
||||
#endif /* GOT_BROADCAST_H */
|
||||
|
||||
|
|
48
candm.h
48
candm.h
|
@ -34,6 +34,7 @@
|
|||
#define GOT_CANDM_H
|
||||
|
||||
#include "sysincl.h"
|
||||
#include "addressing.h"
|
||||
|
||||
/* This is the default port to use for CANDM, if no alternative is
|
||||
defined */
|
||||
|
@ -96,33 +97,33 @@
|
|||
transmitted for each packet type. */
|
||||
|
||||
typedef struct {
|
||||
uint32_t mask;
|
||||
uint32_t address;
|
||||
IPAddr mask;
|
||||
IPAddr address;
|
||||
int32_t EOR;
|
||||
} REQ_Online;
|
||||
|
||||
typedef struct {
|
||||
uint32_t mask;
|
||||
uint32_t address;
|
||||
IPAddr mask;
|
||||
IPAddr address;
|
||||
int32_t EOR;
|
||||
} REQ_Offline;
|
||||
|
||||
typedef struct {
|
||||
uint32_t mask;
|
||||
uint32_t address;
|
||||
IPAddr mask;
|
||||
IPAddr address;
|
||||
int32_t n_good_samples;
|
||||
int32_t n_total_samples;
|
||||
int32_t EOR;
|
||||
} REQ_Burst;
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
IPAddr address;
|
||||
int32_t new_minpoll;
|
||||
int32_t EOR;
|
||||
} REQ_Modify_Minpoll;
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
IPAddr address;
|
||||
int32_t new_maxpoll;
|
||||
int32_t EOR;
|
||||
} REQ_Modify_Maxpoll;
|
||||
|
@ -133,13 +134,13 @@ typedef struct {
|
|||
} REQ_Dump;
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
IPAddr address;
|
||||
int32_t new_max_delay;
|
||||
int32_t EOR;
|
||||
} REQ_Modify_Maxdelay;
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
IPAddr address;
|
||||
int32_t new_max_delay_ratio;
|
||||
int32_t EOR;
|
||||
} REQ_Modify_Maxdelayratio;
|
||||
|
@ -184,18 +185,18 @@ typedef struct {
|
|||
} REQ_Rekey;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip;
|
||||
IPAddr ip;
|
||||
int32_t subnet_bits;
|
||||
int32_t EOR;
|
||||
} REQ_Allow_Deny;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip;
|
||||
IPAddr ip;
|
||||
int32_t EOR;
|
||||
} REQ_Ac_Check;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip_addr;
|
||||
IPAddr ip_addr;
|
||||
uint32_t port;
|
||||
int32_t minpoll;
|
||||
int32_t maxpoll;
|
||||
|
@ -209,7 +210,7 @@ typedef struct {
|
|||
} REQ_NTP_Source;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip_addr;
|
||||
IPAddr ip_addr;
|
||||
int32_t EOR;
|
||||
} REQ_Del_Source;
|
||||
|
||||
|
@ -250,7 +251,7 @@ typedef struct {
|
|||
} REQ_CycleLogs;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip;
|
||||
IPAddr ip;
|
||||
uint32_t bits_specd;
|
||||
} REQ_SubnetsAccessed_Subnet;
|
||||
|
||||
|
@ -263,11 +264,11 @@ typedef struct {
|
|||
|
||||
/* This is based on the response size rather than the
|
||||
request size */
|
||||
#define MAX_CLIENT_ACCESSES 16
|
||||
#define MAX_CLIENT_ACCESSES 8
|
||||
|
||||
typedef struct {
|
||||
uint32_t n_clients;
|
||||
uint32_t client_ips[MAX_CLIENT_ACCESSES];
|
||||
IPAddr client_ips[MAX_CLIENT_ACCESSES];
|
||||
} REQ_ClientAccesses;
|
||||
|
||||
typedef struct {
|
||||
|
@ -310,9 +311,11 @@ typedef struct {
|
|||
|
||||
Version 3 : NTP_Source message lengthened (auto_offline)
|
||||
|
||||
Version 4 : IPv6 addressing added
|
||||
|
||||
*/
|
||||
|
||||
#define PROTO_VERSION_NUMBER 3
|
||||
#define PROTO_VERSION_NUMBER 4
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
|
@ -419,6 +422,7 @@ typedef struct {
|
|||
#define STT_BADRTCFILE 14
|
||||
#define STT_INACTIVE 15
|
||||
#define STT_BADSAMPLE 16
|
||||
#define STT_INVALIDAF 17
|
||||
|
||||
typedef struct {
|
||||
int32_t EOR;
|
||||
|
@ -440,7 +444,7 @@ typedef struct {
|
|||
#define RPY_SD_ST_OTHER 4
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip_addr;
|
||||
IPAddr ip_addr;
|
||||
uint16_t poll;
|
||||
uint16_t stratum;
|
||||
uint16_t state;
|
||||
|
@ -472,7 +476,7 @@ typedef struct {
|
|||
} RPY_Tracking;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip_addr;
|
||||
IPAddr ip_addr;
|
||||
uint32_t n_samples;
|
||||
uint32_t n_runs;
|
||||
uint32_t span_seconds;
|
||||
|
@ -500,7 +504,7 @@ typedef struct {
|
|||
} RPY_ManualTimestamp;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip;
|
||||
IPAddr ip;
|
||||
uint32_t bits_specd;
|
||||
uint32_t bitmap[8];
|
||||
} RPY_SubnetsAccessed_Subnet;
|
||||
|
@ -511,7 +515,7 @@ typedef struct {
|
|||
} RPY_SubnetsAccessed;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip;
|
||||
IPAddr ip;
|
||||
uint32_t client_hits;
|
||||
uint32_t peer_hits;
|
||||
uint32_t cmd_hits_auth;
|
||||
|
|
414
client.c
414
client.c
|
@ -58,8 +58,16 @@
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
union sockaddr_in46 {
|
||||
struct sockaddr_in in4;
|
||||
#ifdef HAVE_IPV6
|
||||
struct sockaddr_in6 in6;
|
||||
#endif
|
||||
struct sockaddr u;
|
||||
};
|
||||
|
||||
static int sock_fd;
|
||||
struct sockaddr_in his_addr;
|
||||
union sockaddr_in46 his_addr;
|
||||
|
||||
static int on_terminal = 0;
|
||||
|
||||
|
@ -137,62 +145,64 @@ read_line(void)
|
|||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static unsigned long
|
||||
get_address(const char *hostname)
|
||||
{
|
||||
char *address0;
|
||||
struct hostent *host;
|
||||
unsigned long result;
|
||||
|
||||
/* Note, this call could block for a while */
|
||||
host = gethostbyname(hostname);
|
||||
if (host == NULL) {
|
||||
fprintf(stderr, "Could not get IP address for %s\n", hostname);
|
||||
exit(1);
|
||||
} else {
|
||||
address0 = host->h_addr_list[0];
|
||||
result = ((((unsigned long) address0[0] & 0xff) << 24) |
|
||||
(((unsigned long) address0[1] & 0xff) << 16) |
|
||||
(((unsigned long) address0[2] & 0xff) << 8) |
|
||||
(((unsigned long) address0[3] & 0xff)));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* Initialise the socket used to talk to the daemon */
|
||||
|
||||
static void
|
||||
open_io(const char *hostname, int port)
|
||||
{
|
||||
struct sockaddr_in my_addr;
|
||||
union sockaddr_in46 my_addr;
|
||||
IPAddr ip;
|
||||
|
||||
/* Note, this call could block for a while */
|
||||
if (!DNS_Name2IPAddress(hostname, &ip, 0)) {
|
||||
fprintf(stderr, "Could not get IP address for %s\n", hostname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&my_addr, 0, sizeof (my_addr));
|
||||
memset(&his_addr, 0, sizeof (his_addr));
|
||||
|
||||
switch (ip.family) {
|
||||
case IPADDR_INET4:
|
||||
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
my_addr.in4.sin_family = AF_INET;
|
||||
my_addr.in4.sin_port = htons(INADDR_ANY);
|
||||
my_addr.in4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
his_addr.in4.sin_family = AF_INET;
|
||||
his_addr.in4.sin_addr.s_addr = htonl(ip.addr.in4);
|
||||
his_addr.in4.sin_port = htons(port);
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case IPADDR_INET6:
|
||||
sock_fd = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
|
||||
my_addr.in6.sin6_family = AF_INET6;
|
||||
my_addr.in6.sin6_port = htons(INADDR_ANY);
|
||||
my_addr.in6.sin6_addr = in6addr_any;
|
||||
|
||||
his_addr.in6.sin6_family = AF_INET6;
|
||||
memcpy(his_addr.in6.sin6_addr.s6_addr, ip.addr.in6,
|
||||
sizeof (his_addr.in6.sin6_addr.s6_addr));
|
||||
his_addr.in6.sin6_port = htons(port);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock_fd < 0) {
|
||||
perror("Can't create socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
my_addr.sin_family = AF_INET;
|
||||
my_addr.sin_port = htons(INADDR_ANY);
|
||||
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if(bind(sock_fd, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) {
|
||||
if(bind(sock_fd, &my_addr.u, sizeof(my_addr)) < 0) {
|
||||
perror("Can't bind socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Build the socket address structure for sending packets */
|
||||
his_addr.sin_family = AF_INET;
|
||||
his_addr.sin_addr.s_addr = htonl(get_address(hostname));
|
||||
|
||||
/* Eventually the port number needs to be a command line param */
|
||||
his_addr.sin_port = htons(port);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -208,34 +218,78 @@ close_io(void)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
read_mask_address(char *line, unsigned long *mask, unsigned long *address)
|
||||
static void
|
||||
bits_to_mask(int bits, int family, IPAddr *mask)
|
||||
{
|
||||
unsigned int ma, mb, mc, md, aa, ab, ac, ad;
|
||||
int ok = 0;
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
mask->family = family;
|
||||
switch (family) {
|
||||
case IPADDR_INET4:
|
||||
if (bits < 0)
|
||||
bits = 32;
|
||||
if (bits > 0) {
|
||||
mask->addr.in4 = -1;
|
||||
mask->addr.in4 <<= 32 - bits;
|
||||
} else {
|
||||
mask->addr.in4 = 0;
|
||||
}
|
||||
break;
|
||||
case IPADDR_INET6:
|
||||
if (bits > 128 || bits < 0)
|
||||
bits = 128;
|
||||
for (i = 0; i < bits / 8; i++)
|
||||
mask->addr.in6[i] = 0xff;
|
||||
if (i < 16)
|
||||
mask->addr.in6[i++] = (0xff << (8 - bits % 8)) & 0xff;
|
||||
for (; i < 16; i++)
|
||||
mask->addr.in6[i] = 0x0;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
read_mask_address(char *line, IPAddr *mask, IPAddr *address)
|
||||
{
|
||||
unsigned int bits;
|
||||
char *p, *q;
|
||||
|
||||
p = line;
|
||||
while (*p && isspace((unsigned char)*p)) p++;
|
||||
if (!*p) {
|
||||
*mask = *address = 0;
|
||||
ok = 1;
|
||||
mask->family = address->family = IPADDR_UNSPEC;
|
||||
return 1;
|
||||
} else {
|
||||
|
||||
if (sscanf(line, "%u.%u.%u.%u/%u.%u.%u.%u",
|
||||
&ma, &mb, &mc, &md,
|
||||
&aa, &ab, &ac, &ad) != 8) {
|
||||
fprintf(stderr, "Invalid syntax for mask/address\n");
|
||||
ok = 0;
|
||||
q = strchr(p, '/');
|
||||
if (q) {
|
||||
*q++ = 0;
|
||||
if (UTI_StringToIP(p, mask)) {
|
||||
p = q;
|
||||
while (*q && !isspace((unsigned char)*q)) q++;
|
||||
*q = 0;
|
||||
if (UTI_StringToIP(p, address)) {
|
||||
if (address->family == mask->family)
|
||||
return 1;
|
||||
} else if (sscanf(p, "%u", &bits) == 1) {
|
||||
*address = *mask;
|
||||
bits_to_mask(bits, address->family, mask);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*mask = (ma << 24) | (mb << 16) | (mc << 8) | md;
|
||||
*address = (aa << 24) | (ab << 16) | (ac << 8) | ad;
|
||||
ok = 1;
|
||||
if (UTI_StringToIP(p, address)) {
|
||||
bits_to_mask(-1, address->family, mask);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
||||
fprintf(stderr, "Invalid syntax for mask/address\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -243,12 +297,12 @@ read_mask_address(char *line, unsigned long *mask, unsigned long *address)
|
|||
static int
|
||||
process_cmd_offline(CMD_Request *msg, char *line)
|
||||
{
|
||||
unsigned long mask, address;
|
||||
IPAddr mask, address;
|
||||
int ok;
|
||||
|
||||
if (read_mask_address(line, &mask, &address)) {
|
||||
msg->data.offline.mask = htonl(mask);
|
||||
msg->data.offline.address = htonl(address);
|
||||
UTI_IPHostToNetwork(&mask, &msg->data.offline.mask);
|
||||
UTI_IPHostToNetwork(&address, &msg->data.offline.address);
|
||||
msg->command = htons(REQ_OFFLINE);
|
||||
ok = 1;
|
||||
} else {
|
||||
|
@ -265,12 +319,12 @@ process_cmd_offline(CMD_Request *msg, char *line)
|
|||
static int
|
||||
process_cmd_online(CMD_Request *msg, char *line)
|
||||
{
|
||||
unsigned long mask, address;
|
||||
IPAddr mask, address;
|
||||
int ok;
|
||||
|
||||
if (read_mask_address(line, &mask, &address)) {
|
||||
msg->data.online.mask = htonl(mask);
|
||||
msg->data.online.address = htonl(address);
|
||||
UTI_IPHostToNetwork(&mask, &msg->data.online.mask);
|
||||
UTI_IPHostToNetwork(&address, &msg->data.online.address);
|
||||
msg->command = htons(REQ_ONLINE);
|
||||
ok = 1;
|
||||
} else {
|
||||
|
@ -284,7 +338,7 @@ process_cmd_online(CMD_Request *msg, char *line)
|
|||
/* ================================================== */
|
||||
|
||||
static int
|
||||
read_address_integer(char *line, unsigned long *address, int *value)
|
||||
read_address_integer(char *line, IPAddr *address, int *value)
|
||||
{
|
||||
char hostname[2048];
|
||||
int ok = 0;
|
||||
|
@ -293,8 +347,7 @@ read_address_integer(char *line, unsigned long *address, int *value)
|
|||
fprintf(stderr, "Invalid syntax for address value\n");
|
||||
ok = 0;
|
||||
} else {
|
||||
*address = DNS_Name2IPAddress(hostname);
|
||||
if (*address == DNS_Failed_Address) {
|
||||
if (!DNS_Name2IPAddress(hostname, address, 0)) {
|
||||
fprintf(stderr, "Could not get address for hostname\n");
|
||||
ok = 0;
|
||||
} else {
|
||||
|
@ -310,7 +363,7 @@ read_address_integer(char *line, unsigned long *address, int *value)
|
|||
/* ================================================== */
|
||||
|
||||
static int
|
||||
read_address_double(char *line, unsigned long *address, double *value)
|
||||
read_address_double(char *line, IPAddr *address, double *value)
|
||||
{
|
||||
char hostname[2048];
|
||||
int ok = 0;
|
||||
|
@ -319,8 +372,7 @@ read_address_double(char *line, unsigned long *address, double *value)
|
|||
fprintf(stderr, "Invalid syntax for address value\n");
|
||||
ok = 0;
|
||||
} else {
|
||||
*address = DNS_Name2IPAddress(hostname);
|
||||
if (*address == DNS_Failed_Address) {
|
||||
if (!DNS_Name2IPAddress(hostname, address, 0)) {
|
||||
fprintf(stderr, "Could not get address for hostname\n");
|
||||
ok = 0;
|
||||
} else {
|
||||
|
@ -338,12 +390,12 @@ read_address_double(char *line, unsigned long *address, double *value)
|
|||
static int
|
||||
process_cmd_minpoll(CMD_Request *msg, char *line)
|
||||
{
|
||||
unsigned long address;
|
||||
IPAddr address;
|
||||
int minpoll;
|
||||
int ok;
|
||||
|
||||
if (read_address_integer(line, &address, &minpoll)) {
|
||||
msg->data.modify_minpoll.address = htonl(address);
|
||||
UTI_IPHostToNetwork(&address, &msg->data.modify_minpoll.address);
|
||||
msg->data.modify_minpoll.new_minpoll = htonl(minpoll);
|
||||
msg->command = htons(REQ_MODIFY_MINPOLL);
|
||||
ok = 1;
|
||||
|
@ -360,12 +412,12 @@ process_cmd_minpoll(CMD_Request *msg, char *line)
|
|||
static int
|
||||
process_cmd_maxpoll(CMD_Request *msg, char *line)
|
||||
{
|
||||
unsigned long address;
|
||||
IPAddr address;
|
||||
int maxpoll;
|
||||
int ok;
|
||||
|
||||
if (read_address_integer(line, &address, &maxpoll)) {
|
||||
msg->data.modify_maxpoll.address = htonl(address);
|
||||
UTI_IPHostToNetwork(&address, &msg->data.modify_maxpoll.address);
|
||||
msg->data.modify_maxpoll.new_maxpoll = htonl(maxpoll);
|
||||
msg->command = htons(REQ_MODIFY_MAXPOLL);
|
||||
ok = 1;
|
||||
|
@ -382,12 +434,12 @@ process_cmd_maxpoll(CMD_Request *msg, char *line)
|
|||
static int
|
||||
process_cmd_maxdelay(CMD_Request *msg, char *line)
|
||||
{
|
||||
unsigned long address;
|
||||
IPAddr address;
|
||||
double max_delay;
|
||||
int ok;
|
||||
|
||||
if (read_address_double(line, &address, &max_delay)) {
|
||||
msg->data.modify_maxdelay.address = htonl(address);
|
||||
UTI_IPHostToNetwork(&address, &msg->data.modify_maxdelay.address);
|
||||
msg->data.modify_maxdelay.new_max_delay = REAL2WIRE(max_delay);
|
||||
msg->command = htons(REQ_MODIFY_MAXDELAY);
|
||||
ok = 1;
|
||||
|
@ -404,12 +456,12 @@ process_cmd_maxdelay(CMD_Request *msg, char *line)
|
|||
static int
|
||||
process_cmd_maxdelayratio(CMD_Request *msg, char *line)
|
||||
{
|
||||
unsigned long address;
|
||||
IPAddr address;
|
||||
double max_delay_ratio;
|
||||
int ok;
|
||||
|
||||
if (read_address_double(line, &address, &max_delay_ratio)) {
|
||||
msg->data.modify_maxdelayratio.address = htonl(address);
|
||||
UTI_IPHostToNetwork(&address, &msg->data.modify_maxdelayratio.address);
|
||||
msg->data.modify_maxdelayratio.new_max_delay_ratio = REAL2WIRE(max_delay_ratio);
|
||||
msg->command = htons(REQ_MODIFY_MAXDELAYRATIO);
|
||||
ok = 1;
|
||||
|
@ -478,36 +530,28 @@ process_cmd_cyclelogs(CMD_Request *msg, char *line)
|
|||
static int
|
||||
process_cmd_burst(CMD_Request *msg, char *line)
|
||||
{
|
||||
int ok;
|
||||
int n_good_samples, n_total_samples;
|
||||
unsigned int ma, mb, mc, md, aa, ab, ac, ad;
|
||||
int n_parsed;
|
||||
char s[101];
|
||||
IPAddr address, mask;
|
||||
|
||||
n_parsed = sscanf(line, "%d/%d %u.%u.%u.%u/%u.%u.%u.%u",
|
||||
&n_good_samples,
|
||||
&n_total_samples,
|
||||
&ma, &mb, &mc, &md,
|
||||
&aa, &ab, &ac, &ad);
|
||||
n_parsed = sscanf(line, "%d/%d %100s", &n_good_samples, &n_total_samples, s);
|
||||
|
||||
msg->command = htons(REQ_BURST);
|
||||
msg->data.burst.n_good_samples = ntohl(n_good_samples);
|
||||
msg->data.burst.n_total_samples = ntohl(n_total_samples);
|
||||
|
||||
if (n_parsed == 10) {
|
||||
msg->data.burst.mask = htonl((ma << 24) | (mb << 16) | (mc << 8) | md);
|
||||
msg->data.burst.address = htonl((aa << 24) | (ab << 16) | (ac << 8) | ad);
|
||||
ok = 1;
|
||||
} else if (n_parsed == 2) {
|
||||
msg->data.burst.mask = 0;
|
||||
msg->data.burst.address = 0;
|
||||
ok = 1;
|
||||
} else {
|
||||
ok = 0;
|
||||
mask.family = address.family = IPADDR_UNSPEC;
|
||||
|
||||
if (n_parsed < 2 || (n_parsed == 3 && !read_mask_address(s, &mask, &address))) {
|
||||
fprintf(stderr, "Invalid syntax for burst command\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ok;
|
||||
UTI_IPHostToNetwork(&mask, &msg->data.burst.mask);
|
||||
UTI_IPHostToNetwork(&address, &msg->data.burst.address);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -574,66 +618,81 @@ process_cmd_manual(CMD_Request *msg, const char *line)
|
|||
static int
|
||||
parse_allow_deny(CMD_Request *msg, char *line)
|
||||
{
|
||||
unsigned long a, b, c, d, n, ip;
|
||||
unsigned long a, b, c, d, n;
|
||||
IPAddr ip;
|
||||
char *p, *q;
|
||||
|
||||
p = line;
|
||||
while (*p && isspace((unsigned char)*p)) p++;
|
||||
if (!*p) {
|
||||
/* blank line - applies to all addresses */
|
||||
msg->data.allow_deny.ip = htonl(0);
|
||||
ip.family = IPADDR_UNSPEC;
|
||||
UTI_IPHostToNetwork(&ip, &msg->data.allow_deny.ip);
|
||||
msg->data.allow_deny.subnet_bits = htonl(0);
|
||||
} else {
|
||||
char *slashpos;
|
||||
slashpos = strchr(p, '/');
|
||||
if (slashpos) *slashpos = 0;
|
||||
|
||||
n = sscanf(p, "%lu.%lu.%lu.%lu", &a, &b, &c, &d);
|
||||
n = 0;
|
||||
if (!UTI_StringToIP(p, &ip) &&
|
||||
(n = sscanf(p, "%lu.%lu.%lu.%lu", &a, &b, &c, &d)) == 0) {
|
||||
|
||||
if (n == 0) {
|
||||
/* Try to parse as the name of a machine */
|
||||
q = p;
|
||||
while (*q) {
|
||||
if (*q == '\n') *q = 0;
|
||||
q++;
|
||||
}
|
||||
ip = DNS_Name2IPAddress(p);
|
||||
if (ip == DNS_Failed_Address) {
|
||||
if (!DNS_Name2IPAddress(p, &ip, 0)) {
|
||||
fprintf(stderr, "Could not read address\n");
|
||||
return 0;
|
||||
} else {
|
||||
msg->data.allow_deny.ip = htonl(ip);
|
||||
msg->data.allow_deny.subnet_bits = htonl(32);
|
||||
UTI_IPHostToNetwork(&ip, &msg->data.allow_deny.ip);
|
||||
if (ip.family == IPADDR_INET6)
|
||||
msg->data.allow_deny.subnet_bits = htonl(128);
|
||||
else
|
||||
msg->data.allow_deny.subnet_bits = htonl(32);
|
||||
}
|
||||
} else {
|
||||
|
||||
a &= 0xff;
|
||||
b &= 0xff;
|
||||
c &= 0xff;
|
||||
d &= 0xff;
|
||||
|
||||
switch (n) {
|
||||
case 1:
|
||||
msg->data.allow_deny.ip = htonl((a<<24));
|
||||
msg->data.allow_deny.subnet_bits = htonl(8);
|
||||
break;
|
||||
case 2:
|
||||
msg->data.allow_deny.ip = htonl((a<<24) | (b<<16));
|
||||
msg->data.allow_deny.subnet_bits = htonl(16);
|
||||
break;
|
||||
case 3:
|
||||
msg->data.allow_deny.ip = htonl((a<<24) | (b<<16) | (c<<8));
|
||||
msg->data.allow_deny.subnet_bits = htonl(24);
|
||||
break;
|
||||
case 4:
|
||||
msg->data.allow_deny.ip = htonl((a<<24) | (b<<16) | (c<<8) | d);
|
||||
if (n == 0) {
|
||||
if (ip.family == IPADDR_INET6)
|
||||
msg->data.allow_deny.subnet_bits = htonl(128);
|
||||
else
|
||||
msg->data.allow_deny.subnet_bits = htonl(32);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
} else {
|
||||
ip.family = IPADDR_INET4;
|
||||
|
||||
a &= 0xff;
|
||||
b &= 0xff;
|
||||
c &= 0xff;
|
||||
d &= 0xff;
|
||||
|
||||
switch (n) {
|
||||
case 1:
|
||||
ip.addr.in4 = htonl((a<<24));
|
||||
msg->data.allow_deny.subnet_bits = htonl(8);
|
||||
break;
|
||||
case 2:
|
||||
ip.addr.in4 = htonl((a<<24) | (b<<16));
|
||||
msg->data.allow_deny.subnet_bits = htonl(16);
|
||||
break;
|
||||
case 3:
|
||||
ip.addr.in4 = htonl((a<<24) | (b<<16) | (c<<8));
|
||||
msg->data.allow_deny.subnet_bits = htonl(24);
|
||||
break;
|
||||
case 4:
|
||||
ip.addr.in4 = htonl((a<<24) | (b<<16) | (c<<8) | d);
|
||||
msg->data.allow_deny.subnet_bits = htonl(32);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
UTI_IPHostToNetwork(&ip, &msg->data.allow_deny.ip);
|
||||
|
||||
if (slashpos) {
|
||||
int specified_subnet_bits, n;
|
||||
n = sscanf(slashpos+1, "%d", &specified_subnet_bits);
|
||||
|
@ -739,9 +798,10 @@ process_cmd_cmddenyall(CMD_Request *msg, char *line)
|
|||
/* ================================================== */
|
||||
|
||||
static int
|
||||
accheck_getaddr(char *line, unsigned long *addr)
|
||||
accheck_getaddr(char *line, IPAddr *addr)
|
||||
{
|
||||
unsigned long a, b, c, d, ip;
|
||||
unsigned long a, b, c, d;
|
||||
IPAddr ip;
|
||||
char *p, *q;
|
||||
p = line;
|
||||
while (*p && isspace(*p)) p++;
|
||||
|
@ -749,7 +809,8 @@ accheck_getaddr(char *line, unsigned long *addr)
|
|||
return 0;
|
||||
} else {
|
||||
if (sscanf(p, "%lu.%lu.%lu.%lu", &a, &b, &c, &d) == 4) {
|
||||
*addr = (a<<24) | (b<<16) | (c<<8) | d;
|
||||
addr->family = IPADDR_INET4;
|
||||
addr->addr.in4 = (a<<24) | (b<<16) | (c<<8) | d;
|
||||
return 1;
|
||||
} else {
|
||||
q = p;
|
||||
|
@ -757,8 +818,7 @@ accheck_getaddr(char *line, unsigned long *addr)
|
|||
if (*q == '\n') *q = 0;
|
||||
q++;
|
||||
}
|
||||
ip = DNS_Name2IPAddress(p);
|
||||
if (ip == DNS_Failed_Address) {
|
||||
if (!DNS_Name2IPAddress(p, &ip, 0)) {
|
||||
return 0;
|
||||
} else {
|
||||
*addr = ip;
|
||||
|
@ -773,10 +833,10 @@ accheck_getaddr(char *line, unsigned long *addr)
|
|||
static int
|
||||
process_cmd_accheck(CMD_Request *msg, char *line)
|
||||
{
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
msg->command = htons(REQ_ACCHECK);
|
||||
if (accheck_getaddr(line, &ip)) {
|
||||
msg->data.ac_check.ip = htonl(ip);
|
||||
UTI_IPHostToNetwork(&ip, &msg->data.ac_check.ip);
|
||||
return 1;
|
||||
} else {
|
||||
fprintf(stderr, "Could not read address\n");
|
||||
|
@ -789,10 +849,10 @@ process_cmd_accheck(CMD_Request *msg, char *line)
|
|||
static int
|
||||
process_cmd_cmdaccheck(CMD_Request *msg, char *line)
|
||||
{
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
msg->command = htons(REQ_CMDACCHECK);
|
||||
if (accheck_getaddr(line, &ip)) {
|
||||
msg->data.ac_check.ip = htonl(ip);
|
||||
UTI_IPHostToNetwork(&ip, &msg->data.ac_check.ip);
|
||||
return 1;
|
||||
} else {
|
||||
fprintf(stderr, "Could not read address\n");
|
||||
|
@ -866,7 +926,7 @@ process_cmd_add_server_or_peer(CMD_Request *msg, char *line)
|
|||
switch (status) {
|
||||
case CPS_Success:
|
||||
msg->data.ntp_source.port = htonl((unsigned long) data.port);
|
||||
msg->data.ntp_source.ip_addr = htonl(data.ip_addr);
|
||||
UTI_IPHostToNetwork(&data.ip_addr, &msg->data.ntp_source.ip_addr);
|
||||
msg->data.ntp_source.minpoll = htonl(data.params.minpoll);
|
||||
msg->data.ntp_source.maxpoll = htonl(data.params.maxpoll);
|
||||
msg->data.ntp_source.presend_minpoll = htonl(data.params.presend_minpoll);
|
||||
|
@ -935,7 +995,7 @@ process_cmd_delete(CMD_Request *msg, char *line)
|
|||
{
|
||||
char hostname[2048];
|
||||
int ok = 0;
|
||||
unsigned long address = 0UL;
|
||||
IPAddr address;
|
||||
|
||||
msg->command = htons(REQ_DEL_SOURCE);
|
||||
|
||||
|
@ -943,8 +1003,7 @@ process_cmd_delete(CMD_Request *msg, char *line)
|
|||
fprintf(stderr, "Invalid syntax for address\n");
|
||||
ok = 0;
|
||||
} else {
|
||||
address = DNS_Name2IPAddress(hostname);
|
||||
if (address == DNS_Failed_Address) {
|
||||
if (!DNS_Name2IPAddress(hostname, &address, 0)) {
|
||||
fprintf(stderr, "Could not get address for hostname\n");
|
||||
ok = 0;
|
||||
} else {
|
||||
|
@ -952,7 +1011,7 @@ process_cmd_delete(CMD_Request *msg, char *line)
|
|||
}
|
||||
}
|
||||
|
||||
msg->data.del_source.ip_addr = htonl(address);
|
||||
UTI_IPHostToNetwork(&address, &msg->data.del_source.ip_addr);
|
||||
|
||||
return ok;
|
||||
|
||||
|
@ -1121,7 +1180,7 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
|
|||
{
|
||||
unsigned long tx_sequence;
|
||||
socklen_t where_from_len;
|
||||
struct sockaddr_in where_from;
|
||||
union sockaddr_in46 where_from;
|
||||
int bad_length, bad_sender, bad_sequence, bad_header;
|
||||
int select_status;
|
||||
int recvfrom_status;
|
||||
|
@ -1168,7 +1227,7 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
|
|||
#endif
|
||||
|
||||
if (sendto(sock_fd, (void *) request, command_length, 0,
|
||||
(struct sockaddr *) &his_addr, sizeof(his_addr)) < 0) {
|
||||
&his_addr.u, sizeof(his_addr)) < 0) {
|
||||
|
||||
|
||||
#if 0
|
||||
|
@ -1210,7 +1269,7 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
|
|||
|
||||
where_from_len = sizeof(where_from);
|
||||
recvfrom_status = recvfrom(sock_fd, (void *) reply, sizeof(CMD_Reply), 0,
|
||||
(struct sockaddr *) &where_from, &where_from_len);
|
||||
&where_from.u, &where_from_len);
|
||||
|
||||
|
||||
#if 0
|
||||
|
@ -1231,8 +1290,17 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
|
|||
expected_length = PKL_ReplyLength(reply);
|
||||
|
||||
bad_length = (read_length != expected_length);
|
||||
bad_sender = ((where_from.sin_addr.s_addr != his_addr.sin_addr.s_addr) ||
|
||||
(where_from.sin_port != his_addr.sin_port));
|
||||
bad_sender = (where_from.u.sa_family != his_addr.u.sa_family ||
|
||||
(where_from.u.sa_family == AF_INET &&
|
||||
(where_from.in4.sin_addr.s_addr != his_addr.in4.sin_addr.s_addr ||
|
||||
where_from.in4.sin_port != his_addr.in4.sin_port)) ||
|
||||
#ifdef HAVE_IPV6
|
||||
(where_from.u.sa_family == AF_INET6 &&
|
||||
(memcmp(where_from.in6.sin6_addr.s6_addr, his_addr.in6.sin6_addr.s6_addr,
|
||||
sizeof (where_from.in6.sin6_addr.s6_addr)) != 0 ||
|
||||
where_from.in6.sin6_port != his_addr.in6.sin6_port)) ||
|
||||
#endif
|
||||
0);
|
||||
|
||||
if (!bad_length) {
|
||||
bad_sequence = (ntohl(reply->sequence) != tx_sequence);
|
||||
|
@ -1382,13 +1450,12 @@ process_cmd_sources(char *line)
|
|||
int verbose = 0;
|
||||
|
||||
int32_t orig_latest_meas, latest_meas, est_offset;
|
||||
uint32_t ip_addr;
|
||||
IPAddr ip_addr;
|
||||
uint32_t latest_meas_err, est_offset_err;
|
||||
uint32_t latest_meas_ago;
|
||||
uint16_t poll, stratum;
|
||||
uint16_t state, mode;
|
||||
double resid_freq, resid_skew;
|
||||
const char *dns_lookup;
|
||||
char hostname_buf[32];
|
||||
uint16_t status;
|
||||
|
||||
|
@ -1439,7 +1506,7 @@ process_cmd_sources(char *line)
|
|||
|
||||
if (submit_ok) {
|
||||
if (ntohs(reply.status) == STT_SUCCESS) {
|
||||
ip_addr = ntohl(reply.data.source_data.ip_addr);
|
||||
UTI_IPNetworkToHost(&reply.data.source_data.ip_addr, &ip_addr);
|
||||
poll = ntohs(reply.data.source_data.poll);
|
||||
stratum = ntohs(reply.data.source_data.stratum);
|
||||
state = ntohs(reply.data.source_data.state);
|
||||
|
@ -1453,14 +1520,13 @@ process_cmd_sources(char *line)
|
|||
resid_freq = (double) ((long) ntohl(reply.data.source_data.resid_freq)) * 1.0e-3;
|
||||
resid_skew = (double) (ntohl(reply.data.source_data.resid_skew)) * 1.0e-3;
|
||||
|
||||
hostname_buf[25] = 0;
|
||||
if (mode == RPY_SD_MD_REF) {
|
||||
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_RefidToString(ip_addr));
|
||||
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_RefidToString(ip_addr.addr.in4));
|
||||
} else if (no_dns) {
|
||||
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_IPToDottedQuad(ip_addr));
|
||||
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_IPToString(&ip_addr));
|
||||
} else {
|
||||
dns_lookup = DNS_IPAddress2Name(ip_addr);
|
||||
strncpy(hostname_buf, dns_lookup, 25);
|
||||
DNS_IPAddress2Name(&ip_addr, hostname_buf, sizeof(hostname_buf));
|
||||
hostname_buf[25] = 0;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
|
@ -1515,12 +1581,11 @@ process_cmd_sourcestats(char *line)
|
|||
int n_sources, i;
|
||||
int verbose = 0;
|
||||
|
||||
const char *dns_lookup;
|
||||
char hostname_buf[32];
|
||||
unsigned long n_samples, n_runs, span_seconds;
|
||||
double resid_freq_ppm, skew_ppm;
|
||||
unsigned long sd_us;
|
||||
unsigned long ip_addr;
|
||||
IPAddr ip_addr;
|
||||
unsigned short status;
|
||||
|
||||
verbose = check_for_verbose_flag(line);
|
||||
|
@ -1569,7 +1634,7 @@ process_cmd_sourcestats(char *line)
|
|||
if (submit_ok) {
|
||||
if (ntohs(reply.status) == STT_SUCCESS) {
|
||||
|
||||
ip_addr = ntohl(reply.data.sourcestats.ip_addr);
|
||||
UTI_IPNetworkToHost(&reply.data.sourcestats.ip_addr, &ip_addr);
|
||||
n_samples = ntohl(reply.data.sourcestats.n_samples);
|
||||
n_runs = ntohl(reply.data.sourcestats.n_runs);
|
||||
span_seconds = ntohl(reply.data.sourcestats.span_seconds);
|
||||
|
@ -1577,12 +1642,11 @@ process_cmd_sourcestats(char *line)
|
|||
skew_ppm = WIRE2REAL(reply.data.sourcestats.skew_ppm);
|
||||
sd_us = ntohl(reply.data.sourcestats.sd_us);
|
||||
|
||||
hostname_buf[25] = 0;
|
||||
if (no_dns) {
|
||||
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_IPToDottedQuad(ip_addr));
|
||||
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_IPToString(&ip_addr));
|
||||
} else {
|
||||
dns_lookup = DNS_IPAddress2Name(ip_addr);
|
||||
strncpy(hostname_buf, dns_lookup, 25);
|
||||
DNS_IPAddress2Name(&ip_addr, hostname_buf, sizeof(hostname_buf));
|
||||
hostname_buf[25] = 0;
|
||||
}
|
||||
|
||||
printf("%-25s %2lu %2lu ", hostname_buf, n_samples, n_runs);
|
||||
|
@ -1644,9 +1708,10 @@ process_cmd_tracking(char *line)
|
|||
b = (ref_id >> 16) & 0xff;
|
||||
c = (ref_id >> 8) & 0xff;
|
||||
d = (ref_id) & 0xff;
|
||||
|
||||
printf("Reference ID : %lu.%lu.%lu.%lu (%s)\n",
|
||||
a, b, c, d,
|
||||
(no_dns) ? UTI_IPToDottedQuad(ref_id) : DNS_IPAddress2Name(ref_id));
|
||||
a, b, c, d, "");
|
||||
//* TODO (no_dns) ? UTI_IPToDottedQuad(ref_id) : DNS_IPAddress2Name(ref_id)); */
|
||||
printf("Stratum : %lu\n", (unsigned long) ntohl(reply.data.tracking.stratum));
|
||||
ref_time.tv_sec = ntohl(reply.data.tracking.ref_time_s);
|
||||
ref_time.tv_usec = ntohl(reply.data.tracking.ref_time_us);
|
||||
|
@ -1766,7 +1831,6 @@ process_cmd_clients(char *line)
|
|||
unsigned long last_ntp_hit_ago;
|
||||
unsigned long last_cmd_hit_ago;
|
||||
char hostname_buf[32];
|
||||
const char *dns_lookup;
|
||||
|
||||
int n_replies;
|
||||
|
||||
|
@ -1922,9 +1986,8 @@ process_cmd_clients(char *line)
|
|||
snprintf(hostname_buf, sizeof(hostname_buf),
|
||||
"%s", UTI_IPToDottedQuad(ip));
|
||||
} else {
|
||||
dns_lookup = DNS_IPAddress2Name(ip);
|
||||
DNS_IPAddress2Name(ip, hostname_buf, sizeof(hostname_buf));
|
||||
hostname_buf[25] = 0;
|
||||
strncpy(hostname_buf, dns_lookup, 25);
|
||||
}
|
||||
printf("%-25s %6d %6d %6d %6d %6d ",
|
||||
hostname_buf,
|
||||
|
@ -1988,7 +2051,7 @@ process_cmd_clients(char *line)
|
|||
int status;
|
||||
unsigned long next_index;
|
||||
int j;
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
unsigned long client_hits;
|
||||
unsigned long peer_hits;
|
||||
unsigned long cmd_hits_auth;
|
||||
|
@ -1997,7 +2060,6 @@ process_cmd_clients(char *line)
|
|||
unsigned long last_ntp_hit_ago;
|
||||
unsigned long last_cmd_hit_ago;
|
||||
char hostname_buf[32];
|
||||
const char *dns_lookup;
|
||||
|
||||
int n_replies;
|
||||
int n_indices_in_table;
|
||||
|
@ -2025,9 +2087,9 @@ process_cmd_clients(char *line)
|
|||
goto finished;
|
||||
}
|
||||
for (j=0; j<n_replies; j++) {
|
||||
ip = ntohl(reply.data.client_accesses_by_index.clients[j].ip);
|
||||
if (ip != 0UL) {
|
||||
/* ip == 0 implies that the node could not be found in
|
||||
UTI_IPNetworkToHost(&reply.data.client_accesses_by_index.clients[j].ip, &ip);
|
||||
if (ip.family != IPADDR_UNSPEC) {
|
||||
/* UNSPEC implies that the node could not be found in
|
||||
the daemon's tables; we shouldn't ever generate this
|
||||
case, but ignore it if we do. (In future there might
|
||||
be a protocol to reset the client logging; if another
|
||||
|
@ -2045,11 +2107,10 @@ process_cmd_clients(char *line)
|
|||
|
||||
if (no_dns) {
|
||||
snprintf(hostname_buf, sizeof(hostname_buf),
|
||||
"%s", UTI_IPToDottedQuad(ip));
|
||||
"%s", UTI_IPToString(&ip));
|
||||
} else {
|
||||
dns_lookup = DNS_IPAddress2Name(ip);
|
||||
DNS_IPAddress2Name(&ip, hostname_buf, sizeof(hostname_buf));
|
||||
hostname_buf[25] = 0;
|
||||
strncpy(hostname_buf, dns_lookup, 25);
|
||||
}
|
||||
printf("%-25s %6ld %6ld %6ld %6ld %6ld ",
|
||||
hostname_buf,
|
||||
|
@ -2475,6 +2536,9 @@ process_line(char *line)
|
|||
case STT_BADRTCFILE:
|
||||
printf("514 Can't write RTC parameters");
|
||||
break;
|
||||
case STT_INVALIDAF:
|
||||
printf("515 Invalid address family");
|
||||
break;
|
||||
}
|
||||
|
||||
if (reply_auth_ok) {
|
||||
|
|
175
clientlog.c
175
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;
|
||||
uint32_t this_subnet;
|
||||
|
||||
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, "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
|
||||
|
||||
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;
|
||||
|
||||
#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
|
||||
this_subnet = get_subnet(addr, bits_consumed);
|
||||
bits_consumed += NBITS;
|
||||
|
||||
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,14 +401,25 @@ 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;
|
||||
|
|
14
clientlog.h
14
clientlog.h
|
@ -35,15 +35,13 @@
|
|||
#include "sysincl.h"
|
||||
#include "reports.h"
|
||||
|
||||
typedef unsigned long CLG_IP_Addr;
|
||||
|
||||
/* Enough to hold flags for 256 hosts in a class C */
|
||||
typedef uint32_t CLG_Bitmap[8];
|
||||
|
||||
extern void CLG_Initialise(void);
|
||||
extern void CLG_Finalise(void);
|
||||
extern void CLG_LogNTPClientAccess(CLG_IP_Addr client, time_t now);
|
||||
extern void CLG_LogNTPPeerAccess(CLG_IP_Addr client, time_t now);
|
||||
extern void CLG_LogNTPClientAccess(IPAddr *client, time_t now);
|
||||
extern void CLG_LogNTPPeerAccess(IPAddr *client, time_t now);
|
||||
|
||||
/* When logging command packets, there are several subtypes */
|
||||
|
||||
|
@ -53,7 +51,7 @@ typedef enum {
|
|||
CLG_CMD_BAD_PKT /* bad version or packet length */
|
||||
} CLG_Command_Type;
|
||||
|
||||
extern void CLG_LogCommandAccess(CLG_IP_Addr client, CLG_Command_Type type, time_t now);
|
||||
extern void CLG_LogCommandAccess(IPAddr *client, CLG_Command_Type type, time_t now);
|
||||
|
||||
/* And some reporting functions, for use by chronyc. */
|
||||
/* TBD */
|
||||
|
@ -70,10 +68,10 @@ typedef enum {
|
|||
known. For bits=24, flag which hosts in that subnet are known.
|
||||
Other values, return 0 (failed) */
|
||||
|
||||
extern CLG_Status CLG_GetSubnetBitmap(CLG_IP_Addr subnet, int bits, CLG_Bitmap result);
|
||||
extern CLG_Status CLG_GetSubnetBitmap(IPAddr *subnet, int bits, CLG_Bitmap result);
|
||||
|
||||
extern 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);
|
||||
|
||||
CLG_Status
|
||||
CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report,
|
||||
|
@ -83,7 +81,7 @@ CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *repo
|
|||
that has accessed us since 'since'. */
|
||||
|
||||
extern void CLG_IterateNTPClients
|
||||
(void (*fn)(CLG_IP_Addr client, void *arb),
|
||||
(void (*fn)(IPAddr *client, void *arb),
|
||||
void *arb,
|
||||
time_t since);
|
||||
|
||||
|
|
408
cmdmon.c
408
cmdmon.c
|
@ -54,8 +54,19 @@
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
/* File descriptor for command and monitoring socket */
|
||||
static int sock_fd;
|
||||
union sockaddr_in46 {
|
||||
struct sockaddr_in in4;
|
||||
#ifdef HAVE_IPV6
|
||||
struct sockaddr_in6 in6;
|
||||
#endif
|
||||
struct sockaddr u;
|
||||
};
|
||||
|
||||
/* File descriptors for command and monitoring sockets */
|
||||
static int sock_fd4;
|
||||
#ifdef HAVE_IPV6
|
||||
static int sock_fd6;
|
||||
#endif
|
||||
|
||||
/* Flag indicating whether this module has been initialised or not */
|
||||
static int initialised = 0;
|
||||
|
@ -157,17 +168,93 @@ static ADF_AuthTable access_auth_table;
|
|||
|
||||
/* ================================================== */
|
||||
/* Forward prototypes */
|
||||
static int prepare_socket(int family);
|
||||
static void read_from_cmd_socket(void *anything);
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
prepare_socket(int family)
|
||||
{
|
||||
int port_number, sock_fd;
|
||||
union sockaddr_in46 my_addr;
|
||||
IPAddr bind_address;
|
||||
int on_off = 1;
|
||||
|
||||
port_number = CNF_GetCommandPort();
|
||||
if (port_number < 0) {
|
||||
port_number = DEFAULT_CANDM_PORT;
|
||||
}
|
||||
|
||||
sock_fd = socket(family, SOCK_DGRAM, 0);
|
||||
if (sock_fd < 0) {
|
||||
LOG(LOGS_ERR, LOGF_CmdMon, "Could not open socket : %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allow reuse of port number */
|
||||
if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on_off, sizeof(on_off)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_CmdMon, "Could not set socket options");
|
||||
/* Don't quit - we might survive anyway */
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
if (family == AF_INET6) {
|
||||
#ifdef IPV6_V6ONLY
|
||||
/* Receive IPv6 packets only */
|
||||
if (setsockopt(sock_fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on_off, sizeof(on_off)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not request IPV6_V6ONLY socket option");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&my_addr, 0, sizeof (my_addr));
|
||||
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
my_addr.in4.sin_family = family;
|
||||
my_addr.in4.sin_port = htons((unsigned short)port_number);
|
||||
|
||||
CNF_GetBindCommandAddress(IPADDR_INET4, &bind_address);
|
||||
|
||||
if (bind_address.family == IPADDR_INET4)
|
||||
my_addr.in4.sin_addr.s_addr = htonl(bind_address.addr.in4);
|
||||
else
|
||||
my_addr.in4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
my_addr.in6.sin6_family = family;
|
||||
my_addr.in6.sin6_port = htons((unsigned short)port_number);
|
||||
|
||||
CNF_GetBindCommandAddress(IPADDR_INET6, &bind_address);
|
||||
|
||||
if (bind_address.family == IPADDR_INET6)
|
||||
memcpy(my_addr.in6.sin6_addr.s6_addr, bind_address.addr.in6,
|
||||
sizeof (my_addr.in6.sin6_addr.s6_addr));
|
||||
else
|
||||
my_addr.in6.sin6_addr = in6addr_any;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (bind(sock_fd, &my_addr.u, sizeof(my_addr)) < 0) {
|
||||
LOG_FATAL(LOGF_CmdMon, "Could not bind socket : %s", strerror(errno));
|
||||
}
|
||||
|
||||
/* Register handler for read events on the socket */
|
||||
SCH_AddInputFileHandler(sock_fd, read_from_cmd_socket, (void *)(long)sock_fd);
|
||||
|
||||
return sock_fd;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
CAM_Initialise(void)
|
||||
{
|
||||
int port_number;
|
||||
struct sockaddr_in my_addr;
|
||||
unsigned long bind_address;
|
||||
int on_off = 1;
|
||||
|
||||
if (initialised) {
|
||||
CROAK("Shouldn't be initialised");
|
||||
|
@ -188,40 +275,19 @@ CAM_Initialise(void)
|
|||
free_replies = NULL;
|
||||
kept_replies.next = NULL;
|
||||
|
||||
port_number = CNF_GetCommandPort();
|
||||
if (port_number < 0) {
|
||||
port_number = DEFAULT_CANDM_PORT;
|
||||
sock_fd4 = prepare_socket(AF_INET);
|
||||
#ifdef HAVE_IPV6
|
||||
sock_fd6 = prepare_socket(AF_INET6);
|
||||
#endif
|
||||
|
||||
if (sock_fd4 < 0
|
||||
#ifdef HAVE_IPV6
|
||||
&& sock_fd6 < 0
|
||||
#endif
|
||||
) {
|
||||
LOG_FATAL(LOGF_CmdMon, "Could not open any command socket");
|
||||
}
|
||||
|
||||
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock_fd < 0) {
|
||||
LOG_FATAL(LOGF_CmdMon, "Could not open socket : %s", strerror(errno));
|
||||
}
|
||||
|
||||
/* Allow reuse of port number */
|
||||
if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on_off, sizeof(on_off)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_CmdMon, "Could not set socket options");
|
||||
/* Don't quit - we might survive anyway */
|
||||
}
|
||||
|
||||
my_addr.sin_family = AF_INET;
|
||||
my_addr.sin_port = htons((unsigned short) port_number);
|
||||
|
||||
CNF_GetBindCommandAddress(&bind_address);
|
||||
|
||||
if (bind_address != 0UL) {
|
||||
my_addr.sin_addr.s_addr = htonl(bind_address);
|
||||
} else {
|
||||
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
}
|
||||
|
||||
if (bind(sock_fd, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) {
|
||||
LOG_FATAL(LOGF_CmdMon, "Could not bind socket : %s", strerror(errno));
|
||||
}
|
||||
|
||||
/* Register handler for read events on the socket */
|
||||
SCH_AddInputFileHandler(sock_fd, read_from_cmd_socket, NULL);
|
||||
|
||||
access_auth_table = ADF_CreateTable();
|
||||
|
||||
}
|
||||
|
@ -231,9 +297,18 @@ CAM_Initialise(void)
|
|||
void
|
||||
CAM_Finalise(void)
|
||||
{
|
||||
SCH_RemoveInputFileHandler(sock_fd);
|
||||
close(sock_fd);
|
||||
sock_fd = -1;
|
||||
if (sock_fd4 >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd4);
|
||||
close(sock_fd4);
|
||||
}
|
||||
sock_fd4 = -1;
|
||||
#ifdef HAVE_IPV6
|
||||
if (sock_fd6 >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd6);
|
||||
close(sock_fd6);
|
||||
}
|
||||
sock_fd6 = -1;
|
||||
#endif
|
||||
|
||||
ADF_DestroyTable(access_auth_table);
|
||||
|
||||
|
@ -644,21 +719,51 @@ print_reply_packet(CMD_Reply *pkt)
|
|||
/* ================================================== */
|
||||
|
||||
static void
|
||||
transmit_reply(CMD_Reply *msg, struct sockaddr_in *where_to)
|
||||
transmit_reply(CMD_Reply *msg, union sockaddr_in46 *where_to)
|
||||
{
|
||||
int status;
|
||||
int tx_message_length;
|
||||
unsigned long remote_ip;
|
||||
unsigned short remote_port;
|
||||
int sock_fd;
|
||||
|
||||
switch (where_to->u.sa_family) {
|
||||
case AF_INET:
|
||||
sock_fd = sock_fd4;
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
sock_fd = sock_fd6;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
tx_message_length = PKL_ReplyLength(msg);
|
||||
status = sendto(sock_fd, (void *) msg, tx_message_length, 0,
|
||||
(struct sockaddr *) where_to, sizeof(struct sockaddr_in));
|
||||
&where_to->u, sizeof(union sockaddr_in46));
|
||||
|
||||
if (status < 0) {
|
||||
remote_ip = ntohl(where_to->sin_addr.s_addr);
|
||||
remote_port = ntohs(where_to->sin_port);
|
||||
LOG(LOGS_WARN, LOGF_CmdMon, "Could not send response to %s:%hu", UTI_IPToDottedQuad(remote_ip), remote_port);
|
||||
unsigned short port;
|
||||
IPAddr ip;
|
||||
|
||||
switch (where_to->u.sa_family) {
|
||||
case AF_INET:
|
||||
ip.family = IPADDR_INET4;
|
||||
ip.addr.in4 = ntohl(where_to->in4.sin_addr.s_addr);
|
||||
port = ntohs(where_to->in4.sin_port);
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
ip.family = IPADDR_INET6;
|
||||
memcpy(ip.addr.in6, (where_to->in6.sin6_addr.s6_addr), sizeof(ip.addr.in6));
|
||||
port = ntohs(where_to->in6.sin6_port);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
LOG(LOGS_WARN, LOGF_CmdMon, "Could not send response to %s:%hu", UTI_IPToString(&ip), port);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -679,7 +784,10 @@ static void
|
|||
handle_online(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
int status;
|
||||
status = NSR_TakeSourcesOnline(ntohl(rx_message->data.online.mask), ntohl(rx_message->data.online.address));
|
||||
IPAddr address, mask;
|
||||
UTI_IPNetworkToHost(&rx_message->data.online.mask, &mask);
|
||||
UTI_IPNetworkToHost(&rx_message->data.online.address, &address);
|
||||
status = NSR_TakeSourcesOnline(&mask, &address);
|
||||
if (status) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
} else {
|
||||
|
@ -693,7 +801,10 @@ static void
|
|||
handle_offline(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
int status;
|
||||
status = NSR_TakeSourcesOffline(ntohl(rx_message->data.offline.mask), ntohl(rx_message->data.offline.address));
|
||||
IPAddr address, mask;
|
||||
UTI_IPNetworkToHost(&rx_message->data.offline.mask, &mask);
|
||||
UTI_IPNetworkToHost(&rx_message->data.offline.address, &address);
|
||||
status = NSR_TakeSourcesOffline(&mask, &address);
|
||||
if (status) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
} else {
|
||||
|
@ -707,10 +818,12 @@ static void
|
|||
handle_burst(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
int status;
|
||||
IPAddr address, mask;
|
||||
UTI_IPNetworkToHost(&rx_message->data.burst.mask, &mask);
|
||||
UTI_IPNetworkToHost(&rx_message->data.burst.address, &address);
|
||||
status = NSR_InitiateSampleBurst(ntohl(rx_message->data.burst.n_good_samples),
|
||||
ntohl(rx_message->data.burst.n_total_samples),
|
||||
ntohl(rx_message->data.burst.mask),
|
||||
ntohl(rx_message->data.burst.address));
|
||||
&mask, &address);
|
||||
|
||||
if (status) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
|
@ -725,7 +838,9 @@ static void
|
|||
handle_modify_minpoll(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
int status;
|
||||
status = NSR_ModifyMinpoll(ntohl(rx_message->data.modify_minpoll.address),
|
||||
IPAddr address;
|
||||
UTI_IPNetworkToHost(&rx_message->data.modify_minpoll.address, &address);
|
||||
status = NSR_ModifyMinpoll(&address,
|
||||
ntohl(rx_message->data.modify_minpoll.new_minpoll));
|
||||
|
||||
if (status) {
|
||||
|
@ -741,7 +856,9 @@ static void
|
|||
handle_modify_maxpoll(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
int status;
|
||||
status = NSR_ModifyMaxpoll(ntohl(rx_message->data.modify_minpoll.address),
|
||||
IPAddr address;
|
||||
UTI_IPNetworkToHost(&rx_message->data.modify_minpoll.address, &address);
|
||||
status = NSR_ModifyMaxpoll(&address,
|
||||
ntohl(rx_message->data.modify_minpoll.new_minpoll));
|
||||
|
||||
if (status) {
|
||||
|
@ -757,7 +874,9 @@ static void
|
|||
handle_modify_maxdelay(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
int status;
|
||||
status = NSR_ModifyMaxdelay(ntohl(rx_message->data.modify_maxdelay.address),
|
||||
IPAddr address;
|
||||
UTI_IPNetworkToHost(&rx_message->data.modify_maxdelay.address, &address);
|
||||
status = NSR_ModifyMaxdelay(&address,
|
||||
WIRE2REAL(rx_message->data.modify_maxdelay.new_max_delay));
|
||||
if (status) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
|
@ -772,7 +891,9 @@ static void
|
|||
handle_modify_maxdelayratio(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
int status;
|
||||
status = NSR_ModifyMaxdelayratio(ntohl(rx_message->data.modify_maxdelayratio.address),
|
||||
IPAddr address;
|
||||
UTI_IPNetworkToHost(&rx_message->data.modify_maxdelayratio.address, &address);
|
||||
status = NSR_ModifyMaxdelayratio(&address,
|
||||
WIRE2REAL(rx_message->data.modify_maxdelayratio.new_max_delay_ratio));
|
||||
if (status) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
|
@ -884,7 +1005,7 @@ handle_source_data(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
tx_message->status = htons(STT_SUCCESS);
|
||||
tx_message->reply = htons(RPY_SOURCE_DATA);
|
||||
|
||||
tx_message->data.source_data.ip_addr = htonl(report.ip_addr);
|
||||
UTI_IPHostToNetwork(&report.ip_addr, &tx_message->data.source_data.ip_addr);
|
||||
tx_message->data.source_data.stratum = htons(report.stratum);
|
||||
tx_message->data.source_data.poll = htons(report.poll);
|
||||
switch (report.state) {
|
||||
|
@ -943,11 +1064,11 @@ handle_rekey(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
static void
|
||||
handle_allow(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
int subnet_bits;
|
||||
ip = ntohl(rx_message->data.allow_deny.ip);
|
||||
UTI_IPNetworkToHost(&rx_message->data.allow_deny.ip, &ip);
|
||||
subnet_bits = ntohl(rx_message->data.allow_deny.subnet_bits);
|
||||
if (NCR_AddAccessRestriction(ip, subnet_bits, 1, 0)) {
|
||||
if (NCR_AddAccessRestriction(&ip, subnet_bits, 1, 0)) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
} else {
|
||||
tx_message->status = htons(STT_BADSUBNET);
|
||||
|
@ -959,11 +1080,11 @@ handle_allow(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
static void
|
||||
handle_allowall(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
int subnet_bits;
|
||||
ip = ntohl(rx_message->data.allow_deny.ip);
|
||||
UTI_IPNetworkToHost(&rx_message->data.allow_deny.ip, &ip);
|
||||
subnet_bits = ntohl(rx_message->data.allow_deny.subnet_bits);
|
||||
if (NCR_AddAccessRestriction(ip, subnet_bits, 1, 1)) {
|
||||
if (NCR_AddAccessRestriction(&ip, subnet_bits, 1, 1)) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
} else {
|
||||
tx_message->status = htons(STT_BADSUBNET);
|
||||
|
@ -975,11 +1096,11 @@ handle_allowall(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
static void
|
||||
handle_deny(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
int subnet_bits;
|
||||
ip = ntohl(rx_message->data.allow_deny.ip);
|
||||
UTI_IPNetworkToHost(&rx_message->data.allow_deny.ip, &ip);
|
||||
subnet_bits = ntohl(rx_message->data.allow_deny.subnet_bits);
|
||||
if (NCR_AddAccessRestriction(ip, subnet_bits, 0, 0)) {
|
||||
if (NCR_AddAccessRestriction(&ip, subnet_bits, 0, 0)) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
} else {
|
||||
tx_message->status = htons(STT_BADSUBNET);
|
||||
|
@ -991,11 +1112,11 @@ handle_deny(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
static void
|
||||
handle_denyall(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
int subnet_bits;
|
||||
ip = ntohl(rx_message->data.allow_deny.ip);
|
||||
UTI_IPNetworkToHost(&rx_message->data.allow_deny.ip, &ip);
|
||||
subnet_bits = ntohl(rx_message->data.allow_deny.subnet_bits);
|
||||
if (NCR_AddAccessRestriction(ip, subnet_bits, 0, 1)) {
|
||||
if (NCR_AddAccessRestriction(&ip, subnet_bits, 0, 1)) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
} else {
|
||||
tx_message->status = htons(STT_BADSUBNET);
|
||||
|
@ -1007,11 +1128,11 @@ handle_denyall(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
static void
|
||||
handle_cmdallow(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
int subnet_bits;
|
||||
ip = ntohl(rx_message->data.allow_deny.ip);
|
||||
UTI_IPNetworkToHost(&rx_message->data.allow_deny.ip, &ip);
|
||||
subnet_bits = ntohl(rx_message->data.allow_deny.subnet_bits);
|
||||
if (CAM_AddAccessRestriction(ip, subnet_bits, 1, 0)) {
|
||||
if (CAM_AddAccessRestriction(&ip, subnet_bits, 1, 0)) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
} else {
|
||||
tx_message->status = htons(STT_BADSUBNET);
|
||||
|
@ -1023,11 +1144,11 @@ handle_cmdallow(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
static void
|
||||
handle_cmdallowall(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
int subnet_bits;
|
||||
ip = ntohl(rx_message->data.allow_deny.ip);
|
||||
UTI_IPNetworkToHost(&rx_message->data.allow_deny.ip, &ip);
|
||||
subnet_bits = ntohl(rx_message->data.allow_deny.subnet_bits);
|
||||
if (CAM_AddAccessRestriction(ip, subnet_bits, 1, 1)) {
|
||||
if (CAM_AddAccessRestriction(&ip, subnet_bits, 1, 1)) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
} else {
|
||||
tx_message->status = htons(STT_BADSUBNET);
|
||||
|
@ -1039,11 +1160,11 @@ handle_cmdallowall(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
static void
|
||||
handle_cmddeny(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
int subnet_bits;
|
||||
ip = ntohl(rx_message->data.allow_deny.ip);
|
||||
UTI_IPNetworkToHost(&rx_message->data.allow_deny.ip, &ip);
|
||||
subnet_bits = ntohl(rx_message->data.allow_deny.subnet_bits);
|
||||
if (CAM_AddAccessRestriction(ip, subnet_bits, 0, 0)) {
|
||||
if (CAM_AddAccessRestriction(&ip, subnet_bits, 0, 0)) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
} else {
|
||||
tx_message->status = htons(STT_BADSUBNET);
|
||||
|
@ -1055,11 +1176,11 @@ handle_cmddeny(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
static void
|
||||
handle_cmddenyall(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
int subnet_bits;
|
||||
ip = ntohl(rx_message->data.allow_deny.ip);
|
||||
UTI_IPNetworkToHost(&rx_message->data.allow_deny.ip, &ip);
|
||||
subnet_bits = ntohl(rx_message->data.allow_deny.subnet_bits);
|
||||
if (CAM_AddAccessRestriction(ip, subnet_bits, 0, 1)) {
|
||||
if (CAM_AddAccessRestriction(&ip, subnet_bits, 0, 1)) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
} else {
|
||||
tx_message->status = htons(STT_BADSUBNET);
|
||||
|
@ -1071,9 +1192,9 @@ handle_cmddenyall(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
static void
|
||||
handle_accheck(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
unsigned long ip;
|
||||
ip = ntohl(rx_message->data.ac_check.ip);
|
||||
if (NCR_CheckAccessRestriction(ip)) {
|
||||
IPAddr ip;
|
||||
UTI_IPNetworkToHost(&rx_message->data.ac_check.ip, &ip);
|
||||
if (NCR_CheckAccessRestriction(&ip)) {
|
||||
tx_message->status = htons(STT_ACCESSALLOWED);
|
||||
} else {
|
||||
tx_message->status = htons(STT_ACCESSDENIED);
|
||||
|
@ -1085,9 +1206,9 @@ handle_accheck(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
static void
|
||||
handle_cmdaccheck(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
unsigned long ip;
|
||||
ip = ntohl(rx_message->data.ac_check.ip);
|
||||
if (CAM_CheckAccessRestriction(ip)) {
|
||||
IPAddr ip;
|
||||
UTI_IPNetworkToHost(&rx_message->data.ac_check.ip, &ip);
|
||||
if (CAM_CheckAccessRestriction(&ip)) {
|
||||
tx_message->status = htons(STT_ACCESSALLOWED);
|
||||
} else {
|
||||
tx_message->status = htons(STT_ACCESSDENIED);
|
||||
|
@ -1103,8 +1224,8 @@ handle_add_server(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
SourceParameters params;
|
||||
NSR_Status status;
|
||||
|
||||
rem_addr.ip_addr = ntohl(rx_message->data.ntp_source.ip_addr);
|
||||
rem_addr.local_ip_addr = 0;
|
||||
UTI_IPNetworkToHost(&rx_message->data.ntp_source.ip_addr, &rem_addr.ip_addr);
|
||||
rem_addr.local_ip_addr.family = IPADDR_UNSPEC;
|
||||
rem_addr.port = (unsigned short)(ntohl(rx_message->data.ntp_source.port));
|
||||
params.minpoll = ntohl(rx_message->data.ntp_source.minpoll);
|
||||
params.maxpoll = ntohl(rx_message->data.ntp_source.maxpoll);
|
||||
|
@ -1125,6 +1246,9 @@ handle_add_server(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
case NSR_TooManySources:
|
||||
tx_message->status = htons(STT_TOOMANYSOURCES);
|
||||
break;
|
||||
case NSR_InvalidAF:
|
||||
tx_message->status = htons(STT_INVALIDAF);
|
||||
break;
|
||||
case NSR_NoSuchSource:
|
||||
CROAK("Impossible");
|
||||
break;
|
||||
|
@ -1140,8 +1264,8 @@ handle_add_peer(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
SourceParameters params;
|
||||
NSR_Status status;
|
||||
|
||||
rem_addr.ip_addr = ntohl(rx_message->data.ntp_source.ip_addr);
|
||||
rem_addr.local_ip_addr = 0;
|
||||
UTI_IPNetworkToHost(&rx_message->data.ntp_source.ip_addr, &rem_addr.ip_addr);
|
||||
rem_addr.local_ip_addr.family = IPADDR_UNSPEC;
|
||||
rem_addr.port = (unsigned short)(ntohl(rx_message->data.ntp_source.port));
|
||||
params.minpoll = ntohl(rx_message->data.ntp_source.minpoll);
|
||||
params.maxpoll = ntohl(rx_message->data.ntp_source.maxpoll);
|
||||
|
@ -1161,6 +1285,9 @@ handle_add_peer(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
case NSR_TooManySources:
|
||||
tx_message->status = htons(STT_TOOMANYSOURCES);
|
||||
break;
|
||||
case NSR_InvalidAF:
|
||||
tx_message->status = htons(STT_INVALIDAF);
|
||||
break;
|
||||
case NSR_NoSuchSource:
|
||||
CROAK("Impossible");
|
||||
break;
|
||||
|
@ -1175,8 +1302,8 @@ handle_del_source(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
NTP_Remote_Address rem_addr;
|
||||
NSR_Status status;
|
||||
|
||||
rem_addr.ip_addr = ntohl(rx_message->data.del_source.ip_addr);
|
||||
rem_addr.local_ip_addr = 0;
|
||||
UTI_IPNetworkToHost(&rx_message->data.del_source.ip_addr, &rem_addr.ip_addr);
|
||||
rem_addr.local_ip_addr.family = IPADDR_UNSPEC;
|
||||
rem_addr.port = 0;
|
||||
|
||||
status = NSR_RemoveSource(&rem_addr);
|
||||
|
@ -1189,6 +1316,7 @@ handle_del_source(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
break;
|
||||
case NSR_TooManySources:
|
||||
case NSR_AlreadyInUse:
|
||||
case NSR_InvalidAF:
|
||||
CROAK("Impossible");
|
||||
break;
|
||||
}
|
||||
|
@ -1273,7 +1401,7 @@ handle_sourcestats(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
if (status) {
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
tx_message->reply = htons(RPY_SOURCESTATS);
|
||||
tx_message->data.sourcestats.ip_addr = htonl(report.ip_addr);
|
||||
UTI_IPHostToNetwork(&report.ip_addr, &tx_message->data.sourcestats.ip_addr);
|
||||
tx_message->data.sourcestats.n_samples = htonl(report.n_samples);
|
||||
tx_message->data.sourcestats.n_runs = htonl(report.n_runs);
|
||||
tx_message->data.sourcestats.span_seconds = htonl(report.span_seconds);
|
||||
|
@ -1345,8 +1473,8 @@ static void
|
|||
handle_subnets_accessed(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
int i, j;
|
||||
unsigned long ns;
|
||||
unsigned long ip, bits_specd;
|
||||
unsigned long ns, bits_specd;
|
||||
IPAddr ip;
|
||||
CLG_Status result;
|
||||
|
||||
ns = ntohl(rx_message->data.subnets_accessed.n_subnets);
|
||||
|
@ -1355,13 +1483,13 @@ handle_subnets_accessed(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
tx_message->data.subnets_accessed.n_subnets = htonl(ns);
|
||||
|
||||
for (i=0; i<ns; i++) {
|
||||
ip = ntohl(rx_message->data.subnets_accessed.subnets[i].ip);
|
||||
UTI_IPNetworkToHost(&rx_message->data.subnets_accessed.subnets[i].ip, &ip);
|
||||
bits_specd = ntohl(rx_message->data.subnets_accessed.subnets[i].bits_specd);
|
||||
|
||||
tx_message->data.subnets_accessed.subnets[i].ip = htonl(ip);
|
||||
UTI_IPHostToNetwork(&ip, &tx_message->data.subnets_accessed.subnets[i].ip);
|
||||
tx_message->data.subnets_accessed.subnets[i].bits_specd = htonl(bits_specd);
|
||||
|
||||
result = CLG_GetSubnetBitmap(ip, bits_specd, tx_message->data.subnets_accessed.subnets[i].bitmap);
|
||||
result = CLG_GetSubnetBitmap(&ip, bits_specd, tx_message->data.subnets_accessed.subnets[i].bitmap);
|
||||
switch (result) {
|
||||
case CLG_SUCCESS:
|
||||
case CLG_EMPTYSUBNET:
|
||||
|
@ -1394,7 +1522,7 @@ handle_client_accesses(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
CLG_Status result;
|
||||
RPT_ClientAccess_Report report;
|
||||
unsigned long nc;
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
int i;
|
||||
struct timeval now;
|
||||
double local_time_error;
|
||||
|
@ -1409,10 +1537,10 @@ handle_client_accesses(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
printf("%d %d\n", (int)sizeof(RPY_ClientAccesses_Client), (int)offsetof(CMD_Reply, data.client_accesses.clients));
|
||||
|
||||
for (i=0; i<nc; i++) {
|
||||
ip = ntohl(rx_message->data.client_accesses.client_ips[i]);
|
||||
tx_message->data.client_accesses.clients[i].ip = htonl(ip);
|
||||
UTI_IPNetworkToHost(&rx_message->data.client_accesses.client_ips[i], &ip);
|
||||
UTI_IPHostToNetwork(&ip, &tx_message->data.client_accesses.clients[i].ip);
|
||||
|
||||
result = CLG_GetClientAccessReportByIP(ip, &report, now.tv_sec);
|
||||
result = CLG_GetClientAccessReportByIP(&ip, &report, now.tv_sec);
|
||||
switch (result) {
|
||||
case CLG_SUCCESS:
|
||||
tx_message->data.client_accesses.clients[i].client_hits = htonl(report.client_hits);
|
||||
|
@ -1422,13 +1550,13 @@ handle_client_accesses(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
tx_message->data.client_accesses.clients[i].cmd_hits_bad = htonl(report.cmd_hits_bad);
|
||||
tx_message->data.client_accesses.clients[i].last_ntp_hit_ago = htonl(report.last_ntp_hit_ago);
|
||||
tx_message->data.client_accesses.clients[i].last_cmd_hit_ago = htonl(report.last_cmd_hit_ago);
|
||||
printf("%08lx %lu %lu %lu %lu %lu %lu %lu\n", ip, report.client_hits, report.peer_hits, report.cmd_hits_auth, report.cmd_hits_normal, report.cmd_hits_bad, report.last_ntp_hit_ago, report.last_cmd_hit_ago);
|
||||
printf("%s %lu %lu %lu %lu %lu %lu %lu\n", UTI_IPToString(&ip), report.client_hits, report.peer_hits, report.cmd_hits_auth, report.cmd_hits_normal, report.cmd_hits_bad, report.last_ntp_hit_ago, report.last_cmd_hit_ago);
|
||||
break;
|
||||
case CLG_EMPTYSUBNET:
|
||||
/* Signal back to the client that this single client address
|
||||
was unknown, by specifying the zero ip address, which will
|
||||
always be invalid (hopefully) */
|
||||
tx_message->data.client_accesses.clients[i].ip = htonl(0);
|
||||
was unknown */
|
||||
ip.family = IPADDR_UNSPEC;
|
||||
UTI_IPHostToNetwork(&ip, &tx_message->data.client_accesses.clients[i].ip);
|
||||
break;
|
||||
case CLG_INACTIVE:
|
||||
tx_message->status = htons(STT_INACTIVE);
|
||||
|
@ -1471,7 +1599,7 @@ handle_client_accesses_by_index(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
|
||||
switch (result) {
|
||||
case CLG_SUCCESS:
|
||||
tx_message->data.client_accesses_by_index.clients[j].ip = htonl(report.ip_addr);
|
||||
UTI_IPHostToNetwork(&report.ip_addr, &tx_message->data.client_accesses_by_index.clients[j].ip);
|
||||
tx_message->data.client_accesses_by_index.clients[j].client_hits = htonl(report.client_hits);
|
||||
tx_message->data.client_accesses_by_index.clients[j].peer_hits = htonl(report.peer_hits);
|
||||
tx_message->data.client_accesses_by_index.clients[j].cmd_hits_auth = htonl(report.cmd_hits_auth);
|
||||
|
@ -1594,9 +1722,10 @@ read_from_cmd_socket(void *anything)
|
|||
CMD_Request rx_message;
|
||||
CMD_Reply tx_message, *prev_tx_message;
|
||||
int rx_message_length, tx_message_length;
|
||||
struct sockaddr_in where_from;
|
||||
int sock_fd;
|
||||
union sockaddr_in46 where_from;
|
||||
socklen_t from_length;
|
||||
unsigned long remote_ip;
|
||||
IPAddr remote_ip;
|
||||
unsigned short remote_port;
|
||||
int md5_ok;
|
||||
int utoken_ok, token_ok;
|
||||
|
@ -1617,14 +1746,14 @@ read_from_cmd_socket(void *anything)
|
|||
rx_message_length = sizeof(rx_message);
|
||||
from_length = sizeof(where_from);
|
||||
|
||||
sock_fd = (long)anything;
|
||||
status = recvfrom(sock_fd, (char *)&rx_message, rx_message_length, flags,
|
||||
(struct sockaddr *)&where_from, &from_length);
|
||||
&where_from.u, &from_length);
|
||||
|
||||
if (status < 0) {
|
||||
LOG(LOGS_WARN, LOGF_CmdMon, "Error [%s] reading from control socket (IP=%s port=%d)",
|
||||
strerror(errno),
|
||||
UTI_IPToDottedQuad(ntohl(where_from.sin_addr.s_addr)),
|
||||
ntohs(where_from.sin_port));
|
||||
LOG(LOGS_WARN, LOGF_CmdMon, "Error [%s] reading from control socket %d",
|
||||
strerror(errno), sock_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
read_length = status;
|
||||
|
@ -1650,12 +1779,31 @@ read_from_cmd_socket(void *anything)
|
|||
tx_message.token = htonl(0xffffffffUL);
|
||||
memset(&tx_message.auth, 0, sizeof(tx_message.auth));
|
||||
|
||||
remote_ip = ntohl(where_from.sin_addr.s_addr);
|
||||
remote_port = ntohs(where_from.sin_port);
|
||||
switch (where_from.u.sa_family) {
|
||||
case AF_INET:
|
||||
remote_ip.family = IPADDR_INET4;
|
||||
remote_ip.addr.in4 = ntohl(where_from.in4.sin_addr.s_addr);
|
||||
remote_port = ntohs(where_from.in4.sin_port);
|
||||
localhost = (remote_ip.addr.in4 == 0x7f000001UL);
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
remote_ip.family = IPADDR_INET6;
|
||||
memcpy(&remote_ip.addr.in6, where_from.in6.sin6_addr.s6_addr,
|
||||
sizeof (remote_ip.addr.in6));
|
||||
remote_port = ntohs(where_from.in6.sin6_port);
|
||||
/* Check for ::1 */
|
||||
for (localhost = 0; localhost < 16; localhost++)
|
||||
if (remote_ip.addr.in6[localhost] != 0)
|
||||
break;
|
||||
localhost = (localhost == 15 && remote_ip.addr.in6[localhost] == 1);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
localhost = (remote_ip == 0x7f000001UL);
|
||||
|
||||
if ((!ADF_IsAllowed(access_auth_table, remote_ip)) &&
|
||||
if ((!ADF_IsAllowed(access_auth_table, &remote_ip)) &&
|
||||
(!localhost)) {
|
||||
/* The client is not allowed access, so don't waste any more time
|
||||
on him. Note that localhost is always allowed access
|
||||
|
@ -1667,7 +1815,7 @@ read_from_cmd_socket(void *anything)
|
|||
hitting us with bad packets until our log file(s) fill up. */
|
||||
|
||||
LOG(LOGS_WARN, LOGF_CmdMon, "Command packet received from unauthorised host %s port %d",
|
||||
UTI_IPToDottedQuad(remote_ip),
|
||||
UTI_IPToString(&remote_ip),
|
||||
remote_port);
|
||||
|
||||
tx_message.status = htons(STT_NOHOSTACCESS);
|
||||
|
@ -1678,8 +1826,8 @@ read_from_cmd_socket(void *anything)
|
|||
|
||||
|
||||
if (read_length != expected_length) {
|
||||
LOG(LOGS_WARN, LOGF_CmdMon, "Read incorrectly sized packet from %s:%hu", UTI_IPToDottedQuad(remote_ip), remote_port);
|
||||
CLG_LogCommandAccess(remote_ip, CLG_CMD_BAD_PKT, cooked_now.tv_sec);
|
||||
LOG(LOGS_WARN, LOGF_CmdMon, "Read incorrectly sized packet from %s:%hu", UTI_IPToString(&remote_ip), remote_port);
|
||||
CLG_LogCommandAccess(&remote_ip, CLG_CMD_BAD_PKT, cooked_now.tv_sec);
|
||||
/* For now, just ignore the packet. We may want to send a reply
|
||||
back eventually */
|
||||
return;
|
||||
|
@ -1691,7 +1839,7 @@ read_from_cmd_socket(void *anything)
|
|||
(rx_message.res2 != 0)) {
|
||||
|
||||
/* We don't know how to process anything like this */
|
||||
CLG_LogCommandAccess(remote_ip, CLG_CMD_BAD_PKT, cooked_now.tv_sec);
|
||||
CLG_LogCommandAccess(&remote_ip, CLG_CMD_BAD_PKT, cooked_now.tv_sec);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1773,7 +1921,7 @@ read_from_cmd_socket(void *anything)
|
|||
status = sendto(sock_fd, (void *) prev_tx_message, tx_message_length, 0,
|
||||
(struct sockaddr *) &where_from, sizeof(where_from));
|
||||
if (status < 0) {
|
||||
LOG(LOGS_WARN, LOGF_CmdMon, "Could not send response to %s:%hu", UTI_IPToDottedQuad(remote_ip), remote_port);
|
||||
LOG(LOGS_WARN, LOGF_CmdMon, "Could not send response to %s:%hu", UTI_IPToString(&remote_ip), remote_port);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1800,9 +1948,9 @@ read_from_cmd_socket(void *anything)
|
|||
authenticated = md5_ok & utoken_ok & token_ok;
|
||||
|
||||
if (authenticated) {
|
||||
CLG_LogCommandAccess(remote_ip, CLG_CMD_AUTH, cooked_now.tv_sec);
|
||||
CLG_LogCommandAccess(&remote_ip, CLG_CMD_AUTH, cooked_now.tv_sec);
|
||||
} else {
|
||||
CLG_LogCommandAccess(remote_ip, CLG_CMD_NORMAL, cooked_now.tv_sec);
|
||||
CLG_LogCommandAccess(&remote_ip, CLG_CMD_NORMAL, cooked_now.tv_sec);
|
||||
}
|
||||
|
||||
if (issue_token) {
|
||||
|
@ -1895,7 +2043,7 @@ read_from_cmd_socket(void *anything)
|
|||
if (!issue_token) {
|
||||
LOG(LOGS_WARN, LOGF_CmdMon,
|
||||
"Bad command logon from %s port %d (md5_ok=%d valid_ts=%d)\n",
|
||||
UTI_IPToDottedQuad(remote_ip),
|
||||
UTI_IPToString(&remote_ip),
|
||||
remote_port,
|
||||
md5_ok, valid_ts);
|
||||
}
|
||||
|
@ -2092,7 +2240,7 @@ read_from_cmd_socket(void *anything)
|
|||
/* ================================================== */
|
||||
|
||||
int
|
||||
CAM_AddAccessRestriction(unsigned long ip_addr, int subnet_bits, int allow, int all)
|
||||
CAM_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all)
|
||||
{
|
||||
ADF_Status status;
|
||||
|
||||
|
@ -2122,7 +2270,7 @@ CAM_AddAccessRestriction(unsigned long ip_addr, int subnet_bits, int allow, int
|
|||
/* ================================================== */
|
||||
|
||||
int
|
||||
CAM_CheckAccessRestriction(unsigned long ip_addr)
|
||||
CAM_CheckAccessRestriction(IPAddr *ip_addr)
|
||||
{
|
||||
return ADF_IsAllowed(access_auth_table, ip_addr);
|
||||
}
|
||||
|
|
6
cmdmon.h
6
cmdmon.h
|
@ -31,11 +31,13 @@
|
|||
#ifndef GOT_CMDMON_H
|
||||
#define GOT_CMDMON_H
|
||||
|
||||
#include "addressing.h"
|
||||
|
||||
extern void CAM_Initialise(void);
|
||||
|
||||
extern void CAM_Finalise(void);
|
||||
|
||||
extern int CAM_AddAccessRestriction(unsigned long ip_addr, int subnet_bits, int allow, int all);
|
||||
extern int CAM_CheckAccessRestriction(unsigned long ip_addr);
|
||||
extern int CAM_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all);
|
||||
extern int CAM_CheckAccessRestriction(IPAddr *ip_addr);
|
||||
|
||||
#endif /* GOT_CMDMON_H */
|
||||
|
|
|
@ -61,8 +61,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
|
|||
|
||||
ok = 0;
|
||||
if (sscanf(line, "%" SMAXLEN "s%n", hostname, &n) == 1) {
|
||||
src->ip_addr = DNS_Name2IPAddressRetry(hostname);
|
||||
if (src->ip_addr != DNS_Failed_Address) {
|
||||
if (DNS_Name2IPAddress(hostname, &src->ip_addr, 1)) {
|
||||
ok = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#define GOT_CMDPARSE_H
|
||||
|
||||
#include "srcparams.h"
|
||||
#include "addressing.h"
|
||||
|
||||
typedef enum {
|
||||
CPS_Success,
|
||||
|
@ -47,7 +48,7 @@ typedef enum {
|
|||
} CPS_Status;
|
||||
|
||||
typedef struct {
|
||||
unsigned long ip_addr;
|
||||
IPAddr ip_addr;
|
||||
unsigned short port;
|
||||
SourceParameters params;
|
||||
} CPS_NTP_Source;
|
||||
|
|
181
conf.c
181
conf.c
|
@ -53,6 +53,7 @@
|
|||
#include "acquire.h"
|
||||
#include "cmdparse.h"
|
||||
#include "broadcast.h"
|
||||
#include "util.h"
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
|
@ -136,7 +137,7 @@ static int n_init_srcs;
|
|||
than this, slew instead of stepping */
|
||||
static int init_slew_threshold = -1;
|
||||
#define MAX_INIT_SRCS 8
|
||||
static unsigned long init_srcs_ip[MAX_INIT_SRCS];
|
||||
static IPAddr init_srcs_ip[MAX_INIT_SRCS];
|
||||
|
||||
static int enable_manual=0;
|
||||
|
||||
|
@ -156,13 +157,13 @@ static double mail_change_threshold = 0.0;
|
|||
memory */
|
||||
static int no_client_log = 0;
|
||||
|
||||
/* IP address (host order) for binding the NTP socket to. 0 means INADDR_ANY
|
||||
/* IP addresses for binding the NTP socket to. UNSPEC family means INADDR_ANY
|
||||
will be used */
|
||||
static unsigned long bind_address = 0UL;
|
||||
static IPAddr bind_address4, bind_address6;
|
||||
|
||||
/* IP address (host order) for binding the command socket to. 0 means
|
||||
/* IP addresses for binding the command socket to. UNSPEC family means
|
||||
use the value of bind_address */
|
||||
static unsigned long bind_cmd_address = 0UL;
|
||||
static IPAddr bind_cmd_address4, bind_cmd_address6;
|
||||
|
||||
/* Filename to use for storing pid of running chronyd, to prevent multiple
|
||||
* chronyds being started. */
|
||||
|
@ -243,7 +244,7 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
NTP_Source_Type type;
|
||||
unsigned long ip_addr;
|
||||
IPAddr ip_addr;
|
||||
unsigned short port;
|
||||
SourceParameters params;
|
||||
} NTP_Source;
|
||||
|
@ -263,7 +264,7 @@ static int n_refclock_sources = 0;
|
|||
typedef struct _AllowDeny {
|
||||
struct _AllowDeny *next;
|
||||
struct _AllowDeny *prev;
|
||||
unsigned long ip;
|
||||
IPAddr ip;
|
||||
int subnet_bits;
|
||||
int all; /* 1 to override existing more specific defns */
|
||||
int allow; /* 0 for deny, 1 for allow */
|
||||
|
@ -697,7 +698,7 @@ parse_initstepslew(const char *line)
|
|||
char hostname[HOSTNAME_LEN+1];
|
||||
int n;
|
||||
int threshold;
|
||||
unsigned long ip_addr;
|
||||
IPAddr ip_addr;
|
||||
|
||||
n_init_srcs = 0;
|
||||
p = line;
|
||||
|
@ -710,8 +711,7 @@ parse_initstepslew(const char *line)
|
|||
}
|
||||
while (*p) {
|
||||
if (sscanf(p, "%" SHOSTNAME_LEN "s%n", hostname, &n) == 1) {
|
||||
ip_addr = DNS_Name2IPAddressRetry(hostname);
|
||||
if (ip_addr != DNS_Failed_Address) {
|
||||
if (DNS_Name2IPAddress(hostname, &ip_addr, 1)) {
|
||||
init_srcs_ip[n_init_srcs] = ip_addr;
|
||||
++n_init_srcs;
|
||||
}
|
||||
|
@ -803,7 +803,7 @@ parse_allow_deny(const char *line, AllowDeny *list, int allow)
|
|||
unsigned long a, b, c, d, n;
|
||||
int all = 0;
|
||||
AllowDeny *new_node = NULL;
|
||||
unsigned long ip_addr;
|
||||
IPAddr ip_addr;
|
||||
|
||||
p = line;
|
||||
|
||||
|
@ -820,45 +820,54 @@ parse_allow_deny(const char *line, AllowDeny *list, int allow)
|
|||
new_node = MallocNew(AllowDeny);
|
||||
new_node->allow = allow;
|
||||
new_node->all = all;
|
||||
new_node->ip = 0UL;
|
||||
new_node->ip.family = IPADDR_UNSPEC;
|
||||
new_node->subnet_bits = 0;
|
||||
} else {
|
||||
char *slashpos;
|
||||
slashpos = strchr(p, '/');
|
||||
if (slashpos) *slashpos = 0;
|
||||
|
||||
n = sscanf(p, "%lu.%lu.%lu.%lu", &a, &b, &c, &d);
|
||||
|
||||
if (n >= 1) {
|
||||
n = 0;
|
||||
if (UTI_StringToIP(p, &ip_addr) ||
|
||||
(n = sscanf(p, "%lu.%lu.%lu.%lu", &a, &b, &c, &d)) >= 1) {
|
||||
new_node = MallocNew(AllowDeny);
|
||||
new_node->allow = allow;
|
||||
new_node->all = all;
|
||||
|
||||
a &= 0xff;
|
||||
b &= 0xff;
|
||||
c &= 0xff;
|
||||
d &= 0xff;
|
||||
|
||||
switch (n) {
|
||||
case 1:
|
||||
new_node->ip = (a<<24);
|
||||
new_node->subnet_bits = 8;
|
||||
break;
|
||||
case 2:
|
||||
new_node->ip = (a<<24) | (b<<16);
|
||||
new_node->subnet_bits = 16;
|
||||
break;
|
||||
case 3:
|
||||
new_node->ip = (a<<24) | (b<<16) | (c<<8);
|
||||
new_node->subnet_bits = 24;
|
||||
break;
|
||||
case 4:
|
||||
new_node->ip = (a<<24) | (b<<16) | (c<<8) | d;
|
||||
if (n == 0) {
|
||||
new_node->ip = ip_addr;
|
||||
if (ip_addr.family == IPADDR_INET6)
|
||||
new_node->subnet_bits = 128;
|
||||
else
|
||||
new_node->subnet_bits = 32;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
} else {
|
||||
new_node->ip.family = IPADDR_INET4;
|
||||
|
||||
a &= 0xff;
|
||||
b &= 0xff;
|
||||
c &= 0xff;
|
||||
d &= 0xff;
|
||||
|
||||
switch (n) {
|
||||
case 1:
|
||||
new_node->ip.addr.in4 = (a<<24);
|
||||
new_node->subnet_bits = 8;
|
||||
break;
|
||||
case 2:
|
||||
new_node->ip.addr.in4 = (a<<24) | (b<<16);
|
||||
new_node->subnet_bits = 16;
|
||||
break;
|
||||
case 3:
|
||||
new_node->ip.addr.in4 = (a<<24) | (b<<16) | (c<<8);
|
||||
new_node->subnet_bits = 24;
|
||||
break;
|
||||
case 4:
|
||||
new_node->ip.addr.in4 = (a<<24) | (b<<16) | (c<<8) | d;
|
||||
new_node->subnet_bits = 32;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (slashpos) {
|
||||
|
@ -872,13 +881,15 @@ parse_allow_deny(const char *line, AllowDeny *list, int allow)
|
|||
}
|
||||
|
||||
} else {
|
||||
ip_addr = DNS_Name2IPAddressRetry(p);
|
||||
if (ip_addr != DNS_Failed_Address) {
|
||||
if (DNS_Name2IPAddress(p, &ip_addr, 1)) {
|
||||
new_node = MallocNew(AllowDeny);
|
||||
new_node->allow = allow;
|
||||
new_node->all = all;
|
||||
new_node->ip = ip_addr;
|
||||
new_node->subnet_bits = 32;
|
||||
if (ip_addr.family == IPADDR_INET6)
|
||||
new_node->subnet_bits = 128;
|
||||
else
|
||||
new_node->subnet_bits = 32;
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_Configure, "Could not read address at line %d", line_number);
|
||||
}
|
||||
|
@ -931,27 +942,20 @@ parse_cmddeny(const char *line)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static unsigned long
|
||||
parse_an_address(const char *line, const char *errmsg)
|
||||
{
|
||||
unsigned long a, b, c, d;
|
||||
int n;
|
||||
n = sscanf(line, "%lu.%lu.%lu.%lu", &a, &b, &c, &d);
|
||||
if (n == 4) {
|
||||
return (((a&0xff)<<24) | ((b&0xff)<<16) |
|
||||
((c&0xff)<<8) | (d&0xff));
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_Configure, errmsg, line_number);
|
||||
return 0UL;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
parse_bindaddress(const char *line)
|
||||
{
|
||||
bind_address = parse_an_address(line, "Could not read bind address at line %d\n");
|
||||
IPAddr ip;
|
||||
char addr[51];
|
||||
|
||||
if (sscanf(line, "%50s", addr) == 1 && UTI_StringToIP(addr, &ip)) {
|
||||
if (ip.family == IPADDR_INET4)
|
||||
bind_address4 = ip;
|
||||
else if (ip.family == IPADDR_INET6)
|
||||
bind_address6 = ip;
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_Configure, "Could not read bind address at line %d\n", line_number);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -959,7 +963,17 @@ parse_bindaddress(const char *line)
|
|||
static void
|
||||
parse_bindcmdaddress(const char *line)
|
||||
{
|
||||
bind_cmd_address = parse_an_address(line, "Could not read bind command address at line %d\n");
|
||||
IPAddr ip;
|
||||
char addr[51];
|
||||
|
||||
if (sscanf(line, "%50s", addr) == 1 && UTI_StringToIP(addr, &ip)) {
|
||||
if (ip.family == IPADDR_INET4)
|
||||
bind_cmd_address4 = ip;
|
||||
else if (ip.family == IPADDR_INET6)
|
||||
bind_cmd_address6 = ip;
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_Configure, "Could not read bind command address at line %d\n", line_number);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -976,7 +990,7 @@ parse_pidfile(const char *line)
|
|||
|
||||
typedef struct {
|
||||
/* Both in host (not necessarily network) order */
|
||||
unsigned long addr;
|
||||
IPAddr addr;
|
||||
unsigned short port;
|
||||
int interval;
|
||||
} NTP_Broadcast_Destination;
|
||||
|
@ -992,27 +1006,22 @@ parse_broadcast(const char *line)
|
|||
{
|
||||
/* Syntax : broadcast <interval> <broadcast-IP-addr> [<port>] */
|
||||
int port;
|
||||
unsigned int a, b, c, d;
|
||||
int n;
|
||||
int interval;
|
||||
unsigned long addr;
|
||||
char addr[51];
|
||||
IPAddr ip;
|
||||
|
||||
n = sscanf(line, "%d %u.%u.%u.%u %d", &interval, &a, &b, &c, &d, &port);
|
||||
if (n < 5) {
|
||||
n = sscanf(line, "%d %50s %d", &interval, addr, &port);
|
||||
if (n < 2 || !UTI_StringToIP(addr, &ip)) {
|
||||
LOG(LOGS_WARN, LOGF_Configure, "Could not parse broadcast directive at line %d", line_number);
|
||||
return;
|
||||
} else if (n == 5) {
|
||||
} else if (n == 2) {
|
||||
/* default port */
|
||||
port = 123;
|
||||
} else if (n > 6) {
|
||||
} else if (n > 3) {
|
||||
LOG(LOGS_WARN, LOGF_Configure, "Too many fields in broadcast directive at line %d", line_number);
|
||||
}
|
||||
|
||||
addr = ((unsigned long) a << 24) |
|
||||
((unsigned long) b << 16) |
|
||||
((unsigned long) c << 8) |
|
||||
((unsigned long) d );
|
||||
|
||||
if (max_broadcasts == n_broadcasts) {
|
||||
/* Expand array */
|
||||
max_broadcasts += 8;
|
||||
|
@ -1023,7 +1032,7 @@ parse_broadcast(const char *line)
|
|||
}
|
||||
}
|
||||
|
||||
broadcasts[n_broadcasts].addr = addr;
|
||||
broadcasts[n_broadcasts].addr = ip;
|
||||
broadcasts[n_broadcasts].port = port;
|
||||
broadcasts[n_broadcasts].interval = interval;
|
||||
++n_broadcasts;
|
||||
|
@ -1074,7 +1083,7 @@ CNF_AddSources(void) {
|
|||
|
||||
for (i=0; i<n_ntp_sources; i++) {
|
||||
server.ip_addr = ntp_sources[i].ip_addr;
|
||||
server.local_ip_addr = 0;
|
||||
memset(&server.local_ip_addr, 0, sizeof (server.local_ip_addr));
|
||||
server.port = ntp_sources[i].port;
|
||||
|
||||
switch (ntp_sources[i].type) {
|
||||
|
@ -1111,7 +1120,7 @@ CNF_AddBroadcasts(void)
|
|||
{
|
||||
int i;
|
||||
for (i=0; i<n_broadcasts; i++) {
|
||||
BRD_AddDestination(broadcasts[i].addr,
|
||||
BRD_AddDestination(&broadcasts[i].addr,
|
||||
broadcasts[i].port,
|
||||
broadcasts[i].interval);
|
||||
}
|
||||
|
@ -1307,14 +1316,14 @@ CNF_SetupAccessRestrictions(void)
|
|||
int status;
|
||||
|
||||
for (node = ntp_auth_list.next; node != &ntp_auth_list; node = node->next) {
|
||||
status = NCR_AddAccessRestriction(node->ip, node->subnet_bits, node->allow, node->all);
|
||||
status = NCR_AddAccessRestriction(&node->ip, node->subnet_bits, node->allow, node->all);
|
||||
if (!status) {
|
||||
LOG(LOGS_WARN, LOGF_Configure, "Bad subnet for %08lx", node->ip);
|
||||
}
|
||||
}
|
||||
|
||||
for (node = cmd_auth_list.next; node != &cmd_auth_list; node = node->next) {
|
||||
status = CAM_AddAccessRestriction(node->ip, node->subnet_bits, node->allow, node->all);
|
||||
status = CAM_AddAccessRestriction(&node->ip, node->subnet_bits, node->allow, node->all);
|
||||
if (!status) {
|
||||
LOG(LOGS_WARN, LOGF_Configure, "Bad subnet for %08lx", node->ip);
|
||||
}
|
||||
|
@ -1334,17 +1343,27 @@ CNF_GetNoClientLog(void)
|
|||
/* ================================================== */
|
||||
|
||||
void
|
||||
CNF_GetBindAddress(unsigned long *addr)
|
||||
CNF_GetBindAddress(int family, IPAddr *addr)
|
||||
{
|
||||
*addr = bind_address;
|
||||
if (family == IPADDR_INET4)
|
||||
*addr = bind_address4;
|
||||
else if (family == IPADDR_INET6)
|
||||
*addr = bind_address6;
|
||||
else
|
||||
addr->family = IPADDR_UNSPEC;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
CNF_GetBindCommandAddress(unsigned long *addr)
|
||||
CNF_GetBindCommandAddress(int family, IPAddr *addr)
|
||||
{
|
||||
*addr = bind_cmd_address ? bind_cmd_address : bind_address;
|
||||
if (family == IPADDR_INET4)
|
||||
*addr = bind_cmd_address4.family != IPADDR_UNSPEC ? bind_cmd_address4 : bind_address4;
|
||||
else if (family == IPADDR_INET6)
|
||||
*addr = bind_cmd_address6.family != IPADDR_UNSPEC ? bind_cmd_address6 : bind_address6;
|
||||
else
|
||||
addr->family = IPADDR_UNSPEC;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
|
6
conf.h
6
conf.h
|
@ -31,6 +31,8 @@
|
|||
#ifndef GOT_CONF_H
|
||||
#define GOT_CONF_H
|
||||
|
||||
#include "addressing.h"
|
||||
|
||||
extern char *CNF_GetRtcDevice(void);
|
||||
|
||||
extern void CNF_ReadFile(const char *filename);
|
||||
|
@ -60,8 +62,8 @@ extern int CNF_GetRTCOnUTC(void);
|
|||
extern void CNF_GetLogChange(int *enabled, double *threshold);
|
||||
extern void CNF_GetMailOnChange(int *enabled, double *threshold, char **user);
|
||||
extern int CNF_GetNoClientLog(void);
|
||||
extern void CNF_GetBindAddress(unsigned long *addr);
|
||||
extern void CNF_GetBindCommandAddress(unsigned long *addr);
|
||||
extern void CNF_GetBindAddress(int family, IPAddr *addr);
|
||||
extern void CNF_GetBindCommandAddress(int family, IPAddr *addr);
|
||||
extern char *CNF_GetPidFile(void);
|
||||
extern void CNF_GetLinuxHz(int *set, int *hz);
|
||||
extern void CNF_GetLinuxFreqScale(int *set, double *freq_scale);
|
||||
|
|
39
configure
vendored
39
configure
vendored
|
@ -106,6 +106,32 @@ EOF
|
|||
echo $result
|
||||
}
|
||||
#}}}
|
||||
#{{{ test_for_ipv6
|
||||
test_for_ipv6 () {
|
||||
cat >docheck.c <<EOF;
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
int main(int argc, char **argv) {
|
||||
struct sockaddr_in6 n;
|
||||
char p[100];
|
||||
n.sin6_addr = in6addr_any;
|
||||
return !inet_ntop(AF_INET6, &n.sin6_addr.s6_addr, p, sizeof(p));
|
||||
}
|
||||
EOF
|
||||
|
||||
${MYCC} ${MYCFLAGS} -c -o docheck.o docheck.c >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
result=0
|
||||
else
|
||||
result=1
|
||||
fi
|
||||
|
||||
rm -f docheck.c docheck.o
|
||||
echo $result
|
||||
}
|
||||
#}}}
|
||||
#{{{ usage
|
||||
usage () {
|
||||
cat <<EOF;
|
||||
|
@ -134,6 +160,7 @@ For better control, use the options below.
|
|||
--readline-inc-dir=DIR Specify where readline include directory is
|
||||
--readline-lib-dir=DIR Specify where readline lib directory is
|
||||
--with-ncurses-library=DIR Specify where ncurses lib directory is
|
||||
--disable-ipv6 Disable IPv6 support
|
||||
--disable-rtc Don't include RTC even on Linux
|
||||
--enable-linuxcaps Enable Linux capabilities support
|
||||
|
||||
|
@ -181,6 +208,7 @@ feat_linuxcaps=0
|
|||
readline_lib=""
|
||||
readline_inc=""
|
||||
ncurses_lib=""
|
||||
feat_ipv6=1
|
||||
|
||||
SETINFODIR=""
|
||||
SETMANDIR=""
|
||||
|
@ -218,6 +246,9 @@ do
|
|||
--disable-rtc)
|
||||
feat_rtc=0
|
||||
;;
|
||||
--disable-ipv6)
|
||||
feat_ipv6=0
|
||||
;;
|
||||
--enable-linuxcaps)
|
||||
feat_linuxcaps=1
|
||||
;;
|
||||
|
@ -339,6 +370,14 @@ else
|
|||
printf "No\n"
|
||||
fi
|
||||
|
||||
printf "Checking for IPv6 support : "
|
||||
if [ $feat_ipv6 -eq 1 -a `test_for_ipv6` -eq 0 ]; then
|
||||
printf "Yes\n"
|
||||
SYSDEFS="${SYSDEFS} -DHAVE_IPV6"
|
||||
else
|
||||
printf "No\n"
|
||||
fi
|
||||
|
||||
if [ "x${MYCC}" = "xgcc" ]; then
|
||||
CCWARNFLAGS="-Wmissing-prototypes -Wall"
|
||||
else
|
||||
|
|
171
nameserv.c
171
nameserv.c
|
@ -32,85 +32,134 @@
|
|||
#include "sysincl.h"
|
||||
|
||||
#include "nameserv.h"
|
||||
#include "util.h"
|
||||
#include <resolv.h>
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#define MAXRETRIES 10
|
||||
static unsigned int retries = 0;
|
||||
|
||||
static unsigned long
|
||||
Name2IPAddress(const char *name, int retry)
|
||||
int
|
||||
DNS_Name2IPAddress(const char *name, IPAddr *addr, int retry)
|
||||
{
|
||||
struct hostent *host;
|
||||
unsigned char *address0;
|
||||
unsigned long result;
|
||||
#ifdef HAVE_IPV6
|
||||
struct addrinfo hints, *res, *ai;
|
||||
int result;
|
||||
|
||||
memset(&hints, 0, sizeof (hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
|
||||
try_again:
|
||||
host = gethostbyname(name);
|
||||
if (host == NULL) {
|
||||
if (retry && h_errno == TRY_AGAIN && retries < 10) {
|
||||
result = getaddrinfo(name, NULL, &hints, &res);
|
||||
|
||||
if (result) {
|
||||
if (retry && result == EAI_AGAIN && retries < MAXRETRIES) {
|
||||
sleep(2 << retries);
|
||||
retries++;
|
||||
res_init();
|
||||
goto try_again;
|
||||
}
|
||||
result = DNS_Failed_Address;
|
||||
} else {
|
||||
address0 = host->h_addr_list[0];
|
||||
result = ((((unsigned long)address0[0])<<24) |
|
||||
(((unsigned long)address0[1])<<16) |
|
||||
(((unsigned long)address0[2])<<8) |
|
||||
(((unsigned long)address0[3])));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
unsigned long
|
||||
DNS_Name2IPAddress(const char *name)
|
||||
{
|
||||
return Name2IPAddress(name, 0);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
unsigned long
|
||||
DNS_Name2IPAddressRetry(const char *name)
|
||||
{
|
||||
return Name2IPAddress(name, 1);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
const char *
|
||||
DNS_IPAddress2Name(unsigned long ip_addr)
|
||||
{
|
||||
struct hostent *host;
|
||||
static char buffer[16];
|
||||
unsigned int a, b, c, d;
|
||||
uint32_t addr;
|
||||
|
||||
addr = htonl(ip_addr);
|
||||
if (addr == 0UL) {
|
||||
/* Catch this as a special case that will never resolve to
|
||||
anything */
|
||||
strcpy(buffer, "0.0.0.0");
|
||||
return buffer;
|
||||
} else {
|
||||
host = gethostbyaddr((const char *) &addr, sizeof(ip_addr), AF_INET);
|
||||
if (!host) {
|
||||
a = (ip_addr >> 24) & 0xff;
|
||||
b = (ip_addr >> 16) & 0xff;
|
||||
c = (ip_addr >> 8) & 0xff;
|
||||
d = (ip_addr) & 0xff;
|
||||
snprintf(buffer, sizeof(buffer), "%u.%u.%u.%u", a, b, c, d);
|
||||
return buffer;
|
||||
} else {
|
||||
return host->h_name;
|
||||
for (ai = res; !result && ai != NULL; ai = ai->ai_next) {
|
||||
switch (ai->ai_family) {
|
||||
case AF_INET:
|
||||
addr->family = IPADDR_INET4;
|
||||
addr->addr.in4 = ntohl(((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr);
|
||||
result = 1;
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
addr->family = IPADDR_INET6;
|
||||
memcpy(&addr->addr.in6, &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr.s6_addr, sizeof (addr->addr.in6));
|
||||
result = 1;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
return result;
|
||||
#else
|
||||
struct hostent *host;
|
||||
char *address0;
|
||||
|
||||
try_again:
|
||||
host = gethostbyname(name);
|
||||
|
||||
if (host == NULL) {
|
||||
if (retry && h_errno == TRY_AGAIN && retries < MAXRETRIES) {
|
||||
sleep(2 << retries);
|
||||
retries++;
|
||||
res_init();
|
||||
goto try_again;
|
||||
}
|
||||
} else {
|
||||
addr->family = IPADDR_INET4;
|
||||
address0 = host->h_addr_list[0];
|
||||
addr->addr.in4 = ((((unsigned long)address0[0])<<24) |
|
||||
(((unsigned long)address0[1])<<16) |
|
||||
(((unsigned long)address0[2])<<8) |
|
||||
(((unsigned long)address0[3])));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
DNS_IPAddress2Name(IPAddr *ip_addr, char *name, int len)
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
int result;
|
||||
struct sockaddr_in in4;
|
||||
struct sockaddr_in6 in6;
|
||||
|
||||
switch (ip_addr->family) {
|
||||
case IPADDR_INET4:
|
||||
memset(&in4, 0, sizeof (in4));
|
||||
in4.sin_family = AF_INET;
|
||||
in4.sin_addr.s_addr = htonl(ip_addr->addr.in4);
|
||||
result = getnameinfo((const struct sockaddr *)&in4, sizeof (in4), name, len, NULL, 0, 0);
|
||||
break;
|
||||
case IPADDR_INET6:
|
||||
memset(&in6, 0, sizeof (in6));
|
||||
in6.sin6_family = AF_INET6;
|
||||
memcpy(&in6.sin6_addr.s6_addr, ip_addr->addr.in6, sizeof (in6.sin6_addr.s6_addr));
|
||||
result = getnameinfo((const struct sockaddr *)&in6, sizeof (in6), name, len, NULL, 0, 0);
|
||||
break;
|
||||
default:
|
||||
result = 1;
|
||||
}
|
||||
|
||||
if (result)
|
||||
snprintf(name, len, "%s", UTI_IPToString(ip_addr));
|
||||
#else
|
||||
struct hostent *host;
|
||||
uint32_t addr;
|
||||
|
||||
switch (ip_addr->family) {
|
||||
case IPADDR_INET4:
|
||||
addr = htonl(ip_addr->addr.in4);
|
||||
host = gethostbyaddr((const char *) &addr, sizeof (ip_addr), AF_INET);
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case IPADDR_INET6:
|
||||
host = gethostbyaddr((const void *) ip_addr->addr.in6, sizeof (ip_addr->addr.in6), AF_INET6);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
host = NULL;
|
||||
}
|
||||
snprintf(name, len, "%s", host ? host->h_name : UTI_IPToString(ip_addr));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
|
|
@ -32,13 +32,11 @@
|
|||
#ifndef GOT_NAMESERV_H
|
||||
#define GOT_NAMESERV_H
|
||||
|
||||
static const unsigned long DNS_Failed_Address = 0x0UL;
|
||||
#include "addressing.h"
|
||||
|
||||
extern unsigned long DNS_Name2IPAddress(const char *name);
|
||||
extern int DNS_Name2IPAddress(const char *name, IPAddr *addr, int retry);
|
||||
|
||||
extern unsigned long DNS_Name2IPAddressRetry(const char *name);
|
||||
|
||||
const char *DNS_IPAddress2Name(unsigned long ip_addr);
|
||||
extern void DNS_IPAddress2Name(IPAddr *ip_addr, char *name, int len);
|
||||
|
||||
#endif /* GOT_NAMESERV_H */
|
||||
|
||||
|
|
56
ntp_core.c
56
ntp_core.c
|
@ -319,7 +319,7 @@ create_instance(NTP_Remote_Address *remote_addr, NTP_Mode mode, SourceParameters
|
|||
result->local_poll = params->minpoll;
|
||||
|
||||
/* Create a source instance for this NTP source */
|
||||
result->source = SRC_CreateNewInstance(remote_addr->ip_addr, SRC_NTP);
|
||||
result->source = SRC_CreateNewInstance(UTI_IPToRefid(&remote_addr->ip_addr), SRC_NTP, &result->remote_addr.ip_addr);
|
||||
|
||||
result->local_rx.tv_sec = 0;
|
||||
result->local_rx.tv_usec = 0;
|
||||
|
@ -626,7 +626,7 @@ transmit_timeout(void *arg)
|
|||
|
||||
#ifdef TRACEON
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Transmit timeout for [%s:%d]",
|
||||
UTI_IPToDottedQuad(inst->remote_addr.ip_addr), inst->remote_addr.port);
|
||||
UTI_IPToString(&inst->remote_addr.ip_addr), inst->remote_addr.port);
|
||||
#endif
|
||||
|
||||
/* Check whether we need to 'warm up' the link to the other end by
|
||||
|
@ -1043,8 +1043,8 @@ receive_packet(NTP_Packet *message, struct timeval *now, NCR_Instance inst, int
|
|||
message->lvm, message->stratum, message->poll, message->precision);
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Root delay=%08lx (%f), dispersion=%08lx (%f)",
|
||||
message->root_delay, pkt_root_delay, message->root_dispersion, pkt_root_dispersion);
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Ref id=[%s], ref_time=%08lx.%08lx [%s]",
|
||||
UTI_IPToDottedQuad(ntohl(message->reference_id)),
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Ref id=[%lx], ref_time=%08lx.%08lx [%s]",
|
||||
ntohl(message->reference_id),
|
||||
message->reference_ts.hi, message->reference_ts.lo,
|
||||
UTI_TimestampToString(&message->reference_ts));
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Originate=%08lx.%08lx [%s]",
|
||||
|
@ -1243,7 +1243,7 @@ receive_packet(NTP_Packet *message, struct timeval *now, NCR_Instance inst, int
|
|||
inst->maxpoll = inst->minpoll;
|
||||
if (inst->minpoll > inst->local_poll)
|
||||
inst->local_poll = inst->minpoll;
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Received KoD RATE from %s, minpoll set to %d", UTI_IPToDottedQuad(inst->remote_addr.ip_addr), inst->minpoll);
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Received KoD RATE from %s, minpoll set to %d", UTI_IPToString(&inst->remote_addr.ip_addr), inst->minpoll);
|
||||
}
|
||||
/* Back off for a while */
|
||||
delay_time += (double) (4 * (1UL << inst->minpoll));
|
||||
|
@ -1268,7 +1268,7 @@ receive_packet(NTP_Packet *message, struct timeval *now, NCR_Instance inst, int
|
|||
|
||||
fprintf(logfile, "%s %-15s %1c %2d %1d%1d%1d%1d %1d%1d %1d%1d%1d%1d %2d %2d %2d %10.3e %10.3e %10.3e %10.3e %10.3e\n",
|
||||
UTI_TimeToLogForm(sample_time.tv_sec),
|
||||
UTI_IPToDottedQuad(inst->remote_addr.ip_addr),
|
||||
UTI_IPToString(&inst->remote_addr.ip_addr),
|
||||
sync_stats[pkt_leap],
|
||||
message->stratum,
|
||||
test1, test2, test3, test4,
|
||||
|
@ -1357,9 +1357,9 @@ process_known
|
|||
one of the secondaries to flywheel it. The behaviour coded here
|
||||
is required in the secondaries to make this possible. */
|
||||
|
||||
if (ADF_IsAllowed(access_auth_table, inst->remote_addr.ip_addr)) {
|
||||
if (ADF_IsAllowed(access_auth_table, &inst->remote_addr.ip_addr)) {
|
||||
|
||||
CLG_LogNTPClientAccess(inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||
CLG_LogNTPClientAccess(&inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||
|
||||
if (do_auth) {
|
||||
auth_key_id = ntohl(message->auth_keyid);
|
||||
|
@ -1392,7 +1392,7 @@ process_known
|
|||
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_NtpCore, "NTP packet received from unauthorised host %s port %d",
|
||||
UTI_IPToDottedQuad(inst->remote_addr.ip_addr),
|
||||
UTI_IPToString(&inst->remote_addr.ip_addr),
|
||||
inst->remote_addr.port);
|
||||
}
|
||||
|
||||
|
@ -1403,7 +1403,7 @@ process_known
|
|||
switch(inst->mode) {
|
||||
case MODE_ACTIVE:
|
||||
/* Ordinary symmetric peering */
|
||||
CLG_LogNTPPeerAccess(inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||
CLG_LogNTPPeerAccess(&inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||
receive_packet(message, now, inst, do_auth);
|
||||
break;
|
||||
case MODE_PASSIVE:
|
||||
|
@ -1413,7 +1413,7 @@ process_known
|
|||
case MODE_CLIENT:
|
||||
/* This is where we have the remote configured as a server and he has
|
||||
us configured as a peer - fair enough. */
|
||||
CLG_LogNTPPeerAccess(inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||
CLG_LogNTPPeerAccess(&inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||
receive_packet(message, now, inst, do_auth);
|
||||
break;
|
||||
case MODE_SERVER:
|
||||
|
@ -1434,7 +1434,7 @@ process_known
|
|||
switch(inst->mode) {
|
||||
case MODE_ACTIVE:
|
||||
/* Slightly bizarre combination, but we can still process it */
|
||||
CLG_LogNTPPeerAccess(inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||
CLG_LogNTPPeerAccess(&inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||
receive_packet(message, now, inst, do_auth);
|
||||
break;
|
||||
case MODE_PASSIVE:
|
||||
|
@ -1462,7 +1462,7 @@ process_known
|
|||
case MODE_ACTIVE:
|
||||
/* This would arise if we have the remote configured as a peer and
|
||||
he does not have us configured */
|
||||
CLG_LogNTPPeerAccess(inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||
CLG_LogNTPPeerAccess(&inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||
receive_packet(message, now, inst, do_auth);
|
||||
break;
|
||||
case MODE_PASSIVE:
|
||||
|
@ -1524,19 +1524,19 @@ NCR_ProcessNoauthUnknown(NTP_Packet *message, struct timeval *now, NTP_Remote_Ad
|
|||
NTP_Mode my_mode;
|
||||
int my_poll;
|
||||
|
||||
if (ADF_IsAllowed(access_auth_table, remote_addr->ip_addr)) {
|
||||
if (ADF_IsAllowed(access_auth_table, &remote_addr->ip_addr)) {
|
||||
|
||||
his_mode = message->lvm & 0x07;
|
||||
|
||||
if (his_mode == MODE_CLIENT) {
|
||||
/* We are server */
|
||||
my_mode = MODE_SERVER;
|
||||
CLG_LogNTPClientAccess(remote_addr->ip_addr, (time_t) now->tv_sec);
|
||||
CLG_LogNTPClientAccess(&remote_addr->ip_addr, (time_t) now->tv_sec);
|
||||
|
||||
} else if (his_mode == MODE_ACTIVE) {
|
||||
/* We are symmetric passive, even though we don't ever lock to him */
|
||||
my_mode = MODE_PASSIVE;
|
||||
CLG_LogNTPPeerAccess(remote_addr->ip_addr, (time_t) now->tv_sec);
|
||||
CLG_LogNTPPeerAccess(&remote_addr->ip_addr, (time_t) now->tv_sec);
|
||||
|
||||
} else {
|
||||
my_mode = MODE_UNDEFINED;
|
||||
|
@ -1560,7 +1560,7 @@ NCR_ProcessNoauthUnknown(NTP_Packet *message, struct timeval *now, NTP_Remote_Ad
|
|||
}
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_NtpCore, "NTP packet received from unauthorised host %s port %d",
|
||||
UTI_IPToDottedQuad(remote_addr->ip_addr),
|
||||
UTI_IPToString(&remote_addr->ip_addr),
|
||||
remote_addr->port);
|
||||
}
|
||||
|
||||
|
@ -1594,19 +1594,19 @@ NCR_ProcessAuthUnknown(NTP_Packet *message, struct timeval *now, NTP_Remote_Addr
|
|||
int valid_key, valid_auth;
|
||||
unsigned long key_id;
|
||||
|
||||
if (ADF_IsAllowed(access_auth_table, remote_addr->ip_addr)) {
|
||||
if (ADF_IsAllowed(access_auth_table, &remote_addr->ip_addr)) {
|
||||
|
||||
his_mode = message->lvm & 0x07;
|
||||
|
||||
if (his_mode == MODE_CLIENT) {
|
||||
/* We are server */
|
||||
my_mode = MODE_SERVER;
|
||||
CLG_LogNTPClientAccess(remote_addr->ip_addr, (time_t) now->tv_sec);
|
||||
CLG_LogNTPClientAccess(&remote_addr->ip_addr, (time_t) now->tv_sec);
|
||||
|
||||
} else if (his_mode == MODE_ACTIVE) {
|
||||
/* We are symmetric passive, even though we don't ever lock to him */
|
||||
my_mode = MODE_PASSIVE;
|
||||
CLG_LogNTPPeerAccess(remote_addr->ip_addr, (time_t) now->tv_sec);
|
||||
CLG_LogNTPPeerAccess(&remote_addr->ip_addr, (time_t) now->tv_sec);
|
||||
|
||||
} else {
|
||||
my_mode = MODE_UNDEFINED;
|
||||
|
@ -1678,7 +1678,7 @@ NCR_TakeSourceOnline(NCR_Instance inst)
|
|||
case MD_OFFLINE:
|
||||
if (!inst->timer_running) {
|
||||
/* We are not already actively polling it */
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s online", UTI_IPToDottedQuad(inst->remote_addr.ip_addr));
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s online", UTI_IPToString(&inst->remote_addr.ip_addr));
|
||||
inst->local_poll = inst->minpoll;
|
||||
inst->score = (ZONE_WIDTH >> 1);
|
||||
inst->opmode = MD_ONLINE;
|
||||
|
@ -1702,7 +1702,7 @@ NCR_TakeSourceOffline(NCR_Instance inst)
|
|||
switch (inst->opmode) {
|
||||
case MD_ONLINE:
|
||||
if (inst->timer_running) {
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s offline", UTI_IPToDottedQuad(inst->remote_addr.ip_addr));
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s offline", UTI_IPToString(&inst->remote_addr.ip_addr));
|
||||
SCH_RemoveTimeout(inst->timeout_id);
|
||||
inst->timer_running = 0;
|
||||
inst->opmode = MD_OFFLINE;
|
||||
|
@ -1725,7 +1725,7 @@ void
|
|||
NCR_ModifyMinpoll(NCR_Instance inst, int new_minpoll)
|
||||
{
|
||||
inst->minpoll = new_minpoll;
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new minpoll %d", UTI_IPToDottedQuad(inst->remote_addr.ip_addr), new_minpoll);
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new minpoll %d", UTI_IPToString(&inst->remote_addr.ip_addr), new_minpoll);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -1734,7 +1734,7 @@ void
|
|||
NCR_ModifyMaxpoll(NCR_Instance inst, int new_maxpoll)
|
||||
{
|
||||
inst->maxpoll = new_maxpoll;
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new maxpoll %d", UTI_IPToDottedQuad(inst->remote_addr.ip_addr), new_maxpoll);
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new maxpoll %d", UTI_IPToString(&inst->remote_addr.ip_addr), new_maxpoll);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -1744,7 +1744,7 @@ NCR_ModifyMaxdelay(NCR_Instance inst, double new_max_delay)
|
|||
{
|
||||
inst->max_delay = new_max_delay;
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new max delay %f",
|
||||
UTI_IPToDottedQuad(inst->remote_addr.ip_addr), new_max_delay);
|
||||
UTI_IPToString(&inst->remote_addr.ip_addr), new_max_delay);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -1754,7 +1754,7 @@ NCR_ModifyMaxdelayratio(NCR_Instance inst, double new_max_delay_ratio)
|
|||
{
|
||||
inst->max_delay_ratio = new_max_delay_ratio;
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new max delay ratio %f",
|
||||
UTI_IPToDottedQuad(inst->remote_addr.ip_addr), new_max_delay_ratio);
|
||||
UTI_IPToString(&inst->remote_addr.ip_addr), new_max_delay_ratio);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -1836,7 +1836,7 @@ NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timeval *no
|
|||
/* ================================================== */
|
||||
|
||||
int
|
||||
NCR_AddAccessRestriction(unsigned long ip_addr, int subnet_bits, int allow, int all)
|
||||
NCR_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all)
|
||||
{
|
||||
ADF_Status status;
|
||||
|
||||
|
@ -1866,7 +1866,7 @@ NCR_AddAccessRestriction(unsigned long ip_addr, int subnet_bits, int allow, int
|
|||
/* ================================================== */
|
||||
|
||||
int
|
||||
NCR_CheckAccessRestriction(unsigned long ip_addr)
|
||||
NCR_CheckAccessRestriction(IPAddr *ip_addr)
|
||||
{
|
||||
return ADF_IsAllowed(access_auth_table, ip_addr);
|
||||
}
|
||||
|
|
|
@ -94,8 +94,8 @@ extern void NCR_InitiateSampleBurst(NCR_Instance inst, int n_good_samples, int n
|
|||
|
||||
extern void NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timeval *now);
|
||||
|
||||
extern int NCR_AddAccessRestriction(unsigned long ip_addr, int subnet_bits, int allow, int all);
|
||||
extern int NCR_CheckAccessRestriction(unsigned long ip_addr);
|
||||
extern int NCR_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all);
|
||||
extern int NCR_CheckAccessRestriction(IPAddr *ip_addr);
|
||||
|
||||
extern void NCR_CycleLogFile(void);
|
||||
|
||||
|
|
204
ntp_io.c
204
ntp_io.c
|
@ -41,8 +41,19 @@
|
|||
|
||||
#include <fcntl.h>
|
||||
|
||||
/* The file descriptor for the socket */
|
||||
static int sock_fd;
|
||||
union sockaddr_in46 {
|
||||
struct sockaddr_in in4;
|
||||
#ifdef HAVE_IPV6
|
||||
struct sockaddr_in6 in6;
|
||||
#endif
|
||||
struct sockaddr u;
|
||||
};
|
||||
|
||||
/* The file descriptors for the IPv4 and IPv6 sockets */
|
||||
static int sock_fd4;
|
||||
#ifdef HAVE_IPV6
|
||||
static int sock_fd6;
|
||||
#endif
|
||||
|
||||
/* Flag indicating that we have been initialised */
|
||||
static int initialised=0;
|
||||
|
@ -50,6 +61,7 @@ static int initialised=0;
|
|||
/* ================================================== */
|
||||
|
||||
/* Forward prototypes */
|
||||
static int prepare_socket(int family);
|
||||
static void read_from_socket(void *anything);
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -81,30 +93,28 @@ do_size_checks(void)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
NIO_Initialise(void)
|
||||
static int
|
||||
prepare_socket(int family)
|
||||
{
|
||||
struct sockaddr_in my_addr;
|
||||
union sockaddr_in46 my_addr;
|
||||
int sock_fd;
|
||||
unsigned short port_number;
|
||||
unsigned long bind_address;
|
||||
IPAddr bind_address;
|
||||
int on_off = 1;
|
||||
|
||||
assert(!initialised);
|
||||
initialised = 1;
|
||||
|
||||
do_size_checks();
|
||||
|
||||
port_number = CNF_GetNTPPort();
|
||||
|
||||
/* Open Internet domain UDP socket for NTP message transmissions */
|
||||
|
||||
#if 0
|
||||
sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
sock_fd = socket(family, SOCK_DGRAM, IPPROTO_UDP);
|
||||
#else
|
||||
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
sock_fd = socket(family, SOCK_DGRAM, 0);
|
||||
#endif
|
||||
|
||||
if (sock_fd < 0) {
|
||||
LOG_FATAL(LOGF_NtpIO, "Could not open socket : %s", strerror(errno));
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not open socket : %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Make the socket capable of re-using an old address */
|
||||
|
@ -125,34 +135,67 @@ NIO_Initialise(void)
|
|||
/* Don't quit - we might survive anyway */
|
||||
}
|
||||
|
||||
/* We want the local IP info too */
|
||||
if (setsockopt(sock_fd, IPPROTO_IP, IP_PKTINFO, (char *)&on_off, sizeof(on_off)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not request packet info using socket option");
|
||||
/* Don't quit - we might survive anyway */
|
||||
if (family == AF_INET) {
|
||||
/* We want the local IP info too */
|
||||
if (setsockopt(sock_fd, IPPROTO_IP, IP_PKTINFO, (char *)&on_off, sizeof(on_off)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not request packet info using socket option");
|
||||
/* Don't quit - we might survive anyway */
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if (family == AF_INET6) {
|
||||
#ifdef IPV6_V6ONLY
|
||||
/* Receive IPv6 packets only */
|
||||
if (setsockopt(sock_fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on_off, sizeof(on_off)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not request IPV6_V6ONLY socket option");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Bind the port */
|
||||
my_addr.sin_family = AF_INET;
|
||||
my_addr.sin_port = htons(port_number);
|
||||
memset(&my_addr, 0, sizeof (my_addr));
|
||||
|
||||
CNF_GetBindAddress(&bind_address);
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
my_addr.in4.sin_family = family;
|
||||
my_addr.in4.sin_port = htons(port_number);
|
||||
|
||||
if (bind_address != 0UL) {
|
||||
my_addr.sin_addr.s_addr = htonl(bind_address);
|
||||
} else {
|
||||
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
CNF_GetBindAddress(IPADDR_INET4, &bind_address);
|
||||
|
||||
if (bind_address.family == IPADDR_INET4)
|
||||
my_addr.in4.sin_addr.s_addr = htonl(bind_address.addr.in4);
|
||||
else
|
||||
my_addr.in4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
my_addr.in6.sin6_family = family;
|
||||
my_addr.in6.sin6_port = htons(port_number);
|
||||
|
||||
CNF_GetBindAddress(IPADDR_INET6, &bind_address);
|
||||
|
||||
if (bind_address.family == IPADDR_INET6)
|
||||
memcpy(my_addr.in6.sin6_addr.s6_addr, bind_address.addr.in6,
|
||||
sizeof (my_addr.in6.sin6_addr.s6_addr));
|
||||
else
|
||||
my_addr.in6.sin6_addr = in6addr_any;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_NtpIO, "Initialising, socket fd=%d", sock_fd);
|
||||
#endif
|
||||
|
||||
if (bind(sock_fd, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) {
|
||||
if (bind(sock_fd, &my_addr.u, sizeof(my_addr)) < 0) {
|
||||
LOG_FATAL(LOGF_NtpIO, "Could not bind socket : %s", strerror(errno));
|
||||
}
|
||||
|
||||
/* Register handler for read events on the socket */
|
||||
SCH_AddInputFileHandler(sock_fd, read_from_socket, NULL);
|
||||
SCH_AddInputFileHandler(sock_fd, read_from_socket, (void *)(long)sock_fd);
|
||||
|
||||
#if 0
|
||||
if (fcntl(sock_fd, F_SETFL, O_NONBLOCK | O_NDELAY) < 0) {
|
||||
|
@ -163,6 +206,29 @@ NIO_Initialise(void)
|
|||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not enable signal");
|
||||
}
|
||||
#endif
|
||||
return sock_fd;
|
||||
}
|
||||
|
||||
void
|
||||
NIO_Initialise(void)
|
||||
{
|
||||
assert(!initialised);
|
||||
initialised = 1;
|
||||
|
||||
do_size_checks();
|
||||
|
||||
sock_fd4 = prepare_socket(AF_INET);
|
||||
#ifdef HAVE_IPV6
|
||||
sock_fd6 = prepare_socket(AF_INET6);
|
||||
#endif
|
||||
|
||||
if (sock_fd4 < 0
|
||||
#ifdef HAVE_IPV6
|
||||
&& sock_fd6 < 0
|
||||
#endif
|
||||
) {
|
||||
LOG_FATAL(LOGF_NtpIO, "Could not open any NTP socket");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -172,11 +238,18 @@ NIO_Initialise(void)
|
|||
void
|
||||
NIO_Finalise(void)
|
||||
{
|
||||
if (sock_fd >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd);
|
||||
close(sock_fd);
|
||||
if (sock_fd4 >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd4);
|
||||
close(sock_fd4);
|
||||
}
|
||||
sock_fd = -1;
|
||||
sock_fd4 = -1;
|
||||
#ifdef HAVE_IPV6
|
||||
if (sock_fd6 >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd6);
|
||||
close(sock_fd6);
|
||||
}
|
||||
sock_fd6 = -1;
|
||||
#endif
|
||||
initialised = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -192,9 +265,9 @@ read_from_socket(void *anything)
|
|||
/* This should only be called when there is something
|
||||
to read, otherwise it will block. */
|
||||
|
||||
int status;
|
||||
int status, sock_fd;
|
||||
ReceiveBuffer message;
|
||||
struct sockaddr_in where_from;
|
||||
union sockaddr_in46 where_from;
|
||||
unsigned int flags = 0;
|
||||
struct timeval now;
|
||||
NTP_Remote_Address remote_addr;
|
||||
|
@ -218,6 +291,7 @@ read_from_socket(void *anything)
|
|||
msg.msg_controllen = sizeof(cmsgbuf);
|
||||
msg.msg_flags = 0;
|
||||
|
||||
sock_fd = (long)anything;
|
||||
status = recvmsg(sock_fd, &msg, flags);
|
||||
|
||||
/* Don't bother checking if read failed or why if it did. More
|
||||
|
@ -228,16 +302,33 @@ read_from_socket(void *anything)
|
|||
reponse on a subsequent recvfrom). */
|
||||
|
||||
if (status > 0) {
|
||||
remote_addr.ip_addr = ntohl(where_from.sin_addr.s_addr);
|
||||
remote_addr.local_ip_addr = 0;
|
||||
remote_addr.port = ntohs(where_from.sin_port);
|
||||
memset(&remote_addr, 0, sizeof (remote_addr));
|
||||
|
||||
switch (where_from.u.sa_family) {
|
||||
case AF_INET:
|
||||
remote_addr.ip_addr.family = IPADDR_INET4;
|
||||
remote_addr.ip_addr.addr.in4 = ntohl(where_from.in4.sin_addr.s_addr);
|
||||
remote_addr.port = ntohs(where_from.in4.sin_port);
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
remote_addr.ip_addr.family = IPADDR_INET6;
|
||||
memcpy(&remote_addr.ip_addr.addr.in6, where_from.in6.sin6_addr.s6_addr,
|
||||
sizeof (remote_addr.ip_addr.addr.in6));
|
||||
remote_addr.port = ntohs(where_from.in6.sin6_port);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
|
||||
struct in_pktinfo ipi;
|
||||
|
||||
memcpy(&ipi, CMSG_DATA(cmsg), sizeof(ipi));
|
||||
remote_addr.local_ip_addr = ntohl(ipi.ipi_spec_dst.s_addr);
|
||||
remote_addr.local_ip_addr.addr.in4 = ntohl(ipi.ipi_spec_dst.s_addr);
|
||||
remote_addr.local_ip_addr.family = IPADDR_INET4;
|
||||
}
|
||||
|
||||
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) {
|
||||
|
@ -279,22 +370,43 @@ read_from_socket(void *anything)
|
|||
static void
|
||||
send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr)
|
||||
{
|
||||
struct sockaddr_in remote;
|
||||
union sockaddr_in46 remote;
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
struct cmsghdr *cmsg;
|
||||
char cmsgbuf[256];
|
||||
int cmsglen;
|
||||
int sock_fd;
|
||||
|
||||
assert(initialised);
|
||||
|
||||
remote.sin_family = AF_INET;
|
||||
remote.sin_port = htons(remote_addr->port);
|
||||
remote.sin_addr.s_addr = htonl(remote_addr->ip_addr);
|
||||
memset(&remote, 0, sizeof (remote));
|
||||
switch (remote_addr->ip_addr.family) {
|
||||
case IPADDR_INET4:
|
||||
remote.in4.sin_family = AF_INET;
|
||||
remote.in4.sin_port = htons(remote_addr->port);
|
||||
remote.in4.sin_addr.s_addr = htonl(remote_addr->ip_addr.addr.in4);
|
||||
sock_fd = sock_fd4;
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case IPADDR_INET6:
|
||||
remote.in6.sin6_family = AF_INET6;
|
||||
remote.in6.sin6_port = htons(remote_addr->port);
|
||||
memcpy(&remote.in6.sin6_addr.s6_addr, &remote_addr->ip_addr.addr.in6,
|
||||
sizeof (remote.in6.sin6_addr.s6_addr));
|
||||
sock_fd = sock_fd6;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (sock_fd < 0)
|
||||
return;
|
||||
|
||||
iov.iov_base = packet;
|
||||
iov.iov_len = packetlen;
|
||||
msg.msg_name = &remote;
|
||||
msg.msg_name = &remote.u;
|
||||
msg.msg_namelen = sizeof(remote);
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
|
@ -303,7 +415,7 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr)
|
|||
msg.msg_flags = 0;
|
||||
cmsglen = 0;
|
||||
|
||||
if (remote_addr->local_ip_addr) {
|
||||
if (remote_addr->local_ip_addr.family == IPADDR_INET4) {
|
||||
struct in_pktinfo *ipi;
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
|
@ -315,10 +427,10 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr)
|
|||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
|
||||
|
||||
ipi = (struct in_pktinfo *) CMSG_DATA(cmsg);
|
||||
ipi->ipi_spec_dst.s_addr = htonl(remote_addr->local_ip_addr);
|
||||
ipi->ipi_spec_dst.s_addr = htonl(remote_addr->local_ip_addr.addr.in4);
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_NtpIO, "sending to %s:%d from %s",
|
||||
UTI_IPToDottedQuad(remote_addr->ip_addr), remote_addr->port, UTI_IPToDottedQuad(remote_addr->local_ip_addr));
|
||||
UTI_IPToString(&remote_addr->ip_addr), remote_addr->port, UTI_IPToString(&remote_addr->local_ip_addr));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -326,7 +438,7 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr)
|
|||
|
||||
if (sendmsg(sock_fd, &msg, 0) < 0) {
|
||||
LOG(LOGS_WARN, LOGF_NtpIO, "Could not send to %s:%d : %s",
|
||||
UTI_IPToDottedQuad(remote_addr->ip_addr), remote_addr->port, strerror(errno));
|
||||
UTI_IPToString(&remote_addr->ip_addr), remote_addr->port, strerror(errno));
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
|
@ -120,17 +120,36 @@ static void
|
|||
find_slot(NTP_Remote_Address *remote_addr, int *slot, int *found)
|
||||
{
|
||||
unsigned long hash;
|
||||
unsigned long ip = remote_addr->ip_addr;
|
||||
unsigned short port = remote_addr->port;
|
||||
unsigned long ip;
|
||||
unsigned short port;
|
||||
uint8_t *ip6;
|
||||
|
||||
assert(N_RECORDS == 256);
|
||||
|
||||
switch (remote_addr->ip_addr.family) {
|
||||
case IPADDR_INET6:
|
||||
ip6 = remote_addr->ip_addr.addr.in6;
|
||||
ip = (ip6[0] ^ ip6[4] ^ ip6[8] ^ ip6[12]) |
|
||||
(ip6[1] ^ ip6[5] ^ ip6[9] ^ ip6[13]) << 8 |
|
||||
(ip6[2] ^ ip6[6] ^ ip6[10] ^ ip6[14]) << 16 |
|
||||
(ip6[3] ^ ip6[7] ^ ip6[11] ^ ip6[15]) << 24;
|
||||
break;
|
||||
case IPADDR_INET4:
|
||||
ip = remote_addr->ip_addr.addr.in4;
|
||||
break;
|
||||
default:
|
||||
*found = *slot = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
port = remote_addr->port;
|
||||
/* Compute hash value just by xor'ing the 4 bytes of the address together */
|
||||
hash = ip ^ (ip >> 16);
|
||||
hash = (hash ^ (hash >> 8)) & 0xff;
|
||||
|
||||
while ((records[hash].in_use) &&
|
||||
(records[hash].remote_addr.ip_addr != ip)) {
|
||||
UTI_CompareIPs(&records[hash].remote_addr.ip_addr,
|
||||
&remote_addr->ip_addr, NULL)) {
|
||||
hash++;
|
||||
if (hash == 256) hash = 0;
|
||||
}
|
||||
|
@ -162,7 +181,7 @@ NSR_AddServer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
|||
assert(initialised);
|
||||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_NtpSources, "IP=%08lx port=%d", (unsigned long)remote_addr->ip_addr, remote_addr->port);
|
||||
LOG(LOGS_INFO, LOGF_NtpSources, "IP=%s port=%d", UTI_IPToString(&remote_addr->ip_addr), remote_addr->port);
|
||||
#endif
|
||||
|
||||
/* Find empty bin & check that we don't have the address already */
|
||||
|
@ -172,6 +191,9 @@ NSR_AddServer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
|||
} else {
|
||||
if (n_sources == MAX_SOURCES) {
|
||||
return NSR_TooManySources;
|
||||
} else if (remote_addr->ip_addr.family != IPADDR_INET4 &&
|
||||
remote_addr->ip_addr.family != IPADDR_INET6) {
|
||||
return NSR_InvalidAF;
|
||||
} else {
|
||||
n_sources++;
|
||||
records[slot].remote_addr = *remote_addr;
|
||||
|
@ -193,7 +215,7 @@ NSR_AddPeer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
|||
assert(initialised);
|
||||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_NtpSources, "IP=%08lx port=%d", (unsigned long) remote_addr->ip_addr, remote_addr->port);
|
||||
LOG(LOGS_INFO, LOGF_NtpSources, "IP=%s port=%d", UTI_IPToString(&remote_addr->ip_addr), remote_addr->port);
|
||||
#endif
|
||||
|
||||
/* Find empty bin & check that we don't have the address already */
|
||||
|
@ -203,6 +225,9 @@ NSR_AddPeer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
|||
} else {
|
||||
if (n_sources == MAX_SOURCES) {
|
||||
return NSR_TooManySources;
|
||||
} else if (remote_addr->ip_addr.family != IPADDR_INET4 &&
|
||||
remote_addr->ip_addr.family != IPADDR_INET6) {
|
||||
return NSR_InvalidAF;
|
||||
} else {
|
||||
n_sources++;
|
||||
records[slot].remote_addr = *remote_addr;
|
||||
|
@ -249,7 +274,7 @@ NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, NTP_Remote_Address
|
|||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_NtpSources, "from (%s,%d) at %s",
|
||||
UTI_IPToDottedQuad(remote_addr->ip_addr),
|
||||
UTI_IPToString(&remote_addr->ip_addr),
|
||||
remote_addr->port, UTI_TimevalToString(now));
|
||||
#endif
|
||||
|
||||
|
@ -296,7 +321,7 @@ slew_sources(struct timeval *raw,
|
|||
if (records[i].in_use) {
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_Sources, "IP=%s dfreq=%f doff=%f",
|
||||
UTI_IPToDottedQuad(records[i].remote_addr.ip_addr), dfreq, doffset);
|
||||
UTI_IPToString(&records[i].remote_addr.ip_addr), dfreq, doffset);
|
||||
#endif
|
||||
|
||||
NCR_SlewTimes(records[i].data, cooked, dfreq, doffset);
|
||||
|
@ -308,17 +333,16 @@ slew_sources(struct timeval *raw,
|
|||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_TakeSourcesOnline(unsigned long mask, unsigned long address)
|
||||
NSR_TakeSourcesOnline(IPAddr *mask, IPAddr *address)
|
||||
{
|
||||
int i;
|
||||
int any;
|
||||
unsigned long ip;
|
||||
|
||||
any = 0;
|
||||
for (i=0; i<N_RECORDS; i++) {
|
||||
if (records[i].in_use) {
|
||||
ip = records[i].remote_addr.ip_addr;
|
||||
if ((ip & mask) == address) {
|
||||
if (address->family == IPADDR_UNSPEC ||
|
||||
!UTI_CompareIPs(&records[i].remote_addr.ip_addr, address, mask)) {
|
||||
any = 1;
|
||||
NCR_TakeSourceOnline(records[i].data);
|
||||
}
|
||||
|
@ -331,17 +355,16 @@ NSR_TakeSourcesOnline(unsigned long mask, unsigned long address)
|
|||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_TakeSourcesOffline(unsigned long mask, unsigned long address)
|
||||
NSR_TakeSourcesOffline(IPAddr *mask, IPAddr *address)
|
||||
{
|
||||
int i;
|
||||
int any;
|
||||
unsigned long ip;
|
||||
|
||||
any = 0;
|
||||
for (i=0; i<N_RECORDS; i++) {
|
||||
if (records[i].in_use) {
|
||||
ip = records[i].remote_addr.ip_addr;
|
||||
if ((ip & mask) == address) {
|
||||
if (address->family == IPADDR_UNSPEC ||
|
||||
!UTI_CompareIPs(&records[i].remote_addr.ip_addr, address, mask)) {
|
||||
any = 1;
|
||||
NCR_TakeSourceOffline(records[i].data);
|
||||
}
|
||||
|
@ -354,11 +377,11 @@ NSR_TakeSourcesOffline(unsigned long mask, unsigned long address)
|
|||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_ModifyMinpoll(unsigned long address, int new_minpoll)
|
||||
NSR_ModifyMinpoll(IPAddr *address, int new_minpoll)
|
||||
{
|
||||
int slot, found;
|
||||
NTP_Remote_Address addr;
|
||||
addr.ip_addr = address;
|
||||
addr.ip_addr = *address;
|
||||
addr.port = 0;
|
||||
|
||||
find_slot(&addr, &slot, &found);
|
||||
|
@ -373,11 +396,11 @@ NSR_ModifyMinpoll(unsigned long address, int new_minpoll)
|
|||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_ModifyMaxpoll(unsigned long address, int new_maxpoll)
|
||||
NSR_ModifyMaxpoll(IPAddr *address, int new_maxpoll)
|
||||
{
|
||||
int slot, found;
|
||||
NTP_Remote_Address addr;
|
||||
addr.ip_addr = address;
|
||||
addr.ip_addr = *address;
|
||||
addr.port = 0;
|
||||
|
||||
find_slot(&addr, &slot, &found);
|
||||
|
@ -392,11 +415,11 @@ NSR_ModifyMaxpoll(unsigned long address, int new_maxpoll)
|
|||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_ModifyMaxdelay(unsigned long address, double new_max_delay)
|
||||
NSR_ModifyMaxdelay(IPAddr *address, double new_max_delay)
|
||||
{
|
||||
int slot, found;
|
||||
NTP_Remote_Address addr;
|
||||
addr.ip_addr = address;
|
||||
addr.ip_addr = *address;
|
||||
addr.port = 0;
|
||||
|
||||
find_slot(&addr, &slot, &found);
|
||||
|
@ -411,11 +434,11 @@ NSR_ModifyMaxdelay(unsigned long address, double new_max_delay)
|
|||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_ModifyMaxdelayratio(unsigned long address, double new_max_delay_ratio)
|
||||
NSR_ModifyMaxdelayratio(IPAddr *address, double new_max_delay_ratio)
|
||||
{
|
||||
int slot, found;
|
||||
NTP_Remote_Address addr;
|
||||
addr.ip_addr = address;
|
||||
addr.ip_addr = *address;
|
||||
addr.port = 0;
|
||||
|
||||
find_slot(&addr, &slot, &found);
|
||||
|
@ -431,17 +454,16 @@ NSR_ModifyMaxdelayratio(unsigned long address, double new_max_delay_ratio)
|
|||
|
||||
int
|
||||
NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples,
|
||||
unsigned long mask, unsigned long address)
|
||||
IPAddr *mask, IPAddr *address)
|
||||
{
|
||||
int i;
|
||||
int any;
|
||||
unsigned long ip;
|
||||
|
||||
any = 0;
|
||||
for (i=0; i<N_RECORDS; i++) {
|
||||
if (records[i].in_use) {
|
||||
ip = records[i].remote_addr.ip_addr;
|
||||
if ((ip & mask) == address) {
|
||||
if (address->family == IPADDR_UNSPEC ||
|
||||
!UTI_CompareIPs(&records[i].remote_addr.ip_addr, address, mask)) {
|
||||
any = 1;
|
||||
NCR_InitiateSampleBurst(records[i].data, n_good_samples, n_total_samples);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,8 @@ typedef enum {
|
|||
NSR_Success, /* Operation successful */
|
||||
NSR_NoSuchSource, /* Remove - attempt to remove a source that is not known */
|
||||
NSR_AlreadyInUse, /* AddServer, AddPeer - attempt to add a source that is already known */
|
||||
NSR_TooManySources /* AddServer, AddPeer - too many sources already present */
|
||||
NSR_TooManySources, /* AddServer, AddPeer - too many sources already present */
|
||||
NSR_InvalidAF /* AddServer, AddPeer - attempt to add a source with invalid address family */
|
||||
} NSR_Status;
|
||||
|
||||
/* Procedure to add a new server source (to which this machine will be
|
||||
|
@ -75,22 +76,22 @@ extern void NSR_Finalise(void);
|
|||
/* This routine is used to indicate that sources whose IP addresses
|
||||
match a particular subnet should be set online again. Returns a
|
||||
flag indicating whether any hosts matched the address */
|
||||
extern int NSR_TakeSourcesOnline(unsigned long mask, unsigned long address);
|
||||
extern int NSR_TakeSourcesOnline(IPAddr *mask, IPAddr *address);
|
||||
|
||||
/* This routine is used to indicate that sources whose IP addresses
|
||||
match a particular subnet should be set offline. Returns a flag
|
||||
indicating whether any hosts matched the address */
|
||||
extern int NSR_TakeSourcesOffline(unsigned long mask, unsigned long address);
|
||||
extern int NSR_TakeSourcesOffline(IPAddr *mask, IPAddr *address);
|
||||
|
||||
extern int NSR_ModifyMinpoll(unsigned long address, int new_minpoll);
|
||||
extern int NSR_ModifyMinpoll(IPAddr *address, int new_minpoll);
|
||||
|
||||
extern int NSR_ModifyMaxpoll(unsigned long address, int new_maxpoll);
|
||||
extern int NSR_ModifyMaxpoll(IPAddr *address, int new_maxpoll);
|
||||
|
||||
extern int NSR_ModifyMaxdelay(unsigned long address, double new_max_delay);
|
||||
extern int NSR_ModifyMaxdelay(IPAddr *address, double new_max_delay);
|
||||
|
||||
extern int NSR_ModifyMaxdelayratio(unsigned long address, double new_max_delay_ratio);
|
||||
extern int NSR_ModifyMaxdelayratio(IPAddr *address, double new_max_delay_ratio);
|
||||
|
||||
extern int NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples, unsigned long mask, unsigned long address);
|
||||
extern int NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples, IPAddr *mask, IPAddr *address);
|
||||
|
||||
extern void NSR_ReportSource(RPT_SourceReport *report, struct timeval *now);
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@ RCL_StartRefclocks(void)
|
|||
for (i = 0; i < n_sources; i++) {
|
||||
RCL_Instance inst = &refclocks[i];
|
||||
|
||||
inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK);
|
||||
inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK, NULL);
|
||||
inst->timeout_id = SCH_AddTimeoutByDelay(0.0, poll_timeout, (void *)inst);
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,8 @@ RCL_ReportSource(RPT_SourceReport *report, struct timeval *now)
|
|||
int i;
|
||||
unsigned long ref_id;
|
||||
|
||||
ref_id = report->ip_addr;
|
||||
assert(report->ip_addr.family == IPADDR_INET4);
|
||||
ref_id = report->ip_addr.addr.in4;
|
||||
|
||||
for (i = 0; i < n_sources; i++) {
|
||||
RCL_Instance inst = &refclocks[i];
|
||||
|
|
|
@ -32,11 +32,12 @@
|
|||
#define GOT_REPORTS_H
|
||||
|
||||
#include "sysincl.h"
|
||||
#include "addressing.h"
|
||||
|
||||
#define REPORT_INVALID_OFFSET 0x80000000
|
||||
|
||||
typedef struct {
|
||||
unsigned long ip_addr;
|
||||
IPAddr ip_addr;
|
||||
int stratum;
|
||||
int poll;
|
||||
enum {RPT_NTP_CLIENT, RPT_NTP_PEER, RPT_LOCAL_REFERENCE} mode;
|
||||
|
@ -65,7 +66,7 @@ typedef struct {
|
|||
} RPT_TrackingReport;
|
||||
|
||||
typedef struct {
|
||||
unsigned long ip_addr;
|
||||
IPAddr ip_addr;
|
||||
unsigned long n_samples;
|
||||
unsigned long n_runs;
|
||||
unsigned long span_seconds;
|
||||
|
@ -94,7 +95,7 @@ typedef struct {
|
|||
} RPT_ClientAccess_Report;
|
||||
|
||||
typedef struct {
|
||||
unsigned long ip_addr;
|
||||
IPAddr ip_addr;
|
||||
unsigned long client_hits;
|
||||
unsigned long peer_hits;
|
||||
unsigned long cmd_hits_auth;
|
||||
|
|
22
sources.c
22
sources.c
|
@ -88,6 +88,7 @@ struct SRC_Instance_Record {
|
|||
unsigned long ref_id; /* The reference ID of this source
|
||||
(i.e. its IP address, NOT the
|
||||
reference _it_ is sync'd to) */
|
||||
IPAddr *ip_addr; /* Its IP address if NTP source */
|
||||
|
||||
/* Flag indicating that we are receiving packets with valid headers
|
||||
from this source and can use it as a reference */
|
||||
|
@ -160,7 +161,7 @@ void SRC_Finalise(void)
|
|||
/* Function to create a new instance. This would be called by one of
|
||||
the individual source-type instance creation routines. */
|
||||
|
||||
SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type)
|
||||
SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, IPAddr *addr)
|
||||
{
|
||||
SRC_Instance result;
|
||||
|
||||
|
@ -189,6 +190,7 @@ SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type)
|
|||
result->index = n_sources;
|
||||
result->leap_status = LEAP_Normal;
|
||||
result->ref_id = ref_id;
|
||||
result->ip_addr = addr;
|
||||
result->reachable = 0;
|
||||
result->status = SRC_BAD_STATS;
|
||||
result->type = type;
|
||||
|
@ -362,7 +364,7 @@ source_to_string(SRC_Instance inst)
|
|||
{
|
||||
switch (inst->type) {
|
||||
case SRC_NTP:
|
||||
return UTI_IPToDottedQuad(inst->ref_id);
|
||||
return UTI_IPToString(inst->ip_addr);
|
||||
case SRC_REFCLOCK:
|
||||
return UTI_RefidToString(inst->ref_id);
|
||||
default:
|
||||
|
@ -912,7 +914,16 @@ SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
|
|||
return 0;
|
||||
} else {
|
||||
src = sources[index];
|
||||
report->ip_addr = src->ref_id;
|
||||
|
||||
memset(&report->ip_addr, 0, sizeof (report->ip_addr));
|
||||
if (src->ip_addr)
|
||||
report->ip_addr = *src->ip_addr;
|
||||
else {
|
||||
/* Use refid as an address */
|
||||
report->ip_addr.addr.in4 = src->ref_id;
|
||||
report->ip_addr.family = IPADDR_INET4;
|
||||
}
|
||||
|
||||
switch (src->status) {
|
||||
case SRC_SYNC:
|
||||
report->state = RPT_SYNC;
|
||||
|
@ -949,7 +960,10 @@ SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report)
|
|||
return 0;
|
||||
} else {
|
||||
src = sources[index];
|
||||
report->ip_addr = src->ref_id;
|
||||
if (src->ip_addr)
|
||||
report->ip_addr = *src->ip_addr;
|
||||
else
|
||||
report->ip_addr.family = IPADDR_UNSPEC;
|
||||
SST_DoSourcestatsReport(src->stats, report);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ typedef enum {
|
|||
/* Function to create a new instance. This would be called by one of
|
||||
the individual source-type instance creation routines. */
|
||||
|
||||
extern SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type);
|
||||
extern SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, IPAddr *addr);
|
||||
|
||||
/* Function to get rid of a source when it is being unconfigured.
|
||||
This may cause the current reference source to be reselected, if this
|
||||
|
|
|
@ -79,6 +79,11 @@
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
/* For inet_ntop() */
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#if defined (SOLARIS) || defined(SUNOS)
|
||||
/* Only needed on these platforms, and doesn't exist on some Linux
|
||||
versions. */
|
||||
|
|
164
util.c
164
util.c
|
@ -31,6 +31,7 @@
|
|||
#include "sysincl.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "md5.h"
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
|
@ -271,6 +272,169 @@ UTI_IPToDottedQuad(unsigned long ip)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
char *
|
||||
UTI_IPToString(IPAddr *addr)
|
||||
{
|
||||
unsigned long a, b, c, d, ip;
|
||||
uint8_t *ip6;
|
||||
char *result;
|
||||
|
||||
result = NEXT_BUFFER;
|
||||
switch (addr->family) {
|
||||
case IPADDR_UNSPEC:
|
||||
snprintf(result, BUFFER_LENGTH, "[UNSPEC]");
|
||||
break;
|
||||
case IPADDR_INET4:
|
||||
ip = addr->addr.in4;
|
||||
a = (ip>>24) & 0xff;
|
||||
b = (ip>>16) & 0xff;
|
||||
c = (ip>> 8) & 0xff;
|
||||
d = (ip>> 0) & 0xff;
|
||||
snprintf(result, BUFFER_LENGTH, "%ld.%ld.%ld.%ld", a, b, c, d);
|
||||
break;
|
||||
case IPADDR_INET6:
|
||||
ip6 = addr->addr.in6;
|
||||
#ifdef HAVE_IPV6
|
||||
inet_ntop(AF_INET6, ip6, result, BUFFER_LENGTH);
|
||||
#else
|
||||
snprintf(result, BUFFER_LENGTH, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
|
||||
ip6[0], ip6[1], ip6[2], ip6[3], ip6[4], ip6[5], ip6[6], ip6[7],
|
||||
ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
snprintf(result, BUFFER_LENGTH, "[UNKNOWN]");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
UTI_StringToIP(const char *addr, IPAddr *ip)
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
struct in_addr in4;
|
||||
struct in6_addr in6;
|
||||
|
||||
if (inet_pton(AF_INET, addr, &in4) > 0) {
|
||||
ip->family = IPADDR_INET4;
|
||||
ip->addr.in4 = ntohl(in4.s_addr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (inet_pton(AF_INET6, addr, &in6) > 0) {
|
||||
ip->family = IPADDR_INET6;
|
||||
memcpy(ip->addr.in6, in6.s6_addr, sizeof (ip->addr.in6));
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
unsigned long a, b, c, d, n;
|
||||
|
||||
n = sscanf(addr, "%lu.%lu.%lu.%lu", &a, &b, &c, &d);
|
||||
if (n == 4) {
|
||||
ip->family = IPADDR_INET4;
|
||||
ip->addr.in4 = ((a & 0xff) << 24) | ((b & 0xff) << 16) |
|
||||
((c & 0xff) << 8) | (d & 0xff);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
unsigned long
|
||||
UTI_IPToRefid(IPAddr *ip)
|
||||
{
|
||||
MD5_CTX ctx;
|
||||
|
||||
switch (ip->family) {
|
||||
case IPADDR_INET4:
|
||||
return ip->addr.in4;
|
||||
case IPADDR_INET6:
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, (unsigned const char *) ip->addr.in6, sizeof (ip->addr.in6));
|
||||
MD5Final(&ctx);
|
||||
return ctx.digest[0] << 24 | ctx.digest[1] << 16 | ctx.digest[2] << 8 | ctx.digest[3];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
UTI_IPHostToNetwork(IPAddr *src, IPAddr *dest)
|
||||
{
|
||||
/* Don't send uninitialized bytes over network */
|
||||
memset(dest, 0, sizeof (IPAddr));
|
||||
|
||||
dest->family = htons(src->family);
|
||||
|
||||
switch (src->family) {
|
||||
case IPADDR_INET4:
|
||||
dest->addr.in4 = htonl(src->addr.in4);
|
||||
break;
|
||||
case IPADDR_INET6:
|
||||
memcpy(dest->addr.in6, src->addr.in6, sizeof (dest->addr.in6));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
UTI_IPNetworkToHost(IPAddr *src, IPAddr *dest)
|
||||
{
|
||||
dest->family = ntohs(src->family);
|
||||
|
||||
switch (dest->family) {
|
||||
case IPADDR_INET4:
|
||||
dest->addr.in4 = ntohl(src->addr.in4);
|
||||
break;
|
||||
case IPADDR_INET6:
|
||||
memcpy(dest->addr.in6, src->addr.in6, sizeof (dest->addr.in6));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
UTI_CompareIPs(IPAddr *a, IPAddr *b, IPAddr *mask)
|
||||
{
|
||||
int i, d;
|
||||
|
||||
if (a->family != b->family)
|
||||
return a->family - b->family;
|
||||
|
||||
if (mask && mask->family != b->family)
|
||||
mask = NULL;
|
||||
|
||||
switch (a->family) {
|
||||
case IPADDR_UNSPEC:
|
||||
return 0;
|
||||
case IPADDR_INET4:
|
||||
if (mask)
|
||||
return (a->addr.in4 & mask->addr.in4) - (b->addr.in4 & mask->addr.in4);
|
||||
else
|
||||
return a->addr.in4 - b->addr.in4;
|
||||
case IPADDR_INET6:
|
||||
for (i = 0, d = 0; !d && i < 16; i++) {
|
||||
if (mask)
|
||||
d = (a->addr.in6[i] & mask->addr.in6[i]) -
|
||||
(b->addr.in6[i] & mask->addr.in6[i]);
|
||||
else
|
||||
d = a->addr.in6[i] - b->addr.in6[i];
|
||||
}
|
||||
return d;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
char *
|
||||
UTI_TimeToLogForm(time_t t)
|
||||
{
|
||||
|
|
10
util.h
10
util.h
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "addressing.h"
|
||||
#include "ntp.h"
|
||||
|
||||
/* Convert a timeval into a floating point number of seconds */
|
||||
|
@ -75,8 +76,15 @@ extern char *UTI_TimestampToString(NTP_int64 *ts);
|
|||
/* Convert ref_id into a temporary string, for diagnostics */
|
||||
extern char *UTI_RefidToString(unsigned long ref_id);
|
||||
|
||||
/* Convert an IP address to dotted quad notation, for diagnostics */
|
||||
/* Convert an IP address to string, for diagnostics */
|
||||
extern char *UTI_IPToDottedQuad(unsigned long ip);
|
||||
extern char *UTI_IPToString(IPAddr *ip);
|
||||
|
||||
extern int UTI_StringToIP(const char *addr, IPAddr *ip);
|
||||
extern unsigned long UTI_IPToRefid(IPAddr *ip);
|
||||
extern void UTI_IPHostToNetwork(IPAddr *src, IPAddr *dest);
|
||||
extern void UTI_IPNetworkToHost(IPAddr *src, IPAddr *dest);
|
||||
extern int UTI_CompareIPs(IPAddr *a, IPAddr *b, IPAddr *mask);
|
||||
|
||||
extern char *UTI_TimeToLogForm(time_t t);
|
||||
|
||||
|
|
Loading…
Reference in a new issue