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