www.pudn.com > Demo C.rar > ntp.c
struct {
unsigned char livnmode, stratum, poll, prec;
unsigned long delay, disp, refid;
unsigned long reftime[2], origtime[2], rcvtime[2], txtime[2];
} pkt;
#define PORT 123
#define MY_OFFSET 2208988800L
/* Sync the time */
int
Sync(char *hostname)
{
int i, fd = -1, len, n, zonemin;
struct sockaddr_in saddr, myaddr;
struct hostent *hp;
char answer[2000];
unsigned long myt;
long offset;
fd_set readfds;
struct timeval tv;
/* Get server name */
n = strlen(hostname);
if (n <= 0) {
perror("hostname");
return 0;
}
sprintf(answer, "Connecting to %s\n", hostname);
printf(answer);
/* Resolve server name */
bzero((char *)&saddr, sizeof saddr);
saddr.sin_family = AF_INET;
saddr.sin_port = htons(PORT);
if ((saddr.sin_addr.s_addr = inet_addr(hostname)) == ERROR) {
perror("unknown server");
return 0;
}
sprintf(answer, "Hostname resolved, getting the socket\n");
printf(answer);
/* Get a socket */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket");
return 0;
}
sprintf(answer, "Got socket, bind to port\n");
printf(answer);
/* Bind it to some port */
bzero((char *)&myaddr, sizeof myaddr);
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(3030);
myaddr.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, (struct sockaddr *) &myaddr, sizeof myaddr) < 0) {
perror("bind error");
close(fd);
return 0;
}
/* Fill in the request packet */
bzero((char *)&pkt, sizeof pkt);
pkt.livnmode = 0x0b; /* version 1, mode 3 (client) */
sprintf(answer, "Send packet\n");
printf(answer);
/* Send packet to server */
if ((n = sendto(fd, (char *)&pkt, sizeof pkt, 0,
(struct sockaddr *) &saddr,
sizeof saddr)) != sizeof pkt) {
sprintf(answer, "sendto %d err %d", n, errno);
perror(answer);
close(fd);
return 0;
}
sprintf(answer, "Wait for reply\n");
printf(answer);
/* Read reply packet from server */
len = sizeof pkt;
FD_SET(fd, &readfds);
tv.tv_sec = 5;
tv.tv_usec = 0;
if(select(fd+1, &readfds, NULL, NULL, &tv)){
if ((n = recvfrom(fd, (char *)&pkt, sizeof pkt, 0,
(struct sockaddr *) &saddr,
&len)) != sizeof pkt) {
sprintf(answer, "recvfrom %d err %d", n, errno);
perror(answer);
close(fd);
return 0;
}
}
else {
perror("Timeout");
close(fd);
return 0;
}
sprintf(answer, "Sanitu check\n");
printf(answer);
/* Sanity checks */
if ((pkt.livnmode & 0xc0) == 0xc0 || !pkt.stratum || !pkt.txtime[0]) {
perror("server not synchronized");
close(fd);
return 0;
}
/*
* NTP timestamps are represented as a 64-bit unsigned fixed-
* point number, in seconds relative to 0h on 1 January 1900. The integer
* part is in the first 32 bits and the fraction part in the last 32 bits.
*/
myt = ntohl(pkt.txtime[0]) - MY_OFFSET;
offset = myt - time(NULL);
sprintf(answer, "Time: %s\nstratum %d offset %ld\n",
ctime(&myt), (int) pkt.stratum, offset);
if (fd >= 0) {
close(fd);
}
printf(answer);
return 1;
}