本文有参考cmpp20协议lua插件,原文网址已遗失,抱歉!

-- CMPPv3.lua
 -- author: adminlocal p_CMPPv3 = Proto("CMPPv3", "China Mobile Peer to Peer Protocol v3.0")
 --消息长度
 local f_length = ProtoField.uint32("CMPPv3.length","MsgLength(消息长度)",base.DEC)
 --命令或响应类型
 local f_command_id = ProtoField.uint32("CMPPv3.commandId","CommandId(消息类型)",base.HEX,{
     [1] = "Connect",
     [2] = "Terminate",
     [4] = "Submit",
     [5] = "Deliver",
     [6] = "Query",
     [8] = "ActiveTest",
     [0x80000001] = "ConnectResp",
     [0x80000002] = "TerminateResp",
     [0x80000004] = "SubmitResp",
     [0x80000005] = "DeliverResp",
     [0x80000006] = "QueryResp",
     [0x80000008] = "ActiveTestResp"
 })
 --消息流水号
 local f_sequence_id = ProtoField.uint32("CMPPv3.sequenceId","SequenceId(序列号)",base.DEC);local f_msg_id_timestamp = ProtoField.string("CMPPv3.msgIdTimestamp","时间戳",base.NONE)
 local f_msg_id_sgw_id = ProtoField.uint32("CMPPv3.msgIdSgwId","网关Id");
 local f_msg_id_sequence = ProtoField.uint16("CMPPv3.msgIdSequence","序号");
 local f_message_id = ProtoField.bytes("CMPPv3.messageId","MsgId(消息Id)")
 local f_pk_total = ProtoField.uint8("CMPPv3.pkTotal","PkTotal(相同消息Id的信息总条数)")
 local f_pk_number = ProtoField.uint8("CMPPv3.pkNumber","PkNumber(相同消息Id的信息序号)")
 local yes_or_no = {
     [1] = "是",
     [0] = "否"
 }
 local f_registered_delivery = ProtoField.uint8("CMPPv3.registeredDelivery","RegisteredDelivery(是否返回状态报告)", base.DEC, yes_or_no)
 local f_is_delivery_report = ProtoField.uint8("CMPPv3.isReport","RegisteredDelivery(是否状态报告)", base.DEC, yes_or_no)
 local f_message_level = ProtoField.uint8("CMPPv3.messageLevel","MsgLevel(消息级别)")
 local f_service_id = ProtoField.string("CMPPv3.serviceId","ServiceId(业务类型)",base.NONE)
 local f_fee_user_type = ProtoField.uint8("CMPPv3.feeUserType","FeeUserType(计费类型)", base.DEC, {
     [0] = "对目的终端MSISDN计费",
     [1] = "对源终端MSISDN计费",
     [2] = "对SP计费",
     [3] = "本字段无效"
 })
 local f_fee_terminal_id = ProtoField.string("CMPPv3.feeTerminalId","FeeTerminalId(计费用户号码)",base.NONE)
 local f_message_src = ProtoField.string("CMPPv3.messageSrc","MessageSrc(信息内容来源)",base.NONE)
 local f_src_id = ProtoField.string("CMPPv3.srcId","SrcId(源号码)",base.NONE)
 local f_SrcTerminalId = ProtoField.string("CMPPv3.srcTerminalId","SrcTerminalId(源终端号码)",base.NONE)
 local f_reserved = ProtoField.bytes("CMPPv3.reserved","Reserve(保留域)")local f_data = ProtoField.bytes("CMPPv3.data","Data(字节数据)")
 local f_result = ProtoField.uint8("CMPPv3.result","Result(结果)",base.DEC,{
     [0] = "成功",
     [1] = "消息结构错",
     [2] = "命令字错",
     [3] = "消息序号重复",
     [4] = "消息长度错",
     [5] = "资费代码错",
     [6] = "超过最大信息长",
     [7] = "业务代码错",
     [8] = "流量控制错",
     [9] = "其他错误"
 })
 local f_dest_user_count = ProtoField.uint8("CMPPv3.destUserCount","DestUserCount(接收用户数)",base.DEC)
 local f_dest_terminal_id = ProtoField.string("CMPPv3.destTerminalId","DestTerminalId(接收用户号码)",base.NONE)
 local f_fee_type = ProtoField.uint16("CMPPv3.feeType","FeeType(计费类型)", base.HEX, {
     [0x03031] = "免费",
     [0x03032] = "按条计费",
     [0x03033] = "包月收费",
     [0x03034] = "封顶收费",
     [0x03035] = "SP收取"
 })
 --Fee_terminal_type 对于cmpp2.0新增部分
 local f_fee_terminal_type = ProtoField.uint8("CMPPv3.feeTerminalType","FeeTerminalType(被计费用户的号码类型)", base.DEC, {
     [0] = "真实号码",
     [1] = "伪码"
 })
 --Dest_terminal_type 对于cmpp2.0新增部分
 local f_dest_terminal_type = ProtoField.uint8("CMPPv3.destTerminalType","DestTerminalType(被计费用户的号码类型)", base.DEC, {
     [0] = "真实号码",
     [1] = "伪码"
 })local f_fee_value = ProtoField.string("CMPPv3.feeValue","FeeValue(资费)",base.NONE)
 local f_valid_time = ProtoField.string("CMPPv3.validTime","ValidTime(有效期)",base.NONE)
 local f_at_time = ProtoField.string("CMPPv3.atTime","AtTime(定时发送时间)",base.NONE)
 local f_tp_pid = ProtoField.uint8("CMPPv3.tpPid","TpPid(TP协议标识符)")
 local f_tp_udhi = ProtoField.uint8("CMPPv3.tpUdhi","TpUdhi(TP用户数据首部指示符)", base.DEC, {
     [0] = "用户数据只含短信内容",
     [1] = "用户数据含首部及短信内容"
 })
 local f_msg_fmt = ProtoField.uint8("CMPPv3.messageFormat","MsgFmt(内容编码)", base.DEC, {
     [0] = "ASCII",
     [3] = "短信写卡",
     [4] = "二进制",
     [8] = "UCS2",
     [15] = "GB18030"
 })
 local f_message_length = ProtoField.uint8("CMPPv3.messageLength","MessageLength(消息内容字节数)")
 local f_msg_content = ProtoField.bytes("CMPPv3.msgContent","MsgContent(消息内容)")
 local f_msg_content_decoded = ProtoField.string("CMPPv3.messageContentDecoded","MessageContentDecoded",base.NONE)
 local f_dest_id = ProtoField.string("CMPPv3.destId","DestId(接收号码)",base.NONE)-- 状态报告内容中的各字段
 local f_content_msg_id = ProtoField.bytes("CMPPv3.contentMsgId","MsgId(消息Id)")
 local f_content_stat = ProtoField.string("CMPPv3.contentStat","Stat(应答结果)",base.NONE)
 local f_content_submit_time = ProtoField.string("CMPPv3.contentSubmitTime","SubmitTime(提交时间)",base.NONE)
 local f_content_done_time = ProtoField.string("CMPPv3.contentDoneTime","DoneTime(完成时间)",base.NONE)
 local f_content_dest_terminal_id = ProtoField.string("CMPPv3.contentDestTerminalId","DestTerminalId(目的终端号码)",base.NONE)
 local f_content_sequence = ProtoField.uint32("CMPPv3.contentSequence","Sequence(序列号)")local f_source_addr = ProtoField.string("CMPPv3.sourceAddr","SourceAddr(源地址)",base.NONE)
 local f_authenticator_source = ProtoField.string("CMPPv3.authenticatorSource","AuthenticatorSource(源地址认证码)",base.NONE)
 local f_version = ProtoField.uint8("CMPPv3.version","Version(版本号)",base.DEC,{[32] = "v2.0",[48] = "v3.0"})
 local f_timestamp = ProtoField.uint32("CMPPv3.timestamp","Timestamp(时间戳)")
 local f_status = ProtoField.uint8("CMPPv3.status","Status(状态)", base.DEC, {[0] = "成功",[1] = "消息结构错",[2] = "非法源地址",[3] = "认证错",[4] = "版本太高",[5] = "其他错误"})
 local f_authenticator_ismg = ProtoField.string("CMPPv3.authenticatorIsmg","AuthenticatorIsmg(短信网关认证码)",base.NONE)
 local f_msg_content_header = ProtoField.bytes("CMPPv3.messageContentHeader", "Header(首部)")p_CMPPv3.fields = {
     f_length, f_command_id, f_sequence_id, f_data, f_result, f_dest_user_count, f_dest_terminal_id,
     f_fee_type, f_fee_value, f_valid_time, f_at_time, f_tp_pid, f_tp_udhi, f_msg_fmt, f_message_length, f_msg_content,
     f_message_id, f_pk_total, f_pk_number, f_registered_delivery, f_message_level, f_service_id, f_fee_user_type,
     f_fee_terminal_id, f_message_src, f_src_id, f_reserved, f_msg_id_timestamp, f_msg_id_sgw_id, f_msg_id_sequence,
     f_SrcTerminalId, f_dest_id, f_content_msg_id, f_content_stat, f_content_submit_time, f_content_done_time,
     f_content_dest_terminal_id, f_content_sequence, f_is_delivery_report, f_msg_content_header,f_source_addr,f_authenticator_source,
     f_version,f_timestamp,f_status,f_authenticator_ismg,f_fee_terminal_type,f_dest_terminal_type
 }-- 处理MessageId:除MessageId本身外,还解析其中包含的时间戳、网关Id和序列号
 local function process_message_id(field, buffer, t)
     local node = t:add(field, buffer)
     node:add(f_msg_id_timestamp, tostring(buffer:bitfield(0, 4)) .. "/" .. tostring(buffer:bitfield(4, 5)) .. " " .. tostring(buffer:bitfield(9, 5)) .. ":" .. tostring(buffer:bitfield(14, 6)) .. ":" .. tostring(buffer:bitfield(20, 6)))
     node:add(f_msg_id_sgw_id, buffer:bitfield(26, 22))
     node:add(f_msg_id_sequence, buffer:bitfield(48, 16))
 end-- 解码短信内容:根据编码方式解码短信内容
 local function decode_content(buf, length, format)
     if (format == 8) then
         return buf(0, length):ustring();
     elseif (format == 0) then
         return buf(0, length):string();
     elseif(format == 15) then
         return buf(0, length):stringz();
     else
         return "API无法解码该编码的内容"
     end
 end-- 处理短信内容:根据长短信标识及编码方式处理短信内容
 local function process_content(buf, pos, length, udhi, encoding, t)
     local node = t:add(f_msg_content, buf(pos, length))
     local head_length
     if (udhi == 1) then
         head_length = buf(pos, 1):uint() + 1
         node:add(f_msg_content_header, buf(pos, head_length))
     else
         head_length = 0
     end
     node:add(f_msg_content_decoded, "Decoded(解码后内容): " .. decode_content(buf(pos + head_length), length - head_length, encoding))
 end-- 解析connect
 local function parse_connect(buf, t)
     t:add(f_source_addr, buf(12, 6))
     t:add(f_authenticator_source, buf(18, 16))
     t:add(f_version, buf(34, 1))
     t:add(f_timestamp, buf(35, 4))
 end-- 解析connect_resp
 local function parse_connect_resp(buf, t)
     t:add(f_status, buf(12, 4))
     t:add(f_authenticator_ismg, buf(16, 16))
     t:add(f_version, buf(32, 1))
 end-- 解析submit
 local function parse_submit(buf, t)
     process_message_id(f_message_id, buf(12, 8), t)
     t:add(f_pk_total, buf(20, 1))
     t:add(f_pk_number, buf(21, 1))
     t:add(f_registered_delivery, buf(22, 1))
     t:add(f_message_level, buf(23, 1))
     t:add(f_service_id, buf(24, 10))
     t:add(f_fee_user_type, buf(34, 1))
     t:add(f_fee_terminal_id, buf(35, 32))
     t:add(f_fee_terminal_type, buf(67, 1))
     t:add(f_tp_pid, buf(68, 1))
     t:add(f_tp_udhi, buf(69, 1))
     t:add(f_msg_fmt, buf(70, 1))
     t:add(f_message_src, buf(71, 6))
     t:add(f_fee_type, buf(77, 2))
     t:add(f_fee_value, buf(79, 6))
     t:add(f_valid_time, buf(85, 17))
     t:add(f_at_time, buf(102, 17))
     t:add(f_src_id, buf(119, 21))
     t:add(f_dest_user_count, buf(140, 1))    local user_num = buf(140, 1):uint();
     local pos = 141
     for i = 1, user_num do
         t:add(f_dest_terminal_id, buf(pos, 32))
         pos = pos + 32
     end
     t:add(f_dest_terminal_type, buf(pos, 1))
     pos = pos + 1
     t:add(f_message_length, buf(pos, 1))
     local length = buf(pos, 1):uint()
     process_content(buf, pos + 1, length, buf(69, 1):uint(), buf(70, 1):uint(), t)
     t:add(f_reserved, buf(pos + 1 + length, 20))
 end-- 解析deliver
 local function parse_deliver(buf, t)
     -- 处理MessageId
     process_message_id(f_message_id, buf(12, 8), t)
     t:add(f_dest_id, buf(20, 21))
     t:add(f_service_id, buf(41, 10))
     t:add(f_tp_pid, buf(51, 1))
     t:add(f_tp_udhi, buf(52, 1))
     t:add(f_msg_fmt, buf(53, 1))
     t:add(f_SrcTerminalId, buf(54, 32))
     t:add(f_is_delivery_report, buf(86, 1))
     t:add(f_dest_terminal_type, buf(87, 1))
     t:add(f_message_length, buf(88, 1))
     local length = buf(88, 1):uint()    if (length > 0) then
         if (buf(86, 1):uint() == 1) then
             local content = t:add(f_msg_content, buf(89, length))
             process_message_id(f_content_msg_id, buf(89, 8), content)
             content:add(f_content_stat, buf(97, 7))
             content:add(f_content_submit_time, buf(104, 10))
             content:add(f_content_done_time, buf(114, 10))
             content:add(f_content_dest_terminal_id, buf(124, 32))
             content:add(f_content_sequence, buf(156, 4))
         else
             process_content(buf, 89, length, buf(52, 1):uint(), buf(53, 1):uint(), t);
         end
     end
     t:add(f_reserved, buf(89 + length, 20))
 end-- 解析响应
 local function parse_response(buf, t)
     process_message_id(f_message_id, buf(12, 8), t)
     t:add(f_result, buf(20, 1))
 endlocal function CMPPv3_dissector(buf,pkt,root)
     local buf_len = buf:len();
     local count = 0;
     while(buf_len > 8)do
         if buf_len < 8 then return false end
     pkt.cols.protocol = "CMPPv3"
     local v_length = buf(0,4)
     local len = v_length:uint()
     local t = root:add(p_CMPPv3, buf(0, len))
     t:add(f_length, v_length)
     t:add(f_command_id, buf(4,4))
     t:add(f_sequence_id, buf(8,4))    local v_command = buf(4,4):uint()
     if v_command == 1 then
         parse_connect(buf, t)
     elseif v_command == 4 then
         parse_submit(buf, t)
     elseif v_command == 5 then
         parse_deliver(buf, t)
     elseif v_command == 0x80000004 or v_command == 0x80000005 then
         parse_response(buf, t)
     elseif v_command == 0x80000001 then
         parse_connect_resp(buf, t)
     else
         if (buf_len > 12) then
             t:add(f_data, buf(12, len))
         end
     end
       count = count+1;
       if(count > 10)then
         break
       end
       if buf_len > len then
         buf = buf(len,buf_len-len)
         buf_len = buf:len();
       else
         break;
       end
   end
   return true
 endfunction p_CMPPv3.dissector(buf,pkt,root)
     -- 解析 CMPPv3
     if not CMPPv3_dissector(buf,pkt,root) then
         -- 使用默认输出
         Dissector.get("data"):call(buf, pkt, root)
     end
 endDissectorTable.get("tcp.port"):add(7890, p_CMPPv3)