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