Skip to content

Commit

Permalink
Simple NTP implementation, time translation, and RTC updating.
Browse files Browse the repository at this point in the history
  • Loading branch information
pdoane committed Jun 18, 2012
1 parent 3f5958f commit 7ec7bd7
Show file tree
Hide file tree
Showing 14 changed files with 387 additions and 49 deletions.
5 changes: 5 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ Setup and Installation for Windows:
- Update PATH:
- Add QEMU and /usr/local/cross/bin to the PATH variable in .bash_profile

-------------------------------------------------------------------------------
Configuration:

- tz_local in time.c

-------------------------------------------------------------------------------
What to expect:

Expand Down
5 changes: 5 additions & 0 deletions REFERENCES
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ DHCP:
- RFC 2131: Dynamic Host Configuration Protocol
- RFC 2132: DHCP Options and BOOTP Vendor Extensions

NTP:

- RFC 5905: Network Time Protocol Version 4: Protocol and Algorithms Specification (NTP)


Registries:

- http://www.iana.org/numbers.html
39 changes: 26 additions & 13 deletions kernel/console_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,20 @@
#include "icmp.h"
#include "io.h"
#include "ipv4.h"
#include "ntp.h"
#include "pit.h"
#include "rtc.h"

// ------------------------------------------------------------------------------------------------
static void cmd_datetime(uint argc, const char** argv)
{
static const char* week_days[] =
{
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};

static const char* months[] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
char buf[TIME_STRING_SIZE];

RTC_Time t;
rtc_get_time(&t);
DateTime dt;
rtc_get_time(&dt);
format_time(buf, sizeof(buf), &dt);

console_print("%s, %02d %s %d %02d:%02d:%02d",
week_days[t.week_day], t.day, months[t.month - 1], t.year, t.hour, t.min, t.sec);
console_print("%s\n", buf);
}

// ------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -97,6 +90,25 @@ static void cmd_ping(uint argc, const char** argv)
icmp_echo_request(&dst_addr, 1, 2, 0, 0);
}

// ------------------------------------------------------------------------------------------------
static void cmd_synctime(uint argc, const char** argv)
{
if (argc != 2)
{
console_print("Usage: synctime <dest ipv4 address>\n");
return;
}

IPv4_Addr dst_addr;
if (!str_to_ipv4_addr(&dst_addr, argv[1]))
{
console_print("Failed to parse destination address\n");
return;
}

ntp_tx(&dst_addr);
}

// ------------------------------------------------------------------------------------------------
static void cmd_reboot(uint argc, const char** argv)
{
Expand All @@ -120,6 +132,7 @@ ConsoleCmd console_cmd_table[] =
{ "lsroute", cmd_lsroute },
{ "ping", cmd_ping },
{ "reboot", cmd_reboot },
{ "synctime", cmd_synctime },
{ "ticks", cmd_ticks },
{ 0, 0 },
};
2 changes: 1 addition & 1 deletion kernel/dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void dns_query_host(const char* host, uint id)

uint len = q - pkt;

uint src_port = 3141; // TODO - bind to random port
uint src_port = PORT_EPHEMERAL;

dns_print(pkt, len);

Expand Down
2 changes: 2 additions & 0 deletions kernel/module.mk
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ KERNEL_SOURCES := \
kernel/net_addr.c \
kernel/net_intf.c \
kernel/net_port.c \
kernel/ntp.c \
kernel/pci.c \
kernel/pci_classify.c \
kernel/pci_driver.c \
kernel/pic.c \
kernel/pit.c \
kernel/rtc.c \
kernel/time.c \
kernel/smp.c \
kernel/string.c \
kernel/udp.c \
Expand Down
16 changes: 14 additions & 2 deletions kernel/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,31 @@
// ------------------------------------------------------------------------------------------------
// Byte Order translation

static inline u16 net_swap16(uint n)
static inline u16 net_swap16(u16 n)
{
return ((n & 0x00ff) << 8) | ((n & 0xff00) >> 8);
}

static inline u32 net_swap32(uint n)
static inline u32 net_swap32(u32 n)
{
return ((n & 0x000000ff) << 24) |
((n & 0x0000ff00) << 8) |
((n & 0x00ff0000) >> 8) |
((n & 0xff000000) >> 24);
}

static inline u64 net_swap64(u64 n)
{
return ((n & 0x00000000000000ff) << 56) |
((n & 0x000000000000ff00) << 40) |
((n & 0x0000000000ff0000) << 24) |
((n & 0x00000000ff000000) << 8) |
((n & 0x000000ff00000000) >> 8) |
((n & 0x0000ff0000000000) >> 24) |
((n & 0x00ff000000000000) >> 40) |
((n & 0xff00000000000000) >> 56);
}

// ------------------------------------------------------------------------------------------------
// Globals

