Giter Club home page Giter Club logo

ntpclient's Introduction

Alt text

NTP Client

This NTP client is similar in nature to ntpdate but does not accept any command line arguments nor does it update the system clock. Note that this NTP client does not use any NTP libraries but rather works directly at the NTP protocol level.

Within ./source there are two versions of the NTP client. One is written in C while the other one is written in Python. They both have the same functionality and are independent of one another. The C version uses us.pool.ntp.org as the NTP server while the Python version uses pool.ntp.org.

For more information be sure to read Let's make a NTP Client in C.

(C) 2014 David Lettier.
http://www.lettier.com/

License

See LICENSE.

ntpclient's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ntpclient's Issues

License?

Hi,

I just stumbled across your NTP client implementation… and at the moment I've got a need for a nice small NTP client for use in an embedded device (ARM Cortex M3-based) which runs the OpenThread network stack.

I was wondering what the license was for your project, and whether you are happy for us to use your code in a commercial product? My thinking is that I'll port your C code across to use the OpenThread API and contribute it there (retaining your original copyright of course)… OpenThread is licensed under the 3-clause BSD license.

https://github.com/openthread/openthread

If you could let us know what the licensing is on your client, that would be a big help. :-)

ordering of LI, VN, mode bits

Hi -

I'm wondering about the order of your bit fields for Leap Indicator, Version Number and Mode. According to multiple sources I've looked at:

LI: bits 0-1
VN: bits 2-4
Mode: bits 5-7

If you wish these values (as indicated in your comment):
LI: 0
VN: 3
Mode: 3

Then the bit pattern should be 011 011 00, or 0110 1100, or 0x6c, not 0x1b as you use.

Not so?

Originate Timestamp not set?

Hi David,

Great work here!
I've got a question, in your code snippet in C,
I don't see you setting the "Originate Timestamp" (or t0) in the packet you're sending,
however, isn't this value mandatory in order to get back a response from the server?

Thank you

program in loop doesn't work

At first I would like to say thank you, great job.

Unfortunately, I have a problem with your code. When I use it in a loop, the program creates a new process for the socket each time. After a few times the program hangs and crashes a thread in my program that works with this code. I even tried to use the close () and socket() + close() outside loop functions (crashes too). The program crashes after a few passes of the loop (sometimes at beginning, not always at the same time). I tried to debug the code (with prinf() before and after every functions) and the program crashes at different times. Sometimes read, sometimes write. Maybe you have an idea how to solve it?

get millisecond timestamp

Thank you for your Tutorial. This code will result ntp time in seconds. How can I get millisecond timestamp, I don't know how to combine txTm_s and txTm_f. And if NTP server's network latency is less then 1ms, the ntp time error in this code will less then 1ms ?

Latency/Delays

Great and succinct client you have there. Love it a lot.

One question I have is with network latencies and whether this is inside the NTP packet (and not used) or at what point is the timestamp valid from a code point of view?

For example the modified code below introduces some "simulated" latencies at various points just before the fd reads and writes. In theory this could be where some latency is introduced. If you were to set the system clock at the end where the printf is then you would be off by a few seconds.

I've scoured the spec and other code and can't seem to find an example!?

/*
 *
 * (C) 2014 David Lettier.
 *
 * http://www.lettier.com/
 *
 * NTP client.
 *
 * Compiled with gcc version 4.7.2 20121109 (Red Hat 4.7.2-8) (GCC).
 *
 * Tested on Linux 3.8.11-200.fc18.x86_64 #1 SMP Wed May 1 19:44:27 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux.
 *
 * To compile: $ gcc main.c -o ntpClient.out
 *
 * Usage: $ ./ntpClient.out
 *
 */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define NTP_TIMESTAMP_DELTA 2208988800ull

#define LI(packet)   (uint8_t) ((packet.li_vn_mode & 0xC0) >> 6) // (li   & 11 000 000) >> 6
#define VN(packet)   (uint8_t) ((packet.li_vn_mode & 0x38) >> 3) // (vn   & 00 111 000) >> 3
#define MODE(packet) (uint8_t) ((packet.li_vn_mode & 0x07) >> 0) // (mode & 00 000 111) >> 0

