⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sntpdate.c

📁 linux下的internet time 时间同步代码
💻 C
字号:
/* smtpdate.c * Simple ntpdate * * Copyright 2003 Norimasa Matsumoto <matsu@netfort.gr.jp> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * */#include <stdio.h>#include <string.h>#include <stdarg.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/time.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <time.h>#include "ntp.h"#define BUFFSIZE 128#define my_abs( x )  ( (x<0)?(-x):(x) )void error( char *format, ... );int  ntp_query( char *host, double *offset, double *delay );int  ntp_send( int sock, unsigned int ip, int port );int  ntp_recv( int sock, unsigned int ip, int port, 	       struct pkt *rcv_pkt, ntp_time *rcv_time );void calc_offset(  struct pkt *rcv_pkt, ntp_time *rcv_time,		   double *offset, double *delay );void getipport( char *arg, unsigned int *ip, int *port );unsigned int getip( char *hostname );int getport( char *service, char *prot );void getsysntptime( ntp_time *ntm );int  setsystime( double offset );char *ipstr( char *buff, int len, unsigned int ip );#ifdef DEBUGchar *ntp_time_str( char *buff, int len, ntp_time *tm );void pr_pkt_info(  struct pkt *rcv_pkt, ntp_time *rcv_time );int  prtime( char *str );int  sock_info( struct sockaddr_in *addr );#endif /* DEBUG */intmain( int argc, char *argv[]){    int i, opt_i;    double offset, delay, opt_offset, opt_delay;    if( argc < 2 ){	error( "usage: sntpdate host[:port] [host[:port] ... ]\n" );    }    printf( "delay(sec)  offset(sec)  server\n" );    opt_i=-1;    opt_delay = 0.;    opt_offset = 0.;    for( i=1; i<argc; i++ ){	ntp_query( argv[i], &offset, &delay );	printf( "%10.6f  %10.6f   %s\n", delay, offset, argv[i] );	if( (opt_i<0)||( my_abs(delay) < my_abs(opt_delay) )) {	    opt_i = i;	    opt_delay = delay;	    opt_offset = offset;	}    }    if( setsystime( opt_offset ) == 0 ){	printf( "------------------------------------\n" );	printf( "%10.6f  %10.6f   %s\n",		opt_delay, opt_offset, argv[opt_i] );    }    return 0;}intntp_query( char *host, double *offset, double *delay ){    int  sock;    struct pkt rcv_pkt;    ntp_time rcv_time;    unsigned int ip;    int port;    getipport( host, &ip, &port );    if( (sock=socket(AF_INET, SOCK_DGRAM, 0))<0){	error( "socket");    }    ntp_send( sock, ip, port );    ntp_recv( sock, ip, port, &rcv_pkt, &rcv_time );#ifdef DEBUG    pr_pkt_info( &rcv_pkt, &rcv_time );#endif /* DEBUG */    calc_offset( &rcv_pkt, &rcv_time, offset, delay );    close(sock);    return 0;}voiderror( char *format, ... ){    va_list arg;    int     ret;    va_start( arg, format );    ret = fprintf( stderr, format, arg );    va_end(arg);    exit(1);}intntp_send( int sock, unsigned int ip, int port ){    struct sockaddr_in dst;    struct pkt  snd_pkt;    bzero( &dst, sizeof(dst));    dst.sin_family = AF_INET;    dst.sin_addr.s_addr = htonl( ip );    dst.sin_port = htons((unsigned short)port);    bzero( &snd_pkt, sizeof(snd_pkt));    snd_pkt.li_vn_mode = (NTP_VN <<3) + NTP_MODE_CLIENT;#ifdef DEBUG    prtime( "send(start):" );#endif /* DEBUG */    getsysntptime( &(snd_pkt.xmt) );    sendto( sock, (void *)&snd_pkt, sizeof(snd_pkt), 0, 	    (struct sockaddr *)&dst, sizeof( dst ) );#ifdef DEBUG    prtime( "send(end):" );#endif /* DEBUG */    return 0;}intntp_recv( int sock, unsigned int ip, int port, 	  struct pkt *rcv_pkt, ntp_time *rcv_time ){    struct sockaddr_in dst;    int dst_len, len, ret;    char recv[BUFFSIZE];    fd_set rfds;    struct timeval tv;    while(1){	dst_len=sizeof(dst);	bzero( &dst, dst_len );	FD_ZERO(&rfds);	FD_SET( sock, &rfds);	tv.tv_sec  = NTP_TIMEOUT_SEC;	tv.tv_usec = NTP_TIMEOUT_USEC;	ret = select( sock+1, &rfds, NULL, NULL, &tv );	getsysntptime( rcv_time );#ifdef DEBUG	prtime( "select:" );#endif /* DEBUG */	if( ret ){	    len=recvfrom( sock, recv, BUFFSIZE, 0,			  (struct sockaddr *)&dst, &dst_len );#ifdef DEBUG	    prtime( "recv:" );#endif /* DEBUG */	    if( ntohl(dst.sin_addr.s_addr) != ip ){		continue;	    }	    if( ntohs(dst.sin_port) != port ){		continue;	    }	    break;	}else{	    error( "time out\n" );	}    }    if( len < sizeof(*rcv_pkt) ){	error( "packet size\n" );    }    memcpy( rcv_pkt, recv, sizeof(*rcv_pkt) );    if( ntp_vn(rcv_pkt->li_vn_mode) != NTP_VN ||	ntp_mode(rcv_pkt->li_vn_mode) != NTP_MODE_SERVER ){	error( "illeagal packer\n");    }    return 0;}voidcalc_offset(  struct pkt *rcv_pkt, ntp_time *rcv_time,	      double *offset, double *delay ){    double t1,t2,t3,t4;    unsigned int sof;    sof = min(	      min( ntohl(rcv_pkt->org.sec), ntohl(rcv_pkt->rec.sec)),	      min( ntohl(rcv_pkt->xmt.sec), ntohl(rcv_time->sec )) );    t1 = (double)(ntohl(rcv_pkt->org.sec) - sof)	+(double)(ntohl(rcv_pkt->org.fsec))/4294967296.;    t2 = (double)(ntohl(rcv_pkt->rec.sec) - sof)	+(double)(ntohl(rcv_pkt->rec.fsec))/4294967296.;    t3 = (double)(ntohl(rcv_pkt->xmt.sec) - sof)	+(double)(ntohl(rcv_pkt->xmt.fsec))/4294967296.;    t4 = (double)(ntohl(rcv_time->sec) - sof)	+(double)(ntohl(rcv_time->fsec))/4294967296.;    *offset = ( (t2-t1) + (t3-t4) )/2.;    *delay  = (t4-t1) -(t2-t3);#ifdef DEBUG    printf( "T1: %10.6f\n", t1 );    printf( "T2: %10.6f\n", t2 );    printf( "T3: %10.6f\n", t3 );    printf( "T4: %10.6f\n", t4 );    printf( "delay  = ( (T2-T1) + (T3-T4) )/2\n" );    printf( "offset = (T4-T1) - (T2-T3)\n" );#endif /* DEBUG */}voidgetipport( char *arg, unsigned int *ip, int *port ){    char *buff;    char *p;    buff = malloc( strlen(arg) +2 );     if( buff == NULL ){	error( "malloc: " );    }    strcpy( buff, arg );    p = strchr( buff, ':' );    if( p == NULL ){	*ip   = getip( buff );	*port = getport( NTP_SERV, "udp" );    }else{	*p++ = '\0';	*ip   = getip( buff );	*port = getport( p, "udp" );    }    free(buff);}unsigned intgetip( char *hostname ){    struct hostent *host;    unsigned int ip;    host = gethostbyname( hostname );    if( host == NULL ){	fprintf( stderr, "[%s ]", hostname );	error( "host name error: " );    }    ip =  ((unsigned int)(0xff & host->h_addr_list[0][0] ) <<24 )	 +((unsigned int)(0xff & host->h_addr_list[0][1] ) <<16 )	 +((unsigned int)(0xff & host->h_addr_list[0][2] ) <<8  )	 +((unsigned int)(0xff & host->h_addr_list[0][3] )      );    return ip;}intgetport( char *service, char *prot ){    struct servent *ent;    int   port;    if( sscanf( service, "%d", &port) < 1 ){	ent = getservbyname( service, prot );	if( ent == NULL ){	    error( "service name error: " );	}	port = ntohs((unsigned short)(ent->s_port));    }    return port;}voidgetsysntptime( ntp_time *ntm ){    struct timeval tv;    struct timezone tz;    gettimeofday( &tv, &tz );    ntm->sec  = htonl( (unsigned int)tv.tv_sec		      +(unsigned int)(70*365+17)*(24*60*60) );    ntm->fsec = htonl( (unsigned int)( 4294967296. * 				       (double)tv.tv_usec/1000000. +.5) );}intsetsystime( double offset ){    struct timeval tv;    struct timezone tz;    int offset_s, offset_us;    offset_s = (int)offset;    if( offset_s < 0 ){	offset_s -= 1;    }    offset_us = (int)((offset - (double)offset_s)*1000000. +.5);    gettimeofday( &tv, &tz );    tv.tv_sec  += offset_s;    tv.tv_usec += offset_us;    if( tv.tv_usec >= 1000000 ){	tv.tv_usec -= 1000000;	tv.tv_sec  += 1;    }else if( tv.tv_usec < 0 ){	tv.tv_usec += 1000000;	tv.tv_sec  -= 1;    }    if( settimeofday( &tv, &tz ) == 0 ){	fprintf( stderr, "set time\n" );	return 0;    }else{	return -1;    }}char *ipstr( char *buff, int len, unsigned int ip ){    snprintf( buff, len, "%d.%d.%d.%d",	      0xff&(ip>>24),	      0xff&(ip>>16),	      0xff&(ip>> 8),	      0xff&(ip    ) );    return buff;}#ifdef DEBUGchar *ntp_time_str( char *buff, int len, ntp_time *tm ){    time_t ttm;    unsigned int fsec;    struct tm *ltm;    fsec = ntohl(tm->fsec);    ttm =  ntohl(tm->sec) - (unsigned int)(70*365+17)*(24*60*60);    ltm = localtime( &ttm );    snprintf( buff, len, "%d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d.%6.6d",	      ltm->tm_year+1900,	      ltm->tm_mon+1,	      ltm->tm_mday,	      ltm->tm_hour,	      ltm->tm_min,	      ltm->tm_sec,	      (int)(((double)fsec/4294967296.)*1000000. +.5) );    return buff;}intprtime( char *str ){    ntp_time ntm;    char buff[BUFFSIZE];    getsysntptime( &ntm );    printf( "%s %s\n", str, ntp_time_str( buff, BUFFSIZE, &ntm )  );    return 0;}voidpr_pkt_info(  struct pkt *rcv_pkt, ntp_time *rcv_time ){    char buff[BUFFSIZE];    printf( "LI:   %d\n", ntp_li(rcv_pkt->li_vn_mode) );    printf( "VN:   %d\n", ntp_vn(rcv_pkt->li_vn_mode) );    printf( "MODE: %d\n", ntp_mode(rcv_pkt->li_vn_mode) );    printf( "stratum:   %u\n", rcv_pkt->stratum );    printf( "ppoll:     %u\n", rcv_pkt->ppoll );    printf( "precision: %d\n", rcv_pkt->precision );    printf( "rootdelay: %u\n", ntohl(rcv_pkt->rootdelay) );    printf( "rootdispersion: %u\n", ntohl(rcv_pkt->rootdispersion) );    printf( "refid:     %s\n", ipstr( buff, BUFFSIZE, ntohl(rcv_pkt->refid)) );    printf( "reftime: %s\n", 	    ntp_time_str( buff,BUFFSIZE, &(rcv_pkt->reftime) ) );    printf( "T1(org): %s\n", 	    ntp_time_str( buff,BUFFSIZE, &(rcv_pkt->org) ) );    printf( "T2(rec): %s\n", 	    ntp_time_str( buff,BUFFSIZE, &(rcv_pkt->rec) ) );    printf( "T3(xmt): %s\n", 	    ntp_time_str( buff,BUFFSIZE, &(rcv_pkt->xmt) ) );    printf( "T4:      %s\n", 	    ntp_time_str( buff,BUFFSIZE, rcv_time ) );}#endif /* DEBUG */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -