Add tvb_set_child_real_data_tvbuff(), which allows you to tell the
[obnox/wireshark/wip.git] / epan / tvbuff.h
1 /* tvbuff.h
2  *
3  * Testy, Virtual(-izable) Buffer of guint8*'s
4  * 
5  * "Testy" -- the buffer gets mad when an attempt is made to access data
6  *              beyond the bounds of the buffer. An exception is thrown.
7  *
8  * "Virtual" -- the buffer can have its own data, can use a subset of
9  *              the data of a backing tvbuff, or can be a composite of
10  *              other tvbuffs.
11  *
12  * $Id: tvbuff.h,v 1.7 2000/11/14 04:33:34 gram Exp $
13  *
14  * Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
15  *
16  * Ethereal - Network traffic analyzer
17  * By Gerald Combs <gerald@zing.org>
18  * Copyright 1998 Gerald Combs
19  *
20  * 
21  * This program is free software; you can redistribute it and/or
22  * modify it under the terms of the GNU General Public License
23  * as published by the Free Software Foundation; either version 2
24  * of the License, or (at your option) any later version.
25  * 
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  * GNU General Public License for more details.
30  * 
31  * You should have received a copy of the GNU General Public License
32  * along with this program; if not, write to the Free Software
33  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
34  */
35
36 #ifndef __TVBUFF_H__
37 #define __TVBUFF_H__
38
39 #include <glib.h>
40 #include "exceptions.h"
41
42 typedef struct tvbuff tvbuff_t;
43
44 typedef void (*tvbuff_free_cb_t)(void*);
45
46 /* The different types of tvbuff's */
47 typedef enum {
48         TVBUFF_REAL_DATA,
49         TVBUFF_SUBSET,
50         TVBUFF_COMPOSITE
51 } tvbuff_type;
52
53 /* TVBUFF_REAL_DATA contains a guint8* that points to real data.
54  * The data is allocated and contiguous.
55  *
56  * TVBUFF_SUBSET has a backing tvbuff. The TVBUFF_SUBSET is a "window"
57  * through which the program sees only a portion of the backing tvbuff.
58  *
59  * TVBUFF_COMPOSITE combines multiple tvbuffs sequentually to produce
60  * a larger byte array.
61  *
62  * tvbuff's of any type can be used as the backing-tvbuff of a
63  * TVBUFF_SUBSET or as the member of a TVBUFF_COMPOSITE.
64  * TVBUFF_COMPOSITEs can have member-tvbuffs of different types.
65  *
66  * Once a tvbuff is create/initialized/finalized, the tvbuff is read-only.
67  * That is, it cannot point to any other data. A new tvbuff must be created if
68  * you want a tvbuff that points to other data.
69  */
70
71
72 /* "class" initialization. Called once during execution of program
73  * so that tvbuff.c can initialize its data. */
74 void tvbuff_init(void);
75
76 /* "class" cleanup. Called once during execution of program
77  * so that tvbuff.c can clean up its data. */
78 void tvbuff_cleanup(void);
79
80
81 /* Returns a pointer to a newly initialized tvbuff. Note that
82  * tvbuff's of types TVBUFF_SUBSET and TVBUFF_COMPOSITE
83  * require further initialization via the appropriate functions */
84 tvbuff_t* tvb_new(tvbuff_type);
85
86 /* Marks a tvbuff for freeing. The guint8* data of a TVBUFF_REAL_DATA
87  * is *never* freed by the tvbuff routines. The tvbuff itself is actually freed
88  * once its usage count drops to 0.
89  *
90  * Usage counts increment for any time the tvbuff is
91  * used as a member of another tvbuff, i.e., as the backing buffer for
92  * a TVBUFF_SUBSET or as a member of a TVBUFF_COMPOSITE.
93  *
94  * Although you may call tvb_free(), the tvbuff may still be in use
95  * by other tvbuff's (TVBUFF_SUBSET or TVBUFF_COMPOSITE), so it is not
96  * safe, unless you know otherwise, to free your guint8* data. If you
97  * cannot be sure that your TVBUFF_REAL_DATA is not in use by another
98  * tvbuff, register a callback with tvb_set_free_cb(); when your tvbuff
99  * is _really_ freed, then your callback will be called, and at that time
100  * you can free your original data.
101  *
102  * The caller can artificially increment/decrement the usage count
103  * with tvbuff_increment_usage_count()/tvbuff_decrement_usage_count().
104  */
105 void tvb_free(tvbuff_t*);
106
107 /* Free the tvbuff_t and all tvbuff's created from it. */
108 void tvb_free_chain(tvbuff_t*);
109
110 /* Both return the new usage count, after the increment or decrement */
111 guint tvb_increment_usage_count(tvbuff_t*, guint count);
112
113 /* If a decrement causes the usage count to drop to 0, a the tvbuff
114  * is immediately freed. Be sure you know exactly what you're doing
115  * if you decide to use this function, as another tvbuff could
116  * still have a pointer to the just-freed tvbuff, causing corrupted data
117  * or a segfault in the future */
118 guint tvb_decrement_usage_count(tvbuff_t*, guint count);
119
120 /* Set a callback function to call when a tvbuff is actually freed
121  * (once the usage count drops to 0). One argument is passed to
122  * that callback --- the guint* that points to the real data.
123  * Obviously, this only applies to a TVBUFF_REAL_DATA tvbuff. */
124 void tvb_set_free_cb(tvbuff_t*, tvbuff_free_cb_t);
125
126
127 /* Attach a TVBUFF_REAL_DATA tvbuff to a parent tvbuff. This connection
128  * is used during a tvb_free_chain()... the "child" TVBUFF_REAL_DATA acts
129  * as if is part of the chain-of-creation of the parent tvbuff, although it
130  * isn't. This is useful if you need to take the data from some tvbuff,
131  * run some operation on it, like decryption or decompression, and make a new
132  * tvbuff from it, yet want the new tvbuff to be part of the chain. The reality
133  * is that the new tvbuff *is* part of the "chain of creation", but in a way
134  * that these tvbuff routines is ignorant of. Use this function to make
135  * the tvbuff routines knowledgable of this fact. */
136 void tvb_set_child_real_data_tvbuff(tvbuff_t* parent, tvbuff_t* child);
137
138 /* Sets parameters for TVBUFF_REAL_DATA. Can throw ReportedBoundsError. */
139 void tvb_set_real_data(tvbuff_t*, const guint8* data, guint length, gint reported_length);
140
141 /* Combination of tvb_new() and tvb_set_real_data(). Can throw ReportedBoundsError. */
142 tvbuff_t* tvb_new_real_data(const guint8* data, guint length, gint reported_length);
143
144
145 /* Define the subset of the backing buffer to use.
146  *
147  * 'backing_offset' can be negative, to indicate bytes from
148  * the end of the backing buffer.
149  *
150  * 'backing_length' can be 0, although the usefulness of the buffer would
151  * be rather limited.
152  *
153  * 'backing_length' of -1 means "to the end of the backing buffer"
154  *
155  * Will throw BoundsError if 'backing_offset'/'length'
156  * is beyond the bounds of the backing tvbuff.
157  * Can throw ReportedBoundsError. */
158 void tvb_set_subset(tvbuff_t* tvb, tvbuff_t* backing,
159                 gint backing_offset, gint backing_length, gint reported_length);
160
161 /* Combination of tvb_new() and tvb_set_subset()
162  * Can throw ReportedBoundsError. */
163 tvbuff_t* tvb_new_subset(tvbuff_t* backing,
164                 gint backing_offset, gint backing_length, gint reported_length);
165
166
167 /* Both tvb_composite_append and tvb_composite_prepend can throw
168  * BoundsError if member_offset/member_length goes beyond bounds of
169  * the 'member' tvbuff. */
170
171 /* Append to the list of tvbuffs that make up this composite tvbuff */
172 void tvb_composite_append(tvbuff_t* tvb, tvbuff_t* member);
173
174 /* Prepend to the list of tvbuffs that make up this composite tvbuff */
175 void tvb_composite_prepend(tvbuff_t* tvb, tvbuff_t* member);
176
177 /* Helper function that calls tvb_new(TVBUFF_COMPOSITE).
178  * Provided only to maintain symmetry with other constructors */
179 tvbuff_t* tvb_new_composite(void);
180
181 /* Mark a composite tvbuff as initialized. No further appends or prepends
182  * occur, data access can finally happen after this finalization. */
183 void tvb_composite_finalize(tvbuff_t* tvb);
184
185
186 /* Get total length of buffer */
187 guint tvb_length(tvbuff_t*);
188
189 /* Computes bytes to end of buffer, from offset (which can be negative,
190  * to indicate bytes from end of buffer). Function returns -1 to
191  * indicate that offset is out of bounds. No exception is thrown. */
192 guint tvb_length_remaining(tvbuff_t*, gint offset);
193
194 /* Checks (w/o throwing exception) that the bytes referred to by 'offset'/'length'
195  * actualy exist in the buffer */
196 gboolean tvb_bytes_exist(tvbuff_t*, gint offset, gint length);
197
198 /* Checks (w/o throwing exception) that offset exists in buffer */
199 gboolean tvb_offset_exists(tvbuff_t*, gint offset);
200
201 /* Get reported length of buffer */
202 guint tvb_reported_length(tvbuff_t*);
203
204 /* Returns the offset from the first byte of real data. This is
205  * the same value as 'offset' in tvb_compat() */
206 gint tvb_raw_offset(tvbuff_t*);
207
208 /************** START OF ACCESSORS ****************/
209 /* All accessors will throw BoundsError or ReportedBoundsError if appropriate */
210
211 guint8  tvb_get_guint8(tvbuff_t*, gint offset);
212
213 guint16 tvb_get_ntohs(tvbuff_t*, gint offset);
214 guint32 tvb_get_ntoh24(tvbuff_t*, gint offset);
215 guint32 tvb_get_ntohl(tvbuff_t*, gint offset);
216 #ifdef G_HAVE_GINT64
217 guint64 tvb_get_ntohll(tvbuff_t*, gint offset);
218 #endif
219
220 guint16 tvb_get_letohs(tvbuff_t*, gint offset);
221 guint32 tvb_get_letoh24(tvbuff_t*, gint offset);
222 guint32 tvb_get_letohl(tvbuff_t*, gint offset);
223 #ifdef G_HAVE_GINT64
224 guint64 tvb_get_letohll(tvbuff_t*, gint offset);
225 #endif
226
227 /* Returns target for convenience. Does not suffer from possible
228  * expense of tvb_get_ptr(), since this routine is smart enough
229  * to copy data in chunks if the request range actually exists in
230  * different TVBUFF_REAL_DATA tvbuffs. This function assumes that the
231  * target memory is already allocated; it does not allocate or free the
232  * target memory. */
233 guint8* tvb_memcpy(tvbuff_t*, guint8* target, gint offset, gint length);
234
235 /* It is the user's responsibility to g_free() the memory allocated by
236  * tvb_memdup(). Calls tvb_memcpy() */
237 guint8* tvb_memdup(tvbuff_t*, gint offset, gint length);
238
239 /* WARNING! This function is possibly expensive, temporarily allocating
240  * another copy of the packet data. Furthermore, it's dangerous because once
241  * this pointer is given to the user, there's no guarantee that the user will
242  * honor the 'length' and not overstep the boundaries of the buffer.
243  *
244  * The returned pointer is data that is internal to the tvbuff, so do not
245  * attempt to free it. Don't modify the data, either, because another tvbuff
246  * that might be using this tvbuff may have already copied that portion of
247  * the data (sometimes tvbuff's need to make copies of data, but that's the
248  * internal implementation that you need not worry about). Assume that the
249  * guint8* points to read-only data that the tvbuff manages.
250  *
251  * Return a pointer into our buffer if the data asked for via 'offset'/'length'
252  * is contiguous (which might not be the case for TVBUFF_COMPOSITE). If the
253  * data is not contiguous, a tvb_memdup() is called for the entire buffer
254  * and the pointer to the newly-contiguous data is returned. This dynamically-
255  * allocated memory will be freed when the tvbuff is freed, after the
256  * tvbuff_free_cb_t() is called, if any. */
257 guint8* tvb_get_ptr(tvbuff_t*, gint offset, gint length);
258
259 /* Find first occurence of any of the needles in tvbuff, starting at offset.
260  * Searches at most maxlength number of bytes; if maxlength is -1, searches
261  * to end of tvbuff.
262  * Returns the offset of the found needle, or -1 if not found.
263  * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
264  * in that case, -1 will be returned if the boundary is reached before
265  * finding needle. */
266 gint tvb_find_guint8(tvbuff_t*, gint offset, guint maxlength, guint8 needle);
267
268 /* Find first occurence of any of the needles in tvbuff, starting at offset.
269  * Searches at most maxlength number of bytes. Returns the offset of the
270  * found needle, or -1 if not found. Will not throw an exception, even if
271  * maxlength exceeds boundary of tvbuff; in that case, -1 will be returned if
272  * the boundary is reached before finding needle. */
273 gint tvb_pbrk_guint8(tvbuff_t *, gint offset, guint maxlength, guint8 *needles);
274
275 /* Find length of string by looking for end of string ('\0'), up to
276  * 'maxlength' characters'; if 'maxlength' is -1, searches to end
277  * of tvbuff.
278  * Returns -1 if 'maxlength' reached before finding EOS. */
279 gint tvb_strnlen(tvbuff_t*, gint offset, guint maxlength);
280
281 /*
282  * Format the data in the tvb from offset for size ...
283  */
284 guint8 * tvb_format_text(tvbuff_t *tvb, gint offset, gint size);
285
286 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
287  * no more than maxlength number of bytes, including terminating NUL, to buffer.
288  * Returns length of string (not including terminating NUL), or -1 if the string was
289  * truncated in the buffer due to not having reached the terminating NUL.
290  * In this way, it acts like snprintf().
291  */
292 gint tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint maxlength, guint8* buffer);
293
294 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
295  * have a terminating NUL. If the string was truncated when copied into buffer,
296  * a NUL is placed at the end of buffer to terminate it.
297  */
298 gint tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint maxlength, guint8* buffer);
299
300 /*
301  * Given a tvbuff, an offset into the tvbuff, and a length that starts
302  * at that offset (which may be -1 for "all the way to the end of the
303  * tvbuff"), find the end of the (putative) line that starts at the
304  * specified offset in the tvbuff, going no further than the specified
305  * length.
306  *
307  * Return the offset right past the end of the line as the return value,
308  * and return the offset of the EOL character(s) in "*eol".
309  */
310 gint tvb_find_line_end(tvbuff_t *tvb, gint offset, int len, gint *eol);
311
312 /*
313  * Given a tvbuff, an offset into the tvbuff, and a length that starts
314  * at that offset (which may be -1 for "all the way to the end of the
315  * tvbuff"), find the end of the (putative) line that starts at the
316  * specified offset in the tvbuff, going no further than the specified
317  * length.
318  *
319  * However, treat quoted strings inside the buffer specially - don't
320  * treat newlines in quoted strings as line terminators.
321  *
322  * Return the length of the line (not counting the line terminator at
323  * the end), or the amount of data remaining in the buffer if we don't
324  * find a line terminator.
325  *
326  * Set "*next_offset" to the offset of the character past the line
327  * terminator, or past the end of the buffer if we don't find a line
328  * terminator.
329  */
330 gint tvb_find_line_end_unquoted(tvbuff_t *tvb, gint offset, int len,
331     gint *next_offset);
332
333 /* Call strncmp after checking if enough chars left, otherwise return -1 */
334 gint tvb_strneql(tvbuff_t *tvb, gint offset, const guint8 *str, gint size);
335
336 /* Call strncasecmp after checking if enough chars left, otherwise return -1 */
337 gint tvb_strncaseeql(tvbuff_t *tvb, gint offset, const guint8 *str, gint size);
338
339 /*
340  * Format a bunch of data from a tvbuff as bytes, returning a pointer
341  * to the string with the formatted data.
342  */
343 gchar *tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len);
344
345 /************** END OF ACCESSORS ****************/
346
347 /* Sets pd and offset so that tvbuff's can be used with code
348  * that only understands pd/offset and not tvbuffs.
349  * This is the "compatibility" function */
350 void tvb_compat(tvbuff_t*, const guint8 **pd, int *offset);
351
352 #define tvb_create_from_top(offset) \
353         tvb_new_subset(pi.compat_top_tvb, (offset), \
354                                 pi.captured_len - (offset), pi.len - (offset))
355
356 #endif /* __TVBUFF_H__ */