/* * ntpprobe.c * * Shows version and stratum of a NTP server. * * Usage: * ntpprobe host * * by Michal Wojciechowski * */ #include #include #include #include #include #include #include #include #include #define MAXATTEMPTS 3 main(int argc, char *argv[]) { int sock; struct sockaddr_in sa; struct hostent *hptr; char sntpmsg[48]; char response[128]; struct in_addr *ia; struct timeval tv; int attempt = 0; int r; if (argc < 2) { fprintf(stderr, "Usage: %s host\n", argv[0]); exit(1); } sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1) { perror(argv[0]); exit(1); } tv.tv_sec = 5; tv.tv_usec = 0; if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { perror(argv[0]); exit(1); } memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(123); if ((hptr = gethostbyname(argv[1])) == NULL) { fprintf(stderr, "Host not found.\n"); exit(1); } ia = (struct in_addr *)hptr->h_addr_list[0]; memcpy(&sa.sin_addr, ia, sizeof(*ia)); memset(sntpmsg, 0, sizeof(sntpmsg)); /* LI = 0, VN = 3, Mode = client (see RFC 2030) */ sntpmsg[0] = 0 << 6 | 3 << 3 | 3; while (attempt < MAXATTEMPTS) { if (sendto(sock, sntpmsg, sizeof(sntpmsg), 0, (struct sockaddr *)&sa, sizeof(sa)) == -1) { fprintf(stderr, "Can't send\n"); exit(1); } if ((r = recvfrom(sock, response, sizeof(response), 0, NULL, NULL)) < 0) { if (++attempt > MAXATTEMPTS) break; } else { printf("%s: NTP server version %d, stratum %d.\n", argv[1], (unsigned char)((response[0] & 0x38) >> 3), (unsigned char)response[1]); exit(0); } } printf("%s: NTP server not available.\n", argv[1]); exit(0); }