iPXE
Data Structures | Functions | Variables
ntp.c File Reference

Network Time Protocol. More...

#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <ipxe/malloc.h>
#include <ipxe/refcnt.h>
#include <ipxe/iobuf.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/retry.h>
#include <ipxe/timer.h>
#include <ipxe/time.h>
#include <ipxe/tcpip.h>
#include <ipxe/ntp.h>

Go to the source code of this file.

Data Structures

struct  ntp_client
 An NTP client. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static void ntp_close (struct ntp_client *ntp, int rc)
 Close NTP client. More...
 
static int ntp_request (struct ntp_client *ntp)
 Send NTP request. More...
 
static int ntp_deliver (struct ntp_client *ntp, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Handle NTP response. More...
 
static void ntp_window_changed (struct ntp_client *ntp)
 Handle data transfer window change. More...
 
static void ntp_expired (struct retry_timer *timer, int fail)
 Handle NTP timer expiry. More...
 
int start_ntp (struct interface *job, const char *hostname)
 Start NTP client. More...
 

Variables

static struct interface_operation ntp_xfer_op []
 Data transfer interface operations. More...
 
static struct interface_descriptor ntp_xfer_desc
 Data transfer interface descriptor. More...
 
static struct interface_operation ntp_job_op []
 Job control interface operations. More...
 
static struct interface_descriptor ntp_job_desc
 Job control interface descriptor. More...
 

Detailed Description

Network Time Protocol.

Definition in file ntp.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ ntp_close()

static void ntp_close ( struct ntp_client ntp,
int  rc 
)
static

Close NTP client.

Parameters
ntpNTP client
rcReason for close

Definition at line 65 of file ntp.c.

65  {
66 
67  /* Stop timer */
68  stop_timer ( &ntp->timer );
69 
70  /* Shut down interfaces */
71  intf_shutdown ( &ntp->xfer, rc );
72  intf_shutdown ( &ntp->job, rc );
73 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:273
int ntp(const char *hostname)
Get time and date via NTP.
Definition: ntpmgmt.c:45
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117

References intf_shutdown(), ntp(), rc, and stop_timer().

Referenced by ntp_deliver(), ntp_expired(), and start_ntp().

◆ ntp_request()

static int ntp_request ( struct ntp_client ntp)
static

Send NTP request.

Parameters
ntpNTP client
Return values
rcReturn status code

Definition at line 81 of file ntp.c.

81  {
82  struct ntp_header hdr;
83  int rc;
84 
85  DBGC ( ntp, "NTP %p sending request\n", ntp );
86 
87  /* Construct header */
88  memset ( &hdr, 0, sizeof ( hdr ) );
90  hdr.transmit.seconds = htonl ( time ( NULL ) + NTP_EPOCH );
91  hdr.transmit.fraction = htonl ( NTP_FRACTION_MAGIC );
92 
93  /* Send request */
94  if ( ( rc = xfer_deliver_raw ( &ntp->xfer, &hdr,
95  sizeof ( hdr ) ) ) != 0 ) {
96  DBGC ( ntp, "NTP %p could not send request: %s\n",
97  ntp, strerror ( rc ) );
98  return rc;
99  }
100 
101  return 0;
102 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
#define NTP_EPOCH
NTP timestamp for start of Unix epoch.
Definition: ntp.h:87
An NTP header.
Definition: ntp.h:46
#define NTP_FL_VN_1
NTP version: 1.
Definition: ntp.h:75
#define htonl(value)
Definition: byteswap.h:133
#define NTP_FL_MODE_CLIENT
NTP mode: client.
Definition: ntp.h:78
int xfer_deliver_raw(struct interface *intf, const void *data, size_t len)
Deliver datagram as raw data without metadata.
Definition: xfer.c:287
#define NTP_FRACTION_MAGIC
NTP fraction of a second magic value.
Definition: ntp.h:93
int ntp(const char *hostname)
Get time and date via NTP.
Definition: ntpmgmt.c:45
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define NTP_FL_LI_UNKNOWN
Leap second indicator: unknown.
Definition: ntp.h:72
uint32_t hdr
Message header.
Definition: intelvf.h:12
uint64_t time
Current time.
Definition: ntlm.h:20
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
void * memset(void *dest, int character, size_t len) __nonnull

References DBGC, hdr, htonl, memset(), ntp(), NTP_EPOCH, NTP_FL_LI_UNKNOWN, NTP_FL_MODE_CLIENT, NTP_FL_VN_1, NTP_FRACTION_MAGIC, NULL, rc, strerror(), time, and xfer_deliver_raw().

Referenced by ntp_expired().

◆ ntp_deliver()

static int ntp_deliver ( struct ntp_client ntp,
struct io_buffer iobuf,
struct xfer_metadata meta 
)
static

Handle NTP response.

Parameters
ntpNTP client
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 112 of file ntp.c.

113  {
114  struct ntp_header *hdr;
115  struct sockaddr_tcpip *st_src;
116  int32_t delta;
117  int rc;
118 
119  /* Check source port */
120  st_src = ( ( struct sockaddr_tcpip * ) meta->src );
121  if ( st_src->st_port != htons ( NTP_PORT ) ) {
122  DBGC ( ntp, "NTP %p received non-NTP packet:\n", ntp );
123  DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) );
124  goto ignore;
125  }
126 
127  /* Check packet length */
128  if ( iob_len ( iobuf ) < sizeof ( *hdr ) ) {
129  DBGC ( ntp, "NTP %p received malformed packet:\n", ntp );
130  DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) );
131  goto ignore;
132  }
133  hdr = iobuf->data;
134 
135  /* Check mode */
136  if ( ( hdr->flags & NTP_FL_MODE_MASK ) != NTP_FL_MODE_SERVER ) {
137  DBGC ( ntp, "NTP %p received non-server packet:\n", ntp );
138  DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) );
139  goto ignore;
140  }
141 
142  /* Check magic value */
143  if ( hdr->originate.fraction != htonl ( NTP_FRACTION_MAGIC ) ) {
144  DBGC ( ntp, "NTP %p received unrecognised packet:\n", ntp );
145  DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) );
146  goto ignore;
147  }
148 
149  /* Check for Kiss-o'-Death packets */
150  if ( ! hdr->stratum ) {
151  DBGC ( ntp, "NTP %p received kiss-o'-death:\n", ntp );
152  DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) );
153  rc = -EPROTO;
154  goto close;
155  }
156 
157  /* Calculate clock delta */
158  delta = ( ntohl ( hdr->receive.seconds ) -
159  ntohl ( hdr->originate.seconds ) );
160  DBGC ( ntp, "NTP %p delta %d seconds\n", ntp, delta );
161 
162  /* Adjust system clock */
163  time_adjust ( delta );
164 
165  /* Success */
166  rc = 0;
167 
168  close:
169  ntp_close ( ntp, rc );
170  ignore:
171  free_iob ( iobuf );
172  return 0;
173 }
TCP/IP socket address.
Definition: tcpip.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#define DBGC(...)
Definition: compiler.h:505
#define ntohl(value)
Definition: byteswap.h:134
An NTP header.
Definition: ntp.h:46
#define htonl(value)
Definition: byteswap.h:133
#define NTP_FRACTION_MAGIC
NTP fraction of a second magic value.
Definition: ntp.h:93
#define DBGC_HDA(...)
Definition: compiler.h:506
int ntp(const char *hostname)
Get time and date via NTP.
Definition: ntpmgmt.c:45
#define EPROTO
Protocol error.
Definition: errno.h:624
int meta(WINDOW *, bool)
uint16_t st_port
TCP/IP port.
Definition: tcpip.h:81
#define NTP_PORT
NTP port.
Definition: ntp.h:17
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
uint32_t hdr
Message header.
Definition: intelvf.h:12
static void ntp_close(struct ntp_client *ntp, int rc)
Close NTP client.
Definition: ntp.c:65
signed int int32_t
Definition: stdint.h:17
void * data
Start of data.
Definition: iobuf.h:44
#define NTP_FL_MODE_SERVER
NTP mode: server.
Definition: ntp.h:81
static struct evtchn_close * close
Definition: xenevent.h:23
#define NTP_FL_MODE_MASK
NTP mode mask.
Definition: ntp.h:84
#define htons(value)
Definition: byteswap.h:135

