faruk has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I am looking into writing a perl script that will do NTP time requests/gets of some NTP servers. I can not find a NTP module. Does anyone know of a way to query NTP servers using Perl? Thanks

Replies are listed 'Best First'.
Re: NTP and perl
by kjherron (Pilgrim) on Oct 22, 2001 at 23:05 UTC
    NTP is a pretty complex protocol. It's a lot more than just querying some other server for the correct time. I can't recall ever seeing any application software with built-in NTP client capabilities.

    Are you just writing something that needs to know the correct time? Generally, to use NTP, you set up an NTP server on the local computer; the NTP server automatically keeps the system clock accurate, so other programs just have to query the system for the current time.

    If you really need to query another host's clock directly from your perl module, check out Net::Time. It supports a couple of older network time protocols.

Re: NTP and perl
by Fletch (Bishop) on Oct 22, 2001 at 22:58 UTC

    Kludgy (at least for some values of kludgy), but you could always run ntpdate via backticks or pipes and then parse out the information it returns.

Re: NTP and perl
by rrwo (Friar) on Oct 23, 2001 at 03:25 UTC

    NTP is complex and has a lot of authentication hooks you probably don't need.

    SNTP (Simple Network Time Protocol) is a stripped-down version that's easy to implement. See RFC 2030.

    The Time Protocol RFC 868 is probably better suited to your needs. It's so incredibly simple to implement, it's often one of the examples used in sockets programming tutorials.

Re: NTP and perl
by Dr. Mu (Hermit) on Oct 23, 2001 at 06:05 UTC
    I wrote the following to make sure that localhost, using an ntp client/server combo (i.e. Tardis 2000), was synchronized to a remote ntp site. But it seems to work directly with the remote site as well. (If my memory serves me correctly, it uses SNTP.) No guarantees, of course! :-)
    use IO::Socket; print GetNTPTime('ntp1.cs.wisc.edu'); sub GetNTPTime{ my $host = shift; my $timeout = 2; my $sock = IO::Socket::INET->new( Proto => 'udp', PeerPort => 123, PeerAddr => $host, Timeout => $timeout ) or do {warn "Can't contact $host\n"; return 0}; my $ntp_msg = pack("B8 C3 N11", '00100011', (0)x14); $sock->send($ntp_msg) or do {warn "Can't send NTP msg."; return 0} +; my $rin=''; vec($rin, fileno($sock), 1) = 1; select(my $rout=$rin, undef, my $eout=$rin, $timeout) or do {warn +"No answer from $host"; return 0}; $sock->recv($ntp_msg, length($ntp_msg)) or do {warn "Receive error from $host: ($!)"; return 0}; my ($LIVNMode, $Stratum, $Poll, $Precision, $RootDelay, $RootDispersion, $RefIdentifier, $Reference, $ReferenceF, $Original, $OriginalF, $Receive, $ReceiveF, $Transmit, $TransmitF ) = unpack('a C2 c1 N8 N N B32', $ntp_msg); $Receive -= 2208988800; my $NTPTime = $Receive + $ReceiveF / 65536 / 65536; $RefIdentifier = unpack('A4', $RefIdentifier); my $LI = vec($LIVNMode, 3, 2); my $VN = unpack("C", $LIVNMode & "\x38") >> 3; my $Mode = unpack("C", $LIVNMode & "\x07"); $sock->close; if ($RefIdentifier ne '1280') { return $NTPTime } else { return 0 } }
    The value returned by GetNTPTime is in the same units as the Perl function time(). However, and note this carefully, it does NOT tell you what time it is. It only tells you what the server returned. Using this information to synchronize a local clock is a very complex process and not one appropriately undertaken by a Perl script.

    If your really want to know what time it is, synchronized to an ntp server, get a good ntp client (e.g. ntpd for Linux or Tardis 2000 for Windows), let it do the dirty work, and just read the system clock.

Re: NTP and perl
by astaines (Curate) on Oct 23, 2001 at 02:56 UTC

    NTP has exactly one function - to keep the time on a computer correct with reference to other computers. It is much more than a communications protocol. It use some quite elaborate modelling to keep the time on the client synched with (very) high precision to the time on the server.

    You could, at least in principle, rewrite the NTP programs in Perl, but this seems a little pointless. Perl is not a good langauge for doing lots of iterative calulations.

    Have a look at the tutorial at http://www.eecis.udel.edu/~ntp/. Personally I think fletch is on the right track, if you need what I think you need.

    -- Anthony Staines