本帖最后由 x527771 于 2011-12-16 01:28:39 编辑
wirshark是一个著名的网络报文捕获, 解码工具。 其自带丰富的报文解码库, 同时提供LUA语言的脚本接口, 用于没在解码库中的报文的解码。
比如, 对于承载在UDP/GRE上的LI报文, 不能被wirshark解码库识别, 但我们可以利用其脚本接口写一个插件, 完成Li报文解码。
LI报文定义:
UDP or GRE is used to encapsulate CC Notification Message.
LI Encapsulated Packet
IP Header
UDP/GRE Header
LI Header
PayLoad
(original subscriber packet)
LI Hearder description:
Definition of LIRP CC Notification Message
7(MSB) 6 5 4 3 2 1 0(LSB)
1 LIRP Edition PACKET Type
2 LIRP Message Type
3 Length of Attached CC
4
5 Sequence Number
6
7
8
9 LIID
10
11
12
13 Time Stamp
14
15
16
17
18
19
20
21 Message Head Length(included option)
22
… Option
Xx Attached CC begins at octet “CC Start Address”
LIRP Edition: It indicates the version of an LIRP message header. The current version is 1 and in some scenario will discard the messages whose version is not 1.
PACKET Type:It indicates the type of the packet. 0 is IPv4, 1 is IPv6, 2 is layer-2 link data.
LIRP Message Type: 0xC0 indicates LIRP CC Notification
Length of Attached CC: Length of the LIRP CC Notification message code stream, counting from the CC Start Address.
Sequence Number: LIRP message sequence number.
LIID: LI Identifier.
Time Stamp: It indicates the current time. See the following table for its format.
Description of Timestamp format
7(MSB) 6 5 4 3 2 1 0(LSB)
……
13 seconds
14
15
16
17 milliseconds
18
19
20
seconds: the seconds from 1970-01-01 00:00 to today's 00:00
Milliseconds: the milliseconds from today’s' 00:00 to now
Message Head Length: It indicates the length of the CC report header, for example, this parameter in Table is 22 + length of IMS charging ID. Its maximum value is 255.
Option: Now it is reserved for future expansion. When the Message Header Length is bigger than 24 + length of IMS charging ID, this parameter exists in the message header.
li.lua脚本如下:
--
li_proto = Proto("LI","LI","LI Protocol")
local li = li_proto.fields
local VALS_VER = {[0x1] = "01"}
local VALS_TYPE = {[0x00] = "ipv4",[0x01] = "ipv6",[0x02] = "layer-2 link data"}
li.ver=ProtoField.uint8("li_proto.ver","ver",base.DEC,VALS_VER,0xF0)
li.type=ProtoField.uint8("li_proto.type","type",base.DEC,VALS_TYPE,0x0F)
function li_proto.dissector(buffer,pinfo,tree)
if pinfo.ipproto==17 then
local udp_dissector = Dissector.get ("udp")
udp_dissector:call (buffer():tvb(), pinfo, tree)
offset=8
end
if pinfo.ipproto==47 then
offset=4
end
type = buffer(1+offset,1):uint()
x=buffer(offset,1):bitfield(0,4)
y=buffer(offset,1):bitfield(4,4)
if (x~=0x01) or (type ~= 0xC0) then
return false
end
pinfo.cols.protocol = "LI"
pinfo.cols.info = "LI data"
local subtree = tree:add(li_proto,buffer(offset,buffer:len()-offset),"LI Protocol")
subtree:add(li.ver,buffer(offset,1))
subtree:add(li.type,buffer(offset,1))
type_str = "Unknown:"
if type == 0xC0 then
type_str = "LIRP CC Notification"
pinfo.cols.info = type_str
end
subtree:add(buffer(1+offset,1), "LIRP Message Type: " .. type_str)
subtree:add(buffer(2+offset,2),"Length of Attached CC: " .. buffer(2+offset,2):uint())
subtree:add(buffer(4+offset,4),"Sequence Number: " .. buffer(4+offset,4):uint())
subtree:add(buffer(8+offset,4),"LIID: " .. buffer(8+offset,4):uint())
subtree:add(buffer(12+offset,4),"Time Stamp: "..buffer(12+offset,4):uint().."s "..os.date("%c", buffer(12+offset,4):uint()))
subtree:add(buffer(16+offset,4),"milliseconds: "..buffer(16+offset,4):uint())
subtree:add(buffer(20+offset,2),"Message Head Length(included option): " .. buffer(20+offset,2):uint())
head_len = buffer(20+offset,2):uint()
--size = buffer:len()
if head_len>22 then
--?? with option
subtree:add(buffer(22+offset,head_len-22),"option: ".. buffer(22+offset,head_len-22):uint())
end
local ip_dis
if y==0 then
ip_dis = Dissector.get("ip")
elseif y==1 then
--??
ip_dis = Dissector.get("ipv6")
elseif y==2 then
--?? layer-2 link data
ip_dis = Dissector.get("data")
else
--??
ip_dis = Dissector.get("data")
end
ip_dis:call(buffer(head_len+offset):tvb(),pinfo,subtree)
pinfo.cols.protocol = "LI"
if type == 0xC0 then
type_str = "LIRP CC Notification"
pinfo.cols.info = type_str
end
return ture
end
udp_table = DissectorTable.get("ip.proto")
udp_table:add(17,li_proto)
udp_table:add(47,li_proto)
如何使用:
1. 把li.lua(LI报文解码脚本) 拷贝到wireshark安装目录(如C:\Program Files\Wireshark)
2. 从wireshark安装目录(如C:\Program Files\Wireshark)找到init.lua
确保开头的disable_lua变量的值是false
disable_lua = false
在末尾增加dofile("li.lua")
3. 完成1,2两步, 重启wireshark, 就可以解LI报文,如图所示, 红色标注部分都是解码脚本产生的作用:
相关报文:
http://download.csdn.net/detail/x527771/3927094