ntp: update packet processing to NTPv4 (RFC 5905)

This commit is contained in:
Miroslav Lichvar 2014-10-13 13:26:23 +02:00
parent 740e8130dd
commit 8fbfe55e92
8 changed files with 435 additions and 529 deletions

View file

@ -68,7 +68,6 @@ timeout_handler(void *arbitrary)
Destination *d = (Destination *) arbitrary;
NTP_Packet message;
/* Parameters read from reference module */
int version;
int leap;
int are_we_synchronised, our_stratum;
NTP_Leap leap_status;
@ -77,8 +76,6 @@ timeout_handler(void *arbitrary)
double our_root_delay, our_root_dispersion;
struct timeval local_transmit;
version = 3;
LCL_ReadCookedTime(&local_transmit, NULL);
REF_GetReferenceParams(&local_transmit,
&are_we_synchronised, &leap_status,
@ -93,7 +90,7 @@ timeout_handler(void *arbitrary)
leap = LEAP_Unsynchronised;
}
message.lvm = ((leap << 6) &0xc0) | ((version << 3) & 0x38) | (MODE_BROADCAST & 0x07);
message.lvm = NTP_LVM(leap, NTP_VERSION, MODE_BROADCAST);
message.stratum = our_stratum;
message.poll = 6; /* FIXME: what should this be? */
message.precision = LCL_GetSysPrecisionAsLog();
@ -115,7 +112,7 @@ timeout_handler(void *arbitrary)
ts_fuzz = UTI_GetNTPTsFuzz(message.precision);
LCL_ReadCookedTime(&local_transmit, NULL);
UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, ts_fuzz);
NIO_SendNormalPacket(&message, &d->addr, &d->local_addr);
NIO_SendPacket(&message, &d->addr, &d->local_addr, NTP_NORMAL_PACKET_LENGTH);
/* Requeue timeout. Don't care if interval drifts gradually, so just do it
* at the end. */

2
keys.c
View file

