Home | History | Annotate | Line # | Download | only in sntp
main.c revision 1.3
      1  1.3  kardel /*	$NetBSD: main.c,v 1.3 2012/02/01 07:46:23 kardel Exp $	*/
      2  1.1  kardel 
      3  1.3  kardel #include <config.h>
      4  1.1  kardel 
      5  1.3  kardel #include "main.h"
      6  1.1  kardel #include "kod_management.h"
      7  1.1  kardel #include "networking.h"
      8  1.1  kardel #include "utilities.h"
      9  1.1  kardel #include "log.h"
     10  1.1  kardel 
     11  1.1  kardel int ai_fam_pref = AF_UNSPEC;
     12  1.1  kardel 
     13  1.1  kardel struct key *keys = NULL;
     14  1.1  kardel 
     15  1.1  kardel void set_li_vn_mode (struct pkt *spkt, char leap, char version, char mode);
     16  1.1  kardel int sntp_main (int argc, char **argv);
     17  1.3  kardel int on_wire (struct addrinfo *host, struct addrinfo *bcastaddr);
     18  1.1  kardel int set_time (double offset);
     19  1.1  kardel 
     20  1.3  kardel #define NORMALIZE_TIMEVAL(tv)				\
     21  1.3  kardel do {							\
     22  1.3  kardel 	while ((tv).tv_usec < 0) {			\
     23  1.3  kardel 		(tv).tv_usec += 1000000;		\
     24  1.3  kardel 		(tv).tv_sec--;				\
     25  1.3  kardel 	}						\
     26  1.3  kardel 	while ((tv).tv_usec > 999999) {			\
     27  1.3  kardel 		(tv).tv_usec -= 1000000;		\
     28  1.3  kardel 		(tv).tv_sec++;				\
     29  1.3  kardel 	}						\
     30  1.3  kardel } while (0)
     31  1.1  kardel 
     32  1.1  kardel 
     33  1.1  kardel /*
     34  1.1  kardel  * The actual main function.
     35  1.1  kardel  */
     36  1.1  kardel int
     37  1.1  kardel sntp_main (
     38  1.3  kardel 	int argc,
     39  1.3  kardel 	char **argv
     40  1.3  kardel 	)
     41  1.1  kardel {
     42  1.1  kardel 	register int c;
     43  1.1  kardel 	struct kod_entry *reason = NULL;
     44  1.1  kardel 	int optct;
     45  1.3  kardel 	/* boolean, u_int quiets gcc4 signed overflow warning */
     46  1.3  kardel 	u_int sync_data_suc;
     47  1.3  kardel 	struct addrinfo **bcastaddr = NULL;
     48  1.1  kardel 	struct addrinfo **resh = NULL;
     49  1.1  kardel 	struct addrinfo *ai;
     50  1.1  kardel 	int resc;
     51  1.1  kardel 	int kodc;
     52  1.1  kardel 	int ow_ret;
     53  1.3  kardel 	int bcast = 0;
     54  1.1  kardel 	char *hostname;
     55  1.1  kardel 
     56  1.3  kardel 	optct = optionProcess(&sntpOptions, argc, argv);
     57  1.3  kardel 	argc -= optct;
     58  1.3  kardel 	argv += optct;
     59  1.3  kardel 
     60  1.3  kardel 	/* Initialize logging system */
     61  1.3  kardel 	init_logging();
     62  1.3  kardel 	if (HAVE_OPT(LOGFILE))
     63  1.3  kardel 		open_logfile(OPT_ARG(LOGFILE));
     64  1.3  kardel 
     65  1.3  kardel 	msyslog(LOG_NOTICE, "Started sntp");
     66  1.3  kardel 
     67  1.1  kardel 	/* IPv6 available? */
     68  1.1  kardel 	if (isc_net_probeipv6() != ISC_R_SUCCESS) {
     69  1.1  kardel 		ai_fam_pref = AF_INET;
     70  1.1  kardel #ifdef DEBUG
     71  1.1  kardel 		printf("No ipv6 support available, forcing ipv4\n");
     72  1.1  kardel #endif
     73  1.3  kardel 	} else {
     74  1.1  kardel 		/* Check for options -4 and -6 */
     75  1.1  kardel 		if (HAVE_OPT(IPV4))
     76  1.1  kardel 			ai_fam_pref = AF_INET;
     77  1.1  kardel 		else if (HAVE_OPT(IPV6))
     78  1.1  kardel 			ai_fam_pref = AF_INET6;
     79  1.1  kardel 	}
     80  1.1  kardel 
     81  1.1  kardel 	/* Parse config file if declared TODO */
     82  1.1  kardel 
     83  1.1  kardel 	/*
     84  1.1  kardel 	 * If there's a specified KOD file init KOD system.  If not use
     85  1.1  kardel 	 * default file.  For embedded systems with no writable
     86  1.1  kardel 	 * filesystem, -K /dev/null can be used to disable KoD storage.
     87  1.1  kardel 	 */
     88  1.1  kardel 	if (HAVE_OPT(KOD))
     89  1.1  kardel 		kod_init_kod_db(OPT_ARG(KOD));
     90  1.1  kardel 	else
     91  1.1  kardel 		kod_init_kod_db("/var/db/ntp-kod");
     92  1.1  kardel 
     93  1.1  kardel 	if (HAVE_OPT(KEYFILE))
     94  1.1  kardel 		auth_init(OPT_ARG(KEYFILE), &keys);
     95  1.1  kardel 
     96  1.1  kardel #ifdef EXERCISE_KOD_DB
     97  1.1  kardel 	add_entry("192.168.169.170", "DENY");
     98  1.1  kardel 	add_entry("192.168.169.171", "DENY");
     99  1.1  kardel 	add_entry("192.168.169.172", "DENY");
    100  1.1  kardel 	add_entry("192.168.169.173", "DENY");
    101  1.1  kardel 	add_entry("192.168.169.174", "DENY");
    102  1.1  kardel 	delete_entry("192.168.169.174", "DENY");
    103  1.1  kardel 	delete_entry("192.168.169.172", "DENY");
    104  1.1  kardel 	delete_entry("192.168.169.170", "DENY");
    105  1.1  kardel 	if ((kodc = search_entry("192.168.169.173", &reason)) == 0)
    106  1.1  kardel 		printf("entry for 192.168.169.173 not found but should have been!\n");
    107  1.1  kardel 	else
    108  1.1  kardel 		free(reason);
    109  1.1  kardel #endif
    110  1.1  kardel 
    111  1.1  kardel 	/* Considering employing a variable that prevents functions of doing anything until
    112  1.1  kardel 	 * everything is initialized properly
    113  1.1  kardel 	 */
    114  1.3  kardel 	resc = resolve_hosts((const char **)argv, argc, &resh, ai_fam_pref);
    115  1.1  kardel 	if (resc < 1) {
    116  1.1  kardel 		printf("Unable to resolve hostname(s)\n");
    117  1.1  kardel 		return -1;
    118  1.1  kardel 	}
    119  1.3  kardel 	bcast = ENABLED_OPT(BROADCAST);
    120  1.3  kardel 	if (bcast) {
    121  1.3  kardel 		const char * myargv[2];
    122  1.3  kardel 
    123  1.3  kardel 		myargv[0] = OPT_ARG(BROADCAST);
    124  1.3  kardel 		myargv[1] = NULL;
    125  1.3  kardel 		bcast = resolve_hosts(myargv, 1, &bcastaddr, ai_fam_pref);
    126  1.3  kardel 	}
    127  1.1  kardel 
    128  1.1  kardel 	/* Select a certain ntp server according to simple criteria? For now
    129  1.1  kardel 	 * let's just pay attention to previous KoDs.
    130  1.1  kardel 	 */
    131  1.3  kardel 	sync_data_suc = FALSE;
    132  1.1  kardel 	for (c = 0; c < resc && !sync_data_suc; c++) {
    133  1.1  kardel 		ai = resh[c];
    134  1.1  kardel 		do {
    135  1.1  kardel 			hostname = addrinfo_to_str(ai);
    136  1.1  kardel 			if ((kodc = search_entry(hostname, &reason)) == 0) {
    137  1.1  kardel 				if (is_reachable(ai)) {
    138  1.3  kardel 					ow_ret = on_wire(ai, bcast ? bcastaddr[0] : NULL);
    139  1.3  kardel 					if (0 == ow_ret)
    140  1.3  kardel 						sync_data_suc = TRUE;
    141  1.1  kardel 				}
    142  1.1  kardel 			} else {
    143  1.1  kardel 				printf("%d prior KoD%s for %s, skipping.\n",
    144  1.1  kardel 					kodc, (kodc > 1) ? "s" : "", hostname);
    145  1.1  kardel 				free(reason);
    146  1.1  kardel 			}
    147  1.1  kardel 			free(hostname);
    148  1.1  kardel 			ai = ai->ai_next;
    149  1.1  kardel 		} while (NULL != ai);
    150  1.1  kardel 		freeaddrinfo(resh[c]);
    151  1.1  kardel 	}
    152  1.1  kardel 	free(resh);
    153  1.1  kardel 
    154  1.3  kardel 	if (!sync_data_suc)
    155  1.3  kardel 		return 1;
    156  1.1  kardel 	return 0;
    157  1.1  kardel }
    158  1.1  kardel 
    159  1.3  kardel static union {
    160  1.3  kardel 	struct pkt pkt;
    161  1.3  kardel 	char   buf[1500];
    162  1.3  kardel } rbuf;
    163  1.3  kardel 
    164  1.3  kardel #define r_pkt  rbuf.pkt
    165  1.3  kardel 
    166  1.3  kardel int
    167  1.3  kardel generate_pkt (
    168  1.3  kardel 	struct pkt *x_pkt,
    169  1.3  kardel 	const struct timeval *tv_xmt,
    170  1.3  kardel 	int key_id,
    171  1.3  kardel 	struct key *pkt_key
    172  1.3  kardel 	)
    173  1.3  kardel {
    174  1.3  kardel 	l_fp xmt;
    175  1.3  kardel 	int pkt_len = LEN_PKT_NOMAC;
    176  1.3  kardel 	memset(x_pkt, 0, sizeof(struct pkt));
    177  1.3  kardel 	TVTOTS(tv_xmt, &xmt);
    178  1.3  kardel 	HTONL_FP(&xmt, &(x_pkt->xmt));
    179  1.3  kardel 	x_pkt->stratum = STRATUM_TO_PKT(STRATUM_UNSPEC);
    180  1.3  kardel 	x_pkt->ppoll = 8;
    181  1.3  kardel 	/* FIXME! Modus broadcast + adr. check -> bdr. pkt */
    182  1.3  kardel 	set_li_vn_mode(x_pkt, LEAP_NOTINSYNC, 4, 3);
    183  1.3  kardel 	if (pkt_key != NULL) {
    184  1.3  kardel 		int mac_size = 20; /* max room for MAC */
    185  1.3  kardel 		x_pkt->exten[0] = htonl(key_id);
    186  1.3  kardel 		mac_size = make_mac((char *)x_pkt, pkt_len, mac_size, pkt_key, (char *)&x_pkt->exten[1]);
    187  1.3  kardel 		if (mac_size)
    188  1.3  kardel 			pkt_len += mac_size + 4;
    189  1.3  kardel 	}
    190  1.3  kardel 	return pkt_len;
    191  1.3  kardel }
    192  1.3  kardel 
    193  1.1  kardel int
    194  1.3  kardel handle_pkt (
    195  1.3  kardel 	int rpktl,
    196  1.3  kardel 	struct pkt *rpkt,
    197  1.3  kardel 	struct addrinfo *host
    198  1.3  kardel 	)
    199  1.1  kardel {
    200  1.3  kardel 	struct timeval tv_dst;
    201  1.3  kardel 	int sw_case, digits;
    202  1.3  kardel 	char *hostname = NULL, *ref, *ts_str = NULL;
    203  1.3  kardel 	double offset, precision, root_dispersion;
    204  1.1  kardel 	char addr_buf[INET6_ADDRSTRLEN];
    205  1.3  kardel 	char *p_SNTP_PRETEND_TIME;
    206  1.3  kardel 	time_t pretend_time;
    207  1.1  kardel 
    208  1.3  kardel 	if(rpktl > 0)
    209  1.3  kardel 		sw_case = 1;
    210  1.3  kardel 	else
    211  1.3  kardel 		sw_case = rpktl;
    212  1.1  kardel 
    213  1.3  kardel 	switch(sw_case) {
    214  1.3  kardel 	case SERVER_UNUSEABLE:
    215  1.3  kardel 		return -1;
    216  1.3  kardel 		break;
    217  1.1  kardel 
    218  1.3  kardel 	case PACKET_UNUSEABLE:
    219  1.3  kardel 		break;
    220  1.3  kardel 
    221  1.3  kardel 	case SERVER_AUTH_FAIL:
    222  1.3  kardel 		break;
    223  1.3  kardel 
    224  1.3  kardel 	case KOD_DEMOBILIZE:
    225  1.3  kardel 		/* Received a DENY or RESTR KOD packet */
    226  1.3  kardel 		hostname = addrinfo_to_str(host);
    227  1.3  kardel 		ref = (char *)&rpkt->refid;
    228  1.3  kardel 		add_entry(hostname, ref);
    229  1.3  kardel 
    230  1.3  kardel 		if (ENABLED_OPT(NORMALVERBOSE))
    231  1.3  kardel 			printf("sntp handle_pkt: Received KOD packet with code: %c%c%c%c from %s, demobilizing all connections\n",
    232  1.3  kardel 				   ref[0], ref[1], ref[2], ref[3],
    233  1.3  kardel 				   hostname);
    234  1.3  kardel 
    235  1.3  kardel 		msyslog(LOG_WARNING, "Received a KOD packet with code %c%c%c%c from %s, demobilizing all connections",
    236  1.3  kardel 			ref[0], ref[1], ref[2], ref[3], hostname);
    237  1.3  kardel 		break;
    238  1.3  kardel 
    239  1.3  kardel 	case KOD_RATE:
    240  1.3  kardel 		/* Hmm... probably we should sleep a bit here */
    241  1.3  kardel 		break;
    242  1.3  kardel 
    243  1.3  kardel 	case 1:
    244  1.3  kardel 		if (ENABLED_OPT(NORMALVERBOSE)) {
    245  1.3  kardel 			getnameinfo(host->ai_addr, host->ai_addrlen, addr_buf,
    246  1.3  kardel 				sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
    247  1.3  kardel 			printf("sntp handle_pkt: Received %i bytes from %s\n", rpktl, addr_buf);
    248  1.3  kardel 		}
    249  1.1  kardel 
    250  1.3  kardel 		GETTIMEOFDAY(&tv_dst, (struct timezone *)NULL);
    251  1.1  kardel 
    252  1.3  kardel 		p_SNTP_PRETEND_TIME = getenv("SNTP_PRETEND_TIME");
    253  1.3  kardel 		if (p_SNTP_PRETEND_TIME) {
    254  1.3  kardel #if SIZEOF_TIME_T == 4
    255  1.3  kardel 			sscanf(p_SNTP_PRETEND_TIME, "%ld", &pretend_time);
    256  1.3  kardel #elif SIZEOF_TIME_T == 8
    257  1.3  kardel 			sscanf(p_SNTP_PRETEND_TIME, "%lld", &pretend_time);
    258  1.3  kardel #else
    259  1.3  kardel # include "GRONK: unexpected value for SIZEOF_TIME_T"
    260  1.1  kardel #endif
    261  1.3  kardel 			tv_dst.tv_sec = pretend_time;
    262  1.3  kardel 		}
    263  1.1  kardel 
    264  1.3  kardel 		offset_calculation(rpkt, rpktl, &tv_dst, &offset,
    265  1.3  kardel 				   &precision, &root_dispersion);
    266  1.1  kardel 
    267  1.3  kardel 		for (digits = 0; (precision *= 10.) < 1.; ++digits)
    268  1.3  kardel 			/* empty */ ;
    269  1.3  kardel 		if (digits > 6)
    270  1.3  kardel 			digits = 6;
    271  1.3  kardel 
    272  1.3  kardel 		ts_str = tv_to_str(&tv_dst);
    273  1.3  kardel 		printf("%s ", ts_str);
    274  1.3  kardel 		if (offset > 0)
    275  1.3  kardel 			printf("+");
    276  1.3  kardel 		printf("%.*f", digits, offset);
    277  1.3  kardel 		if (root_dispersion > 0.)
    278  1.3  kardel 			printf(" +/- %f secs", root_dispersion);
    279  1.3  kardel 		printf("\n");
    280  1.3  kardel 		free(ts_str);
    281  1.1  kardel 
    282  1.3  kardel 		if (p_SNTP_PRETEND_TIME)
    283  1.3  kardel 			return 0;
    284  1.3  kardel 
    285  1.3  kardel 		if (ENABLED_OPT(SETTOD) || ENABLED_OPT(ADJTIME))
    286  1.3  kardel 			return set_time(offset);
    287  1.3  kardel 
    288  1.3  kardel 		return 0;
    289  1.3  kardel 	}
    290  1.3  kardel 
    291  1.3  kardel 	return 1;
    292  1.3  kardel }
    293  1.3  kardel 
    294  1.3  kardel void
    295  1.3  kardel offset_calculation (
    296  1.3  kardel 	struct pkt *rpkt,
    297  1.3  kardel 	int rpktl,
    298  1.3  kardel 	struct timeval *tv_dst,
    299  1.3  kardel 	double *offset,
    300  1.3  kardel 	double *precision,
    301  1.3  kardel 	double *root_dispersion
    302  1.3  kardel 	)
    303  1.3  kardel {
    304  1.3  kardel 	l_fp p_rec, p_xmt, p_ref, p_org, tmp, dst;
    305  1.3  kardel 	u_fp p_rdly, p_rdsp;
    306  1.3  kardel 	double t21, t34, delta;
    307  1.3  kardel 
    308  1.3  kardel 	/* Convert timestamps from network to host byte order */
    309  1.3  kardel 	p_rdly = NTOHS_FP(rpkt->rootdelay);
    310  1.3  kardel 	p_rdsp = NTOHS_FP(rpkt->rootdisp);
    311  1.3  kardel 	NTOHL_FP(&rpkt->reftime, &p_ref);
    312  1.3  kardel 	NTOHL_FP(&rpkt->org, &p_org);
    313  1.3  kardel 	NTOHL_FP(&rpkt->rec, &p_rec);
    314  1.3  kardel 	NTOHL_FP(&rpkt->xmt, &p_xmt);
    315  1.1  kardel 
    316  1.3  kardel 	*precision = LOGTOD(rpkt->precision);
    317  1.1  kardel #ifdef DEBUG
    318  1.3  kardel 	printf("sntp precision: %f\n", *precision);
    319  1.1  kardel #endif /* DEBUG */
    320  1.1  kardel 
    321  1.3  kardel 	*root_dispersion = FPTOD(p_rdsp);
    322  1.1  kardel 
    323  1.1  kardel #ifdef DEBUG
    324  1.3  kardel 	printf("sntp rootdelay: %f\n", FPTOD(p_rdly));
    325  1.3  kardel 	printf("sntp rootdisp: %f\n", *root_dispersion);
    326  1.1  kardel 
    327  1.3  kardel 	pkt_output(rpkt, rpktl, stdout);
    328  1.1  kardel 
    329  1.3  kardel 	printf("sntp offset_calculation: rpkt->reftime:\n");
    330  1.3  kardel 	l_fp_output(&(rpkt->reftime), stdout);
    331  1.3  kardel 	printf("sntp offset_calculation: rpkt->org:\n");
    332  1.3  kardel 	l_fp_output(&(rpkt->org), stdout);
    333  1.3  kardel 	printf("sntp offset_calculation: rpkt->rec:\n");
    334  1.3  kardel 	l_fp_output(&(rpkt->rec), stdout);
    335  1.3  kardel 	printf("sntp offset_calculation: rpkt->rec:\n");
    336  1.3  kardel 	l_fp_output_bin(&(rpkt->rec), stdout);
    337  1.3  kardel 	printf("sntp offset_calculation: rpkt->rec:\n");
    338  1.3  kardel 	l_fp_output_dec(&(rpkt->rec), stdout);
    339  1.3  kardel 	printf("sntp offset_calculation: rpkt->xmt:\n");
    340  1.3  kardel 	l_fp_output(&(rpkt->xmt), stdout);
    341  1.1  kardel #endif
    342  1.1  kardel 
    343  1.3  kardel 	/* Compute offset etc. */
    344  1.3  kardel 	tmp = p_rec;
    345  1.3  kardel 	L_SUB(&tmp, &p_org);
    346  1.3  kardel 	LFPTOD(&tmp, t21);
    347  1.3  kardel 	TVTOTS(tv_dst, &dst);
    348  1.3  kardel 	dst.l_ui += JAN_1970;
    349  1.3  kardel 	tmp = p_xmt;
    350  1.3  kardel 	L_SUB(&tmp, &dst);
    351  1.3  kardel 	LFPTOD(&tmp, t34);
    352  1.3  kardel 	*offset = (t21 + t34) / 2.;
    353  1.3  kardel 	delta = t21 - t34;
    354  1.1  kardel 
    355  1.3  kardel 	if (ENABLED_OPT(NORMALVERBOSE))
    356  1.3  kardel 		printf("sntp offset_calculation:\tt21: %.6f\t\t t34: %.6f\n\t\tdelta: %.6f\t offset: %.6f\n",
    357  1.3  kardel 			   t21, t34, delta, *offset);
    358  1.3  kardel }
    359  1.1  kardel 
    360  1.3  kardel /* The heart of (S)NTP, exchange NTP packets and compute values to correct the local clock */
    361  1.3  kardel int
    362  1.3  kardel on_wire (
    363  1.3  kardel 	struct addrinfo *host,
    364  1.3  kardel 	struct addrinfo *bcast
    365  1.3  kardel 	)
    366  1.3  kardel {
    367  1.3  kardel 	char addr_buf[INET6_ADDRSTRLEN];
    368  1.3  kardel 	register int try;
    369  1.3  kardel 	SOCKET sock;
    370  1.3  kardel 	struct key *pkt_key = NULL;
    371  1.3  kardel 	int key_id = 0;
    372  1.3  kardel 	struct timeval tv_xmt;
    373  1.3  kardel 	struct pkt x_pkt;
    374  1.3  kardel 	int error, rpktl, handle_pkt_res;
    375  1.1  kardel 
    376  1.1  kardel 
    377  1.3  kardel 	if (ENABLED_OPT(AUTHENTICATION)) {
    378  1.3  kardel 		key_id = (int) atol(OPT_ARG(AUTHENTICATION));
    379  1.3  kardel 		get_key(key_id, &pkt_key);
    380  1.3  kardel 	}
    381  1.3  kardel 	for (try=0; try<5; try++) {
    382  1.3  kardel 		memset(&r_pkt, 0, sizeof rbuf);
    383  1.3  kardel 
    384  1.3  kardel 		error = GETTIMEOFDAY(&tv_xmt, (struct timezone *)NULL);
    385  1.3  kardel 		tv_xmt.tv_sec += JAN_1970;
    386  1.1  kardel 
    387  1.3  kardel #ifdef DEBUG
    388  1.3  kardel 		printf("sntp on_wire: Current time sec: %i msec: %i\n", (unsigned int) tv_xmt.tv_sec,
    389  1.3  kardel 				(unsigned int) tv_xmt.tv_usec);
    390  1.3  kardel #endif
    391  1.1  kardel 
    392  1.3  kardel 		if (bcast) {
    393  1.3  kardel 			create_socket(&sock, (sockaddr_u *)bcast->ai_addr);
    394  1.3  kardel 			rpktl = recv_bcst_pkt(sock, &r_pkt, sizeof rbuf, (sockaddr_u *)bcast->ai_addr);
    395  1.3  kardel 			closesocket(sock);
    396  1.3  kardel 		} else {
    397  1.3  kardel 			int pkt_len = generate_pkt(&x_pkt, &tv_xmt, key_id, pkt_key);
    398  1.3  kardel 
    399  1.3  kardel 			create_socket(&sock, (sockaddr_u *)host->ai_addr);
    400  1.3  kardel 			sendpkt(sock, (sockaddr_u *)host->ai_addr, &x_pkt, pkt_len);
    401  1.3  kardel 			rpktl = recvpkt(sock, &r_pkt, sizeof rbuf, &x_pkt);
    402  1.3  kardel 			closesocket(sock);
    403  1.3  kardel 		}
    404  1.1  kardel 
    405  1.3  kardel 		handle_pkt_res = handle_pkt(rpktl, &r_pkt, host);
    406  1.3  kardel 		if (handle_pkt_res < 1)
    407  1.3  kardel 			return handle_pkt_res;
    408  1.1  kardel 	}
    409  1.1  kardel 
    410  1.1  kardel 	getnameinfo(host->ai_addr, host->ai_addrlen, addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
    411  1.3  kardel 	msyslog(LOG_DEBUG, "Received no useable packet from %s!", addr_buf);
    412  1.1  kardel 
    413  1.1  kardel 	return -1;
    414  1.1  kardel }
    415  1.1  kardel 
    416  1.1  kardel /* Compute the 8 bits for li_vn_mode */
    417  1.1  kardel void
    418  1.1  kardel set_li_vn_mode (
    419  1.3  kardel 	struct pkt *spkt,
    420  1.3  kardel 	char leap,
    421  1.3  kardel 	char version,
    422  1.3  kardel 	char mode
    423  1.3  kardel 	)
    424  1.1  kardel {
    425  1.3  kardel 	if (leap > 3) {
    426  1.3  kardel 		msyslog(LOG_DEBUG, "set_li_vn_mode: leap > 3 using max. 3");
    427  1.1  kardel 		leap = 3;
    428  1.1  kardel 	}
    429  1.1  kardel 
    430  1.3  kardel 	if (mode > 7) {
    431  1.3  kardel 		msyslog(LOG_DEBUG, "set_li_vn_mode: mode > 7, using client mode 3");
    432  1.1  kardel 		mode = 3;
    433  1.1  kardel 	}
    434  1.1  kardel 
    435  1.1  kardel 	spkt->li_vn_mode  = leap << 6;
    436  1.1  kardel 	spkt->li_vn_mode |= version << 3;
    437  1.1  kardel 	spkt->li_vn_mode |= mode;
    438  1.1  kardel }
    439  1.1  kardel 
    440  1.1  kardel /* set_time corrects the local clock by offset with either settimeofday() or by default
    441  1.1  kardel  * with adjtime()/adjusttimeofday().
    442  1.1  kardel  */
    443  1.1  kardel int
    444  1.3  kardel set_time(
    445  1.3  kardel 	double offset
    446  1.3  kardel 	)
    447  1.1  kardel {
    448  1.1  kardel 	struct timeval tp;
    449  1.1  kardel 
    450  1.3  kardel 	if (ENABLED_OPT(SETTOD)) {
    451  1.3  kardel 		GETTIMEOFDAY(&tp, NULL);
    452  1.1  kardel 
    453  1.3  kardel 		tp.tv_sec += (long)offset;
    454  1.3  kardel 		tp.tv_usec += 1e6 * (offset - (long)offset);
    455  1.3  kardel 		NORMALIZE_TIMEVAL(tp);
    456  1.1  kardel 
    457  1.3  kardel 		if (SETTIMEOFDAY(&tp, NULL) < 0) {
    458  1.3  kardel 			msyslog(LOG_ERR, "Time not set: settimeofday(): %m");
    459  1.1  kardel 			return -1;
    460  1.1  kardel 		}
    461  1.3  kardel 		return 0;
    462  1.1  kardel 	}
    463  1.3  kardel 
    464  1.3  kardel 	tp.tv_sec = (long)offset;
    465  1.3  kardel 	tp.tv_usec = 1e6 * (offset - (long)offset);
    466  1.3  kardel 	NORMALIZE_TIMEVAL(tp);
    467  1.3  kardel 
    468  1.3  kardel 	if (ADJTIMEOFDAY(&tp, NULL) < 0) {
    469  1.3  kardel 		msyslog(LOG_ERR, "Time not set: adjtime(): %m");
    470  1.3  kardel 		return -1;
    471  1.1  kardel 	}
    472  1.3  kardel 	return 0;
    473  1.1  kardel }
    474