|
|
@@ -1,5 +1,6 @@
|
|
|
-
|
|
|
+#include <netdb.h>
|
|
|
#include "ntpclient.h"
|
|
|
+
|
|
|
|
|
|
#define NTP_PORT 123
|
|
|
#define NTP_PACKET_SIZE 48
|
|
|
@@ -8,7 +9,7 @@
|
|
|
static int sendNTPRequest(NTPClient* client) {
|
|
|
client->ntp_packet[0] = 0x1B; // LI = 0, VN = 3, Mode = 3 (client)
|
|
|
ssize_t sentBytes = sendto(client->sockfd, client->ntp_packet, NTP_PACKET_SIZE, 0,
|
|
|
- (struct sockaddr *)&client->server_addr, sizeof(client->server_addr));
|
|
|
+ &client->server_addr, sizeof(client->server_addr));
|
|
|
if (sentBytes < 0) {
|
|
|
perror("sendto failed");
|
|
|
return -1;
|
|
|
@@ -20,7 +21,7 @@ static int sendNTPRequest(NTPClient* client) {
|
|
|
static int receiveNTPResponse(NTPClient* client) {
|
|
|
socklen_t len = sizeof(client->server_addr);
|
|
|
ssize_t receivedBytes = recvfrom(client->sockfd, client->ntp_packet, NTP_PACKET_SIZE, 0,
|
|
|
- (struct sockaddr *)&client->server_addr, &len);
|
|
|
+ &client->server_addr, &len);
|
|
|
if (receivedBytes < 0) {
|
|
|
perror("recvfrom failed");
|
|
|
return -1;
|
|
|
@@ -35,8 +36,31 @@ static time_t parseNTPResponse(const char* ntp_packet) {
|
|
|
double frac = frac_sec * 2.0e-32;
|
|
|
return (time_t)(sec_since_1900 - 2208988800U) + (time_t)frac;
|
|
|
}
|
|
|
- #include<netdb.h>
|
|
|
-// 创建NTP客户端实例
|
|
|
+
|
|
|
+static int get_addr(const char* ip, int port, struct sockaddr *saddr)
|
|
|
+{
|
|
|
+ char *p=NULL;
|
|
|
+ struct sockaddr_in *p4=(struct sockaddr_in*)saddr;
|
|
|
+ struct sockaddr_in6 *p6=(struct sockaddr_in6*)saddr;
|
|
|
+
|
|
|
+ p4->sin_family = AF_INET;
|
|
|
+ p4->sin_port = port;
|
|
|
+ p = (char*)inet_pton(AF_INET, ip, &p4->sin_addr);
|
|
|
+ if(p) {
|
|
|
+ printf("____ ipv4, %d\n", AF_INET);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ p6->sin6_family = AF_INET6;
|
|
|
+ p6->sin6_port = port;
|
|
|
+ p = (char*)inet_pton(AF_INET, ip, &p6->sin6_addr);
|
|
|
+ if(p) {
|
|
|
+ printf("____ ipv6, %d\n", AF_INET6);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return -1;
|
|
|
+}
|
|
|
NTPClient* createNTPClient(const char* ntp_server, int port) {
|
|
|
NTPClient* client = (NTPClient*)malloc(sizeof(NTPClient));
|
|
|
if (!client) {
|
|
|
@@ -44,44 +68,62 @@ NTPClient* createNTPClient(const char* ntp_server, int port) {
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
- int fd=-1;
|
|
|
+ int r,fd=-1;
|
|
|
char tmp[32];
|
|
|
struct addrinfo hints;
|
|
|
struct addrinfo *res=NULL,*rp;
|
|
|
char temp[INET6_ADDRSTRLEN];
|
|
|
+ struct sockaddr_in *p4=NULL;
|
|
|
+ struct sockaddr_in6 *p6=NULL;
|
|
|
|
|
|
memset(&hints, 0, sizeof hints);
|
|
|
hints.ai_family = AF_UNSPEC;
|
|
|
hints.ai_socktype = SOCK_DGRAM;
|
|
|
- hints.ai_protocol = IPPROTO_UDP;
|
|
|
+ hints.ai_protocol = 0;//IPPROTO_UDP;
|
|
|
|
|
|
- sprintf(tmp, "%d", port);
|
|
|
- if(getaddrinfo(ntp_server, tmp, &hints, &res) || (res==NULL)){
|
|
|
- printf(" getaddrinfo %s:%d failed\n", ntp_server, port);
|
|
|
- free(client); return NULL;
|
|
|
- }
|
|
|
-
|
|
|
- for(rp=res; rp; rp=rp->ai_next){
|
|
|
- fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
|
|
+ r = get_addr(ntp_server, port, &client->server_addr);
|
|
|
+ if(r==0) {
|
|
|
+ fd = socket(client->server_addr.sa_family, SOCK_DGRAM, 0);
|
|
|
if (fd>=0) {
|
|
|
- break;
|
|
|
+ client->sockfd = fd;
|
|
|
}
|
|
|
- if(rp->ai_family==AF_INET) {
|
|
|
- struct sockaddr_in *p4=(struct sockaddr_in*)rp->ai_addr;
|
|
|
- inet_ntop(AF_INET, p4, temp, INET6_ADDRSTRLEN);
|
|
|
- printf("socket to %s:%d failed\n", temp, p4->sin_port);
|
|
|
+ printf("socket to %s:%d %s, %d\n", ntp_server, port, (fd>=0)?"ok!":"failed!", client->server_addr.sa_family);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ sprintf(tmp, "%d", port);
|
|
|
+ if(getaddrinfo(ntp_server, tmp, &hints, &res) || (res==NULL)){
|
|
|
+ printf(" getaddrinfo from %s:%d failed\n", ntp_server, port);
|
|
|
+ free(client); return NULL;
|
|
|
}
|
|
|
- else {
|
|
|
- struct sockaddr_in6 *p6=(struct sockaddr_in6*)rp->ai_addr;
|
|
|
- inet_ntop(AF_INET6, p6, temp, INET6_ADDRSTRLEN);
|
|
|
- printf("socket to %s:%d failed\n", temp, p6->sin6_port);
|
|
|
+
|
|
|
+ for(rp=res; rp; rp=rp->ai_next){
|
|
|
+ if(rp->ai_family==AF_INET) {
|
|
|
+ p4=(struct sockaddr_in*)rp->ai_addr;
|
|
|
+ inet_ntop(AF_INET, p4, temp, INET6_ADDRSTRLEN);
|
|
|
+ printf("socket to %s:%d ", temp, p4->sin_port);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ p6=(struct sockaddr_in6*)rp->ai_addr;
|
|
|
+ inet_ntop(AF_INET6, p6, temp, INET6_ADDRSTRLEN);
|
|
|
+ printf("socket to %s:%d ", temp, p6->sin6_port);
|
|
|
+ }
|
|
|
+
|
|
|
+ fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
|
|
+ if (fd>=0) {
|
|
|
+ client->sockfd = fd;
|
|
|
+ client->server_addr = *rp->ai_addr;
|
|
|
+ printf("ok!\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ printf("failed!\n");
|
|
|
}
|
|
|
+ freeaddrinfo(res);
|
|
|
}
|
|
|
- freeaddrinfo(res);
|
|
|
+
|
|
|
if(fd<0) {
|
|
|
free(client); return NULL;
|
|
|
}
|
|
|
- client->sockfd = fd;
|
|
|
+ printf("___createNTPClient ok!\n");
|
|
|
|
|
|
return client;
|
|
|
}
|
|
|
@@ -98,7 +140,7 @@ void destroyNTPClient(NTPClient* client) {
|
|
|
int getCurrentTimeFromNTP(NTPClient* client, time_t* current_time) {
|
|
|
if (sendNTPRequest(client) < 0) {
|
|
|
return -1;
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
if (receiveNTPResponse(client) < 0) {
|
|
|
return -1;
|