void error( char* msg )
{
		perror( msg ); // Print the error message to stderr.

		exit( 0 ); // Quit the process.
}

int main( int argc, char* argv[ ] )
{
	int sockfd, n; // Socket file descriptor and the n return result from writing/reading from the socket.

	int portno = 123; // NTP UDP port number.

	char* host_name = "us.pool.ntp.org"; // NTP server host-name.

	// Structure that defines the 48 byte NTP packet protocol.

	typedef struct
	{

		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;        // 32 bits. Reference time-stamp seconds.
		uint32_t refTm_f;        // 32 bits. Reference time-stamp fraction of a second.

		uint32_t origTm_s;       // 32 bits. Originate time-stamp seconds.
		uint32_t origTm_f;       // 32 bits. Originate time-stamp fraction of a second.

		uint32_t rxTm_s;         // 32 bits. Received time-stamp seconds.
		uint32_t rxTm_f;         // 32 bits. Received time-stamp fraction of a second.

		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.

	} ntp_packet;              // Total: 384 bits or 48 bytes.

	// Create and zero out the packet. All 48 bytes worth.

	ntp_packet packet = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

	memset( &packet, 0, sizeof( ntp_packet ) );

	// Set the first byte's bits to 00,011,011 for li = 0, vn = 3, and mode = 3. The rest will be left set to zero.

	*( ( char * ) &packet + 0 ) = 0x1b; // Represents 27 in base 10 or 00011011 in base 2.

	// Create a UDP socket, convert the host-name to an IP address, set the port number,
	// connect to the server, send the packet, and then read in the return packet.

	struct sockaddr_in serv_addr; // Server address data structure.
	struct hostent *server;      // Server data structure.

	sockfd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); // Create a UDP socket.

	if ( sockfd < 0 )
		error( "ERROR opening socket" );

	server = gethostbyname( host_name ); // Convert URL to IP.

	if ( server == NULL )
		error( "ERROR, no such host" );

	// Zero out the server address structure.

	bzero( ( char* ) &serv_addr, sizeof( serv_addr ) );

	serv_addr.sin_family = AF_INET;

	// Copy the server's IP address to the server address structure.

	bcopy( ( char* )server->h_addr, ( char* ) &serv_addr.sin_addr.s_addr, server->h_length );

	// Convert the port number integer to network big-endian style and save it to the server address structure.

	serv_addr.sin_port = htons( portno );

	// Call up the server using its IP address and port number.

	if ( connect( sockfd, ( struct sockaddr * ) &serv_addr, sizeof( serv_addr) ) < 0 )
		error( "ERROR connecting" );

	// Send it the NTP packet it wants. If n == -1, it failed.
	
	sleep(2);

	n = write( sockfd, ( char* ) &packet, sizeof( ntp_packet ) );
	
	sleep(2);

	if ( n < 0 )
		error( "ERROR writing to socket" );

	// Wait and receive the packet back from the server. If n == -1, it failed.

	n = read( sockfd, ( char* ) &packet, sizeof( ntp_packet ) );
	
	sleep(2);

	if ( n < 0 )
		error( "ERROR reading from socket" );

	// These two fields contain the time-stamp seconds as the packet left the NTP server.
	// The number of seconds correspond to the seconds passed since 1900.
	// ntohl() converts the bit/byte order from the network's to host's "endianness".

	packet.txTm_s = ntohl( packet.txTm_s ); // Time-stamp seconds.
	packet.txTm_f = ntohl( packet.txTm_f ); // Time-stamp fraction of a second.

	// Extract the 32 bits that represent the time-stamp seconds (since NTP epoch) from when the packet left the server.
	// Subtract 70 years worth of seconds from the seconds since 1900.
	// This leaves the seconds since the UNIX epoch of 1970.
	// (1900)------------------(1970)**************************************(Time Packet Left the Server)

	time_t txTm = ( time_t ) ( packet.txTm_s - NTP_TIMESTAMP_DELTA );

	// Print the time we got from the server, accounting for local timezone and conversion from UTC time.

	printf( "Time: %s", ctime( ( const time_t* ) &txTm ) );

	return 0;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.