summaryrefslogtreecommitdiff
path: root/net/ntp.c
blob: 9c0d3c7fb27cd88d4881f417a19047c5debeb646 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "udp.h"
#include "inet.h"
#include "net_sys.h"
#include "ntp.h"

//http://ptspts.blogspot.com/2009/11/how-to-convert-unix-timestamp-to-civil.html
// Convert a Unix timestamp to a civil date ([year, month, day, hour, minute,
// second]) in GMT.
void timestamp_to_gmt_civil(uint32_t ts)
{
  uint32_t s = ts%86400;
  ts /= 86400;
  uint32_t h = s/3600;
  uint32_t m = s/60%60;
  s = s%60;
  uint32_t x = (ts*4+102032)/146097+15;
  uint32_t b = ts+2442113+x-(x/4);
  uint32_t c = (b*20-2442)/7305;
  uint32_t d = b-365*c-c/4;
  uint32_t e = d*1000/30601;
  uint32_t f = d-e*30-e*601/1000;
  if(e < 14){c-=4716;e-=1;}
  else {c-=4715;e-=13;}

  // final result is in: c / e / f / h / m / s
  klog ("%d.%d.%d %d:%d:%d UTC",f,e,c,h,m,s);
}

uint32_t ntp_generic(struct netdev *dev, uint32_t ip, uint16_t src, uint16_t dst, uint8_t* pos,uint8_t *end)
{
    pos-=48; // we need 48 bytes
    struct udp_v4_ntp *ntp=pos;
    
    ntp->li_vn_mode=0x1b;      // 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.

    ntp->stratum=0;         // Eight bits. Stratum level of the local clock.
    ntp->poll=0;            // Eight bits. Maximum interval between successive messages.
    ntp->precision=0;       // Eight bits. Precision of the local clock.

    ntp->rootDelay=0;      // 32 bits. Total round trip delay time.
    ntp->rootDispersion=0; // 32 bits. Max error aloud from primary clock source.
    ntp->refId=0;          // 32 bits. Reference clock identifier.

    ntp->refTm_s=0;        // 32 bits. Reference time-stamp seconds.
    ntp->refTm_f=0;        // 32 bits. Reference time-stamp fraction of a second.

    ntp->origTm_s=0;       // 32 bits. Originate time-stamp seconds.
    ntp->origTm_f=0;       // 32 bits. Originate time-stamp fraction of a second.

    ntp->rxTm_s=0;         // 32 bits. Received time-stamp seconds.
    ntp->rxTm_f=0;         // 32 bits. Received time-stamp fraction of a second.

    ntp->txTm_s=0;         // 32 bits and the most important field the client cares about. Transmit time-stamp seconds.
    ntp->txTm_f=0;         // 32 bits. Transmit time-stamp fraction of a second.

    return udp_generic(dev, ip, src, dst, pos,end);
}

uint32_t ntp_incoming(uint8_t* start, uint8_t *pos)
{
    struct udp_v4_ntp *ntp=pos;
    uint32_t ntp_time=ntohl(ntp->txTm_s);
    uint32_t unix_time=ntp_time-2208988800; // subtract offset to get unixtime
    timestamp_to_gmt_civil(unix_time);
    return 0; // all ok
}