#include <epan/guid-utils.h>
#include "exceptions.h"
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
/** @file
* "testy, virtual(-izable) buffer". They are testy in that they get mad when
* an attempt is made to access data beyond the bounds of their array. In that
* case, they throw an exception.
- *
- * They are virtualizable in that new tvbuff's can be made from other tvbuffs,
- * while only the original tvbuff may have data. That is, the new tvbuff has
+ *
+ * They are virtualizable in that new tvbuff's can be made from other tvbuffs,
+ * while only the original tvbuff may have data. That is, the new tvbuff has
* virtual data.
*/
-
/** The different types of tvbuff's */
typedef enum {
TVBUFF_REAL_DATA,
TVBUFF_COMPOSITE
} tvbuff_type;
-typedef struct {
- /* The backing tvbuff_t */
- struct tvbuff *tvb;
-
- /* The offset/length of 'tvb' to which I'm privy */
- guint offset;
- guint length;
-
-} tvb_backing_t;
-
-typedef struct {
- GSList *tvbs;
-
- /* Used for quick testing to see if this
- * is the tvbuff that a COMPOSITE is
- * interested in. */
- guint *start_offsets;
- guint *end_offsets;
-
-} tvb_comp_t;
-
-typedef void (*tvbuff_free_cb_t)(void*);
-
-typedef struct tvbuff {
- /* Record-keeping */
- tvbuff_type type;
- gboolean initialized;
- guint usage_count;
- struct tvbuff *ds_tvb; /* data source top-level tvbuff */
-
- /* The tvbuffs in which this tvbuff is a member
- * (that is, a backing tvbuff for a TVBUFF_SUBSET
- * or a member for a TVB_COMPOSITE) */
- GSList *used_in;
-
- /* TVBUFF_SUBSET and TVBUFF_COMPOSITE keep track
- * of the other tvbuff's they use */
- union {
- tvb_backing_t subset;
- tvb_comp_t composite;
- } tvbuffs;
-
- /* We're either a TVBUFF_REAL_DATA or a
- * TVBUFF_SUBSET that has a backing buffer that
- * has real_data != NULL, or a TVBUFF_COMPOSITE
- * which has flattened its data due to a call
- * to tvb_get_ptr().
- */
- const guint8 *real_data;
-
- /* Length of virtual buffer (and/or real_data). */
- guint length;
-
- /* Reported length. */
- guint reported_length;
-
- /* Offset from beginning of first TVBUFF_REAL. */
- gint raw_offset;
-
- /* Func to call when actually freed */
- tvbuff_free_cb_t free_cb;
-} tvbuff_t;
-
+struct tvbuff;
+typedef struct tvbuff tvbuff_t;
+/**
+ * tvbuffs: dissector use and management
+ *
+ * Consider a collection of tvbs as being a chain or stack of tvbs.
+ *
+ * The top-level dissector (packet.c) pushes the initial tvb onto the stack
+ * (starts the chain) and then calls a sub-dissector which in turn calls the next
+ * sub-dissector and so on. Each sub-dissector may chain additional tvbs to
+ * the tvb handed to that dissector. After dissection is complete and control has
+ * returned to the top-level dissector, the chain of tvbs (stack) is free'd
+ * via a call to tvb_free_chain() (in epan_dissect_cleanup()).
+ *
+ * A dissector:
+ * - Can chain new tvbs (real, subset, composite) to the tvb
+ * handed to the dissector via tvb_subset(), tvb_new_child_real_data(), etc.
+ * (Subset and Composite tvbs should reference only tvbs which are
+ * already part of the chain).
+ * - Must not save a pointer to a tvb handed to the dissector for
+ * use when dissecting another frame; A higher level function
+ * may very well free the chain). This also applies to any tvbs chained
+ * by the dissector to the tvb handed to the dissector.
+ * - Can create its own tvb chain (using tvb_new_real_data() which
+ * the dissector is free to manage as desired. */
/** TVBUFF_REAL_DATA contains a guint8* that points to real data.
* The data is allocated and contiguous.
* Once a tvbuff is create/initialized/finalized, the tvbuff is read-only.
* That is, it cannot point to any other data. A new tvbuff must be created if
* you want a tvbuff that points to other data.
+ *
+ * tvbuff's are normally chained together to allow efficient de-allocation of tvbuff's.
+ *
*/
-
-/** "class" initialization. Called once during execution of program
- * so that tvbuff.c can initialize its data. */
-extern void tvbuff_init(void);
-
-/** "class" cleanup. Called once during execution of program
- * so that tvbuff.c can clean up its data. */
-extern void tvbuff_cleanup(void);
-
+typedef void (*tvbuff_free_cb_t)(void*);
/** Returns a pointer to a newly initialized tvbuff. Note that
* tvbuff's of types TVBUFF_SUBSET and TVBUFF_COMPOSITE
- * require further initialization via the appropriate functions */
+ * require further initialization via the appropriate functions. */
extern tvbuff_t* tvb_new(tvbuff_type);
-/** Marks a tvbuff for freeing. The guint8* data of a TVBUFF_REAL_DATA
- * is *never* freed by the tvbuff routines. The tvbuff itself is actually freed
- * once its usage count drops to 0.
- *
- * Usage counts increment for any time the tvbuff is
- * used as a member of another tvbuff, i.e., as the backing buffer for
- * a TVBUFF_SUBSET or as a member of a TVBUFF_COMPOSITE.
- *
- * Although you may call tvb_free(), the tvbuff may still be in use
- * by other tvbuff's (TVBUFF_SUBSET or TVBUFF_COMPOSITE), so it is not
- * safe, unless you know otherwise, to free your guint8* data. If you
- * cannot be sure that your TVBUFF_REAL_DATA is not in use by another
- * tvbuff, register a callback with tvb_set_free_cb(); when your tvbuff
- * is _really_ freed, then your callback will be called, and at that time
- * you can free your original data.
- *
- * The caller can artificially increment/decrement the usage count
- * with tvbuff_increment_usage_count()/tvbuff_decrement_usage_count().
+/** Extracts 'number of bits' starting at 'bit offset'.
+ * Returns a pointer to a newly initialized ep_alloc'd REAL_DATA
+ * tvbuff with the bits octet aligned.
*/
+extern tvbuff_t* tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits);
+
+/** Free a tvbuff_t and all tvbuffs chained from it
+ * The tvbuff must be 'the 'head' (initial) tvb of a chain or
+ * must not be in a chain.
+ * If specified, a callback to free the tvbuff data will be invoked
+ * for each tvbuff free'd */
extern void tvb_free(tvbuff_t*);
-/** Free the tvbuff_t and all tvbuff's created from it. */
+/** Free the tvbuff_t and all tvbuffs chained from it.
+ * The tvbuff must be 'the 'head' (initial) tvb of a chain or
+ * must not be in a chain.
+ * If specified, a callback to free the tvbuff data will be invoked
+ * for each tvbuff free'd */
extern void tvb_free_chain(tvbuff_t*);
-/** Both return the new usage count, after the increment or decrement */
-extern guint tvb_increment_usage_count(tvbuff_t*, guint count);
-
-/** If a decrement causes the usage count to drop to 0, a the tvbuff
- * is immediately freed. Be sure you know exactly what you're doing
- * if you decide to use this function, as another tvbuff could
- * still have a pointer to the just-freed tvbuff, causing corrupted data
- * or a segfault in the future */
-extern guint tvb_decrement_usage_count(tvbuff_t*, guint count);
-
/** Set a callback function to call when a tvbuff is actually freed
- * (once the usage count drops to 0). One argument is passed to
- * that callback --- a void* that points to the real data.
- * Obviously, this only applies to a TVBUFF_REAL_DATA tvbuff. */
-extern void tvb_set_free_cb(tvbuff_t*, tvbuff_free_cb_t);
-
+ * One argument is passed to that callback --- a void* that points
+ * to the real data. Obviously, this only applies to a
+ * TVBUFF_REAL_DATA tvbuff. */
+extern void tvb_set_free_cb(tvbuff_t*, const tvbuff_free_cb_t);
/** Attach a TVBUFF_REAL_DATA tvbuff to a parent tvbuff. This connection
* is used during a tvb_free_chain()... the "child" TVBUFF_REAL_DATA acts
* run some operation on it, like decryption or decompression, and make a new
* tvbuff from it, yet want the new tvbuff to be part of the chain. The reality
* is that the new tvbuff *is* part of the "chain of creation", but in a way
- * that these tvbuff routines is ignorant of. Use this function to make
+ * that these tvbuff routines are ignorant of. Use this function to make
* the tvbuff routines knowledgable of this fact. */
extern void tvb_set_child_real_data_tvbuff(tvbuff_t* parent, tvbuff_t* child);
-extern tvbuff_t* tvb_new_child_real_data(tvbuff_t* parent, const guint8* data, guint length,
- gint reported_length);
-
-/**Sets parameters for TVBUFF_REAL_DATA. Can throw ReportedBoundsError. */
-extern void tvb_set_real_data(tvbuff_t*, const guint8* data, guint length,
- gint reported_length);
+extern tvbuff_t* tvb_new_child_real_data(tvbuff_t* parent, const guint8* data, const guint length,
+ const gint reported_length);
-/** Combination of tvb_new() and tvb_set_real_data(). Can throw ReportedBoundsError. */
-extern tvbuff_t* tvb_new_real_data(const guint8* data, guint length,
- gint reported_length);
+/** Sets parameters for TVBUFF_REAL_DATA. Can throw ReportedBoundsError. */
+extern void tvb_set_real_data(tvbuff_t*, const guint8* data, const guint length,
+ const gint reported_length);
+/** Combination of tvb_new() and tvb_set_real_data(). Can throw ReportedBoundsError.
+ * Normally, a callback to free the data should be registered using tvb_set_free_cb();
+ * when this tvbuff is freed, then your callback will be called, and at that time
+ * you can free your original data. */
+extern tvbuff_t* tvb_new_real_data(const guint8* data, const guint length,
+ const gint reported_length);
/** Define the subset of the backing buffer to use.
*
* is beyond the bounds of the backing tvbuff.
* Can throw ReportedBoundsError. */
extern void tvb_set_subset(tvbuff_t* tvb, tvbuff_t* backing,
- gint backing_offset, gint backing_length, gint reported_length);
+ const gint backing_offset, const gint backing_length, const gint reported_length);
/** Combination of tvb_new() and tvb_set_subset()
* Can throw ReportedBoundsError. */
extern tvbuff_t* tvb_new_subset(tvbuff_t* backing,
- gint backing_offset, gint backing_length, gint reported_length);
+ const gint backing_offset, const gint backing_length, const gint reported_length);
+/** Similar to tvb_new_subset() but with backing_length and reported_length set to -1.
+ * Can throw ReportedBoundsError. */
+extern tvbuff_t* tvb_new_subset_remaining(tvbuff_t* backing,
+ const gint backing_offset);
/** Both tvb_composite_append and tvb_composite_prepend can throw
* BoundsError if member_offset/member_length goes beyond bounds of
/* Get total length of buffer */
-extern guint tvb_length(tvbuff_t*);
+extern guint tvb_length(const tvbuff_t*);
/** Computes bytes to end of buffer, from offset (which can be negative,
* to indicate bytes from end of buffer). Function returns -1 to
* indicate that offset is out of bounds. No exception is thrown. */
-extern gint tvb_length_remaining(tvbuff_t*, gint offset);
+extern gint tvb_length_remaining(const tvbuff_t*, const gint offset);
/** Same as above, but throws an exception if the offset is out of bounds. */
-extern guint tvb_ensure_length_remaining(tvbuff_t*, gint offset);
+extern guint tvb_ensure_length_remaining(const tvbuff_t*, const gint offset);
/* Checks (w/o throwing exception) that the bytes referred to by
* 'offset'/'length' actually exist in the buffer */
-extern gboolean tvb_bytes_exist(tvbuff_t*, gint offset, gint length);
+extern gboolean tvb_bytes_exist(const tvbuff_t*, const gint offset, const gint length);
/** Checks that the bytes referred to by 'offset'/'length' actually exist
* in the buffer, and throws an exception if they aren't. */
-extern void tvb_ensure_bytes_exist(tvbuff_t *tvb, gint offset, gint length);
+extern void tvb_ensure_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length);
/* Checks (w/o throwing exception) that offset exists in buffer */
-extern gboolean tvb_offset_exists(tvbuff_t*, gint offset);
+extern gboolean tvb_offset_exists(const tvbuff_t*, const gint offset);
/* Get reported length of buffer */
-extern guint tvb_reported_length(tvbuff_t*);
+extern guint tvb_reported_length(const tvbuff_t*);
/** Computes bytes of reported packet data to end of buffer, from offset
* (which can be negative, to indicate bytes from end of buffer). Function
* returns -1 to indicate that offset is out of bounds. No exception is
* thrown. */
-extern gint tvb_reported_length_remaining(tvbuff_t *tvb, gint offset);
+extern gint tvb_reported_length_remaining(const tvbuff_t *tvb, const gint offset);
/** Set the reported length of a tvbuff to a given value; used for protocols
whose headers contain an explicit length and where the calling
this protocol.
Also adjusts the data length. */
-extern void tvb_set_reported_length(tvbuff_t*, guint);
+extern void tvb_set_reported_length(tvbuff_t*, const guint);
-extern int offset_from_real_beginning(tvbuff_t *tvb, int counter);
+extern guint tvb_offset_from_real_beginning(const tvbuff_t *tvb);
/* Returns the offset from the first byte of real data. */
-#define TVB_RAW_OFFSET(tvb) \
- ((tvb->raw_offset==-1)?(tvb->raw_offset = offset_from_real_beginning(tvb, 0)):tvb->raw_offset)
+extern gint tvb_raw_offset(tvbuff_t *tvb);
/************** START OF ACCESSORS ****************/
/* All accessors will throw an exception if appropriate */
-extern guint8 tvb_get_guint8(tvbuff_t*, gint offset);
-
-extern guint16 tvb_get_ntohs(tvbuff_t*, gint offset);
-extern guint32 tvb_get_ntoh24(tvbuff_t*, gint offset);
-extern guint32 tvb_get_ntohl(tvbuff_t*, gint offset);
-extern guint64 tvb_get_ntoh64(tvbuff_t*, gint offset);
-extern gfloat tvb_get_ntohieee_float(tvbuff_t*, gint offset);
-extern gdouble tvb_get_ntohieee_double(tvbuff_t*, gint offset);
-
-extern guint16 tvb_get_letohs(tvbuff_t*, gint offset);
-extern guint32 tvb_get_letoh24(tvbuff_t*, gint offset);
-extern guint32 tvb_get_letohl(tvbuff_t*, gint offset);
-extern guint64 tvb_get_letoh64(tvbuff_t*, gint offset);
-extern gfloat tvb_get_letohieee_float(tvbuff_t*, gint offset);
-extern gdouble tvb_get_letohieee_double(tvbuff_t*, gint offset);
+extern guint8 tvb_get_guint8(tvbuff_t*, const gint offset);
+
+extern guint16 tvb_get_ntohs(tvbuff_t*, const gint offset);
+extern guint32 tvb_get_ntoh24(tvbuff_t*, const gint offset);
+extern guint32 tvb_get_ntohl(tvbuff_t*, const gint offset);
+extern guint64 tvb_get_ntoh40(tvbuff_t*, const gint offset);
+extern guint64 tvb_get_ntoh48(tvbuff_t*, const gint offset);
+extern guint64 tvb_get_ntoh56(tvbuff_t*, const gint offset);
+extern guint64 tvb_get_ntoh64(tvbuff_t*, const gint offset);
+extern gfloat tvb_get_ntohieee_float(tvbuff_t*, const gint offset);
+extern gdouble tvb_get_ntohieee_double(tvbuff_t*, const gint offset);
+
+extern guint16 tvb_get_letohs(tvbuff_t*, const gint offset);
+extern guint32 tvb_get_letoh24(tvbuff_t*, const gint offset);
+extern guint32 tvb_get_letohl(tvbuff_t*, const gint offset);
+extern guint64 tvb_get_letoh40(tvbuff_t*, const gint offset);
+extern guint64 tvb_get_letoh48(tvbuff_t*, const gint offset);
+extern guint64 tvb_get_letoh56(tvbuff_t*, const gint offset);
+extern guint64 tvb_get_letoh64(tvbuff_t*, const gint offset);
+extern gfloat tvb_get_letohieee_float(tvbuff_t*, const gint offset);
+extern gdouble tvb_get_letohieee_double(tvbuff_t*, const gint offset);
/**
* Fetch an IPv4 address, in network byte order.
* We do *not* convert it to host byte order; we leave it in
* network byte order, as that's what its callers expect. */
-extern guint32 tvb_get_ipv4(tvbuff_t*, gint offset);
+extern guint32 tvb_get_ipv4(tvbuff_t*, const gint offset);
/* Fetch an IPv6 address. */
-extern void tvb_get_ipv6(tvbuff_t*, gint offset, struct e_in6_addr *addr);
+extern void tvb_get_ipv6(tvbuff_t*, const gint offset, struct e_in6_addr *addr);
/* Fetch a GUID. */
-extern void tvb_get_ntohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid);
-extern void tvb_get_letohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid);
-extern void tvb_get_guid(tvbuff_t *tvb, gint offset, e_guid_t *guid, gboolean little_endian);
+extern void tvb_get_ntohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid);
+extern void tvb_get_letohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid);
+extern void tvb_get_guid(tvbuff_t *tvb, const gint offset, e_guid_t *guid, const guint representation);
/* Fetch a specified number of bits from bit offset in a tvb */
-extern guint8 tvb_get_bits8(tvbuff_t *tvb, gint bit_offset, gint no_of_bits);
-extern guint16 tvb_get_bits16(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian);
-extern guint32 tvb_get_bits32(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian);
-extern guint64 tvb_get_bits64(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian);
+extern guint8 tvb_get_bits8(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits);
+extern guint16 tvb_get_bits16(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const guint encoding);
+extern guint32 tvb_get_bits32(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const guint encoding);
+extern guint64 tvb_get_bits64(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const guint encoding);
+
+/**
+ * Fetch a specified number of bits from bit offset in a tvb, but allow number
+ * of bits to range between 1 and 32. If the requested number of bits is known
+ * beforehand, or its range can be handled by a single function of the group
+ * above, use one of them instead.
+ */
+extern guint32 tvb_get_bits(tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits, const guint encoding);
+
+void tvb_get_bits_buf(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, guint8 *buf, gboolean lsb0);
+guint8 *ep_tvb_get_bits(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean lsb0);
/** Returns target for convenience. Does not suffer from possible
* expense of tvb_get_ptr(), since this routine is smart enough
* different TVBUFF_REAL_DATA tvbuffs. This function assumes that the
* target memory is already allocated; it does not allocate or free the
* target memory. */
-extern void* tvb_memcpy(tvbuff_t*, void* target, gint offset, gint length);
+extern void* tvb_memcpy(tvbuff_t*, void* target, const gint offset, size_t length);
/** It is the user's responsibility to g_free() the memory allocated by
* tvb_memdup(). Calls tvb_memcpy() */
-extern void* tvb_memdup(tvbuff_t*, gint offset, gint length);
+extern void* tvb_memdup(tvbuff_t*, const gint offset, size_t length);
/* Same as above but the buffer returned from this function does not have to
* be freed. It will be automatically freed after the packet is dissected.
* Buffers allocated by this function are NOT persistent.
*/
-extern void* ep_tvb_memdup(tvbuff_t *tvb, gint offset, gint length);
+extern void* ep_tvb_memdup(tvbuff_t *tvb, const gint offset, size_t length);
/** WARNING! This function is possibly expensive, temporarily allocating
* another copy of the packet data. Furthermore, it's dangerous because once
* this pointer is given to the user, there's no guarantee that the user will
* honor the 'length' and not overstep the boundaries of the buffer.
*
+ * If you're thinking of using tvb_get_ptr, STOP WHAT YOU ARE DOING
+ * IMMEDIATELY. Go take a break. Consider that tvb_get_ptr hands you
+ * a raw, unprotected pointer that you can easily use to create a
+ * security vulnerability or otherwise crash Wireshark. Then consider
+ * that you can probably find a function elsewhere in this file that
+ * does exactly what you want in a much more safe and robust manner.
+ *
* The returned pointer is data that is internal to the tvbuff, so do not
* attempt to free it. Don't modify the data, either, because another tvbuff
* that might be using this tvbuff may have already copied that portion of
* and the pointer to the newly-contiguous data is returned. This dynamically-
* allocated memory will be freed when the tvbuff is freed, after the
* tvbuff_free_cb_t() is called, if any. */
-extern const guint8* tvb_get_ptr(tvbuff_t*, gint offset, gint length);
+extern const guint8* tvb_get_ptr(tvbuff_t*, const gint offset, const gint length);
/** Find first occurence of any of the needles in tvbuff, starting at offset.
* Searches at most maxlength number of bytes; if maxlength is -1, searches
* Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
* in that case, -1 will be returned if the boundary is reached before
* finding needle. */
-extern gint tvb_find_guint8(tvbuff_t*, gint offset, gint maxlength,
- guint8 needle);
+extern gint tvb_find_guint8(tvbuff_t*, const gint offset, const gint maxlength,
+ const guint8 needle);
/** Find first occurence of any of the needles in tvbuff, starting at offset.
* Searches at most maxlength number of bytes. Returns the offset of the
- * found needle, or -1 if not found. Will not throw an exception, even if
+ * found needle, or -1 if not found and the found needle.
+ * Will not throw an exception, even if
* maxlength exceeds boundary of tvbuff; in that case, -1 will be returned if
* the boundary is reached before finding needle. */
-extern gint tvb_pbrk_guint8(tvbuff_t *, gint offset, gint maxlength,
- const guint8 *needles);
+extern gint tvb_pbrk_guint8(tvbuff_t *, const gint offset, const gint maxlength,
+ const guint8 *needles, guchar *found_needle);
/** Find size of stringz (NUL-terminated string) by looking for terminating
* NUL. The size of the string includes the terminating NUL.
*
* If the NUL isn't found, it throws the appropriate exception.
*/
-extern guint tvb_strsize(tvbuff_t *tvb, gint offset);
+extern guint tvb_strsize(tvbuff_t *tvb, const gint offset);
/** Find length of string by looking for end of zero terminated string, up to
* 'maxlength' characters'; if 'maxlength' is -1, searches to end
* of tvbuff.
* Returns -1 if 'maxlength' reached before finding EOS. */
-extern gint tvb_strnlen(tvbuff_t*, gint offset, guint maxlength);
+extern gint tvb_strnlen(tvbuff_t*, const gint offset, const guint maxlength);
/** Convert a string from Unicode to ASCII. At the moment we fake it by
- * assuming all characters are ASCII )-: The len parameter is the number
- * of guint16's to convert from Unicode.
+ * assuming all characters are ASCII )-: The len parameter is the number
+ * of guint16's to convert from Unicode.
+ *
+ * XXX - These functions have been superceded by tvb_get_unicode_string()
+ * and tvb_get_ephemeral_unicode_string()
*
* tvb_fake_unicode() returns a buffer allocated by g_malloc() and must
* be g_free() by the caller.
* automatically freed when wireshark starts dissecting
* the next packet.
*/
-extern char *tvb_fake_unicode(tvbuff_t *tvb, int offset, int len,
- gboolean little_endian);
-extern char *tvb_get_ephemeral_faked_unicode(tvbuff_t *tvb, int offset, int len,
- gboolean little_endian);
+extern char *tvb_fake_unicode(tvbuff_t *tvb, int offset, const int len,
+ const gboolean little_endian);
+extern char *tvb_get_ephemeral_faked_unicode(tvbuff_t *tvb, int offset, const int len,
+ const gboolean little_endian);
/**
* Format the data in the tvb from offset for size ...
*/
-extern gchar * tvb_format_text(tvbuff_t *tvb, gint offset, gint size);
+extern gchar * tvb_format_text(tvbuff_t *tvb, const gint offset, const gint size);
/**
* Like "tvb_format_text()", but for 'wsp'; don't show
* the characters as C-style escapes.
*/
-extern gchar * tvb_format_text_wsp(tvbuff_t *tvb, gint offset, gint size);
+extern gchar * tvb_format_text_wsp(tvbuff_t *tvb, const gint offset, const gint size);
/**
* Like "tvb_format_text()", but for null-padded strings; don't show
* the null padding characters as "\000".
*/
-extern gchar *tvb_format_stringzpad(tvbuff_t *tvb, gint offset, gint size);
+extern gchar *tvb_format_stringzpad(tvbuff_t *tvb, const gint offset, const gint size);
+
+/**
+ * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
+ * the null padding characters as "\000".
+ */
+extern gchar *tvb_format_stringzpad_wsp(tvbuff_t *tvb, const gint offset, const gint size);
/**
* MUST be g_free() by the caller in order not to leak
* memory.
*
+ * tvb_get_unicode_string() Unicode (UTF-16) version of above
+ *
* tvb_get_ephemeral_string() returns a string that does not need to be freed,
* instead it will automatically be freed once the next
* packet is dissected.
*
+ * tvb_get_ephemeral_string_enc() takes a string encoding as well, and
+ * converts to UTF-8 from the encoding (only UTF-8 and
+ * EBCDIC supported)
+ *
+ * tvb_get_ephemeral_unicode_string() Unicode (UTF-16) version of above
+ *
* tvb_get_seasonal_string() returns a string that does not need to be freed,
* instead it will automatically be freed when a new capture
* or file is opened.
*/
-extern guint8 *tvb_get_string(tvbuff_t *tvb, gint offset, gint length);
-extern guint8 *tvb_get_ephemeral_string(tvbuff_t *tvb, gint offset, gint length);
-extern guint8 *tvb_get_seasonal_string(tvbuff_t *tvb, gint offset, gint length);
+extern guint8 *tvb_get_string(tvbuff_t *tvb, const gint offset, const gint length);
+extern gchar *tvb_get_unicode_string(tvbuff_t *tvb, const gint offset, gint length, const guint encoding);
+extern guint8 *tvb_get_ephemeral_string(tvbuff_t *tvb, const gint offset, const gint length);
+extern guint8 *tvb_get_ephemeral_string_enc(tvbuff_t *tvb, const gint offset,
+ const gint length, const gint encoding);
+extern gchar *tvb_get_ephemeral_unicode_string(tvbuff_t *tvb, const gint offset, gint length, const guint encoding);
+extern guint8 *tvb_get_seasonal_string(tvbuff_t *tvb, const gint offset, const gint length);
/**
* MUST be g_free() by the caller in order not to leak
* memory.
*
+ * tvb_get_stringz_enc() takes a string encoding as well, and converts to
+ * UTF-8 from the encoding (only UTF-8 and EBCDIC supported)
+ *
+ * tvb_get_const_stringz() returns a constant (unmodifiable) string that does
+ * not need to be freed, instead it will automatically be
+ * freed once the next packet is dissected. It is slightly
+ * more efficient than the other routines.
+ *
* tvb_get_ephemeral_stringz() returns a string that does not need to be freed,
* instead it will automatically be freed once the next
* packet is dissected.
*
+ * tvb_get_ephemeral_stringz_enc() takes a string encoding as well, and
+ * converts to UTF-8 from the encoding (only UTF-8 and
+ * EBCDIC supported)
+ * packet is dissected.
+ *
+ * tvb_get_ephemeral_unicode_stringz() Unicode (UTF-16) version of above
+ *
* tvb_get_seasonal_stringz() returns a string that does not need to be freed,
* instead it will automatically be freed when a new capture
* or file is opened.
*/
-extern guint8 *tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp);
-extern guint8 *tvb_get_ephemeral_stringz(tvbuff_t *tvb, gint offset, gint *lengthp);
-extern guint8 *tvb_get_seasonal_stringz(tvbuff_t *tvb, gint offset, gint *lengthp);
+extern guint8 *tvb_get_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp);
+extern guint8 *tvb_get_stringz_enc(tvbuff_t *tvb, const gint offset, gint *lengthp, gint encoding);
+extern const guint8 *tvb_get_const_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp);
+extern guint8 *tvb_get_ephemeral_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp);
+extern guint8 *tvb_get_ephemeral_stringz_enc(tvbuff_t *tvb, const gint offset, gint *lengthp, gint encoding);
+extern gchar *tvb_get_ephemeral_unicode_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding);
+extern guint8 *tvb_get_seasonal_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp);
/** Looks for a stringz (NUL-terminated string) in tvbuff and copies
* no more than bufsize number of bytes, including terminating NUL, to buffer.
* is truncated with a NUL, albeit not at buffer[bufsize - 1], but
* at the correct spot, terminating the string.
*/
-extern gint tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize,
+extern gint tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize,
guint8* buffer);
/** Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
*
* bufsize MUST be greater than 0.
*/
-extern gint tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize,
+extern gint tvb_get_nstringz0(tvbuff_t *tvb, const gint offset, const guint bufsize,
guint8* buffer);
/**
* terminator, or past the end of the buffer if we don't find a line
* terminator. (It's not set if we return -1.)
*/
-extern gint tvb_find_line_end(tvbuff_t *tvb, gint offset, int len,
- gint *next_offset, gboolean desegment);
+extern gint tvb_find_line_end(tvbuff_t *tvb, const gint offset, int len,
+ gint *next_offset, const gboolean desegment);
/**
* Given a tvbuff, an offset into the tvbuff, and a length that starts
* terminator, or past the end of the buffer if we don't find a line
* terminator.
*/
-extern gint tvb_find_line_end_unquoted(tvbuff_t *tvb, gint offset, int len,
+extern gint tvb_find_line_end_unquoted(tvbuff_t *tvb, const gint offset, int len,
gint *next_offset);
/**
* is smaller.
*/
-extern gint tvb_skip_wsp(tvbuff_t* tvb, gint offset, gint maxlength);
+extern gint tvb_skip_wsp(tvbuff_t* tvb, const gint offset, const gint maxlength);
-extern gint tvb_skip_wsp_return(tvbuff_t* tvb, gint offset);
+extern gint tvb_skip_wsp_return(tvbuff_t* tvb, const gint offset);
/**
* Call strncmp after checking if enough chars left, returning 0 if
* it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
*/
-extern gint tvb_strneql(tvbuff_t *tvb, gint offset, const gchar *str,
- gint size);
+extern gint tvb_strneql(tvbuff_t *tvb, const gint offset, const gchar *str,
+ const size_t size);
/**
* Call g_ascii_strncasecmp after checking if enough chars left, returning
* 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
*/
-extern gint tvb_strncaseeql(tvbuff_t *tvb, gint offset, const gchar *str,
- gint size);
+extern gint tvb_strncaseeql(tvbuff_t *tvb, const gint offset, const gchar *str,
+ const size_t size);
/**
* Call memcmp after checking if enough chars left, returning 0 if
* it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
*/
-extern gint tvb_memeql(tvbuff_t *tvb, gint offset, const guint8 *str,
- gint size);
+extern gint tvb_memeql(tvbuff_t *tvb, const gint offset, const guint8 *str,
+ size_t size);
/**
* Format a bunch of data from a tvbuff as bytes, returning a pointer
* to the string with the formatted data, with "punct" as a byte
* separator.
*/
-extern gchar *tvb_bytes_to_str_punct(tvbuff_t *tvb, gint offset, gint len,
- gchar punct);
+extern gchar *tvb_bytes_to_str_punct(tvbuff_t *tvb, const gint offset, const gint len,
+ const gchar punct);
-/*
+/**
* Format a bunch of data from a tvbuff as bytes, returning a pointer
* to the string with the formatted data.
*/
-extern gchar *tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len);
+extern gchar *tvb_bytes_to_str(tvbuff_t *tvb, const gint offset, const gint len);
-#define TVB_GET_DS_TVB(tvb) \
- (tvb->ds_tvb)
+/**
+ * Given a tvbuff, an offset into the tvbuff, and a length that starts
+ * at that offset (which may be -1 for "all the way to the end of the
+ * tvbuff"), fetch BCD encoded digits from a tvbuff starting from either
+ * the low or high half byte, formating the digits according to an input digit set,
+ * if NUll a default digit set of 0-9 returning "?" for overdecadic digits will be used.
+ * A pointer to the EP allocated string will be returned.
+ * Note a tvbuff content of 0xf is considered a 'filler' and will end the conversion.
+ */
+typedef struct dgt_set_t
+{
+ const unsigned char out[15];
+}
+dgt_set_t;
+
+extern const gchar *tvb_bcd_dig_to_ep_str(tvbuff_t *tvb, const gint offset, const gint len, dgt_set_t *dgt, gboolean skip_first);
+
+struct tvbuff *tvb_get_ds_tvb(tvbuff_t *tvb);
/** Locate a sub-tvbuff within another tvbuff, starting at position
* 'haystack_offset'. Returns the index of the beginning of 'needle' within
* 'haystack', or -1 if 'needle' is not found. The index is relative
* to the start of 'haystack', not 'haystack_offset'. */
extern gint tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb,
- gint haystack_offset);
+ const gint haystack_offset);
/**
* Uncompresses a zlib compressed packet inside a tvbuff at offset with
* length comprlen. Returns an uncompressed tvbuffer if uncompression
* succeeded or NULL if uncompression failed.
*/
-extern tvbuff_t* tvb_uncompress(tvbuff_t *tvb, int offset, int comprlen);
+extern tvbuff_t* tvb_uncompress(tvbuff_t *tvb, const int offset, int comprlen);
/**
* Uncompresses a zlib compressed packet inside a tvbuff at offset with
* length comprlen. Returns an uncompressed tvbuffer attached to tvb if uncompression
* succeeded or NULL if uncompression failed.
*/
-extern tvbuff_t* tvb_child_uncompress(tvbuff_t *parent, tvbuff_t *tvb, int offset, int comprlen);
+extern tvbuff_t* tvb_child_uncompress(tvbuff_t *parent, tvbuff_t *tvb, const int offset, int comprlen);
/************** END OF ACCESSORS ****************/
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
#endif /* __TVBUFF_H__ */