This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

Create my own dissector

0

Hi,

i try to create a dissector for my own simple UDP-Command-Protocol.

       -- Deklaration des neuen Protokolls 
       -- Proto("KurzName für FilterListbox", "LangName") 
UDP_CMD_proto = Proto("UDP-CMD","UDP-Command Protocol")
   -- Deklaration der Felder im UDP_CMD_proto 
local f = UDP_CMD_proto.fields
   -- .uint8(StatusText, "Text", Hex-Ausgane, nil, welche Bits) 
  f.Flag1 = ProtoField.uint8("UDP_CMD_proto.Flag1", "Response required", base.HEX, { [1] = "YES", [0] = "NO"}, 0x01)
  f.Flag2 = ProtoField.uint8("UDP_CMD_proto.Flag2", "...", base.HEX, nil, 0x02)
  f.Flag3 = ProtoField.uint8("UDP_CMD_proto.Flag3", "...", base.HEX, nil, 0x04)
  f.Flag4 = ProtoField.uint8("UDP_CMD_proto.Flag4", "...", base.HEX, nil, 0x08)
  f.Flag5 = ProtoField.uint8("UDP_CMD_proto.Flag5", "...", base.HEX, nil, 0x10)
  f.Flag6 = ProtoField.uint8("UDP_CMD_proto.Flag6", "...", base.HEX, nil, 0x20)
  f.Flag7 = ProtoField.uint8("UDP_CMD_proto.Flag7", "...", base.HEX, nil, 0x40)
  f.Flag8 = ProtoField.uint8("UDP_CMD_proto.Flag8", "...", base.HEX, nil, 0x80)

   -- Scriptfunktion zum "sezieren" der Protokolldaten
   -- mit Zugriff auf
   -- .dissector(PayloadData, InfoZeile, AnzeigeBaum)

function UDP_CMD_proto.dissector(buffer,pinfo,tree)


   -- Zugriff auf den Protokollnamen in der InfoZeile
pinfo.cols.protocol = "UDP-CMD"
   -- Zugriff auf den InfoText in der InfoZeile
if pinfo.dst_port == 33333 then
  pinfo.cols.info = "Command         --> PC"
end
if pinfo.src_port == 33333 then
  pinfo.cols.info = "PC-Response     --> WIZ200"
end
if pinfo.dst_port == 33334 then
  pinfo.cols.info = "Command         --> WIZ200"
end
if pinfo.src_port == 33334 then
  pinfo.cols.info = "WIZ200-Response --> PC"
end

   -- Erstellung des AnzeigeBaumes für die PayloadData
   -- Neue main_TreeNode-Variable zum betehenden Tree (Frame, Ethernet, IP-Protokoll, UDP-Protokoll)
   -- tree:add(DISSECTOR, alleBytes, "NameDerZeile") [wir brauchen nur einen Zeiger für den ganzen Baum!]          
local TreeNode_E1 = tree:add(UDP_CMD_proto,buffer(),"UDP-Command Protocol Data")

TreeNode = TreeNode_E1:add("Source")    
  TreeNode:add("IP  :", pinfo.src)
  TreeNode:add("Port:", pinfo.src_port)

TreeNode = TreeNode_E1:add("Destination")
  TreeNode:add("IP  :", pinfo.dst)
  TreeNode:add("Port:", pinfo.dst_port)

local flags = buffer(0,1)
TreeNode = TreeNode_E1:add(buffer(0,1), "CommandFlags")
  TreeNode:add(f.Flag1, flags)
  TreeNode:add(f.Flag2, flags)
  TreeNode:add(f.Flag3, flags)
  TreeNode:add(f.Flag4, flags)
  TreeNode:add(f.Flag5, flags)
  TreeNode:add(f.Flag6, flags)
  TreeNode:add(f.Flag7, flags)
  TreeNode:add(f.Flag8, flags)

   -- Neuer Eintrag eine Ebene unterhalb der eben erstellten main_TreeNode-Variable        
   -- TreeNode:add(Byte(Pos, Count), Text .. Byte(Pos, Count)AsInteger  .. Text)

TreeNode_E1:add(buffer(1,1),"Modul Type:" , buffer(1,1):uint())

--TreeNode:add(buffer(1,1),"Command    : <" .. buffer(1,1):uint() .. ">")
--TreeNode:add(buffer(3),"OptionalCMD: " .. buffer(3):string())

end

   -- Zuweisung der UDP-Tabelle

udp_table = DissectorTable.get("udp.port") – Zuweisung der zu überwachenden Ports udp_table:add(33334,UDP_CMD_proto) udp_table:add(33333,UDP_CMD_proto)

With

TreeNode = TreeNode_E1:add("Destination")
TreeNode:add("IP  :", pinfo.src)
TreeNode:add("Port:", pinfo.dst_port)

I try to show the destination IP and Port, the Port filter works but the IP-filter don´t.

I also tryed : ip.src…..

How to show the soure and destination IP from the IP-Protocol part? Same Problem with the MAC-Address from the Ethernet part.

Thanks for your Help and excuse my bad english. Greets from the rainy Germany… Pfanne

asked 06 Jun ‘11, 09:43

Pfanne's gravatar image

Pfanne
1334
accept rate: 0%


4 Answers:

2

pinfo.src returns an Address userdata object (not string, which tree:add() requires). The same is true for:

  • pinfo.dst
  • pinfo.dl_src
  • pinfo.dl_dst
  • pinfo.net_src
  • pinfo.net_dst

You have to use tostring to get the string representation of the IP address. In your case:

TreeNode = TreeNode_E1:add("Source")    
  TreeNode:add("IP  :", tostring(pinfo.src))
  TreeNode:add("Port:", pinfo.src_port)

TreeNode = TreeNode_E1:add("Destination") TreeNode:add("IP :", tostring(pinfo.dst)) TreeNode:add("Port:", pinfo.dst_port)

answered 06 Jun ‘11, 10:35

bstn's gravatar image

bstn
3751415
accept rate: 14%

Jiiip, that´s the “missing link”

I try´d toString bevor but only in combination with - ip.src - UDP_CMD_proto.src

but never with pinfo.scr, the good was so near.. :-)

thanks….

Next Question: Is ist possible to add an If or an CASE query to this TreeNode

TreeNode_E1:add(buffer(1,1),"Modul Type:" , buffer(1,1):uint())

like this IF-statement

f.Flag1 = ProtoField.uint8("UDP_CMD_proto.Flag1", "Response required", base.HEX, { [1] = "YES", [0] = "NO"}, 0x01)

like this {[1]=“Case1”, [2]=“Case2”}

thanks for your help….. :-) The lua-syntax is not may world…..

(06 Jun ‘11, 12:00) Pfanne

No, TreeItem can’t lookup value-strings the way you describe, but it only takes an extra line of code to do what you need. In the following example, we use a Lua table to implement a value-string map:

– map "yes" and "no"
local VALS_YES_NO = {[1] = "YES", [0] = "NO"}

– add the 2nd byte as "yes" or "no" (default: "no") TreeNode_E1:add( buffer(1,1), "Response required:", VALS_YES_NO[ buffer(1,1):uint() ] or "NO" )

(06 Jun ‘11, 12:58) bstn

1

The following Lua gets you close (the format of the strings are slightly different):

local idx0 = 6  -- start index
local idx1 = 11     -- end index

local asc = "" local dec = "" local hex = ""

– Get the ASCII, decimal, and hex codes of each character – in the buffer between idx0 and idx1 and concatenate them – with a space delimiter for i = idx0, idx1 do local c = buffer(i,1):uint()

-- only append printable characters (hide garbage with spaces)
if c >= 0x20 and c <= 0x7E then
    asc = string.format("%s %3c", asc, c)
else
    asc = asc .. "    "
end

dec = string.format("%s %03d", dec, c)
hex = string.format("%s %3x", hex, c)

end

TreeNode = TreeNode_E1:add("Value") TreeNode:add( buffer(idx0, idx1), "String :" , asc ) TreeNode:add( buffer(idx0, idx1), "Dezimal :" , dec ) TreeNode:add( buffer(idx0, idx1), "HEX :" , hex )

answered 07 Jun ‘11, 14:26

bstn's gravatar image

bstn
3751415
accept rate: 14%

0

Hi,

another great hint, thanks for it..... two more day and i will love the lua script language....

i think we have finished "our" little projekt soon.... :-) maybe the last problem:

i would like to constitute the last protokollbytes (Byte 6 to n) in all possible formats / vartypes e.g.:

ASCII: H   a   l   l   o
DEC  : 072 097 108 108 111
HEX  : 48  61  6C  6C  6F

How to add this to a treenode, absolutely we need to create a string in a for/next loop and add each formatet/transformed byte to the string. The main problem is..... right, the lua syntax for this....

local VALS_Value = ""
for i = 6, 11, 1 do
  VALS_Value = VALS_Value + buffer(i):string()
end

TreeNode = TreeNode_E1:add("Value") TreeNode:add(buffer(6), "String :" , buffer(6):string()) TreeNode:add(buffer(6), "Dezimal :" , buffer(6):string()) TreeNode:add(buffer(6), "HEX :" , buffer(6):string()) TreeNode:add(VALS_Value)

please can you help me again….. :-)

Thanks ands greeds from Hamburg Pfanne

answered 07 Jun ‘11, 13:30

Pfanne's gravatar image

Pfanne
1334
accept rate: 0%

0

Hi bstn,

thanks for your great help again.... :-) I will test this code soon as possible, when i´m at home.

local idx1 = 11     -- end index

the end index shoud be the last byte of the payload data....

TreeNode:add( buffer(idx0),...

could this be work: local idx1 = pinfo.len <-- here we need the length of the payload data, i think this is the total lenght of the frame.

EDIT: What about --> buffer:len() ??

Thanks Pfanne

answered 07 Jun '11, 23:45

Pfanne's gravatar image

Pfanne
1334
accept rate: 0%

edited 08 Jun '11, 02:16