-2

So I've created a sntp client and I'm trying to test it on a trusted ntp server. My client is sending a request, the server should then respond with it's own time stamps then the client calculates the round trip delay etc. But when my client sends a request it gets nothing back, I really dont know why as it works with the sntp server i created. I've looked at wire shark to see what's going on and the request from the client looks fine and so does the response from the server so I'm not sure what is going on! Heres the client code:

/* talker.c
* run the program and enter hostname on command line
* e.g ./talker localhost
* Author: Adam Gloyne (14012913)
* Purpose: Sends request to server and calculates received time stamps
* Date Edited: 01/12/15 - added comments
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <time.h> //for time calcs
/* server port the client connects to */
#define PORT 123
#define MAXBUFLEN 100

int main( int argc, char * argv[]) {
/**Variables **********************************/ 
/* for gethostbyname() */
struct hostent *he;
struct sockaddr_in their_addr;
int sockfd, numbytes, addr_len;
char buf[ MAXBUFLEN];
//variables for time processing ***
struct tm * timer;
char message [64];
char format [64];
long long t1; //originate time stamp
long long t2; //transmit time stamp
long long t3; //receive time stamp
long long t4; //final time stamp
long long roundDelay;
long long offset;
time_t secs; //microseconds for calcs
//***********************************
/***********************************************/

/* server address info */
if( argc != 2) {
fprintf( stderr, "usage: talker hostname message\n");
exit( 1);
}
/* resolve server host name or IP address */
if( (he = gethostbyname( argv[1])) == NULL) {
perror( "Talker gethostbyname");
exit( 1);
}
if( (sockfd = socket( AF_INET, SOCK_DGRAM, 0)) == -1) {
perror( "Talker socket");
exit( 1);
}
memset( &their_addr,0, sizeof(their_addr));
/* zero struct */
their_addr.sin_family = AF_INET;    
/* host byte order .. */
their_addr.sin_port = htons( PORT);
/* .. short, netwk byte order */
their_addr.sin_addr = *((struct in_addr *)he -> h_addr);


//get system time *********************************************
time (&secs);
timer = localtime (&secs);
//format time and place into buffer ready to send to server
strftime (format,64,"Client Originate Timestamp  %y-%m-%d %H:%M:%S.\n",timer);
snprintf (message,64,format,(unsigned long)secs); //casting secs
printf (message);

t1 = ntohl((time_t)buf[10]); //get the originate time stamp, needed for final calculation at the end

t1 -= 2208988800U; //converting from ntp to unix time, difference in seconds from ntp time 0h 1st Jan 1900 and unix time 0h 1st Jan 1970 (from RFC)
//********************************************************************

//send the message and check for errors
if( (numbytes = sendto( sockfd, message, strlen(message) + 1, 0,
(struct sockaddr *)&their_addr, sizeof( struct sockaddr))) == -1) {
perror( "Talker sendto");
exit( 1);
}
printf( "Sent %d bytes to %s\n", numbytes,
inet_ntoa( their_addr.sin_addr));


//receive response from server and check for errors
//will be receiving one time stamp from the server but will be the value for both receive and transmit
 addr_len = sizeof (struct sockaddr);
 if( (numbytes = recvfrom( sockfd, buf, MAXBUFLEN - 1, 0,
 (struct sockaddr *)&their_addr, &addr_len)) == -1); {
 perror( "Talker recvfrom");
 //exit( 1);
 }
 //print out received message from server
 printf( "Packet contains \"%s\"\n", buf);

 t3 = ntohl((time_t)buf[10]); //get the server receive time time

 t3 -= 2208988800U; //convert from ntp to unix time

 //assigning transmit stamp from server the same as receive (as specified in RFC)
 t2 = t3;


 //get new system time for final time stamp
 secs = 0;
 time (&secs);
 timer = localtime (&secs);
 strftime (format,64,"\nClient Recieve Timestamp  %y-%m-%d %H:%M:%S.%%06lu %z\n",timer);
 snprintf (message,64,format,(unsigned long)secs); //casting secs
 printf(message);

 t4 = ntohl((time_t)message[10]); //get the client receieve time

 t4 -= 2208988800U; //convert to unix time

 //now we have all time stamps can work out round trip delay and offset
 //round trip first d = (T4 - T1) - (T3 - T2)
 roundDelay = ((t4-t1) - (t3 - t2));
 printf("\nHere is the round trip delay: %d microseconds", roundDelay);

 //now we can calculate the system clock offset.
 //t = ((T2  -T1) + (T3 -T4)) / 2
 offset = ((t2 - t1) + (t3 - t4)) / 2;
 printf("\nHere is the system clock offset: %d microseconds\n", offset);

 //all is done here so close socket and kill client
 close( sockfd);
 return 0;
 }

Any help would be greatly appreciated.

A.G.8
  • 11
  • 3

2 Answers2

1

cross check your code with mine, it is working version 4.

//SNTP Client  

