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