References close, io_buffer::data, DBGC, DBGC_HDA, EPROTO, free_iob(), hdr, htonl, htons, iob_len(), meta(), ntohl, ntp(), ntp_close(), NTP_FL_MODE_MASK, NTP_FL_MODE_SERVER, NTP_FRACTION_MAGIC, NTP_PORT, rc, and sockaddr_tcpip::st_port.

◆ ntp_window_changed()

static void ntp_window_changed ( struct ntp_client ntp)
static

Handle data transfer window change.

Parameters
ntpNTP client

Definition at line 180 of file ntp.c.

180  {
181 
182  /* Start timer to send initial request */
183  start_timer_nodelay ( &ntp->timer );
184 }
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:99
int ntp(const char *hostname)
Get time and date via NTP.
Definition: ntpmgmt.c:45

References ntp(), and start_timer_nodelay().

◆ ntp_expired()

static void ntp_expired ( struct retry_timer timer,
int  fail 
)
static

Handle NTP timer expiry.

Parameters
timerRetransmission timer
failFailure indicator

Definition at line 213 of file ntp.c.

213  {
214  struct ntp_client *ntp =
215  container_of ( timer, struct ntp_client, timer );
216 
217  /* Shut down client if we have failed */
218  if ( fail ) {
219  ntp_close ( ntp, -ETIMEDOUT );
220  return;
221  }
222 
223  /* Otherwise, restart timer and (re)transmit request */
224  start_timer ( &ntp->timer );
225  ntp_request ( ntp );
226 }
A timer.
Definition: timer.h:28
An NTP client.
Definition: ntp.c:48
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
int ntp(const char *hostname)
Get time and date via NTP.
Definition: ntpmgmt.c:45
static int ntp_request(struct ntp_client *ntp)
Send NTP request.
Definition: ntp.c:81
void start_timer(struct retry_timer *timer)
Start timer.
Definition: retry.c:93
static void ntp_close(struct ntp_client *ntp, int rc)
Close NTP client.
Definition: ntp.c:65
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669

