regen pidl all: rm epan/dissectors/pidl/*-stamp; pushd epan/dissectors/pidl/ && make...
[wireshark-sm.git] / epan / wslua / wslua_tvb.c
blob01ecb6591fdff03feb86c3eac0e582f7bfcc5498
1 /*
2 * wslua_tvb.c
4 * Wireshark's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
7 * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
8 * (c) 2009, Stig Bjorlykke <stig@bjorlykke.org>
9 * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include "config.h"
20 #include "wslua.h"
21 #include <epan/wmem_scopes.h>
24 /* WSLUA_MODULE Tvb Functions For Handling Packet Data */
28 * Tvb & TvbRange
30 * a Tvb represents a tvbuff_t in Lua.
31 * a TvbRange represents a range in a tvb (tvb,offset,length) its main purpose is to do bounds checking,
32 * It helps, too, simplifying argument passing to Tree.
34 * Normally in Wireshark explicit bounds checking is unnecessary as the tvbuff
35 * functions throw appropriate exceptions depending on why data wasn't present.
36 * In Lua, the interaction between the exception handling in epan and Lua's error
37 * handling, both of which use setjmp/longjmp, requires careful programming to
38 * avoid longjmp'ing down to the stack to a location that has already exited,
39 * particularly when Lua dissector calls are nested. TvbRange reduces the amount
40 * of possible exceptions (and TRY/CATCH to deal with them) by doing preemptive
41 * bounds checking - at a cost of making it impossible to support truncated
42 * captures where captured length < reported length (#15655).
44 * These lua objects refer to structures in wireshark that are freed independently from Lua's garbage collector.
45 * To avoid using pointers from Lua to Wireshark structures that are already freed, we maintain a list of the
46 * pointers each with a marker that tracks its expiry.
48 * All pointers are marked as expired when the dissection of the current frame is finished or when the garbage
49 * collector tries to free the object referring to the pointer, whichever comes first.
51 * All allocated memory chunks used for tracking the pointers' state are freed after marking the pointer as expired
52 * by the garbage collector or by the end of the dissection of the current frame, whichever comes second.
54 * We check the expiry state of the pointer before each access.
58 WSLUA_CLASS_DEFINE(Tvb,FAIL_ON_NULL_OR_EXPIRED("Tvb"));
59 /* A <<lua_class_Tvb,`Tvb`>> represents the packet's buffer. It is passed as an argument to listeners and dissectors,
60 and can be used to extract information (via <<lua_class_TvbRange,`TvbRange`>>) from the packet's data.
62 To create a <<lua_class_TvbRange,`TvbRange`>> the <<lua_class_Tvb,`Tvb`>> must be called with offset and length as optional arguments;
63 the offset defaults to 0 and the length to `tvb:captured_len()`.
65 [WARNING]
66 ====
67 Tvbs are usable only by the current listener or dissector call and are destroyed
68 as soon as the listener or dissector returns, so references to them are unusable once the function
69 has returned.
70 ====
73 static GPtrArray* outstanding_Tvb;
74 static GPtrArray* outstanding_TvbRange;
76 /* this is used to push Tvbs that were created brand new by wslua code */
77 int push_wsluaTvb(lua_State* L, Tvb t) {
78 g_ptr_array_add(outstanding_Tvb,t);
79 pushTvb(L,t);
80 return 1;
83 #define PUSH_TVBRANGE(L,t) {g_ptr_array_add(outstanding_TvbRange,t);pushTvbRange(L,t);}
86 static void free_Tvb(Tvb tvb) {
87 if (!tvb) return;
89 if (!tvb->expired) {
90 tvb->expired = true;
91 } else {
92 if (tvb->need_free)
93 tvb_free(tvb->ws_tvb);
94 g_free(tvb);
98 void clear_outstanding_Tvb(void) {
99 while (outstanding_Tvb->len) {
100 Tvb tvb = (Tvb)g_ptr_array_remove_index_fast(outstanding_Tvb,0);
101 free_Tvb(tvb);
105 /* this is used to push Tvbs that just point to pre-existing C-code Tvbs */
106 Tvb* push_Tvb(lua_State* L, tvbuff_t* ws_tvb) {
107 Tvb tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
108 tvb->ws_tvb = ws_tvb;
109 tvb->expired = false;
110 tvb->need_free = false;
111 g_ptr_array_add(outstanding_Tvb,tvb);
112 return pushTvb(L,tvb);
116 WSLUA_METAMETHOD Tvb__tostring(lua_State* L) {
118 Convert the bytes of a <<lua_class_Tvb,`Tvb`>> into a string.
119 This is primarily useful for debugging purposes since the string will be truncated if it is too long.
121 Tvb tvb = checkTvb(L,1);
122 int len = tvb_captured_length(tvb->ws_tvb);
123 char* str = tvb_bytes_to_str(NULL,tvb->ws_tvb,0,len);
125 lua_pushfstring(L, "TVB(%d) : %s", len, str);
127 wmem_free(NULL, str);
129 WSLUA_RETURN(1); /* The string. */
132 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
133 static int Tvb__gc(lua_State* L) {
134 Tvb tvb = toTvb(L,1);
136 free_Tvb(tvb);
138 return 0;
142 WSLUA_METHOD Tvb_reported_len(lua_State* L) {
143 /* Obtain the reported length (length on the network) of a <<lua_class_Tvb,`Tvb`>>. */
144 Tvb tvb = checkTvb(L,1);
146 lua_pushinteger(L,tvb_reported_length(tvb->ws_tvb));
147 WSLUA_RETURN(1); /* The reported length of the <<lua_class_Tvb,`Tvb`>>. */
150 WSLUA_METHOD Tvb_captured_len(lua_State* L) {
151 /* Obtain the captured length (amount saved in the capture process) of a <<lua_class_Tvb,`Tvb`>>. */
152 Tvb tvb = checkTvb(L,1);
154 lua_pushinteger(L,tvb_captured_length(tvb->ws_tvb));
155 WSLUA_RETURN(1); /* The captured length of the <<lua_class_Tvb,`Tvb`>>. */
158 WSLUA_METHOD Tvb_len(lua_State* L) {
159 /* Obtain the captured length (amount saved in the capture process) of a <<lua_class_Tvb,`Tvb`>>.
160 Same as captured_len; kept only for backwards compatibility */
161 Tvb tvb = checkTvb(L,1);
163 lua_pushinteger(L,tvb_captured_length(tvb->ws_tvb));
164 WSLUA_RETURN(1); /* The captured length of the <<lua_class_Tvb,`Tvb`>>. */
167 WSLUA_METHOD Tvb_reported_length_remaining(lua_State* L) {
168 /* Obtain the reported (not captured) length of packet data to end of a <<lua_class_Tvb,`Tvb`>> or 0 if the
169 offset is beyond the end of the <<lua_class_Tvb,`Tvb`>>. */
170 #define WSLUA_OPTARG_Tvb_reported_length_remaining_OFFSET 2 /* The offset (in octets) from the beginning of the <<lua_class_Tvb,`Tvb`>>. Defaults to 0. */
171 Tvb tvb = checkTvb(L,1);
172 int offset = (int) luaL_optinteger(L, WSLUA_OPTARG_Tvb_reported_length_remaining_OFFSET, 0);
174 lua_pushinteger(L,tvb_reported_length_remaining(tvb->ws_tvb, offset));
175 WSLUA_RETURN(1); /* The remaining reported length of the <<lua_class_Tvb,`Tvb`>>. */
178 WSLUA_METHOD Tvb_bytes(lua_State* L) {
179 /* Obtain a <<lua_class_ByteArray,`ByteArray`>> from a <<lua_class_Tvb,`Tvb`>>. */
180 #define WSLUA_OPTARG_Tvb_bytes_OFFSET 2 /* The offset (in octets) from the beginning of the <<lua_class_Tvb,`Tvb`>>. Defaults to 0. */
181 #define WSLUA_OPTARG_Tvb_bytes_LENGTH 3 /* The length (in octets) of the range. Defaults to until the end of the <<lua_class_Tvb,`Tvb`>>. */
182 Tvb tvb = checkTvb(L,1);
183 GByteArray* ba;
184 #if LUA_VERSION_NUM >= 503
185 int offset = (int)luaL_optinteger(L, WSLUA_OPTARG_Tvb_bytes_OFFSET, 0);
186 int len = (int)luaL_optinteger(L, WSLUA_OPTARG_Tvb_bytes_LENGTH, -1);
187 #else
188 int offset = luaL_optint(L, WSLUA_OPTARG_Tvb_bytes_OFFSET, 0);
189 int len = luaL_optint(L,WSLUA_OPTARG_Tvb_bytes_LENGTH,-1);
190 #endif
191 if (tvb->expired) {
192 luaL_error(L,"expired tvb");
193 return 0;
196 if (len < 0) {
197 len = tvb_captured_length_remaining(tvb->ws_tvb,offset);
198 if (len < 0) {
199 luaL_error(L,"out of bounds");
200 return 0;
202 } else if ( (unsigned)(len + offset) > tvb_captured_length(tvb->ws_tvb)) {
203 luaL_error(L,"Range is out of bounds");
204 return 0;
207 ba = g_byte_array_new();
208 g_byte_array_append(ba, tvb_get_ptr(tvb->ws_tvb, offset, len), len);
209 pushByteArray(L,ba);
211 WSLUA_RETURN(1); /* The <<lua_class_ByteArray,`ByteArray`>> object or nil. */
214 WSLUA_METHOD Tvb_offset(lua_State* L) {
215 /* Returns the raw offset (from the beginning of the source <<lua_class_Tvb,`Tvb`>>) of a sub <<lua_class_Tvb,`Tvb`>>. */
216 Tvb tvb = checkTvb(L,1);
218 lua_pushinteger(L,tvb_raw_offset(tvb->ws_tvb));
219 WSLUA_RETURN(1); /* The raw offset of the <<lua_class_Tvb,`Tvb`>>. */
223 #if USED_FOR_DOC_PURPOSES
224 WSLUA_METAMETHOD Tvb__call(lua_State* L) {
225 /* Equivalent to tvb:range(...) */
226 return 0;
228 #endif
231 WSLUA_METHOD Tvb_range(lua_State* L) {
232 /* Creates a <<lua_class_TvbRange,`TvbRange`>> from this <<lua_class_Tvb,`Tvb`>>. */
233 #define WSLUA_OPTARG_Tvb_range_OFFSET 2 /* The offset (in octets) from the beginning of the <<lua_class_Tvb,`Tvb`>>. Defaults to 0. */
234 #define WSLUA_OPTARG_Tvb_range_LENGTH 3 /* The length (in octets) of the range. Defaults to -1, which specifies the remaining bytes in the <<lua_class_Tvb,`Tvb`>>. */
236 Tvb tvb = checkTvb(L,1);
237 int offset = (int) luaL_optinteger(L,WSLUA_OPTARG_Tvb_range_OFFSET,0);
238 int len = (int) luaL_optinteger(L,WSLUA_OPTARG_Tvb_range_LENGTH,-1);
240 if (push_TvbRange(L,tvb->ws_tvb,offset,len)) {
241 WSLUA_RETURN(1); /* The TvbRange */
244 return 0;
247 WSLUA_METHOD Tvb_raw(lua_State* L) {
248 /* Obtain a Lua string of the binary bytes in a <<lua_class_Tvb,`Tvb`>>. */
249 #define WSLUA_OPTARG_Tvb_raw_OFFSET 2 /* The position of the first byte. Default is 0, or the first byte. */
250 #define WSLUA_OPTARG_Tvb_raw_LENGTH 3 /* The length of the segment to get. Default is -1, or the remaining bytes in the <<lua_class_Tvb,`Tvb`>>. */
251 Tvb tvb = checkTvb(L,1);
252 int offset = (int) luaL_optinteger(L,WSLUA_OPTARG_Tvb_raw_OFFSET,0);
253 int len = (int) luaL_optinteger(L,WSLUA_OPTARG_Tvb_raw_LENGTH,-1);
255 if (!tvb) return 0;
256 if (tvb->expired) {
257 luaL_error(L,"expired tvb");
258 return 0;
261 if ((unsigned)offset > tvb_captured_length(tvb->ws_tvb)) {
262 WSLUA_OPTARG_ERROR(Tvb_raw,OFFSET,"offset beyond end of Tvb");
263 return 0;
266 if (len == -1) {
267 len = tvb_captured_length_remaining(tvb->ws_tvb,offset);
268 if (len < 0) {
269 luaL_error(L,"out of bounds");
270 return false;
272 } else if ( (unsigned)(len + offset) > tvb_captured_length(tvb->ws_tvb)) {
273 luaL_error(L,"Range is out of bounds");
274 return false;
277 lua_pushlstring(L, tvb_get_ptr(tvb->ws_tvb, offset, len), len);
279 WSLUA_RETURN(1); /* A Lua string of the binary bytes in the <<lua_class_Tvb,`Tvb`>>. */
282 WSLUA_METAMETHOD Tvb__eq(lua_State* L) {
283 /* Checks whether contents of two <<lua_class_Tvb,`Tvb`>>s are equal. */
284 Tvb tvb_l = checkTvb(L,1);
285 Tvb tvb_r = checkTvb(L,2);
287 int len_l = tvb_captured_length(tvb_l->ws_tvb);
288 int len_r = tvb_captured_length(tvb_r->ws_tvb);
290 /* it is not an error if their ds_tvb are different... they're just not equal */
291 if (len_l == len_r)
293 const char* lp = tvb_get_ptr(tvb_l->ws_tvb, 0, len_l);
294 const char* rp = tvb_get_ptr(tvb_r->ws_tvb, 0, len_r);
295 int i = 0;
297 for (; i < len_l; ++i) {
298 if (lp[i] != rp[i]) {
299 lua_pushboolean(L,0);
300 return 1;
303 lua_pushboolean(L,1);
304 } else {
305 lua_pushboolean(L,0);
308 return 1;
311 WSLUA_METHODS Tvb_methods[] = {
312 WSLUA_CLASS_FNREG(Tvb,bytes),
313 WSLUA_CLASS_FNREG(Tvb,range),
314 WSLUA_CLASS_FNREG(Tvb,offset),
315 WSLUA_CLASS_FNREG(Tvb,reported_len),
316 WSLUA_CLASS_FNREG(Tvb,reported_length_remaining),
317 WSLUA_CLASS_FNREG(Tvb,captured_len),
318 WSLUA_CLASS_FNREG(Tvb,len),
319 WSLUA_CLASS_FNREG(Tvb,raw),
320 { NULL, NULL }
323 WSLUA_META Tvb_meta[] = {
324 WSLUA_CLASS_MTREG(Tvb,eq),
325 WSLUA_CLASS_MTREG(Tvb,tostring),
326 {"__call", Tvb_range},
327 { NULL, NULL }
330 int Tvb_register(lua_State* L) {
331 WSLUA_REGISTER_CLASS(Tvb);
332 if (outstanding_Tvb != NULL) {
333 g_ptr_array_unref(outstanding_Tvb);
335 outstanding_Tvb = g_ptr_array_new();
336 return 0;
342 WSLUA_CLASS_DEFINE(TvbRange,FAIL_ON_NULL("TvbRange"));
344 A <<lua_class_TvbRange,`TvbRange`>> represents a usable range of a <<lua_class_Tvb,`Tvb`>> and is used to extract data from the <<lua_class_Tvb,`Tvb`>> that generated it.
346 <<lua_class_TvbRange,`TvbRange`>>s are created by calling a <<lua_class_Tvb,`Tvb`>> (e.g. 'tvb(offset,length)').
347 A length of -1, which is the default, means to use the bytes up to the end of the <<lua_class_Tvb,`Tvb`>>.
348 If the <<lua_class_TvbRange,`TvbRange`>> span is outside the <<lua_class_Tvb,`Tvb`>>'s range the creation will cause a runtime error.
351 static void free_TvbRange(TvbRange tvbr) {
352 if (!(tvbr && tvbr->tvb)) return;
354 if (!tvbr->tvb->expired) {
355 tvbr->tvb->expired = true;
356 } else {
357 free_Tvb(tvbr->tvb);
358 g_free(tvbr);
362 void clear_outstanding_TvbRange(void) {
363 while (outstanding_TvbRange->len) {
364 TvbRange tvbr = (TvbRange)g_ptr_array_remove_index_fast(outstanding_TvbRange,0);
365 free_TvbRange(tvbr);
370 bool push_TvbRange(lua_State* L, tvbuff_t* ws_tvb, int offset, int len) {
371 TvbRange tvbr;
373 if (!ws_tvb) {
374 luaL_error(L,"expired tvb");
375 return false;
378 if (len == -1) {
379 len = tvb_captured_length_remaining(ws_tvb,offset);
380 if (len < 0) {
381 luaL_error(L,"out of bounds");
382 return false;
384 } else if (len < -1) {
385 luaL_error(L, "negative length in tvb range");
386 return false;
387 } else if ( (unsigned)(len + offset) > tvb_captured_length(ws_tvb)) {
388 luaL_error(L,"Range is out of bounds");
389 return false;
392 tvbr = (TvbRange)g_malloc(sizeof(struct _wslua_tvbrange));
393 tvbr->tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
394 tvbr->tvb->ws_tvb = ws_tvb;
395 tvbr->tvb->expired = false;
396 tvbr->tvb->need_free = false;
397 tvbr->offset = offset;
398 tvbr->len = len;
400 PUSH_TVBRANGE(L,tvbr);
402 return true;
406 WSLUA_METHOD TvbRange_tvb(lua_State *L) {
407 /* Creates a new <<lua_class_Tvb,`Tvb`>> from a <<lua_class_TvbRange,`TvbRange`>>. */
409 TvbRange tvbr = checkTvbRange(L,1);
410 Tvb tvb;
412 if (! (tvbr && tvbr->tvb)) return 0;
413 if (tvbr->tvb->expired) {
414 luaL_error(L,"expired tvb");
415 return 0;
418 if (tvb_offset_exists(tvbr->tvb->ws_tvb, tvbr->offset + tvbr->len -1 )) {
419 tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
420 tvb->expired = false;
421 tvb->need_free = false;
422 tvb->ws_tvb = tvb_new_subset_length(tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len);
423 return push_wsluaTvb(L, tvb);
424 } else {
425 luaL_error(L,"Out Of Bounds");
426 return 0;
432 * get a Blefuscuoan unsigned integer from a tvb
434 WSLUA_METHOD TvbRange_uint(lua_State* L) {
435 /* Get a Big Endian (network order) unsigned integer from a <<lua_class_TvbRange,`TvbRange`>>.
436 The range must be 1-4 octets long. */
437 TvbRange tvbr = checkTvbRange(L,1);
438 if (!(tvbr && tvbr->tvb)) return 0;
439 if (tvbr->tvb->expired) {
440 luaL_error(L,"expired tvb");
441 return 0;
444 switch (tvbr->len) {
445 case 1:
446 lua_pushinteger(L,tvb_get_uint8(tvbr->tvb->ws_tvb,tvbr->offset));
447 return 1;
448 case 2:
449 lua_pushinteger(L,tvb_get_ntohs(tvbr->tvb->ws_tvb,tvbr->offset));
450 return 1;
451 case 3:
452 lua_pushinteger(L,tvb_get_ntoh24(tvbr->tvb->ws_tvb,tvbr->offset));
453 return 1;
454 case 4:
455 lua_pushinteger(L,tvb_get_ntohl(tvbr->tvb->ws_tvb,tvbr->offset));
456 WSLUA_RETURN(1); /* The unsigned integer value. */
457 default:
458 luaL_error(L,"TvbRange:uint() does not handle %d byte integers",tvbr->len);
459 return 0;
464 * get a Lilliputian unsigned integer from a tvb
466 WSLUA_METHOD TvbRange_le_uint(lua_State* L) {
467 /* Get a Little Endian unsigned integer from a <<lua_class_TvbRange,`TvbRange`>>.
468 The range must be 1-4 octets long. */
469 TvbRange tvbr = checkTvbRange(L,1);
470 if (!(tvbr && tvbr->tvb)) return 0;
471 if (tvbr->tvb->expired) {
472 luaL_error(L,"expired tvb");
473 return 0;
476 switch (tvbr->len) {
477 case 1:
478 /* XXX unsigned anyway */
479 lua_pushinteger(L,(lua_Integer)(unsigned)tvb_get_uint8(tvbr->tvb->ws_tvb,tvbr->offset));
480 return 1;
481 case 2:
482 lua_pushinteger(L,tvb_get_letohs(tvbr->tvb->ws_tvb,tvbr->offset));
483 return 1;
484 case 3:
485 lua_pushinteger(L,tvb_get_letoh24(tvbr->tvb->ws_tvb,tvbr->offset));
486 return 1;
487 case 4:
488 lua_pushinteger(L,tvb_get_letohl(tvbr->tvb->ws_tvb,tvbr->offset));
489 WSLUA_RETURN(1); /* The unsigned integer value */
490 default:
491 luaL_error(L,"TvbRange:le_uint() does not handle %d byte integers",tvbr->len);
492 return 0;
497 * get a Blefuscuoan unsigned 64 bit integer from a tvb
499 WSLUA_METHOD TvbRange_uint64(lua_State* L) {
500 /* Get a Big Endian (network order) unsigned 64 bit integer from a <<lua_class_TvbRange,`TvbRange`>>, as a <<lua_class_UInt64,`UInt64`>> object.
501 The range must be 1-8 octets long. */
502 TvbRange tvbr = checkTvbRange(L,1);
503 if (!(tvbr && tvbr->tvb)) return 0;
504 if (tvbr->tvb->expired) {
505 luaL_error(L,"expired tvb");
506 return 0;
509 switch (tvbr->len) {
510 case 1:
511 pushUInt64(L,tvb_get_uint8(tvbr->tvb->ws_tvb,tvbr->offset));
512 return 1;
513 case 2:
514 pushUInt64(L,tvb_get_ntohs(tvbr->tvb->ws_tvb,tvbr->offset));
515 return 1;
516 case 3:
517 pushUInt64(L,tvb_get_ntoh24(tvbr->tvb->ws_tvb,tvbr->offset));
518 return 1;
519 case 4:
520 pushUInt64(L,tvb_get_ntohl(tvbr->tvb->ws_tvb,tvbr->offset));
521 return 1;
522 case 5:
523 pushUInt64(L,tvb_get_ntoh40(tvbr->tvb->ws_tvb,tvbr->offset));
524 return 1;
525 case 6:
526 pushUInt64(L,tvb_get_ntoh48(tvbr->tvb->ws_tvb,tvbr->offset));
527 return 1;
528 case 7:
529 pushUInt64(L,tvb_get_ntoh56(tvbr->tvb->ws_tvb,tvbr->offset));
530 return 1;
531 case 8:
532 pushUInt64(L,tvb_get_ntoh64(tvbr->tvb->ws_tvb,tvbr->offset));
533 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> object. */
534 default:
535 luaL_error(L,"TvbRange:uint64() does not handle %d byte integers",tvbr->len);
536 return 0;
541 * get a Lilliputian unsigned 64 bit integer from a tvb
543 WSLUA_METHOD TvbRange_le_uint64(lua_State* L) {
544 /* Get a Little Endian unsigned 64 bit integer from a <<lua_class_TvbRange,`TvbRange`>>, as a <<lua_class_UInt64,`UInt64`>> object.
545 The range must be 1-8 octets long. */
546 TvbRange tvbr = checkTvbRange(L,1);
547 if (!(tvbr && tvbr->tvb)) return 0;
548 if (tvbr->tvb->expired) {
549 luaL_error(L,"expired tvb");
550 return 0;
553 switch (tvbr->len) {
554 case 1:
555 pushUInt64(L,tvb_get_uint8(tvbr->tvb->ws_tvb,tvbr->offset));
556 return 1;
557 case 2:
558 pushUInt64(L,tvb_get_letohs(tvbr->tvb->ws_tvb,tvbr->offset));
559 return 1;
560 case 3:
561 pushUInt64(L,tvb_get_letoh24(tvbr->tvb->ws_tvb,tvbr->offset));
562 return 1;
563 case 4:
564 pushUInt64(L,tvb_get_letohl(tvbr->tvb->ws_tvb,tvbr->offset));
565 return 1;
566 case 5:
567 pushUInt64(L,tvb_get_letoh40(tvbr->tvb->ws_tvb,tvbr->offset));
568 return 1;
569 case 6:
570 pushUInt64(L,tvb_get_letoh48(tvbr->tvb->ws_tvb,tvbr->offset));
571 return 1;
572 case 7:
573 pushUInt64(L,tvb_get_letoh56(tvbr->tvb->ws_tvb,tvbr->offset));
574 return 1;
575 case 8:
576 pushUInt64(L,tvb_get_letoh64(tvbr->tvb->ws_tvb,tvbr->offset));
577 WSLUA_RETURN(1); /* The <<lua_class_UInt64,`UInt64`>> object. */
578 default:
579 luaL_error(L,"TvbRange:le_uint64() does not handle %d byte integers",tvbr->len);
580 return 0;
585 * get a Blefuscuoan signed integer from a tvb
587 WSLUA_METHOD TvbRange_int(lua_State* L) {
588 /* Get a Big Endian (network order) signed integer from a <<lua_class_TvbRange,`TvbRange`>>.
589 The range must be 1-4 octets long. */
590 TvbRange tvbr = checkTvbRange(L,1);
591 if (!(tvbr && tvbr->tvb)) return 0;
592 if (tvbr->tvb->expired) {
593 luaL_error(L,"expired tvb");
594 return 0;
597 switch (tvbr->len) {
598 case 1:
599 lua_pushinteger(L,tvb_get_int8(tvbr->tvb->ws_tvb,tvbr->offset));
600 return 1;
601 case 2:
602 lua_pushinteger(L,tvb_get_ntohis(tvbr->tvb->ws_tvb,tvbr->offset));
603 return 1;
604 case 3:
605 lua_pushinteger(L,tvb_get_ntohi24(tvbr->tvb->ws_tvb,tvbr->offset));
606 return 1;
607 case 4:
608 lua_pushinteger(L,tvb_get_ntohil(tvbr->tvb->ws_tvb,tvbr->offset));
609 WSLUA_RETURN(1); /* The signed integer value. */
611 * XXX:
612 * lua uses double so we have 52 bits to play with
613 * we are missing 5 and 6 byte integers within lua's range
614 * and 64 bit integers are not supported (there's a lib for
615 * lua that does).
617 default:
618 luaL_error(L,"TvbRange:int() does not handle %d byte integers",tvbr->len);
619 return 0;
624 * get a Lilliputian signed integer from a tvb
626 WSLUA_METHOD TvbRange_le_int(lua_State* L) {
627 /* Get a Little Endian signed integer from a <<lua_class_TvbRange,`TvbRange`>>.
628 The range must be 1-4 octets long. */
629 TvbRange tvbr = checkTvbRange(L,1);
630 if (!(tvbr && tvbr->tvb)) return 0;
631 if (tvbr->tvb->expired) {
632 luaL_error(L,"expired tvb");
633 return 0;
636 switch (tvbr->len) {
637 case 1:
638 lua_pushinteger(L,tvb_get_int8(tvbr->tvb->ws_tvb,tvbr->offset));
639 return 1;
640 case 2:
641 lua_pushinteger(L,tvb_get_letohis(tvbr->tvb->ws_tvb,tvbr->offset));
642 return 1;
643 case 3:
644 lua_pushinteger(L,tvb_get_letohi24(tvbr->tvb->ws_tvb,tvbr->offset));
645 return 1;
646 case 4:
647 lua_pushinteger(L,tvb_get_letohil(tvbr->tvb->ws_tvb,tvbr->offset));
648 WSLUA_RETURN(1); /* The signed integer value. */
649 default:
650 luaL_error(L,"TvbRange:le_int() does not handle %d byte integers",tvbr->len);
651 return 0;
656 * get a Blefuscuoan signed 64 bit integer from a tvb
658 WSLUA_METHOD TvbRange_int64(lua_State* L) {
659 /* Get a Big Endian (network order) signed 64 bit integer from a <<lua_class_TvbRange,`TvbRange`>>, as an <<lua_class_Int64,`Int64`>> object.
660 The range must be 1-8 octets long. */
661 TvbRange tvbr = checkTvbRange(L,1);
662 if (!(tvbr && tvbr->tvb)) return 0;
663 if (tvbr->tvb->expired) {
664 luaL_error(L,"expired tvb");
665 return 0;
668 switch (tvbr->len) {
669 case 1:
670 pushInt64(L,tvb_get_int8(tvbr->tvb->ws_tvb,tvbr->offset));
671 return 1;
672 case 2:
673 pushInt64(L,tvb_get_ntohis(tvbr->tvb->ws_tvb,tvbr->offset));
674 return 1;
675 case 3:
676 pushInt64(L,tvb_get_ntohi24(tvbr->tvb->ws_tvb,tvbr->offset));
677 return 1;
678 case 4:
679 pushInt64(L,tvb_get_ntohil(tvbr->tvb->ws_tvb,tvbr->offset));
680 return 1;
681 case 5:
682 pushInt64(L,tvb_get_ntohi40(tvbr->tvb->ws_tvb,tvbr->offset));
683 return 1;
684 case 6:
685 pushInt64(L,tvb_get_ntohi48(tvbr->tvb->ws_tvb,tvbr->offset));
686 return 1;
687 case 7:
688 pushInt64(L,tvb_get_ntohi56(tvbr->tvb->ws_tvb,tvbr->offset));
689 return 1;
690 case 8:
691 pushInt64(L,tvb_get_ntohi64(tvbr->tvb->ws_tvb,tvbr->offset));
692 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object. */
693 default:
694 luaL_error(L,"TvbRange:int64() does not handle %d byte integers",tvbr->len);
695 return 0;
700 * get a Lilliputian signed 64 bit integer from a tvb
702 WSLUA_METHOD TvbRange_le_int64(lua_State* L) {
703 /* Get a Little Endian signed 64 bit integer from a <<lua_class_TvbRange,`TvbRange`>>, as an <<lua_class_Int64,`Int64`>> object.
704 The range must be 1-8 octets long. */
705 TvbRange tvbr = checkTvbRange(L,1);
706 if (!(tvbr && tvbr->tvb)) return 0;
707 if (tvbr->tvb->expired) {
708 luaL_error(L,"expired tvb");
709 return 0;
712 switch (tvbr->len) {
713 case 1:
714 pushInt64(L,tvb_get_int8(tvbr->tvb->ws_tvb,tvbr->offset));
715 return 1;
716 case 2:
717 pushInt64(L,tvb_get_letohis(tvbr->tvb->ws_tvb,tvbr->offset));
718 return 1;
719 case 3:
720 pushInt64(L,tvb_get_letohi24(tvbr->tvb->ws_tvb,tvbr->offset));
721 return 1;
722 case 4:
723 pushInt64(L,tvb_get_letohil(tvbr->tvb->ws_tvb,tvbr->offset));
724 return 1;
725 case 5:
726 pushInt64(L,tvb_get_letohi40(tvbr->tvb->ws_tvb,tvbr->offset));
727 return 1;
728 case 6:
729 pushInt64(L,tvb_get_letohi48(tvbr->tvb->ws_tvb,tvbr->offset));
730 return 1;
731 case 7:
732 pushInt64(L,tvb_get_letohi56(tvbr->tvb->ws_tvb,tvbr->offset));
733 return 1;
734 case 8:
735 pushInt64(L,tvb_get_letohi64(tvbr->tvb->ws_tvb,tvbr->offset));
736 WSLUA_RETURN(1); /* The <<lua_class_Int64,`Int64`>> object. */
737 default:
738 luaL_error(L,"TvbRange:le_int64() does not handle %d byte integers",tvbr->len);
739 return 0;
744 * get a Blefuscuoan float
746 WSLUA_METHOD TvbRange_float(lua_State* L) {
747 /* Get a Big Endian (network order) floating point number from a <<lua_class_TvbRange,`TvbRange`>>.
748 The range must be 4 or 8 octets long. */
749 TvbRange tvbr = checkTvbRange(L,1);
750 if (!(tvbr && tvbr->tvb)) return 0;
751 if (tvbr->tvb->expired) {
752 luaL_error(L,"expired tvb");
753 return 0;
756 switch (tvbr->len) {
757 case 4:
758 lua_pushnumber(L,(double)tvb_get_ntohieee_float(tvbr->tvb->ws_tvb,tvbr->offset));
759 return 1;
760 case 8:
761 lua_pushnumber(L,tvb_get_ntohieee_double(tvbr->tvb->ws_tvb,tvbr->offset));
762 WSLUA_RETURN(1); /* The floating point value. */
763 default:
764 luaL_error(L,"TvbRange:float() does not handle %d byte floating numbers",tvbr->len);
765 return 0;
770 * get a Lilliputian float
772 WSLUA_METHOD TvbRange_le_float(lua_State* L) {
773 /* Get a Little Endian floating point number from a <<lua_class_TvbRange,`TvbRange`>>.
774 The range must be 4 or 8 octets long. */
775 TvbRange tvbr = checkTvbRange(L,1);
776 if (!(tvbr && tvbr->tvb)) return 0;
778 switch (tvbr->len) {
779 case 4:
780 lua_pushnumber(L,tvb_get_letohieee_float(tvbr->tvb->ws_tvb,tvbr->offset));
781 return 1;
782 case 8:
783 lua_pushnumber(L,tvb_get_letohieee_double(tvbr->tvb->ws_tvb,tvbr->offset));
784 WSLUA_RETURN(1); /* The floating point value. */
785 default:
786 luaL_error(L,"TvbRange:le_float() does not handle %d byte floating numbers",tvbr->len);
787 return 0;
791 WSLUA_METHOD TvbRange_ipv4(lua_State* L) {
792 /* Get an IPv4 Address from a <<lua_class_TvbRange,`TvbRange`>>, as an <<lua_class_Address,`Address`>> object. */
793 TvbRange tvbr = checkTvbRange(L,1);
794 Address addr;
796 if ( !(tvbr && tvbr->tvb)) return 0;
797 if (tvbr->tvb->expired) {
798 luaL_error(L,"expired tvb");
799 return 0;
802 if (tvbr->len != 4) {
803 WSLUA_ERROR(TvbRange_ipv4,"The range must be 4 octets long");
804 return 0;
807 addr = g_new(address,1);
808 alloc_address_tvb(NULL,addr,AT_IPv4,sizeof(uint32_t),tvbr->tvb->ws_tvb,tvbr->offset);
809 pushAddress(L,addr);
811 WSLUA_RETURN(1); /* The IPv4 <<lua_class_Address,`Address`>> object. */
814 WSLUA_METHOD TvbRange_le_ipv4(lua_State* L) {
815 /* Get an Little Endian IPv4 Address from a <<lua_class_TvbRange,`TvbRange`>>, as an <<lua_class_Address,`Address`>> object. */
816 TvbRange tvbr = checkTvbRange(L,1);
817 Address addr;
818 uint32_t ip_addr;
820 if ( !(tvbr && tvbr->tvb)) return 0;
821 if (tvbr->tvb->expired) {
822 luaL_error(L,"expired tvb");
823 return 0;
826 if (tvbr->len != 4) {
827 WSLUA_ERROR(TvbRange_ipv4,"The range must be 4 octets long");
828 return 0;
831 addr = g_new(address,1);
832 ip_addr = GUINT32_SWAP_LE_BE(tvb_get_ipv4(tvbr->tvb->ws_tvb,tvbr->offset));
833 alloc_address_wmem(NULL, addr, AT_IPv4, sizeof(ip_addr), &ip_addr);
834 pushAddress(L,addr);
836 WSLUA_RETURN(1); /* The IPv4 <<lua_class_Address,`Address`>> object. */
839 WSLUA_METHOD TvbRange_ipv6(lua_State* L) {
840 /* Get an IPv6 Address from a <<lua_class_TvbRange,`TvbRange`>>, as an <<lua_class_Address,`Address`>> object. */
841 TvbRange tvbr = checkTvbRange(L,1);
842 Address addr;
844 if ( !(tvbr && tvbr->tvb)) return 0;
845 if (tvbr->tvb->expired) {
846 luaL_error(L,"expired tvb");
847 return 0;
850 if (tvbr->len != 16) {
851 WSLUA_ERROR(TvbRange_ipv6,"The range must be 16 octets long");
852 return 0;
855 addr = g_new(address,1);
856 alloc_address_tvb(NULL,addr,AT_IPv6,16,tvbr->tvb->ws_tvb,tvbr->offset);
857 pushAddress(L,addr);
859 WSLUA_RETURN(1); /* The IPv6 <<lua_class_Address,`Address`>> object. */
862 WSLUA_METHOD TvbRange_ether(lua_State* L) {
863 /* Get an Ethernet Address from a <<lua_class_TvbRange,`TvbRange`>>, as an <<lua_class_Address,`Address`>> object. */
864 TvbRange tvbr = checkTvbRange(L,1);
865 Address addr;
867 if ( !(tvbr && tvbr->tvb)) return 0;
868 if (tvbr->tvb->expired) {
869 luaL_error(L,"expired tvb");
870 return 0;
873 if (tvbr->len != 6) {
874 WSLUA_ERROR(TvbRange_ether,"The range must be 6 bytes long");
875 return 0;
878 addr = g_new(address,1);
879 alloc_address_tvb(NULL,addr,AT_ETHER,6,tvbr->tvb->ws_tvb,tvbr->offset);
880 pushAddress(L,addr);
882 WSLUA_RETURN(1); /* The Ethernet <<lua_class_Address,`Address`>> object. */
885 WSLUA_METHOD TvbRange_nstime(lua_State* L) {
886 /* Obtain a time_t structure from a <<lua_class_TvbRange,`TvbRange`>>, as an <<lua_class_NSTime,`NSTime`>> object. */
887 #define WSLUA_OPTARG_TvbRange_nstime_ENCODING 2 /* An optional ENC_* encoding value to use */
888 TvbRange tvbr = checkTvbRange(L,1);
889 NSTime nstime;
890 const unsigned encoding = (unsigned) luaL_optinteger(L, WSLUA_OPTARG_TvbRange_nstime_ENCODING, 0);
892 if ( !(tvbr && tvbr->tvb)) return 0;
893 if (tvbr->tvb->expired) {
894 luaL_error(L,"expired tvb");
895 return 0;
898 if (encoding & ~ENC_STR_TIME_MASK) {
899 WSLUA_OPTARG_ERROR(TvbRange_nstime, ENCODING, "invalid encoding value");
900 return 0;
903 nstime = g_new(nstime_t,1);
905 if (encoding == 0) {
906 if (tvbr->len == 4) {
907 nstime->secs = tvb_get_ntohl(tvbr->tvb->ws_tvb, tvbr->offset);
908 nstime->nsecs = 0;
909 } else if (tvbr->len == 8) {
910 nstime->secs = tvb_get_ntohl(tvbr->tvb->ws_tvb, tvbr->offset);
911 nstime->nsecs = tvb_get_ntohl(tvbr->tvb->ws_tvb, tvbr->offset + 4);
912 } else {
913 g_free(nstime);
914 WSLUA_ERROR(TvbRange_nstime,"The range must be 4 or 8 bytes long");
915 return 0;
917 pushNSTime(L, nstime);
918 lua_pushinteger(L, tvbr->len);
920 else {
921 int endoff = 0;
922 nstime_t *retval = tvb_get_string_time(tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len,
923 encoding, nstime, &endoff);
924 if (!retval || endoff == 0) {
925 g_free(nstime);
926 /* push nil nstime and offset */
927 lua_pushnil(L);
928 lua_pushnil(L);
930 else {
931 pushNSTime(L, nstime);
932 lua_pushinteger(L, endoff);
936 WSLUA_RETURN(2); /* The <<lua_class_NSTime,`NSTime`>> object and number of bytes used, or nil on failure. */
939 WSLUA_METHOD TvbRange_le_nstime(lua_State* L) {
940 /* Obtain a nstime from a <<lua_class_TvbRange,`TvbRange`>>, as an <<lua_class_NSTime,`NSTime`>> object. */
941 TvbRange tvbr = checkTvbRange(L,1);
942 NSTime nstime;
944 if ( !(tvbr && tvbr->tvb)) return 0;
945 if (tvbr->tvb->expired) {
946 luaL_error(L,"expired tvb");
947 return 0;
950 nstime = g_new(nstime_t,1);
952 if (tvbr->len == 4) {
953 nstime->secs = tvb_get_letohl(tvbr->tvb->ws_tvb, tvbr->offset);
954 nstime->nsecs = 0;
955 } else if (tvbr->len == 8) {
956 nstime->secs = tvb_get_letohl(tvbr->tvb->ws_tvb, tvbr->offset);
957 nstime->nsecs = tvb_get_letohl(tvbr->tvb->ws_tvb, tvbr->offset + 4);
958 } else {
959 g_free(nstime);
960 WSLUA_ERROR(TvbRange_nstime,"The range must be 4 or 8 bytes long");
961 return 0;
964 pushNSTime(L, nstime);
966 WSLUA_RETURN(1); /* The <<lua_class_NSTime,`NSTime`>> object. */
969 WSLUA_METHOD TvbRange_string(lua_State* L) {
970 /* Obtain a string from a <<lua_class_TvbRange,`TvbRange`>>. */
971 #define WSLUA_OPTARG_TvbRange_string_ENCODING 2 /* The encoding to use. Defaults to ENC_ASCII. */
972 TvbRange tvbr = checkTvbRange(L,1);
973 unsigned encoding = (unsigned)luaL_optinteger(L,WSLUA_OPTARG_TvbRange_string_ENCODING, ENC_ASCII|ENC_NA);
974 char * str;
976 if ( !(tvbr && tvbr->tvb)) return 0;
977 if (tvbr->tvb->expired) {
978 luaL_error(L,"expired tvb");
979 return 0;
982 str = (char*)tvb_get_string_enc(NULL,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,encoding);
983 lua_pushlstring(L, str, strlen(str));
984 wmem_free(NULL, str);
986 WSLUA_RETURN(1); /* A string containing all bytes in the <<lua_class_TvbRange,`TvbRange`>> including all zeroes (e.g., "a\000bc\000"). */
989 static int TvbRange_ustring_any(lua_State* L, bool little_endian) {
990 /* Obtain a UTF-16 encoded string from a <<lua_class_TvbRange,`TvbRange`>>. */
991 TvbRange tvbr = checkTvbRange(L,1);
992 char * str;
994 if ( !(tvbr && tvbr->tvb)) return 0;
995 if (tvbr->tvb->expired) {
996 luaL_error(L,"expired tvb");
997 return 0;
1000 str = (char*)tvb_get_string_enc(NULL,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(little_endian ? ENC_UTF_16|ENC_LITTLE_ENDIAN : ENC_UTF_16|ENC_BIG_ENDIAN));
1001 lua_pushlstring(L, str, strlen(str));
1002 wmem_free(NULL, str);
1004 return 1; /* The string */
1007 WSLUA_METHOD TvbRange_ustring(lua_State* L) {
1008 /* Obtain a Big Endian (network order) UTF-16 encoded string from a <<lua_class_TvbRange,`TvbRange`>>. */
1009 WSLUA_RETURN(TvbRange_ustring_any(L, false)); /* A string containing all bytes in the <<lua_class_TvbRange,`TvbRange`>> including all zeroes (e.g., "a\000bc\000"). */
1012 WSLUA_METHOD TvbRange_le_ustring(lua_State* L) {
1013 /* Obtain a Little Endian UTF-16 encoded string from a <<lua_class_TvbRange,`TvbRange`>>. */
1014 WSLUA_RETURN(TvbRange_ustring_any(L, true)); /* A string containing all bytes in the <<lua_class_TvbRange,`TvbRange`>> including all zeroes (e.g., "a\000bc\000"). */
1017 WSLUA_METHOD TvbRange_stringz(lua_State* L) {
1018 /* Obtain a zero terminated string from a <<lua_class_TvbRange,`TvbRange`>>. */
1019 #define WSLUA_OPTARG_TvbRange_stringz_ENCODING 2 /* The encoding to use. Defaults to ENC_ASCII. */
1020 TvbRange tvbr = checkTvbRange(L,1);
1021 unsigned encoding = (unsigned)luaL_optinteger(L,WSLUA_OPTARG_TvbRange_stringz_ENCODING, ENC_ASCII|ENC_NA);
1022 int offset;
1023 gunichar2 uchar;
1024 char *str;
1026 if ( !(tvbr && tvbr->tvb)) return 0;
1027 if (tvbr->tvb->expired) {
1028 luaL_error(L,"expired tvb");
1029 return 0;
1032 switch (encoding & ENC_CHARENCODING_MASK) {
1034 case ENC_UTF_16:
1035 case ENC_UCS_2:
1036 offset = tvbr->offset;
1037 do {
1038 if (!tvb_bytes_exist (tvbr->tvb->ws_tvb, offset, 2)) {
1039 luaL_error(L,"out of bounds");
1040 return 0;
1042 /* Endianness doesn't matter when looking for null */
1043 uchar = tvb_get_ntohs (tvbr->tvb->ws_tvb, offset);
1044 offset += 2;
1045 } while(uchar != 0);
1046 break;
1048 default:
1049 if (tvb_find_uint8 (tvbr->tvb->ws_tvb, tvbr->offset, -1, 0) == -1) {
1050 luaL_error(L,"out of bounds");
1051 return 0;
1053 break;
1056 str = (char*)tvb_get_stringz_enc(NULL,tvbr->tvb->ws_tvb,tvbr->offset,NULL,encoding);
1057 lua_pushstring(L, str);
1058 wmem_free(NULL, str);
1060 WSLUA_RETURN(1); /* The string containing all bytes in the <<lua_class_TvbRange,`TvbRange`>> up to the first terminating zero. */
1063 WSLUA_METHOD TvbRange_strsize(lua_State* L) {
1065 Find the size of a zero terminated string from a <<lua_class_TvbRange,`TvbRange`>>.
1066 The size of the string includes the terminating zero. */
1067 #define WSLUA_OPTARG_TvbRange_strsize_ENCODING 2 /* The encoding to use. Defaults to ENC_ASCII. */
1068 TvbRange tvbr = checkTvbRange(L,1);
1069 unsigned encoding = (unsigned)luaL_optinteger(L,WSLUA_OPTARG_TvbRange_strsize_ENCODING, ENC_ASCII|ENC_NA);
1070 int offset;
1071 gunichar2 uchar;
1073 if ( !(tvbr && tvbr->tvb)) return 0;
1074 if (tvbr->tvb->expired) {
1075 luaL_error(L,"expired tvb");
1076 return 0;
1079 switch (encoding & ENC_CHARENCODING_MASK) {
1081 case ENC_UTF_16:
1082 case ENC_UCS_2:
1083 offset = tvbr->offset;
1084 do {
1085 if (!tvb_bytes_exist (tvbr->tvb->ws_tvb, offset, 2)) {
1086 luaL_error(L,"out of bounds");
1087 return 0;
1089 /* Endianness doesn't matter when looking for null */
1090 uchar = tvb_get_ntohs (tvbr->tvb->ws_tvb, offset);
1091 offset += 2;
1092 } while (uchar != 0);
1093 lua_pushinteger(L, tvb_unicode_strsize(tvbr->tvb->ws_tvb, tvbr->offset));
1094 break;
1096 default:
1097 if (tvb_find_uint8 (tvbr->tvb->ws_tvb, tvbr->offset, -1, 0) == -1) {
1098 luaL_error(L,"out of bounds");
1099 return 0;
1101 lua_pushinteger(L, tvb_strsize(tvbr->tvb->ws_tvb, tvbr->offset));
1102 break;
1105 WSLUA_RETURN(1); /* Length of the zero terminated string. */
1109 static int TvbRange_ustringz_any(lua_State* L, bool little_endian) {
1110 /* Obtain a zero terminated string from a TvbRange */
1111 int count;
1112 TvbRange tvbr = checkTvbRange(L,1);
1113 int offset;
1114 gunichar2 uchar;
1115 char *str;
1117 if ( !(tvbr && tvbr->tvb)) return 0;
1118 if (tvbr->tvb->expired) {
1119 luaL_error(L,"expired tvb");
1120 return 0;
1123 offset = tvbr->offset;
1124 do {
1125 if (!tvb_bytes_exist (tvbr->tvb->ws_tvb, offset, 2)) {
1126 luaL_error(L,"out of bounds");
1127 return 0;
1129 /* Endianness doesn't matter when looking for null */
1130 uchar = tvb_get_ntohs (tvbr->tvb->ws_tvb, offset);
1131 offset += 2;
1132 } while (uchar != 0);
1134 str = (char*)tvb_get_stringz_enc(NULL,tvbr->tvb->ws_tvb,tvbr->offset,&count,
1135 (little_endian ? ENC_UTF_16|ENC_LITTLE_ENDIAN : ENC_UTF_16|ENC_BIG_ENDIAN));
1136 lua_pushstring(L, str);
1137 lua_pushinteger(L,count);
1138 wmem_free(NULL, str);
1140 return 2; /* The zero terminated string, the length found in tvbr */
1143 WSLUA_METHOD TvbRange_ustringz(lua_State* L) {
1144 /* Obtain a Big Endian (network order) UTF-16 encoded zero terminated string from a <<lua_class_TvbRange,`TvbRange`>>. */
1145 WSLUA_RETURN(TvbRange_ustringz_any(L, false)); /* Two return values: the zero terminated string, and the length. */
1148 WSLUA_METHOD TvbRange_le_ustringz(lua_State* L) {
1149 /* Obtain a Little Endian UTF-16 encoded zero terminated string from a TvbRange */
1150 WSLUA_RETURN(TvbRange_ustringz_any(L, true)); /* Two return values: the zero terminated string, and the length. */
1153 WSLUA_METHOD TvbRange_bytes(lua_State* L) {
1154 /* Obtain a <<lua_class_ByteArray,`ByteArray`>> from a <<lua_class_TvbRange,`TvbRange`>>.
1156 Starting in 1.11.4, this function also takes an optional `encoding` argument,
1157 which can be set to `ENC_STR_HEX` to decode a hex-string from the <<lua_class_TvbRange,`TvbRange`>>
1158 into the returned <<lua_class_ByteArray,`ByteArray`>>. The `encoding` can be bitwise-or'ed with one
1159 or more separator encodings, such as `ENC_SEP_COLON`, to allow separators
1160 to occur between each pair of hex characters.
1162 The return value also now returns the number of bytes used as a second return value.
1164 On failure or error, nil is returned for both return values.
1166 [NOTE]
1167 ====
1168 The encoding type of the hex string should also be set, for example
1169 `ENC_ASCII` or `ENC_UTF_8`, along with `ENC_STR_HEX`.
1170 ====
1172 #define WSLUA_OPTARG_TvbRange_bytes_ENCODING 2 /* An optional ENC_* encoding value to use */
1173 TvbRange tvbr = checkTvbRange(L,1);
1174 GByteArray* ba;
1175 uint8_t* raw;
1176 const unsigned encoding = (unsigned)luaL_optinteger(L, WSLUA_OPTARG_TvbRange_bytes_ENCODING, 0);
1179 if ( !(tvbr && tvbr->tvb)) return 0;
1180 if (tvbr->tvb->expired) {
1181 luaL_error(L,"expired tvb");
1182 return 0;
1185 if (encoding == 0) {
1186 ba = g_byte_array_new();
1187 raw = (uint8_t *)tvb_memdup(NULL,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len);
1188 g_byte_array_append(ba,raw,tvbr->len);
1189 wmem_free(NULL, raw);
1190 pushByteArray(L,ba);
1191 lua_pushinteger(L, tvbr->len);
1193 else if ((encoding & ENC_STR_HEX) == 0) {
1194 WSLUA_OPTARG_ERROR(TvbRange_nstime, ENCODING, "invalid encoding value");
1196 else {
1197 int endoff = 0;
1198 GByteArray* retval;
1200 ba = g_byte_array_new();
1201 retval = tvb_get_string_bytes(tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len,
1202 encoding, ba, &endoff);
1203 if (!retval || endoff == 0) {
1204 g_byte_array_free(ba, true);
1205 /* push nil nstime and offset */
1206 lua_pushnil(L);
1207 lua_pushnil(L);
1209 else {
1210 pushByteArray(L,ba);
1211 lua_pushinteger(L, endoff);
1215 WSLUA_RETURN(2); /* The <<lua_class_ByteArray,`ByteArray`>> object or nil, and number of bytes consumed or nil. */
1218 WSLUA_METHOD TvbRange_bitfield(lua_State* L) {
1219 /* Get a bitfield from a <<lua_class_TvbRange,`TvbRange`>>. */
1220 #define WSLUA_OPTARG_TvbRange_bitfield_POSITION 2 /* The bit offset (link:https://en.wikipedia.org/wiki/Bit_numbering#MSB_0_bit_numbering[MSB 0 bit numbering]) from the beginning of the <<lua_class_TvbRange,`TvbRange`>>. Defaults to 0. */
1221 #define WSLUA_OPTARG_TvbRange_bitfield_LENGTH 3 /* The length in bits of the field. Defaults to 1. */
1223 TvbRange tvbr = checkTvbRange(L,1);
1224 int pos = (int)luaL_optinteger(L,WSLUA_OPTARG_TvbRange_bitfield_POSITION,0);
1225 int len = (int)luaL_optinteger(L,WSLUA_OPTARG_TvbRange_bitfield_LENGTH,1);
1227 if (!(tvbr && tvbr->tvb)) return 0;
1228 if (tvbr->tvb->expired) {
1229 luaL_error(L,"expired tvb");
1230 return 0;
1233 if ((pos+len) > (tvbr->len<<3)) {
1234 luaL_error(L, "Requested bitfield out of range");
1235 return 0;
1238 if (len <= 32) {
1239 /* XXX - If LUA_INTEGER_SIZE is 4 (on Lua 5.3/5.4 it's usually 8), then
1240 * for len == 32 an unsigned won't necessarily fit in a lua_Integer.
1241 * Should we use a UInt64 then?
1243 WRAP_NON_LUA_EXCEPTIONS(
1244 lua_pushinteger(L,tvb_get_bits32(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len, false));
1246 } else if (len <= 64) {
1247 WRAP_NON_LUA_EXCEPTIONS(
1248 pushUInt64(L,tvb_get_bits64(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len, false));
1250 } else {
1251 luaL_error(L,"TvbRange:bitfield() does not handle %d bits",len);
1252 return 0;
1255 WSLUA_RETURN(1); /* The bitfield value */
1258 WSLUA_METHOD TvbRange_range(lua_State* L) {
1259 /* Creates a sub-<<lua_class_TvbRange,`TvbRange`>> from this <<lua_class_TvbRange,`TvbRange`>>. */
1260 #define WSLUA_OPTARG_TvbRange_range_OFFSET 2 /* The offset (in octets) from the beginning of the <<lua_class_TvbRange,`TvbRange`>>. Defaults to 0. */
1261 #define WSLUA_OPTARG_TvbRange_range_LENGTH 3 /* The length (in octets) of the range. Defaults to until the end of the <<lua_class_TvbRange,`TvbRange`>>. */
1263 TvbRange tvbr = checkTvbRange(L,1);
1264 int offset = (int)luaL_optinteger(L,WSLUA_OPTARG_TvbRange_range_OFFSET,0);
1265 int len;
1267 if (!(tvbr && tvbr->tvb)) return 0;
1269 len = (int)luaL_optinteger(L,WSLUA_OPTARG_TvbRange_range_LENGTH,tvbr->len-offset);
1271 if (tvbr->tvb->expired) {
1272 luaL_error(L,"expired tvb");
1273 return 0;
1276 if (offset >= tvbr->len || (len + offset) > tvbr->len) {
1277 luaL_error(L,"Range is out of bounds");
1278 return 0;
1281 if (push_TvbRange(L,tvbr->tvb->ws_tvb,tvbr->offset+offset,len)) {
1282 WSLUA_RETURN(1); /* The <<lua_class_TvbRange,`TvbRange`>>. */
1285 return 0;
1288 WSLUA_METHOD TvbRange_uncompress_zlib(lua_State* L) {
1289 /* Given a <<lua_class_TvbRange,`TvbRange`>> containing zlib compressed data, decompresses the data and returns a new <<lua_class_TvbRange,`TvbRange`>> containing the uncompressed data.
1290 @since 4.3.0
1292 #define WSLUA_ARG_TvbRange_uncompress_zlib_NAME 2 /* The name to be given to the new data-source. */
1293 TvbRange tvbr = checkTvbRange(L,1);
1294 #if defined (HAVE_ZLIB) || defined (HAVE_ZLIBNG)
1295 const char* name = luaL_optstring(L,WSLUA_ARG_TvbRange_uncompress_zlib_NAME,"Uncompressed");
1296 tvbuff_t *uncompr_tvb;
1297 #endif
1299 if (!(tvbr && tvbr->tvb)) return 0;
1301 if (tvbr->tvb->expired) {
1302 luaL_error(L,"expired tvb");
1303 return 0;
1306 #if defined (HAVE_ZLIB) || defined (HAVE_ZLIBNG)
1307 uncompr_tvb = tvb_child_uncompress_zlib(tvbr->tvb->ws_tvb, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
1308 if (uncompr_tvb) {
1309 add_new_data_source (lua_pinfo, uncompr_tvb, name);
1310 if (push_TvbRange(L,uncompr_tvb,0,tvb_captured_length(uncompr_tvb))) {
1311 WSLUA_RETURN(1); /* The <<lua_class_TvbRange,`TvbRange`>>. */
1314 #else
1315 luaL_error(L,"Missing support for ZLIB");
1316 #endif
1318 return 0;
1321 WSLUA_METHOD TvbRange_uncompress(lua_State* L) {
1322 /* Given a <<lua_class_TvbRange,`TvbRange`>> containing zlib compressed data, decompresses the data and returns a new <<lua_class_TvbRange,`TvbRange`>> containing the uncompressed data. Deprecated; use tvbrange:uncompress_zlib() instead. */
1323 #define WSLUA_ARG_TvbRange_uncompress_NAME 2 /* The name to be given to the new data-source. */
1324 return TvbRange_uncompress_zlib(L);
1327 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
1328 static int TvbRange__gc(lua_State* L) {
1329 TvbRange tvbr = checkTvbRange(L,1);
1331 free_TvbRange(tvbr);
1333 return 0;
1337 WSLUA_METHOD TvbRange_uncompress_brotli(lua_State* L) {
1338 /* Given a <<lua_class_TvbRange,`TvbRange`>> containing Brotli compressed data, decompresses the data and returns a new <<lua_class_TvbRange,`TvbRange`>> containing the uncompressed data.
1339 @since 4.3.0
1341 #define WSLUA_ARG_TvbRange_uncompress_brotli_NAME 2 /* The name to be given to the new data-source. */
1342 TvbRange tvbr = checkTvbRange(L,1);
1343 #ifdef HAVE_BROTLI
1344 const char* name = luaL_optstring(L,WSLUA_ARG_TvbRange_uncompress_brotli_NAME,"Uncompressed");
1345 tvbuff_t *uncompr_tvb;
1346 #endif
1348 if (!(tvbr && tvbr->tvb)) return 0;
1350 if (tvbr->tvb->expired) {
1351 luaL_error(L,"expired tvb");
1352 return 0;
1355 #ifdef HAVE_BROTLI
1356 uncompr_tvb = tvb_child_uncompress_brotli(tvbr->tvb->ws_tvb, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
1357 if (uncompr_tvb) {
1358 add_new_data_source (lua_pinfo, uncompr_tvb, name);
1359 if (push_TvbRange(L,uncompr_tvb,0,tvb_captured_length(uncompr_tvb))) {
1360 WSLUA_RETURN(1); /* The <<lua_class_TvbRange,`TvbRange`>>. */
1363 #else
1364 luaL_error(L,"Missing support for Brotli");
1365 #endif
1367 return 0;
1370 WSLUA_METHOD TvbRange_uncompress_hpack_huff(lua_State* L) {
1371 /* Given a <<lua_class_TvbRange,`TvbRange`>> containing data compressed using the Huffman encoding in HTTP/2 HPACK and HTTP/3 QPACK, decompresses the data and returns a new <<lua_class_TvbRange,`TvbRange`>> containing the uncompressed data.
1372 @since 4.3.0
1374 #define WSLUA_ARG_TvbRange_uncompress_hpack_huff_NAME 2 /* The name to be given to the new data-source. */
1375 TvbRange tvbr = checkTvbRange(L,1);
1376 const char* name = luaL_optstring(L,WSLUA_ARG_TvbRange_uncompress_hpack_huff_NAME,"Uncompressed");
1377 tvbuff_t *uncompr_tvb;
1379 if (!(tvbr && tvbr->tvb)) return 0;
1381 if (tvbr->tvb->expired) {
1382 luaL_error(L,"expired tvb");
1383 return 0;
1386 uncompr_tvb = tvb_child_uncompress_hpack_huff(tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
1387 if (uncompr_tvb) {
1388 add_new_data_source (lua_pinfo, uncompr_tvb, name);
1389 if (push_TvbRange(L,uncompr_tvb,0,tvb_captured_length(uncompr_tvb))) {
1390 WSLUA_RETURN(1); /* The <<lua_class_TvbRange,`TvbRange`>>. */
1394 return 0;
1397 WSLUA_METHOD TvbRange_uncompress_lz77(lua_State* L) {
1398 /* Given a <<lua_class_TvbRange,`TvbRange`>> containing Microsoft Plain LZ77 compressed data, decompresses the data and returns a new <<lua_class_TvbRange,`TvbRange`>> containing the uncompressed data.
1399 @since 4.3.0
1401 #define WSLUA_ARG_TvbRange_uncompress_lz77_NAME 2 /* The name to be given to the new data-source. */
1402 TvbRange tvbr = checkTvbRange(L,1);
1403 const char* name = luaL_optstring(L,WSLUA_ARG_TvbRange_uncompress_lz77_NAME,"Uncompressed");
1404 tvbuff_t *uncompr_tvb;
1406 if (!(tvbr && tvbr->tvb)) return 0;
1408 if (tvbr->tvb->expired) {
1409 luaL_error(L,"expired tvb");
1410 return 0;
1413 uncompr_tvb = tvb_child_uncompress_lz77(tvbr->tvb->ws_tvb, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
1414 if (uncompr_tvb) {
1415 add_new_data_source (lua_pinfo, uncompr_tvb, name);
1416 if (push_TvbRange(L,uncompr_tvb,0,tvb_captured_length(uncompr_tvb))) {
1417 WSLUA_RETURN(1); /* The <<lua_class_TvbRange,`TvbRange`>>. */
1421 return 0;
1424 WSLUA_METHOD TvbRange_uncompress_lz77huff(lua_State* L) {
1425 /* Given a <<lua_class_TvbRange,`TvbRange`>> containing Microsoft LZ77+Huffman compressed data, decompresses the data and returns a new <<lua_class_TvbRange,`TvbRange`>> containing the uncompressed data.
1426 @since 4.3.0
1428 #define WSLUA_ARG_TvbRange_uncompress_lz77huff_NAME 2 /* The name to be given to the new data-source. */
1429 TvbRange tvbr = checkTvbRange(L,1);
1430 const char* name = luaL_optstring(L,WSLUA_ARG_TvbRange_uncompress_lz77huff_NAME,"Uncompressed");
1431 tvbuff_t *uncompr_tvb;
1433 if (!(tvbr && tvbr->tvb)) return 0;
1435 if (tvbr->tvb->expired) {
1436 luaL_error(L,"expired tvb");
1437 return 0;
1440 uncompr_tvb = tvb_child_uncompress_lz77huff(tvbr->tvb->ws_tvb, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
1441 if (uncompr_tvb) {
1442 add_new_data_source (lua_pinfo, uncompr_tvb, name);
1443 if (push_TvbRange(L,uncompr_tvb,0,tvb_captured_length(uncompr_tvb))) {
1444 WSLUA_RETURN(1); /* The <<lua_class_TvbRange,`TvbRange`>>. */
1448 return 0;
1451 WSLUA_METHOD TvbRange_uncompress_lznt1(lua_State* L) {
1452 /* Given a <<lua_class_TvbRange,`TvbRange`>> containing Microsoft LZNT1 compressed data, decompresses the data and returns a new <<lua_class_TvbRange,`TvbRange`>> containing the uncompressed data.
1453 @since 4.3.0
1455 #define WSLUA_ARG_TvbRange_uncompress_lznt1_NAME 2 /* The name to be given to the new data-source. */
1456 TvbRange tvbr = checkTvbRange(L,1);
1457 const char* name = luaL_optstring(L,WSLUA_ARG_TvbRange_uncompress_lznt1_NAME,"Uncompressed");
1458 tvbuff_t *uncompr_tvb;
1460 if (!(tvbr && tvbr->tvb)) return 0;
1462 if (tvbr->tvb->expired) {
1463 luaL_error(L,"expired tvb");
1464 return 0;
1467 uncompr_tvb = tvb_child_uncompress_lznt1(tvbr->tvb->ws_tvb, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
1468 if (uncompr_tvb) {
1469 add_new_data_source (lua_pinfo, uncompr_tvb, name);
1470 if (push_TvbRange(L,uncompr_tvb,0,tvb_captured_length(uncompr_tvb))) {
1471 WSLUA_RETURN(1); /* The <<lua_class_TvbRange,`TvbRange`>>. */
1475 return 0;
1478 WSLUA_METHOD TvbRange_uncompress_snappy(lua_State* L) {
1479 /* Given a <<lua_class_TvbRange,`TvbRange`>> containing Snappy compressed data, decompresses the data and returns a new <<lua_class_TvbRange,`TvbRange`>> containing the uncompressed data.
1480 @since 4.3.0
1482 #define WSLUA_ARG_TvbRange_uncompress_snappy_NAME 2 /* The name to be given to the new data-source. */
1483 TvbRange tvbr = checkTvbRange(L,1);
1484 #ifdef HAVE_SNAPPY
1485 const char* name = luaL_optstring(L,WSLUA_ARG_TvbRange_uncompress_snappy_NAME,"Uncompressed");
1486 tvbuff_t *uncompr_tvb;
1487 #endif
1489 if (!(tvbr && tvbr->tvb)) return 0;
1491 if (tvbr->tvb->expired) {
1492 luaL_error(L,"expired tvb");
1493 return 0;
1496 #ifdef HAVE_SNAPPY
1497 uncompr_tvb = tvb_child_uncompress_snappy(tvbr->tvb->ws_tvb, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
1498 if (uncompr_tvb) {
1499 add_new_data_source (lua_pinfo, uncompr_tvb, name);
1500 if (push_TvbRange(L,uncompr_tvb,0,tvb_captured_length(uncompr_tvb))) {
1501 WSLUA_RETURN(1); /* The <<lua_class_TvbRange,`TvbRange`>>. */
1504 #else
1505 luaL_error(L,"Missing support for Snappy");
1506 #endif
1508 return 0;
1511 WSLUA_METHOD TvbRange_uncompress_zstd(lua_State* L) {
1512 /* Given a <<lua_class_TvbRange,`TvbRange`>> containing Zstandard compressed data, decompresses the data and returns a new <<lua_class_TvbRange,`TvbRange`>> containing the uncompressed data.
1513 @since 4.3.0
1515 #define WSLUA_ARG_TvbRange_uncompress_zstd_NAME 2 /* The name to be given to the new data-source. */
1516 TvbRange tvbr = checkTvbRange(L,1);
1517 #ifdef HAVE_ZSTD
1518 const char* name = luaL_optstring(L,WSLUA_ARG_TvbRange_uncompress_zstd_NAME,"Uncompressed");
1519 tvbuff_t *uncompr_tvb;
1520 #endif
1522 if (!(tvbr && tvbr->tvb)) return 0;
1524 if (tvbr->tvb->expired) {
1525 luaL_error(L,"expired tvb");
1526 return 0;
1529 #ifdef HAVE_ZSTD
1530 uncompr_tvb = tvb_child_uncompress_zstd(tvbr->tvb->ws_tvb, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
1531 if (uncompr_tvb) {
1532 add_new_data_source (lua_pinfo, uncompr_tvb, name);
1533 if (push_TvbRange(L,uncompr_tvb,0,tvb_captured_length(uncompr_tvb))) {
1534 WSLUA_RETURN(1); /* The <<lua_class_TvbRange,`TvbRange`>>. */
1537 #else
1538 luaL_error(L,"Missing support for ZStandard");
1539 #endif
1541 return 0;
1544 WSLUA_METHOD TvbRange_decode_base64(lua_State* L) {
1545 /* Given a <<lua_class_TvbRange,`TvbRange`>> containing Base64 encoded data, return a new <<lua_class_TvbRange,`TvbRange`>> containing the decoded data.
1546 @since 4.3.0
1548 #define WSLUA_ARG_TvbRange_decode_base64_NAME 2 /* The name to be given to the new data-source. */
1549 TvbRange tvbr = checkTvbRange(L,1);
1550 const char* name = luaL_optstring(L,WSLUA_ARG_TvbRange_decode_base64_NAME,"Decoded");
1551 tvbuff_t *decoded_tvb;
1553 if (!(tvbr && tvbr->tvb)) return 0;
1555 if (tvbr->tvb->expired) {
1556 luaL_error(L,"expired tvb");
1557 return 0;
1560 decoded_tvb = base64_tvb_to_new_tvb(tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
1561 if (decoded_tvb) {
1562 add_new_data_source (lua_pinfo, decoded_tvb, name);
1563 if (push_TvbRange(L,decoded_tvb,0,tvb_captured_length(decoded_tvb))) {
1564 WSLUA_RETURN(1); /* The <<lua_class_TvbRange,`TvbRange`>>. */
1568 return 0;
1571 WSLUA_METHOD TvbRange_decode_base64url(lua_State* L) {
1572 /* Given a <<lua_class_TvbRange,`TvbRange`>> containing base64url encoded data, return a new <<lua_class_TvbRange,`TvbRange`>> containing the decoded data.
1573 @since 4.3.0
1575 #define WSLUA_ARG_TvbRange_decode_base64url_NAME 2 /* The name to be given to the new data-source. */
1576 TvbRange tvbr = checkTvbRange(L,1);
1577 const char* name = luaL_optstring(L,WSLUA_ARG_TvbRange_decode_base64url_NAME,"Decoded");
1578 tvbuff_t *decoded_tvb;
1580 if (!(tvbr && tvbr->tvb)) return 0;
1582 if (tvbr->tvb->expired) {
1583 luaL_error(L,"expired tvb");
1584 return 0;
1587 decoded_tvb = base64uri_tvb_to_new_tvb(tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
1588 if (decoded_tvb) {
1589 add_new_data_source (lua_pinfo, decoded_tvb, name);
1590 if (push_TvbRange(L,decoded_tvb,0,tvb_captured_length(decoded_tvb))) {
1591 WSLUA_RETURN(1); /* The <<lua_class_TvbRange,`TvbRange`>>. */
1595 return 0;
1598 WSLUA_METHOD TvbRange_len(lua_State* L) {
1599 /* Obtain the length of a <<lua_class_TvbRange,`TvbRange`>>. */
1600 TvbRange tvbr = checkTvbRange(L,1);
1602 if (!(tvbr && tvbr->tvb)) return 0;
1603 if (tvbr->tvb->expired) {
1604 luaL_error(L,"expired tvb");
1605 return 0;
1607 lua_pushinteger(L,(lua_Integer)tvbr->len);
1608 return 1;
1611 WSLUA_METHOD TvbRange_offset(lua_State* L) {
1612 /* Obtain the offset in a <<lua_class_TvbRange,`TvbRange`>>. */
1613 TvbRange tvbr = checkTvbRange(L,1);
1615 if (!(tvbr && tvbr->tvb)) return 0;
1616 if (tvbr->tvb->expired) {
1617 luaL_error(L,"expired tvb");
1618 return 0;
1620 lua_pushinteger(L,(lua_Integer)tvbr->offset);
1621 return 1;
1624 WSLUA_METHOD TvbRange_raw(lua_State* L) {
1625 /* Obtain a Lua string of the binary bytes in a <<lua_class_TvbRange,`TvbRange`>>. */
1626 #define WSLUA_OPTARG_TvbRange_raw_OFFSET 2 /* The position of the first byte within the range. Default is 0, or first byte. */
1627 #define WSLUA_OPTARG_TvbRange_raw_LENGTH 3 /* The length of the segment to get. Default is -1, or the remaining bytes in the range. */
1628 TvbRange tvbr = checkTvbRange(L,1);
1629 int offset = (int)luaL_optinteger(L,WSLUA_OPTARG_TvbRange_raw_OFFSET,0);
1630 int len = (int)luaL_optinteger(L,WSLUA_OPTARG_TvbRange_raw_LENGTH,-1);
1632 if (!tvbr || !tvbr->tvb) return 0;
1633 if (tvbr->tvb->expired) {
1634 luaL_error(L,"expired tvb");
1635 return 0;
1638 if (offset < 0) {
1639 WSLUA_OPTARG_ERROR(TvbRange_raw,OFFSET,"offset before start of TvbRange");
1640 return 0;
1642 if (offset > tvbr->len) {
1643 WSLUA_OPTARG_ERROR(TvbRange_raw,OFFSET,"offset beyond end of TvbRange");
1644 return 0;
1647 if (len == -1) {
1648 len = tvbr->len - offset;
1650 if (len < 0) {
1651 luaL_error(L,"out of bounds");
1652 return false;
1653 } else if ( (len + offset) > tvbr->len) {
1654 luaL_error(L,"Range is out of bounds");
1655 return false;
1658 lua_pushlstring(L, tvb_get_ptr(tvbr->tvb->ws_tvb, tvbr->offset+offset, len), len);
1660 WSLUA_RETURN(1); /* A Lua string of the binary bytes in the <<lua_class_TvbRange,`TvbRange`>>. */
1663 WSLUA_METAMETHOD TvbRange__eq(lua_State* L) {
1664 /* Checks whether the contents of two <<lua_class_TvbRange,`TvbRange`>>s are equal. */
1665 TvbRange tvb_l = checkTvbRange(L,1);
1666 TvbRange tvb_r = checkTvbRange(L,2);
1668 /* it is not an error if their ds_tvb are different... they're just not equal */
1669 if (tvb_l->len == tvb_r->len &&
1670 tvb_l->len <= tvb_captured_length_remaining(tvb_l->tvb->ws_tvb, tvb_l->offset) &&
1671 tvb_r->len <= tvb_captured_length_remaining(tvb_r->tvb->ws_tvb, tvb_r->offset))
1673 const char* lp = tvb_get_ptr(tvb_l->tvb->ws_tvb, tvb_l->offset, tvb_l->len);
1674 const char* rp = tvb_get_ptr(tvb_r->tvb->ws_tvb, tvb_r->offset, tvb_r->len);
1675 int i = 0;
1677 for (; i < tvb_r->len; ++i) {
1678 if (lp[i] != rp[i]) {
1679 lua_pushboolean(L,0);
1680 return 1;
1683 lua_pushboolean(L,1);
1684 } else {
1685 lua_pushboolean(L,0);
1688 return 1;
1691 WSLUA_METAMETHOD TvbRange__tostring(lua_State* L) {
1693 Converts the <<lua_class_TvbRange,`TvbRange`>> into a string.
1694 The string can be truncated, so this is primarily useful for debugging or in cases where truncation is preferred, e.g. "67:89:AB:...".
1696 TvbRange tvbr = checkTvbRange(L,1);
1697 char* str = NULL;
1699 if (!(tvbr && tvbr->tvb)) return 0;
1700 if (tvbr->tvb->expired) {
1701 luaL_error(L,"expired tvb");
1702 return 0;
1705 if (tvbr->len == 0) {
1706 lua_pushstring(L, "<EMPTY>");
1707 } else {
1708 str = tvb_bytes_to_str(NULL,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len);
1709 lua_pushstring(L,str);
1710 wmem_free(NULL, str);
1713 WSLUA_RETURN(1); /* A Lua hex string of the <<lua_class_TvbRange,`TvbRange`>> truncated to 24 bytes. */
1716 WSLUA_METHODS TvbRange_methods[] = {
1717 WSLUA_CLASS_FNREG(TvbRange,uint),
1718 WSLUA_CLASS_FNREG(TvbRange,le_uint),
1719 WSLUA_CLASS_FNREG(TvbRange,int),
1720 WSLUA_CLASS_FNREG(TvbRange,le_int),
1721 WSLUA_CLASS_FNREG(TvbRange,uint64),
1722 WSLUA_CLASS_FNREG(TvbRange,le_uint64),
1723 WSLUA_CLASS_FNREG(TvbRange,int64),
1724 WSLUA_CLASS_FNREG(TvbRange,le_int64),
1725 WSLUA_CLASS_FNREG(TvbRange,float),
1726 WSLUA_CLASS_FNREG(TvbRange,le_float),
1727 WSLUA_CLASS_FNREG(TvbRange,ether),
1728 WSLUA_CLASS_FNREG(TvbRange,ipv4),
1729 WSLUA_CLASS_FNREG(TvbRange,le_ipv4),
1730 WSLUA_CLASS_FNREG(TvbRange,ipv6),
1731 WSLUA_CLASS_FNREG(TvbRange,nstime),
1732 WSLUA_CLASS_FNREG(TvbRange,le_nstime),
1733 WSLUA_CLASS_FNREG(TvbRange,string),
1734 WSLUA_CLASS_FNREG(TvbRange,stringz),
1735 WSLUA_CLASS_FNREG(TvbRange,strsize),
1736 WSLUA_CLASS_FNREG(TvbRange,bytes),
1737 WSLUA_CLASS_FNREG(TvbRange,bitfield),
1738 WSLUA_CLASS_FNREG(TvbRange,range),
1739 WSLUA_CLASS_FNREG(TvbRange,len),
1740 WSLUA_CLASS_FNREG(TvbRange,offset),
1741 WSLUA_CLASS_FNREG(TvbRange,tvb),
1742 WSLUA_CLASS_FNREG(TvbRange,le_ustring),
1743 WSLUA_CLASS_FNREG(TvbRange,ustring),
1744 WSLUA_CLASS_FNREG(TvbRange,le_ustringz),
1745 WSLUA_CLASS_FNREG(TvbRange,ustringz),
1746 WSLUA_CLASS_FNREG(TvbRange,uncompress),
1747 WSLUA_CLASS_FNREG(TvbRange,uncompress_zlib),
1748 WSLUA_CLASS_FNREG(TvbRange,uncompress_brotli),
1749 WSLUA_CLASS_FNREG(TvbRange,uncompress_hpack_huff),
1750 WSLUA_CLASS_FNREG(TvbRange,uncompress_lz77),
1751 WSLUA_CLASS_FNREG(TvbRange,uncompress_lz77huff),
1752 WSLUA_CLASS_FNREG(TvbRange,uncompress_lznt1),
1753 WSLUA_CLASS_FNREG(TvbRange,uncompress_snappy),
1754 WSLUA_CLASS_FNREG(TvbRange,uncompress_zstd),
1755 WSLUA_CLASS_FNREG(TvbRange,decode_base64),
1756 WSLUA_CLASS_FNREG(TvbRange,decode_base64url),
1757 WSLUA_CLASS_FNREG(TvbRange,raw),
1758 { NULL, NULL }
1761 WSLUA_META TvbRange_meta[] = {
1762 WSLUA_CLASS_MTREG(TvbRange,tostring),
1763 WSLUA_CLASS_MTREG(wslua,concat),
1764 WSLUA_CLASS_MTREG(TvbRange,eq),
1765 {"__call", TvbRange_range},
1766 { NULL, NULL }
1769 int TvbRange_register(lua_State* L) {
1770 if (outstanding_TvbRange != NULL) {
1771 g_ptr_array_unref(outstanding_TvbRange);
1773 outstanding_TvbRange = g_ptr_array_new();
1774 WSLUA_REGISTER_CLASS(TvbRange);
1775 return 0;
1779 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1781 * Local variables:
1782 * c-basic-offset: 4
1783 * tab-width: 8
1784 * indent-tabs-mode: nil
1785 * End:
1787 * vi: set shiftwidth=4 tabstop=8 expandtab:
1788 * :indentSize=4:tabSize=8:noTabs=true: