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

// define these to be exact values on your platform.
typedef unsigned char byte_t;   // 8bit
typedef unsigned short word_t;  // 16bit
typedef unsigned int dword_t;   // 32bit
typedef unsigned long qword_t;  // 64bit; on 64bit system

// define NTP packet format.
typedef struct {
    byte_t mode:3;      // mode; low bits.
    byte_t version:3;   // version; 3
    byte_t li:2;        // leap second indicator; high bits
    byte_t stratum;     // how close are we to actual source
    byte_t pollint;     // how often to query.
    byte_t pres;        // precision
    dword_t rootdelay;  // roundtrip time.
    dword_t rootdisp;   // root dispersion.
    byte_t refid[4];    // reference id
    qword_t reftim;
    qword_t origtim;
    qword_t recvtim;
    qword_t sendtim;
} ntpdata_t;


// kick this thing off.
int main(int argc,char** argv) {
    int sock,ret;
    struct hostent *hostinfo;
    struct sockaddr_in name;
    ntpdata_t datapacket;
    qword_t tim;
    char buf[1024];
    int namelen;
    int i;

    assert(sizeof(ntpdata_t) == 48);

    // create SOCK_DGRAM socket
    // int socket(int domain, int type, int protocol);

    // lookup destination address; pool.ntp.org
    // struct hostent *gethostbyname(const char *name);
    
    // setup destination address.
    //name.sin_family = ...
    //name.sin_port = htons(123);
    //name.sin_addr = ...

    // prepare packet.
    memset(&datapacket,0,sizeof(datapacket));
    datapacket.version = 1;

    // send packet; use
    // ssize_t sendto(int s, const void *buf, size_t len, int flags,
    //                       const struct sockaddr *to, socklen_t tolen);
    // (you should be sending &datapacket, etc.)

    // recieve data back; use
    //  ssize_t recvfrom(int s, void *buf, size_t len, int flags,
    //                          struct sockaddr *from, socklen_t *fromlen);
    // (again, should get data into &datapacket)

    // close socket.
    // int close(int fd);

    // display the whole packet:
    //printf("li: %d\n",datapacket.li);
    //printf("version: %d\n",datapacket.version);
    //printf("mode: %d\n",datapacket.mode);
    //printf("stratum: %d\n",datapacket.stratum);
    //printf("pollint: %d\n",datapacket.pollint);
    //printf("pres: %d\n",datapacket.pres);
    //printf("rootdelay: %d\n",datapacket.rootdelay);
    //printf("rootdisp: %d\n",datapacket.rootdisp);
    //printf("refid: %c%c%c%c\n",datapacket.refid[0],datapacket.refid[1],datapacket.refid[2],datapacket.refid[3]);
    //printf("rootdisp: %d\n",datapacket.rootdisp);

    // display all timestamps.
    //datapacket.reftim = ntohl((time_t) datapacket.reftim) - 2208988800U;    
    //ctime_r(&datapacket.reftim,buf);
    //printf("reftim: %d;     %s\n",datapacket.reftim,buf);
    
    //datapacket.origtim = ntohl((time_t) datapacket.origtim) - 2208988800U;
    //ctime_r(&datapacket.origtim,buf);
    //printf("origtim: %d;     %s\n",datapacket.origtim,buf);
    
    //datapacket.recvtim = ntohl((time_t) datapacket.recvtim) - 2208988800U;
    //ctime_r(&datapacket.recvtim,buf);
    //printf("recvtim: %d;     %s\n",datapacket.recvtim,buf);
    
    datapacket.sendtim = ntohl((time_t) datapacket.sendtim) - 2208988800U;
    ctime_r(&datapacket.sendtim,buf);
    printf("NTP Timetamp(%d): %s",datapacket.sendtim,buf);

    // display current system time (for reference)
    tim = time(0);
    ctime_r(&tim,buf);
    printf("System Time (%d); %s",tim,buf);

    return 0;
}



