本帖最后由 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 |
|