References container_of, ETIMEDOUT, ntp(), ntp_close(), ntp_request(), and start_timer().

Referenced by start_ntp().

◆ start_ntp()

int start_ntp ( struct interface job,
const char *  hostname 
)

Start NTP client.

Parameters
jobJob control interface
hostnameNTP server
Return values
rcReturn status code

Definition at line 235 of file ntp.c.

235  {
236  struct ntp_client *ntp;
237  union {
238  struct sockaddr_tcpip st;
239  struct sockaddr sa;
240  } server;
241  int rc;
242 
243  /* Allocate and initialise structure*/
244  ntp = zalloc ( sizeof ( *ntp ) );
245  if ( ! ntp ) {
246  rc = -ENOMEM;
247  goto err_alloc;
248  }
249  ref_init ( &ntp->refcnt, NULL );
250  intf_init ( &ntp->job, &ntp_job_desc, &ntp->refcnt );
251  intf_init ( &ntp->xfer, &ntp_xfer_desc, &ntp->refcnt );
252  timer_init ( &ntp->timer, ntp_expired, &ntp->refcnt );
253  set_timer_limits ( &ntp->timer, NTP_MIN_TIMEOUT, NTP_MAX_TIMEOUT );
254 
255  /* Open socket */
256  memset ( &server, 0, sizeof ( server ) );
257  server.st.st_port = htons ( NTP_PORT );
258  if ( ( rc = xfer_open_named_socket ( &ntp->xfer, SOCK_DGRAM, &server.sa,
259  hostname, NULL ) ) != 0 ) {
260  DBGC ( ntp, "NTP %p could not open socket: %s\n",
261  ntp, strerror ( rc ) );
262  goto err_open;
263  }
264 
265  /* Attach parent interface, mortalise self, and return */
266  intf_plug_plug ( &ntp->job, job );
267  ref_put ( &ntp->refcnt );
268  return 0;
269 
270  err_open:
271  ntp_close ( ntp, rc );
272  ref_put ( &ntp->refcnt );
273  err_alloc:
274  return rc;
275 }
TCP/IP socket address.
Definition: tcpip.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct sockaddr sa
Definition: dns.c:68
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
#define SOCK_DGRAM
Definition: socket.h:29
#define DBGC(...)
Definition: compiler.h:505
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:102
An NTP client.
Definition: ntp.c:48
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct sockaddr_tcpip st
Definition: dns.c:69
int ntp(const char *hostname)
Get time and date via NTP.
Definition: ntpmgmt.c:45
Generalized socket address structure.
Definition: socket.h:96
#define NTP_PORT
NTP port.
Definition: ntp.h:17
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
static struct interface_descriptor ntp_xfer_desc
Data transfer interface descriptor.
Definition: ntp.c:195
static struct interface_descriptor ntp_job_desc
Job control interface descriptor.
Definition: ntp.c:204
#define NTP_MIN_TIMEOUT
NTP minimum retransmission timeout.
Definition: ntp.h:99
static void ntp_close(struct ntp_client *ntp, int rc)
Close NTP client.
Definition: ntp.c:65
#define NTP_MAX_TIMEOUT
NTP maximum retransmission timeout.
Definition: ntp.h:105
static void ntp_expired(struct retry_timer *timer, int fail)
Handle NTP timer expiry.
Definition: ntp.c:213
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define htons(value)
Definition: byteswap.h:135
int xfer_open_named_socket(struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local)
Open named socket.
Definition: resolv.c:402
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
void * memset(void *dest, int character, size_t len) __nonnull

