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 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 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 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 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 * 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 * 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 * 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 * 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