1 /* $NetBSD: utilities.c,v 1.1.1.2 2012/01/31 21:27:14 kardel 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, "%d: %x \t", 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 register int a; 44 45 fprintf(output, HLINE); 46 47 for(a=0; a<8; a++) 48 fprintf(output, "%i: %x \t", a, ((unsigned char *) ts)[a]); 49 50 fprintf(output, "\n"); 51 fprintf(output, HLINE); 52 53 } 54 55 /* Output a long floating point value in binary in the style described above 56 */ 57 void 58 l_fp_output_bin ( 59 l_fp *ts, 60 FILE *output 61 ) 62 { 63 register int a, b; 64 65 fprintf(output, HLINE); 66 67 for(a=0; a<8; a++) { 68 short tmp = ((unsigned char *) ts)[a]; 69 tmp++; 70 71 fprintf(output, "%i: ", a); 72 73 for(b=7; b>=0; b--) { 74 int texp = (int) pow(2, b); 75 76 if(tmp - texp > 0) { 77 fprintf(output, "1"); 78 tmp -= texp; 79 } 80 else { 81 fprintf(output, "0"); 82 } 83 } 84 85 fprintf(output, " "); 86 } 87 88 fprintf(output, "\n"); 89 fprintf(output, HLINE); 90 } 91 92 /* Output a long floating point value in decimal in the style described above 93 */ 94 void 95 l_fp_output_dec ( 96 l_fp *ts, 97 FILE *output 98 ) 99 { 100 register int a; 101 102 fprintf(output, HLINE); 103 104 for(a=0; a<8; a++) 105 fprintf(output, "%i: %i \t", a, ((unsigned char *) ts)[a]); 106 107 fprintf(output, "\n"); 108 fprintf(output, HLINE); 109 110 } 111 112 /* Convert a struct addrinfo to a string containing the address in style 113 * of inet_ntoa 114 */ 115 char * 116 addrinfo_to_str ( 117 struct addrinfo *addr 118 ) 119 { 120 sockaddr_u s; 121 122 memset(&s, 0, sizeof(s)); 123 memcpy(&s, addr->ai_addr, min(sizeof(s), addr->ai_addrlen)); 124 125 return ss_to_str(&s); 126 } 127 128 /* Convert a sockaddr_u to a string containing the address in 129 * style of inet_ntoa 130 * Why not switch callers to use stoa from libntp? No free() needed 131 * in that case. 132 */ 133 char * 134 ss_to_str ( 135 sockaddr_u *saddr 136 ) 137 { 138 char * buf; 139 140 buf = emalloc(INET6_ADDRSTRLEN); 141 strncpy(buf, stoa(saddr), INET6_ADDRSTRLEN); 142 143 return buf; 144 } 145 /* 146 * Converts a struct tv to a date string 147 */ 148 char * 149 tv_to_str( 150 const struct timeval *tv 151 ) 152 { 153 const size_t bufsize = 48; 154 char *buf; 155 time_t gmt_time, local_time; 156 struct tm *p_tm_local; 157 int hh, mm, lto; 158 159 /* 160 * convert to struct tm in UTC, then intentionally feed 161 * that tm to mktime() which expects local time input, to 162 * derive the offset from UTC to local time. 163 */ 164 gmt_time = tv->tv_sec; 165 local_time = mktime(gmtime(&gmt_time)); 166 p_tm_local = localtime(&gmt_time); 167 168 /* Local timezone offsets should never cause an overflow. Yeah. */ 169 lto = difftime(local_time, gmt_time); 170 lto /= 60; 171 hh = lto / 60; 172 mm = abs(lto % 60); 173 174 buf = emalloc(bufsize); 175 snprintf(buf, bufsize, 176 "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)", 177 p_tm_local->tm_year + 1900, 178 p_tm_local->tm_mon + 1, 179 p_tm_local->tm_mday, 180 p_tm_local->tm_hour, 181 p_tm_local->tm_min, 182 p_tm_local->tm_sec, 183 (int)tv->tv_usec, 184 hh, 185 mm); 186 187 return buf; 188 } 189 190 191 192 193