Files
m241Neelima/components/ip_net2-6.9/ipntp/src/ntpd/ipntp.c
T
2026-07-30 11:19:44 +05:30

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(&ltv, 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 *)&ltv.tv_sec));
#else
ipcom_printf("local time: %lx.%lx, %s",ltv.tv_sec, ltv.tv_usec, ipcom_ctime((Ip_time_t *)&ltv.tv_sec));
#endif
ltv.tv_sec += offset;
if(ipcom_settimeofday(&ltv, 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 *)&ltv.tv_sec));
#else
ipcom_printf("local time after changed: %lx.%lx, %s",
ltv.tv_sec, ltv.tv_usec, ipcom_ctime((Ip_time_t *)&ltv.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(&ltv, 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 *)&ltv.tv_sec));
#else
ipcom_printf("local time: %lx.%lx, %s",
ltv.tv_sec, ltv.tv_usec, ipcom_ctime((Ip_time_t *)&ltv.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(&params, 0, sizeof(Ipntp_key_param));
ipcom_memcpy(&params.rndfile, pathfilename, IP_MIN(ipcom_strlen(pathfilename), IPNTP_MAX_NAME));
ntpkeygen(&params);
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
****************************************************************************
*/