ntp-tools
/
ntpprint-win.c
/
1 contributor
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#include <time.h>
#pragma comment(lib, "ws2_32.lib")
#define NTP_TIMESTAMP_DELTA 2208988800ull
typedef struct {
unsigned char li_vn_mode; // Eight bits. li, vn, and mode.
unsigned char stratum; // Stratum level of the local clock.
unsigned char poll; // Maximum interval between successive messages.
unsigned char precision; // Precision of the local clock.
unsigned int rootDelay;
unsigned int rootDispersion;
unsigned int refId;
unsigned int refTm_s;
unsigned int refTm_f;
unsigned int origTm_s;
unsigned int origTm_f;
unsigned int rxTm_s;
unsigned int rxTm_f;
unsigned int txTm_s;
unsigned int txTm_f;
} NTPPacket;
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <ntp_server>\n", argv[0]);
return 1;
}
const char* ntp_server = argv[1];
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in serverAddr;
NTPPacket packet;
WSAStartup(MAKEWORD(2, 2), &wsaData);
memset(&packet, 0, sizeof(NTPPacket));
packet.li_vn_mode = 0x1B; // LI = 0, VN = 3 (version), Mode = 3 (client)
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET) {
perror("socket");
return 1;
}
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
struct hostent* server = gethostbyname(ntp_server);
if (!server) {
printf("Error: Cannot resolve hostname %s\n", ntp_server);
closesocket(sock);
WSACleanup();
return 1;
}
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(123); // NTP port
memcpy(&serverAddr.sin_addr, server->h_addr, server->h_length);
int sent = sendto(sock, (char*)&packet, sizeof(NTPPacket), 0,
(struct sockaddr*)&serverAddr, sizeof(serverAddr));
if (sent == SOCKET_ERROR) {
perror("sendto");
closesocket(sock);
WSACleanup();
return 1;
}
struct sockaddr_in recvAddr;
int recvAddrLen = sizeof(recvAddr);
int recvLen = recvfrom(sock, (char*)&packet, sizeof(NTPPacket), 0,
(struct sockaddr*)&recvAddr, &recvAddrLen);
if (recvLen == SOCKET_ERROR) {
//perror("recvfrom");
if (WSAGetLastError() == WSAETIMEDOUT) {
printf("Timeout: No response from NTP server within 5 seconds.\n");
} else {
perror("recvfrom");
}
closesocket(sock);
WSACleanup();
return 1;
}
packet.txTm_s = ntohl(packet.txTm_s); // Convert from network byte order
time_t txTime = (time_t)(packet.txTm_s - NTP_TIMESTAMP_DELTA);
printf("NTP Response: %s", ctime(&txTime));
closesocket(sock);
WSACleanup();
return 0;
}