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