aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorEd Warnicke <hagbard@physics.rutgers.edu>2001-04-01 02:47:56 +0000
committerEd Warnicke <hagbard@physics.rutgers.edu>2001-04-01 02:47:56 +0000
commitc17e3b00c6396ec52a6ca39441dabcaa97a4365d (patch)
treeaa445c8e30cfee75054eb46e14d58c1e7789ffd7 /epan
parent3b6554c069c6d607b343415f5e78794e2010d350 (diff)
Moved various to_str files from packet.{c,h} to a separate
to_str.{c,h}. Resolved strange situation where ipx_addr_to_str was declared in packet.h but defined in packet-ipx.c by moving ipx_addr_to_str, ipxnet_to_str_punct, and ipxnet_to_str from packet-ipx.{c,h} to to_str.{c,h} svn path=/trunk/; revision=3219
Diffstat (limited to 'epan')
-rw-r--r--epan/Makefile.am4
-rw-r--r--epan/packet.c324
-rw-r--r--epan/packet.h18
-rw-r--r--epan/to_str.c443
-rw-r--r--epan/to_str.h65
5 files changed, 515 insertions, 339 deletions
diff --git a/epan/Makefile.am b/epan/Makefile.am
index c7e6204c81..e6eebdb6a6 100644
--- a/epan/Makefile.am
+++ b/epan/Makefile.am
@@ -2,7 +2,7 @@
# Automake file for the EPAN library
# (Ethereal Protocol ANalyzer Library)
#
-# $Id: Makefile.am,v 1.17 2001/03/22 16:24:16 gram Exp $
+# $Id: Makefile.am,v 1.18 2001/04/01 02:47:55 hagbard Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@@ -64,6 +64,8 @@ libethereal_a_SOURCES = \
sna-utils.h \
strutil.c \
strutil.h \
+ to_str.c \
+ to_str.h \
tvbuff.c \
tvbuff.h
diff --git a/epan/packet.c b/epan/packet.c
index bbb4f4c61d..7cf1872d0f 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -1,7 +1,7 @@
/* packet.c
* Routines for packet disassembly
*
- * $Id: packet.c,v 1.24 2001/03/31 23:02:31 hagbard Exp $
+ * $Id: packet.c,v 1.25 2001/04/01 02:47:55 hagbard Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -77,15 +77,12 @@
#include "sna-utils.h"
#include "packet-vines.h"
#include "packet-osi.h"
+#include "to_str.h"
#include "resolv.h"
#include "tvbuff.h"
#include "plugins.h"
-static void display_signed_time(gchar *, int, gint32, gint32);
-
-
-
/* Protocol-specific data attached to a frame_data structure - protocol
index and opaque pointer. */
typedef struct _frame_proto_data {
@@ -130,251 +127,6 @@ packet_cleanup(void)
/* nothing */
}
-/* Wrapper for the most common case of asking
- * for a string using a colon as the hex-digit separator.
- */
-gchar *
-ether_to_str(const guint8 *ad)
-{
- return ether_to_str_punct(ad, ':');
-}
-
-/* Places char punct in the string as the hex-digit separator.
- * If punct is '\0', no punctuation is applied (and thus
- * the resulting string is 5 bytes shorter)
- */
-gchar *
-ether_to_str_punct(const guint8 *ad, char punct) {
- static gchar str[3][18];
- static gchar *cur;
- gchar *p;
- int i;
- guint32 octet;
- static const gchar hex_digits[16] = "0123456789abcdef";
-
- if (cur == &str[0][0]) {
- cur = &str[1][0];
- } else if (cur == &str[1][0]) {
- cur = &str[2][0];
- } else {
- cur = &str[0][0];
- }
- p = &cur[18];
- *--p = '\0';
- i = 5;
- for (;;) {
- octet = ad[i];
- *--p = hex_digits[octet&0xF];
- octet >>= 4;
- *--p = hex_digits[octet&0xF];
- if (i == 0)
- break;
- if (punct)
- *--p = punct;
- i--;
- }
- return p;
-}
-
-gchar *
-ip_to_str(const guint8 *ad) {
- static gchar str[3][16];
- static gchar *cur;
-
- if (cur == &str[0][0]) {
- cur = &str[1][0];
- } else if (cur == &str[1][0]) {
- cur = &str[2][0];
- } else {
- cur = &str[0][0];
- }
- ip_to_str_buf(ad, cur);
- return cur;
-}
-
-void
-ip_to_str_buf(const guint8 *ad, gchar *buf)
-{
- gchar *p;
- int i;
- guint32 octet;
- guint32 digit;
- gboolean saw_nonzero;
-
- p = buf;
- i = 0;
- for (;;) {
- saw_nonzero = FALSE;
- octet = ad[i];
- digit = octet/100;
- if (digit != 0) {
- *p++ = digit + '0';
- saw_nonzero = TRUE;
- }
- octet %= 100;
- digit = octet/10;
- if (saw_nonzero || digit != 0)
- *p++ = digit + '0';
- digit = octet%10;
- *p++ = digit + '0';
- if (i == 3)
- break;
- *p++ = '.';
- i++;
- }
- *p = '\0';
-}
-
-gchar *
-ip6_to_str(struct e_in6_addr *ad) {
-#ifndef INET6_ADDRSTRLEN
-#define INET6_ADDRSTRLEN 46
-#endif
- static gchar buf[INET6_ADDRSTRLEN];
-
- inet_ntop(AF_INET6, (u_char*)ad, (gchar*)buf, sizeof(buf));
- return buf;
-}
-
-
-#define PLURALIZE(n) (((n) > 1) ? "s" : "")
-#define COMMA(do_it) ((do_it) ? ", " : "")
-
-gchar *
-time_secs_to_str(guint32 time)
-{
- static gchar str[3][8+1+4+2+2+5+2+2+7+2+2+7+1];
- static gchar *cur, *p;
- int hours, mins, secs;
- int do_comma;
-
- if (cur == &str[0][0]) {
- cur = &str[1][0];
- } else if (cur == &str[1][0]) {
- cur = &str[2][0];
- } else {
- cur = &str[0][0];
- }
-
- if (time == 0) {
- sprintf(cur, "0 time");
- return cur;
- }
-
- secs = time % 60;
- time /= 60;
- mins = time % 60;
- time /= 60;
- hours = time % 24;
- time /= 24;
-
- p = cur;
- if (time != 0) {
- sprintf(p, "%u day%s", time, PLURALIZE(time));
- p += strlen(p);
- do_comma = 1;
- } else
- do_comma = 0;
- if (hours != 0) {
- sprintf(p, "%s%u hour%s", COMMA(do_comma), hours, PLURALIZE(hours));
- p += strlen(p);
- do_comma = 1;
- } else
- do_comma = 0;
- if (mins != 0) {
- sprintf(p, "%s%u minute%s", COMMA(do_comma), mins, PLURALIZE(mins));
- p += strlen(p);
- do_comma = 1;
- } else
- do_comma = 0;
- if (secs != 0)
- sprintf(p, "%s%u second%s", COMMA(do_comma), secs, PLURALIZE(secs));
- return cur;
-}
-
-static const char *mon_names[12] = {
- "Jan",
- "Feb",
- "Mar",
- "Apr",
- "May",
- "Jun",
- "Jul",
- "Aug",
- "Sep",
- "Oct",
- "Nov",
- "Dec"
-};
-
-gchar *
-abs_time_to_str(struct timeval *abs_time)
-{
- struct tm *tmp;
- static gchar *cur;
- static char str[3][3+1+2+2+4+1+2+1+2+1+2+1+4+1 + 5 /* extra */];
-
- if (cur == &str[0][0]) {
- cur = &str[1][0];
- } else if (cur == &str[1][0]) {
- cur = &str[2][0];
- } else {
- cur = &str[0][0];
- }
-
- tmp = localtime(&abs_time->tv_sec);
- sprintf(cur, "%s %2d, %d %02d:%02d:%02d.%04ld",
- mon_names[tmp->tm_mon],
- tmp->tm_mday,
- tmp->tm_year + 1900,
- tmp->tm_hour,
- tmp->tm_min,
- tmp->tm_sec,
- (long)abs_time->tv_usec/100);
-
- return cur;
-}
-
-#define REL_TIME_LEN (1+10+1+6+1)
-
-gchar *
-rel_time_to_str(struct timeval *rel_time)
-{
- static gchar *cur;
- static char str[3][REL_TIME_LEN];
-
- if (cur == &str[0][0]) {
- cur = &str[1][0];
- } else if (cur == &str[1][0]) {
- cur = &str[2][0];
- } else {
- cur = &str[0][0];
- }
-
- display_signed_time(cur, REL_TIME_LEN, rel_time->tv_sec,
- rel_time->tv_usec);
- return cur;
-}
-
-static void
-display_signed_time(gchar *buf, int buflen, gint32 sec, gint32 usec)
-{
- char *sign;
-
- /* If the microseconds part of the time stamp is negative,
- print its absolute value and, if the seconds part isn't
- (the seconds part should be zero in that case), stick
- a "-" in front of the entire time stamp. */
- sign = "";
- if (usec < 0) {
- usec = -usec;
- if (sec >= 0)
- sign = "-";
- }
- snprintf(buf, buflen, "%s%d.%06d", sign, sec, usec);
-}
-
-
/* Tries to match val against each element in the value_string array vs.
Returns the associated string ptr on a match.
Formats val with fmt, and returns the resulting string, on failure. */
@@ -413,58 +165,6 @@ match_strval(guint32 val, const value_string *vs) {
return(NULL);
}
-/* Generate, into "buf", a string showing the bits of a bitfield.
- Return a pointer to the character after that string. */
-char *
-decode_bitfield_value(char *buf, guint32 val, guint32 mask, int width)
-{
- int i;
- guint32 bit;
- char *p;
-
- i = 0;
- p = buf;
- bit = 1 << (width - 1);
- for (;;) {
- if (mask & bit) {
- /* This bit is part of the field. Show its value. */
- if (val & bit)
- *p++ = '1';
- else
- *p++ = '0';
- } else {
- /* This bit is not part of the field. */
- *p++ = '.';
- }
- bit >>= 1;
- i++;
- if (i >= width)
- break;
- if (i % 4 == 0)
- *p++ = ' ';
- }
- strcpy(p, " = ");
- p += 3;
- return p;
-}
-
-/* Generate a string describing a Boolean bitfield (a one-bit field that
- says something is either true of false). */
-const char *
-decode_boolean_bitfield(guint32 val, guint32 mask, int width,
- const char *truedesc, const char *falsedesc)
-{
- static char buf[1025];
- char *p;
-
- p = decode_bitfield_value(buf, val, mask, width);
- if (val & mask)
- strcpy(p, truedesc);
- else
- strcpy(p, falsedesc);
- return buf;
-}
-
/* Generate a string describing an enumerated bitfield (an N-bit field
with various specific values having particular names). */
const char *
@@ -479,26 +179,6 @@ decode_enumerated_bitfield(guint32 val, guint32 mask, int width,
return buf;
}
-/* Generate a string describing a numeric bitfield (an N-bit field whose
- value is just a number). */
-const char *
-decode_numeric_bitfield(guint32 val, guint32 mask, int width,
- const char *fmt)
-{
- static char buf[1025];
- char *p;
- int shift = 0;
-
- /* Compute the number of bits we have to shift the bitfield right
- to extract its value. */
- while ((mask & (1<<shift)) == 0)
- shift++;
-
- p = decode_bitfield_value(buf, val, mask, width);
- sprintf(p, fmt, (val & mask) >> shift);
- return buf;
-}
-
/* Allocate all the data structures for constructing column data, given
the number of columns. */
void
diff --git a/epan/packet.h b/epan/packet.h
index 7a8882c4d0..7b7fb84fee 100644
--- a/epan/packet.h
+++ b/epan/packet.h
@@ -1,7 +1,7 @@
/* packet.h
* Definitions for packet disassembly structures and routines
*
- * $Id: packet.h,v 1.24 2001/03/23 14:44:01 jfoster Exp $
+ * $Id: packet.h,v 1.25 2001/04/01 02:47:55 hagbard Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -31,6 +31,7 @@
#include "proto.h"
#include "tvbuff.h"
#include "pint.h"
+#include "to_str.h"
#define hi_nibble(b) (((b) & 0xf0) >> 4)
#define lo_nibble(b) ((b) & 0x0f)
@@ -327,25 +328,10 @@ void call_dissector(dissector_handle_t handle, tvbuff_t *tvb,
packet_info *pinfo, proto_tree *tree);
/* Utility routines used by packet*.c */
-gchar* ether_to_str(const guint8 *);
-gchar* ether_to_str_punct(const guint8 *, char);
-gchar* ip_to_str(const guint8 *);
-void ip_to_str_buf(const guint8 *, gchar *);
-struct e_in6_addr;
-gchar* ip6_to_str(struct e_in6_addr *);
-gchar* ipx_addr_to_str(guint32, const guint8 *);
-gchar* abs_time_to_str(struct timeval*);
-gchar* rel_time_to_str(struct timeval*);
-gchar* time_secs_to_str(guint32);
gchar* val_to_str(guint32, const value_string *, const char *);
gchar* match_strval(guint32, const value_string*);
-char * decode_bitfield_value(char *buf, guint32 val, guint32 mask, int width);
-const char *decode_boolean_bitfield(guint32 val, guint32 mask, int width,
- const char *truedesc, const char *falsedesc);
const char *decode_enumerated_bitfield(guint32 val, guint32 mask, int width,
const value_string *tab, const char *fmt);
-const char *decode_numeric_bitfield(guint32 val, guint32 mask, int width,
- const char *fmt);
void col_set_writable(frame_data *fd, gboolean writable);
gint check_col(frame_data *, gint);
diff --git a/epan/to_str.c b/epan/to_str.c
new file mode 100644
index 0000000000..111a06265a
--- /dev/null
+++ b/epan/to_str.c
@@ -0,0 +1,443 @@
+/* to_str.h
+ * Routines for utilities to convert various other types to strings.
+ *
+ * $Id: to_str.c,v 1.1 2001/04/01 02:47:55 hagbard Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * Copyright 1998 Gerald Combs
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef NEED_SNPRINTF_H
+# include "snprintf.h"
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef NEED_INET_V6DEFS_H
+# include "inet_v6defs.h"
+#endif
+
+#include "to_str.h"
+#include "resolv.h"
+#include "pint.h"
+#include <stdio.h>
+#include <time.h>
+
+/* Wrapper for the most common case of asking
+ * for a string using a colon as the hex-digit separator.
+ */
+
+gchar *
+ether_to_str(const guint8 *ad)
+{
+ return ether_to_str_punct(ad, ':');
+}
+
+/* Places char punct in the string as the hex-digit separator.
+ * If punct is '\0', no punctuation is applied (and thus
+ * the resulting string is 5 bytes shorter)
+ */
+gchar *
+ether_to_str_punct(const guint8 *ad, char punct) {
+ static gchar str[3][18];
+ static gchar *cur;
+ gchar *p;
+ int i;
+ guint32 octet;
+ static const gchar hex_digits[16] = "0123456789abcdef";
+
+ if (cur == &str[0][0]) {
+ cur = &str[1][0];
+ } else if (cur == &str[1][0]) {
+ cur = &str[2][0];
+ } else {
+ cur = &str[0][0];
+ }
+ p = &cur[18];
+ *--p = '\0';
+ i = 5;
+ for (;;) {
+ octet = ad[i];
+ *--p = hex_digits[octet&0xF];
+ octet >>= 4;
+ *--p = hex_digits[octet&0xF];
+ if (i == 0)
+ break;
+ if (punct)
+ *--p = punct;
+ i--;
+ }
+ return p;
+}
+
+gchar *
+ip_to_str(const guint8 *ad) {
+ static gchar str[3][16];
+ static gchar *cur;
+
+ if (cur == &str[0][0]) {
+ cur = &str[1][0];
+ } else if (cur == &str[1][0]) {
+ cur = &str[2][0];
+ } else {
+ cur = &str[0][0];
+ }
+ ip_to_str_buf(ad, cur);
+ return cur;
+}
+
+void
+ip_to_str_buf(const guint8 *ad, gchar *buf)
+{
+ gchar *p;
+ int i;
+ guint32 octet;
+ guint32 digit;
+ gboolean saw_nonzero;
+
+ p = buf;
+ i = 0;
+ for (;;) {
+ saw_nonzero = FALSE;
+ octet = ad[i];
+ digit = octet/100;
+ if (digit != 0) {
+ *p++ = digit + '0';
+ saw_nonzero = TRUE;
+ }
+ octet %= 100;
+ digit = octet/10;
+ if (saw_nonzero || digit != 0)
+ *p++ = digit + '0';
+ digit = octet%10;
+ *p++ = digit + '0';
+ if (i == 3)
+ break;
+ *p++ = '.';
+ i++;
+ }
+ *p = '\0';
+}
+
+gchar *
+ip6_to_str(struct e_in6_addr *ad) {
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+ static gchar buf[INET6_ADDRSTRLEN];
+
+ inet_ntop(AF_INET6, (u_char*)ad, (gchar*)buf, sizeof(buf));
+ return buf;
+}
+
+gchar*
+ipx_addr_to_str(guint32 net, const guint8 *ad)
+{
+ static gchar str[3][8+1+MAXNAMELEN+1]; /* 8 digits, 1 period, NAME, 1 null */
+ static gchar *cur;
+ char *name;
+
+ if (cur == &str[0][0]) {
+ cur = &str[1][0];
+ } else if (cur == &str[1][0]) {
+ cur = &str[2][0];
+ } else {
+ cur = &str[0][0];
+ }
+
+ name = get_ether_name_if_known(ad);
+
+ if (name) {
+ sprintf(cur, "%s.%s", get_ipxnet_name(net), name);
+ }
+ else {
+ sprintf(cur, "%s.%s", get_ipxnet_name(net), ether_to_str_punct(ad, '\0'));
+ }
+ return cur;
+}
+
+gchar*
+ipxnet_to_string(const guint8 *ad)
+{
+ guint32 addr = pntohl(ad);
+ return ipxnet_to_str_punct(addr, ' ');
+}
+
+gchar *
+ipxnet_to_str_punct(const guint32 ad, char punct)
+{
+ static gchar str[3][12];
+ static gchar *cur;
+ gchar *p;
+ int i;
+ guint32 octet;
+ static const gchar hex_digits[16] = "0123456789ABCDEF";
+ static const guint32 octet_mask[4] =
+ { 0xff000000 , 0x00ff0000, 0x0000ff00, 0x000000ff };
+
+ if (cur == &str[0][0]) {
+ cur = &str[1][0];
+ } else if (cur == &str[1][0]) {
+ cur = &str[2][0];
+ } else {
+ cur = &str[0][0];
+ }
+ p = &cur[12];
+ *--p = '\0';
+ i = 3;
+ for (;;) {
+ octet = (ad & octet_mask[i]) >> ((3 - i) * 8);
+ *--p = hex_digits[octet&0xF];
+ octet >>= 4;
+ *--p = hex_digits[octet&0xF];
+ if (i == 0)
+ break;
+ if (punct)
+ *--p = punct;
+ i--;
+ }
+ return p;
+}
+
+
+#define PLURALIZE(n) (((n) > 1) ? "s" : "")
+#define COMMA(do_it) ((do_it) ? ", " : "")
+
+gchar *
+time_secs_to_str(guint32 time)
+{
+ static gchar str[3][8+1+4+2+2+5+2+2+7+2+2+7+1];
+ static gchar *cur, *p;
+ int hours, mins, secs;
+ int do_comma;
+
+ if (cur == &str[0][0]) {
+ cur = &str[1][0];
+ } else if (cur == &str[1][0]) {
+ cur = &str[2][0];
+ } else {
+ cur = &str[0][0];
+ }
+
+ if (time == 0) {
+ sprintf(cur, "0 time");
+ return cur;
+ }
+
+ secs = time % 60;
+ time /= 60;
+ mins = time % 60;
+ time /= 60;
+ hours = time % 24;
+ time /= 24;
+
+ p = cur;
+ if (time != 0) {
+ sprintf(p, "%u day%s", time, PLURALIZE(time));
+ p += strlen(p);
+ do_comma = 1;
+ } else
+ do_comma = 0;
+ if (hours != 0) {
+ sprintf(p, "%s%u hour%s", COMMA(do_comma), hours, PLURALIZE(hours));
+ p += strlen(p);
+ do_comma = 1;
+ } else
+ do_comma = 0;
+ if (mins != 0) {
+ sprintf(p, "%s%u minute%s", COMMA(do_comma), mins, PLURALIZE(mins));
+ p += strlen(p);
+ do_comma = 1;
+ } else
+ do_comma = 0;
+ if (secs != 0)
+ sprintf(p, "%s%u second%s", COMMA(do_comma), secs, PLURALIZE(secs));
+ return cur;
+}
+
+static const char *mon_names[12] = {
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+};
+
+gchar *
+abs_time_to_str(struct timeval *abs_time)
+{
+ struct tm *tmp;
+ static gchar *cur;
+ static char str[3][3+1+2+2+4+1+2+1+2+1+2+1+4+1 + 5 /* extra */];
+
+ if (cur == &str[0][0]) {
+ cur = &str[1][0];
+ } else if (cur == &str[1][0]) {
+ cur = &str[2][0];
+ } else {
+ cur = &str[0][0];
+ }
+
+ tmp = localtime(&abs_time->tv_sec);
+ sprintf(cur, "%s %2d, %d %02d:%02d:%02d.%04ld",
+ mon_names[tmp->tm_mon],
+ tmp->tm_mday,
+ tmp->tm_year + 1900,
+ tmp->tm_hour,
+ tmp->tm_min,
+ tmp->tm_sec,
+ (long)abs_time->tv_usec/100);
+
+ return cur;
+}
+
+#define REL_TIME_LEN (1+10+1+6+1)
+
+void
+display_signed_time(gchar *buf, int buflen, gint32 sec, gint32 usec)
+{
+ char *sign;
+
+ /* If the microseconds part of the time stamp is negative,
+ print its absolute value and, if the seconds part isn't
+ (the seconds part should be zero in that case), stick
+ a "-" in front of the entire time stamp. */
+ sign = "";
+ if (usec < 0) {
+ usec = -usec;
+ if (sec >= 0)
+ sign = "-";
+ }
+ snprintf(buf, buflen, "%s%d.%06d", sign, sec, usec);
+}
+
+gchar *
+rel_time_to_str(struct timeval *rel_time)
+{
+ static gchar *cur;
+ static char str[3][REL_TIME_LEN];
+
+ if (cur == &str[0][0]) {
+ cur = &str[1][0];
+ } else if (cur == &str[1][0]) {
+ cur = &str[2][0];
+ } else {
+ cur = &str[0][0];
+ }
+
+ display_signed_time(cur, REL_TIME_LEN, rel_time->tv_sec,
+ rel_time->tv_usec);
+ return cur;
+}
+
+/* Generate, into "buf", a string showing the bits of a bitfield.
+ Return a pointer to the character after that string. */
+char *
+decode_bitfield_value(char *buf, guint32 val, guint32 mask, int width)
+{
+ int i;
+ guint32 bit;
+ char *p;
+
+ i = 0;
+ p = buf;
+ bit = 1 << (width - 1);
+ for (;;) {
+ if (mask & bit) {
+ /* This bit is part of the field. Show its value. */
+ if (val & bit)
+ *p++ = '1';
+ else
+ *p++ = '0';
+ } else {
+ /* This bit is not part of the field. */
+ *p++ = '.';
+ }
+ bit >>= 1;
+ i++;
+ if (i >= width)
+ break;
+ if (i % 4 == 0)
+ *p++ = ' ';
+ }
+ strcpy(p, " = ");
+ p += 3;
+ return p;
+}
+
+/* Generate a string describing a Boolean bitfield (a one-bit field that
+ says something is either true of false). */
+const char *
+decode_boolean_bitfield(guint32 val, guint32 mask, int width,
+ const char *truedesc, const char *falsedesc)
+{
+ static char buf[1025];
+ char *p;
+
+ p = decode_bitfield_value(buf, val, mask, width);
+ if (val & mask)
+ strcpy(p, truedesc);
+ else
+ strcpy(p, falsedesc);
+ return buf;
+}
+
+/* Generate a string describing a numeric bitfield (an N-bit field whose
+ value is just a number). */
+const char *
+decode_numeric_bitfield(guint32 val, guint32 mask, int width,
+ const char *fmt)
+{
+ static char buf[1025];
+ char *p;
+ int shift = 0;
+
+ /* Compute the number of bits we have to shift the bitfield right
+ to extract its value. */
+ while ((mask & (1<<shift)) == 0)
+ shift++;
+
+ p = decode_bitfield_value(buf, val, mask, width);
+ sprintf(p, fmt, (val & mask) >> shift);
+ return buf;
+}
+
+
+
diff --git a/epan/to_str.h b/epan/to_str.h
new file mode 100644
index 0000000000..a9fcbb8cf2
--- /dev/null
+++ b/epan/to_str.h
@@ -0,0 +1,65 @@
+/* to_str.h
+ * Definitions for utilities to convert various other types to strings.
+ *
+ * $Id: to_str.h,v 1.1 2001/04/01 02:47:56 hagbard Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * Copyright 1998 Gerald Combs
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __TO_STR_H__
+#define __TO_STR_H__
+
+#include "glib.h"
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+
+/*
+ * These are utility functions which convert various types to strings,
+ * but for which no more specific module applies.
+ */
+
+gchar* ether_to_str(const guint8 *);
+gchar* ether_to_str_punct(const guint8 *, char);
+gchar* ip_to_str(const guint8 *);
+void ip_to_str_buf(const guint8 *, gchar *);
+struct e_in6_addr;
+gchar* ip6_to_str(struct e_in6_addr *);
+gchar* ipx_addr_to_str(guint32, const guint8 *);
+gchar* ipxnet_to_string(const guint8 *ad);
+gchar* ipxnet_to_str_punct(const guint32 ad, char punct);
+gchar* time_secs_to_str(guint32);
+gchar* abs_time_to_str(struct timeval*);
+void display_signed_time(gchar *, int, gint32, gint32);
+gchar* rel_time_to_str(struct timeval*);
+
+
+char * decode_bitfield_value(char *buf, guint32 val, guint32 mask, int width);
+const char *decode_boolean_bitfield(guint32 val, guint32 mask, int width,
+ const char *truedesc, const char *falsedesc);
+const char *decode_numeric_bitfield(guint32 val, guint32 mask, int width,
+ const char *fmt);
+
+#endif /* __TO_STR_H__ */