References DBGC, ENOMEM, htons, intf_init(), intf_plug_plug(), memset(), ntp(), ntp_close(), ntp_expired(), ntp_job_desc, NTP_MAX_TIMEOUT, NTP_MIN_TIMEOUT, NTP_PORT, ntp_xfer_desc, NULL, rc, ref_init, ref_put, sa, SOCK_DGRAM, st, strerror(), xfer_open_named_socket(), and zalloc().

Referenced by ntp().

Variable Documentation

◆ ntp_xfer_op

struct interface_operation ntp_xfer_op[]
static
Initial value:
= {
}
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:145
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
static void ntp_window_changed(struct ntp_client *ntp)
Handle data transfer window change.
Definition: ntp.c:180
An NTP client.
Definition: ntp.c:48
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
static int ntp_deliver(struct ntp_client *ntp, struct io_buffer *iobuf, struct xfer_metadata *meta)
Handle NTP response.
Definition: ntp.c:112
static void ntp_close(struct ntp_client *ntp, int rc)
Close NTP client.
Definition: ntp.c:65

Data transfer interface operations.

Definition at line 187 of file ntp.c.

◆ ntp_xfer_desc

struct interface_descriptor ntp_xfer_desc
static
Initial value:
=
INTF_DESC_PASSTHRU ( struct ntp_client, xfer, ntp_xfer_op, job )
An NTP client.
Definition: ntp.c:48
static struct interface_operation ntp_xfer_op[]
Data transfer interface operations.
Definition: ntp.c:187
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition: interface.h:82

Data transfer interface descriptor.

Definition at line 195 of file ntp.c.

Referenced by start_ntp().

◆ ntp_job_op

struct interface_operation ntp_job_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
An NTP client.
Definition: ntp.c:48
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
static void ntp_close(struct ntp_client *ntp, int rc)
Close NTP client.
Definition: ntp.c:65

Job control interface operations.

Definition at line 199 of file ntp.c.

◆ ntp_job_desc

struct interface_descriptor ntp_job_desc
static
Initial value:
=
INTF_DESC_PASSTHRU ( struct ntp_client, job, ntp_job_op, xfer )
An NTP client.
Definition: ntp.c:48
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition: interface.h:82
static struct interface_operation ntp_job_op[]
Job control interface operations.
Definition: ntp.c:199

Job control interface descriptor.

Definition at line 204 of file ntp.c.

Referenced by start_ntp().