/* ****************************************************************************** * 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 #include #include #include #include #include #include #include #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 **************************************************************************** */