#include <inttypes.h>   //(since C99)   Format conversion of integer types
#include <stdio.h>      //Input/output example printf
#include <stdlib.h>     //General utilities: memory management, program utilities, string conversions, random numbers
#include <unistd.h>     //standard symbolic constants and types
#include <string.h>     //string operations
#include <sys/types.h>  //data types
#include <sys/socket.h> //Internet Protocol family
#include <netinet/in.h> //Internet address family
#include <netdb.h>      //definitions for network database operations
#include <time.h>       //time types
#include <sys/time.h>   //time types
#include <arpa/inet.h>  //definitions for internet operations
//#include<linux/time.h>//time types in linux



//struct for gettimeofday
typedef struct {
    long tv_sec;
    long tv_usec;
} timeval;


struct packets
{
    uint8_t LIVNMODE; 
    uint8_t startum; 
    uint8_t poll; 
    uint8_t precision; 
    uint32_t Root_Delay; 
    uint32_t Root_Dispersion; 
    uint32_t Ref_Identifier; 
    uint32_t Ref_T; 
    uint32_t Ref_Tp2; 
    uint32_t Origin_T;  
    uint32_t Origin_Tp2; 
    uint32_t Receive_T; 
    uint32_t Receive_Tp2; 
    uint32_t T_T; 
    uint32_t T_Tp2; 
};


int main(int argc, char *argv[])
{
int sock_desc;
socklen_t len; 
int today_time;

struct sockaddr_in Cli_addr,Serv_addr; 
struct packets message_send;
struct packets message_receive; 

//add all packets in initialization 
//LI, VN and MODE in a one bytes as a 00 100 011 eg VN=4
message_send.LIVNMODE=0b00100011; 
message_send.startum=0;
message_send.poll=0;
message_send.precision=0;
message_send.Root_Delay=0;
message_send.Root_Dispersion=0;
message_send.Ref_Identifier=0;
message_send.Ref_T=0;
message_send.Ref_Tp2=0;
message_send.Origin_T=0;
message_send.Origin_Tp2=0;
message_send.Receive_T=0;
message_send.Receive_Tp2=0;
message_send.T_T=0;
message_send.T_Tp2=0;


message_receive.Ref_T=0;
message_receive.Ref_Tp2=0;
message_receive.Origin_T=0;
message_receive.Origin_Tp2=0;
message_receive.Receive_T=0;
message_receive.Receive_Tp2=0;
message_receive.T_T=0;
message_receive.T_Tp2=0;
char * HOSTADDRESS;
int PORT;

if (argc>=2){
      HOSTADDRESS=(char *)argv[1]; 
      PORT = atoi(argv[2]);
}
else{
    printf("--------------------------------------------\n");
    printf("usage: ./file.out HOST_ADDRESS PORT \n");
    printf("--------------------------------------------\n");
    return -1;
}


if ((sock_desc = socket(AF_INET,SOCK_DGRAM,0)) < 0){
    printf("Error: can't create the socket ");
    return -1; 
}


len=sizeof(struct sockaddr_in);   
bzero((char *) &Serv_addr,sizeof(Serv_addr));    
Serv_addr.sin_family = AF_INET; 
Serv_addr.sin_addr.s_addr=inet_addr(HOSTADDRESS); 
Serv_addr.sin_port=ntohs(PORT);    


if(sendto(sock_desc,&message_send,sizeof(message_send),0,(struct sockaddr *)&Serv_addr,len) < 0){
     printf("Error: can not send a message on a socket");
     return -1;
}

if(recvfrom(sock_desc,&message_receive,sizeof(message_receive),0,(struct sockaddr *)&Cli_addr,&len) < 0){
     printf("Error: can not receive a message on a socket");
     return -1;
}
printf("message_receive.Ref_T: %" PRIu32 "\n",message_receive.Ref_T);
printf("message_receive.Ref_Tp2: %" PRIu32 "\n",message_receive.Ref_Tp2);
printf("message_receive.Origin_T: %" PRIu32 "\n",message_receive.Origin_T);
printf("message_receive.Origin_Tp2: %" PRIu32 "\n",message_receive.Origin_Tp2);
printf("message_receive.Receive_T: %" PRIu32 "\n",message_receive.Receive_T);
printf("message_receive.Receive_Tp2: %" PRIu32 "\n",message_receive.Receive_Tp2);
printf("message_receive.T_T: %" PRIu32 "\n",message_receive.T_T);
printf("message_receive.T_Tp2: %" PRIu32 "\n",message_receive.T_Tp2);
time_t total_secs;
int Receive_T=ntohl(message_receive.T_T);
Receive_T = Receive_T - 2208988800L;
total_secs = Receive_T;
printf("Today time is: %s",ctime((const long *)&total_secs));
}
0

You are sending a string "Client Originate Timestamp …" to the NTP server; this is not a valid NTP packet as described in the NTP Specification.

Community
  • 1
  • 1
Armali
  • 18,255
  • 14
  • 57
  • 171