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