xref: /freebsd/contrib/ntp/sntp/utilities.c (revision 2b15cb3d0922bd70ea592f0da9b4a5b167f4d53f)
1*2b15cb3dSCy Schubert #include <config.h>
2*2b15cb3dSCy Schubert #include "utilities.h"
3*2b15cb3dSCy Schubert #include <assert.h>
4*2b15cb3dSCy Schubert 
5*2b15cb3dSCy Schubert /* Display a NTP packet in hex with leading address offset
6*2b15cb3dSCy Schubert  * e.g. offset: value, 0: ff 1: fe ... 255: 00
7*2b15cb3dSCy Schubert  */
8*2b15cb3dSCy Schubert void
9*2b15cb3dSCy Schubert pkt_output (
10*2b15cb3dSCy Schubert 		struct pkt *dpkg,
11*2b15cb3dSCy Schubert 		int pkt_length,
12*2b15cb3dSCy Schubert 		FILE *output
13*2b15cb3dSCy Schubert 	   )
14*2b15cb3dSCy Schubert {
15*2b15cb3dSCy Schubert 	register int a;
16*2b15cb3dSCy Schubert 	u_char *pkt;
17*2b15cb3dSCy Schubert 
18*2b15cb3dSCy Schubert 	pkt = (u_char *)dpkg;
19*2b15cb3dSCy Schubert 
20*2b15cb3dSCy Schubert 	fprintf(output, HLINE);
21*2b15cb3dSCy Schubert 
22*2b15cb3dSCy Schubert 	for (a = 0; a < pkt_length; a++) {
23*2b15cb3dSCy Schubert 		if (a > 0 && a % 8 == 0)
24*2b15cb3dSCy Schubert 			fprintf(output, "\n");
25*2b15cb3dSCy Schubert 
26*2b15cb3dSCy Schubert 		fprintf(output, "%d: %x \t", a, pkt[a]);
27*2b15cb3dSCy Schubert 	}
28*2b15cb3dSCy Schubert 
29*2b15cb3dSCy Schubert 	fprintf(output, "\n");
30*2b15cb3dSCy Schubert 	fprintf(output, HLINE);
31*2b15cb3dSCy Schubert }
32*2b15cb3dSCy Schubert 
33*2b15cb3dSCy Schubert /* Output a long floating point value in hex in the style described above
34*2b15cb3dSCy Schubert  */
35*2b15cb3dSCy Schubert void
36*2b15cb3dSCy Schubert l_fp_output(
37*2b15cb3dSCy Schubert 	l_fp *	ts,
38*2b15cb3dSCy Schubert 	FILE *	output
39*2b15cb3dSCy Schubert 	)
40*2b15cb3dSCy Schubert {
41*2b15cb3dSCy Schubert 	fprintf(output, "%s\n", prettydate(ts));
42*2b15cb3dSCy Schubert }
43*2b15cb3dSCy Schubert 
44*2b15cb3dSCy Schubert /* Output a long floating point value in binary in the style described above
45*2b15cb3dSCy Schubert  */
46*2b15cb3dSCy Schubert void
47*2b15cb3dSCy Schubert l_fp_output_bin (
48*2b15cb3dSCy Schubert 		l_fp *ts,
49*2b15cb3dSCy Schubert 		FILE *output
50*2b15cb3dSCy Schubert 		)
51*2b15cb3dSCy Schubert {
52*2b15cb3dSCy Schubert 	register int a, b;
53*2b15cb3dSCy Schubert 
54*2b15cb3dSCy Schubert 	fprintf(output, HLINE);
55*2b15cb3dSCy Schubert 
56*2b15cb3dSCy Schubert 	for(a=0; a<8; a++) {
57*2b15cb3dSCy Schubert 		short tmp = ((unsigned char *) ts)[a];
58*2b15cb3dSCy Schubert 		tmp++;
59*2b15cb3dSCy Schubert 
60*2b15cb3dSCy Schubert 		fprintf(output, "%i: ", a);
61*2b15cb3dSCy Schubert 
62*2b15cb3dSCy Schubert 		for(b=7; b>=0; b--) {
63*2b15cb3dSCy Schubert 			int texp = (int) pow(2, b);
64*2b15cb3dSCy Schubert 
65*2b15cb3dSCy Schubert 			if(tmp - texp > 0) {
66*2b15cb3dSCy Schubert 				fprintf(output, "1");
67*2b15cb3dSCy Schubert 				tmp -= texp;
68*2b15cb3dSCy Schubert 			}
69*2b15cb3dSCy Schubert 			else {
70*2b15cb3dSCy Schubert 				fprintf(output, "0");
71*2b15cb3dSCy Schubert 			}
72*2b15cb3dSCy Schubert 		}
73*2b15cb3dSCy Schubert 
74*2b15cb3dSCy Schubert 		fprintf(output, " ");
75*2b15cb3dSCy Schubert 	}
76*2b15cb3dSCy Schubert 
77*2b15cb3dSCy Schubert 	fprintf(output, "\n");
78*2b15cb3dSCy Schubert 	fprintf(output, HLINE);
79*2b15cb3dSCy Schubert }
80*2b15cb3dSCy Schubert 
81*2b15cb3dSCy Schubert /* Output a long floating point value in decimal in the style described above
82*2b15cb3dSCy Schubert  */
83*2b15cb3dSCy Schubert void
84*2b15cb3dSCy Schubert l_fp_output_dec (
85*2b15cb3dSCy Schubert 		l_fp *ts,
86*2b15cb3dSCy Schubert 		FILE *output
87*2b15cb3dSCy Schubert 	    )
88*2b15cb3dSCy Schubert {
89*2b15cb3dSCy Schubert 	register int a;
90*2b15cb3dSCy Schubert 
91*2b15cb3dSCy Schubert 	fprintf(output, HLINE);
92*2b15cb3dSCy Schubert 
93*2b15cb3dSCy Schubert 	for(a=0; a<8; a++)
94*2b15cb3dSCy Schubert 		fprintf(output, "%i: %i \t", a, ((unsigned char *) ts)[a]);
95*2b15cb3dSCy Schubert 
96*2b15cb3dSCy Schubert 	fprintf(output, "\n");
97*2b15cb3dSCy Schubert 	fprintf(output, HLINE);
98*2b15cb3dSCy Schubert 
99*2b15cb3dSCy Schubert }
100*2b15cb3dSCy Schubert 
101*2b15cb3dSCy Schubert /* Convert a struct addrinfo to a string containing the address in style
102*2b15cb3dSCy Schubert  * of inet_ntoa
103*2b15cb3dSCy Schubert  */
104*2b15cb3dSCy Schubert char *
105*2b15cb3dSCy Schubert addrinfo_to_str (
106*2b15cb3dSCy Schubert 	const struct addrinfo *addr
107*2b15cb3dSCy Schubert 	)
108*2b15cb3dSCy Schubert {
109*2b15cb3dSCy Schubert 	sockaddr_u	s;
110*2b15cb3dSCy Schubert 
111*2b15cb3dSCy Schubert 	ZERO(s);
112*2b15cb3dSCy Schubert 	memcpy(&s, addr->ai_addr, min(sizeof(s), addr->ai_addrlen));
113*2b15cb3dSCy Schubert 
114*2b15cb3dSCy Schubert 	return ss_to_str(&s);
115*2b15cb3dSCy Schubert }
116*2b15cb3dSCy Schubert 
117*2b15cb3dSCy Schubert 
118*2b15cb3dSCy Schubert /* Convert a sockaddr_u to a string containing the address in
119*2b15cb3dSCy Schubert  * style of inet_ntoa
120*2b15cb3dSCy Schubert  * Why not switch callers to use stoa from libntp?  No free() needed
121*2b15cb3dSCy Schubert  * in that case.
122*2b15cb3dSCy Schubert  */
123*2b15cb3dSCy Schubert char *
124*2b15cb3dSCy Schubert ss_to_str(
125*2b15cb3dSCy Schubert 	sockaddr_u *saddr
126*2b15cb3dSCy Schubert 	)
127*2b15cb3dSCy Schubert {
128*2b15cb3dSCy Schubert 	return estrdup(stoa(saddr));
129*2b15cb3dSCy Schubert }
130*2b15cb3dSCy Schubert 
131*2b15cb3dSCy Schubert 
132*2b15cb3dSCy Schubert /*
133*2b15cb3dSCy Schubert  * Converts a struct tv to a date string
134*2b15cb3dSCy Schubert  */
135*2b15cb3dSCy Schubert char *
136*2b15cb3dSCy Schubert tv_to_str(
137*2b15cb3dSCy Schubert 	const struct timeval *tv
138*2b15cb3dSCy Schubert 	)
139*2b15cb3dSCy Schubert {
140*2b15cb3dSCy Schubert 	const size_t bufsize = 48;
141*2b15cb3dSCy Schubert 	char *buf;
142*2b15cb3dSCy Schubert 	time_t gmt_time, local_time;
143*2b15cb3dSCy Schubert 	struct tm *p_tm_local;
144*2b15cb3dSCy Schubert 	int hh, mm, lto;
145*2b15cb3dSCy Schubert 
146*2b15cb3dSCy Schubert 	/*
147*2b15cb3dSCy Schubert 	 * convert to struct tm in UTC, then intentionally feed
148*2b15cb3dSCy Schubert 	 * that tm to mktime() which expects local time input, to
149*2b15cb3dSCy Schubert 	 * derive the offset from UTC to local time.
150*2b15cb3dSCy Schubert 	 */
151*2b15cb3dSCy Schubert 	gmt_time = tv->tv_sec;
152*2b15cb3dSCy Schubert 	local_time = mktime(gmtime(&gmt_time));
153*2b15cb3dSCy Schubert 	p_tm_local = localtime(&gmt_time);
154*2b15cb3dSCy Schubert 
155*2b15cb3dSCy Schubert 	/* Local timezone offsets should never cause an overflow.  Yeah. */
156*2b15cb3dSCy Schubert 	lto = difftime(local_time, gmt_time);
157*2b15cb3dSCy Schubert 	lto /= 60;
158*2b15cb3dSCy Schubert 	hh = lto / 60;
159*2b15cb3dSCy Schubert 	mm = abs(lto % 60);
160*2b15cb3dSCy Schubert 
161*2b15cb3dSCy Schubert 	buf = emalloc(bufsize);
162*2b15cb3dSCy Schubert 	snprintf(buf, bufsize,
163*2b15cb3dSCy Schubert 		 "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)",
164*2b15cb3dSCy Schubert 		 p_tm_local->tm_year + 1900,
165*2b15cb3dSCy Schubert 		 p_tm_local->tm_mon + 1,
166*2b15cb3dSCy Schubert 		 p_tm_local->tm_mday,
167*2b15cb3dSCy Schubert 		 p_tm_local->tm_hour,
168*2b15cb3dSCy Schubert 		 p_tm_local->tm_min,
169*2b15cb3dSCy Schubert 		 p_tm_local->tm_sec,
170*2b15cb3dSCy Schubert 		 (int)tv->tv_usec,
171*2b15cb3dSCy Schubert 		 hh,
172*2b15cb3dSCy Schubert 		 mm);
173*2b15cb3dSCy Schubert 
174*2b15cb3dSCy Schubert 	return buf;
175*2b15cb3dSCy Schubert }
176*2b15cb3dSCy Schubert 
177*2b15cb3dSCy Schubert 
178*2b15cb3dSCy Schubert /*
179*2b15cb3dSCy Schubert  *
180*2b15cb3dSCy Schubert  * hostnameaddr()
181*2b15cb3dSCy Schubert  *
182*2b15cb3dSCy Schubert  * Formats the hostname and resulting numeric IP address into a string,
183*2b15cb3dSCy Schubert  * avoiding duplication if the "hostname" was in fact a numeric address.
184*2b15cb3dSCy Schubert  *
185*2b15cb3dSCy Schubert  */
186*2b15cb3dSCy Schubert const char *
187*2b15cb3dSCy Schubert hostnameaddr(
188*2b15cb3dSCy Schubert 	const char *		hostname,
189*2b15cb3dSCy Schubert 	const sockaddr_u *	addr
190*2b15cb3dSCy Schubert 	)
191*2b15cb3dSCy Schubert {
192*2b15cb3dSCy Schubert 	const char *	addrtxt;
193*2b15cb3dSCy Schubert 	char *		result;
194*2b15cb3dSCy Schubert 	int		cnt;
195*2b15cb3dSCy Schubert 
196*2b15cb3dSCy Schubert 	addrtxt = stoa(addr);
197*2b15cb3dSCy Schubert 	LIB_GETBUF(result);
198*2b15cb3dSCy Schubert 	if (strcmp(hostname, addrtxt))
199*2b15cb3dSCy Schubert 		cnt = snprintf(result, LIB_BUFLENGTH, "%s %s",
200*2b15cb3dSCy Schubert 			       hostname, addrtxt);
201*2b15cb3dSCy Schubert 	else
202*2b15cb3dSCy Schubert 		cnt = snprintf(result, LIB_BUFLENGTH, "%s", addrtxt);
203*2b15cb3dSCy Schubert 	if (cnt >= LIB_BUFLENGTH)
204*2b15cb3dSCy Schubert 		snprintf(result, LIB_BUFLENGTH,
205*2b15cb3dSCy Schubert 			 "hostnameaddr ERROR have %d (%d needed)",
206*2b15cb3dSCy Schubert 			 LIB_BUFLENGTH, cnt + 1);
207*2b15cb3dSCy Schubert 
208*2b15cb3dSCy Schubert 	return result;
209*2b15cb3dSCy Schubert }
210