1258945Sroberto#include <config.h>
2258945Sroberto#include "utilities.h"
3258945Sroberto#include <assert.h>
4258945Sroberto
5258945Sroberto/* Display a NTP packet in hex with leading address offset
6258945Sroberto * e.g. offset: value, 0: ff 1: fe ... 255: 00
7258945Sroberto */
8258945Srobertovoid
9258945Srobertopkt_output (
10258945Sroberto		struct pkt *dpkg,
11258945Sroberto		int pkt_length,
12258945Sroberto		FILE *output
13258945Sroberto	   )
14258945Sroberto{
15258945Sroberto	register int a;
16258945Sroberto	u_char *pkt;
17258945Sroberto
18258945Sroberto	pkt = (u_char *)dpkg;
19258945Sroberto
20258945Sroberto	fprintf(output, HLINE);
21258945Sroberto
22258945Sroberto	for (a = 0; a < pkt_length; a++) {
23258945Sroberto		if (a > 0 && a % 8 == 0)
24258945Sroberto			fprintf(output, "\n");
25258945Sroberto
26330106Sdelphij		fprintf(output, "%3d: %02x  ", a, pkt[a]);
27258945Sroberto	}
28258945Sroberto
29258945Sroberto	fprintf(output, "\n");
30258945Sroberto	fprintf(output, HLINE);
31258945Sroberto}
32258945Sroberto
33258945Sroberto/* Output a long floating point value in hex in the style described above
34258945Sroberto */
35258945Srobertovoid
36280849Scyl_fp_output(
37280849Scy	l_fp *	ts,
38280849Scy	FILE *	output
39280849Scy	)
40258945Sroberto{
41280849Scy	fprintf(output, "%s\n", prettydate(ts));
42258945Sroberto}
43258945Sroberto
44258945Sroberto/* Output a long floating point value in binary in the style described above
45258945Sroberto */
46258945Srobertovoid
47258945Srobertol_fp_output_bin (
48258945Sroberto		l_fp *ts,
49258945Sroberto		FILE *output
50258945Sroberto		)
51258945Sroberto{
52258945Sroberto	register int a, b;
53258945Sroberto
54258945Sroberto	fprintf(output, HLINE);
55258945Sroberto
56258945Sroberto	for(a=0; a<8; a++) {
57258945Sroberto		short tmp = ((unsigned char *) ts)[a];
58258945Sroberto		tmp++;
59258945Sroberto
60258945Sroberto		fprintf(output, "%i: ", a);
61258945Sroberto
62258945Sroberto		for(b=7; b>=0; b--) {
63258945Sroberto			int texp = (int) pow(2, b);
64258945Sroberto
65258945Sroberto			if(tmp - texp > 0) {
66258945Sroberto				fprintf(output, "1");
67258945Sroberto				tmp -= texp;
68258945Sroberto			}
69258945Sroberto			else {
70258945Sroberto				fprintf(output, "0");
71258945Sroberto			}
72258945Sroberto		}
73258945Sroberto
74258945Sroberto		fprintf(output, " ");
75258945Sroberto	}
76258945Sroberto
77258945Sroberto	fprintf(output, "\n");
78258945Sroberto	fprintf(output, HLINE);
79258945Sroberto}
80258945Sroberto
81258945Sroberto/* Output a long floating point value in decimal in the style described above
82258945Sroberto */
83258945Srobertovoid
84258945Srobertol_fp_output_dec (
85258945Sroberto		l_fp *ts,
86258945Sroberto		FILE *output
87258945Sroberto	    )
88258945Sroberto{
89258945Sroberto	register int a;
90258945Sroberto
91258945Sroberto	fprintf(output, HLINE);
92258945Sroberto
93258945Sroberto	for(a=0; a<8; a++)
94258945Sroberto		fprintf(output, "%i: %i \t", a, ((unsigned char *) ts)[a]);
95258945Sroberto
96258945Sroberto	fprintf(output, "\n");
97258945Sroberto	fprintf(output, HLINE);
98258945Sroberto
99258945Sroberto}
100258945Sroberto
101258945Sroberto/* Convert a struct addrinfo to a string containing the address in style
102258945Sroberto * of inet_ntoa
103258945Sroberto */
104258945Srobertochar *
105258945Srobertoaddrinfo_to_str (
106280849Scy	const struct addrinfo *addr
107258945Sroberto	)
108258945Sroberto{
109258945Sroberto	sockaddr_u	s;
110258945Sroberto
111280849Scy	ZERO(s);
112258945Sroberto	memcpy(&s, addr->ai_addr, min(sizeof(s), addr->ai_addrlen));
113258945Sroberto
114258945Sroberto	return ss_to_str(&s);
115258945Sroberto}
116258945Sroberto
117280849Scy
118258945Sroberto/* Convert a sockaddr_u to a string containing the address in
119258945Sroberto * style of inet_ntoa
120258945Sroberto * Why not switch callers to use stoa from libntp?  No free() needed
121258945Sroberto * in that case.
122258945Sroberto */
123258945Srobertochar *
124280849Scyss_to_str(
125258945Sroberto	sockaddr_u *saddr
126258945Sroberto	)
127258945Sroberto{
128280849Scy	return estrdup(stoa(saddr));
129280849Scy}
130258945Sroberto
131280849Scy
132258945Sroberto/*
133258945Sroberto * Converts a struct tv to a date string
134258945Sroberto */
135258945Srobertochar *
136258945Srobertotv_to_str(
137258945Sroberto	const struct timeval *tv
138258945Sroberto	)
139258945Sroberto{
140258945Sroberto	const size_t bufsize = 48;
141258945Sroberto	char *buf;
142258945Sroberto	time_t gmt_time, local_time;
143258945Sroberto	struct tm *p_tm_local;
144258945Sroberto	int hh, mm, lto;
145258945Sroberto
146258945Sroberto	/*
147258945Sroberto	 * convert to struct tm in UTC, then intentionally feed
148258945Sroberto	 * that tm to mktime() which expects local time input, to
149258945Sroberto	 * derive the offset from UTC to local time.
150258945Sroberto	 */
151258945Sroberto	gmt_time = tv->tv_sec;
152258945Sroberto	local_time = mktime(gmtime(&gmt_time));
153258945Sroberto	p_tm_local = localtime(&gmt_time);
154258945Sroberto
155258945Sroberto	/* Local timezone offsets should never cause an overflow.  Yeah. */
156258945Sroberto	lto = difftime(local_time, gmt_time);
157258945Sroberto	lto /= 60;
158258945Sroberto	hh = lto / 60;
159258945Sroberto	mm = abs(lto % 60);
160258945Sroberto
161258945Sroberto	buf = emalloc(bufsize);
162258945Sroberto	snprintf(buf, bufsize,
163258945Sroberto		 "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)",
164258945Sroberto		 p_tm_local->tm_year + 1900,
165258945Sroberto		 p_tm_local->tm_mon + 1,
166258945Sroberto		 p_tm_local->tm_mday,
167258945Sroberto		 p_tm_local->tm_hour,
168258945Sroberto		 p_tm_local->tm_min,
169258945Sroberto		 p_tm_local->tm_sec,
170258945Sroberto		 (int)tv->tv_usec,
171258945Sroberto		 hh,
172258945Sroberto		 mm);
173258945Sroberto
174258945Sroberto	return buf;
175258945Sroberto}
176258945Sroberto
177258945Sroberto
178280849Scy/*
179280849Scy *
180280849Scy * hostnameaddr()
181280849Scy *
182280849Scy * Formats the hostname and resulting numeric IP address into a string,
183280849Scy * avoiding duplication if the "hostname" was in fact a numeric address.
184280849Scy *
185280849Scy */
186280849Scyconst char *
187280849Scyhostnameaddr(
188280849Scy	const char *		hostname,
189280849Scy	const sockaddr_u *	addr
190280849Scy	)
191280849Scy{
192280849Scy	const char *	addrtxt;
193280849Scy	char *		result;
194280849Scy	int		cnt;
195258945Sroberto
196280849Scy	addrtxt = stoa(addr);
197280849Scy	LIB_GETBUF(result);
198280849Scy	if (strcmp(hostname, addrtxt))
199280849Scy		cnt = snprintf(result, LIB_BUFLENGTH, "%s %s",
200280849Scy			       hostname, addrtxt);
201280849Scy	else
202280849Scy		cnt = snprintf(result, LIB_BUFLENGTH, "%s", addrtxt);
203280849Scy	if (cnt >= LIB_BUFLENGTH)
204280849Scy		snprintf(result, LIB_BUFLENGTH,
205280849Scy			 "hostnameaddr ERROR have %d (%d needed)",
206280849Scy			 LIB_BUFLENGTH, cnt + 1);
207280849Scy
208280849Scy	return result;
209280849Scy}
210