2008-04-23 23:36:57 +03:00
|
|
|
{==============================================================================|
|
2008-04-24 10:05:26 +03:00
|
|
|
| Project : Delphree - Synapse | 002.000.001 |
|
2008-04-23 23:36:57 +03:00
|
|
|
|==============================================================================|
|
|
|
|
| Content: SNTP client |
|
|
|
|
|==============================================================================|
|
2008-04-24 10:05:26 +03:00
|
|
|
| The contents of this file are subject to the Mozilla Public License Ver. 1.1 |
|
2008-04-23 23:36:57 +03:00
|
|
|
| (the "License"); you may not use this file except in compliance with the |
|
|
|
|
| License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ |
|
|
|
|
| |
|
|
|
|
| Software distributed under the License is distributed on an "AS IS" basis, |
|
|
|
|
| WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for |
|
|
|
|
| the specific language governing rights and limitations under the License. |
|
|
|
|
|==============================================================================|
|
|
|
|
| The Original Code is Synapse Delphi Library. |
|
|
|
|
|==============================================================================|
|
|
|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
2008-04-24 10:05:26 +03:00
|
|
|
| Portions created by Lukas Gebauer are Copyright (c)2000,2001. |
|
2008-04-23 23:36:57 +03:00
|
|
|
| All Rights Reserved. |
|
|
|
|
|==============================================================================|
|
|
|
|
| Contributor(s): |
|
|
|
|
|==============================================================================|
|
|
|
|
| History: see HISTORY.HTM from distribution package |
|
2008-04-23 23:48:39 +03:00
|
|
|
| (Found at URL: http://www.ararat.cz/synapse/) |
|
2008-04-23 23:36:57 +03:00
|
|
|
|==============================================================================}
|
|
|
|
|
2008-04-24 10:00:43 +03:00
|
|
|
{$Q-}
|
2008-04-24 10:05:26 +03:00
|
|
|
{$WEAKPACKAGEUNIT ON}
|
2008-04-23 23:36:57 +03:00
|
|
|
|
|
|
|
unit SNTPsend;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2008-04-24 10:05:26 +03:00
|
|
|
SysUtils,
|
|
|
|
synsock, blcksock;
|
2008-04-23 23:36:57 +03:00
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
const
|
|
|
|
cNtpProtocol = 'ntp';
|
2008-04-23 23:36:57 +03:00
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
type
|
|
|
|
PNtp = ^TNtp;
|
2008-04-23 23:36:57 +03:00
|
|
|
TNtp = packed record
|
2008-04-24 10:05:26 +03:00
|
|
|
mode: Byte;
|
|
|
|
stratum: Byte;
|
|
|
|
poll: Byte;
|
|
|
|
Precision: Byte;
|
|
|
|
RootDelay: Longint;
|
|
|
|
RootDisperson: Longint;
|
|
|
|
RefID: Longint;
|
|
|
|
Ref1: Longint;
|
|
|
|
Ref2: Longint;
|
|
|
|
Org1: Longint;
|
|
|
|
Org2: Longint;
|
|
|
|
Rcv1: Longint;
|
|
|
|
Rcv2: Longint;
|
|
|
|
Xmit1: Longint;
|
|
|
|
Xmit2: Longint;
|
2008-04-23 23:36:57 +03:00
|
|
|
end;
|
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
TSNTPSend = class(TObject)
|
2008-04-23 23:36:57 +03:00
|
|
|
private
|
2008-04-24 10:05:26 +03:00
|
|
|
FNTPReply: TNtp;
|
|
|
|
FNTPTime: TDateTime;
|
|
|
|
FSntpHost: string;
|
|
|
|
FTimeout: Integer;
|
|
|
|
FSock: TUDPBlockSocket;
|
|
|
|
FBuffer: string;
|
2008-04-23 23:36:57 +03:00
|
|
|
public
|
|
|
|
constructor Create;
|
|
|
|
destructor Destroy; override;
|
2008-04-24 10:05:26 +03:00
|
|
|
function DecodeTs(Nsec, Nfrac: Longint): TDateTime;
|
|
|
|
function GetNTP: Boolean;
|
|
|
|
function GetBroadcastNTP: Boolean;
|
|
|
|
published
|
|
|
|
property NTPReply: TNtp read FNTPReply;
|
|
|
|
property NTPTime: TDateTime read FNTPTime;
|
|
|
|
property SntpHost: string read FSntpHost write FSntpHost;
|
|
|
|
property Timeout: Integer read FTimeout write FTimeout;
|
|
|
|
end;
|
2008-04-23 23:36:57 +03:00
|
|
|
|
|
|
|
implementation
|
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
constructor TSNTPSend.Create;
|
2008-04-23 23:36:57 +03:00
|
|
|
begin
|
|
|
|
inherited Create;
|
2008-04-24 10:05:26 +03:00
|
|
|
FSock := TUDPBlockSocket.Create;
|
|
|
|
FSock.CreateSocket;
|
|
|
|
FTimeout := 5000;
|
|
|
|
FSntpHost := cLocalhost;
|
2008-04-23 23:36:57 +03:00
|
|
|
end;
|
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
destructor TSNTPSend.Destroy;
|
2008-04-23 23:36:57 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
FSock.Free;
|
|
|
|
inherited Destroy;
|
2008-04-23 23:36:57 +03:00
|
|
|
end;
|
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
function TSNTPSend.DecodeTs(Nsec, Nfrac: Longint): TDateTime;
|
2008-04-23 23:36:57 +03:00
|
|
|
const
|
|
|
|
maxi = 4294967296.0;
|
|
|
|
var
|
2008-04-24 10:05:26 +03:00
|
|
|
d, d1: Double;
|
2008-04-23 23:36:57 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
Nsec := synsock.htonl(Nsec);
|
|
|
|
Nfrac := synsock.htonl(Nfrac);
|
|
|
|
d := Nsec;
|
|
|
|
if d < 0 then
|
|
|
|
d := maxi + d - 1;
|
|
|
|
d1 := Nfrac;
|
|
|
|
if d1 < 0 then
|
|
|
|
d1 := maxi + d1 - 1;
|
|
|
|
d1 := d1 / maxi;
|
|
|
|
d1 := Trunc(d1 * 1000) / 1000;
|
|
|
|
Result := (d + d1) / 86400;
|
|
|
|
Result := Result + 2;
|
2008-04-23 23:36:57 +03:00
|
|
|
end;
|
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
function TSNTPSend.GetBroadcastNTP: Boolean;
|
2008-04-23 23:36:57 +03:00
|
|
|
var
|
2008-04-24 10:05:26 +03:00
|
|
|
NtpPtr: PNtp;
|
|
|
|
x: Integer;
|
2008-04-23 23:36:57 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
Result := False;
|
|
|
|
FSock.Bind('0.0.0.0', cNtpProtocol);
|
|
|
|
if FSock.CanRead(Timeout) then
|
|
|
|
begin
|
|
|
|
x := FSock.WaitingData;
|
|
|
|
SetLength(FBuffer, x);
|
|
|
|
FSock.RecvBufferFrom(Pointer(FBuffer), x);
|
|
|
|
if (SntpHost = '0.0.0.0') or (FSock.GetRemoteSinIP = SntpHost) then
|
|
|
|
if x >= SizeOf(NTPReply) then
|
|
|
|
begin
|
|
|
|
NtpPtr := Pointer(FBuffer);
|
|
|
|
FNTPReply := NtpPtr^;
|
|
|
|
FNTPTime := DecodeTs(NTPReply.Xmit1, NTPReply.Xmit2);
|
|
|
|
Result := True;
|
|
|
|
end;
|
|
|
|
end;
|
2008-04-23 23:36:57 +03:00
|
|
|
end;
|
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
function TSNTPSend.GetNTP: Boolean;
|
2008-04-23 23:36:57 +03:00
|
|
|
var
|
2008-04-24 10:05:26 +03:00
|
|
|
q: TNtp;
|
|
|
|
NtpPtr: PNtp;
|
|
|
|
x: Integer;
|
2008-04-23 23:36:57 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
Result := False;
|
|
|
|
FSock.Connect(sntphost, cNtpProtocol);
|
|
|
|
FillChar(q, SizeOf(q), 0);
|
|
|
|
q.mode := $1B;
|
|
|
|
FSock.SendBuffer(@q, SizeOf(q));
|
|
|
|
if FSock.CanRead(Timeout) then
|
|
|
|
begin
|
|
|
|
x := FSock.WaitingData;
|
|
|
|
SetLength(FBuffer, x);
|
|
|
|
FSock.RecvBuffer(Pointer(FBuffer), x);
|
|
|
|
if x >= SizeOf(NTPReply) then
|
|
|
|
begin
|
|
|
|
NtpPtr := Pointer(FBuffer);
|
|
|
|
FNTPReply := NtpPtr^;
|
|
|
|
FNTPTime := DecodeTs(NTPReply.Xmit1, NTPReply.Xmit2);
|
|
|
|
Result := True;
|
2008-04-23 23:36:57 +03:00
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
end;
|
2008-04-23 23:36:57 +03:00
|
|
|
end;
|
|
|
|
|
|
|
|
end.
|