@ -174,7 +174,7 @@ determine_hash_delay(uint32_t key_id)
for (i = 0; i < 10; i++) {
LCL_ReadRawTime(&before);
KEY_GenerateAuth(key_id, (unsigned char *)&pkt, NTP_NORMAL_PACKET_SIZE,
KEY_GenerateAuth(key_id, (unsigned char *)&pkt, NTP_NORMAL_PACKET_LENGTH,
(unsigned char *)&pkt.auth_data, sizeof (pkt.auth_data));
LCL_ReadRawTime(&after);

45
ntp.h
View file

@ -38,7 +38,20 @@ typedef struct {
typedef uint32_t NTP_int32;
#define MAX_NTP_AUTH_DATA_LEN MAX_HASH_LENGTH
/* The NTP protocol version that we support */
#define NTP_VERSION 4
/* The minimum valid length of an extension field */
#define NTP_MIN_EXTENSION_LENGTH 16
/* The maximum assumed length of all extension fields in received
packets (RFC 5905 doesn't specify a limit on length or number of
extension fields in one packet) */
#define NTP_MAX_EXTENSIONS_LENGTH 1024
/* The minimum and maximum supported length of MAC */
#define NTP_MIN_MAC_LENGTH 16
#define NTP_MAX_MAC_LENGTH MAX_HASH_LENGTH
/* Type definition for leap bits */
typedef enum {
@ -69,24 +82,28 @@ typedef struct {
NTP_int64 originate_ts;
NTP_int64 receive_ts;
NTP_int64 transmit_ts;
/* Optional extension fields, we don't send packets with them yet */
/* uint8_t extensions[] */
/* Optional message authentication code (MAC) */
NTP_int32 auth_keyid;
uint8_t auth_data[MAX_NTP_AUTH_DATA_LEN];
uint8_t auth_data[NTP_MAX_MAC_LENGTH];
} NTP_Packet;
/* We have to declare a buffer type to hold a datagram read from the
network. Even though we won't be using them (yet?!), this must be
large enough to hold NTP control messages. */
#define NTP_NORMAL_PACKET_LENGTH offsetof(NTP_Packet, auth_keyid)
/* Define the maximum number of bytes that can be read in a single
message. (This is cribbed from ntp.h in the xntpd source code). */
#define MAX_NTP_MESSAGE_SIZE (468+12+16+4)
typedef union {
/* The buffer used to hold a datagram read from the network */
typedef struct {
NTP_Packet ntp_pkt;
uint8_t arbitrary[MAX_NTP_MESSAGE_SIZE];
} ReceiveBuffer;
uint8_t extensions[NTP_MAX_EXTENSIONS_LENGTH];
} NTP_Receive_Buffer;
#define NTP_NORMAL_PACKET_SIZE offsetof(NTP_Packet, auth_keyid)
/* Macros to work with the lvm field */
#define NTP_LVM_TO_LEAP(lvm) (((lvm) >> 6) & 0x3)
#define NTP_LVM_TO_VERSION(lvm) (((lvm) >> 3) & 0x7)
#define NTP_LVM_TO_MODE(lvm) ((lvm) & 0x7)
#define NTP_LVM(leap, version, mode) \
((((leap) << 6) & 0xc0) | (((version) << 3) & 0x38) | ((mode) & 0x07))
#endif /* GOT_NTP_H */

File diff suppressed because it is too large Load diff

View file

@ -60,7 +60,7 @@ extern void NCR_ResetInstance(NCR_Instance inst);
/* This routine is called when a new packet arrives off the network,
and it relates to a source we have an ongoing protocol exchange with */
extern void NCR_ProcessKnown(NTP_Packet *message, struct timeval *now, double now_err, NCR_Instance data, int sock_fd, int length);
extern void NCR_ProcessKnown(NTP_Packet *message, struct timeval *now, double now_err, NCR_Instance data, NTP_Local_Address *local_addr, int length);
/* This routine is called when a new packet arrives off the network,
and we do not recognize its source */

View file

@ -423,7 +423,7 @@ read_from_socket(void *anything)
to read, otherwise it will block. */
int status, sock_fd;
ReceiveBuffer message;
NTP_Receive_Buffer message;
union sockaddr_in46 where_from;
unsigned int flags = 0;
struct timeval now;
@ -439,7 +439,7 @@ read_from_socket(void *anything)
SCH_GetLastEventTime(&now, &now_err, NULL);
iov.iov_base = message.arbitrary;
iov.iov_base = &message.ntp_pkt;
iov.iov_len = sizeof(message);
msg.msg_name = &where_from;
msg.msg_namelen = sizeof(where_from);
@ -507,7 +507,7 @@ read_from_socket(void *anything)
UTI_IPToString(&local_addr.ip_addr), local_addr.sock_fd);
}
if (status >= NTP_NORMAL_PACKET_SIZE && status <= sizeof(NTP_Packet)) {
if (status >= NTP_NORMAL_PACKET_LENGTH) {
NSR_ProcessReceive((NTP_Packet *) &message.ntp_pkt, &now, now_err,
&remote_addr, &local_addr, status);
@ -521,7 +521,7 @@ read_from_socket(void *anything)
}
/* ================================================== */
/* Send a packet to given address */
/* Send a packet to remote address from local address */
static int
send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr)
@ -628,19 +628,10 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr, NTP_Lo
}
/* ================================================== */
/* Send an unauthenticated packet to a given address */
/* Send a packet to a given address */
int
NIO_SendNormalPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr)
NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length)
{
return send_packet((void *) packet, NTP_NORMAL_PACKET_SIZE, remote_addr, local_addr);
}
/* ================================================== */
/* Send an authenticated packet to a given address */
int
NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int auth_len)
{
return send_packet((void *) packet, NTP_NORMAL_PACKET_SIZE + auth_len, remote_addr, local_addr);
return send_packet((void *) packet, length, remote_addr, local_addr);
}

View file

@ -51,9 +51,6 @@ extern void NIO_CloseClientSocket(int sock_fd);
extern int NIO_IsServerSocket(int sock_fd);
/* Function to transmit a packet */
extern int NIO_SendNormalPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr);
/* Function to transmit an authenticated packet */
extern int NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int auth_len);
extern int NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length);
#endif /* GOT_NTP_IO_H */

View file

@ -518,7 +518,7 @@ NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, double now_err, NTP
find_slot(remote_addr, &slot, &found);
if (found == 2) { /* Must match IP address AND port number */
NCR_ProcessKnown(message, now, now_err, get_record(slot)->data,
local_addr->sock_fd, length);
local_addr, length);
} else {
NCR_ProcessUnknown(message, now, now_err, remote_addr, local_addr, length);
}