From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: NTP
Date: Sat, 16 Sep 2017 11:29:09 +0200
Date: 2017-09-16T11:29:09+02:00 [thread overview]
Message-ID: <opiqt5$12h5$1@gioia.aioe.org> (raw)
In-Reply-To: 65e4e16d-3ab1-46e9-8351-d6185e15905a@googlegroups.com
On 2017-09-16 08:40, Anatoly Chernyshev wrote:
> Is there a way to get time via the Network Time Protocol in Ada? It
> doesn't look like AWS has it (or I've missed something).
>
> Currently I'm getting around spawning the Cygwin "nc" command, but it hurts my feelings.
Do you mean send a single UDP request to an NTP server and convert the
response to Ada time?
You can try this:
----------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Calendar; use Ada.Calendar;
with Ada.Calendar.Formatting; use Ada.Calendar.Formatting;
with Ada.Exceptions; use Ada.Exceptions;
with Ada.Streams; use Ada.Streams;
with GNAT.Sockets; use GNAT.Sockets;
with Interfaces; use Interfaces;
procedure Test is
function Get_NTP_Time
( Server : String;
Timeout : Timeval_Duration := 10.0
) return Time is
NTP_Packet_Size : constant := 48;
-- RFC 5905: Official NTP era begins at 1 Jan 1900. We cannot
-- have it in Ada.Calendar.Time, so taking a later time. Note
-- Time_Zone = 0 in order to have it UTC
Era : constant Time := Time_Of (1999, 12, 31, Time_Zone => 0);
-- RFC 5905: seconds since 1 Jan 1900 to 31 Dec 1999
Era_Offset : constant := 3_155_587_200;
Socket : Socket_Type;
Address : Sock_Addr_Type;
Seconds : Unsigned_32;
Fraction : Unsigned_32;
Last : Stream_Element_Offset;
Data : Stream_Element_Array (1..NTP_Packet_Size) :=
( 1 => 2#1110_0011#, -- LI, Version, Mode
2 => 0, -- Stratum, or type of clock
3 => 0, -- Polling Interval
4 => 16#EC#, -- Peer Clock Precision
13 => 49,
14 => 16#4E#,
15 => 49,
16 => 52,
others => 0
);
begin
Address.Addr := Addresses (Get_Host_By_Name (Server), 1);
Address.Port := 123; -- NTP port
Create_Socket (Socket, Family_Inet, Socket_Datagram);
Set_Socket_Option
( Socket,
Socket_Level,
(Receive_Timeout, Timeout)
);
Send_Socket (Socket, Data, Last, Address);
Receive_Socket (Socket, Data, Last, Address);
if Last /= Data'Last then
Raise_Exception (Data_Error'Identity, "Mangled response");
end if;
Seconds := ( Unsigned_32 (Data (41)) * 2**24
+ Unsigned_32 (Data (42)) * 2**16
+ Unsigned_32 (Data (43)) * 2**8
+ Unsigned_32 (Data (44))
- Era_OFfset
);
Fraction := ( Unsigned_32 (Data (45)) * 2**24
+ Unsigned_32 (Data (46)) * 2**16
+ Unsigned_32 (Data (47)) * 2**8
+ Unsigned_32 (Data (48))
);
return ( Era
+ Duration (Seconds)
-- + Duration (Long_Float (Fraction) / 2.0**32)
);
end Get_NTP_Time;
Stamp : Time;
begin
Stamp := Get_NTP_Time ("time.nist.gov");
Put_Line ("NTP time " & Image (Stamp));
exception
when Error : others =>
Put_Line ("Error: " & Exception_Information (Error));
end Test;
-------------------------------------------------------------------
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
next prev parent reply other threads:[~2017-09-16 9:29 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-16 6:40 NTP Anatoly Chernyshev
2017-09-16 9:29 ` Dmitry A. Kazakov [this message]
2017-09-16 12:56 ` NTP Anatoly Chernyshev
2017-09-18 7:54 ` NTP Tarjei Jensen
2017-09-18 8:21 ` NTP Dmitry A. Kazakov
[not found] ` <cb9fcb70-1fb6-4f22-aa25-10044b4cc9a7@googlegroups.com>
2017-09-27 19:25 ` NTP erlo
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox