2015-05-04 49 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 
相关问题