xref: /freebsd/contrib/ntp/sntp/utilities.c (revision 091002585974d17c9533f943ec351c13a69788ab)
12b15cb3dSCy Schubert #include <config.h>
22b15cb3dSCy Schubert #include "utilities.h"
32b15cb3dSCy Schubert #include <assert.h>
42b15cb3dSCy Schubert 
52b15cb3dSCy Schubert /* Display a NTP packet in hex with leading address offset
62b15cb3dSCy Schubert  * e.g. offset: value, 0: ff 1: fe ... 255: 00
72b15cb3dSCy Schubert  */
82b15cb3dSCy Schubert void
92b15cb3dSCy Schubert pkt_output (
102b15cb3dSCy Schubert 		struct pkt *dpkg,
112b15cb3dSCy Schubert 		int pkt_length,
122b15cb3dSCy Schubert 		FILE *output
132b15cb3dSCy Schubert 	   )
142b15cb3dSCy Schubert {
152b15cb3dSCy Schubert 	register int a;
162b15cb3dSCy Schubert 	u_char *pkt;
172b15cb3dSCy Schubert 
182b15cb3dSCy Schubert 	pkt = (u_char *)dpkg;
192b15cb3dSCy Schubert 
202b15cb3dSCy Schubert 	fprintf(output, HLINE);
212b15cb3dSCy Schubert 
222b15cb3dSCy Schubert 	for (a = 0; a < pkt_length; a++) {
232b15cb3dSCy Schubert 		if (a > 0 && a % 8 == 0)
242b15cb3dSCy Schubert 			fprintf(output, "\n");
252b15cb3dSCy Schubert 
26*09100258SXin LI 		fprintf(output, "%3d: %02x  ", a, pkt[a]);
272b15cb3dSCy Schubert 	}
282b15cb3dSCy Schubert 
292b15cb3dSCy Schubert 	fprintf(output, "\n");
302b15cb3dSCy Schubert 	fprintf(output, HLINE);
312b15cb3dSCy Schubert }
322b15cb3dSCy Schubert 
332b15cb3dSCy Schubert /* Output a long floating point value in hex in the style described above
342b15cb3dSCy Schubert  */
352b15cb3dSCy Schubert void
362b15cb3dSCy Schubert l_fp_output(
372b15cb3dSCy Schubert 	l_fp *	ts,
382b15cb3dSCy Schubert 	FILE *	output
392b15cb3dSCy Schubert 	)
402b15cb3dSCy Schubert {
412b15cb3dSCy Schubert 	fprintf(output, "%s\n", prettydate(ts));
422b15cb3dSCy Schubert }
432b15cb3dSCy Schubert 
442b15cb3dSCy Schubert /* Output a long floating point value in binary in the style described above
452b15cb3dSCy Schubert  */
462b15cb3dSCy Schubert void
472b15cb3dSCy Schubert l_fp_output_bin (
482b15cb3dSCy Schubert 		l_fp *ts,
492b15cb3dSCy Schubert 		FILE *output
502b15cb3dSCy Schubert 		)
512b15cb3dSCy Schubert {
522b15cb3dSCy Schubert 	register int a, b;
532b15cb3dSCy Schubert 
542b15cb3dSCy Schubert 	fprintf(output, HLINE);
552b15cb3dSCy Schubert 
562b15cb3dSCy Schubert 	for(a=0; a<8; a++) {
572b15cb3dSCy Schubert 		short tmp = ((unsigned char *) ts)[a];
582b15cb3dSCy Schubert 		tmp++;
592b15cb3dSCy Schubert 
602b15cb3dSCy Schubert 		fprintf(output, "%i: ", a);
612b15cb3dSCy Schubert 
622b15cb3dSCy Schubert 		for(b=7; b>=0; b--) {
632b15cb3dSCy Schubert 			int texp = (int) pow(2, b);
642b15cb3dSCy Schubert 
652b15cb3dSCy Schubert 			if(tmp - texp > 0) {
662b15cb3dSCy Schubert 				fprintf(output, "1");
672b15cb3dSCy Schubert 				tmp -= texp;
682b15cb3dSCy Schubert 			}
692b15cb3dSCy Schubert 			else {
702b15cb3dSCy Schubert 				fprintf(output, "0");
712b15cb3dSCy Schubert 			}
722b15cb3dSCy Schubert 		}
732b15cb3dSCy Schubert 
742b15cb3dSCy Schubert 		fprintf(output, " ");
752b15cb3dSCy Schubert 	}
762b15cb3dSCy Schubert 
772b15cb3dSCy Schubert 	fprintf(output, "\n");
782b15cb3dSCy Schubert 	fprintf(output, HLINE);
792b15cb3dSCy Schubert }
802b15cb3dSCy Schubert 
812b15cb3dSCy Schubert /* Output a long floating point value in decimal in the style described above
822b15cb3dSCy Schubert  */
832b15cb3dSCy Schubert void
842b15cb3dSCy Schubert l_fp_output_dec (
852b15cb3dSCy Schubert 		l_fp *ts,
862b15cb3dSCy Schubert 		FILE *output
872b15cb3dSCy Schubert 	    )
882b15cb3dSCy Schubert {
892b15cb3dSCy Schubert 	register int a;
902b15cb3dSCy Schubert 
912b15cb3dSCy Schubert 	fprintf(output, HLINE);
922b15cb3dSCy Schubert 
932b15cb3dSCy Schubert 	for(a=0; a<8; a++)
942b15cb3dSCy Schubert 		fprintf(output, "%i: %i \t", a, ((unsigned char *) ts)[a]);
952b15cb3dSCy Schubert 
962b15cb3dSCy Schubert 	fprintf(output, "\n");
972b15cb3dSCy Schubert 	fprintf(output, HLINE);
982b15cb3dSCy Schubert 
992b15cb3dSCy Schubert }
1002b15cb3dSCy Schubert 
1012b15cb3dSCy Schubert /* Convert a struct addrinfo to a string containing the address in style
1022b15cb3dSCy Schubert  * of inet_ntoa
1032b15cb3dSCy Schubert  */
1042b15cb3dSCy Schubert char *
1052b15cb3dSCy Schubert addrinfo_to_str (
1062b15cb3dSCy Schubert 	const struct addrinfo *addr
1072b15cb3dSCy Schubert 	)
1082b15cb3dSCy Schubert {
1092b15cb3dSCy Schubert 	sockaddr_u	s;
1102b15cb3dSCy Schubert 
1112b15cb3dSCy Schubert 	ZERO(s);
1122b15cb3dSCy Schubert 	memcpy(&s, addr->ai_addr, min(sizeof(s), addr->ai_addrlen));
1132b15cb3dSCy Schubert 
1142b15cb3dSCy Schubert 	return ss_to_str(&s);
1152b15cb3dSCy Schubert }
1162b15cb3dSCy Schubert 
1172b15cb3dSCy Schubert 
1182b15cb3dSCy Schubert /* Convert a sockaddr_u to a string containing the address in
1192b15cb3dSCy Schubert  * style of inet_ntoa
1202b15cb3dSCy Schubert  * Why not switch callers to use stoa from libntp?  No free() needed
1212b15cb3dSCy Schubert  * in that case.
1222b15cb3dSCy Schubert  */
1232b15cb3dSCy Schubert char *
1242b15cb3dSCy Schubert ss_to_str(
1252b15cb3dSCy Schubert 	sockaddr_u *saddr
1262b15cb3dSCy Schubert 	)
1272b15cb3dSCy Schubert {
1282b15cb3dSCy Schubert 	return estrdup(stoa(saddr));
1292b15cb3dSCy Schubert }
1302b15cb3dSCy Schubert 
1312b15cb3dSCy Schubert 
1322b15cb3dSCy Schubert /*
1332b15cb3dSCy Schubert  * Converts a struct tv to a date string
1342b15cb3dSCy Schubert  */
1352b15cb3dSCy Schubert char *
1362b15cb3dSCy Schubert tv_to_str(
1372b15cb3dSCy Schubert 	const struct timeval *tv
1382b15cb3dSCy Schubert 	)
1392b15cb3dSCy Schubert {
1402b15cb3dSCy Schubert 	const size_t bufsize = 48;
1412b15cb3dSCy Schubert 	char *buf;
1422b15cb3dSCy Schubert 	time_t gmt_time, local_time;
1432b15cb3dSCy Schubert 	struct tm *p_tm_local;
1442b15cb3dSCy Schubert 	int hh, mm, lto;
1452b15cb3dSCy Schubert 
1462b15cb3dSCy Schubert 	/*
1472b15cb3dSCy Schubert 	 * convert to struct tm in UTC, then intentionally feed
1482b15cb3dSCy Schubert 	 * that tm to mktime() which expects local time input, to
1492b15cb3dSCy Schubert 	 * derive the offset from UTC to local time.
1502b15cb3dSCy Schubert 	 */
1512b15cb3dSCy Schubert 	gmt_time = tv->tv_sec;
1522b15cb3dSCy Schubert 	local_time = mktime(gmtime(&gmt_time));
1532b15cb3dSCy Schubert 	p_tm_local = localtime(&gmt_time);
1542b15cb3dSCy Schubert 
1552b15cb3dSCy Schubert 	/* Local timezone offsets should never cause an overflow.  Yeah. */
1562b15cb3dSCy Schubert 	lto = difftime(local_time, gmt_time);
1572b15cb3dSCy Schubert 	lto /= 60;
1582b15cb3dSCy Schubert 	hh = lto / 60;
1592b15cb3dSCy Schubert 	mm = abs(lto % 60);
1602b15cb3dSCy Schubert 
1612b15cb3dSCy Schubert 	buf = emalloc(bufsize);
1622b15cb3dSCy Schubert 	snprintf(buf, bufsize,
1632b15cb3dSCy Schubert 		 "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)",
1642b15cb3dSCy Schubert 		 p_tm_local->tm_year + 1900,
1652b15cb3dSCy Schubert 		 p_tm_local->tm_mon + 1,
1662b15cb3dSCy Schubert 		 p_tm_local->tm_mday,
1672b15cb3dSCy Schubert 		 p_tm_local->tm_hour,
1682b15cb3dSCy Schubert 		 p_tm_local->tm_min,
1692b15cb3dSCy Schubert 		 p_tm_local->tm_sec,
1702b15cb3dSCy Schubert 		 (int)tv->tv_usec,
1712b15cb3dSCy Schubert 		 hh,
1722b15cb3dSCy Schubert 		 mm);
1732b15cb3dSCy Schubert 
1742b15cb3dSCy Schubert 	return buf;
1752b15cb3dSCy Schubert }
1762b15cb3dSCy Schubert 
1772b15cb3dSCy Schubert 
1782b15cb3dSCy Schubert /*
1792b15cb3dSCy Schubert  *
1802b15cb3dSCy Schubert  * hostnameaddr()
1812b15cb3dSCy Schubert  *
1822b15cb3dSCy Schubert  * Formats the hostname and resulting numeric IP address into a string,
1832b15cb3dSCy Schubert  * avoiding duplication if the "hostname" was in fact a numeric address.
1842b15cb3dSCy Schubert  *
1852b15cb3dSCy Schubert  */
1862b15cb3dSCy Schubert const char *
1872b15cb3dSCy Schubert hostnameaddr(
1882b15cb3dSCy Schubert 	const char *		hostname,
1892b15cb3dSCy Schubert 	const sockaddr_u *	addr
1902b15cb3dSCy Schubert 	)
1912b15cb3dSCy Schubert {
1922b15cb3dSCy Schubert 	const char *	addrtxt;
1932b15cb3dSCy Schubert 	char *		result;
1942b15cb3dSCy Schubert 	int		cnt;
1952b15cb3dSCy Schubert 
1962b15cb3dSCy Schubert 	addrtxt = stoa(addr);
1972b15cb3dSCy Schubert 	LIB_GETBUF(result);
1982b15cb3dSCy Schubert 	if (strcmp(hostname, addrtxt))
1992b15cb3dSCy Schubert 		cnt = snprintf(result, LIB_BUFLENGTH, "%s %s",
2002b15cb3dSCy Schubert 			       hostname, addrtxt);
2012b15cb3dSCy Schubert 	else
2022b15cb3dSCy Schubert 		cnt = snprintf(result, LIB_BUFLENGTH, "%s", addrtxt);
2032b15cb3dSCy Schubert 	if (cnt >= LIB_BUFLENGTH)
2042b15cb3dSCy Schubert 		snprintf(result, LIB_BUFLENGTH,
2052b15cb3dSCy Schubert 			 "hostnameaddr ERROR have %d (%d needed)",
2062b15cb3dSCy Schubert 			 LIB_BUFLENGTH, cnt + 1);
2072b15cb3dSCy Schubert 
2082b15cb3dSCy Schubert 	return result;
2092b15cb3dSCy Schubert }
210