1/** 2 * @file 3 * SNTP client module 4 */ 5 6/* 7 * Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without modification, 11 * are permitted provided that the following conditions are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright notice, 14 * this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 24 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 30 * OF SUCH DAMAGE. 31 * 32 * This file is part of the lwIP TCP/IP stack. 33 * 34 * Author: Frédéric Bernon, Simon Goldschmidt 35 */ 36 37 38/** 39 * @defgroup sntp SNTP 40 * @ingroup apps 41 * 42 * This is simple "SNTP" client for the lwIP raw API. 43 * It is a minimal implementation of SNTPv4 as specified in RFC 4330. 44 * 45 * For a list of some public NTP servers, see this link: 46 * http://support.ntp.org/bin/view/Servers/NTPPoolServers 47 * 48 * @todo: 49 * - complete SNTP_CHECK_RESPONSE checks 3 and 4 50 */ 51 52#include "lwip/apps/sntp.h" 53 54#include "lwip/opt.h" 55#include "lwip/timeouts.h" 56#include "lwip/udp.h" 57#include "lwip/dns.h" 58#include "lwip/ip_addr.h" 59#include "lwip/pbuf.h" 60#include "lwip/dhcp.h" 61 62#include <string.h> 63#include <time.h> 64 65#if LWIP_UDP 66 67/* Handle support for more than one server via SNTP_MAX_SERVERS */ 68#if SNTP_MAX_SERVERS > 1 69#define SNTP_SUPPORT_MULTIPLE_SERVERS 1 70#else /* NTP_MAX_SERVERS > 1 */ 71#define SNTP_SUPPORT_MULTIPLE_SERVERS 0 72#endif /* NTP_MAX_SERVERS > 1 */ 73 74#ifndef SNTP_SUPPRESS_DELAY_CHECK 75#if SNTP_UPDATE_DELAY < 15000 76#error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds (define SNTP_SUPPRESS_DELAY_CHECK to disable this error)!" 77#endif 78#endif 79 80/* the various debug levels for this file */ 81#define SNTP_DEBUG_TRACE (SNTP_DEBUG | LWIP_DBG_TRACE) 82#define SNTP_DEBUG_STATE (SNTP_DEBUG | LWIP_DBG_STATE) 83#define SNTP_DEBUG_WARN (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING) 84#define SNTP_DEBUG_WARN_STATE (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE) 85#define SNTP_DEBUG_SERIOUS (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS) 86 87#define SNTP_ERR_KOD 1 88 89/* SNTP protocol defines */ 90#define SNTP_MSG_LEN 48 91 92#define SNTP_OFFSET_LI_VN_MODE 0 93#define SNTP_LI_MASK 0xC0 94#define SNTP_LI_NO_WARNING (0x00 << 6) 95#define SNTP_LI_LAST_MINUTE_61_SEC (0x01 << 6) 96#define SNTP_LI_LAST_MINUTE_59_SEC (0x02 << 6) 97#define SNTP_LI_ALARM_CONDITION (0x03 << 6) /* (clock not synchronized) */ 98 99#define SNTP_VERSION_MASK 0x38 100#define SNTP_VERSION (4/* NTP Version 4*/<<3) 101 102#define SNTP_MODE_MASK 0x07 103#define SNTP_MODE_CLIENT 0x03 104#define SNTP_MODE_SERVER 0x04 105#define SNTP_MODE_BROADCAST 0x05 106 107#define SNTP_OFFSET_STRATUM 1 108#define SNTP_STRATUM_KOD 0x00 109 110#define SNTP_OFFSET_ORIGINATE_TIME 24 111#define SNTP_OFFSET_RECEIVE_TIME 32 112#define SNTP_OFFSET_TRANSMIT_TIME 40 113 114/* Number of seconds between 1970 and Feb 7, 2036 06:28:16 UTC (epoch 1) */ 115#define DIFF_SEC_1970_2036 ((u32_t)2085978496L) 116 117/** Convert NTP timestamp fraction to microseconds. 118 */ 119#ifndef SNTP_FRAC_TO_US 120# if LWIP_HAVE_INT64 121# define SNTP_FRAC_TO_US(f) ((u32_t)(((u64_t)(f) * 1000000UL) >> 32)) 122# else 123# define SNTP_FRAC_TO_US(f) ((u32_t)(f) / 4295) 124# endif 125#endif /* !SNTP_FRAC_TO_US */ 126 127/* Configure behaviour depending on native, microsecond or second precision. 128 * Treat NTP timestamps as signed two's-complement integers. This way, 129 * timestamps that have the MSB set simply become negative offsets from 130 * the epoch (Feb 7, 2036 06:28:16 UTC). Representable dates range from 131 * 1968 to 2104. 132 */ 133#ifndef SNTP_SET_SYSTEM_TIME_NTP 134# ifdef SNTP_SET_SYSTEM_TIME_US 135# define SNTP_SET_SYSTEM_TIME_NTP(s, f) \ 136 SNTP_SET_SYSTEM_TIME_US((u32_t)((s) + DIFF_SEC_1970_2036), SNTP_FRAC_TO_US(f)) 137# else 138# define SNTP_SET_SYSTEM_TIME_NTP(s, f) \ 139 SNTP_SET_SYSTEM_TIME((u32_t)((s) + DIFF_SEC_1970_2036)) 140# endif 141#endif /* !SNTP_SET_SYSTEM_TIME_NTP */ 142 143/* Get the system time either natively as NTP timestamp or convert from 144 * Unix time in seconds and microseconds. Take care to avoid overflow if the 145 * microsecond value is at the maximum of 999999. Also add 0.5 us fudge to 146 * avoid special values like 0, and to mask round-off errors that would 147 * otherwise break round-trip conversion identity. 148 */ 149#ifndef SNTP_GET_SYSTEM_TIME_NTP 150# define SNTP_GET_SYSTEM_TIME_NTP(s, f) do { \ 151 u32_t sec_, usec_; \ 152 SNTP_GET_SYSTEM_TIME(sec_, usec_); \ 153 (s) = (s32_t)(sec_ - DIFF_SEC_1970_2036); \ 154 (f) = usec_ * 4295 - ((usec_ * 2143) >> 16) + 2147; \ 155 } while (0) 156#endif /* !SNTP_GET_SYSTEM_TIME_NTP */ 157 158/* Start offset of the timestamps to extract from the SNTP packet */ 159#define SNTP_OFFSET_TIMESTAMPS \ 160 (SNTP_OFFSET_TRANSMIT_TIME + 8 - sizeof(struct sntp_timestamps)) 161 162/* Round-trip delay arithmetic helpers */ 163#if SNTP_COMP_ROUNDTRIP 164# if !LWIP_HAVE_INT64 165# error "SNTP round-trip delay compensation requires 64-bit arithmetic" 166# endif 167# define SNTP_SEC_FRAC_TO_S64(s, f) \ 168 ((s64_t)(((u64_t)(s) << 32) | (u32_t)(f))) 169# define SNTP_TIMESTAMP_TO_S64(t) \ 170 SNTP_SEC_FRAC_TO_S64(lwip_ntohl((t).sec), lwip_ntohl((t).frac)) 171#endif /* SNTP_COMP_ROUNDTRIP */ 172 173/** 174 * 64-bit NTP timestamp, in network byte order. 175 */ 176struct sntp_time { 177 u32_t sec; 178 u32_t frac; 179}; 180 181/** 182 * Timestamps to be extracted from the NTP header. 183 */ 184struct sntp_timestamps { 185#if SNTP_COMP_ROUNDTRIP || SNTP_CHECK_RESPONSE >= 2 186 struct sntp_time orig; 187 struct sntp_time recv; 188#endif 189 struct sntp_time xmit; 190}; 191 192/** 193 * SNTP packet format (without optional fields) 194 * Timestamps are coded as 64 bits: 195 * - signed 32 bits seconds since Feb 07, 2036, 06:28:16 UTC (epoch 1) 196 * - unsigned 32 bits seconds fraction (2^32 = 1 second) 197 */ 198#ifdef PACK_STRUCT_USE_INCLUDES 199# include "arch/bpstruct.h" 200#endif 201PACK_STRUCT_BEGIN 202struct sntp_msg { 203 PACK_STRUCT_FLD_8(u8_t li_vn_mode); 204 PACK_STRUCT_FLD_8(u8_t stratum); 205 PACK_STRUCT_FLD_8(u8_t poll); 206 PACK_STRUCT_FLD_8(u8_t precision); 207 PACK_STRUCT_FIELD(u32_t root_delay); 208 PACK_STRUCT_FIELD(u32_t root_dispersion); 209 PACK_STRUCT_FIELD(u32_t reference_identifier); 210 PACK_STRUCT_FIELD(u32_t reference_timestamp[2]); 211 PACK_STRUCT_FIELD(u32_t originate_timestamp[2]); 212 PACK_STRUCT_FIELD(u32_t receive_timestamp[2]); 213 PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]); 214} PACK_STRUCT_STRUCT; 215PACK_STRUCT_END 216#ifdef PACK_STRUCT_USE_INCLUDES 217# include "arch/epstruct.h" 218#endif 219 220/* function prototypes */ 221static void sntp_request(void *arg); 222 223/** The operating mode */ 224static u8_t sntp_opmode; 225 226/** The UDP pcb used by the SNTP client */ 227static struct udp_pcb *sntp_pcb; 228/** Names/Addresses of servers */ 229struct sntp_server { 230#if SNTP_SERVER_DNS 231 const char *name; 232#endif /* SNTP_SERVER_DNS */ 233 ip_addr_t addr; 234#if SNTP_MONITOR_SERVER_REACHABILITY 235 /** Reachability shift register as described in RFC 5905 */ 236 u8_t reachability; 237#endif /* SNTP_MONITOR_SERVER_REACHABILITY */ 238}; 239static struct sntp_server sntp_servers[SNTP_MAX_SERVERS]; 240 241#if SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 242static u8_t sntp_set_servers_from_dhcp; 243#endif /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */ 244#if SNTP_SUPPORT_MULTIPLE_SERVERS 245/** The currently used server (initialized to 0) */ 246static u8_t sntp_current_server; 247#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */ 248#define sntp_current_server 0 249#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */ 250 251#if SNTP_RETRY_TIMEOUT_EXP 252#define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT 253/** Retry time, initialized with SNTP_RETRY_TIMEOUT and doubled with each retry. */ 254static u32_t sntp_retry_timeout; 255#else /* SNTP_RETRY_TIMEOUT_EXP */ 256#define SNTP_RESET_RETRY_TIMEOUT() 257#define sntp_retry_timeout SNTP_RETRY_TIMEOUT 258#endif /* SNTP_RETRY_TIMEOUT_EXP */ 259 260#if SNTP_CHECK_RESPONSE >= 1 261/** Saves the last server address to compare with response */ 262static ip_addr_t sntp_last_server_address; 263#endif /* SNTP_CHECK_RESPONSE >= 1 */ 264 265#if SNTP_CHECK_RESPONSE >= 2 266/** Saves the last timestamp sent (which is sent back by the server) 267 * to compare against in response. Stored in network byte order. */ 268static struct sntp_time sntp_last_timestamp_sent; 269#endif /* SNTP_CHECK_RESPONSE >= 2 */ 270 271#if defined(LWIP_DEBUG) && !defined(sntp_format_time) 272/* Debug print helper. */ 273static const char * 274sntp_format_time(s32_t sec) 275{ 276 time_t ut; 277 ut = (u32_t)((u32_t)sec + DIFF_SEC_1970_2036); 278 return ctime(&ut); 279} 280#endif /* LWIP_DEBUG && !sntp_format_time */ 281 282/** 283 * SNTP processing of received timestamp 284 */ 285static void 286sntp_process(const struct sntp_timestamps *timestamps) 287{ 288 s32_t sec; 289 u32_t frac; 290 291 sec = (s32_t)lwip_ntohl(timestamps->xmit.sec); 292 frac = lwip_ntohl(timestamps->xmit.frac); 293 294#if SNTP_COMP_ROUNDTRIP 295# if SNTP_CHECK_RESPONSE >= 2 296 if (timestamps->recv.sec != 0 || timestamps->recv.frac != 0) 297# endif 298 { 299 s32_t dest_sec; 300 u32_t dest_frac; 301 u32_t step_sec; 302 303 /* Get the destination time stamp, i.e. the current system time */ 304 SNTP_GET_SYSTEM_TIME_NTP(dest_sec, dest_frac); 305 306 step_sec = (dest_sec < sec) ? ((u32_t)sec - (u32_t)dest_sec) 307 : ((u32_t)dest_sec - (u32_t)sec); 308 /* In order to avoid overflows, skip the compensation if the clock step 309 * is larger than about 34 years. */ 310 if ((step_sec >> 30) == 0) { 311 s64_t t1, t2, t3, t4; 312 313 t4 = SNTP_SEC_FRAC_TO_S64(dest_sec, dest_frac); 314 t3 = SNTP_SEC_FRAC_TO_S64(sec, frac); 315 t1 = SNTP_TIMESTAMP_TO_S64(timestamps->orig); 316 t2 = SNTP_TIMESTAMP_TO_S64(timestamps->recv); 317 /* Clock offset calculation according to RFC 4330 */ 318 t4 += ((t2 - t1) + (t3 - t4)) / 2; 319 320 sec = (s32_t)((u64_t)t4 >> 32); 321 frac = (u32_t)((u64_t)t4); 322 } 323 } 324#endif /* SNTP_COMP_ROUNDTRIP */ 325 326 SNTP_SET_SYSTEM_TIME_NTP(sec, frac); 327 LWIP_UNUSED_ARG(frac); /* might be unused if only seconds are set */ 328 LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %" U32_F " us\n", 329 sntp_format_time(sec), SNTP_FRAC_TO_US(frac))); 330} 331 332/** 333 * Initialize request struct to be sent to server. 334 */ 335static void 336sntp_initialize_request(struct sntp_msg *req) 337{ 338 memset(req, 0, SNTP_MSG_LEN); 339 req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT; 340 341#if SNTP_CHECK_RESPONSE >= 2 || SNTP_COMP_ROUNDTRIP 342 { 343 s32_t secs; 344 u32_t sec, frac; 345 /* Get the transmit timestamp */ 346 SNTP_GET_SYSTEM_TIME_NTP(secs, frac); 347 sec = lwip_htonl((u32_t)secs); 348 frac = lwip_htonl(frac); 349 350# if SNTP_CHECK_RESPONSE >= 2 351 sntp_last_timestamp_sent.sec = sec; 352 sntp_last_timestamp_sent.frac = frac; 353# endif 354 req->transmit_timestamp[0] = sec; 355 req->transmit_timestamp[1] = frac; 356 } 357#endif /* SNTP_CHECK_RESPONSE >= 2 || SNTP_COMP_ROUNDTRIP */ 358} 359 360/** 361 * Retry: send a new request (and increase retry timeout). 362 * 363 * @param arg is unused (only necessary to conform to sys_timeout) 364 */ 365static void 366sntp_retry(void *arg) 367{ 368 LWIP_UNUSED_ARG(arg); 369 370 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_retry: Next request will be sent in %"U32_F" ms\n", 371 sntp_retry_timeout)); 372 373 /* set up a timer to send a retry and increase the retry delay */ 374 sys_untimeout(sntp_request, NULL); 375 sys_timeout(sntp_retry_timeout, sntp_request, NULL); 376 377#if SNTP_RETRY_TIMEOUT_EXP 378 { 379 u32_t new_retry_timeout; 380 /* increase the timeout for next retry */ 381 new_retry_timeout = sntp_retry_timeout << 1; 382 /* limit to maximum timeout and prevent overflow */ 383 if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) && 384 (new_retry_timeout > sntp_retry_timeout)) { 385 sntp_retry_timeout = new_retry_timeout; 386 } else { 387 sntp_retry_timeout = SNTP_RETRY_TIMEOUT_MAX; 388 } 389 } 390#endif /* SNTP_RETRY_TIMEOUT_EXP */ 391} 392 393#if SNTP_SUPPORT_MULTIPLE_SERVERS 394/** 395 * If Kiss-of-Death is received (or another packet parsing error), 396 * try the next server or retry the current server and increase the retry 397 * timeout if only one server is available. 398 * (implicitly, SNTP_MAX_SERVERS > 1) 399 * 400 * @param arg is unused (only necessary to conform to sys_timeout) 401 */ 402static void 403sntp_try_next_server(void *arg) 404{ 405 u8_t old_server, i; 406 LWIP_UNUSED_ARG(arg); 407 408 old_server = sntp_current_server; 409 for (i = 0; i < SNTP_MAX_SERVERS - 1; i++) { 410 sntp_current_server++; 411 if (sntp_current_server >= SNTP_MAX_SERVERS) { 412 sntp_current_server = 0; 413 } 414 if (!ip_addr_isany(&sntp_servers[sntp_current_server].addr) 415#if SNTP_SERVER_DNS 416 || (sntp_servers[sntp_current_server].name != NULL) 417#endif 418 ) { 419 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_try_next_server: Sending request to server %"U16_F"\n", 420 (u16_t)sntp_current_server)); 421 /* new server: reset retry timeout */ 422 SNTP_RESET_RETRY_TIMEOUT(); 423 /* instantly send a request to the next server */ 424 sntp_request(NULL); 425 return; 426 } 427 } 428 /* no other valid server found */ 429 sntp_current_server = old_server; 430 sntp_retry(NULL); 431} 432#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */ 433/* Always retry on error if only one server is supported */ 434#define sntp_try_next_server sntp_retry 435#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */ 436 437/** UDP recv callback for the sntp pcb */ 438static void 439sntp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) 440{ 441 struct sntp_timestamps timestamps; 442 u8_t mode; 443 u8_t stratum; 444 err_t err; 445 446 LWIP_UNUSED_ARG(arg); 447 LWIP_UNUSED_ARG(pcb); 448 449 err = ERR_ARG; 450#if SNTP_CHECK_RESPONSE >= 1 451 /* check server address and port */ 452 if (((sntp_opmode != SNTP_OPMODE_POLL) || ip_addr_cmp(addr, &sntp_last_server_address)) && 453 (port == SNTP_PORT)) 454#else /* SNTP_CHECK_RESPONSE >= 1 */ 455 LWIP_UNUSED_ARG(addr); 456 LWIP_UNUSED_ARG(port); 457#endif /* SNTP_CHECK_RESPONSE >= 1 */ 458 { 459 /* process the response */ 460 if (p->tot_len == SNTP_MSG_LEN) { 461 mode = pbuf_get_at(p, SNTP_OFFSET_LI_VN_MODE) & SNTP_MODE_MASK; 462 /* if this is a SNTP response... */ 463 if (((sntp_opmode == SNTP_OPMODE_POLL) && (mode == SNTP_MODE_SERVER)) || 464 ((sntp_opmode == SNTP_OPMODE_LISTENONLY) && (mode == SNTP_MODE_BROADCAST))) { 465 stratum = pbuf_get_at(p, SNTP_OFFSET_STRATUM); 466 467 if (stratum == SNTP_STRATUM_KOD) { 468 /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ 469 err = SNTP_ERR_KOD; 470 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n")); 471 } else { 472 pbuf_copy_partial(p, ×tamps, sizeof(timestamps), SNTP_OFFSET_TIMESTAMPS); 473#if SNTP_CHECK_RESPONSE >= 2 474 /* check originate_timetamp against sntp_last_timestamp_sent */ 475 if (timestamps.orig.sec != sntp_last_timestamp_sent.sec || 476 timestamps.orig.frac != sntp_last_timestamp_sent.frac) { 477 LWIP_DEBUGF(SNTP_DEBUG_WARN, 478 ("sntp_recv: Invalid originate timestamp in response\n")); 479 } else 480#endif /* SNTP_CHECK_RESPONSE >= 2 */ 481 /* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */ 482 { 483 /* correct answer */ 484 err = ERR_OK; 485 } 486 } 487 } else { 488 LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode)); 489 /* wait for correct response */ 490 err = ERR_TIMEOUT; 491 } 492 } else { 493 LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len)); 494 } 495 } 496#if SNTP_CHECK_RESPONSE >= 1 497 else { 498 /* packet from wrong remote address or port, wait for correct response */ 499 err = ERR_TIMEOUT; 500 } 501#endif /* SNTP_CHECK_RESPONSE >= 1 */ 502 503 pbuf_free(p); 504 505 if (err == ERR_OK) { 506 /* correct packet received: process it it */ 507 sntp_process(×tamps); 508 509#if SNTP_MONITOR_SERVER_REACHABILITY 510 /* indicate that server responded */ 511 sntp_servers[sntp_current_server].reachability |= 1; 512#endif /* SNTP_MONITOR_SERVER_REACHABILITY */ 513 /* Set up timeout for next request (only if poll response was received)*/ 514 if (sntp_opmode == SNTP_OPMODE_POLL) { 515 u32_t sntp_update_delay; 516 sys_untimeout(sntp_try_next_server, NULL); 517 sys_untimeout(sntp_request, NULL); 518 519 /* Correct response, reset retry timeout */ 520 SNTP_RESET_RETRY_TIMEOUT(); 521 522 sntp_update_delay = (u32_t)SNTP_UPDATE_DELAY; 523 sys_timeout(sntp_update_delay, sntp_request, NULL); 524 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n", 525 sntp_update_delay)); 526 } 527 } else if (err == SNTP_ERR_KOD) { 528 /* KOD errors are only processed in case of an explicit poll response */ 529 if (sntp_opmode == SNTP_OPMODE_POLL) { 530 /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ 531 sntp_try_next_server(NULL); 532 } 533 } else { 534 /* ignore any broken packet, poll mode: retry after timeout to avoid flooding */ 535 } 536} 537 538/** Actually send an sntp request to a server. 539 * 540 * @param server_addr resolved IP address of the SNTP server 541 */ 542static void 543sntp_send_request(const ip_addr_t *server_addr) 544{ 545 struct pbuf *p; 546 547 LWIP_ASSERT("server_addr != NULL", server_addr != NULL); 548 549 p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM); 550 if (p != NULL) { 551 struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload; 552 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n")); 553 /* initialize request message */ 554 sntp_initialize_request(sntpmsg); 555 /* send request */ 556 udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT); 557 /* free the pbuf after sending it */ 558 pbuf_free(p); 559#if SNTP_MONITOR_SERVER_REACHABILITY 560 /* indicate new packet has been sent */ 561 sntp_servers[sntp_current_server].reachability <<= 1; 562#endif /* SNTP_MONITOR_SERVER_REACHABILITY */ 563 /* set up receive timeout: try next server or retry on timeout */ 564 sys_untimeout(sntp_try_next_server, NULL); 565 sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL); 566#if SNTP_CHECK_RESPONSE >= 1 567 /* save server address to verify it in sntp_recv */ 568 ip_addr_copy(sntp_last_server_address, *server_addr); 569#endif /* SNTP_CHECK_RESPONSE >= 1 */ 570 } else { 571 LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n", 572 (u32_t)SNTP_RETRY_TIMEOUT)); 573 /* out of memory: set up a timer to send a retry */ 574 sys_untimeout(sntp_request, NULL); 575 sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL); 576 } 577} 578 579#if SNTP_SERVER_DNS 580/** 581 * DNS found callback when using DNS names as server address. 582 */ 583static void 584sntp_dns_found(const char *hostname, const ip_addr_t *ipaddr, void *arg) 585{ 586 LWIP_UNUSED_ARG(hostname); 587 LWIP_UNUSED_ARG(arg); 588 589 if (ipaddr != NULL) { 590 /* Address resolved, send request */ 591 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_dns_found: Server address resolved, sending request\n")); 592 sntp_servers[sntp_current_server].addr = *ipaddr; 593 sntp_send_request(ipaddr); 594 } else { 595 /* DNS resolving failed -> try another server */ 596 LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_dns_found: Failed to resolve server address resolved, trying next server\n")); 597 sntp_try_next_server(NULL); 598 } 599} 600#endif /* SNTP_SERVER_DNS */ 601 602/** 603 * Send out an sntp request. 604 * 605 * @param arg is unused (only necessary to conform to sys_timeout) 606 */ 607static void 608sntp_request(void *arg) 609{ 610 ip_addr_t sntp_server_address; 611 err_t err; 612 613 LWIP_UNUSED_ARG(arg); 614 615 /* initialize SNTP server address */ 616#if SNTP_SERVER_DNS 617 if (sntp_servers[sntp_current_server].name) { 618 /* always resolve the name and rely on dns-internal caching & timeout */ 619 ip_addr_set_zero(&sntp_servers[sntp_current_server].addr); 620 err = dns_gethostbyname(sntp_servers[sntp_current_server].name, &sntp_server_address, 621 sntp_dns_found, NULL); 622 if (err == ERR_INPROGRESS) { 623 /* DNS request sent, wait for sntp_dns_found being called */ 624 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n")); 625 return; 626 } else if (err == ERR_OK) { 627 sntp_servers[sntp_current_server].addr = sntp_server_address; 628 } 629 } else 630#endif /* SNTP_SERVER_DNS */ 631 { 632 sntp_server_address = sntp_servers[sntp_current_server].addr; 633 err = (ip_addr_isany_val(sntp_server_address)) ? ERR_ARG : ERR_OK; 634 } 635 636 if (err == ERR_OK) { 637 LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_request: current server address is %s\n", 638 ipaddr_ntoa(&sntp_server_address))); 639 sntp_send_request(&sntp_server_address); 640 } else { 641 /* address conversion failed, try another server */ 642 LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n")); 643 sys_untimeout(sntp_try_next_server, NULL); 644 sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL); 645 } 646} 647 648/** 649 * @ingroup sntp 650 * Initialize this module. 651 * Send out request instantly or after SNTP_STARTUP_DELAY(_FUNC). 652 */ 653void 654sntp_init(void) 655{ 656 /* LWIP_ASSERT_CORE_LOCKED(); is checked by udp_new() */ 657 LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_init: SNTP initialised\n")); 658 659#ifdef SNTP_SERVER_ADDRESS 660#if SNTP_SERVER_DNS 661 sntp_setservername(0, SNTP_SERVER_ADDRESS); 662#else 663#error SNTP_SERVER_ADDRESS string not supported SNTP_SERVER_DNS==0 664#endif 665#endif /* SNTP_SERVER_ADDRESS */ 666 667 if (sntp_pcb == NULL) { 668 sntp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); 669 LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL); 670 if (sntp_pcb != NULL) { 671 udp_recv(sntp_pcb, sntp_recv, NULL); 672 673 if (sntp_opmode == SNTP_OPMODE_POLL) { 674 SNTP_RESET_RETRY_TIMEOUT(); 675#if SNTP_STARTUP_DELAY 676 sys_timeout((u32_t)SNTP_STARTUP_DELAY_FUNC, sntp_request, NULL); 677#else 678 sntp_request(NULL); 679#endif 680 } else if (sntp_opmode == SNTP_OPMODE_LISTENONLY) { 681 ip_set_option(sntp_pcb, SOF_BROADCAST); 682 udp_bind(sntp_pcb, IP_ANY_TYPE, SNTP_PORT); 683 } 684 } 685 } 686} 687 688/** 689 * @ingroup sntp 690 * Stop this module. 691 */ 692void 693sntp_stop(void) 694{ 695 LWIP_ASSERT_CORE_LOCKED(); 696 if (sntp_pcb != NULL) { 697#if SNTP_MONITOR_SERVER_REACHABILITY 698 u8_t i; 699 for (i = 0; i < SNTP_MAX_SERVERS; i++) { 700 sntp_servers[i].reachability = 0; 701 } 702#endif /* SNTP_MONITOR_SERVER_REACHABILITY */ 703 sys_untimeout(sntp_request, NULL); 704 sys_untimeout(sntp_try_next_server, NULL); 705 udp_remove(sntp_pcb); 706 sntp_pcb = NULL; 707 } 708} 709 710/** 711 * @ingroup sntp 712 * Get enabled state. 713 */ 714u8_t sntp_enabled(void) 715{ 716 return (sntp_pcb != NULL) ? 1 : 0; 717} 718 719/** 720 * @ingroup sntp 721 * Sets the operating mode. 722 * @param operating_mode one of the available operating modes 723 */ 724void 725sntp_setoperatingmode(u8_t operating_mode) 726{ 727 LWIP_ASSERT_CORE_LOCKED(); 728 LWIP_ASSERT("Invalid operating mode", operating_mode <= SNTP_OPMODE_LISTENONLY); 729 LWIP_ASSERT("Operating mode must not be set while SNTP client is running", sntp_pcb == NULL); 730 sntp_opmode = operating_mode; 731} 732 733/** 734 * @ingroup sntp 735 * Gets the operating mode. 736 */ 737u8_t 738sntp_getoperatingmode(void) 739{ 740 return sntp_opmode; 741} 742 743#if SNTP_MONITOR_SERVER_REACHABILITY 744/** 745 * @ingroup sntp 746 * Gets the server reachability shift register as described in RFC 5905. 747 * 748 * @param idx the index of the NTP server 749 */ 750u8_t 751sntp_getreachability(u8_t idx) 752{ 753 if (idx < SNTP_MAX_SERVERS) { 754 return sntp_servers[idx].reachability; 755 } 756 return 0; 757} 758#endif /* SNTP_MONITOR_SERVER_REACHABILITY */ 759 760#if SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 761/** 762 * Config SNTP server handling by IP address, name, or DHCP; clear table 763 * @param set_servers_from_dhcp enable or disable getting server addresses from dhcp 764 */ 765void 766sntp_servermode_dhcp(int set_servers_from_dhcp) 767{ 768 u8_t new_mode = set_servers_from_dhcp ? 1 : 0; 769 LWIP_ASSERT_CORE_LOCKED(); 770 if (sntp_set_servers_from_dhcp != new_mode) { 771 sntp_set_servers_from_dhcp = new_mode; 772 } 773} 774#endif /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */ 775 776/** 777 * @ingroup sntp 778 * Initialize one of the NTP servers by IP address 779 * 780 * @param idx the index of the NTP server to set must be < SNTP_MAX_SERVERS 781 * @param server IP address of the NTP server to set 782 */ 783void 784sntp_setserver(u8_t idx, const ip_addr_t *server) 785{ 786 LWIP_ASSERT_CORE_LOCKED(); 787 if (idx < SNTP_MAX_SERVERS) { 788 if (server != NULL) { 789 sntp_servers[idx].addr = (*server); 790 } else { 791 ip_addr_set_zero(&sntp_servers[idx].addr); 792 } 793#if SNTP_SERVER_DNS 794 sntp_servers[idx].name = NULL; 795#endif 796 } 797} 798 799#if LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP 800/** 801 * Initialize one of the NTP servers by IP address, required by DHCP 802 * 803 * @param num the index of the NTP server to set must be < SNTP_MAX_SERVERS 804 * @param server IP address of the NTP server to set 805 */ 806void 807dhcp_set_ntp_servers(u8_t num, const ip4_addr_t *server) 808{ 809 LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u.%u.%u.%u as NTP server #%u via DHCP\n", 810 (sntp_set_servers_from_dhcp ? "Got" : "Rejected"), 811 ip4_addr1(server), ip4_addr2(server), ip4_addr3(server), ip4_addr4(server), num)); 812 if (sntp_set_servers_from_dhcp && num) { 813 u8_t i; 814 for (i = 0; (i < num) && (i < SNTP_MAX_SERVERS); i++) { 815 ip_addr_t addr; 816 ip_addr_copy_from_ip4(addr, server[i]); 817 sntp_setserver(i, &addr); 818 } 819 for (i = num; i < SNTP_MAX_SERVERS; i++) { 820 sntp_setserver(i, NULL); 821 } 822 } 823} 824#endif /* LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP */ 825 826#if LWIP_IPV6_DHCP6 && SNTP_GET_SERVERS_FROM_DHCPV6 827/** 828 * Initialize one of the NTP servers by IP address, required by DHCPV6 829 * 830 * @param num the number of NTP server addresses to set must be < SNTP_MAX_SERVERS 831 * @param server array of IP address of the NTP servers to set 832 */ 833void 834dhcp6_set_ntp_servers(u8_t num_ntp_servers, ip_addr_t* ntp_server_addrs) 835{ 836 LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u NTP server(s) via DHCPv6\n", 837 (sntp_set_servers_from_dhcp ? "Got" : "Rejected"), 838 num_ntp_servers)); 839 if (sntp_set_servers_from_dhcp && num_ntp_servers) { 840 u8_t i; 841 for (i = 0; (i < num_ntp_servers) && (i < SNTP_MAX_SERVERS); i++) { 842 LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: NTP server %u: %s\n", 843 i, ipaddr_ntoa(&ntp_server_addrs[i]))); 844 sntp_setserver(i, &ntp_server_addrs[i]); 845 } 846 for (i = num_ntp_servers; i < SNTP_MAX_SERVERS; i++) { 847 sntp_setserver(i, NULL); 848 } 849 } 850} 851#endif /* LWIP_DHCPv6 && SNTP_GET_SERVERS_FROM_DHCPV6 */ 852 853/** 854 * @ingroup sntp 855 * Obtain one of the currently configured by IP address (or DHCP) NTP servers 856 * 857 * @param idx the index of the NTP server 858 * @return IP address of the indexed NTP server or "ip_addr_any" if the NTP 859 * server has not been configured by address (or at all). 860 */ 861const ip_addr_t * 862sntp_getserver(u8_t idx) 863{ 864 if (idx < SNTP_MAX_SERVERS) { 865 return &sntp_servers[idx].addr; 866 } 867 return IP_ADDR_ANY; 868} 869 870#if SNTP_SERVER_DNS 871/** 872 * Initialize one of the NTP servers by name 873 * 874 * @param idx the index of the NTP server to set must be < SNTP_MAX_SERVERS 875 * @param server DNS name of the NTP server to set, to be resolved at contact time 876 */ 877void 878sntp_setservername(u8_t idx, const char *server) 879{ 880 LWIP_ASSERT_CORE_LOCKED(); 881 if (idx < SNTP_MAX_SERVERS) { 882 sntp_servers[idx].name = server; 883 } 884} 885 886/** 887 * Obtain one of the currently configured by name NTP servers. 888 * 889 * @param idx the index of the NTP server 890 * @return IP address of the indexed NTP server or NULL if the NTP 891 * server has not been configured by name (or at all) 892 */ 893const char * 894sntp_getservername(u8_t idx) 895{ 896 if (idx < SNTP_MAX_SERVERS) { 897 return sntp_servers[idx].name; 898 } 899 return NULL; 900} 901#endif /* SNTP_SERVER_DNS */ 902 903#endif /* LWIP_UDP */ 904