1*2b15cb3dSCy Schubert #include <config.h> 2*2b15cb3dSCy Schubert #include "utilities.h" 3*2b15cb3dSCy Schubert #include <assert.h> 4*2b15cb3dSCy Schubert 5*2b15cb3dSCy Schubert /* Display a NTP packet in hex with leading address offset 6*2b15cb3dSCy Schubert * e.g. offset: value, 0: ff 1: fe ... 255: 00 7*2b15cb3dSCy Schubert */ 8*2b15cb3dSCy Schubert void 9*2b15cb3dSCy Schubert pkt_output ( 10*2b15cb3dSCy Schubert struct pkt *dpkg, 11*2b15cb3dSCy Schubert int pkt_length, 12*2b15cb3dSCy Schubert FILE *output 13*2b15cb3dSCy Schubert ) 14*2b15cb3dSCy Schubert { 15*2b15cb3dSCy Schubert register int a; 16*2b15cb3dSCy Schubert u_char *pkt; 17*2b15cb3dSCy Schubert 18*2b15cb3dSCy Schubert pkt = (u_char *)dpkg; 19*2b15cb3dSCy Schubert 20*2b15cb3dSCy Schubert fprintf(output, HLINE); 21*2b15cb3dSCy Schubert 22*2b15cb3dSCy Schubert for (a = 0; a < pkt_length; a++) { 23*2b15cb3dSCy Schubert if (a > 0 && a % 8 == 0) 24*2b15cb3dSCy Schubert fprintf(output, "\n"); 25*2b15cb3dSCy Schubert 26*2b15cb3dSCy Schubert fprintf(output, "%d: %x \t", a, pkt[a]); 27*2b15cb3dSCy Schubert } 28*2b15cb3dSCy Schubert 29*2b15cb3dSCy Schubert fprintf(output, "\n"); 30*2b15cb3dSCy Schubert fprintf(output, HLINE); 31*2b15cb3dSCy Schubert } 32*2b15cb3dSCy Schubert 33*2b15cb3dSCy Schubert /* Output a long floating point value in hex in the style described above 34*2b15cb3dSCy Schubert */ 35*2b15cb3dSCy Schubert void 36*2b15cb3dSCy Schubert l_fp_output( 37*2b15cb3dSCy Schubert l_fp * ts, 38*2b15cb3dSCy Schubert FILE * output 39*2b15cb3dSCy Schubert ) 40*2b15cb3dSCy Schubert { 41*2b15cb3dSCy Schubert fprintf(output, "%s\n", prettydate(ts)); 42*2b15cb3dSCy Schubert } 43*2b15cb3dSCy Schubert 44*2b15cb3dSCy Schubert /* Output a long floating point value in binary in the style described above 45*2b15cb3dSCy Schubert */ 46*2b15cb3dSCy Schubert void 47*2b15cb3dSCy Schubert l_fp_output_bin ( 48*2b15cb3dSCy Schubert l_fp *ts, 49*2b15cb3dSCy Schubert FILE *output 50*2b15cb3dSCy Schubert ) 51*2b15cb3dSCy Schubert { 52*2b15cb3dSCy Schubert register int a, b; 53*2b15cb3dSCy Schubert 54*2b15cb3dSCy Schubert fprintf(output, HLINE); 55*2b15cb3dSCy Schubert 56*2b15cb3dSCy Schubert for(a=0; a<8; a++) { 57*2b15cb3dSCy Schubert short tmp = ((unsigned char *) ts)[a]; 58*2b15cb3dSCy Schubert tmp++; 59*2b15cb3dSCy Schubert 60*2b15cb3dSCy Schubert fprintf(output, "%i: ", a); 61*2b15cb3dSCy Schubert 62*2b15cb3dSCy Schubert for(b=7; b>=0; b--) { 63*2b15cb3dSCy Schubert int texp = (int) pow(2, b); 64*2b15cb3dSCy Schubert 65*2b15cb3dSCy Schubert if(tmp - texp > 0) { 66*2b15cb3dSCy Schubert fprintf(output, "1"); 67*2b15cb3dSCy Schubert tmp -= texp; 68*2b15cb3dSCy Schubert } 69*2b15cb3dSCy Schubert else { 70*2b15cb3dSCy Schubert fprintf(output, "0"); 71*2b15cb3dSCy Schubert } 72*2b15cb3dSCy Schubert } 73*2b15cb3dSCy Schubert 74*2b15cb3dSCy Schubert fprintf(output, " "); 75*2b15cb3dSCy Schubert } 76*2b15cb3dSCy Schubert 77*2b15cb3dSCy Schubert fprintf(output, "\n"); 78*2b15cb3dSCy Schubert fprintf(output, HLINE); 79*2b15cb3dSCy Schubert } 80*2b15cb3dSCy Schubert 81*2b15cb3dSCy Schubert /* Output a long floating point value in decimal in the style described above 82*2b15cb3dSCy Schubert */ 83*2b15cb3dSCy Schubert void 84*2b15cb3dSCy Schubert l_fp_output_dec ( 85*2b15cb3dSCy Schubert l_fp *ts, 86*2b15cb3dSCy Schubert FILE *output 87*2b15cb3dSCy Schubert ) 88*2b15cb3dSCy Schubert { 89*2b15cb3dSCy Schubert register int a; 90*2b15cb3dSCy Schubert 91*2b15cb3dSCy Schubert fprintf(output, HLINE); 92*2b15cb3dSCy Schubert 93*2b15cb3dSCy Schubert for(a=0; a<8; a++) 94*2b15cb3dSCy Schubert fprintf(output, "%i: %i \t", a, ((unsigned char *) ts)[a]); 95*2b15cb3dSCy Schubert 96*2b15cb3dSCy Schubert fprintf(output, "\n"); 97*2b15cb3dSCy Schubert fprintf(output, HLINE); 98*2b15cb3dSCy Schubert 99*2b15cb3dSCy Schubert } 100*2b15cb3dSCy Schubert 101*2b15cb3dSCy Schubert /* Convert a struct addrinfo to a string containing the address in style 102*2b15cb3dSCy Schubert * of inet_ntoa 103*2b15cb3dSCy Schubert */ 104*2b15cb3dSCy Schubert char * 105*2b15cb3dSCy Schubert addrinfo_to_str ( 106*2b15cb3dSCy Schubert const struct addrinfo *addr 107*2b15cb3dSCy Schubert ) 108*2b15cb3dSCy Schubert { 109*2b15cb3dSCy Schubert sockaddr_u s; 110*2b15cb3dSCy Schubert 111*2b15cb3dSCy Schubert ZERO(s); 112*2b15cb3dSCy Schubert memcpy(&s, addr->ai_addr, min(sizeof(s), addr->ai_addrlen)); 113*2b15cb3dSCy Schubert 114*2b15cb3dSCy Schubert return ss_to_str(&s); 115*2b15cb3dSCy Schubert } 116*2b15cb3dSCy Schubert 117*2b15cb3dSCy Schubert 118*2b15cb3dSCy Schubert /* Convert a sockaddr_u to a string containing the address in 119*2b15cb3dSCy Schubert * style of inet_ntoa 120*2b15cb3dSCy Schubert * Why not switch callers to use stoa from libntp? No free() needed 121*2b15cb3dSCy Schubert * in that case. 122*2b15cb3dSCy Schubert */ 123*2b15cb3dSCy Schubert char * 124*2b15cb3dSCy Schubert ss_to_str( 125*2b15cb3dSCy Schubert sockaddr_u *saddr 126*2b15cb3dSCy Schubert ) 127*2b15cb3dSCy Schubert { 128*2b15cb3dSCy Schubert return estrdup(stoa(saddr)); 129*2b15cb3dSCy Schubert } 130*2b15cb3dSCy Schubert 131*2b15cb3dSCy Schubert 132*2b15cb3dSCy Schubert /* 133*2b15cb3dSCy Schubert * Converts a struct tv to a date string 134*2b15cb3dSCy Schubert */ 135*2b15cb3dSCy Schubert char * 136*2b15cb3dSCy Schubert tv_to_str( 137*2b15cb3dSCy Schubert const struct timeval *tv 138*2b15cb3dSCy Schubert ) 139*2b15cb3dSCy Schubert { 140*2b15cb3dSCy Schubert const size_t bufsize = 48; 141*2b15cb3dSCy Schubert char *buf; 142*2b15cb3dSCy Schubert time_t gmt_time, local_time; 143*2b15cb3dSCy Schubert struct tm *p_tm_local; 144*2b15cb3dSCy Schubert int hh, mm, lto; 145*2b15cb3dSCy Schubert 146*2b15cb3dSCy Schubert /* 147*2b15cb3dSCy Schubert * convert to struct tm in UTC, then intentionally feed 148*2b15cb3dSCy Schubert * that tm to mktime() which expects local time input, to 149*2b15cb3dSCy Schubert * derive the offset from UTC to local time. 150*2b15cb3dSCy Schubert */ 151*2b15cb3dSCy Schubert gmt_time = tv->tv_sec; 152*2b15cb3dSCy Schubert local_time = mktime(gmtime(&gmt_time)); 153*2b15cb3dSCy Schubert p_tm_local = localtime(&gmt_time); 154*2b15cb3dSCy Schubert 155*2b15cb3dSCy Schubert /* Local timezone offsets should never cause an overflow. Yeah. */ 156*2b15cb3dSCy Schubert lto = difftime(local_time, gmt_time); 157*2b15cb3dSCy Schubert lto /= 60; 158*2b15cb3dSCy Schubert hh = lto / 60; 159*2b15cb3dSCy Schubert mm = abs(lto % 60); 160*2b15cb3dSCy Schubert 161*2b15cb3dSCy Schubert buf = emalloc(bufsize); 162*2b15cb3dSCy Schubert snprintf(buf, bufsize, 163*2b15cb3dSCy Schubert "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)", 164*2b15cb3dSCy Schubert p_tm_local->tm_year + 1900, 165*2b15cb3dSCy Schubert p_tm_local->tm_mon + 1, 166*2b15cb3dSCy Schubert p_tm_local->tm_mday, 167*2b15cb3dSCy Schubert p_tm_local->tm_hour, 168*2b15cb3dSCy Schubert p_tm_local->tm_min, 169*2b15cb3dSCy Schubert p_tm_local->tm_sec, 170*2b15cb3dSCy Schubert (int)tv->tv_usec, 171*2b15cb3dSCy Schubert hh, 172*2b15cb3dSCy Schubert mm); 173*2b15cb3dSCy Schubert 174*2b15cb3dSCy Schubert return buf; 175*2b15cb3dSCy Schubert } 176*2b15cb3dSCy Schubert 177*2b15cb3dSCy Schubert 178*2b15cb3dSCy Schubert /* 179*2b15cb3dSCy Schubert * 180*2b15cb3dSCy Schubert * hostnameaddr() 181*2b15cb3dSCy Schubert * 182*2b15cb3dSCy Schubert * Formats the hostname and resulting numeric IP address into a string, 183*2b15cb3dSCy Schubert * avoiding duplication if the "hostname" was in fact a numeric address. 184*2b15cb3dSCy Schubert * 185*2b15cb3dSCy Schubert */ 186*2b15cb3dSCy Schubert const char * 187*2b15cb3dSCy Schubert hostnameaddr( 188*2b15cb3dSCy Schubert const char * hostname, 189*2b15cb3dSCy Schubert const sockaddr_u * addr 190*2b15cb3dSCy Schubert ) 191*2b15cb3dSCy Schubert { 192*2b15cb3dSCy Schubert const char * addrtxt; 193*2b15cb3dSCy Schubert char * result; 194*2b15cb3dSCy Schubert int cnt; 195*2b15cb3dSCy Schubert 196*2b15cb3dSCy Schubert addrtxt = stoa(addr); 197*2b15cb3dSCy Schubert LIB_GETBUF(result); 198*2b15cb3dSCy Schubert if (strcmp(hostname, addrtxt)) 199*2b15cb3dSCy Schubert cnt = snprintf(result, LIB_BUFLENGTH, "%s %s", 200*2b15cb3dSCy Schubert hostname, addrtxt); 201*2b15cb3dSCy Schubert else 202*2b15cb3dSCy Schubert cnt = snprintf(result, LIB_BUFLENGTH, "%s", addrtxt); 203*2b15cb3dSCy Schubert if (cnt >= LIB_BUFLENGTH) 204*2b15cb3dSCy Schubert snprintf(result, LIB_BUFLENGTH, 205*2b15cb3dSCy Schubert "hostnameaddr ERROR have %d (%d needed)", 206*2b15cb3dSCy Schubert LIB_BUFLENGTH, cnt + 1); 207*2b15cb3dSCy Schubert 208*2b15cb3dSCy Schubert return result; 209*2b15cb3dSCy Schubert } 210