#!/usr/bin/perl use strict; use warnings; use IO::Socket::INET; use Time::HiRes qw(gettimeofday); use constant TRUE => scalar 1; use constant PORT => scalar 12345; use constant MAXBYTES => scalar 1024; use constant ARGUMENTS => scalar 0; # flush after every initialization $| = 1; my ($server_socket,$received_data,$peer_address,$peer_port,$ntp_packet); # we call IO::Socket::INET->new() to create the UDP Socket and bound if (@ARGV > ARGUMENTS) { print "\nPlease no more than ".ARGUMENTS." arguments (ARGV[])!\n"; print "\nCorrect Syntax: perl $0 \n\n"; exit(); } else { $server_socket = new IO::Socket::INET ( LocalPort => 12345, # Default NTP port 123 Type => SOCK_DGRAM, Proto => 'udp', ) or die "ERROR in Socket Creation : $!\n"; printf("\nServer is up, listens on port: ".PORT." and waiting for client...\n"); while (TRUE) { # read operation on the socket $server_socket->recv($received_data,MAXBYTES) or die "Server received: $!\n"; my ($epoc_rec_sec, $epoc_rec_nano_sec) = gettimeofday(); $peer_address = $server_socket->peerhost(); $peer_port = $server_socket->peerport(); #send the data to the client at which the read/write operations done recently. if ($received_data) { my $server_li_binary = substr($received_data, 0, 2); my $server_li = oct("0b".$server_li_binary); my $server_vn_binary = substr($received_data, 2, 3); my $server_vn = oct("0b".$server_vn_binary); my $server_mode_binary = substr($received_data, 5, 3); my $server_mode = oct("0b".$server_mode_binary); my $server_stratum_binary = substr($received_data, 8, 8); my $server_stratum = oct("0b".$server_stratum_binary); my $server_poll_interval_binary = substr($received_data, 16, 8); my $server_poll_interval = oct("0b".$server_poll_interval_binary); my $server_precission_binary = substr($received_data, 24, 8); my $server_precission = oct("0b".$server_precission_binary); my $server_root_delay_binary = substr($received_data, 32, 32); my $server_root_delay = oct("0b".$server_root_delay_binary); my $server_root_dispersion_binary = substr($received_data, 64, 32); my $server_root_dispersion = oct("0b".$server_root_dispersion_binary); my $server_root_identifier_binary = substr($received_data, 96, 32); my $server_root_identifier = oct("0b".$server_root_identifier_binary); my $ref_client_epoch_binary = substr($received_data, 128, 64); my $ref_client_epoch = oct("0b".$ref_client_epoch_binary); my $originate_client_epoch_binary = substr($received_data, 192, 64); my $originate_client_epoch = oct("0b".$originate_client_epoch_binary); printf "\nNumber of seconds since Jan 1, 1970 - ".$epoc_rec_sec." time of message arrival.\n"; # save exported data...prepare new packet my $difference = $epoc_rec_sec - $originate_client_epoch; my $dec_li; if ($difference < 59) { $dec_li = "0"; } elsif ($difference > 61 ) { $dec_li = "1"; } else { $dec_li = "3"; } # $li = 0; is the client we have no waring for asynchronization my $li = sprintf ("%02b",$dec_li); # $vn = 3; is the version 3 only IPV4 my $dec_vn = "3"; my $vn = sprintf ("%03b",$dec_vn); # $mode = 4; is the server (mode 4) my $dec_mode = "4"; my $mode = sprintf ("%03b",$dec_mode); # $stratum = 1; is the server clock which is radio or clock (Read RFC) my $dec_stratum = "1"; my $stratum = sprintf ("%08b",$dec_stratum); # $poll = 6; maximum interval between messages 6 = 64 sec my $dec_poll = "6"; my $poll = sprintf ("%08b",$dec_poll); # $precision = 0; is the precission interval undefined local clock pecision my $dec_precision = "0"; my $precision = sprintf ("%08b",$dec_precision); # $root_delay = 0; is the roundtrip delay 32 bit client is 0 my $dec_root_delay = "0"; my $root_delay = sprintf ("%032b",$dec_root_delay); # $root_dispersion = 0; is the nominal error relative to the primary reference my $dec_root_dispersion = "0"; my $root_dispersion = sprintf ("%032b",$dec_root_dispersion); # $reference_identifier = 0; is the nominal error relative to the primary reference my $reference_identifier_str = "LOCL"; my $reference_identifier .= unpack("B32", $reference_identifier_str); my ($dec_epoc_ref, $epoc_ref_nano_sec) = gettimeofday(); my $epoc_ref = sprintf ("%064b",$dec_epoc_ref); # $ref_client_epoch is the time that the message departed the client my $epoc_send = sprintf ("%064b",$ref_client_epoch); # Receive time of msg client my $epoc_rec_sec_msg = sprintf ("%064b",$epoc_rec_sec); #printf "\$epoc_rec_sec_msg: ".$epoc_rec_sec."\n"; my ($dec_epoc_sec_send, $dec_epoc_nano_sec_send) = gettimeofday(); my $epoc_send_msg = sprintf ("%064b",$dec_epoc_sec_send); #get the peerhost and peerport at which the recent data received. #print "\n(".$time." \, ".$peer_address.") data received at port number: ".$peer_port." Client said: ".$received_data."\n"; printf "Number of seconds since Jan 1, 1970 - ".$dec_epoc_sec_send." time of message departure.\n"; $ntp_packet = $li . $vn . $mode . $stratum . $poll . $precision . $root_delay . $root_dispersion . $reference_identifier . $epoc_ref . $epoc_send . $epoc_rec_sec_msg . $epoc_send_msg; } # End of if($received_data) else { $ntp_packet = "Invalid Request"; } $server_socket->send($ntp_packet) or die "Server Send: $!\n"; } # End of while loop } #End of else ARGV $server_socket->close(); # Close socket