#include #include "utilities.h" #include /* Display a NTP packet in hex with leading address offset * e.g. offset: value, 0: ff 1: fe ... 255: 00 */ void pkt_output ( struct pkt *dpkg, int pkt_length, FILE *output ) { register int a; u_char *pkt; pkt = (u_char *)dpkg; fprintf(output, HLINE); for (a = 0; a < pkt_length; a++) { if (a > 0 && a % 8 == 0) fprintf(output, "\n"); fprintf(output, "%3d: %02x ", a, pkt[a]); } fprintf(output, "\n"); fprintf(output, HLINE); } /* Output a long floating point value in hex in the style described above */ void l_fp_output( l_fp * ts, FILE * output ) { fprintf(output, "%s\n", prettydate(ts)); } /* Output a long floating point value in binary in the style described above */ void l_fp_output_bin ( l_fp *ts, FILE *output ) { register int a, b; fprintf(output, HLINE); for(a=0; a<8; a++) { short tmp = ((unsigned char *) ts)[a]; tmp++; fprintf(output, "%i: ", a); for(b=7; b>=0; b--) { int texp = (int) pow(2, b); if(tmp - texp > 0) { fprintf(output, "1"); tmp -= texp; } else { fprintf(output, "0"); } } fprintf(output, " "); } fprintf(output, "\n"); fprintf(output, HLINE); } /* Output a long floating point value in decimal in the style described above */ void l_fp_output_dec ( l_fp *ts, FILE *output ) { register int a; fprintf(output, HLINE); for(a=0; a<8; a++) fprintf(output, "%i: %i \t", a, ((unsigned char *) ts)[a]); fprintf(output, "\n"); fprintf(output, HLINE); } /* Convert a struct addrinfo to a string containing the address in style * of inet_ntoa */ char * addrinfo_to_str ( const struct addrinfo *addr ) { sockaddr_u s; ZERO(s); memcpy(&s, addr->ai_addr, min(sizeof(s), addr->ai_addrlen)); return ss_to_str(&s); } /* Convert a sockaddr_u to a string containing the address in * style of inet_ntoa * Why not switch callers to use stoa from libntp? No free() needed * in that case. */ char * ss_to_str( sockaddr_u *saddr ) { return estrdup(stoa(saddr)); } /* * Converts a struct tv to a date string */ char * tv_to_str( const struct timeval *tv ) { const size_t bufsize = 48; char *buf; time_t gmt_time, local_time; struct tm *ptm, tm_local; int hh, mm, lto, isdst; /* * convert to struct tm in UTC, then intentionally feed * that tm to mktime() which expects local time input, to * derive the offset from UTC to local time. * Need to retrieve dst flag from localtime first for mktime. */ gmt_time = tv->tv_sec; ptm = localtime(&gmt_time); memcpy (&tm_local, ptm, sizeof(tm_local)); isdst = ptm->tm_isdst; ptm = gmtime(&gmt_time); ptm->tm_isdst = isdst; local_time = mktime(ptm); /* Local timezone offsets should never cause an overflow. Yeah. */ lto = difftime(local_time, gmt_time); lto /= 60; hh = lto / 60; mm = abs(lto % 60); buf = emalloc(bufsize); snprintf(buf, bufsize, "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)", tm_local.tm_year + 1900, tm_local.tm_mon + 1, tm_local.tm_mday, tm_local.tm_hour, tm_local.tm_min, tm_local.tm_sec, (int)tv->tv_usec, hh, mm); return buf; } /* * * hostnameaddr() * * Formats the hostname and resulting numeric IP address into a string, * avoiding duplication if the "hostname" was in fact a numeric address. * */ const char * hostnameaddr( const char * hostname, const sockaddr_u * addr ) { const char * addrtxt; char * result; int cnt; addrtxt = stoa(addr); LIB_GETBUF(result); if (strcmp(hostname, addrtxt)) cnt = snprintf(result, LIB_BUFLENGTH, "%s %s", hostname, addrtxt); else cnt = snprintf(result, LIB_BUFLENGTH, "%s", addrtxt); if (cnt >= LIB_BUFLENGTH) snprintf(result, LIB_BUFLENGTH, "hostnameaddr ERROR have %d (%d needed)", LIB_BUFLENGTH, cnt + 1); return result; }