Expand Down
3 changes: 3 additions & 0 deletions kernel/net_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@
#define PORT_DNS 53
#define PORT_BOOTP_SERVER 67
#define PORT_BOOTP_CLIENT 68
#define PORT_NTP 123

#define PORT_EPHEMERAL 3141 // TODO - add proper ephemeral port management
120 changes: 120 additions & 0 deletions kernel/ntp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// ------------------------------------------------------------------------------------------------
// ntp.c
// ------------------------------------------------------------------------------------------------

#include "ntp.h"
#include "console.h"
#include "net.h"
#include "net_port.h"
#include "rtc.h"
#include "time.h"
#include "udp.h"

// ------------------------------------------------------------------------------------------------
// NTP Constants

#define NTP_VERSION 4
#define UNIX_EPOCH 0x83aa7e80

// ------------------------------------------------------------------------------------------------
// NTP Packet

typedef struct NTP_Header
{
u8 mode;
u8 stratum;
u8 poll;
i8 precision;
u32 root_delay;
u32 root_dispersion;
u32 ref_id;
u64 ref_timestamp;
u64 orig_timestamp;
u64 rx_timestamp;
u64 tx_timestamp;
} PACKED NTP_Header;

// ------------------------------------------------------------------------------------------------
// NTP Modes

#define MODE_CLIENT 3
#define MODE_SERVER 4

// ------------------------------------------------------------------------------------------------
void ntp_rx(Net_Intf* intf, const u8* pkt, uint len)
{
ntp_print(pkt, len);

if (len < sizeof(NTP_Header))
{
return;
}

NTP_Header* hdr = (NTP_Header*)pkt;

time_t t = (net_swap64(hdr->tx_timestamp) >> 32) - UNIX_EPOCH;
DateTime dt;
split_time(&dt, t, tz_local);

char str[TIME_STRING_SIZE];
format_time(str, sizeof(str), &dt);
console_print("Setting time to %s\n", str);

rtc_set_time(&dt);
}

// ------------------------------------------------------------------------------------------------
void ntp_tx(const IPv4_Addr* dst_addr)
{
u8 buf[MAX_PACKET_SIZE];
u8* pkt = buf + MAX_PACKET_HEADER;

NTP_Header* hdr = (NTP_Header*)pkt;
hdr->mode = (NTP_VERSION << 3) | MODE_CLIENT;
hdr->stratum = 0;
hdr->poll = 4;
hdr->precision = -6;
hdr->root_delay = net_swap32(1 << 16);
hdr->root_dispersion = net_swap32(1 << 16);
hdr->ref_id = net_swap32(0);
hdr->ref_timestamp = net_swap64(0);
hdr->orig_timestamp = net_swap64(0);
hdr->rx_timestamp = net_swap64(0);
hdr->tx_timestamp = net_swap64(0);

uint len = sizeof(NTP_Header);
uint src_port = PORT_EPHEMERAL;

ntp_print(pkt, len);
udp_tx(dst_addr, PORT_NTP, src_port, pkt, len);
}

// ------------------------------------------------------------------------------------------------
void ntp_print(const u8* pkt, uint len)
{
if (!net_trace)
{
return;
}

if (len < sizeof(NTP_Header))
{
return;
}

NTP_Header* hdr = (NTP_Header*)pkt;

time_t t = (net_swap64(hdr->tx_timestamp) >> 32) - UNIX_EPOCH;

console_print(" NTP: mode=%02x stratum=%d poll=%d precision=%d\n",
hdr->mode, hdr->stratum, hdr->poll, hdr->precision);
console_print(" NTP: root_delay=%08x root_dispersion=%08x ref_id=%08x\n",
net_swap32(hdr->root_delay), net_swap32(hdr->root_dispersion), net_swap32(hdr->ref_id));
console_print(" NTP: ref_timestamp=%016x orig_timestamp=%016x\n",
net_swap64(hdr->ref_timestamp), net_swap64(hdr->orig_timestamp));
console_print(" NTP: rx_timestamp=%016x tx_timestamp=%016x\n",
net_swap64(hdr->rx_timestamp), net_swap64(hdr->tx_timestamp));
console_print(" NTP: unix_epoch=%u\n",
t);
}

13 changes: 13 additions & 0 deletions kernel/ntp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// ------------------------------------------------------------------------------------------------
// ntp.h
// ------------------------------------------------------------------------------------------------

#pragma once

#include "net_intf.h"

// ------------------------------------------------------------------------------------------------
void ntp_rx(Net_Intf* intf, const u8* pkt, uint len);
void ntp_tx(const IPv4_Addr* dst_addr);

void ntp_print(const u8* pkt, uint len);
Loading

0 comments on commit 7ec7bd7

Please sign in to comment.