12b15cb3dSCy Schubert #include <config.h>
22b15cb3dSCy Schubert #include "utilities.h"
32b15cb3dSCy Schubert #include <assert.h>
42b15cb3dSCy Schubert
52b15cb3dSCy Schubert /* Display a NTP packet in hex with leading address offset
62b15cb3dSCy Schubert * e.g. offset: value, 0: ff 1: fe ... 255: 00
72b15cb3dSCy Schubert */
82b15cb3dSCy Schubert void
pkt_output(struct pkt * dpkg,int pkt_length,FILE * output)92b15cb3dSCy Schubert pkt_output (
102b15cb3dSCy Schubert struct pkt *dpkg,
112b15cb3dSCy Schubert int pkt_length,
122b15cb3dSCy Schubert FILE *output
132b15cb3dSCy Schubert )
142b15cb3dSCy Schubert {
152b15cb3dSCy Schubert register int a;
162b15cb3dSCy Schubert u_char *pkt;
172b15cb3dSCy Schubert
182b15cb3dSCy Schubert pkt = (u_char *)dpkg;
192b15cb3dSCy Schubert
202b15cb3dSCy Schubert fprintf(output, HLINE);
212b15cb3dSCy Schubert
222b15cb3dSCy Schubert for (a = 0; a < pkt_length; a++) {
232b15cb3dSCy Schubert if (a > 0 && a % 8 == 0)
242b15cb3dSCy Schubert fprintf(output, "\n");
252b15cb3dSCy Schubert
2609100258SXin LI fprintf(output, "%3d: %02x ", a, pkt[a]);
272b15cb3dSCy Schubert }
282b15cb3dSCy Schubert
292b15cb3dSCy Schubert fprintf(output, "\n");
302b15cb3dSCy Schubert fprintf(output, HLINE);
312b15cb3dSCy Schubert }
322b15cb3dSCy Schubert
332b15cb3dSCy Schubert /* Output a long floating point value in hex in the style described above
342b15cb3dSCy Schubert */
352b15cb3dSCy Schubert void
l_fp_output(l_fp * ts,FILE * output)362b15cb3dSCy Schubert l_fp_output(
372b15cb3dSCy Schubert l_fp * ts,
382b15cb3dSCy Schubert FILE * output
392b15cb3dSCy Schubert )
402b15cb3dSCy Schubert {
412b15cb3dSCy Schubert fprintf(output, "%s\n", prettydate(ts));
422b15cb3dSCy Schubert }
432b15cb3dSCy Schubert
442b15cb3dSCy Schubert /* Output a long floating point value in binary in the style described above
452b15cb3dSCy Schubert */
462b15cb3dSCy Schubert void
l_fp_output_bin(l_fp * ts,FILE * output)472b15cb3dSCy Schubert l_fp_output_bin (
482b15cb3dSCy Schubert l_fp *ts,
492b15cb3dSCy Schubert FILE *output
502b15cb3dSCy Schubert )
512b15cb3dSCy Schubert {
522b15cb3dSCy Schubert register int a, b;
532b15cb3dSCy Schubert
542b15cb3dSCy Schubert fprintf(output, HLINE);
552b15cb3dSCy Schubert
562b15cb3dSCy Schubert for(a=0; a<8; a++) {
572b15cb3dSCy Schubert short tmp = ((unsigned char *) ts)[a];
582b15cb3dSCy Schubert tmp++;
592b15cb3dSCy Schubert
602b15cb3dSCy Schubert fprintf(output, "%i: ", a);
612b15cb3dSCy Schubert
622b15cb3dSCy Schubert for(b=7; b>=0; b--) {
632b15cb3dSCy Schubert int texp = (int) pow(2, b);
642b15cb3dSCy Schubert
652b15cb3dSCy Schubert if(tmp - texp > 0) {
662b15cb3dSCy Schubert fprintf(output, "1");
672b15cb3dSCy Schubert tmp -= texp;
682b15cb3dSCy Schubert }
692b15cb3dSCy Schubert else {
702b15cb3dSCy Schubert fprintf(output, "0");
712b15cb3dSCy Schubert }
722b15cb3dSCy Schubert }
732b15cb3dSCy Schubert
742b15cb3dSCy Schubert fprintf(output, " ");
752b15cb3dSCy Schubert }
762b15cb3dSCy Schubert
772b15cb3dSCy Schubert fprintf(output, "\n");
782b15cb3dSCy Schubert fprintf(output, HLINE);
792b15cb3dSCy Schubert }
802b15cb3dSCy Schubert
812b15cb3dSCy Schubert /* Output a long floating point value in decimal in the style described above
822b15cb3dSCy Schubert */
832b15cb3dSCy Schubert void
l_fp_output_dec(l_fp * ts,FILE * output)842b15cb3dSCy Schubert l_fp_output_dec (
852b15cb3dSCy Schubert l_fp *ts,
862b15cb3dSCy Schubert FILE *output
872b15cb3dSCy Schubert )
882b15cb3dSCy Schubert {
892b15cb3dSCy Schubert register int a;
902b15cb3dSCy Schubert
912b15cb3dSCy Schubert fprintf(output, HLINE);
922b15cb3dSCy Schubert
932b15cb3dSCy Schubert for(a=0; a<8; a++)
942b15cb3dSCy Schubert fprintf(output, "%i: %i \t", a, ((unsigned char *) ts)[a]);
952b15cb3dSCy Schubert
962b15cb3dSCy Schubert fprintf(output, "\n");
972b15cb3dSCy Schubert fprintf(output, HLINE);
982b15cb3dSCy Schubert
992b15cb3dSCy Schubert }
1002b15cb3dSCy Schubert
1012b15cb3dSCy Schubert /* Convert a struct addrinfo to a string containing the address in style
1022b15cb3dSCy Schubert * of inet_ntoa
1032b15cb3dSCy Schubert */
1042b15cb3dSCy Schubert char *
addrinfo_to_str(const struct addrinfo * addr)1052b15cb3dSCy Schubert addrinfo_to_str (
1062b15cb3dSCy Schubert const struct addrinfo *addr
1072b15cb3dSCy Schubert )
1082b15cb3dSCy Schubert {
1092b15cb3dSCy Schubert sockaddr_u s;
1102b15cb3dSCy Schubert
1112b15cb3dSCy Schubert ZERO(s);
1122b15cb3dSCy Schubert memcpy(&s, addr->ai_addr, min(sizeof(s), addr->ai_addrlen));
1132b15cb3dSCy Schubert
1142b15cb3dSCy Schubert return ss_to_str(&s);
1152b15cb3dSCy Schubert }
1162b15cb3dSCy Schubert
1172b15cb3dSCy Schubert
1182b15cb3dSCy Schubert /* Convert a sockaddr_u to a string containing the address in
1192b15cb3dSCy Schubert * style of inet_ntoa
1202b15cb3dSCy Schubert * Why not switch callers to use stoa from libntp? No free() needed
1212b15cb3dSCy Schubert * in that case.
1222b15cb3dSCy Schubert */
1232b15cb3dSCy Schubert char *
ss_to_str(sockaddr_u * saddr)1242b15cb3dSCy Schubert ss_to_str(
1252b15cb3dSCy Schubert sockaddr_u *saddr
1262b15cb3dSCy Schubert )
1272b15cb3dSCy Schubert {
1282b15cb3dSCy Schubert return estrdup(stoa(saddr));
1292b15cb3dSCy Schubert }
1302b15cb3dSCy Schubert
1312b15cb3dSCy Schubert
1322b15cb3dSCy Schubert /*
1332b15cb3dSCy Schubert * Converts a struct tv to a date string
1342b15cb3dSCy Schubert */
1352b15cb3dSCy Schubert char *
tv_to_str(const struct timeval * tv)1362b15cb3dSCy Schubert tv_to_str(
1372b15cb3dSCy Schubert const struct timeval *tv
1382b15cb3dSCy Schubert )
1392b15cb3dSCy Schubert {
1402b15cb3dSCy Schubert const size_t bufsize = 48;
1412b15cb3dSCy Schubert char *buf;
1422b15cb3dSCy Schubert time_t gmt_time, local_time;
143*a466cc55SCy Schubert struct tm *ptm, tm_local;
144*a466cc55SCy Schubert int hh, mm, lto, isdst;
1452b15cb3dSCy Schubert
1462b15cb3dSCy Schubert /*
1472b15cb3dSCy Schubert * convert to struct tm in UTC, then intentionally feed
1482b15cb3dSCy Schubert * that tm to mktime() which expects local time input, to
1492b15cb3dSCy Schubert * derive the offset from UTC to local time.
150*a466cc55SCy Schubert * Need to retrieve dst flag from localtime first for mktime.
1512b15cb3dSCy Schubert */
1522b15cb3dSCy Schubert gmt_time = tv->tv_sec;
153*a466cc55SCy Schubert ptm = localtime(&gmt_time);
154*a466cc55SCy Schubert memcpy (&tm_local, ptm, sizeof(tm_local));
155*a466cc55SCy Schubert isdst = ptm->tm_isdst;
156*a466cc55SCy Schubert ptm = gmtime(&gmt_time);
157*a466cc55SCy Schubert ptm->tm_isdst = isdst;
158*a466cc55SCy Schubert local_time = mktime(ptm);
1592b15cb3dSCy Schubert
1602b15cb3dSCy Schubert /* Local timezone offsets should never cause an overflow. Yeah. */
1612b15cb3dSCy Schubert lto = difftime(local_time, gmt_time);
1622b15cb3dSCy Schubert lto /= 60;
1632b15cb3dSCy Schubert hh = lto / 60;
1642b15cb3dSCy Schubert mm = abs(lto % 60);
1652b15cb3dSCy Schubert
1662b15cb3dSCy Schubert buf = emalloc(bufsize);
1672b15cb3dSCy Schubert snprintf(buf, bufsize,
1682b15cb3dSCy Schubert "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)",
169*a466cc55SCy Schubert tm_local.tm_year + 1900,
170*a466cc55SCy Schubert tm_local.tm_mon + 1,
171*a466cc55SCy Schubert tm_local.tm_mday,
172*a466cc55SCy Schubert tm_local.tm_hour,
173*a466cc55SCy Schubert tm_local.tm_min,
174*a466cc55SCy Schubert tm_local.tm_sec,
1752b15cb3dSCy Schubert (int)tv->tv_usec,
1762b15cb3dSCy Schubert hh,
1772b15cb3dSCy Schubert mm);
1782b15cb3dSCy Schubert
1792b15cb3dSCy Schubert return buf;
1802b15cb3dSCy Schubert }
1812b15cb3dSCy Schubert
1822b15cb3dSCy Schubert
1832b15cb3dSCy Schubert /*
1842b15cb3dSCy Schubert *
1852b15cb3dSCy Schubert * hostnameaddr()
1862b15cb3dSCy Schubert *
1872b15cb3dSCy Schubert * Formats the hostname and resulting numeric IP address into a string,
1882b15cb3dSCy Schubert * avoiding duplication if the "hostname" was in fact a numeric address.
1892b15cb3dSCy Schubert *
1902b15cb3dSCy Schubert */
1912b15cb3dSCy Schubert const char *
hostnameaddr(const char * hostname,const sockaddr_u * addr)1922b15cb3dSCy Schubert hostnameaddr(
1932b15cb3dSCy Schubert const char * hostname,
1942b15cb3dSCy Schubert const sockaddr_u * addr
1952b15cb3dSCy Schubert )
1962b15cb3dSCy Schubert {
1972b15cb3dSCy Schubert const char * addrtxt;
1982b15cb3dSCy Schubert char * result;
1992b15cb3dSCy Schubert int cnt;
2002b15cb3dSCy Schubert
2012b15cb3dSCy Schubert addrtxt = stoa(addr);
2022b15cb3dSCy Schubert LIB_GETBUF(result);
2032b15cb3dSCy Schubert if (strcmp(hostname, addrtxt))
2042b15cb3dSCy Schubert cnt = snprintf(result, LIB_BUFLENGTH, "%s %s",
2052b15cb3dSCy Schubert hostname, addrtxt);
2062b15cb3dSCy Schubert else
2072b15cb3dSCy Schubert cnt = snprintf(result, LIB_BUFLENGTH, "%s", addrtxt);
2082b15cb3dSCy Schubert if (cnt >= LIB_BUFLENGTH)
2092b15cb3dSCy Schubert snprintf(result, LIB_BUFLENGTH,
2102b15cb3dSCy Schubert "hostnameaddr ERROR have %d (%d needed)",
2112b15cb3dSCy Schubert LIB_BUFLENGTH, cnt + 1);
2122b15cb3dSCy Schubert
2132b15cb3dSCy Schubert return result;
2142b15cb3dSCy Schubert }
215