263 lines
10 KiB
C
263 lines
10 KiB
C
/* tvbuff.h
|
|
*
|
|
* Testy, Virtual(-izable) Buffer of guint8*'s
|
|
*
|
|
* "Testy" -- the buffer gets mad when an attempt is made to access data
|
|
* beyond the bounds of the buffer. An exception is thrown.
|
|
*
|
|
* "Virtual" -- the buffer can have its own data, can use a subset of
|
|
* the data of a backing tvbuff, or can be a composite of
|
|
* other tvbuffs.
|
|
*
|
|
* $Id: tvbuff.h,v 1.8 2000/08/17 17:16:02 gram Exp $
|
|
*
|
|
* Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
|
|
*
|
|
* 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 __TVBUFF_H__
|
|
#define __TVBUFF_H__
|
|
|
|
#include <glib.h>
|
|
#include "exceptions.h"
|
|
|
|
typedef struct tvbuff tvbuff_t;
|
|
|
|
typedef void (*tvbuff_free_cb_t)(void*);
|
|
|
|
/* The different types of tvbuff's */
|
|
typedef enum {
|
|
TVBUFF_REAL_DATA,
|
|
TVBUFF_SUBSET,
|
|
TVBUFF_COMPOSITE
|
|
} tvbuff_type;
|
|
|
|
/* TVBUFF_REAL_DATA contains a guint8* that points to real data.
|
|
* The data is allocated and contiguous.
|
|
*
|
|
* TVBUFF_SUBSET has a backing tvbuff. The TVBUFF_SUBSET is a "window"
|
|
* through which the program sees only a portion of the backing tvbuff.
|
|
*
|
|
* TVBUFF_COMPOSITE combines multiple tvbuffs sequentually to produce
|
|
* a larger byte array.
|
|
*
|
|
* tvbuff's of any type can be used as the backing-tvbuff of a
|
|
* TVBUFF_SUBSET or as the member of a TVBUFF_COMPOSITE.
|
|
* TVBUFF_COMPOSITEs can have member-tvbuffs of different types.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
|
|
/* "class" initialization. Called once during execution of program
|
|
* so that tvbuff.c can initialize its data. */
|
|
void tvbuff_init(void);
|
|
|
|
/* "class" cleanup. Called once during execution of program
|
|
* so that tvbuff.c can clean up its data. */
|
|
void tvbuff_cleanup(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 */
|
|
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().
|
|
*/
|
|
void tvb_free(tvbuff_t*);
|
|
|
|
/* Free the tvbuff_t and all tvbuff's created from it. */
|
|
void tvb_free_chain(tvbuff_t*);
|
|
|
|
/* Both return the new usage count, after the increment or decrement */
|
|
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 */
|
|
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 --- the guint* that points to the real data.
|
|
* Obviously, this only applies to a TVBUFF_REAL_DATA tvbuff. */
|
|
void tvb_set_free_cb(tvbuff_t*, tvbuff_free_cb_t);
|
|
|
|
|
|
/* Sets parameters for TVBUFF_REAL_DATA */
|
|
void tvb_set_real_data(tvbuff_t*, const guint8* data, guint length, gint reported_length);
|
|
|
|
/* Combination of tvb_new() and tvb_set_real_data() */
|
|
tvbuff_t* tvb_new_real_data(const guint8* data, guint length, gint reported_length);
|
|
|
|
|
|
/* Define the subset of the backing buffer to use.
|
|
*
|
|
* 'backing_offset' can be negative, to indicate bytes from
|
|
* the end of the backing buffer.
|
|
*
|
|
* 'backing_length' can be 0, although the usefulness of the buffer would
|
|
* be rather limited.
|
|
*
|
|
* 'backing_length' of -1 means "to the end of the backing buffer"
|
|
*
|
|
* Will throw BoundsError if 'backing_offset'/'length'
|
|
* is beyond the bounds of the backing tvbuff. */
|
|
void tvb_set_subset(tvbuff_t* tvb, tvbuff_t* backing,
|
|
gint backing_offset, gint backing_length, gint reported_length);
|
|
|
|
/* Combination of tvb_new() and tvb_set_subset() */
|
|
tvbuff_t* tvb_new_subset(tvbuff_t* backing,
|
|
gint backing_offset, gint backing_length, gint reported_length);
|
|
|
|
|
|
/* Both tvb_composite_append and tvb_composite_prepend can throw
|
|
* BoundsError if member_offset/member_length goes beyond bounds of
|
|
* the 'member' tvbuff. */
|
|
|
|
/* Append to the list of tvbuffs that make up this composite tvbuff */
|
|
void tvb_composite_append(tvbuff_t* tvb, tvbuff_t* member);
|
|
|
|
/* Prepend to the list of tvbuffs that make up this composite tvbuff */
|
|
void tvb_composite_prepend(tvbuff_t* tvb, tvbuff_t* member);
|
|
|
|
/* Helper function that calls tvb_new(TVBUFF_COMPOSITE).
|
|
* Provided only to maintain symmetry with other constructors */
|
|
tvbuff_t* tvb_new_composite(void);
|
|
|
|
/* Mark a composite tvbuff as initialized. No further appends or prepends
|
|
* occur, data access can finally happen after this finalization. */
|
|
void tvb_composite_finalize(tvbuff_t* tvb);
|
|
|
|
|
|
/* Get total length of buffer */
|
|
guint tvb_length(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. */
|
|
guint tvb_length_remaining(tvbuff_t*, gint offset);
|
|
|
|
/* Checks (w/o throwing exception) that the bytes referred to by 'offset'/'length'
|
|
* actualy exist in the buffer */
|
|
gboolean tvb_bytes_exist(tvbuff_t*, gint offset, gint length);
|
|
|
|
/* Checks (w/o throwing exception) that offset exists in buffer */
|
|
gboolean tvb_offset_exists(tvbuff_t*, gint offset);
|
|
|
|
/* Get reported length of buffer */
|
|
guint tvb_reported_length(tvbuff_t*);
|
|
|
|
/* Returns the offset from the first byte of real data. This is
|
|
* the same value as 'offset' in tvb_compat() */
|
|
gint tvb_raw_offset(tvbuff_t*);
|
|
|
|
/************** START OF ACCESSORS ****************/
|
|
/* All accessors will throw BoundsError or ReportedBoundsError if appropriate */
|
|
|
|
guint8 tvb_get_guint8(tvbuff_t*, gint offset);
|
|
|
|
guint16 tvb_get_ntohs(tvbuff_t*, gint offset);
|
|
guint32 tvb_get_ntoh24(tvbuff_t*, gint offset);
|
|
guint32 tvb_get_ntohl(tvbuff_t*, gint offset);
|
|
#ifdef G_HAVE_GINT64
|
|
guint64 tvb_get_ntohll(tvbuff_t*, gint offset);
|
|
#endif
|
|
|
|
guint16 tvb_get_letohs(tvbuff_t*, gint offset);
|
|
guint32 tvb_get_letoh24(tvbuff_t*, gint offset);
|
|
guint32 tvb_get_letohl(tvbuff_t*, gint offset);
|
|
#ifdef G_HAVE_GINT64
|
|
guint64 tvb_get_letohll(tvbuff_t*, gint offset);
|
|
#endif
|
|
|
|
/* Returns target for convenience. Does not suffer from possible
|
|
* expense of tvb_get_ptr(), since this routine is smart enough
|
|
* to copy data in chunks if the request range actually exists in
|
|
* different TVBUFF_REAL_DATA tvbuffs. This function assumes that the
|
|
* target memory is already allocated; it does not allocate or free the
|
|
* target memory. */
|
|
guint8* tvb_memcpy(tvbuff_t*, guint8* target, gint offset, gint length);
|
|
|
|
/* It is the user's responsibility to g_free() the memory allocated by
|
|
* tvb_memdup(). Calls tvb_memcpy() */
|
|
guint8* tvb_memdup(tvbuff_t*, gint offset, gint 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.
|
|
*
|
|
* 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
|
|
* the data (sometimes tvbuff's need to make copies of data, but that's the
|
|
* internal implementation that you need not worry about). Assume that the
|
|
* guint8* points to read-only data that the tvbuff manages.
|
|
*
|
|
* Return a pointer into our buffer if the data asked for via 'offset'/'length'
|
|
* is contiguous (which might not be the case for TVBUFF_COMPOSITE). If the
|
|
* data is not contiguous, a tvb_memdup() is called for the entire buffer
|
|
* 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. */
|
|
guint8* tvb_get_ptr(tvbuff_t*, gint offset, gint length);
|
|
|
|
/* Find length of string by looking for end of string ('\0'), up to
|
|
* 'max_length' characters'. Returns -1 if 'max_length' reached
|
|
* before finding EOS. */
|
|
/*gint tvb_strnlen(tvbuff_t*, gint offset, gint max_length);*/
|
|
|
|
/************** END OF ACCESSORS ****************/
|
|
|
|
/* Sets pd and offset so that tvbuff's can be used with code
|
|
* that only understands pd/offset and not tvbuffs.
|
|
* This is the "compatibility" function */
|
|
void tvb_compat(tvbuff_t*, const guint8 **pd, int *offset);
|
|
|
|
#define tvb_create_from_top(offset) \
|
|
tvb_new_subset(pi.compat_top_tvb, (offset), \
|
|
pi.captured_len - (offset), pi.len - (offset))
|
|
|
|
#endif /* __TVBUFF_H__ */
|