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 */
8void
9pkt_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, "%d: %x \t", 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 */
35void
36l_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 */
46void
47l_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 */
83void
84l_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 */
104char *
105addrinfo_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 */
123char *
124ss_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 */
135char *
136tv_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 *p_tm_local;
144	int hh, mm, lto;
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	 */
151	gmt_time = tv->tv_sec;
152	local_time = mktime(gmtime(&gmt_time));
153	p_tm_local = localtime(&gmt_time);
154
155	/* Local timezone offsets should never cause an overflow.  Yeah. */
156	lto = difftime(local_time, gmt_time);
157	lto /= 60;
158	hh = lto / 60;
159	mm = abs(lto % 60);
160
161	buf = emalloc(bufsize);
162	snprintf(buf, bufsize,
163		 "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)",
164		 p_tm_local->tm_year + 1900,
165		 p_tm_local->tm_mon + 1,
166		 p_tm_local->tm_mday,
167		 p_tm_local->tm_hour,
168		 p_tm_local->tm_min,
169		 p_tm_local->tm_sec,
170		 (int)tv->tv_usec,
171		 hh,
172		 mm);
173
174	return buf;
175}
176
177
178/*
179 *
180 * hostnameaddr()
181 *
182 * Formats the hostname and resulting numeric IP address into a string,
183 * avoiding duplication if the "hostname" was in fact a numeric address.
184 *
185 */
186const char *
187hostnameaddr(
188	const char *		hostname,
189	const sockaddr_u *	addr
190	)
191{
192	const char *	addrtxt;
193	char *		result;
194	int		cnt;
195
196	addrtxt = stoa(addr);
197	LIB_GETBUF(result);
198	if (strcmp(hostname, addrtxt))
199		cnt = snprintf(result, LIB_BUFLENGTH, "%s %s",
200			       hostname, addrtxt);
201	else
202		cnt = snprintf(result, LIB_BUFLENGTH, "%s", addrtxt);
203	if (cnt >= LIB_BUFLENGTH)
204		snprintf(result, LIB_BUFLENGTH,
205			 "hostnameaddr ERROR have %d (%d needed)",
206			 LIB_BUFLENGTH, cnt + 1);
207
208	return result;
209}
210