2 * Routines for utilities to convert various other types to strings.
4 * $Id: to_str.c,v 1.4 2001/04/02 02:30:06 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
8 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
34 #ifdef NEED_SNPRINTF_H
35 # include "snprintf.h"
38 #ifdef HAVE_NETINET_IN_H
39 # include <netinet/in.h>
42 #ifdef HAVE_ARPA_INET_H
43 #include <arpa/inet.h>
46 #ifdef HAVE_SYS_SOCKET_H
47 #include <sys/socket.h>
50 #ifdef NEED_INET_V6DEFS_H
51 # include "inet_v6defs.h"
54 #ifdef HAVE_SYS_TIME_H
55 # include <sys/time.h>
65 /* Wrapper for the most common case of asking
66 * for a string using a colon as the hex-digit separator.
70 ether_to_str(const guint8 *ad)
72 return ether_to_str_punct(ad, ':');
75 /* Places char punct in the string as the hex-digit separator.
76 * If punct is '\0', no punctuation is applied (and thus
77 * the resulting string is 5 bytes shorter)
80 ether_to_str_punct(const guint8 *ad, char punct) {
81 static gchar str[3][18];
86 static const gchar hex_digits[16] = "0123456789abcdef";
88 if (cur == &str[0][0]) {
90 } else if (cur == &str[1][0]) {
100 *--p = hex_digits[octet&0xF];
102 *--p = hex_digits[octet&0xF];
113 ip_to_str(const guint8 *ad) {
114 static gchar str[3][16];
117 if (cur == &str[0][0]) {
119 } else if (cur == &str[1][0]) {
124 ip_to_str_buf(ad, cur);
129 ip_to_str_buf(const guint8 *ad, gchar *buf)
135 gboolean saw_nonzero;
149 if (saw_nonzero || digit != 0)
162 ip6_to_str(struct e_in6_addr *ad) {
163 #ifndef INET6_ADDRSTRLEN
164 #define INET6_ADDRSTRLEN 46
166 static gchar buf[INET6_ADDRSTRLEN];
168 inet_ntop(AF_INET6, (u_char*)ad, (gchar*)buf, sizeof(buf));
173 ipx_addr_to_str(guint32 net, const guint8 *ad)
175 static gchar str[3][8+1+MAXNAMELEN+1]; /* 8 digits, 1 period, NAME, 1 null */
179 if (cur == &str[0][0]) {
181 } else if (cur == &str[1][0]) {
187 name = get_ether_name_if_known(ad);
190 sprintf(cur, "%s.%s", get_ipxnet_name(net), name);
193 sprintf(cur, "%s.%s", get_ipxnet_name(net), ether_to_str_punct(ad, '\0'));
199 ipxnet_to_string(const guint8 *ad)
201 guint32 addr = pntohl(ad);
202 return ipxnet_to_str_punct(addr, ' ');
206 ipxnet_to_str_punct(const guint32 ad, char punct)
208 static gchar str[3][12];
213 static const gchar hex_digits[16] = "0123456789ABCDEF";
214 static const guint32 octet_mask[4] =
215 { 0xff000000 , 0x00ff0000, 0x0000ff00, 0x000000ff };
217 if (cur == &str[0][0]) {
219 } else if (cur == &str[1][0]) {
228 octet = (ad & octet_mask[i]) >> ((3 - i) * 8);
229 *--p = hex_digits[octet&0xF];
231 *--p = hex_digits[octet&0xF];
242 vines_addr_to_str(const guint8 *addrp)
244 static gchar str[3][214];
247 if (cur == &str[0][0]) {
249 } else if (cur == &str[1][0]) {
255 sprintf(cur, "%08x.%04x", pntohl(&addrp[0]), pntohs(&addrp[4]));
259 #define PLURALIZE(n) (((n) > 1) ? "s" : "")
260 #define COMMA(do_it) ((do_it) ? ", " : "")
263 time_secs_to_str(guint32 time)
265 static gchar str[3][8+1+4+2+2+5+2+2+7+2+2+7+1];
266 static gchar *cur, *p;
267 int hours, mins, secs;
270 if (cur == &str[0][0]) {
272 } else if (cur == &str[1][0]) {
279 sprintf(cur, "0 time");
292 sprintf(p, "%u day%s", time, PLURALIZE(time));
298 sprintf(p, "%s%u hour%s", COMMA(do_comma), hours, PLURALIZE(hours));
304 sprintf(p, "%s%u minute%s", COMMA(do_comma), mins, PLURALIZE(mins));
310 sprintf(p, "%s%u second%s", COMMA(do_comma), secs, PLURALIZE(secs));
314 static const char *mon_names[12] = {
330 abs_time_to_str(struct timeval *abs_time)
334 static char str[3][3+1+2+2+4+1+2+1+2+1+2+1+4+1 + 5 /* extra */];
336 if (cur == &str[0][0]) {
338 } else if (cur == &str[1][0]) {
344 tmp = localtime(&abs_time->tv_sec);
345 sprintf(cur, "%s %2d, %d %02d:%02d:%02d.%04ld",
346 mon_names[tmp->tm_mon],
352 (long)abs_time->tv_usec/100);
357 #define REL_TIME_LEN (1+10+1+6+1)
360 display_signed_time(gchar *buf, int buflen, gint32 sec, gint32 usec)
364 /* If the microseconds part of the time stamp is negative,
365 print its absolute value and, if the seconds part isn't
366 (the seconds part should be zero in that case), stick
367 a "-" in front of the entire time stamp. */
374 snprintf(buf, buflen, "%s%d.%06d", sign, sec, usec);
378 rel_time_to_str(struct timeval *rel_time)
381 static char str[3][REL_TIME_LEN];
383 if (cur == &str[0][0]) {
385 } else if (cur == &str[1][0]) {
391 display_signed_time(cur, REL_TIME_LEN, rel_time->tv_sec,
396 /* Generate, into "buf", a string showing the bits of a bitfield.
397 Return a pointer to the character after that string. */
399 decode_bitfield_value(char *buf, guint32 val, guint32 mask, int width)
407 bit = 1 << (width - 1);
410 /* This bit is part of the field. Show its value. */
416 /* This bit is not part of the field. */
431 /* Generate a string describing a Boolean bitfield (a one-bit field that
432 says something is either true of false). */
434 decode_boolean_bitfield(guint32 val, guint32 mask, int width,
435 const char *truedesc, const char *falsedesc)
437 static char buf[1025];
440 p = decode_bitfield_value(buf, val, mask, width);
444 strcpy(p, falsedesc);
448 /* Generate a string describing a numeric bitfield (an N-bit field whose
449 value is just a number). */
451 decode_numeric_bitfield(guint32 val, guint32 mask, int width,
454 static char buf[1025];
458 /* Compute the number of bits we have to shift the bitfield right
459 to extract its value. */
460 while ((mask & (1<<shift)) == 0)
463 p = decode_bitfield_value(buf, val, mask, width);
464 sprintf(p, fmt, (val & mask) >> shift);