What is a VoidString object? - lua

I am programming a LUA Dissector for Wireshark and have read about a VoidString object which could be passed by while creating a ProtoField object. See https://wiki.wireshark.org/LuaAPI/Proto#ProtoField for more information. I would like to no more about this object and what's the purpose of using it. If I am clicking on the link ''VoidString'' an empty page is getting displayed unfortunately because the documentation for this object seems to be missed. I have googled it but found nothing. Any Ideas?
Thanks in Advance!

I have learned from the examples provided by Wireshark that voidString can be passed an table. This table maps the values that you expect with what the value means.
local packet_type = {
[0] = "Data",
[1] = "heartBeat",
[2] = "Keep Alive",
}
local pf_packet_type = ProtoField.uint16("my_discector.packet_type", "Packet Type", base.DEC, packet_type, nil, "This describes a packet type")
This packet will show the string along with the actual value it got instead of just the value. Hope this helps.

Related

Custom wireshark disector shows value but fieldname is not visible using lua

I am testing some network packets of my Organisation's product. We already have custom plugins. I am trying to add some some more fields into those existing plugins (like conversion of 2 byte code to a string and assign it to a field)
Thankyou in advance for reading my query.
--edit
Wireshark version : 2.4.5 (organization's plugins dont work on latest wireshark application)
--edit
Problem statement:
I am able to add field and show value, but fieldname is not displayed as defined.
I cannot share the entire .lua file but i will try to explain What i did:
Below is the image where I have a field aprint.type. this is a two byte field. In .lua file, for display purpose it is appended with corresponding description using a custom function int_to_enum.
I want to add one more proto field aprint.typetext which will show the text.
What I did:
Added a protofield f_apr_msg_type_txt = ProtoField.string("aprint.typetxt","aprint_type_text") (Tried f_apr_msg_type_txt = ProtoField.string("aprint.typetxt","aprint_type_text",FT_STRING) also)
Below the code where subtree aprint.type is shown, added my required field as subtree:add(f_apr_msg_type_txt, msg_type_string) (Below is image of code extract)
I am able to see the text but field Name is shown as Wireshark Lua text (_ws.lua.text)
Normally displaying strings based on numeric values is accomplished by a value string lookup, so you'd have something like so:
local aprint_type_vals = {
[1] = "Foo",
[2] = "Bar",
[9] = "State alarm"
}
f_apr_msg_type = ProtoField.uint16("aprint.type", "Type", base.DEC, aprint_type_vals)
f_apr_msg_type_txt = ProtoField.string("aprint.typetxt","aprint_type_text", base.ASCII)
... then
local msg_type = tvb(offset, 2):le_uint()
subtree:add_le(f_apr_msg_type, tvb(offset, 2))
subtree:add(f_apr_msg_type_txt, tvb(offset, 2), (aprint_type_vals[msg_type] or "Unknown"))
--[[
Alternatively:
subtree:add(f_apr_msg_type_txt, tvb(offset, 2)):set_text("aprint_type_text: " .. (aprint_type_vals[msg_type] or "Unknown"))
--]]
I'm also not sure why you need the extra field with only the text when the text is already displayed with the existing field, but that's basically how you'd do it.

0 Checking if TextBox.Text contains the string in the table. But it doesn't work? Lua

I am making a script inside TextButton script that will check if the TextBox contains any of the word or string inside the table.
text = script.Parent.Parent:WaitForChild('TextBox')
label = script.Parent.Parent:WaitForChild('TextLabel')
a = {'test1','test2','test3'}
script.Parent.MouseButton1Click:connect(function()
if string.match(text.Text, a) then
label.Text = "The word "..text.Text.." was found in the table."
else
label.Text = "The word "..text.Text.." was not found in the table."
end
end)
But it gives an error string expected, got table. from line 7 which is refering to the line if string.match....
Is there any way to get all text in the table?
What's the right way to do it?
Oh boy, there's a lot to say about this.
The error message
Yes.
No, seriously, the answer is yes. The error message is exactly right. a is a table value; you can clearly see that on the third line of code. string.match needs a string as its second argument, so it obviously crashes.
Simple solution
use a for loop and check for each string in a separately.
found = false
for index, entry in ipairs(a) do
if entry == text.Text then
found = true
end
end
if found then
... -- the rest of your code
The better* solution
In Lua, if we want to know if a single element is in a set, we usually take advantage of the fact that tables are implemented as hashmaps, meaning they are very fast when looking up keys.
For that to work, one first needs to change the way the table looks:
a = {["test1"] = true, ["test2"] = true, ["test3"] = true}
Then we can just index a with a string to find out if it is contained int eh set.
if a[text.Text] then ...
* In practice this is just as good as the first solution as long as you only have a few elements in your table. It only becomes relevant when you have a few hundred entries or your code needs to run absolutely as fast as possible.

How to correctly return a list of dictionaries in Zapier Code (Python)?

The Zapier code documentation says that the output of a code zap can be either a dictionary or a list of dictionaries (See "Data Variable" section: https://zapier.com/help/code-python/).
When doing this,
output = [{'Booking':'Shirt'},{'Booking':'Jeans'}]
the output of the code returns only the first dictionary, however:
runtime_meta__duration_ms: 2
runtime_meta__memory_used_mb: 22
id: [redacted]
Booking: Shirt
Fields with no value:
runtime_meta__logs
What am I doing wrong here? Thanks a lot!
David from the Zapier platform team here. Code steps returning an array is a mostly undocumented (because there's no UI support and it's confusing, as you can tell) feature.
When testing, it'll only show the first item in the array. When it runs for real, all steps after the code step will run for each item in the array. The task history will reflect this
So set up the zap and turn on and it'll work like you expect.
Sorry for the confusion and let me know if you have any other questions!
For anyone still looking for an answer to this questions, below is what find out returning list in Zapier.
# first import and convert your input value to an array.
# special note any line items imported into a python variable are converted to list format.
my_items = input_data['my_CSV_string']
my_list_of_items = my_items.split(",")
# Create a new list array
my_new_list = []
length = len(my_list_of_items)
#Do all your computations
for i in range(length):
my_new_list.append(float(my_list_of_items[i])*1.5)
# After completing any tasks you can return the list as follows,
# If you are using line items keep the list in its original format
return {
'my_processed_values': my_new_list,
'original_values': my_list_of_items
}
# If you want to return it as a CSV "basically making the array flat"
my_old_CSV_list= ','.join(map(str, my_list_of_items))
my_new_CSV_list= ','.join(map(str, my_new_list))
return {
'my_processed_cvs_values': my_new_CSV_list,
'original_values': my_list_of_items
}
Hope this helps. I am not a Python expert but in theory the more lists used the longer the zap will take to process. Try to keep your python processing time to the lowest.
Best,

Wireshark: display filters vs nested dissectors

I have an application that sends JSON objects over AMQP, and I want to inspect the network traffic with Wireshark. The AMQP dissector gives the payload as a series of bytes in the field amqp.payload, but I'd like to extract and filter on specific fields in the JSON object, so I'm trying to write a plugin in Lua for that.
Wireshark already has a dissector for JSON, so I was hoping to piggy-back on that, and not have to deal with JSON parsing myself.
Here is my code:
local amqp_json_p = Proto("amqp_json", "AMQP JSON payload")
local amqp_json_result = ProtoField.string("amqp_json.result", "Result")
amqp_json_p.fields = { amqp_json_result }
register_postdissector(amqp_json_p)
local amqp_payload_f = Field.new("amqp.payload")
local json_dissector = Dissector.get("json")
local json_member_f = Field.new("json.member")
local json_string_f = Field.new("json.value.string")
function amqp_json_p.dissector(tvb, pinfo, tree)
local amqp_payload = amqp_payload_f()
if amqp_payload then
local payload_tvbrange = amqp_payload.range
if payload_tvbrange:range(0,1):string() == "{" then
json_dissector(payload_tvbrange:tvb(), pinfo, tree)
-- So far so good. Let's look at what the JSON dissector came up with.
local members = { json_member_f() }
local strings = { json_string_f() }
local subtree = tree:add(amqp_json_p)
for k, member in pairs(members) do
if member.display == 'result' then
for _, s in ipairs(strings) do
-- Find the string value inside this member
if not (s < member) and (s <= member) then
subtree:add(amqp_json_result, s.range)
break
end
end
end
end
end
end
end
(To start with, I'm just looking at the result field, and the payload I'm testing with is {"result":"ok"}.)
It gets me halfway there. The following shows up in the packet dissection, whereas without my plugin I only get the AMQP section:
Advanced Message Queueing Protocol
Type: Content body (3)
Channel: 1
Length: 15
Payload: 7b22726573756c74223a226f6b227d
JavaScript Object Notation
Object
Member Key: result
String value: ok
Key: result
AMQP JSON payload
Result: "ok"
Now I want to be able to use these new fields as display filters, and also to add them as columns in Wireshark. The following work for both:
json (shows up as Yes when added as a column)
json.value.string (I can also filter with json.value.string == "ok")
amqp_json
But amqp_json.result doesn't work: if I use it as a display filter, Wireshark doesn't show any packets, and if I use it as a column, the column is empty.
Why does it behave differently for json.value.string and amqp_json.result? And how can I achieve what I want? (It seems like I do need a custom dissector, as with json.value.string I can only filter on any member having a certain value, not necessarily result.)
I found a thread on the wireshark-dev mailing list ("Lua post-dissector not getting field values", 2009-09-17, 2009-09-22, 2009-09-23), that points to the interesting_hfids hash table, but it seems like the code has changed a lot since then.
If you'd like to try this, here is my PCAP file, base64-encoded, containing a single packet:
1MOyoQIABAAAAAAAAAAAAAAABAAAAAAAjBi1WfYOCgBjAAAAYwAAAB4AAABgBMEqADcGQA
AAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAB/tcWKO232y46mkSqgBgxtgA/AAAB
AQgKRjDNvkYwzb4DAAEAAAAPeyJyZXN1bHQiOiJvayJ9zg==
Decode with base64 -d (on Linux) or base64 -D (on OSX).
It turns out I shouldn't have tried to compare the display property of the json.member field. Sometimes it gets set by the JSON dissector, and sometimes it just stays as Member.
The proper solution would involve checking the value of the json.key field, but since the key I'm looking for presumably would never get escaped, I can get away with looking for the string literal in the range property of the member field.
So instead of:
if member.display == 'result' then
I have:
if member.range:range(1, 6):string() == 'result' then
and now both filtering and columns work.

Array.size() returned wrong values (Grails)

I'm developing an app using Grails. I want to get length of array.
I got a wrong value. Here is my code,
def Medias = params.medias
println params.medias // I got [37, 40]
println params.medias.size() // I got 7 but it should be 2
What I did wrong ?
Thanks for help.
What is params.medias (where is it being set)?
If Grials is treating it as a string, then using size() will return the length of the string, rather than an array.
Does:
println params.medias.length
also return 7?
You can check what Grails thinks an object is by using the assert keyword.
If it is indeed a string, you can try the following code to convert it into an array:
def mediasArray = Eval.me(params.medias)
println mediasArray.size()
The downside of this is that Eval presents the possibility of unwanted code execution if the params.medias is provided by an end user, or can be maliciously modified outside of your compiled code.
A good snippet on the "evil (or lack thereof) of eval" is here if you're interested (not mine):
https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/
I think 7 is result of length of the string : "[37,40]"
Seems your media variable is an array not a collection
Try : params.medias.length
Thanks to everyone. I've found my mistake
First of all, I sent an array from client and my params.medias returned null,so I converted it to string but it is a wrong way.
Finally, I sent and array from client as array and in the grails, I got a params by
params."medias[]"
List medias = params.list('medias')
Documentation: http://grails.github.io/grails-doc/latest/guide/single.html#typeConverters

Resources