1132718Skan#include <config.h>
2169689Skan#include "utilities.h"
3132718Skan#include <assert.h>
4132718Skan
5132718Skan/* Display a NTP packet in hex with leading address offset
6132718Skan * e.g. offset: value, 0: ff 1: fe ... 255: 00
7132718Skan */
8132718Skanvoid
9132718Skanpkt_output (
10132718Skan		struct pkt *dpkg,
11132718Skan		int pkt_length,
12132718Skan		FILE *output
13132718Skan	   )
14132718Skan{
15132718Skan	register int a;
16132718Skan	u_char *pkt;
17132718Skan
18132718Skan	pkt = (u_char *)dpkg;
19169689Skan
20169689Skan	fprintf(output, HLINE);
21132718Skan
22132718Skan	for (a = 0; a < pkt_length; a++) {
23132718Skan		if (a > 0 && a % 8 == 0)
24132718Skan			fprintf(output, "\n");
25132718Skan
26132718Skan		fprintf(output, "%3d: %02x  ", a, pkt[a]);
27132718Skan	}
28132718Skan
29132718Skan	fprintf(output, "\n");
30132718Skan	fprintf(output, HLINE);
31132718Skan}
32132718Skan
33132718Skan/* Output a long floating point value in hex in the style described above
34132718Skan */
35132718Skanvoid
36132718Skanl_fp_output(
37132718Skan	l_fp *	ts,
38132718Skan	FILE *	output
39132718Skan	)
40132718Skan{
41132718Skan	fprintf(output, "%s\n", prettydate(ts));
42132718Skan}
43169689Skan
44169689Skan/* Output a long floating point value in binary in the style described above
45169689Skan */
46169689Skanvoid
47169689Skanl_fp_output_bin (
48132718Skan		l_fp *ts,
49132718Skan		FILE *output
50132718Skan		)
51132718Skan{
52132718Skan	register int a, b;
53132718Skan
54132718Skan	fprintf(output, HLINE);
55132718Skan
56132718Skan	for(a=0; a<8; a++) {
57132718Skan		short tmp = ((unsigned char *) ts)[a];
58132718Skan		tmp++;
59132718Skan
60132718Skan		fprintf(output, "%i: ", a);
61132718Skan
62132718Skan		for(b=7; b>=0; b--) {
63132718Skan			int texp = (int) pow(2, b);
64132718Skan
65132718Skan			if(tmp - texp > 0) {
66132718Skan				fprintf(output, "1");
67132718Skan				tmp -= texp;
68132718Skan			}
69132718Skan			else {
70132718Skan				fprintf(output, "0");
71132718Skan			}
72132718Skan		}
73132718Skan
74132718Skan		fprintf(output, " ");
75132718Skan	}
76132718Skan
77132718Skan	fprintf(output, "\n");
78132718Skan	fprintf(output, HLINE);
79261188Spfg}
80261188Spfg
81132718Skan/* Output a long floating point value in decimal in the style described above
82132718Skan */
83169689Skanvoid
84169689Skanl_fp_output_dec (
85169689Skan		l_fp *ts,
86169689Skan		FILE *output
87169689Skan	    )
88169689Skan{
89169689Skan	register int a;
90169689Skan
91169689Skan	fprintf(output, HLINE);
92169689Skan
93169689Skan	for(a=0; a<8; a++)
94169689Skan		fprintf(output, "%i: %i \t", a, ((unsigned char *) ts)[a]);
95169689Skan
96169689Skan	fprintf(output, "\n");
97132718Skan	fprintf(output, HLINE);
98132718Skan
99132718Skan}
100132718Skan
101132718Skan/* Convert a struct addrinfo to a string containing the address in style
102132718Skan * of inet_ntoa
103132718Skan */
104132718Skanchar *
105132718Skanaddrinfo_to_str (
106132718Skan	const struct addrinfo *addr
107132718Skan	)
108132718Skan{
109132718Skan	sockaddr_u	s;
110169689Skan
111169689Skan	ZERO(s);
112169689Skan	memcpy(&s, addr->ai_addr, min(sizeof(s), addr->ai_addrlen));
113132718Skan
114169689Skan	return ss_to_str(&s);
115169689Skan}
116132718Skan
117132718Skan
118169689Skan/* Convert a sockaddr_u to a string containing the address in
119169689Skan * style of inet_ntoa
120132718Skan * Why not switch callers to use stoa from libntp?  No free() needed
121132718Skan * in that case.
122169689Skan */
123132718Skanchar *
124132718Skanss_to_str(
125132718Skan	sockaddr_u *saddr
126169689Skan	)
127132718Skan{
128132718Skan	return estrdup(stoa(saddr));
129169689Skan}
130169689Skan
131169689Skan
132169689Skan/*
133169689Skan * Converts a struct tv to a date string
134169689Skan */
135169689Skanchar *
136169689Skantv_to_str(
137169689Skan	const struct timeval *tv
138169689Skan	)
139169689Skan{
140169689Skan	const size_t bufsize = 48;
141169689Skan	char *buf;
142169689Skan	time_t gmt_time, local_time;
143169689Skan	struct tm *p_tm_local;
144169689Skan	int hh, mm, lto;
145169689Skan
146169689Skan	/*
147275699Sdim	 * convert to struct tm in UTC, then intentionally feed
148169689Skan	 * that tm to mktime() which expects local time input, to
149169689Skan	 * derive the offset from UTC to local time.
150169689Skan	 */
151169689Skan	gmt_time = tv->tv_sec;
152169689Skan	local_time = mktime(gmtime(&gmt_time));
153169689Skan	p_tm_local = localtime(&gmt_time);
154169689Skan
155132718Skan	/* Local timezone offsets should never cause an overflow.  Yeah. */
156132718Skan	lto = difftime(local_time, gmt_time);
157132718Skan	lto /= 60;
158132718Skan	hh = lto / 60;
159132718Skan	mm = abs(lto % 60);
160132718Skan
161132718Skan	buf = emalloc(bufsize);
162132718Skan	snprintf(buf, bufsize,
163132718Skan		 "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)",
164132718Skan		 p_tm_local->tm_year + 1900,
165132718Skan		 p_tm_local->tm_mon + 1,
166132718Skan		 p_tm_local->tm_mday,
167132718Skan		 p_tm_local->tm_hour,
168132718Skan		 p_tm_local->tm_min,
169132718Skan		 p_tm_local->tm_sec,
170132718Skan		 (int)tv->tv_usec,
171132718Skan		 hh,
172132718Skan		 mm);
173132718Skan
174132718Skan	return buf;
175132718Skan}
176132718Skan
177132718Skan
178132718Skan/*
179132718Skan *
180132718Skan * hostnameaddr()
181132718Skan *
182132718Skan * Formats the hostname and resulting numeric IP address into a string,
183132718Skan * avoiding duplication if the "hostname" was in fact a numeric address.
184132718Skan *
185132718Skan */
186132718Skanconst char *
187132718Skanhostnameaddr(
188132718Skan	const char *		hostname,
189132718Skan	const sockaddr_u *	addr
190132718Skan	)
191132718Skan{
192132718Skan	const char *	addrtxt;
193132718Skan	char *		result;
194169689Skan	int		cnt;
195132718Skan
196132718Skan	addrtxt = stoa(addr);
197169689Skan	LIB_GETBUF(result);
198132718Skan	if (strcmp(hostname, addrtxt))
199132718Skan		cnt = snprintf(result, LIB_BUFLENGTH, "%s %s",
200132718Skan			       hostname, addrtxt);
201132718Skan	else
202132718Skan		cnt = snprintf(result, LIB_BUFLENGTH, "%s", addrtxt);
203132718Skan	if (cnt >= LIB_BUFLENGTH)
204132718Skan		snprintf(result, LIB_BUFLENGTH,
205132718Skan			 "hostnameaddr ERROR have %d (%d needed)",
206169689Skan			 LIB_BUFLENGTH, cnt + 1);
207169689Skan
208169689Skan	return result;
209132718Skan}
210132718Skan