I have tried creating a ntp client by creating a packet with ntp request send that to server. but I am not able to code to calculate offset and set time according to that offset. Though whatever i have done through that I am getting some offset value but i am not sure that value is correct. Please if anyone can help me. Thanks in advance.
#include <stdio.h>
#define NTP_HDR_LEN 48
#define FRAC 4294967296
struct ntp_packet
{
uint8_t li_vn_mode; // Eight bits. li, vn, and mode.
// li. Two bits. Leap indicator.
// vn. Three bits. Version number of the protocol.
// mode. Three bits. Client will pick mode 3 for client.
uint8_t stratum; // Eight bits. Stratum level of the local clock.
uint8_t poll; // Eight bits. Maximum interval between successive messages.
uint8_t precision; // Eight bits. Precision of the local clock.
uint32_t rootDelay; // 32 bits. Total round trip delay time.
uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source.
uint32_t refId; // 32 bits. Reference clock identifier.
uint32_t refTm_s;
uint32_t refTm_f; // 64 bits. Reference time-stamp seconds.
uint32_t origTm_s;
uint32_t origTm_f; // 64 bits. Originate time-stamp seconds.
uint32_t rxTm_s;
uint32_t rxTm_f; // 64 bits. Received time-stamp seconds.
uint32_t txTm_s; // 32 bits and the most important field the client cares about. Transmit time-stamp seconds.
uint32_t txTm_f; // 32 bits. Transmit time-stamp fraction of a second.
}packet;
char sendBuf[2048];
char rcvBuf[2048];
struct timeval txt, trecv, tsend;
void adjust_time(signed long long off)
{
unsigned long long ntp_tym;
struct timeval unix_time;
gettimeofday(&unix_time, NULL);
ntp_tym = off + ((ntohl(txt.tv_sec + 2208988800)) + (ntohl(txt.tv_usec) /
1e6));
unix_time.tv_sec = ntp_tym >> 32;
unix_time.tv_usec = (long)(((ntp_tym - unix_time.tv_sec) << 32) / FRAC *
1e6);
settimeofday(&unix_time, NULL);
}
void CreateSocket()
{
sourceIp = "192.168.1.109";
hostNameInteractive = "139.143.5.30";
source_dest_Port = 123;
uint32_t s_recv_s, s_recv_f, s_trans_s, s_trans_f;
unsigned long long t1, t2, t3, t4;
signed long long offs;
double offset;
if ((sock_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
{
perror ("socket() failed to get socket descriptor for using ioctl() ");
exit(1);
}
CreateNtpHeader();
SendRecv();
gettimeofday(&trecv, NULL);
struct ntp_packet *npkt = (struct ntp_packet*)(rcvBuf);
s_recv_s = ntohl(npkt->rxTm_s);
s_recv_f = ntohl(npkt->rxTm_f);
s_trans_s = ntohl(npkt->txTm_s);
s_trans_f = ntohl(npkt->txTm_f);
t1 = ((ntohl(txt.tv_sec + 2208988800)) + (ntohl(txt.tv_usec) /
1000000));
t4 = ((ntohl(trecv.tv_sec + 2208988800)) + (ntohl(trecv.tv_usec) /
1000000));
t2 = ((s_recv_s) + (s_recv_f / 1e12));
t3 = ((s_trans_s) + (s_trans_f / 1e12));
offs = (((t2 - t1) + (t3 - t4))/2);
offset = ((double)offs) / FRAC;
std::cout<<"offset : "<<offset<<" sec"<<std::endl;
adjust_time(offs);
close(sock_raw);
}
void CreateNtpHeader()
{
struct ntp_packet *pkt = (struct ntp_packet *)(sendBuf);
gettimeofday(&txt, NULL);
pkt->li_vn_mode = 0xe3;
pkt->stratum = 0;
pkt->poll = 3;
pkt->precision = 0xfa;
pkt->rootDelay = 0x00000100;
pkt->rootDispersion = 0x00000100;
pkt->refId = 0;
pkt->refTm_s = 0;
pkt->refTm_f = 0;
pkt->origTm_s = 0;
pkt->origTm_f = 0;
pkt->rxTm_s = 0;
pkt->rxTm_f = 0;
pkt->txTm_s = htonl(txt.tv_sec + 2208988800);
pkt->txTm_f = htonl(txt.tv_usec);
}
int main(int arg, char* args[])
{
CreateSocket();
return 0;
}
This is not a complete code. this is just a part of code where i am having the problem. I have included all the needed headers. If any thing else needed or any explanation needed please let me know.
User contributions licensed under CC BY-SA 3.0