1258945Sroberto#include <config.h> 2258945Sroberto#include "utilities.h" 3258945Sroberto#include <assert.h> 4258945Sroberto 5258945Sroberto/* Display a NTP packet in hex with leading address offset 6258945Sroberto * e.g. offset: value, 0: ff 1: fe ... 255: 00 7258945Sroberto */ 8258945Srobertovoid 9258945Srobertopkt_output ( 10258945Sroberto struct pkt *dpkg, 11258945Sroberto int pkt_length, 12258945Sroberto FILE *output 13258945Sroberto ) 14258945Sroberto{ 15258945Sroberto register int a; 16258945Sroberto u_char *pkt; 17258945Sroberto 18258945Sroberto pkt = (u_char *)dpkg; 19258945Sroberto 20258945Sroberto fprintf(output, HLINE); 21258945Sroberto 22258945Sroberto for (a = 0; a < pkt_length; a++) { 23258945Sroberto if (a > 0 && a % 8 == 0) 24258945Sroberto fprintf(output, "\n"); 25258945Sroberto 26330106Sdelphij fprintf(output, "%3d: %02x ", a, pkt[a]); 27258945Sroberto } 28258945Sroberto 29258945Sroberto fprintf(output, "\n"); 30258945Sroberto fprintf(output, HLINE); 31258945Sroberto} 32258945Sroberto 33258945Sroberto/* Output a long floating point value in hex in the style described above 34258945Sroberto */ 35258945Srobertovoid 36280849Scyl_fp_output( 37280849Scy l_fp * ts, 38280849Scy FILE * output 39280849Scy ) 40258945Sroberto{ 41280849Scy fprintf(output, "%s\n", prettydate(ts)); 42258945Sroberto} 43258945Sroberto 44258945Sroberto/* Output a long floating point value in binary in the style described above 45258945Sroberto */ 46258945Srobertovoid 47258945Srobertol_fp_output_bin ( 48258945Sroberto l_fp *ts, 49258945Sroberto FILE *output 50258945Sroberto ) 51258945Sroberto{ 52258945Sroberto register int a, b; 53258945Sroberto 54258945Sroberto fprintf(output, HLINE); 55258945Sroberto 56258945Sroberto for(a=0; a<8; a++) { 57258945Sroberto short tmp = ((unsigned char *) ts)[a]; 58258945Sroberto tmp++; 59258945Sroberto 60258945Sroberto fprintf(output, "%i: ", a); 61258945Sroberto 62258945Sroberto for(b=7; b>=0; b--) { 63258945Sroberto int texp = (int) pow(2, b); 64258945Sroberto 65258945Sroberto if(tmp - texp > 0) { 66258945Sroberto fprintf(output, "1"); 67258945Sroberto tmp -= texp; 68258945Sroberto } 69258945Sroberto else { 70258945Sroberto fprintf(output, "0"); 71258945Sroberto } 72258945Sroberto } 73258945Sroberto 74258945Sroberto fprintf(output, " "); 75258945Sroberto } 76258945Sroberto 77258945Sroberto fprintf(output, "\n"); 78258945Sroberto fprintf(output, HLINE); 79258945Sroberto} 80258945Sroberto 81258945Sroberto/* Output a long floating point value in decimal in the style described above 82258945Sroberto */ 83258945Srobertovoid 84258945Srobertol_fp_output_dec ( 85258945Sroberto l_fp *ts, 86258945Sroberto FILE *output 87258945Sroberto ) 88258945Sroberto{ 89258945Sroberto register int a; 90258945Sroberto 91258945Sroberto fprintf(output, HLINE); 92258945Sroberto 93258945Sroberto for(a=0; a<8; a++) 94258945Sroberto fprintf(output, "%i: %i \t", a, ((unsigned char *) ts)[a]); 95258945Sroberto 96258945Sroberto fprintf(output, "\n"); 97258945Sroberto fprintf(output, HLINE); 98258945Sroberto 99258945Sroberto} 100258945Sroberto 101258945Sroberto/* Convert a struct addrinfo to a string containing the address in style 102258945Sroberto * of inet_ntoa 103258945Sroberto */ 104258945Srobertochar * 105258945Srobertoaddrinfo_to_str ( 106280849Scy const struct addrinfo *addr 107258945Sroberto ) 108258945Sroberto{ 109258945Sroberto sockaddr_u s; 110258945Sroberto 111280849Scy ZERO(s); 112258945Sroberto memcpy(&s, addr->ai_addr, min(sizeof(s), addr->ai_addrlen)); 113258945Sroberto 114258945Sroberto return ss_to_str(&s); 115258945Sroberto} 116258945Sroberto 117280849Scy 118258945Sroberto/* Convert a sockaddr_u to a string containing the address in 119258945Sroberto * style of inet_ntoa 120258945Sroberto * Why not switch callers to use stoa from libntp? No free() needed 121258945Sroberto * in that case. 122258945Sroberto */ 123258945Srobertochar * 124280849Scyss_to_str( 125258945Sroberto sockaddr_u *saddr 126258945Sroberto ) 127258945Sroberto{ 128280849Scy return estrdup(stoa(saddr)); 129280849Scy} 130258945Sroberto 131280849Scy 132258945Sroberto/* 133258945Sroberto * Converts a struct tv to a date string 134258945Sroberto */ 135258945Srobertochar * 136258945Srobertotv_to_str( 137258945Sroberto const struct timeval *tv 138258945Sroberto ) 139258945Sroberto{ 140258945Sroberto const size_t bufsize = 48; 141258945Sroberto char *buf; 142258945Sroberto time_t gmt_time, local_time; 143258945Sroberto struct tm *p_tm_local; 144258945Sroberto int hh, mm, lto; 145258945Sroberto 146258945Sroberto /* 147258945Sroberto * convert to struct tm in UTC, then intentionally feed 148258945Sroberto * that tm to mktime() which expects local time input, to 149258945Sroberto * derive the offset from UTC to local time. 150258945Sroberto */ 151258945Sroberto gmt_time = tv->tv_sec; 152258945Sroberto local_time = mktime(gmtime(&gmt_time)); 153258945Sroberto p_tm_local = localtime(&gmt_time); 154258945Sroberto 155258945Sroberto /* Local timezone offsets should never cause an overflow. Yeah. */ 156258945Sroberto lto = difftime(local_time, gmt_time); 157258945Sroberto lto /= 60; 158258945Sroberto hh = lto / 60; 159258945Sroberto mm = abs(lto % 60); 160258945Sroberto 161258945Sroberto buf = emalloc(bufsize); 162258945Sroberto snprintf(buf, bufsize, 163258945Sroberto "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)", 164258945Sroberto p_tm_local->tm_year + 1900, 165258945Sroberto p_tm_local->tm_mon + 1, 166258945Sroberto p_tm_local->tm_mday, 167258945Sroberto p_tm_local->tm_hour, 168258945Sroberto p_tm_local->tm_min, 169258945Sroberto p_tm_local->tm_sec, 170258945Sroberto (int)tv->tv_usec, 171258945Sroberto hh, 172258945Sroberto mm); 173258945Sroberto 174258945Sroberto return buf; 175258945Sroberto} 176258945Sroberto 177258945Sroberto 178280849Scy/* 179280849Scy * 180280849Scy * hostnameaddr() 181280849Scy * 182280849Scy * Formats the hostname and resulting numeric IP address into a string, 183280849Scy * avoiding duplication if the "hostname" was in fact a numeric address. 184280849Scy * 185280849Scy */ 186280849Scyconst char * 187280849Scyhostnameaddr( 188280849Scy const char * hostname, 189280849Scy const sockaddr_u * addr 190280849Scy ) 191280849Scy{ 192280849Scy const char * addrtxt; 193280849Scy char * result; 194280849Scy int cnt; 195258945Sroberto 196280849Scy addrtxt = stoa(addr); 197280849Scy LIB_GETBUF(result); 198280849Scy if (strcmp(hostname, addrtxt)) 199280849Scy cnt = snprintf(result, LIB_BUFLENGTH, "%s %s", 200280849Scy hostname, addrtxt); 201280849Scy else 202280849Scy cnt = snprintf(result, LIB_BUFLENGTH, "%s", addrtxt); 203280849Scy if (cnt >= LIB_BUFLENGTH) 204280849Scy snprintf(result, LIB_BUFLENGTH, 205280849Scy "hostnameaddr ERROR have %d (%d needed)", 206280849Scy LIB_BUFLENGTH, cnt + 1); 207280849Scy 208280849Scy return result; 209280849Scy} 210