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 */ 176 struct sntp_time { 177 u32_t sec; 178 u32_t frac; 179 }; 180 181 /** 182 * Timestamps to be extracted from the NTP header. 183 */ 184 struct 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 201 PACK_STRUCT_BEGIN 202 struct 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; 215 PACK_STRUCT_END 216 #ifdef PACK_STRUCT_USE_INCLUDES 217 # include "arch/epstruct.h" 218 #endif 219 220 /* function prototypes */ 221 static void sntp_request(void *arg); 222 223 /** The operating mode */ 224 static u8_t sntp_opmode; 225 226 /** The UDP pcb used by the SNTP client */ 227 static struct udp_pcb *sntp_pcb; 228 /** Names/Addresses of servers */ 229 struct 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 }; 239 static struct sntp_server sntp_servers[SNTP_MAX_SERVERS]; 240 241 #if SNTP_GET_SERVERS_FROM_DHCP 242 static u8_t sntp_set_servers_from_dhcp; 243 #endif /* SNTP_GET_SERVERS_FROM_DHCP */ 244 #if SNTP_SUPPORT_MULTIPLE_SERVERS 245 /** The currently used server (initialized to 0) */ 246 static 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. */ 254 static 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 */ 262 static 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. */ 268 static 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. */ 273 static const char * 274 sntp_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 */ 285 static void 286 sntp_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 */ 335 static void 336 sntp_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 */ 365 static void 366 sntp_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_timeout(sntp_retry_timeout, sntp_request, NULL); 375 376 #if SNTP_RETRY_TIMEOUT_EXP 377 { 378 u32_t new_retry_timeout; 379 /* increase the timeout for next retry */ 380 new_retry_timeout = sntp_retry_timeout << 1; 381 /* limit to maximum timeout and prevent overflow */ 382 if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) && 383 (new_retry_timeout > sntp_retry_timeout)) { 384 sntp_retry_timeout = new_retry_timeout; 385 } 386 } 387 #endif /* SNTP_RETRY_TIMEOUT_EXP */ 388 } 389 390 #if SNTP_SUPPORT_MULTIPLE_SERVERS 391 /** 392 * If Kiss-of-Death is received (or another packet parsing error), 393 * try the next server or retry the current server and increase the retry 394 * timeout if only one server is available. 395 * (implicitly, SNTP_MAX_SERVERS > 1) 396 * 397 * @param arg is unused (only necessary to conform to sys_timeout) 398 */ 399 static void 400 sntp_try_next_server(void *arg) 401 { 402 u8_t old_server, i; 403 LWIP_UNUSED_ARG(arg); 404 405 old_server = sntp_current_server; 406 for (i = 0; i < SNTP_MAX_SERVERS - 1; i++) { 407 sntp_current_server++; 408 if (sntp_current_server >= SNTP_MAX_SERVERS) { 409 sntp_current_server = 0; 410 } 411 if (!ip_addr_isany(&sntp_servers[sntp_current_server].addr) 412 #if SNTP_SERVER_DNS 413 || (sntp_servers[sntp_current_server].name != NULL) 414 #endif 415 ) { 416 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_try_next_server: Sending request to server %"U16_F"\n", 417 (u16_t)sntp_current_server)); 418 /* new server: reset retry timeout */ 419 SNTP_RESET_RETRY_TIMEOUT(); 420 /* instantly send a request to the next server */ 421 sntp_request(NULL); 422 return; 423 } 424 } 425 /* no other valid server found */ 426 sntp_current_server = old_server; 427 sntp_retry(NULL); 428 } 429 #else /* SNTP_SUPPORT_MULTIPLE_SERVERS */ 430 /* Always retry on error if only one server is supported */ 431 #define sntp_try_next_server sntp_retry 432 #endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */ 433 434 /** UDP recv callback for the sntp pcb */ 435 static void 436 sntp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) 437 { 438 struct sntp_timestamps timestamps; 439 u8_t mode; 440 u8_t stratum; 441 err_t err; 442 443 LWIP_UNUSED_ARG(arg); 444 LWIP_UNUSED_ARG(pcb); 445 446 err = ERR_ARG; 447 #if SNTP_CHECK_RESPONSE >= 1 448 /* check server address and port */ 449 if (((sntp_opmode != SNTP_OPMODE_POLL) || ip_addr_cmp(addr, &sntp_last_server_address)) && 450 (port == SNTP_PORT)) 451 #else /* SNTP_CHECK_RESPONSE >= 1 */ 452 LWIP_UNUSED_ARG(addr); 453 LWIP_UNUSED_ARG(port); 454 #endif /* SNTP_CHECK_RESPONSE >= 1 */ 455 { 456 /* process the response */ 457 if (p->tot_len == SNTP_MSG_LEN) { 458 mode = pbuf_get_at(p, SNTP_OFFSET_LI_VN_MODE) & SNTP_MODE_MASK; 459 /* if this is a SNTP response... */ 460 if (((sntp_opmode == SNTP_OPMODE_POLL) && (mode == SNTP_MODE_SERVER)) || 461 ((sntp_opmode == SNTP_OPMODE_LISTENONLY) && (mode == SNTP_MODE_BROADCAST))) { 462 stratum = pbuf_get_at(p, SNTP_OFFSET_STRATUM); 463 464 if (stratum == SNTP_STRATUM_KOD) { 465 /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ 466 err = SNTP_ERR_KOD; 467 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n")); 468 } else { 469 pbuf_copy_partial(p, ×tamps, sizeof(timestamps), SNTP_OFFSET_TIMESTAMPS); 470 #if SNTP_CHECK_RESPONSE >= 2 471 /* check originate_timetamp against sntp_last_timestamp_sent */ 472 if (timestamps.orig.sec != sntp_last_timestamp_sent.sec || 473 timestamps.orig.frac != sntp_last_timestamp_sent.frac) { 474 LWIP_DEBUGF(SNTP_DEBUG_WARN, 475 ("sntp_recv: Invalid originate timestamp in response\n")); 476 } else 477 #endif /* SNTP_CHECK_RESPONSE >= 2 */ 478 /* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */ 479 { 480 /* correct answer */ 481 err = ERR_OK; 482 } 483 } 484 } else { 485 LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode)); 486 /* wait for correct response */ 487 err = ERR_TIMEOUT; 488 } 489 } else { 490 LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len)); 491 } 492 } 493 #if SNTP_CHECK_RESPONSE >= 1 494 else { 495 /* packet from wrong remote address or port, wait for correct response */ 496 err = ERR_TIMEOUT; 497 } 498 #endif /* SNTP_CHECK_RESPONSE >= 1 */ 499 500 pbuf_free(p); 501 502 if (err == ERR_OK) { 503 /* correct packet received: process it it */ 504 sntp_process(×tamps); 505 506 #if SNTP_MONITOR_SERVER_REACHABILITY 507 /* indicate that server responded */ 508 sntp_servers[sntp_current_server].reachability |= 1; 509 #endif /* SNTP_MONITOR_SERVER_REACHABILITY */ 510 /* Set up timeout for next request (only if poll response was received)*/ 511 if (sntp_opmode == SNTP_OPMODE_POLL) { 512 u32_t sntp_update_delay; 513 sys_untimeout(sntp_try_next_server, NULL); 514 sys_untimeout(sntp_request, NULL); 515 516 /* Correct response, reset retry timeout */ 517 SNTP_RESET_RETRY_TIMEOUT(); 518 519 sntp_update_delay = (u32_t)SNTP_UPDATE_DELAY; 520 sys_timeout(sntp_update_delay, sntp_request, NULL); 521 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n", 522 sntp_update_delay)); 523 } 524 } else if (err == SNTP_ERR_KOD) { 525 /* KOD errors are only processed in case of an explicit poll response */ 526 if (sntp_opmode == SNTP_OPMODE_POLL) { 527 /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ 528 sntp_try_next_server(NULL); 529 } 530 } else { 531 /* ignore any broken packet, poll mode: retry after timeout to avoid flooding */ 532 } 533 } 534 535 /** Actually send an sntp request to a server. 536 * 537 * @param server_addr resolved IP address of the SNTP server 538 */ 539 static void 540 sntp_send_request(const ip_addr_t *server_addr) 541 { 542 struct pbuf *p; 543 544 LWIP_ASSERT("server_addr != NULL", server_addr != NULL); 545 546 p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM); 547 if (p != NULL) { 548 struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload; 549 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n")); 550 /* initialize request message */ 551 sntp_initialize_request(sntpmsg); 552 /* send request */ 553 udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT); 554 /* free the pbuf after sending it */ 555 pbuf_free(p); 556 #if SNTP_MONITOR_SERVER_REACHABILITY 557 /* indicate new packet has been sent */ 558 sntp_servers[sntp_current_server].reachability <<= 1; 559 #endif /* SNTP_MONITOR_SERVER_REACHABILITY */ 560 /* set up receive timeout: try next server or retry on timeout */ 561 sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL); 562 #if SNTP_CHECK_RESPONSE >= 1 563 /* save server address to verify it in sntp_recv */ 564 ip_addr_copy(sntp_last_server_address, *server_addr); 565 #endif /* SNTP_CHECK_RESPONSE >= 1 */ 566 } else { 567 LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n", 568 (u32_t)SNTP_RETRY_TIMEOUT)); 569 /* out of memory: set up a timer to send a retry */ 570 sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL); 571 } 572 } 573 574 #if SNTP_SERVER_DNS 575 /** 576 * DNS found callback when using DNS names as server address. 577 */ 578 static void 579 sntp_dns_found(const char *hostname, const ip_addr_t *ipaddr, void *arg) 580 { 581 LWIP_UNUSED_ARG(hostname); 582 LWIP_UNUSED_ARG(arg); 583 584 if (ipaddr != NULL) { 585 /* Address resolved, send request */ 586 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_dns_found: Server address resolved, sending request\n")); 587 sntp_servers[sntp_current_server].addr = *ipaddr; 588 sntp_send_request(ipaddr); 589 } else { 590 /* DNS resolving failed -> try another server */ 591 LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_dns_found: Failed to resolve server address resolved, trying next server\n")); 592 sntp_try_next_server(NULL); 593 } 594 } 595 #endif /* SNTP_SERVER_DNS */ 596 597 /** 598 * Send out an sntp request. 599 * 600 * @param arg is unused (only necessary to conform to sys_timeout) 601 */ 602 static void 603 sntp_request(void *arg) 604 { 605 ip_addr_t sntp_server_address; 606 err_t err; 607 608 LWIP_UNUSED_ARG(arg); 609 610 /* initialize SNTP server address */ 611 #if SNTP_SERVER_DNS 612 if (sntp_servers[sntp_current_server].name) { 613 /* always resolve the name and rely on dns-internal caching & timeout */ 614 ip_addr_set_zero(&sntp_servers[sntp_current_server].addr); 615 err = dns_gethostbyname(sntp_servers[sntp_current_server].name, &sntp_server_address, 616 sntp_dns_found, NULL); 617 if (err == ERR_INPROGRESS) { 618 /* DNS request sent, wait for sntp_dns_found being called */ 619 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n")); 620 return; 621 } else if (err == ERR_OK) { 622 sntp_servers[sntp_current_server].addr = sntp_server_address; 623 } 624 } else 625 #endif /* SNTP_SERVER_DNS */ 626 { 627 sntp_server_address = sntp_servers[sntp_current_server].addr; 628 err = (ip_addr_isany_val(sntp_server_address)) ? ERR_ARG : ERR_OK; 629 } 630 631 if (err == ERR_OK) { 632 LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_request: current server address is %s\n", 633 ipaddr_ntoa(&sntp_server_address))); 634 sntp_send_request(&sntp_server_address); 635 } else { 636 /* address conversion failed, try another server */ 637 LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n")); 638 sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL); 639 } 640 } 641 642 /** 643 * @ingroup sntp 644 * Initialize this module. 645 * Send out request instantly or after SNTP_STARTUP_DELAY(_FUNC). 646 */ 647 void 648 sntp_init(void) 649 { 650 /* LWIP_ASSERT_CORE_LOCKED(); is checked by udp_new() */ 651 652 #ifdef SNTP_SERVER_ADDRESS 653 #if SNTP_SERVER_DNS 654 sntp_setservername(0, SNTP_SERVER_ADDRESS); 655 #else 656 #error SNTP_SERVER_ADDRESS string not supported SNTP_SERVER_DNS==0 657 #endif 658 #endif /* SNTP_SERVER_ADDRESS */ 659 660 if (sntp_pcb == NULL) { 661 sntp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); 662 LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL); 663 if (sntp_pcb != NULL) { 664 udp_recv(sntp_pcb, sntp_recv, NULL); 665 666 if (sntp_opmode == SNTP_OPMODE_POLL) { 667 SNTP_RESET_RETRY_TIMEOUT(); 668 #if SNTP_STARTUP_DELAY 669 sys_timeout((u32_t)SNTP_STARTUP_DELAY_FUNC, sntp_request, NULL); 670 #else 671 sntp_request(NULL); 672 #endif 673 } else if (sntp_opmode == SNTP_OPMODE_LISTENONLY) { 674 ip_set_option(sntp_pcb, SOF_BROADCAST); 675 udp_bind(sntp_pcb, IP_ANY_TYPE, SNTP_PORT); 676 } 677 } 678 } 679 } 680 681 /** 682 * @ingroup sntp 683 * Stop this module. 684 */ 685 void 686 sntp_stop(void) 687 { 688 LWIP_ASSERT_CORE_LOCKED(); 689 if (sntp_pcb != NULL) { 690 #if SNTP_MONITOR_SERVER_REACHABILITY 691 u8_t i; 692 for (i = 0; i < SNTP_MAX_SERVERS; i++) { 693 sntp_servers[i].reachability = 0; 694 } 695 #endif /* SNTP_MONITOR_SERVER_REACHABILITY */ 696 sys_untimeout(sntp_request, NULL); 697 sys_untimeout(sntp_try_next_server, NULL); 698 udp_remove(sntp_pcb); 699 sntp_pcb = NULL; 700 } 701 } 702 703 /** 704 * @ingroup sntp 705 * Get enabled state. 706 */ 707 u8_t sntp_enabled(void) 708 { 709 return (sntp_pcb != NULL) ? 1 : 0; 710 } 711 712 /** 713 * @ingroup sntp 714 * Sets the operating mode. 715 * @param operating_mode one of the available operating modes 716 */ 717 void 718 sntp_setoperatingmode(u8_t operating_mode) 719 { 720 LWIP_ASSERT_CORE_LOCKED(); 721 LWIP_ASSERT("Invalid operating mode", operating_mode <= SNTP_OPMODE_LISTENONLY); 722 LWIP_ASSERT("Operating mode must not be set while SNTP client is running", sntp_pcb == NULL); 723 sntp_opmode = operating_mode; 724 } 725 726 /** 727 * @ingroup sntp 728 * Gets the operating mode. 729 */ 730 u8_t 731 sntp_getoperatingmode(void) 732 { 733 return sntp_opmode; 734 } 735 736 #if SNTP_MONITOR_SERVER_REACHABILITY 737 /** 738 * @ingroup sntp 739 * Gets the server reachability shift register as described in RFC 5905. 740 * 741 * @param idx the index of the NTP server 742 */ 743 u8_t 744 sntp_getreachability(u8_t idx) 745 { 746 if (idx < SNTP_MAX_SERVERS) { 747 return sntp_servers[idx].reachability; 748 } 749 return 0; 750 } 751 #endif /* SNTP_MONITOR_SERVER_REACHABILITY */ 752 753 #if SNTP_GET_SERVERS_FROM_DHCP 754 /** 755 * Config SNTP server handling by IP address, name, or DHCP; clear table 756 * @param set_servers_from_dhcp enable or disable getting server addresses from dhcp 757 */ 758 void 759 sntp_servermode_dhcp(int set_servers_from_dhcp) 760 { 761 u8_t new_mode = set_servers_from_dhcp ? 1 : 0; 762 LWIP_ASSERT_CORE_LOCKED(); 763 if (sntp_set_servers_from_dhcp != new_mode) { 764 sntp_set_servers_from_dhcp = new_mode; 765 } 766 } 767 #endif /* SNTP_GET_SERVERS_FROM_DHCP */ 768 769 /** 770 * @ingroup sntp 771 * Initialize one of the NTP servers by IP address 772 * 773 * @param idx the index of the NTP server to set must be < SNTP_MAX_SERVERS 774 * @param server IP address of the NTP server to set 775 */ 776 void 777 sntp_setserver(u8_t idx, const ip_addr_t *server) 778 { 779 LWIP_ASSERT_CORE_LOCKED(); 780 if (idx < SNTP_MAX_SERVERS) { 781 if (server != NULL) { 782 sntp_servers[idx].addr = (*server); 783 } else { 784 ip_addr_set_zero(&sntp_servers[idx].addr); 785 } 786 #if SNTP_SERVER_DNS 787 sntp_servers[idx].name = NULL; 788 #endif 789 } 790 } 791 792 #if LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP 793 /** 794 * Initialize one of the NTP servers by IP address, required by DHCP 795 * 796 * @param num the index of the NTP server to set must be < SNTP_MAX_SERVERS 797 * @param server IP address of the NTP server to set 798 */ 799 void 800 dhcp_set_ntp_servers(u8_t num, const ip4_addr_t *server) 801 { 802 LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u.%u.%u.%u as NTP server #%u via DHCP\n", 803 (sntp_set_servers_from_dhcp ? "Got" : "Rejected"), 804 ip4_addr1(server), ip4_addr2(server), ip4_addr3(server), ip4_addr4(server), num)); 805 if (sntp_set_servers_from_dhcp && num) { 806 u8_t i; 807 for (i = 0; (i < num) && (i < SNTP_MAX_SERVERS); i++) { 808 ip_addr_t addr; 809 ip_addr_copy_from_ip4(addr, server[i]); 810 sntp_setserver(i, &addr); 811 } 812 for (i = num; i < SNTP_MAX_SERVERS; i++) { 813 sntp_setserver(i, NULL); 814 } 815 } 816 } 817 #endif /* LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP */ 818 819 /** 820 * @ingroup sntp 821 * Obtain one of the currently configured by IP address (or DHCP) NTP servers 822 * 823 * @param idx the index of the NTP server 824 * @return IP address of the indexed NTP server or "ip_addr_any" if the NTP 825 * server has not been configured by address (or at all). 826 */ 827 const ip_addr_t * 828 sntp_getserver(u8_t idx) 829 { 830 if (idx < SNTP_MAX_SERVERS) { 831 return &sntp_servers[idx].addr; 832 } 833 return IP_ADDR_ANY; 834 } 835 836 #if SNTP_SERVER_DNS 837 /** 838 * Initialize one of the NTP servers by name 839 * 840 * @param idx the index of the NTP server to set must be < SNTP_MAX_SERVERS 841 * @param server DNS name of the NTP server to set, to be resolved at contact time 842 */ 843 void 844 sntp_setservername(u8_t idx, const char *server) 845 { 846 LWIP_ASSERT_CORE_LOCKED(); 847 if (idx < SNTP_MAX_SERVERS) { 848 sntp_servers[idx].name = server; 849 } 850 } 851 852 /** 853 * Obtain one of the currently configured by name NTP servers. 854 * 855 * @param idx the index of the NTP server 856 * @return IP address of the indexed NTP server or NULL if the NTP 857 * server has not been configured by name (or at all) 858 */ 859 const char * 860 sntp_getservername(u8_t idx) 861 { 862 if (idx < SNTP_MAX_SERVERS) { 863 return sntp_servers[idx].name; 864 } 865 return NULL; 866 } 867 #endif /* SNTP_SERVER_DNS */ 868 869 #endif /* LWIP_UDP */ 870