diff options
Diffstat (limited to 'roms/ipxe/src/net/udp/ntp.c')
-rw-r--r-- | roms/ipxe/src/net/udp/ntp.c | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/roms/ipxe/src/net/udp/ntp.c b/roms/ipxe/src/net/udp/ntp.c deleted file mode 100644 index 11f8ccc00..000000000 --- a/roms/ipxe/src/net/udp/ntp.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#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> - -/** @file - * - * Network Time Protocol - * - */ - -/** An NTP client */ -struct ntp_client { - /** Reference count */ - struct refcnt refcnt; - /** Job control interface */ - struct interface job; - /** Data transfer interface */ - struct interface xfer; - /** Retransmission timer */ - struct retry_timer timer; -}; - -/** - * Close NTP client - * - * @v ntp NTP client - * @v rc Reason for close - */ -static void ntp_close ( struct ntp_client *ntp, int rc ) { - - /* Stop timer */ - stop_timer ( &ntp->timer ); - - /* Shut down interfaces */ - intf_shutdown ( &ntp->xfer, rc ); - intf_shutdown ( &ntp->job, rc ); -} - -/** - * Send NTP request - * - * @v ntp NTP client - * @ret rc Return status code - */ -static int ntp_request ( struct ntp_client *ntp ) { - struct ntp_header hdr; - int rc; - - DBGC ( ntp, "NTP %p sending request\n", ntp ); - - /* Construct header */ - memset ( &hdr, 0, sizeof ( hdr ) ); - hdr.flags = ( NTP_FL_LI_UNKNOWN | NTP_FL_VN_1 | NTP_FL_MODE_CLIENT ); - hdr.transmit.seconds = htonl ( time ( NULL ) + NTP_EPOCH ); - hdr.transmit.fraction = htonl ( NTP_FRACTION_MAGIC ); - - /* Send request */ - if ( ( rc = xfer_deliver_raw ( &ntp->xfer, &hdr, - sizeof ( hdr ) ) ) != 0 ) { - DBGC ( ntp, "NTP %p could not send request: %s\n", - ntp, strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * Handle NTP response - * - * @v ntp NTP client - * @v iobuf I/O buffer - * @v meta Data transfer metadata - * @ret rc Return status code - */ -static int ntp_deliver ( struct ntp_client *ntp, struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct ntp_header *hdr; - struct sockaddr_tcpip *st_src; - int32_t delta; - int rc; - - /* Check source port */ - st_src = ( ( struct sockaddr_tcpip * ) meta->src ); - if ( st_src->st_port != htons ( NTP_PORT ) ) { - DBGC ( ntp, "NTP %p received non-NTP packet:\n", ntp ); - DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) ); - goto ignore; - } - - /* Check packet length */ - if ( iob_len ( iobuf ) < sizeof ( *hdr ) ) { - DBGC ( ntp, "NTP %p received malformed packet:\n", ntp ); - DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) ); - goto ignore; - } - hdr = iobuf->data; - - /* Check mode */ - if ( ( hdr->flags & NTP_FL_MODE_MASK ) != NTP_FL_MODE_SERVER ) { - DBGC ( ntp, "NTP %p received non-server packet:\n", ntp ); - DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) ); - goto ignore; - } - - /* Check magic value */ - if ( hdr->originate.fraction != htonl ( NTP_FRACTION_MAGIC ) ) { - DBGC ( ntp, "NTP %p received unrecognised packet:\n", ntp ); - DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) ); - goto ignore; - } - - /* Check for Kiss-o'-Death packets */ - if ( ! hdr->stratum ) { - DBGC ( ntp, "NTP %p received kiss-o'-death:\n", ntp ); - DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) ); - rc = -EPROTO; - goto close; - } - - /* Calculate clock delta */ - delta = ( ntohl ( hdr->receive.seconds ) - - ntohl ( hdr->originate.seconds ) ); - DBGC ( ntp, "NTP %p delta %d seconds\n", ntp, delta ); - - /* Adjust system clock */ - time_adjust ( delta ); - - /* Success */ - rc = 0; - - close: - ntp_close ( ntp, rc ); - ignore: - free_iob ( iobuf ); - return 0; -} - -/** - * Handle data transfer window change - * - * @v ntp NTP client - */ -static void ntp_window_changed ( struct ntp_client *ntp ) { - - /* Start timer to send initial request */ - start_timer_nodelay ( &ntp->timer ); -} - -/** Data transfer interface operations */ -static struct interface_operation ntp_xfer_op[] = { - INTF_OP ( xfer_deliver, struct ntp_client *, ntp_deliver ), - INTF_OP ( xfer_window_changed, struct ntp_client *, - ntp_window_changed ), - INTF_OP ( intf_close, struct ntp_client *, ntp_close ), -}; - -/** Data transfer interface descriptor */ -static struct interface_descriptor ntp_xfer_desc = - INTF_DESC_PASSTHRU ( struct ntp_client, xfer, ntp_xfer_op, job ); - -/** Job control interface operations */ -static struct interface_operation ntp_job_op[] = { - INTF_OP ( intf_close, struct ntp_client *, ntp_close ), -}; - -/** Job control interface descriptor */ -static struct interface_descriptor ntp_job_desc = - INTF_DESC_PASSTHRU ( struct ntp_client, job, ntp_job_op, xfer ); - -/** - * Handle NTP timer expiry - * - * @v timer Retransmission timer - * @v fail Failure indicator - */ -static void ntp_expired ( struct retry_timer *timer, int fail ) { - struct ntp_client *ntp = - container_of ( timer, struct ntp_client, timer ); - - /* Shut down client if we have failed */ - if ( fail ) { - ntp_close ( ntp, -ETIMEDOUT ); - return; - } - - /* Otherwise, restart timer and (re)transmit request */ - start_timer ( &ntp->timer ); - ntp_request ( ntp ); -} - -/** - * Start NTP client - * - * @v job Job control interface - * @v hostname NTP server - * @ret rc Return status code - */ -int start_ntp ( struct interface *job, const char *hostname ) { - struct ntp_client *ntp; - union { - struct sockaddr_tcpip st; - struct sockaddr sa; - } server; - int rc; - - /* Allocate and initialise structure*/ - ntp = zalloc ( sizeof ( *ntp ) ); - if ( ! ntp ) { - rc = -ENOMEM; - goto err_alloc; - } - ref_init ( &ntp->refcnt, NULL ); - intf_init ( &ntp->job, &ntp_job_desc, &ntp->refcnt ); - intf_init ( &ntp->xfer, &ntp_xfer_desc, &ntp->refcnt ); - timer_init ( &ntp->timer, ntp_expired, &ntp->refcnt ); - set_timer_limits ( &ntp->timer, NTP_MIN_TIMEOUT, NTP_MAX_TIMEOUT ); - - /* Open socket */ - memset ( &server, 0, sizeof ( server ) ); - server.st.st_port = htons ( NTP_PORT ); - if ( ( rc = xfer_open_named_socket ( &ntp->xfer, SOCK_DGRAM, &server.sa, - hostname, NULL ) ) != 0 ) { - DBGC ( ntp, "NTP %p could not open socket: %s\n", - ntp, strerror ( rc ) ); - goto err_open; - } - - /* Attach parent interface, mortalise self, and return */ - intf_plug_plug ( &ntp->job, job ); - ref_put ( &ntp->refcnt ); - return 0; - - err_open: - ntp_close ( ntp, rc ); - ref_put ( &ntp->refcnt ); - err_alloc: - return rc; -} |