zoukankan      html  css  js  c++  java
  • 工欲善其事,必先利其器-redis 6.0 RCMB集群协议wireshark解析插件

    先看效果

    代码实现

    需要修改适配相关的端口,或者wireshark设置强制解析

    do
        -- 简单的认为单个tcp报文就是单个rcmb消息,假设不会拆包或者合包
        local p_RCMB = Proto("RCMB","Redis Cluster message bus")
    
        --RCmb协议的基础字段
        local base_sig = ProtoField.string("RCMB.sig","Sig")
        local base_totlen = ProtoField.uint32("RCMB.totlen","TotLen",base.DEC)
        local base_ver = ProtoField.uint16("RCMB.ver","Ver",base.DEC)
        local base_port = ProtoField.uint16("RCMB.port","Port",base.DEC)
        local base_type = ProtoField.uint16("RCMB.type","Type",base.DEC,
            { [0] = "PING", [1] = "PONG", [2] = "MEET", [3] = "FAIL", [4] = "PUBLISH",
             [5] = "FAILOVER_AUTH_REQUEST", [6] = "FAILOVER_AUTH_ACK", 
             [7] = "UPDATE", [8] = "MFSTART", [9] = "MODULE"})
    
        local base_count = ProtoField.uint16("RCMB.count","Count",base.DEC)
        local base_currentEpoch = ProtoField.uint64("RCMB.currentEpoch","CurrentEpoch",base.DEC)
        local base_configEpoch = ProtoField.uint64("RCMB.configEpoch","ConfigEpoch",base.DEC)
        local base_offset = ProtoField.uint64("RCMB.offset","Offset",base.DEC)
    
        local base_sender = ProtoField.string("RCMB.sender","Sender")
        local base_myslots = ProtoField.bytes("RCMB.myslots","Myslots")
        local base_slaveof = ProtoField.string("RCMB.slaveof","Slaveof")
        local base_myip = ProtoField.string("RCMB.myip","Myip")
        local base_notused1 = ProtoField.bytes("RCMB.notused1","Notused1")
        local base_cport = ProtoField.uint16("RCMB.cport","Cport",base.DEC)
        local base_flags = ProtoField.uint16("RCMB.flags","Flags",base.DEC)
        local base_state = ProtoField.uint8("RCMB.state","State",base.DEC,
            { [0] = "CLUSTER_OK", [1] = "CLUSTER_FAIL"})
        local base_mflags = ProtoField.bytes("RCMB.mflags","Mflags")
    
        -- ping消息字段
        local gossip_nodename = ProtoField.string("RCMB.gossip_nodename","Gossip_nodename")
        local gossip_ping_sent = ProtoField.uint32("RCMB.gossip_ping_sent","Gossip_ping_sent",base.DEC)
        local gossip_pong_received= ProtoField.uint32("RCMB.gossip_pong_received","Gossip_pong_received",base.DEC)
        local gossip_ip = ProtoField.string("RCMB.gossip_ip","Gossip_ip")
        local gossip_port = ProtoField.uint16("RCMB.gossip_port","Gossip_port",base.DEC)
        local gossip_cport = ProtoField.uint16("RCMB.gossip_cport","Gossip_cport",base.DEC)
        local gossip_flags = ProtoField.uint16("RCMB.gossip_flags","Gossip_flags",base.DEC)
        local gossip_notused1= ProtoField.uint32("RCMB.gossip_notused1","Gossip_notused1",base.DEC)
    
        -- fail消息字段
        local fail_nodename = ProtoField.string("RCMB.fail_nodename","Fail_nodename")
    
        -- publish消息字段
        local publish_channel_len= ProtoField.uint32("RCMB.publish_channel_len","Publish_channel_len",base.DEC)
        local publish_message_len= ProtoField.uint32("RCMB.publish_message_len","Publish_message_len",base.DEC)
        local publish_bulk_data = ProtoField.bytes("RCMB.publish_bulk_data","Publish_bulk_data")
    
        -- update消息字段
        local update_configEpoch= ProtoField.uint64("RCMB.update_configEpoch","Update_configEpoch",base.DEC)
        local update_nodename = ProtoField.string("RCMB.update_nodename","Update_nodename")
        local update_slots = ProtoField.bytes("RCMB.update_slots","Update_slots")
    
        -- module消息字段
        local module_id = ProtoField.uint64("RCMB.module_id","Module_id",base.DEC)
        local module_len = ProtoField.uint32("RCMB.module_len","Module_len",base.DEC)
        local module_type = ProtoField.uint8("RCMB.module_type","Module_type",base.DEC)
        local module_bulk_data = ProtoField.bytes("RCMB.module_bulk_data","Module_bulk_data")
    
    
        p_RCMB.fields = { base_sig, base_totlen, base_ver, base_port, base_type, base_count, base_currentEpoch, base_configEpoch, base_offset,
            base_sender, base_myslots, base_slaveof, base_myip, base_notused1, base_cport, base_flags, base_state, base_mflags, 
            gossip_nodename, gossip_ping_sent, gossip_pong_received, gossip_ip, gossip_port, gossip_cport, gossip_flags, gossip_notused1,
            fail_nodename,
            publish_channel_len, publish_message_len, publish_bulk_data,
            update_configEpoch, update_nodename, update_slots,
            module_id,module_len,module_type,module_bulk_data}
    
        local data_dis = Dissector.get("data")
    
        local function RCMB_dissector(buf,pkt,root)
            local buf_len = buf:len();
            -- 先确保至少有4个byte存放"RCmb"
            if buf_len < 4 then return false end
    
            if (buf(0,4):uint()~=1380150626)
                -- 1380150626为RCmc的uint32表示
                then return false end
    
    
            local t = root:add(p_RCMB,buf)
            pkt.cols.protocol = "RCMB"
    
            t:add(base_sig,buf(0,4))
            t:add(base_totlen,buf(4,4))
            t:add(base_ver,buf(8,2))
            t:add(base_port,buf(10,2))
            -- 记录type信息,用于后续根据type解析不同字段
            local i_type = buf(12,2):uint()
            t:add(base_type,buf(12,2))
            t:add(base_count,buf(14,2))
    
            t:add(base_currentEpoch,buf(16,8))
            t:add(base_configEpoch,buf(24,8))
            t:add(base_offset,buf(32,8))
    
            t:add(base_sender,buf(40,40))
            t:add(base_myslots,buf(80,2048))
            t:add(base_slaveof,buf(2128,40))
    
            t:add(base_myip,buf(2168,46))
    
            t:add(base_notused1,buf(2214,34))
            t:add(base_cport,buf(2248,2))
            t:add(base_flags,buf(2250,2))
            t:add(base_state,buf(2252,1))
            t:add(base_mflags,buf(2253,3))
    
    
            -- 按照消息类型分类型解析
            if (i_type == 0) then
                --把存在的字段逐个添加进去
                t:add(gossip_nodename,buf(2256,40))
                t:add(gossip_ping_sent,buf(2296,4))
                t:add(gossip_pong_received,buf(2300,4))
                t:add(gossip_ip,buf(2304,46))
    
                t:add(gossip_port,buf(2350,2))
                t:add(gossip_cport,buf(2352,2))
                t:add(gossip_flags,buf(2354,2))
                t:add(gossip_notused1,buf(2256,4))
    
            elseif (i_type == 3) then
                t:add(fail_nodename,buf(2256,40))
    
            elseif (i_type == 4) then
                t:add(publish_channel_len, buf(2256,4))
                t:add(publish_message_len, buf(2260,4))
                t:add(publish_bulk_data, buf(2264,8))
    
            elseif (i_type == 7) then
                t:add(update_configEpoch,buf(2256,8))
                t:add(update_nodename,buf(2264,40))
                t:add(update_slots,buf(2304,2048))
    
            elseif (i_type == 9) then
                t:add(module_id,buf(2256,8))
                t:add(module_len,buf(2264,4))
                t:add(module_type,buf(2268,2))
                t:add(module_bulk_data,buf(2270,3))
            end
    
    
            return true
        end
    
        function p_RCMB.dissector(buf,pkt,root) 
            if RCMB_dissector(buf,pkt,root) then
                --valid RCMB diagram
            else
                --data这个dissector几乎是必不可少的;当发现不是我的协议时,就应该调用data
                -- return 0;同样效果?
                data_dis:call(buf,pkt,root)
            end
        end
    
        local tcp_port_table = DissectorTable.get("tcp.port")
        --只需要处理UDP1127端口就可以了
        tcp_port_table:add(40001,p_RCMB)
        for i,port in ipairs{40002,40003, 40004, 40005, 40006} do
            tcp_port_table:add(port,p_RCMB)
        end
    end

    补充:

    1. 实现参考: https://www.jianshu.com/p/1e2f63a484d6
    2. TCP解析复杂处理https://wiki.wireshark.org/Lua/Examples?action=AttachFile&do=get&target=fpm.lua

    附件列表

    • 相关阅读:
      python模块:XML
      python常用模块:json&pickle
      python模块:os,sys
      python常用模块:time与random
      文件查询修改功能实现
      Ubuntu--smb配置文件详解
      Ubuntu添加计划任务
      Docker私有仓库registry
      docker + calico网络,实现不同容器之间的相互访问
      Centos7 yum安装nginx
    • 原文地址:https://www.cnblogs.com/lshs/p/14276541.html
    Copyright © 2011-2022 走看看