607 lines
16 KiB
C
607 lines
16 KiB
C
/*
|
|
******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_RCPL8_2024030303 $ $RCSfile: ipntp.c,v $ $Revision: 1.7.2.13 $
|
|
* $Source: /home/interpeak/CVSRoot/ipntp/src/ntpd/ipntp.c,v $
|
|
* $Author: jren $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by windriver
|
|
******************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
* NTP main source file.
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include "ipntp_config.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_syslog.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_os.h>
|
|
#include <ipcom_shell.h>
|
|
#include <ipcom_sysvar.h>
|
|
#include <ipcom_ipd.h>
|
|
#include <ipcom_tmo.h>
|
|
#include "ipntp.h"
|
|
#include "ipntp_h.h"
|
|
|
|
#include "ipsntp.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
extern void ntp_delete(void);
|
|
extern void ntpdc_delete(void);
|
|
extern int ntpdmain(int argc, char *argv[]);
|
|
#ifdef AUTOKEY
|
|
extern IP_GLOBAL int ntpkeygen(Ipntp_key_param *params);
|
|
extern Ip_pid_t ntpkeygen_pid;
|
|
#endif
|
|
extern Ip_pid_t ntpq_pid;
|
|
extern Ip_pid_t ntpdc_pid;
|
|
|
|
|
|
double fric = 65536.0;
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
IP_PUBLIC Ip_err ipntp_create(void);
|
|
IP_PUBLIC Ip_err ipntp_start(void);
|
|
IP_PUBLIC const char *ipntp_version(void);
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_GLOBAL ipntp_data ipntp;
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipntp_get_configuration
|
|
*===========================================================================
|
|
* Description: Get NTP configuration from system variables.
|
|
* Parameters: none.
|
|
* Returns: IPCOM_SUCCESS = success.
|
|
* IPCOM_ERR_NOT_INSTALLED = neither client nor daemon.
|
|
*/
|
|
IP_STATIC Ip_err
|
|
ipntp_get_configuration(void)
|
|
{
|
|
char *filename = IP_NULL;
|
|
char *init = IP_NULL;
|
|
char *config = IP_NULL;
|
|
|
|
filename = ipcom_sysvar_get("ipntp.config.filename", IP_NULL, 0);
|
|
if(filename != IP_NULL)
|
|
{
|
|
ipntp.config_filename = ipcom_malloc(ipcom_strlen(filename)+1);
|
|
if(IP_NULL == ipntp.config_filename)
|
|
{
|
|
ipcom_free(filename);
|
|
return IPCOM_ERR_NOT_INSTALLED;
|
|
}
|
|
ipcom_strcpy(ipntp.config_filename,filename);
|
|
ipcom_free(filename);
|
|
}
|
|
|
|
config = ipcom_sysvar_get("ipntp.config.param", IP_NULL, 0);
|
|
if(config != IP_NULL)
|
|
{
|
|
ipntp.config_param = ipcom_malloc(ipcom_strlen(config)+1);
|
|
if(IP_NULL == ipntp.config_param)
|
|
{
|
|
ipcom_free(config);
|
|
return IPCOM_ERR_NOT_INSTALLED;
|
|
}
|
|
|
|
ipcom_strcpy(ipntp.config_param,config);
|
|
ipcom_free(config);
|
|
}
|
|
|
|
init = ipcom_sysvar_get("ipntp.init.param", IP_NULL, 0);
|
|
if(init != IP_NULL)
|
|
{
|
|
ipcom_strcpy(ipntp.init_param,init);
|
|
ipcom_free(init);
|
|
}
|
|
|
|
if((filename == IP_NULL) && (config == IP_NULL) &&(init == IP_NULL))
|
|
return IPCOM_ERR_NOT_INSTALLED;
|
|
|
|
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipntp_daemon
|
|
*===========================================================================
|
|
* Description: Main NTP daemon.
|
|
* Parameters: None.
|
|
* Returns: Nothing.
|
|
*/
|
|
IP_STATIC void
|
|
ipntp_daemon(void)
|
|
{
|
|
Ip_fd ipd = IP_INVALID_SOCKET;
|
|
Ip_pid_t ntpd_pid = ipntp.ntpd_pid;
|
|
char* tempArgv[12];
|
|
char ** ntpd_argv = tempArgv;
|
|
int ntpd_argc = 1;
|
|
|
|
ipcom_memset(&ipntp, 0, sizeof(ipntp));
|
|
/* save ipntpd pid */
|
|
ipntp.ntpd_pid = ntpd_pid;
|
|
|
|
/* Init timers. */
|
|
IPCOM_TMO_INIT(&ipntp.ntpd_tmo);
|
|
if(ipntp_get_configuration() != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipntp_daemon() :: ipntp_get_configuration() failed");
|
|
goto fail;
|
|
}
|
|
|
|
if (ipd == IP_INVALID_SOCKET) /* Only at start, not at reconfigure */
|
|
(void)ipcom_ipd_init("ipntp", IPCOM_SUCCESS, &ipd);
|
|
|
|
ipntp.ntpd_ipd = ipd;
|
|
|
|
/* The routeine to start ntpd daemon which will be used by ipntp component. */
|
|
if(ipntp_getOptServ (ipntp.init_param, "ntpd", &ntpd_argc, ntpd_argv, 12) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipntp_daemon() :: parse init parameters failed");
|
|
goto fail;
|
|
}
|
|
ntpdmain(ntpd_argc,ntpd_argv);
|
|
|
|
/* free ntp deamon resources */
|
|
ntp_delete();
|
|
|
|
fail:
|
|
if (ipd == IP_INVALID_SOCKET)
|
|
(void)ipcom_ipd_init("ipntp", IPCOM_ERR_FAILED, &ipd);
|
|
(void)ipcom_ipd_exit("ipntp", ipd);
|
|
|
|
if(IP_NULL != ipntp.config_param)
|
|
{
|
|
ipcom_free(ipntp.config_param);
|
|
}
|
|
if(IP_NULL != ipntp.config_filename)
|
|
{
|
|
ipcom_free(ipntp.config_filename);
|
|
}
|
|
/* cancel and delete timer */
|
|
(void)ipcom_tmo_cancel(&ipntp.ntpd_tmo);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipntpd
|
|
*===========================================================================
|
|
* Description: OS process that runs the NTP daemon.
|
|
* Parameters: None.
|
|
* Returns: Nothing.
|
|
*/
|
|
IP_STATIC
|
|
IPCOM_PROCESS(ipntpd)
|
|
{
|
|
ipcom_proc_init();
|
|
ipntp_daemon();
|
|
ipcom_proc_exit();
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipntp_exit_callback
|
|
*===========================================================================
|
|
* Description: NTP proc exit callback routine.
|
|
* Parameters: the pid of proc.
|
|
* Returns: None.
|
|
*/
|
|
IP_GLOBAL void
|
|
ipntp_exit_callback(Ip_pid_t pid)
|
|
{
|
|
if (pid == ipntp.ntpd_pid)
|
|
{
|
|
if(IP_NULL != ipntp.config_param)
|
|
{
|
|
ipcom_free(ipntp.config_param);
|
|
}
|
|
if(IP_NULL != ipntp.config_filename)
|
|
{
|
|
ipcom_free(ipntp.config_filename);
|
|
}
|
|
/* free ntp deamon resources */
|
|
ntp_delete();
|
|
|
|
(void)ipcom_ipd_exit("ipntp", ipntp.ntpd_ipd);
|
|
ipntp.ntpd_ipd = IP_INVALID_SOCKET;
|
|
}
|
|
else if (pid == ntpq_pid)
|
|
ntpq_pid = 0;
|
|
else if (pid == ntpdc_pid)
|
|
{
|
|
ntpdc_delete();
|
|
ntpdc_pid = 0;
|
|
}
|
|
#ifdef AUTOKEY
|
|
else if (pid == ntpkeygen_pid)
|
|
ntpkeygen_pid = 0;
|
|
#endif
|
|
|
|
ipcom_proc_exit();
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipntp_getOptServ
|
|
*===========================================================================
|
|
* Description: parse parameter string into argc, argv format.
|
|
* Parameters: .
|
|
* Returns: IPCOM_SUCCESS = success.
|
|
* IPCOM_ERR_FAILED = failed.
|
|
*/
|
|
IP_GLOBAL Ip_err
|
|
ipntp_getOptServ(
|
|
char * ParamString,
|
|
const char * progName, /* program name value for argv[0] */
|
|
int *argc,
|
|
char *argvloc[],
|
|
int argvlen)
|
|
{
|
|
char *p;
|
|
char * pLast = IP_NULL;
|
|
int i = 1; /* skip first slot for program name */
|
|
static const char argv0 [] = "???";
|
|
|
|
if (argvlen < 2 || argc == IP_NULL || argvloc == IP_NULL)
|
|
return IPCOM_ERR_FAILED;
|
|
|
|
if (progName == IP_NULL)
|
|
progName = argv0;
|
|
|
|
* (const char **) &argvloc[0] = progName;
|
|
|
|
argvlen -= 1; /* reserve slot for NULL */
|
|
|
|
if (ParamString != IP_NULL)
|
|
{
|
|
for (p = ipcom_strtok_r (ParamString, " \t", &pLast); p != IP_NULL;
|
|
p = ipcom_strtok_r (IP_NULL, " \t", &pLast))
|
|
{
|
|
if (i < argvlen)
|
|
argvloc[i] = p;
|
|
++i;
|
|
}
|
|
}
|
|
|
|
*argc = i;
|
|
|
|
if (i < argvlen)
|
|
argvloc [i] = IP_NULL;
|
|
else
|
|
argvloc [argvlen] = IP_NULL;
|
|
|
|
return (i <= argvlen ? IPCOM_SUCCESS : IPCOM_ERR_FAILED);
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipntp_changetime
|
|
*===========================================================================
|
|
* Description: See description in ipntp.h
|
|
* Parameters:
|
|
* Returns:
|
|
*/
|
|
IP_PUBLIC Ip_err ipntp_changetime(int offset)
|
|
{
|
|
struct Ip_timeval ltv;
|
|
|
|
if(ipcom_gettimeofday(<v, IP_NULL))
|
|
{
|
|
ipcom_printf("Failed to read local time!\n");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
else
|
|
{
|
|
#ifdef _WRS_CONFIG_TIME_T_LONG_LONG
|
|
ipcom_printf("local time: %llx.%lx, %s",ltv.tv_sec, ltv.tv_usec, ipcom_ctime((Ip_time_t *)<v.tv_sec));
|
|
#else
|
|
ipcom_printf("local time: %lx.%lx, %s",ltv.tv_sec, ltv.tv_usec, ipcom_ctime((Ip_time_t *)<v.tv_sec));
|
|
#endif
|
|
ltv.tv_sec += offset;
|
|
if(ipcom_settimeofday(<v, IP_NULL))
|
|
{
|
|
ipcom_printf("Failed to set local time!\n");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
else
|
|
{
|
|
#ifdef _WRS_CONFIG_TIME_T_LONG_LONG
|
|
ipcom_printf("local time after changed: %llx.%lx, %s",
|
|
ltv.tv_sec, ltv.tv_usec, ipcom_ctime((Ip_time_t *)<v.tv_sec));
|
|
#else
|
|
ipcom_printf("local time after changed: %lx.%lx, %s",
|
|
ltv.tv_sec, ltv.tv_usec, ipcom_ctime((Ip_time_t *)<v.tv_sec));
|
|
#endif
|
|
}
|
|
}
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipntp_timediff
|
|
*===========================================================================
|
|
* Description: See description in ipntp.h
|
|
* Parameters:
|
|
* Returns:
|
|
*/
|
|
IP_PUBLIC Ip_err ipntp_timediff(char * pServerAddr, Ip_s32 timeout, double *diff)
|
|
{
|
|
Ip_s32 ret;
|
|
struct Ip_timeval ltv, rtv;
|
|
double lsum, rsum;
|
|
|
|
if(ipcom_gettimeofday(<v, IP_NULL))
|
|
{
|
|
ipcom_printf("Failed to read local time!\n");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
else
|
|
{
|
|
#ifdef _WRS_CONFIG_TIME_T_LONG_LONG
|
|
ipcom_printf("local time: %llx.%lx, %s",
|
|
ltv.tv_sec, ltv.tv_usec, ipcom_ctime((Ip_time_t *)<v.tv_sec));
|
|
#else
|
|
ipcom_printf("local time: %lx.%lx, %s",
|
|
ltv.tv_sec, ltv.tv_usec, ipcom_ctime((Ip_time_t *)<v.tv_sec));
|
|
#endif
|
|
}
|
|
|
|
ret = ipntp_querytime(pServerAddr, timeout, &rtv);
|
|
if (ret == IPCOM_SUCCESS)
|
|
{
|
|
lsum = (double)ltv.tv_sec + (double)ltv.tv_usec/1000000 ;
|
|
rsum = (double)rtv.tv_sec + (double)rtv.tv_usec/1000000 ;
|
|
*diff = lsum -rsum;
|
|
ipcom_printf("time difference: %+.6f s\n",*diff);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipntp_updatetime
|
|
*===========================================================================
|
|
* Description: See description in ipntp.h
|
|
* Parameters:
|
|
* Returns:
|
|
*/
|
|
IP_PUBLIC Ip_err ipntp_updatetime(char * pServerAddr, Ip_s32 timeout)
|
|
{
|
|
Ip_s32 ret;
|
|
struct Ip_timeval tv;
|
|
|
|
ret = ipntp_querytime(pServerAddr, timeout, &tv);
|
|
if (ret == IPCOM_SUCCESS)
|
|
{
|
|
if(ipcom_settimeofday(&tv, IP_NULL))
|
|
{
|
|
ipcom_printf("Failed to update system time!\n");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
else
|
|
{
|
|
ipcom_printf("System time updated!\n");
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipntp_querytime
|
|
*===========================================================================
|
|
* Description: See description in ipntp.h
|
|
* Parameters:
|
|
* Returns:
|
|
*/
|
|
IP_PUBLIC Ip_err ipntp_querytime(char * pServerAddr, Ip_s32 timeout, struct Ip_timeval *tv)
|
|
{
|
|
Ip_s32 ret;
|
|
Ip_u16 port = (Ip_u16)atoi("123");
|
|
struct Ip_timespec tm;
|
|
|
|
ret = ipsntp_query_time(pServerAddr, port, timeout, &tm, SNTP_VERSION);
|
|
tv->tv_sec = tm.tv_sec;
|
|
tv->tv_usec = tm.tv_nsec / 1000;
|
|
|
|
switch(ret)
|
|
{
|
|
case IPCOM_SUCCESS:
|
|
#ifdef _WRS_CONFIG_TIME_T_LONG_LONG
|
|
ipcom_printf("(S)NTP time: %llx.%lx, %s",tv->tv_sec, tv->tv_usec, ipcom_ctime((Ip_time_t *)&tv->tv_sec));
|
|
#else
|
|
ipcom_printf("(S)NTP time: %lx.%lx, %s",tv->tv_sec, tv->tv_usec, ipcom_ctime((Ip_time_t *)&tv->tv_sec));
|
|
#endif
|
|
break;
|
|
case IPCOM_ERR_INVALID_ARG:
|
|
ipcom_printf("Invalid argument(s)\n");
|
|
break;
|
|
case IPCOM_ERR_TIMEOUT:
|
|
ipcom_printf("Timeout. No responses received!\n");
|
|
break;
|
|
case IPCOM_ERR_SOCKCALLFAILED:
|
|
ipcom_printf("A socket call failed!\n");
|
|
break;
|
|
case IPCOM_ERR_NO_MEMORY:
|
|
ipcom_printf("Memory error!\n");
|
|
break;
|
|
default:
|
|
ipcom_printf("General error!\n");
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#ifdef AUTOKEY
|
|
/*
|
|
*===========================================================================
|
|
* ipntp_keygen
|
|
*===========================================================================
|
|
* Description: This routine generates cryptographic data files used by the NTPv4
|
|
authentication and identification schemes.
|
|
* Parameters: None.
|
|
* Returns: Nothing.
|
|
*/
|
|
IP_PUBLIC void
|
|
ipntp_keygen(char *pathfilename)
|
|
{
|
|
Ipntp_key_param params;
|
|
|
|
ipcom_memset(¶ms, 0, sizeof(Ipntp_key_param));
|
|
ipcom_memcpy(¶ms.rndfile, pathfilename, IP_MIN(ipcom_strlen(pathfilename), IPNTP_MAX_NAME));
|
|
|
|
ntpkeygen(¶ms);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipntp_create
|
|
*===========================================================================
|
|
* Description: NTP create routine.
|
|
* Parameters: None.
|
|
* Returns: IPCOM_SUCCESS or IPCOM_ERR_XXX error code.
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipntp_create(void)
|
|
{
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipntp_start
|
|
*===========================================================================
|
|
* Description: NTP start routine.
|
|
* Parameters: None.
|
|
* Returns: IPCOM_SUCCESS or IPCOM_ERR_XXX error code.
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipntp_start(void)
|
|
{
|
|
Ipcom_proc_attr attr;
|
|
|
|
ipcom_proc_attr_init(&attr);
|
|
attr.stacksize = IPCOM_PROC_STACK_LARGE;
|
|
attr.flags |= IPCOM_PROC_FLAG_FP;
|
|
if(ipcom_proc_acreate("ipntpd", (Ipcom_proc_func)ipntpd, &attr, &ipntp.ntpd_pid))
|
|
{
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipntp_version
|
|
*===========================================================================
|
|
* Description: Get the NTP product's version string.
|
|
* Parameters: None.
|
|
* Returns: The version string.
|
|
*/
|
|
IP_PUBLIC const char *
|
|
ipntp_version(void)
|
|
{
|
|
return "@(#) IPNTP $Name: VXWORKS_ITER40_RCPL8_2024030303 $ - INTERPEAK_COPYRIGHT_STRING";
|
|
}
|
|
|
|
|
|
IP_GLOBAL Ip_bool ipntp_ipdkill_check(const char *name, Ipcom_ipd_msg *msg)
|
|
{
|
|
if (strcmp(name, "ipntp") != 0)
|
|
return IP_TRUE;
|
|
|
|
if (msg->msgtype != IPCOM_IPD_MSGTYPE_KILL)
|
|
return IP_TRUE;
|
|
|
|
if (ntpq_pid != 0)
|
|
return IP_FALSE;
|
|
|
|
return IP_TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|