2015-05-04 48 views
1

我有這樣
「數據包」 的協議 - 消息
{頭} {內容} {頭} {內容} ...

「頭」 的序列 - 1個字節
位1- 7:消息長度
位8:真味精或不是

這是一個udp通信,我必須使用第8位來確定是否需要跳過消息。
以下是我的玩具解析器,問題我面對的是如何提取幫助我作出決定的bool值。

如何在Wireshark中使用Lua字段提取器?

TOY_proto = Proto("TOY", "TOY Protocol") 

local isSkip = ProtoField.new("Is Skip?", "mytoy.isSkip", ftypes.BOOLEAN, {"Yes", "No"}, 8, 0x01) 
local msgLen = ProroField.new("Message Length", "mytoy.msgLen", ftypes.UINT8, nil, base.DEC, 0xFE) 

TOY_proto.fields = {isSkip, msgLen} 

local isSkip_Field = Field.new("mytoy.isSkip") 
local function getIsSkip() 
    return isSkip_Field()() 
end 
local msgLen_Field = Field.new("mytoy.msgLen") 
local function getMsgLen() 
    return msgLen_Field()() 
end 

function TOY_proto.dissector(tvbuf, pktinfo, root) 
    pktinfo.cols.protocol = "TOY" 
    local pktlen = tvbuf:reported_length_remaining() 
    local pos = 0 

    while pos < pktlen do 
     local headTree = tree:add("Head") 
     headTree:add_le(isSkip, tvbuf:range(pos,1)) 
     headTree:add_le(msgLen, tvbuf:range(pos,1)) 
     if getIsSkip() then 
      pos = pos + getMsgLen() 
     else 
      -- do something else 
     end 
    end 
end 
udp_table = DissectorTable.get("udp.port") 
udp_table:add(6628, TOY_proto) 

的問題是,在第一循環中,每一個變量是做對的,但第一個循環後,從getIsSkip()和getMsgLen返回的值()始終不變。

回答

2

當你這樣做:

return isSkip_Field()() 

你真正做的是邏輯上等同於這樣:

-- extract the FieldInfo object using the Field object "isSkip_Field" 
local tempFieldInfo = isSkip_Field() 

-- get the Lua boolean value of the FieldInfo object 
local tempValue = tempFieldInfo() 

-- return it 
return tempValue 

我提到上述解釋爲什麼你得到你在做什麼後來在這個答案...

當你調用一個字段提取器(即,你打電話Field對象得到FieldInfo對象),你實際上回FieldInfoField的對象在調用提取器時在該數據包中存在的類型。您的數據包包含您的協議的多個「消息」,因此在每個循環中,您可以找回以前的循環的FieldInfo對象以及當前的對象。

換句話說,當你的腳本執行此:

return isSkip_Field()() 

...第一次爲一個包,它回來一個FieldInfo對象,稱那,並得到了布爾。當它第二次運行時,對isSkip_Field()的調用實際上返回了兩個FieldInfo對象,但它丟棄了第二個對象,因爲代碼在邏輯上等同於我在此答案頂部寫的代碼,而只是調用第一個實例當然,它與第一次循環迭代相同的布爾值;當它第三次運行相同的數據包時,它返回了三個FieldInfo對象,丟棄了第二個對象,稱爲第一個對象等。

所以你真正想要做的是選擇正確的FieldInfo對象每個循環迭代 - 即最近的(最後一個)。您可以採用以下兩種方法之一:(1)使用Lua select()函數,或(2)將返回的FieldInfo對象放入表中並檢索最後一個條目。

例如,做到這一點:

local isSkip_Field = Field.new("mytoy.isSkip") 
local function getIsSkip(num) 
    return select(num, isSkip_Field())() 
end 
local msgLen_Field = Field.new("mytoy.msgLen") 
local function getMsgLen(num) 
    return select(num, msgLen_Field())() 
end 

function TOY_proto.dissector(tvbuf, pktinfo, root) 
    pktinfo.cols.protocol = "TOY" 
    local pktlen = tvbuf:reported_length_remaining() 
    local pos = 0 

    local num = 1 
    while pos < pktlen do 
     local headTree = tree:add("Head") 
     headTree:add_le(isSkip, tvbuf:range(pos,1)) 
     headTree:add_le(msgLen, tvbuf:range(pos,1)) 
     if getIsSkip(num) then 
      pos = pos + getMsgLen(num) 
     else 
      -- do something else 
     end 
     num = num + 1 
    end 
end 

...或本:

local isSkip_Field = Field.new("mytoy.isSkip") 
local function getIsSkip() 
    local tbl = { isSkip_Field() } 
    return tbl[#tbl]() 
end 
local msgLen_Field = Field.new("mytoy.msgLen") 
local function getMsgLen() 
    local tbl = { msgLen_Field() } 
    return tbl[#tbl]() 
end 

function TOY_proto.dissector(tvbuf, pktinfo, root) 
    pktinfo.cols.protocol = "TOY" 
    local pktlen = tvbuf:reported_length_remaining() 
    local pos = 0 

    while pos < pktlen do 
     local headTree = tree:add("Head") 
     headTree:add_le(isSkip, tvbuf:range(pos,1)) 
     headTree:add_le(msgLen, tvbuf:range(pos,1)) 
     if getIsSkip() then 
      pos = pos + getMsgLen() 
     else 
      -- do something else 
     end 
    end 
end 

...或者,如果有將是很多領域的,這可能是更好:

local isSkip_Field = Field.new("mytoy.isSkip") 
local msgLen_Field = Field.new("mytoy.msgLen") 

local function getFieldValue(field) 
    local tbl = { field() } 
    return tbl[#tbl]() 
end 

function TOY_proto.dissector(tvbuf, pktinfo, root) 
    pktinfo.cols.protocol = "TOY" 
    local pktlen = tvbuf:reported_length_remaining() 
    local pos = 0 

    while pos < pktlen do 
     local headTree = tree:add("Head") 
     headTree:add_le(isSkip, tvbuf:range(pos,1)) 
     headTree:add_le(msgLen, tvbuf:range(pos,1)) 
     if getFieldValue(isSkip_Field) then 
      pos = pos + getFieldValue(msgLen_Field) 
     else 
      -- do something else 
     end 
    end 
end 
相關問題