WSLUA_FUNCTION wslua_new_dialog(lua_State* L) { /* Pops up a new dialog */ #define WSLUA_ARG_new_dialog_TITLE 1 /* Title of the dialog's window. */ #define WSLUA_ARG_new_dialog_ACTION 2 /* Action to be performed when OKd. */ /* WSLUA_MOREARGS new_dialog A series of strings to be used as labels of the dialog's fields */ const gchar* title; int top = lua_gettop(L); int i; GPtrArray* labels; struct _dlg_cb_data* dcbd; if (! ops) { luaL_error(L,"the GUI facility has to be enabled"); return 0; } if (! (title = luaL_checkstring(L,WSLUA_ARG_new_dialog_TITLE)) ) { WSLUA_ARG_ERROR(new_dialog,TITLE,"Must be a string"); } if (! lua_isfunction(L,WSLUA_ARG_new_dialog_ACTION)) { WSLUA_ARG_ERROR(new_dialog,ACTION,"Must be a function"); } if (top < 3) { WSLUA_ERROR(new_dialog,"At least one field required"); } dcbd = g_malloc(sizeof(struct _dlg_cb_data)); dcbd->L = L; lua_remove(L,1); lua_pushvalue(L, 1); dcbd->func_ref = luaL_ref(L, LUA_REGISTRYINDEX); lua_remove(L,1); labels = g_ptr_array_new(); top -= 2; for (i = 1; i <= top; i++) { gchar* label = (void*)luaL_checkstring(L,i); /* XXX leaks labels on error */ if (! label) WSLUA_ERROR(new_dialog,"All fields must be strings"); g_ptr_array_add(labels,label); } g_ptr_array_add(labels,NULL); ops->new_dialog(title, (const gchar**)labels->pdata, lua_dialog_cb, dcbd); g_ptr_array_free(labels,FALSE); WSLUA_RETURN(0); }
WSLUA_METHOD Dissector_call(lua_State* L) { /* Calls a dissector against a given packet (or part of it). */ #define WSLUA_ARG_Dissector_call_TVB 2 /* The buffer to dissect. */ #define WSLUA_ARG_Dissector_call_PINFO 3 /* The packet info. */ #define WSLUA_ARG_Dissector_call_TREE 4 /* The tree on which to add the protocol items. */ Dissector volatile d = checkDissector(L,1); Tvb tvb = checkTvb(L,WSLUA_ARG_Dissector_call_TVB); Pinfo pinfo = checkPinfo(L,WSLUA_ARG_Dissector_call_PINFO); TreeItem ti = checkTreeItem(L,WSLUA_ARG_Dissector_call_TREE); const char *volatile error = NULL; int len = 0; if (! ( d && tvb && pinfo) ) return 0; TRY { len = call_dissector(d, tvb->ws_tvb, pinfo->ws_pinfo, ti->tree); /* XXX Are we sure about this??? is this the right/only thing to catch */ } CATCH_NONFATAL_ERRORS { show_exception(tvb->ws_tvb, pinfo->ws_pinfo, ti->tree, EXCEPT_CODE, GET_MESSAGE); error = "Malformed frame"; } ENDTRY; if (error) { WSLUA_ERROR(Dissector_call,error); } lua_pushnumber(L,(lua_Number)len); WSLUA_RETURN(1); /* Number of bytes dissected. Note that some dissectors always return number of bytes in incoming buffer, so be aware. */ }
WSLUA_METHOD TvbRange_ether(lua_State* L) { /* Get an Ethernet Address from a TvbRange. */ TvbRange tvbr = checkTvbRange(L,1); Address addr; guint8* buff; if ( !(tvbr && tvbr->tvb)) return 0; if (tvbr->tvb->expired) { luaL_error(L,"expired tvb"); return 0; } if (tvbr->len != 6) { WSLUA_ERROR(TvbRange_ether,"The range must be 6 bytes long"); return 0; } addr = g_new(address,1); buff = (guint8 *)tvb_memdup(NULL,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len); SET_ADDRESS(addr, AT_ETHER, 6, buff); pushAddress(L,addr); WSLUA_RETURN(1); /* The Ethernet Address */ }
WSLUA_FUNCTION wslua_all_field_infos(lua_State* L) { /* Obtain all fields from the current tree. Note this only gets whatever fields the underlying dissectors have filled in for this packet at this time - there may be fields applicable to the packet that simply aren't being filled in because at this time they're not needed for anything. This function only gets what the C-side code has currently populated, not the full list. */ GPtrArray* found; int items_found = 0; guint i; if (! lua_tree || ! lua_tree->tree ) { WSLUA_ERROR(wslua_all_field_infos,"Cannot be called outside a listener or dissector"); return 0; } found = proto_all_finfos(lua_tree->tree); if (found) { for (i=0; i<found->len; i++) { push_FieldInfo(L, (field_info *)g_ptr_array_index(found,i)); items_found++; } g_ptr_array_free(found,TRUE); } return items_found; }
WSLUA_METHOD TvbRange_le_nstime(lua_State* L) { /* Obtain a nstime from a TvbRange */ TvbRange tvbr = checkTvbRange(L,1); NSTime nstime; if ( !(tvbr && tvbr->tvb)) return 0; if (tvbr->tvb->expired) { luaL_error(L,"expired tvb"); return 0; } nstime = g_new(nstime_t,1); if (tvbr->len == 4) { nstime->secs = tvb_get_letohl(tvbr->tvb->ws_tvb, tvbr->offset); nstime->nsecs = 0; } else if (tvbr->len == 8) { nstime->secs = tvb_get_letohl(tvbr->tvb->ws_tvb, tvbr->offset); nstime->nsecs = tvb_get_letohl(tvbr->tvb->ws_tvb, tvbr->offset + 4); } else { g_free(nstime); WSLUA_ERROR(TvbRange_nstime,"The range must be 4 or 8 bytes long"); return 0; } pushNSTime(L, nstime); WSLUA_RETURN(1); /* The NSTime */ }
WSLUA_METHOD TvbRange_le_ipv4(lua_State* L) { /* Get an Little Endian IPv4 Address from a TvbRange. */ TvbRange tvbr = checkTvbRange(L,1); Address addr; guint32* ip_addr; if ( !(tvbr && tvbr->tvb)) return 0; if (tvbr->tvb->expired) { luaL_error(L,"expired tvb"); return 0; } if (tvbr->len != 4) WSLUA_ERROR(TvbRange_ipv4,"The range must be 4 octets long"); addr = (address *)g_malloc(sizeof(address)); ip_addr = (guint32 *)g_malloc(sizeof(guint32)); *ip_addr = tvb_get_ipv4(tvbr->tvb->ws_tvb,tvbr->offset); *((guint32 *)ip_addr) = GUINT32_SWAP_LE_BE(*((guint32 *)ip_addr)); SET_ADDRESS(addr, AT_IPv4, 4, ip_addr); pushAddress(L,addr); WSLUA_RETURN(1); /* The IPv4 Address */ }
WSLUA_FUNCTION wslua_open_capture_file(lua_State* L) { /* Open and display a capture file */ #define WSLUA_ARG_open_capture_file_FILENAME 1 /* The name of the file to be opened. */ #define WSLUA_ARG_open_capture_file_FILTER 2 /* A filter to be applied as the file gets opened. */ const char* fname = luaL_checkstring(L,WSLUA_ARG_open_capture_file_FILENAME); const char* filter = luaL_optstring(L,WSLUA_ARG_open_capture_file_FILTER,NULL); const char* error = NULL; if (!ops->open_file) { WSLUA_ERROR(wslua_open_capture_file, "Does not work on TShark"); } if (!fname) { WSLUA_ARG_ERROR(open_capture_file,FILENAME,"Must be a string"); } if (! ops->open_file(fname,filter,&error) ) { lua_pushboolean(L,FALSE); if (error) lua_pushstring(L,error); else lua_pushnil(L); return 2; } else { lua_pushboolean(L,TRUE); return 1; } }
WSLUA_METHOD TvbRange_ipv4(lua_State* L) { /* Get an IPv4 Address from a `TvbRange`, as an `Address` object. */ TvbRange tvbr = checkTvbRange(L,1); Address addr; guint32* ip_addr; if ( !(tvbr && tvbr->tvb)) return 0; if (tvbr->tvb->expired) { luaL_error(L,"expired tvb"); return 0; } if (tvbr->len != 4) { WSLUA_ERROR(TvbRange_ipv4,"The range must be 4 octets long"); return 0; } addr = (address *)g_malloc(sizeof(address)); ip_addr = (guint32 *)g_malloc(sizeof(guint32)); *ip_addr = tvb_get_ipv4(tvbr->tvb->ws_tvb,tvbr->offset); set_address(addr, AT_IPv4, 4, ip_addr); pushAddress(L,addr); WSLUA_RETURN(1); /* The IPv4 `Address` object. */ }
WSLUA_FUNCTION wslua_apply_filter(lua_State* L) { /* Apply the filter in the main filter box */ if (!ops->apply_filter) { WSLUA_ERROR(wslua_apply_filter, "Does not work on TShark"); } ops->apply_filter(); return 0; }
WSLUA_FUNCTION wslua_reload(lua_State* L) { /* Reload the current capture file */ if (!ops->reload) { WSLUA_ERROR(wslua_reload, "Does not work on TShark"); } ops->reload(); return 0; }
WSLUA_METHOD ProgDlg_stopped(lua_State* L) { /* Checks wheher the user has pressed the stop button. */ ProgDlg pd = checkProgDlg(L,1); if (!pd) { WSLUA_ERROR(ProgDlg_stopped,"Cannot be called for something not a ProgDlg"); } lua_pushboolean(L,pd->stopped); WSLUA_RETURN(1); /* true if the user has asked to stop the progress. */ }
WSLUA_FUNCTION wslua_retap_packets(lua_State* L) { /* Rescan all packets and just run taps - don't reconstruct the display. */ if ( ops->retap_packets ) { ops->retap_packets(); } else { WSLUA_ERROR(wslua_retap_packets, "Does not work on TShark"); } return 0; }
WSLUA_METHOD TextWindow_clear(lua_State* L) { /* Erases all text in the window. */ TextWindow tw = checkTextWindow(L,1); if (!tw) WSLUA_ERROR(TextWindow_clear,"Cannot be called for something not a TextWindow"); if (tw->expired) WSLUA_ARG_ERROR(TextWindow_set,TEXT,"Expired TextWindow"); ops->clear_text(tw->ws_tw); WSLUA_RETURN(1); /* The TextWindow object. */ }
WSLUA_METHOD ProgDlg_close(lua_State* L) { /* Appends text */ ProgDlg pd = checkProgDlg(L,1); if (!pd) { WSLUA_ERROR(ProgDlg_update,"Cannot be called for something not a ProgDlg"); } if (pd->pw) { ops->destroy_progress_window(pd->pw); pd->pw = NULL; } return 0; }
WSLUA_METHOD ByteArray_append(lua_State* L) { /* Append a ByteArray to this ByteArray */ #define WSLUA_ARG_ByteArray_append_APPENDED 2 /* Array to be appended */ ByteArray ba = checkByteArray(L,1); ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray_append_APPENDED); if (! (ba && ba2) ) WSLUA_ERROR(ByteArray_append,"Both arguments must be ByteArrays"); g_byte_array_append(ba,ba2->data,ba2->len); return 0; }
WSLUA_METHOD ProgDlg_update(lua_State* L) { /* Appends text */ #define WSLUA_ARG_ProgDlg_update_PROGRESS 2 /* Part done ( e.g. 0.75 ). */ #define WSLUA_OPTARG_ProgDlg_update_TASK 3 /* Current task, defaults to "". */ ProgDlg pd = checkProgDlg(L,1); double pr = lua_tonumber(L,WSLUA_ARG_ProgDlg_update_PROGRESS); const gchar* task = luaL_optstring(L,WSLUA_OPTARG_ProgDlg_update_TASK,""); g_free(pd->task); pd->task = g_strdup(task); if (!pd) { WSLUA_ERROR(ProgDlg_update,"Cannot be called for something not a ProgDlg"); } if (pr >= 0.0 || pr <= 1.0) { ops->update_progress(pd->pw, (float) pr, task); } else { WSLUA_ERROR(ProgDlg_update,"Progress value out of range (must be between 0.0 and 1.0)"); } return 0; }
WSLUA_METHOD TvbRange_nstime(lua_State* L) { /* Obtain a time_t structure from a `TvbRange`, as an `NSTime` object. */ #define WSLUA_OPTARG_TvbRange_nstime_ENCODING 2 /* An optional ENC_* encoding value to use */ TvbRange tvbr = checkTvbRange(L,1); NSTime nstime; const guint encoding = (guint) luaL_optinteger(L, WSLUA_OPTARG_TvbRange_nstime_ENCODING, 0); if ( !(tvbr && tvbr->tvb)) return 0; if (tvbr->tvb->expired) { luaL_error(L,"expired tvb"); return 0; } nstime = g_new(nstime_t,1); if (encoding == 0) { if (tvbr->len == 4) { nstime->secs = tvb_get_ntohl(tvbr->tvb->ws_tvb, tvbr->offset); nstime->nsecs = 0; } else if (tvbr->len == 8) { nstime->secs = tvb_get_ntohl(tvbr->tvb->ws_tvb, tvbr->offset); nstime->nsecs = tvb_get_ntohl(tvbr->tvb->ws_tvb, tvbr->offset + 4); } else { g_free(nstime); WSLUA_ERROR(TvbRange_nstime,"The range must be 4 or 8 bytes long"); return 0; } pushNSTime(L, nstime); lua_pushinteger(L, tvbr->len); } else if (encoding & ~ENC_STR_TIME_MASK) { WSLUA_OPTARG_ERROR(TvbRange_nstime, ENCODING, "invalid encoding value"); } else { gint endoff = 0; nstime_t *retval = tvb_get_string_time(tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, encoding, nstime, &endoff); if (!retval || endoff == 0) { g_free(nstime); /* push nil nstime and offset */ lua_pushnil(L); lua_pushnil(L); } else { pushNSTime(L, nstime); lua_pushinteger(L, endoff); } } WSLUA_RETURN(2); /* The `NSTime` object and number of bytes used, or nil on failure. */ }
WSLUA_METAMETHOD NSTime__lt(lua_State* L) { /* Compares two NSTimes */ NSTime time1 = checkNSTime(L,1); NSTime time2 = checkNSTime(L,2); gboolean result = FALSE; if (!time1 || !time2) WSLUA_ERROR(NSTime__lt,"Both values must be a NSTime"); if (nstime_cmp(time1, time2) < 0) result = TRUE; lua_pushboolean(L,result); return 1; }
WSLUA_METHOD TextWindow_get_text(lua_State* L) { /* Get the text of the window */ TextWindow tw = checkTextWindow(L,1); const gchar* text; if (!tw) WSLUA_ERROR(TextWindow_get_text,"Cannot be called for something not a TextWindow"); if (tw->expired) WSLUA_ARG_ERROR(TextWindow_set,TEXT,"Expired TextWindow"); text = ops->get_text(tw->ws_tw); lua_pushstring(L,text); WSLUA_RETURN(1); /* The TextWindow's text. */ }
WSLUA_METAMETHOD NSTime__lt(lua_State* L) { /* Compares two NSTimes */ NSTime time1 = checkNSTime(L,1); NSTime time2 = checkNSTime(L,2); gboolean result = FALSE; if (!time1 || !time2) WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields"); if (nstime_cmp(time1, time2) < 0) result = TRUE; lua_pushboolean(L,result); return 1; }
WSLUA_METAMETHOD FieldInfo__lt(lua_State* L) { /* Checks whether the end byte of rhs is before the beginning of rhs */ FieldInfo l = checkFieldInfo(L,1); FieldInfo r = checkFieldInfo(L,2); if (l->ds_tvb != r->ds_tvb) WSLUA_ERROR(FieldInfo__lt,"Data source must be the same for both fields"); if ( r->start + r->length < l->start ) { lua_pushboolean(L,1); return 1; } else { return 0; } }
WSLUA_METAMETHOD FieldInfo__eq(lua_State* L) { /* Checks whether lhs is within rhs */ FieldInfo l = checkFieldInfo(L,1); FieldInfo r = checkFieldInfo(L,2); if (l->ds_tvb != r->ds_tvb) WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields"); if (l->start <= r->start && r->start + r->length <= l->start + r->length) { lua_pushboolean(L,1); return 1; } else { return 0; } }
WSLUA_METAMETHOD FieldInfo__le(lua_State* L) { /* Checks whether the end byte of lhs is before the end of rhs. */ FieldInfo l = checkFieldInfo(L,1); FieldInfo r = checkFieldInfo(L,2); if (l->ws_fi->ds_tvb != r->ws_fi->ds_tvb) WSLUA_ERROR(FieldInfo__le,"Data source must be the same for both fields"); if (r->ws_fi->start + r->ws_fi->length <= l->ws_fi->start + l->ws_fi->length) { lua_pushboolean(L,1); } else { lua_pushboolean(L,0); } return 1; }
WSLUA_METAMETHOD ByteArray__concat(lua_State* L) { /* Concatenate two ByteArrays */ #define WSLUA_ARG_ByteArray__cat_FIRST 1 /* First array */ #define WSLUA_ARG_ByteArray__cat_SECOND 2 /* Second array */ ByteArray ba = checkByteArray(L,WSLUA_ARG_ByteArray__cat_FIRST); ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray__cat_SECOND); if (! (ba && ba2) ) WSLUA_ERROR(ByteArray__cat,"Both arguments must be ByteArrays"); g_byte_array_append(ba,ba2->data,ba2->len); pushByteArray(L,ba); WSLUA_RETURN(1); /* The new composite ByteArray. */ }
WSLUA_FUNCTION wslua_set_filter(lua_State* L) { /* Set the main filter text */ #define WSLUA_ARG_set_filter_TEXT 1 /* The filter's text. */ const char* filter_str = luaL_checkstring(L,WSLUA_ARG_set_filter_TEXT); if (!ops->set_filter) { WSLUA_ERROR(wslua_set_filter, "Does not work on TShark"); } if (!filter_str) { WSLUA_ARG_ERROR(set_filter,TEXT,"Must be a string"); } ops->set_filter(filter_str); return 0; }
WSLUA_FUNCTION wslua_browser_open_url(lua_State* L) { /* Open an url in a browser */ #define WSLUA_ARG_browser_open_url_URL 1 /* The url. */ const char* url = luaL_checkstring(L,WSLUA_ARG_browser_open_url_URL); if (!ops->browser_open_url) { WSLUA_ERROR(browser_open_url, "Does not work on TShark"); } if (!url) { WSLUA_ARG_ERROR(browser_open_url,URL,"Must be a string"); } ops->browser_open_url(url); return 0; }
WSLUA_FUNCTION wslua_browser_open_data_file(lua_State* L) { /* Open an file in a browser */ #define WSLUA_ARG_browser_open_data_file_FILENAME 1 /* The url. */ const char* file = luaL_checkstring(L,WSLUA_ARG_browser_open_data_file_FILENAME); if (!ops->browser_open_data_file) { WSLUA_ERROR(browser_open_data_file, "Does not work on TShark"); } if (!file) { WSLUA_ARG_ERROR(browser_open_data_file,FILENAME,"Must be a string"); } ops->browser_open_data_file(file); return 0; }
WSLUA_METHOD TextWindow_set_editable(lua_State* L) { /* Make this window editable */ #define WSLUA_OPTARG_TextWindow_set_editable_EDITABLE 2 /* A boolean flag, defaults to true */ TextWindow tw = checkTextWindow(L,1); gboolean editable = wslua_optbool(L,WSLUA_OPTARG_TextWindow_set_editable_EDITABLE,TRUE); if (!tw) WSLUA_ERROR(TextWindow_set_editable,"Cannot be called for something not a TextWindow"); if (tw->expired) WSLUA_ARG_ERROR(TextWindow_set,TEXT,"Expired TextWindow"); if (ops->set_editable) ops->set_editable(tw->ws_tw,editable); WSLUA_RETURN(1); /* The TextWindow object. */ }
WSLUA_METHOD TextWindow_prepend(lua_State* L) { /* Prepends text */ #define WSLUA_ARG_TextWindow_prepend_TEXT 2 /* The text to be appended */ TextWindow tw = checkTextWindow(L,1); const gchar* text = luaL_checkstring(L,WSLUA_ARG_TextWindow_prepend_TEXT); if (!tw) WSLUA_ERROR(TextWindow_prepend,"Cannot be called for something not a TextWindow"); if (tw->expired) WSLUA_ARG_ERROR(TextWindow_set,TEXT,"Expired TextWindow"); if (!text) WSLUA_ARG_ERROR(TextWindow_prepend,TEXT,"Must be a string"); ops->prepend_text(tw->ws_tw,text); WSLUA_RETURN(1); /* The TextWindow object. */ }
WSLUA_FUNCTION wslua_copy_to_clipboard(lua_State* L) { /* Copy a string into the clipboard */ #define WSLUA_ARG_copy_to_clipboard_TEXT 1 /* The string to be copied into the clipboard. */ const char* copied_str = luaL_checkstring(L,WSLUA_ARG_copy_to_clipboard_TEXT); GString* gstr; if (!ops->copy_to_clipboard) { WSLUA_ERROR(wslua_copy_to_clipboard, "Does not work on TShark"); } if (!copied_str) { WSLUA_ARG_ERROR(copy_to_clipboard,TEXT,"Must be a string"); } gstr = g_string_new(copied_str); ops->copy_to_clipboard(gstr); g_string_free(gstr,TRUE); return 0; }