HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / wslua / wslua_tvb.c
blob9bca207ddb9d71f23d73b33c9478a5b562acd7b1
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>
10 * $Id$
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include "config.h"
33 #include <epan/emem.h>
35 /* WSLUA_MODULE Tvb Functions for handling packet data */
37 #include "wslua.h"
39 WSLUA_CLASS_DEFINE(ByteArray,FAIL_ON_NULL("null bytearray"),NOP);
41 WSLUA_CONSTRUCTOR ByteArray_new(lua_State* L) { /* Creates a ByteArray Object */
42 #define WSLUA_OPTARG_ByteArray_new_HEXBYTES 1 /* A string consisting of hexadecimal bytes like "00 B1 A2" or "1a2b3c4d" */
43 GByteArray* ba = g_byte_array_new();
44 const gchar* s;
45 int nibble[2];
46 int i = 0;
47 gchar c;
49 if (lua_gettop(L) == 1) {
50 s = luaL_checkstring(L,WSLUA_OPTARG_ByteArray_new_HEXBYTES);
52 if (!s)
53 WSLUA_OPTARG_ERROR(ByteArray_new,HEXBYTES,"must be a string");
55 /* XXX: slow! */
56 for (; (c = *s); s++) {
57 switch(c) {
58 case '0': case '1': case '2': case '3': case '4': case '5' : case '6' : case '7': case '8' : case '9' :
59 nibble[(i++)%2] = c - '0';
60 break;
61 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f' :
62 nibble[(i++)%2] = c - 'a' + 0xa;
63 break;
64 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F' :
65 nibble[(i++)%2] = c - 'A' + 0xa;
66 break;
67 default:
68 break;
71 if ( i == 2 ) {
72 guint8 b = (guint8)(nibble[0] * 16 + nibble[1]);
73 g_byte_array_append(ba,&b,1);
74 i = 0;
79 pushByteArray(L,ba);
81 WSLUA_RETURN(1); /* The new ByteArray object. */
84 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
85 static int ByteArray__gc(lua_State* L) {
86 ByteArray ba = checkByteArray(L,1);
88 if (!ba) return 0;
90 g_byte_array_free(ba,TRUE);
91 return 0;
94 WSLUA_METAMETHOD ByteArray__concat(lua_State* L) {
95 /* Concatenate two ByteArrays */
96 #define WSLUA_ARG_ByteArray__cat_FIRST 1 /* First array */
97 #define WSLUA_ARG_ByteArray__cat_SECOND 2 /* Second array */
99 ByteArray ba1 = checkByteArray(L,WSLUA_ARG_ByteArray__cat_FIRST);
100 ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray__cat_SECOND);
101 ByteArray ba;
103 if (! (ba1 && ba2) )
104 WSLUA_ERROR(ByteArray__cat,"Both arguments must be ByteArrays");
106 ba = g_byte_array_new();
107 g_byte_array_append(ba,ba1->data,ba1->len);
108 g_byte_array_append(ba,ba2->data,ba2->len);
110 pushByteArray(L,ba);
111 WSLUA_RETURN(1); /* The new composite ByteArray. */
114 WSLUA_METHOD ByteArray_prepend(lua_State* L) {
115 /* Prepend a ByteArray to this ByteArray */
116 #define WSLUA_ARG_ByteArray_prepend_PREPENDED 2 /* Array to be prepended */
117 ByteArray ba = checkByteArray(L,1);
118 ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray_prepend_PREPENDED);
120 if (! (ba && ba2) )
121 WSLUA_ERROR(ByteArray_prepend,"Both arguments must be ByteArrays");
123 g_byte_array_prepend(ba,ba2->data,ba2->len);
125 return 0;
128 WSLUA_METHOD ByteArray_append(lua_State* L) {
129 /* Append a ByteArray to this ByteArray */
130 #define WSLUA_ARG_ByteArray_append_APPENDED 2 /* Array to be appended */
131 ByteArray ba = checkByteArray(L,1);
132 ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray_append_APPENDED);
134 if (! (ba && ba2) )
135 WSLUA_ERROR(ByteArray_append,"Both arguments must be ByteArrays");
137 g_byte_array_append(ba,ba2->data,ba2->len);
139 return 0;
142 WSLUA_METHOD ByteArray_set_size(lua_State* L) {
143 /* Sets the size of a ByteArray, either truncating it or filling it with zeros. */
144 #define WSLUA_ARG_ByteArray_set_size_SIZE 2 /* New size of the array*/
146 ByteArray ba = checkByteArray(L,1);
147 int siz = luaL_checkint(L,WSLUA_ARG_ByteArray_set_size_SIZE);
148 guint8* padding;
150 if (!ba) return 0;
151 if (siz < 0)
152 WSLUA_ERROR(ByteArray_set_size,"ByteArray size must be non-negative");
154 if (ba->len >= (guint)siz) { /* truncate */
155 g_byte_array_set_size(ba,siz);
156 } else { /* fill */
157 padding = (guint8 *)g_malloc0(sizeof(guint8)*(siz - ba->len));
158 g_byte_array_append(ba,padding,siz - ba->len);
159 g_free(padding);
161 return 0;
164 WSLUA_METHOD ByteArray_set_index(lua_State* L) {
165 /* Sets the value of an index of a ByteArray. */
166 #define WSLUA_ARG_ByteArray_set_index_INDEX 2 /* The position of the byte to be set */
167 #define WSLUA_ARG_ByteArray_set_index_VALUE 3 /* The char value to set [0-255] */
168 ByteArray ba = checkByteArray(L,1);
169 int idx = luaL_checkint(L,WSLUA_ARG_ByteArray_set_index_INDEX);
170 int v = luaL_checkint(L,WSLUA_ARG_ByteArray_set_index_VALUE);
172 if (!ba) return 0;
174 if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) {
175 luaL_argerror(L,2,"bad index");
176 return 0;
179 if (idx < 0 || (guint)idx >= ba->len) {
180 luaL_argerror(L,2,"index out of range");
181 return 0;
184 if (v < 0 || v > 255) {
185 luaL_argerror(L,3,"Byte out of range");
186 return 0;
189 ba->data[idx] = (guint8)v;
191 return 0;
195 WSLUA_METHOD ByteArray_get_index(lua_State* L) {
196 /* Get the value of a byte in a ByteArray */
197 #define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the byte to get */
198 ByteArray ba = checkByteArray(L,1);
199 int idx = luaL_checkint(L,WSLUA_ARG_ByteArray_get_index_INDEX);
201 if (!ba) return 0;
203 if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) {
204 luaL_argerror(L,2,"bad index");
205 return 0;
208 if (idx < 0 || (guint)idx >= ba->len) {
209 luaL_argerror(L,2,"index out of range");
210 return 0;
212 lua_pushnumber(L,ba->data[idx]);
214 WSLUA_RETURN(1); /* The value [0-255] of the byte. */
217 WSLUA_METHOD ByteArray_len(lua_State* L) {
218 /* Obtain the length of a ByteArray */
219 ByteArray ba = checkByteArray(L,1);
221 if (!ba) return 0;
223 lua_pushnumber(L,(lua_Number)ba->len);
225 WSLUA_RETURN(1); /* The length of the ByteArray. */
228 WSLUA_METHOD ByteArray_subset(lua_State* L) {
229 /* Obtain a segment of a ByteArray */
230 #define WSLUA_ARG_ByteArray_set_index_OFFSET 2 /* The position of the first byte */
231 #define WSLUA_ARG_ByteArray_set_index_LENGTH 3 /* The length of the segment */
232 ByteArray ba = checkByteArray(L,1);
233 int offset = luaL_checkint(L,WSLUA_ARG_ByteArray_set_index_OFFSET);
234 int len = luaL_checkint(L,WSLUA_ARG_ByteArray_set_index_LENGTH);
235 ByteArray sub;
237 if (!ba) return 0;
239 if ((offset + len) > (int)ba->len || offset < 0 || len < 1) {
240 luaL_error(L,"Out Of Bounds");
241 return 0;
244 sub = g_byte_array_new();
245 g_byte_array_append(sub,ba->data + offset,len);
247 pushByteArray(L,sub);
249 WSLUA_RETURN(1); /* A ByteArray contaning the requested segment. */
252 static int ByteArray_tostring(lua_State* L) {
253 /* Obtain a string containing the bytes in a ByteArray so that it can be used in display filters (e.g. "01:23:45:67:89:AB") */
254 static const gchar* byte_to_str[] = {
255 "00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",
256 "10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",
257 "20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",
258 "30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F",
259 "40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",
260 "50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",
261 "60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",
262 "70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",
263 "80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",
264 "90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",
265 "A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",
266 "B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",
267 "C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",
268 "D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",
269 "E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",
270 "F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF"
272 ByteArray ba = checkByteArray(L,1);
273 int i;
274 GString* s;
276 if (!ba) return 0;
278 s = g_string_new("");
280 for (i = 0; i < (int)ba->len; i++) {
281 g_string_append(s,byte_to_str[(ba->data)[i]]);
284 lua_pushstring(L,s->str);
285 g_string_free(s,TRUE);
287 WSLUA_RETURN(1); /* A string contaning a representaion of the ByteArray. */
290 static int ByteArray_tvb (lua_State *L);
292 static const luaL_Reg ByteArray_methods[] = {
293 {"new", ByteArray_new},
294 {"len", ByteArray_len},
295 {"prepend", ByteArray_prepend},
296 {"append", ByteArray_append},
297 {"subset", ByteArray_subset},
298 {"set_size", ByteArray_set_size},
299 {"tvb", ByteArray_tvb},
300 {"get_index", ByteArray_get_index},
301 {"set_index", ByteArray_set_index},
302 { NULL, NULL }
305 static const luaL_Reg ByteArray_meta[] = {
306 {"__tostring", ByteArray_tostring},
307 {"__concat", ByteArray__concat},
308 {"__call",ByteArray_subset},
309 { NULL, NULL }
312 int ByteArray_register(lua_State* L) {
313 WSLUA_REGISTER_CLASS(ByteArray);
314 return 1;
319 * Tvb & TvbRange
321 * a Tvb represents a tvbuff_t in Lua.
322 * a TvbRange represents a range in a tvb (tvb,offset,length) its main purpose is to do bounds checking,
323 * It helps, too, simplifying argument passing to Tree. In wireshark terms this is worthless nothing
324 * not already done by the TVB itself. In lua's terms it's necessary to avoid abusing TRY{}CATCH(){}
325 * via preemptive bounds checking.
327 * These lua objects refer to structures in wireshark that are freed independently from Lua's garbage collector.
328 * To avoid using pointers from Lua to Wireshark structures that are already freed, we maintain a list of the
329 * pointers each with a marker that tracks its expiry.
331 * All pointers are marked as expired when the dissection of the current frame is finished or when the garbage
332 * collector tries to free the object referring to the pointer, whichever comes first.
334 * All allocated memory chunks used for tracking the pointers' state are freed after marking the pointer as expired
335 * by the garbage collector or by the end of the dissection of the current frame, whichever comes second.
337 * We check the expiry state of the pointer before each access.
341 WSLUA_CLASS_DEFINE(Tvb,FAIL_ON_NULL("expired tvb"),NOP);
342 /* A Tvb represents the packet's buffer. It is passed as an argument to listeners and dissectors,
343 and can be used to extract information (via TvbRange) from the packet's data. Beware that Tvbs are usable only by the current
344 listener or dissector call and are destroyed as soon as the listener/dissector returns, so references
345 to them are unusable once the function has returned.
346 To create a tvbrange the tvb must be called with offset and length as optional arguments ( the offset defaults to 0 and the length to tvb:len() )*/
348 static GPtrArray* outstanding_Tvb = NULL;
349 static GPtrArray* outstanding_TvbRange = NULL;
351 #define PUSH_TVB(L,t) {g_ptr_array_add(outstanding_Tvb,t);pushTvb(L,t);}
352 #define PUSH_TVBRANGE(L,t) {g_ptr_array_add(outstanding_TvbRange,t);pushTvbRange(L,t);}
354 static void free_Tvb(Tvb tvb) {
355 if (!tvb) return;
357 if (!tvb->expired) {
358 tvb->expired = TRUE;
359 } else {
360 if (tvb->need_free)
361 tvb_free(tvb->ws_tvb);
362 g_free(tvb);
366 void clear_outstanding_Tvb(void) {
367 while (outstanding_Tvb->len) {
368 Tvb tvb = (Tvb)g_ptr_array_remove_index_fast(outstanding_Tvb,0);
369 free_Tvb(tvb);
373 static void free_TvbRange(TvbRange tvbr) {
374 if (!(tvbr && tvbr->tvb)) return;
376 if (!tvbr->tvb->expired) {
377 tvbr->tvb->expired = TRUE;
378 } else {
379 free_Tvb(tvbr->tvb);
380 g_free(tvbr);
384 void clear_outstanding_TvbRange(void) {
385 while (outstanding_TvbRange->len) {
386 TvbRange tvbr = (TvbRange)g_ptr_array_remove_index_fast(outstanding_TvbRange,0);
387 free_TvbRange(tvbr);
392 Tvb* push_Tvb(lua_State* L, tvbuff_t* ws_tvb) {
393 Tvb tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
394 tvb->ws_tvb = ws_tvb;
395 tvb->expired = FALSE;
396 tvb->need_free = FALSE;
397 g_ptr_array_add(outstanding_Tvb,tvb);
398 return pushTvb(L,tvb);
404 * ByteArray_tvb(name)
406 WSLUA_CONSTRUCTOR ByteArray_tvb (lua_State *L) {
407 /* Creates a new Tvb from a bytearray (it gets added to the current frame too) */
408 #define WSLUA_ARG_ByteArray_tvb_NAME 2 /* The name to be given to the new data-source. */
409 ByteArray ba = checkByteArray(L,1);
410 const gchar* name = luaL_optstring(L,WSLUA_ARG_ByteArray_tvb_NAME,"Unnamed") ;
411 guint8* data;
412 Tvb tvb;
414 if (!ba) return 0;
416 if (!lua_tvb) {
417 luaL_error(L,"Tvbs can only be created and used in dissectors");
418 return 0;
421 data = (guint8 *)g_memdup(ba->data, ba->len);
423 tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
424 tvb->ws_tvb = tvb_new_real_data(data, ba->len,ba->len);
425 tvb->expired = FALSE;
426 tvb->need_free = TRUE;
427 tvb_set_free_cb(tvb->ws_tvb, g_free);
429 add_new_data_source(lua_pinfo, tvb->ws_tvb, name);
430 PUSH_TVB(L,tvb);
431 WSLUA_RETURN(1); /* The created Tvb. */
434 WSLUA_CONSTRUCTOR TvbRange_tvb (lua_State *L) {
435 /* Creates a (sub)Tvb from using a TvbRange */
436 #define WSLUA_ARG_Tvb_new_subset_RANGE 1 /* The TvbRange from which to create the new Tvb. */
438 TvbRange tvbr = checkTvbRange(L,WSLUA_ARG_Tvb_new_subset_RANGE);
439 Tvb tvb;
441 if (! (tvbr && tvbr->tvb)) return 0;
442 if (tvbr->tvb->expired) {
443 luaL_error(L,"expired tvb");
444 return 0;
447 if (tvb_offset_exists(tvbr->tvb->ws_tvb, tvbr->offset + tvbr->len -1 )) {
448 tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
449 tvb->expired = FALSE;
450 tvb->need_free = FALSE;
451 tvb->ws_tvb = tvb_new_subset(tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len, tvbr->len);
452 PUSH_TVB(L, tvb);
453 return 1;
454 } else {
455 luaL_error(L,"Out Of Bounds");
456 return 0;
460 WSLUA_METAMETHOD Tvb__tostring(lua_State* L) {
461 /* Convert the bytes of a Tvb into a string, to be used for debugging purposes as '...' will be appended in case the string is too long. */
462 Tvb tvb = checkTvb(L,1);
463 int len;
464 gchar* str;
466 if (!tvb) return 0;
467 if (tvb->expired) {
468 luaL_error(L,"expired tvb");
469 return 0;
472 len = tvb_length(tvb->ws_tvb);
473 str = ep_strdup_printf("TVB(%i) : %s",len,tvb_bytes_to_str(tvb->ws_tvb,0,len));
474 lua_pushstring(L,str);
475 WSLUA_RETURN(1); /* The string. */
478 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
479 static int Tvb__gc(lua_State* L) {
480 Tvb tvb = checkTvb(L,1);
482 free_Tvb(tvb);
484 return 0;
488 WSLUA_METHOD Tvb_reported_len(lua_State* L) {
489 /* Obtain the reported length of a TVB */
490 Tvb tvb = checkTvb(L,1);
492 if (!tvb) return 0;
493 if (tvb->expired) {
494 luaL_error(L,"expired tvb");
495 return 0;
498 lua_pushnumber(L,tvb_reported_length(tvb->ws_tvb));
499 WSLUA_RETURN(1); /* The length of the Tvb. */
502 WSLUA_METHOD Tvb_len(lua_State* L) {
503 /* Obtain the length of a TVB */
504 Tvb tvb = checkTvb(L,1);
506 if (!tvb) return 0;
507 if (tvb->expired) {
508 luaL_error(L,"expired tvb");
509 return 0;
512 lua_pushnumber(L,tvb_length(tvb->ws_tvb));
513 WSLUA_RETURN(1); /* The length of the Tvb. */
516 WSLUA_METHOD Tvb_reported_length_remaining(lua_State* L) {
517 /* Obtain the reported length of packet data to end of a TVB or -1 if the offset is beyond the end of the TVB */
518 #define Tvb_reported_length_remaining_OFFSET 2 /* offset */
519 Tvb tvb = checkTvb(L,1);
520 int offset = luaL_optint(L, Tvb_reported_length_remaining_OFFSET, 0);
522 if (!tvb) return 0;
523 if (tvb->expired) {
524 luaL_error(L,"expired tvb");
525 return 0;
528 lua_pushnumber(L,tvb_reported_length_remaining(tvb->ws_tvb, offset));
529 WSLUA_RETURN(1); /* The length of the Tvb. */
532 WSLUA_METHOD Tvb_offset(lua_State* L) {
533 /* Returns the raw offset (from the beginning of the source Tvb) of a sub Tvb. */
534 Tvb tvb = checkTvb(L,1);
536 if (!tvb) return 0;
537 if (tvb->expired) {
538 luaL_error(L,"expired tvb");
539 return 0;
542 lua_pushnumber(L,tvb_raw_offset(tvb->ws_tvb));
543 WSLUA_RETURN(1); /* The raw offset of the Tvb. */
547 #if USED_FOR_DOC_PURPOSES
548 WSLUA_METAMETHOD Tvb__call(lua_State* L) {
549 /* Equivalent to tvb:range(...) */
550 return 0;
552 #endif
554 WSLUA_METAMETHOD wslua__concat(lua_State* L) {
555 /* Concatenate two objects to a string */
556 if (!luaL_callmeta(L,1,"__tostring"))
557 lua_pushvalue(L,1);
558 if (!luaL_callmeta(L,2,"__tostring"))
559 lua_pushvalue(L,2);
561 lua_concat(L,2);
563 return 1;
566 WSLUA_CLASS_DEFINE(TvbRange,FAIL_ON_NULL("expired tvbrange"),NOP);
568 A TvbRange represents a usable range of a Tvb and is used to extract data from the Tvb that generated it
569 TvbRanges are created by calling a tvb (e.g. tvb(offset,length)). If the TvbRange span is outside the
570 Tvb's range the creation will cause a runtime error.
573 static TvbRange new_TvbRange(lua_State* L, tvbuff_t* ws_tvb, int offset, int len) {
574 TvbRange tvbr;
577 if (!ws_tvb) {
578 luaL_error(L,"expired tvb");
579 return 0;
582 if (len == -1) {
583 len = tvb_length_remaining(ws_tvb,offset);
584 if (len < 0) {
585 luaL_error(L,"out of bounds");
586 return 0;
588 } else if ( (guint)(len + offset) > tvb_length(ws_tvb)) {
589 luaL_error(L,"Range is out of bounds");
590 return NULL;
593 tvbr = (TvbRange)g_malloc(sizeof(struct _wslua_tvbrange));
594 tvbr->tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
595 tvbr->tvb->ws_tvb = ws_tvb;
596 tvbr->tvb->expired = FALSE;
597 tvbr->tvb->need_free = FALSE;
598 tvbr->offset = offset;
599 tvbr->len = len;
601 return tvbr;
605 WSLUA_METHOD Tvb_range(lua_State* L) {
606 /* Creates a tvbr from this Tvb. This is used also as the Tvb:__call() metamethod. */
607 #define WSLUA_OPTARG_Tvb_range_OFFSET 2 /* The offset (in octets) from the beginning of the Tvb. Defaults to 0. */
608 #define WSLUA_OPTARG_Tvb_range_LENGTH 3 /* The length (in octets) of the range. Defaults to until the end of the Tvb. */
610 Tvb tvb = checkTvb(L,1);
611 int offset = luaL_optint(L,WSLUA_OPTARG_Tvb_range_OFFSET,0);
612 int len = luaL_optint(L,WSLUA_OPTARG_Tvb_range_LENGTH,-1);
613 TvbRange tvbr;
615 if (!tvb) return 0;
616 if (tvb->expired) {
617 luaL_error(L,"expired tvb");
618 return 0;
621 if ((tvbr = new_TvbRange(L,tvb->ws_tvb,offset,len))) {
622 PUSH_TVBRANGE(L,tvbr);
623 WSLUA_RETURN(1); /* The TvbRange */
626 return 0;
629 static const luaL_Reg Tvb_methods[] = {
630 {"range", Tvb_range},
631 {"len", Tvb_len},
632 {"offset", Tvb_offset},
633 {"reported_len", Tvb_reported_len},
634 {"reported_length_remaining", Tvb_reported_length_remaining},
635 { NULL, NULL }
638 static const luaL_Reg Tvb_meta[] = {
639 {"__call", Tvb_range},
640 {"__tostring", Tvb__tostring},
641 { NULL, NULL }
644 int Tvb_register(lua_State* L) {
645 WSLUA_REGISTER_CLASS(Tvb);
646 return 1;
651 * get a Blefuscuoan unsigned integer from a tvb
653 WSLUA_METHOD TvbRange_uint(lua_State* L) {
654 /* Get a Big Endian (network order) unsigned integer from a TvbRange. The range must be 1, 2, 3 or 4 octets long. */
655 TvbRange tvbr = checkTvbRange(L,1);
656 if (!(tvbr && tvbr->tvb)) return 0;
657 if (tvbr->tvb->expired) {
658 luaL_error(L,"expired tvb");
659 return 0;
662 switch (tvbr->len) {
663 case 1:
664 lua_pushnumber(L,tvb_get_guint8(tvbr->tvb->ws_tvb,tvbr->offset));
665 return 1;
666 case 2:
667 lua_pushnumber(L,tvb_get_ntohs(tvbr->tvb->ws_tvb,tvbr->offset));
668 return 1;
669 case 3:
670 lua_pushnumber(L,tvb_get_ntoh24(tvbr->tvb->ws_tvb,tvbr->offset));
671 return 1;
672 case 4:
673 lua_pushnumber(L,tvb_get_ntohl(tvbr->tvb->ws_tvb,tvbr->offset));
674 WSLUA_RETURN(1); /* The unsigned integer value */
676 * XXX:
677 * lua uses double so we have 52 bits to play with
678 * we are missing 5 and 6 byte integers within lua's range
679 * and 64 bit integers are not supported (there's a lib for
680 * lua that does).
682 default:
683 luaL_error(L,"TvbRange:uint() does not handle %d byte integers",tvbr->len);
684 return 0;
689 * get a Lilliputian unsigned integer from a tvb
691 WSLUA_METHOD TvbRange_le_uint(lua_State* L) {
692 /* Get a Little Endian unsigned integer from a TvbRange. The range must be 1, 2, 3 or 4 octets long. */
693 TvbRange tvbr = checkTvbRange(L,1);
694 if (!(tvbr && tvbr->tvb)) return 0;
695 if (tvbr->tvb->expired) {
696 luaL_error(L,"expired tvb");
697 return 0;
700 switch (tvbr->len) {
701 case 1:
702 /* XXX unsigned anyway */
703 lua_pushnumber(L,(lua_Number)tvb_get_guint8(tvbr->tvb->ws_tvb,tvbr->offset));
704 return 1;
705 case 2:
706 lua_pushnumber(L,tvb_get_letohs(tvbr->tvb->ws_tvb,tvbr->offset));
707 return 1;
708 case 3:
709 lua_pushnumber(L,tvb_get_letoh24(tvbr->tvb->ws_tvb,tvbr->offset));
710 return 1;
711 case 4:
712 lua_pushnumber(L,tvb_get_letohl(tvbr->tvb->ws_tvb,tvbr->offset));
713 WSLUA_RETURN(1); /* The unsigned integer value */
714 default:
715 luaL_error(L,"TvbRange:le_uint() does not handle %d byte integers",tvbr->len);
716 return 0;
721 * get a Blefuscuoan unsigned 64 bit integer from a tvb
723 WSLUA_METHOD TvbRange_uint64(lua_State* L) {
724 /* Get a Big Endian (network order) unsigned 64 bit integer from a TvbRange. The range must be 1-8 octets long. */
725 TvbRange tvbr = checkTvbRange(L,1);
726 if (!(tvbr && tvbr->tvb)) return 0;
727 if (tvbr->tvb->expired) {
728 luaL_error(L,"expired tvb");
729 return 0;
732 switch (tvbr->len) {
733 case 1:
734 case 2:
735 case 3:
736 case 4:
737 case 5:
738 case 6:
739 case 7:
740 case 8: {
741 UInt64 num = (UInt64)g_malloc(sizeof(guint64));
742 *num = tvb_get_ntoh64(tvbr->tvb->ws_tvb,tvbr->offset);
743 pushUInt64(L,num);
744 WSLUA_RETURN(1);
746 default:
747 luaL_error(L,"TvbRange:uint64() does not handle %d byte integers",tvbr->len);
748 return 0;
753 * get a Lilliputian unsigned 64 bit integer from a tvb
755 WSLUA_METHOD TvbRange_le_uint64(lua_State* L) {
756 /* Get a Little Endian unsigned 64 bit integer from a TvbRange. The range must be 1-8 octets long. */
757 TvbRange tvbr = checkTvbRange(L,1);
758 if (!(tvbr && tvbr->tvb)) return 0;
759 if (tvbr->tvb->expired) {
760 luaL_error(L,"expired tvb");
761 return 0;
764 switch (tvbr->len) {
765 case 1:
766 case 2:
767 case 3:
768 case 4:
769 case 5:
770 case 6:
771 case 7:
772 case 8: {
773 UInt64 num = (UInt64)g_malloc(sizeof(guint64));
774 *num = tvb_get_letoh64(tvbr->tvb->ws_tvb,tvbr->offset);
775 pushUInt64(L,num);
776 WSLUA_RETURN(1);
778 default:
779 luaL_error(L,"TvbRange:le_uint64() does not handle %d byte integers",tvbr->len);
780 return 0;
785 * get a Blefuscuoan signed integer from a tvb
787 WSLUA_METHOD TvbRange_int(lua_State* L) {
788 /* Get a Big Endian (network order) signed integer from a TvbRange. The range must be 1, 2 or 4 octets long. */
789 TvbRange tvbr = checkTvbRange(L,1);
790 if (!(tvbr && tvbr->tvb)) return 0;
791 if (tvbr->tvb->expired) {
792 luaL_error(L,"expired tvb");
793 return 0;
796 switch (tvbr->len) {
797 case 1:
798 lua_pushnumber(L,(gchar)tvb_get_guint8(tvbr->tvb->ws_tvb,tvbr->offset));
799 return 1;
800 case 2:
801 lua_pushnumber(L,(gshort)tvb_get_ntohs(tvbr->tvb->ws_tvb,tvbr->offset));
802 return 1;
803 case 4:
804 lua_pushnumber(L,(gint)tvb_get_ntohl(tvbr->tvb->ws_tvb,tvbr->offset));
805 WSLUA_RETURN(1); /* The signed integer value */
807 * XXX:
808 * lua uses double so we have 52 bits to play with
809 * we are missing 5 and 6 byte integers within lua's range
810 * and 64 bit integers are not supported (there's a lib for
811 * lua that does).
813 default:
814 luaL_error(L,"TvbRange:int() does not handle %d byte integers",tvbr->len);
815 return 0;
820 * get a Lilliputian signed integer from a tvb
822 WSLUA_METHOD TvbRange_le_int(lua_State* L) {
823 /* Get a Little Endian signed integer from a TvbRange. The range must be 1, 2 or 4 octets long. */
824 TvbRange tvbr = checkTvbRange(L,1);
825 if (!(tvbr && tvbr->tvb)) return 0;
826 if (tvbr->tvb->expired) {
827 luaL_error(L,"expired tvb");
828 return 0;
831 switch (tvbr->len) {
832 case 1:
833 lua_pushnumber(L,(gchar)tvb_get_guint8(tvbr->tvb->ws_tvb,tvbr->offset));
834 return 1;
835 case 2:
836 lua_pushnumber(L,(gshort)tvb_get_letohs(tvbr->tvb->ws_tvb,tvbr->offset));
837 return 1;
838 case 4:
839 lua_pushnumber(L,(gint)tvb_get_letohl(tvbr->tvb->ws_tvb,tvbr->offset));
840 WSLUA_RETURN(1); /* The signed integer value */
841 default:
842 luaL_error(L,"TvbRange:le_int() does not handle %d byte integers",tvbr->len);
843 return 0;
848 * get a Blefuscuoan signed 64 bit integer from a tvb
850 WSLUA_METHOD TvbRange_int64(lua_State* L) {
851 /* Get a Big Endian (network order) signed 64 bit integer from a TvbRange. The range must be 1-8 octets long. */
852 TvbRange tvbr = checkTvbRange(L,1);
853 if (!(tvbr && tvbr->tvb)) return 0;
854 if (tvbr->tvb->expired) {
855 luaL_error(L,"expired tvb");
856 return 0;
859 switch (tvbr->len) {
860 case 1:
861 case 2:
862 case 3:
863 case 4:
864 case 5:
865 case 6:
866 case 7:
867 case 8: {
868 Int64 num = (Int64)g_malloc(sizeof(gint64));
869 *num = (gint64)tvb_get_ntoh64(tvbr->tvb->ws_tvb,tvbr->offset);
870 pushInt64(L,num);
871 WSLUA_RETURN(1);
873 default:
874 luaL_error(L,"TvbRange:int64() does not handle %d byte integers",tvbr->len);
875 return 0;
880 * get a Lilliputian signed 64 bit integer from a tvb
882 WSLUA_METHOD TvbRange_le_int64(lua_State* L) {
883 /* Get a Little Endian signed 64 bit integer from a TvbRange. The range must be 1-8 octets long. */
884 TvbRange tvbr = checkTvbRange(L,1);
885 if (!(tvbr && tvbr->tvb)) return 0;
886 if (tvbr->tvb->expired) {
887 luaL_error(L,"expired tvb");
888 return 0;
891 switch (tvbr->len) {
892 case 1:
893 case 2:
894 case 3:
895 case 4:
896 case 5:
897 case 6:
898 case 7:
899 case 8: {
900 Int64 num = (Int64)g_malloc(sizeof(gint64));
901 *num = (gint64)tvb_get_letoh64(tvbr->tvb->ws_tvb,tvbr->offset);
902 pushInt64(L,num);
903 WSLUA_RETURN(1);
905 default:
906 luaL_error(L,"TvbRange:le_int64() does not handle %d byte integers",tvbr->len);
907 return 0;
912 * get a Blefuscuoan float
914 WSLUA_METHOD TvbRange_float(lua_State* L) {
915 /* Get a Big Endian (network order) floating point number from a TvbRange. The range must be 4 or 8 octets long. */
916 TvbRange tvbr = checkTvbRange(L,1);
917 if (!(tvbr && tvbr->tvb)) return 0;
918 if (tvbr->tvb->expired) {
919 luaL_error(L,"expired tvb");
920 return 0;
923 switch (tvbr->len) {
924 case 4:
925 lua_pushnumber(L,(double)tvb_get_ntohieee_float(tvbr->tvb->ws_tvb,tvbr->offset));
926 return 1;
927 case 8:
928 lua_pushnumber(L,tvb_get_ntohieee_double(tvbr->tvb->ws_tvb,tvbr->offset));
929 WSLUA_RETURN(1); /* The floating point value */
930 default:
931 luaL_error(L,"TvbRange:float() does not handle %d byte floating numbers",tvbr->len);
932 return 0;
937 * get a Lilliputian float
939 WSLUA_METHOD TvbRange_le_float(lua_State* L) {
940 /* Get a Little Endian floating point number from a TvbRange. The range must be 4 or 8 octets long. */
941 TvbRange tvbr = checkTvbRange(L,1);
942 if (!(tvbr && tvbr->tvb)) return 0;
944 switch (tvbr->len) {
945 case 4:
946 lua_pushnumber(L,tvb_get_letohieee_float(tvbr->tvb->ws_tvb,tvbr->offset));
947 return 1;
948 case 8:
949 lua_pushnumber(L,tvb_get_letohieee_double(tvbr->tvb->ws_tvb,tvbr->offset));
950 WSLUA_RETURN(1); /* The floating point value */
951 default:
952 luaL_error(L,"TvbRange:le_float() does not handle %d byte floating numbers",tvbr->len);
953 return 0;
957 WSLUA_METHOD TvbRange_ipv4(lua_State* L) {
958 /* Get an IPv4 Address from a TvbRange. */
959 TvbRange tvbr = checkTvbRange(L,1);
960 Address addr;
961 guint32* ip_addr;
963 if ( !(tvbr && tvbr->tvb)) return 0;
964 if (tvbr->tvb->expired) {
965 luaL_error(L,"expired tvb");
966 return 0;
969 if (tvbr->len != 4)
970 WSLUA_ERROR(TvbRange_ipv4,"The range must be 4 octets long");
972 addr = (address *)g_malloc(sizeof(address));
974 ip_addr = (guint32 *)g_malloc(sizeof(guint32));
975 *ip_addr = tvb_get_ipv4(tvbr->tvb->ws_tvb,tvbr->offset);
977 SET_ADDRESS(addr, AT_IPv4, 4, ip_addr);
978 pushAddress(L,addr);
980 WSLUA_RETURN(1); /* The IPv4 Address */
983 WSLUA_METHOD TvbRange_le_ipv4(lua_State* L) {
984 /* Get an Little Endian IPv4 Address from a TvbRange. */
985 TvbRange tvbr = checkTvbRange(L,1);
986 Address addr;
987 guint32* ip_addr;
989 if ( !(tvbr && tvbr->tvb)) return 0;
990 if (tvbr->tvb->expired) {
991 luaL_error(L,"expired tvb");
992 return 0;
995 if (tvbr->len != 4)
996 WSLUA_ERROR(TvbRange_ipv4,"The range must be 4 octets long");
998 addr = (address *)g_malloc(sizeof(address));
1000 ip_addr = (guint32 *)g_malloc(sizeof(guint32));
1001 *ip_addr = tvb_get_ipv4(tvbr->tvb->ws_tvb,tvbr->offset);
1002 *((guint32 *)ip_addr) = GUINT32_SWAP_LE_BE(*((guint32 *)ip_addr));
1004 SET_ADDRESS(addr, AT_IPv4, 4, ip_addr);
1005 pushAddress(L,addr);
1007 WSLUA_RETURN(1); /* The IPv4 Address */
1010 WSLUA_METHOD TvbRange_ether(lua_State* L) {
1011 /* Get an Ethernet Address from a TvbRange. */
1012 TvbRange tvbr = checkTvbRange(L,1);
1013 Address addr;
1014 guint8* buff;
1016 if ( !(tvbr && tvbr->tvb)) return 0;
1017 if (tvbr->tvb->expired) {
1018 luaL_error(L,"expired tvb");
1019 return 0;
1022 if (tvbr->len != 6)
1023 WSLUA_ERROR(TvbRange_ether,"The range must be 6 bytes long");
1025 addr = g_new(address,1);
1027 buff = (guint8 *)tvb_memdup(NULL,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len);
1029 SET_ADDRESS(addr, AT_ETHER, 6, buff);
1030 pushAddress(L,addr);
1032 WSLUA_RETURN(1); /* The Ethernet Address */
1035 WSLUA_METHOD TvbRange_nstime(lua_State* L) {
1036 /* Obtain a nstime from a TvbRange */
1037 TvbRange tvbr = checkTvbRange(L,1);
1038 NSTime nstime;
1040 if ( !(tvbr && tvbr->tvb)) return 0;
1041 if (tvbr->tvb->expired) {
1042 luaL_error(L,"expired tvb");
1043 return 0;
1046 nstime = g_new(nstime_t,1);
1048 if (tvbr->len == 4) {
1049 nstime->secs = tvb_get_ntohl(tvbr->tvb->ws_tvb, tvbr->offset);
1050 nstime->nsecs = 0;
1051 } else if (tvbr->len == 8) {
1052 nstime->secs = tvb_get_ntohl(tvbr->tvb->ws_tvb, tvbr->offset);
1053 nstime->nsecs = tvb_get_ntohl(tvbr->tvb->ws_tvb, tvbr->offset + 4);
1054 } else {
1055 g_free(nstime);
1056 WSLUA_ERROR(TvbRange_nstime,"The range must be 4 or 8 bytes long");
1057 return 0;
1060 pushNSTime(L, nstime);
1062 WSLUA_RETURN(1); /* The NSTime */
1065 WSLUA_METHOD TvbRange_le_nstime(lua_State* L) {
1066 /* Obtain a nstime from a TvbRange */
1067 TvbRange tvbr = checkTvbRange(L,1);
1068 NSTime nstime;
1070 if ( !(tvbr && tvbr->tvb)) return 0;
1071 if (tvbr->tvb->expired) {
1072 luaL_error(L,"expired tvb");
1073 return 0;
1076 nstime = g_new(nstime_t,1);
1078 if (tvbr->len == 4) {
1079 nstime->secs = tvb_get_letohl(tvbr->tvb->ws_tvb, tvbr->offset);
1080 nstime->nsecs = 0;
1081 } else if (tvbr->len == 8) {
1082 nstime->secs = tvb_get_letohl(tvbr->tvb->ws_tvb, tvbr->offset);
1083 nstime->nsecs = tvb_get_letohl(tvbr->tvb->ws_tvb, tvbr->offset + 4);
1084 } else {
1085 g_free(nstime);
1086 WSLUA_ERROR(TvbRange_nstime,"The range must be 4 or 8 bytes long");
1087 return 0;
1090 pushNSTime(L, nstime);
1092 WSLUA_RETURN(1); /* The NSTime */
1095 WSLUA_METHOD TvbRange_string(lua_State* L) {
1096 /* Obtain a string from a TvbRange */
1097 TvbRange tvbr = checkTvbRange(L,1);
1099 if ( !(tvbr && tvbr->tvb)) return 0;
1100 if (tvbr->tvb->expired) {
1101 luaL_error(L,"expired tvb");
1102 return 0;
1105 lua_pushlstring(L, (gchar*)tvb_get_string(wmem_packet_scope(),tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len), tvbr->len );
1107 WSLUA_RETURN(1); /* The string */
1110 static int TvbRange_ustring_any(lua_State* L, gboolean little_endian) {
1111 /* Obtain a UTF-16 encoded string from a TvbRange */
1112 TvbRange tvbr = checkTvbRange(L,1);
1113 gchar * str;
1115 if ( !(tvbr && tvbr->tvb)) return 0;
1116 if (tvbr->tvb->expired) {
1117 luaL_error(L,"expired tvb");
1118 return 0;
1121 str = (gchar*)tvb_get_unicode_string(wmem_packet_scope(),tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN));
1122 lua_pushlstring(L, str, strlen(str));
1124 return 1; /* The string */
1127 WSLUA_METHOD TvbRange_ustring(lua_State* L) {
1128 /* Obtain a Big Endian (network order) UTF-16 encoded string from a TvbRange */
1129 WSLUA_RETURN(TvbRange_ustring_any(L, FALSE)); /* The string */
1132 WSLUA_METHOD TvbRange_le_ustring(lua_State* L) {
1133 /* Obtain a Little Endian UTF-16 encoded string from a TvbRange */
1134 WSLUA_RETURN(TvbRange_ustring_any(L, TRUE)); /* The string */
1137 WSLUA_METHOD TvbRange_stringz(lua_State* L) {
1138 /* Obtain a zero terminated string from a TvbRange */
1139 TvbRange tvbr = checkTvbRange(L,1);
1141 if ( !(tvbr && tvbr->tvb)) return 0;
1142 if (tvbr->tvb->expired) {
1143 luaL_error(L,"expired tvb");
1144 return 0;
1147 lua_pushstring(L, (gchar*)tvb_get_stringz(wmem_packet_scope(),tvbr->tvb->ws_tvb,tvbr->offset,NULL) );
1149 WSLUA_RETURN(1); /* The zero terminated string */
1152 WSLUA_METHOD TvbRange_strsize(lua_State* L) {
1153 /* Find the size of a zero terminated string from a TvbRange. The size of the string includes the terminating zero. */
1154 TvbRange tvbr = checkTvbRange(L,1);
1156 if ( !(tvbr && tvbr->tvb)) return 0;
1157 if (tvbr->tvb->expired) {
1158 luaL_error(L,"expired tvb");
1159 return 0;
1162 lua_pushinteger(L, tvb_strsize(tvbr->tvb->ws_tvb, tvbr->offset));
1164 WSLUA_RETURN(1); /* Length of the zero terminated string */
1168 static int TvbRange_ustringz_any(lua_State* L, gboolean little_endian) {
1169 /* Obtain a zero terminated string from a TvbRange */
1170 gint count;
1171 TvbRange tvbr = checkTvbRange(L,1);
1173 if ( !(tvbr && tvbr->tvb)) return 0;
1174 if (tvbr->tvb->expired) {
1175 luaL_error(L,"expired tvb");
1176 return 0;
1179 lua_pushstring(L, (gchar*)tvb_get_unicode_stringz(wmem_packet_scope(),tvbr->tvb->ws_tvb,tvbr->offset,&count,(little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN)) );
1180 lua_pushinteger(L,count);
1182 return 2; /* The zero terminated string, the length found in tvbr */
1185 WSLUA_METHOD TvbRange_ustringz(lua_State* L) {
1186 /* Obtain a Big Endian (network order) UTF-16 encoded zero terminated string from a TvbRange */
1187 WSLUA_RETURN(TvbRange_ustringz_any(L, FALSE)); /* The zero terminated string, the length found in tvbr */
1190 WSLUA_METHOD TvbRange_le_ustringz(lua_State* L) {
1191 /* Obtain a Little Endian UTF-16 encoded zero terminated string from a TvbRange */
1192 WSLUA_RETURN(TvbRange_ustringz_any(L, TRUE)); /* The zero terminated string, the length found in tvbr */
1195 WSLUA_METHOD TvbRange_bytes(lua_State* L) {
1196 /* Obtain a ByteArray */
1197 TvbRange tvbr = checkTvbRange(L,1);
1198 GByteArray* ba;
1200 if ( !(tvbr && tvbr->tvb)) return 0;
1201 if (tvbr->tvb->expired) {
1202 luaL_error(L,"expired tvb");
1203 return 0;
1206 ba = g_byte_array_new();
1207 g_byte_array_append(ba,(const guint8 *)tvb_memdup(wmem_packet_scope(),tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len),tvbr->len);
1209 pushByteArray(L,ba);
1211 WSLUA_RETURN(1); /* The ByteArray */
1214 WSLUA_METHOD TvbRange_bitfield(lua_State* L) {
1215 /* Get a bitfield from a TvbRange. */
1216 #define WSLUA_OPTARG_TvbRange_bitfield_POSITION 2 /* The bit offset from the beginning of the TvbRange. Defaults to 0. */
1217 #define WSLUA_OPTARG_TvbRange_bitfield_LENGTH 3 /* The length (in bits) of the field. Defaults to 1. */
1219 TvbRange tvbr = checkTvbRange(L,1);
1220 int pos = luaL_optint(L,WSLUA_OPTARG_TvbRange_bitfield_POSITION,0);
1221 int len = luaL_optint(L,WSLUA_OPTARG_TvbRange_bitfield_LENGTH,1);
1223 if (!(tvbr && tvbr->tvb)) return 0;
1224 if (tvbr->tvb->expired) {
1225 luaL_error(L,"expired tvb");
1226 return 0;
1229 if ((pos+len) > (tvbr->len<<3)) {
1230 luaL_error(L, "Requested bitfield out of range");
1231 return 0;
1234 if (len <= 8) {
1235 lua_pushnumber(L,(lua_Number)tvb_get_bits8(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len));
1236 return 1;
1237 } else if (len <= 16) {
1238 lua_pushnumber(L,tvb_get_bits16(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len, FALSE));
1239 return 1;
1240 } else if (len <= 32) {
1241 lua_pushnumber(L,tvb_get_bits32(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len, FALSE));
1242 return 1;
1243 } else if (len <= 64) {
1244 UInt64 num = (UInt64)g_malloc(sizeof(guint64));
1245 *num = tvb_get_bits64(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len, FALSE);
1246 pushUInt64(L,num);
1247 WSLUA_RETURN(1); /* The bitfield value */
1248 } else {
1249 luaL_error(L,"TvbRange:bitfield() does not handle %d bits",len);
1250 return 0;
1254 WSLUA_METHOD TvbRange_range(lua_State* L) {
1255 /* Creates a sub-TvbRange from this TvbRange. This is used also as the TvbRange:__call() metamethod. */
1256 #define WSLUA_OPTARG_TvbRange_range_OFFSET 2 /* The offset (in octets) from the beginning of the TvbRange. Defaults to 0. */
1257 #define WSLUA_OPTARG_TvbRange_range_LENGTH 3 /* The length (in octets) of the range. Defaults to until the end of the TvbRange. */
1259 TvbRange tvbr = checkTvbRange(L,1);
1260 int offset = luaL_optint(L,WSLUA_OPTARG_TvbRange_range_OFFSET,0);
1261 int len;
1263 if (!(tvbr && tvbr->tvb)) return 0;
1265 len = luaL_optint(L,WSLUA_OPTARG_TvbRange_range_LENGTH,tvbr->len-offset);
1267 if (tvbr->tvb->expired) {
1268 luaL_error(L,"expired tvb");
1269 return 0;
1272 if (offset >= tvbr->len || (len + offset) > tvbr->len) {
1273 luaL_error(L,"Range is out of bounds");
1274 return 0;
1277 if ((tvbr = new_TvbRange(L,tvbr->tvb->ws_tvb,tvbr->offset+offset,len))) {
1278 PUSH_TVBRANGE(L,tvbr);
1279 WSLUA_RETURN(1); /* The TvbRange */
1282 return 0;
1285 static int TvbRange_uncompress(lua_State* L) {
1286 /* Obtain a uncompressed TvbRange from a TvbRange */
1287 #define WSLUA_ARG_TvbRange_tvb_NAME 2 /* The name to be given to the new data-source. */
1288 TvbRange tvbr = checkTvbRange(L,1);
1289 const gchar* name = luaL_optstring(L,WSLUA_ARG_ByteArray_tvb_NAME,"Uncompressed");
1290 tvbuff_t *uncompr_tvb;
1292 if (!(tvbr && tvbr->tvb)) return 0;
1294 if (tvbr->tvb->expired) {
1295 luaL_error(L,"expired tvb");
1296 return 0;
1299 #ifdef HAVE_LIBZ
1300 uncompr_tvb = tvb_child_uncompress(tvbr->tvb->ws_tvb, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
1301 if (uncompr_tvb) {
1302 add_new_data_source (lua_pinfo, uncompr_tvb, name);
1303 if ((tvbr = new_TvbRange(L,uncompr_tvb,0,tvb_length(uncompr_tvb)))) {
1304 PUSH_TVBRANGE(L,tvbr);
1305 WSLUA_RETURN(1); /* The TvbRange */
1308 #else
1309 luaL_error(L,"Missing support for ZLIB");
1310 #endif
1312 return 0;
1315 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
1316 static int TvbRange__gc(lua_State* L) {
1317 TvbRange tvbr = checkTvbRange(L,1);
1319 free_TvbRange(tvbr);
1321 return 0;
1325 WSLUA_METHOD TvbRange_len(lua_State* L) {
1326 /* Obtain the length of a TvbRange */
1327 TvbRange tvbr = checkTvbRange(L,1);
1329 if (!(tvbr && tvbr->tvb)) return 0;
1330 if (tvbr->tvb->expired) {
1331 luaL_error(L,"expired tvb");
1332 return 0;
1334 lua_pushnumber(L,(lua_Number)tvbr->len);
1335 return 1;
1338 WSLUA_METHOD TvbRange_offset(lua_State* L) {
1339 /* Obtain the offset in a TvbRange */
1340 TvbRange tvbr = checkTvbRange(L,1);
1342 if (!(tvbr && tvbr->tvb)) return 0;
1343 if (tvbr->tvb->expired) {
1344 luaL_error(L,"expired tvb");
1345 return 0;
1347 lua_pushnumber(L,(lua_Number)tvbr->offset);
1348 return 1;
1352 WSLUA_METAMETHOD TvbRange__tostring(lua_State* L) {
1353 /* Converts the TvbRange into a string. As the string gets truncated
1354 you should use this only for debugging purposes
1355 or if what you want is to have a truncated string in the format 67:89:AB:... */
1356 TvbRange tvbr = checkTvbRange(L,1);
1358 if (!(tvbr && tvbr->tvb)) return 0;
1359 if (tvbr->tvb->expired) {
1360 luaL_error(L,"expired tvb");
1361 return 0;
1364 lua_pushstring(L,tvb_bytes_to_str(tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len));
1365 return 1;
1368 static const luaL_Reg TvbRange_methods[] = {
1369 {"uint", TvbRange_uint},
1370 {"le_uint", TvbRange_le_uint},
1371 {"int", TvbRange_int},
1372 {"le_int", TvbRange_le_int},
1373 {"uint64", TvbRange_uint64},
1374 {"le_uint64", TvbRange_le_uint64},
1375 {"int64", TvbRange_int64},
1376 {"le_int64", TvbRange_le_int64},
1377 {"float", TvbRange_float},
1378 {"le_float", TvbRange_le_float},
1379 {"ether", TvbRange_ether},
1380 {"ipv4", TvbRange_ipv4},
1381 {"le_ipv4", TvbRange_le_ipv4},
1382 {"nstime", TvbRange_nstime},
1383 {"le_nstime", TvbRange_le_nstime},
1384 {"string", TvbRange_string},
1385 {"stringz", TvbRange_stringz},
1386 {"strsize", TvbRange_strsize},
1387 {"bytes", TvbRange_bytes},
1388 {"bitfield", TvbRange_bitfield},
1389 {"range", TvbRange_range},
1390 {"len", TvbRange_len},
1391 {"offset", TvbRange_offset},
1392 {"tvb", TvbRange_tvb},
1393 {"le_ustring", TvbRange_le_ustring},
1394 {"ustring", TvbRange_ustring},
1395 {"le_ustringz", TvbRange_le_ustringz},
1396 {"ustringz", TvbRange_ustringz},
1397 {"uncompress", TvbRange_uncompress},
1398 { NULL, NULL }
1401 static const luaL_Reg TvbRange_meta[] = {
1402 {"__tostring", TvbRange__tostring},
1403 {"__concat", wslua__concat},
1404 {"__call", TvbRange_range},
1405 { NULL, NULL }
1408 int TvbRange_register(lua_State* L) {
1409 outstanding_Tvb = g_ptr_array_new();
1410 outstanding_TvbRange = g_ptr_array_new();
1411 WSLUA_REGISTER_CLASS(TvbRange);
1412 return 1;
1415 WSLUA_CLASS_DEFINE(Int64,FAIL_ON_NULL("null int64"),NOP);
1417 Int64 represents a 64 bit integer.
1418 Lua uses one single number representation which can be chosen at compile time and since
1419 it is often set to IEEE 754 double precision floating point, we cannot store a 64 bit integer
1420 with full precision.
1421 For details, see: http://lua-users.org/wiki/FloatingPoint
1424 WSLUA_METAMETHOD Int64__tostring(lua_State* L) {
1425 /* Converts the Int64 into a string */
1426 Int64 num = checkInt64(L,1);
1427 lua_pushstring(L,ep_strdup_printf("%" G_GINT64_MODIFIER "d",(gint64)*(num)));
1428 return 1;
1431 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
1432 static int Int64__gc(lua_State* L) {
1433 Int64 num = checkInt64(L,1);
1435 if (!num) return 0;
1437 g_free(num);
1439 return 0;
1442 static const luaL_Reg Int64_methods[] = {
1443 { NULL, NULL }
1446 static const luaL_Reg Int64_meta[] = {
1447 {"__tostring", Int64__tostring},
1448 {"__concat", wslua__concat},
1449 { NULL, NULL }
1452 int Int64_register(lua_State* L) {
1453 WSLUA_REGISTER_CLASS(Int64);
1454 return 1;
1457 WSLUA_CLASS_DEFINE(UInt64,FAIL_ON_NULL("null uint64"),NOP);
1458 /* UInt64 represents a 64 bit unsigned integer. */
1460 WSLUA_METAMETHOD UInt64__tostring(lua_State* L) {
1461 /* Converts the UInt64 into a string */
1462 UInt64 num = checkUInt64(L,1);
1463 lua_pushstring(L,ep_strdup_printf("%" G_GINT64_MODIFIER "u",(guint64)*(num)));
1464 return 1;
1467 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
1468 static int UInt64__gc(lua_State* L) {
1469 UInt64 num = checkUInt64(L,1);
1471 if (!num) return 0;
1473 g_free(num);
1475 return 0;
1478 static const luaL_Reg UInt64_methods[] = {
1479 { NULL, NULL }
1482 static const luaL_Reg UInt64_meta[] = {
1483 {"__tostring", UInt64__tostring},
1484 {"__concat", wslua__concat},
1485 { NULL, NULL }
1488 int UInt64_register(lua_State* L) {
1489 WSLUA_REGISTER_CLASS(UInt64);
1490 return 1;