#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <time.h>

#define NTP_TIMESTAMP_DELTA 2208988800ull

int main() {
    int sockfd;
    struct sockaddr_in server_addr;
    unsigned char packet[48] = {0};

    // Set version = 4, mode = 3 (client)
    packet[0] = 0b11100011; // LI = 3 (unsynchronized), VN = 4, Mode = 3

    sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sockfd < 0) {
        perror("Socket creation failed");
        return 1;
    }

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(123);

    // Set NTP server IP (e.g., time.nist.gov)
    if (inet_pton(AF_INET, "129.6.15.28", &server_addr.sin_addr) <= 0) {
        perror("Invalid address");
        close(sockfd);
        return 1;
    }

    // Send packet
    if (sendto(sockfd, packet, sizeof(packet), 0,
               (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Send failed");
        close(sockfd);
        return 1;
    }

    // Receive response
    socklen_t addr_len = sizeof(server_addr);
    if (recvfrom(sockfd, packet, sizeof(packet), 0,
                 (struct sockaddr *)&server_addr, &addr_len) < 0) {
        perror("Receive failed");
        close(sockfd);
        return 1;
    }

    // Extract Transmit Timestamp (bytes 40-43: seconds part)
    uint32_t transmit_time_sec;
    memcpy(&transmit_time_sec, &packet[40], sizeof(transmit_time_sec));
    transmit_time_sec = ntohl(transmit_time_sec);

    time_t real_time = transmit_time_sec - NTP_TIMESTAMP_DELTA;
    printf("Server time: %s", ctime(&real_time));

    close(sockfd);
    return 0;
}

