1 /*
2 * Copyright (c) 2001 Mark Fullmer and The Ohio State University
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: fmt.c,v 1.17 2003/03/06 22:57:25 maf Exp $
27 */
28
29 #include "ftinclude.h"
30 #include "ftlib.h"
31
32 #include <netdb.h>
33
fmt_uint8(char * s,uint8_t u,int format)34 unsigned int fmt_uint8(char *s, uint8_t u, int format)
35 {
36 int len = 0;
37 char *s1;
38
39 if (!s)
40 return 0;
41
42 s1 = s;
43
44 s += FMT_UINT8 - 1;
45 do {
46
47 ++len;
48 *--s = '0' + (u % 10);
49 u /= 10;
50
51 } while(u);
52
53 if ((format == FMT_PAD_RIGHT) || (format == FMT_JUST_LEFT)) {
54 bcopy(s, s1, len);
55 if (format == FMT_PAD_RIGHT)
56 for (; len < (FMT_UINT8 - 1); ++len)
57 s1[len] = ' ';
58 s1[len] = 0;
59 return len;
60 }
61
62 return len;
63
64 } /* fmt_uint8 */
65
fmt_uint16s(struct ftsym * ftsym,int max,char * s,uint16_t u,int format)66 unsigned int fmt_uint16s(struct ftsym *ftsym, int max, char *s, uint16_t u,
67 int format)
68 {
69 int ret;
70 char *str;
71
72 if (ftsym && ftsym_findbyval(ftsym, (uint32_t) u, &str) == 1) {
73
74 strncpy(s, str, max);
75 s[max-1] = 0;
76
77 ret = strlen(s);
78
79 if (format == FMT_PAD_RIGHT)
80 for (; ret < (max-1); ++ret)
81 s[ret] = ' ';
82
83 if (format == FMT_PAD_RIGHT)
84 return max-1;
85 else
86 return ret;
87
88 } else {
89 return fmt_uint16(s, u, format);
90 }
91
92 } /* fmt_uint16s */
93
fmt_uint8s(struct ftsym * ftsym,int max,char * s,uint8_t u,int format)94 unsigned int fmt_uint8s(struct ftsym *ftsym, int max, char *s, uint8_t u,
95 int format)
96 {
97 int ret;
98 char *str;
99
100 if (ftsym && ftsym_findbyval(ftsym, (uint32_t) u, &str) == 1) {
101
102 strncpy(s, str, max);
103 s[max-1] = 0;
104
105 ret = strlen(s);
106
107 if (format == FMT_PAD_RIGHT)
108 for (; ret < (max-1); ++ret)
109 s[ret] = ' ';
110
111 if (format == FMT_PAD_RIGHT)
112 return max-1;
113 else
114 return ret;
115
116 } else {
117 return fmt_uint8(s, u, format);
118 }
119
120 } /* fmt_uint8s */
121
fmt_uint32s(struct ftsym * ftsym,int max,char * s,uint32_t u,int format)122 unsigned int fmt_uint32s(struct ftsym *ftsym, int max, char *s, uint32_t u,
123 int format)
124 {
125 int ret;
126 char *str;
127
128 if (ftsym && ftsym_findbyval(ftsym, (uint32_t) u, &str) == 1) {
129
130 strncpy(s, str, max);
131 s[max-1] = 0;
132
133 ret = strlen(s);
134
135 if (format == FMT_PAD_RIGHT)
136 for (; ret < (max-1); ++ret)
137 s[ret] = ' ';
138
139 if (format == FMT_PAD_RIGHT)
140 return max-1;
141 else
142 return ret;
143
144 } else {
145 return fmt_uint32(s, u, format);
146 }
147
148 } /* fmt_uint32s */
149
150
fmt_uint16(char * s,uint16_t u,int format)151 unsigned int fmt_uint16(char *s, uint16_t u, int format)
152 {
153 int len = 0;
154 char *s1;
155
156 if (!s)
157 return 0;
158
159 s1 = s;
160
161 s += FMT_UINT16 - 1;
162 do {
163
164 ++len;
165 *--s = '0' + (u % 10);
166 u /= 10;
167
168 } while(u);
169
170 if ((format == FMT_PAD_RIGHT) || (format == FMT_JUST_LEFT)) {
171 bcopy(s, s1, len);
172 if (format == FMT_PAD_RIGHT)
173 for (; len < (FMT_UINT16 - 1); ++len)
174 s1[len] = ' ';
175 s1[len] = 0;
176 return len;
177 }
178
179 return len;
180
181 } /* fmt_uint16_t */
182
183
184
fmt_uint32(char * s,uint32_t u,int format)185 unsigned int fmt_uint32(char *s, uint32_t u, int format)
186 {
187 int len = 0;
188 char *s1;
189 int i;
190
191 if (!s)
192 return 0;
193
194 s1 = s;
195
196 s += FMT_UINT32 - 1;
197 do {
198
199 ++len;
200 *--s = '0' + (u % 10);
201 u /= 10;
202
203 } while(u);
204
205 if ((format == FMT_PAD_RIGHT) || (format == FMT_JUST_LEFT)) {
206 bcopy(s, s1, len);
207 if (format == FMT_PAD_RIGHT)
208 for (; len < (FMT_UINT32 - 1); ++len)
209 s1[len] = ' ';
210 s1[len] = 0;
211 return len;
212 }
213
214 if (format == FMT_PAD_LEFT) {
215 for (i = 0; i < ((FMT_UINT32 - 1) - len); ++i)
216 s1[i] = ' ';
217 s1[(FMT_UINT32 - 1)] = 0;
218 return (FMT_UINT32 - 1);
219 }
220
221 return 0;
222
223 } /* fmt_uint32 */
224
fmt_uint64(char * s,uint64_t u,int format)225 unsigned int fmt_uint64(char *s, uint64_t u, int format)
226 {
227 int len = 0;
228 char *s1;
229 int i;
230
231 if (!s)
232 return 0;
233
234 s1 = s;
235
236 s += FMT_UINT64 - 1;
237
238 do {
239
240 ++len;
241 *--s = '0' + (u % 10);
242 u /= 10;
243
244 } while(u);
245
246 if ((format == FMT_PAD_RIGHT) || (format == FMT_JUST_LEFT)) {
247 bcopy(s, s1, len);
248 if (format == FMT_PAD_RIGHT)
249 for (; len < (FMT_UINT64 - 1); ++len)
250 s1[len] = ' ';
251 s1[len] = 0;
252 return len;
253 }
254
255 if (format == FMT_PAD_LEFT) {
256 for (i = 0; i < ((FMT_UINT64 - 1) - len); ++i)
257 s1[i] = ' ';
258 s1[(FMT_UINT64 - 1)] = 0;
259 return (FMT_UINT64 - 1);
260 }
261
262 return 0;
263
264 } /* fmt_uint64 */
265
fmt_ipv4s(char * s,uint32_t u,int len,int format)266 unsigned int fmt_ipv4s(char *s, uint32_t u, int len,
267 int format)
268 {
269 struct sockaddr_in in;
270 struct hostent *he;
271
272 /* need at least this much */
273 if (len < FMT_IPV4) {
274 if (len > 0)
275 s[0] = 0;
276 return 0;
277 }
278
279 /* symbol lookups disabled? */
280 if (!(format & FMT_SYM))
281 return fmt_ipv4(s, u, format);
282
283 in.sin_addr.s_addr = htonl(u);
284
285 if (!(he = gethostbyaddr((char*)&in.sin_addr.s_addr,
286 sizeof (in.sin_addr.s_addr), AF_INET)))
287 return fmt_ipv4(s, u, format);
288
289 strncpy(s, he->h_name, len);
290 s[len-1] = 0;
291
292 return (strlen(s));
293
294 } /* fmt_ipv4s */
295
fmt_ipv4(char * s,uint32_t u,int format)296 unsigned int fmt_ipv4(char *s, uint32_t u, int format)
297 {
298 int len = 0;
299 char *s1;
300 int i, j;
301 uint8_t e[4];
302 char c[4][4];
303
304 if (!s)
305 return 0;
306
307 j = 0;
308
309 e[0] = (u & 0xFF000000)>>24; e[1] = (u & 0x00FF0000)>>16;
310 e[2] = (u & 0x0000FF00)>>8; e[3] = (u & 0x000000FF);
311
312 for (i = 0; i < 4; ++i) {
313 s1 = &c[i][3];
314 len = 0;
315 do {
316 ++len;
317 *--s1 = '0' + (e[i] % 10);
318 e[i] /= 10;
319 } while(e[i]);
320
321 bcopy(s1, s+j, len);
322 j += len;
323 *(s+j) = '.';
324 ++j;
325 }
326
327 --j;
328 s[j] = 0;
329
330 if (format == FMT_JUST_LEFT)
331 return j;
332
333 if (format == FMT_PAD_RIGHT) {
334 for (; j < (FMT_IPV4-1); ++j)
335 s[j] = ' ';
336 s[j] = 0;
337 return (FMT_IPV4-1);
338 }
339
340 if (format == FMT_JUST_RIGHT) {
341 bcopy(s, s+(FMT_IPV4-1)-j, j);
342 for (i = 0; i < (FMT_IPV4-1)-j; ++i)
343 s[i] = ' ';
344 s[FMT_IPV4-1] = 0;
345 return (FMT_IPV4-1);
346 }
347
348 return j;
349
350 } /* fmt_ipv4 */
351
fmt_ipv4prefixs(char * s,uint32_t u,unsigned char mask,int len,int format)352 unsigned int fmt_ipv4prefixs(char *s, uint32_t u,
353 unsigned char mask, int len, int format)
354 {
355 struct sockaddr_in in;
356 struct hostent *he;
357
358 /* need at least this much */
359 if (len < FMT_IPV4_PREFIX) {
360 if (len > 0)
361 s[0] = 0;
362 return 0;
363 }
364
365 /* symbol lookups disabled? */
366 if (!(format & FMT_SYM))
367 return fmt_ipv4prefix(s, u, mask, format);
368
369 in.sin_addr.s_addr = htonl(u & ipv4_len2mask(mask));
370
371 if (!(he = gethostbyaddr((char*)&in.sin_addr.s_addr,
372 sizeof (in.sin_addr.s_addr), AF_INET)))
373 return fmt_ipv4(s, u, format);
374
375 strncpy(s, he->h_name, len);
376 s[len-1] = 0;
377
378 return (strlen(s));
379
380 } /* int fmt_ipv4prefixs */
381
fmt_ipv4prefix(char * s,uint32_t u,unsigned char mask,int format)382 unsigned int fmt_ipv4prefix(char *s, uint32_t u,
383 unsigned char mask, int format)
384 {
385 int len = 0;
386 char *s1;
387 int i, j, k, done;
388 uint8_t e[4];
389 char c[5][4];
390
391 if (!s)
392 return 0;
393
394 j = 0;
395 done = 0;
396
397 if (mask > 32)
398 mask = 0;
399
400 e[0] = (u & 0xFF000000)>>24; e[1] = (u & 0x00FF0000)>>16;
401 e[2] = (u & 0x0000FF00)>>8; e[3] = (u & 0x000000FF);
402
403 for (i = 0; i < 4; ++i) {
404
405 s1 = &c[i][3];
406
407 /* check for last octets are all 0, make sure to encode at least one 0 */
408 if (i > 0)
409 for (done = 1, k = 1; k < 4; ++k)
410 if (e[k] != 0)
411 done = 0;
412
413 if (done)
414 break;
415
416 len = 0;
417 do {
418 ++len;
419 *--s1 = '0' + (e[i] % 10);
420 e[i] /= 10;
421 } while(e[i]);
422
423 bcopy(s1, s+j, len);
424 j += len;
425 *(s+j) = '.';
426 ++j;
427 }
428
429 /* backup over the last . and replace with / */
430 --j;
431 s[j++] = '/';
432
433 s1 = &c[4][3];
434 len = 0;
435 do {
436 ++len;
437 *--s1 = '0' + (mask % 10);
438 mask /= 10;
439 } while(mask);
440 bcopy(s1, s+j, len);
441 j += len;
442
443 s[j] = 0;
444
445 if (format == FMT_JUST_LEFT)
446 return j;
447
448 if (format == FMT_PAD_RIGHT) {
449 for (; j < (FMT_IPV4_PREFIX-1); ++j)
450 s[j] = ' ';
451 s[j] = 0;
452 return (FMT_IPV4_PREFIX-1);
453 }
454
455 if (format == FMT_JUST_RIGHT) {
456 bcopy(s, s+(FMT_IPV4_PREFIX-1)-j, j);
457 for (i = 0; i < (FMT_IPV4_PREFIX-1)-j; ++i)
458 s[i] = ' ';
459 s[FMT_IPV4_PREFIX-1] = 0;
460 return (FMT_IPV4_PREFIX-1);
461 }
462
463 return j;
464
465 } /* fmt_ipv4prefix */
466
467