#include "defs.h"
static __inline void
s_fixedpt_ntoh(struct s_fixedpt *fixed)
{
fixed->int_parts = ntohs(fixed->int_parts);
fixed->fractions = ntohs(fixed->fractions);
}
static __inline void
s_fixedpt_hton(struct s_fixedpt *fixed)
{
fixed->int_parts = htons(fixed->int_parts);
fixed->fractions = htons(fixed->fractions);
}
static __inline void
l_fixedpt_ntoh(struct l_fixedpt *fixed)
{
fixed->int_partl = ntohl(fixed->int_partl);
fixed->fractionl = ntohl(fixed->fractionl);
}
static __inline void
l_fixedpt_hton(struct l_fixedpt *fixed)
{
fixed->int_partl = htonl(fixed->int_partl);
fixed->fractionl = htonl(fixed->fractionl);
}
static void
ntp_ntoh(struct ntp_msg *msg)
{
msg->refid = ntohl(msg->refid);
s_fixedpt_ntoh(&msg->rootdelay);
s_fixedpt_ntoh(&msg->dispersion);
l_fixedpt_ntoh(&msg->reftime);
l_fixedpt_ntoh(&msg->orgtime);
l_fixedpt_ntoh(&msg->rectime);
l_fixedpt_ntoh(&msg->xmttime);
msg->keyid = ntohl(msg->keyid);
}
static void
ntp_hton(struct ntp_msg *msg)
{
msg->refid = htonl(msg->refid);
s_fixedpt_hton(&msg->rootdelay);
s_fixedpt_hton(&msg->dispersion);
l_fixedpt_hton(&msg->reftime);
l_fixedpt_hton(&msg->orgtime);
l_fixedpt_hton(&msg->rectime);
l_fixedpt_hton(&msg->xmttime);
msg->keyid = htonl(msg->keyid);
}
int
udp_ntptimereq(int fd, struct timeval *rtvp, struct timeval *ltvp,
struct timeval *lbtvp)
{
struct ntp_msg wmsg;
struct ntp_msg rmsg;
struct timeval tv1;
struct timeval seltv;
fd_set rfds;
int error;
int n;
bzero(&wmsg, sizeof(wmsg));
wmsg.status = LI_ALARM | MODE_CLIENT | (NTP_VERSION << 3);
wmsg.ppoll = 4;
wmsg.precision = -6;
wmsg.rootdelay.int_parts = 1;
wmsg.dispersion.int_parts = 1;
wmsg.refid = 0;
wmsg.xmttime.int_partl = time(NULL) + JAN_1970;
wmsg.xmttime.fractionl = random();
gettimeofday(&tv1, NULL);
ntp_hton(&wmsg);
n = write(fd, &wmsg, NTP_MSGSIZE_NOAUTH);
if (n != NTP_MSGSIZE_NOAUTH)
return(-1);
ntp_ntoh(&wmsg);
seltv.tv_sec = 2;
seltv.tv_usec = 0;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
select(fd + 1, &rfds, NULL, NULL, &seltv);
error = -1;
while ((n = read(fd, &rmsg, sizeof(rmsg))) >= 0) {
if (n < NTP_MSGSIZE_NOAUTH)
continue;
ntp_ntoh(&rmsg);
if (bcmp(&rmsg.orgtime, &wmsg.xmttime, sizeof(rmsg.orgtime)) != 0)
continue;
gettimeofday(ltvp, NULL);
sysntp_getbasetime(lbtvp);
l_fixedpt_to_tv(&rmsg.xmttime, rtvp);
tv_add_micro(rtvp, (long)(tv_delta_double(&tv1, ltvp) * 1000000.0) / 2);
error = 0;
break;
}
return(error);
}