xref: /freebsd/contrib/ntp/sntp/utilities.c (revision a466cc55373fc3cf86837f09da729535b57e69a1)
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
pkt_output(struct pkt * dpkg,int pkt_length,FILE * output)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 
2609100258SXin 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
l_fp_output(l_fp * ts,FILE * output)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
l_fp_output_bin(l_fp * ts,FILE * output)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
l_fp_output_dec(l_fp * ts,FILE * output)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 *
addrinfo_to_str(const struct addrinfo * addr)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 *
ss_to_str(sockaddr_u * saddr)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 *
tv_to_str(const struct timeval * tv)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;
143*a466cc55SCy Schubert 	struct tm *ptm, tm_local;
144*a466cc55SCy Schubert 	int hh, mm, lto, isdst;
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.
150*a466cc55SCy Schubert 	 * Need to retrieve dst flag from localtime first for mktime.
1512b15cb3dSCy Schubert 	 */
1522b15cb3dSCy Schubert 	gmt_time = tv->tv_sec;
153*a466cc55SCy Schubert 	ptm = localtime(&gmt_time);
154*a466cc55SCy Schubert 	memcpy (&tm_local, ptm, sizeof(tm_local));
155*a466cc55SCy Schubert 	isdst = ptm->tm_isdst;
156*a466cc55SCy Schubert 	ptm = gmtime(&gmt_time);
157*a466cc55SCy Schubert 	ptm->tm_isdst = isdst;
158*a466cc55SCy Schubert 	local_time = mktime(ptm);
1592b15cb3dSCy Schubert 
1602b15cb3dSCy Schubert 	/* Local timezone offsets should never cause an overflow.  Yeah. */
1612b15cb3dSCy Schubert 	lto = difftime(local_time, gmt_time);
1622b15cb3dSCy Schubert 	lto /= 60;
1632b15cb3dSCy Schubert 	hh = lto / 60;
1642b15cb3dSCy Schubert 	mm = abs(lto % 60);
1652b15cb3dSCy Schubert 
1662b15cb3dSCy Schubert 	buf = emalloc(bufsize);
1672b15cb3dSCy Schubert 	snprintf(buf, bufsize,
1682b15cb3dSCy Schubert 		 "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)",
169*a466cc55SCy Schubert 		 tm_local.tm_year + 1900,
170*a466cc55SCy Schubert 		 tm_local.tm_mon + 1,
171*a466cc55SCy Schubert 		 tm_local.tm_mday,
172*a466cc55SCy Schubert 		 tm_local.tm_hour,
173*a466cc55SCy Schubert 		 tm_local.tm_min,
174*a466cc55SCy Schubert 		 tm_local.tm_sec,
1752b15cb3dSCy Schubert 		 (int)tv->tv_usec,
1762b15cb3dSCy Schubert 		 hh,
1772b15cb3dSCy Schubert 		 mm);
1782b15cb3dSCy Schubert 
1792b15cb3dSCy Schubert 	return buf;
1802b15cb3dSCy Schubert }
1812b15cb3dSCy Schubert 
1822b15cb3dSCy Schubert 
1832b15cb3dSCy Schubert /*
1842b15cb3dSCy Schubert  *
1852b15cb3dSCy Schubert  * hostnameaddr()
1862b15cb3dSCy Schubert  *
1872b15cb3dSCy Schubert  * Formats the hostname and resulting numeric IP address into a string,
1882b15cb3dSCy Schubert  * avoiding duplication if the "hostname" was in fact a numeric address.
1892b15cb3dSCy Schubert  *
1902b15cb3dSCy Schubert  */
1912b15cb3dSCy Schubert const char *
hostnameaddr(const char * hostname,const sockaddr_u * addr)1922b15cb3dSCy Schubert hostnameaddr(
1932b15cb3dSCy Schubert 	const char *		hostname,
1942b15cb3dSCy Schubert 	const sockaddr_u *	addr
1952b15cb3dSCy Schubert 	)
1962b15cb3dSCy Schubert {
1972b15cb3dSCy Schubert 	const char *	addrtxt;
1982b15cb3dSCy Schubert 	char *		result;
1992b15cb3dSCy Schubert 	int		cnt;
2002b15cb3dSCy Schubert 
2012b15cb3dSCy Schubert 	addrtxt = stoa(addr);
2022b15cb3dSCy Schubert 	LIB_GETBUF(result);
2032b15cb3dSCy Schubert 	if (strcmp(hostname, addrtxt))
2042b15cb3dSCy Schubert 		cnt = snprintf(result, LIB_BUFLENGTH, "%s %s",
2052b15cb3dSCy Schubert 			       hostname, addrtxt);
2062b15cb3dSCy Schubert 	else
2072b15cb3dSCy Schubert 		cnt = snprintf(result, LIB_BUFLENGTH, "%s", addrtxt);
2082b15cb3dSCy Schubert 	if (cnt >= LIB_BUFLENGTH)
2092b15cb3dSCy Schubert 		snprintf(result, LIB_BUFLENGTH,
2102b15cb3dSCy Schubert 			 "hostnameaddr ERROR have %d (%d needed)",
2112b15cb3dSCy Schubert 			 LIB_BUFLENGTH, cnt + 1);
2122b15cb3dSCy Schubert 
2132b15cb3dSCy Schubert 	return result;
2142b15cb3dSCy Schubert }
215