This is our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

Hello,

At my job we regularly use switches which got a proprietary ring redundancy protocol. In order to make our job easier, I am trying to make a dissector so wireshark correctly shows information instead of showing 'llc' as it currently does.

I looked up multiple tutorials, but so far almost all of those I found talk about connecting to a specific UDP or TCP port while what I intend to do hooks directly on the MAC/ethernet level.

I know for sure that the lua gets loaded, as writing an error or invalid action causes a crash. I tried multiple ways of getting wireshark to translate as my protocol instead of LLC, but I got no success so far. If anyone can give me a hint or a source where I can find the answer myself I would appreciate it!

wireshark trace of a few packets of the protocol: https://drive.google.com/file/d/0B9vmLCalgzm1NC1KUzNqRENFY1E/view?usp=sharing

image for those who rather don't download files from unknown sources: alt text

My current code attempt:

    original_802_3_dissector = DissectorTable.get( "wtap_encap" ):get_dissector( 1 )

protoRGERP = Proto("RGERP", "Redundant Gigabit Ethernet Ring Protocol")

local f = protoRGERP.fields
local vs_state = {[0]="normal",[1]="abnormal"}

f.ringId = ProtoField.uint16("protoRGERP.ringId", "Ring ID")
f.ringState = ProtoField.bool("protoRGERP.ringState", "Ring Status")
f.ringMaster = ProtoField.ether("protoRGERP.ringMaster","Ring Master")
f.ringData = ProtoField.bytes ("protoRGERP.ringData","Data")
--f.ringInfo = ProtoField.string("protoRGERP.ringInfo","Ring Info")

local packet_counter
function protoRGERP.init()
    packet_counter = 0
end

function protoRGERP.dissector(buffer, pinfo, tree)
    --run default ethernet dissector
    original_802_3_dissector:call(buffer,pinfo,tree)
    --tree additions
    local subtree = tree:add(protoRGERP, buffer())
    local offset=12
    local ringId = buffer(offset,1)
    subtree:add (f.ringId, ringId)
    subtree:append_text(", Ring ID: "..ringId:uint())
    offset=offset+1

    local ringState = buffer(offset,1)
    subtree:add(f.ringState, ringState)
    subtree:append_text(", Ring normal : "..ringState:bool())
    offset=offset+1

    local ringMaster = buffer(offset,6)
    subtree:add(f.ringMaster, ringMaster)
    subtree:append_text(", RM MAC: "..ringMaster:ether())
    offset=offset+6

    subtree:add( f.ringData, buffer(offset))

    -- modify columns; to be extended
    pinfo.cols['protocol'] = "RGERP"
    pinfo.cols.info = "RGERP ID: "
    pinfo.cols.info:append(ringId:uint())

end

--local wtap_encap_table = DissectorTable.get("wtap_encap")
--wtap_encap_table:add(0x1a, protoRGERP)
--below causes wireshark to crash
--local llc_table = DissectorTable.get("llc.dsap")
--llc_table:add(0x6b, protoRGERP)
local dissector_table2 = DissectorTable.get("ethertype")
dissector_table2:add(0x1a,protoRGERP)
local dissector_table3 = DissectorTable.get("wtap_encap")
dissector_table3:add(wtap.USER0, protoRGERP)

asked 04 Apr '17, 08:10

nikdubois's gravatar image

nikdubois
6115
accept rate: 100%

minor update: with replacing ethernet I can get it working, but I can't get the if structure working to run the original ethernet dissector if mine isn't needed. A way to do this might be a good workaround if anyone knows how/if this is possible!

this is how I replaced the dissector:

original_802_3_dissector = DissectorTable.get( "wtap_encap" ):get_dissector( 1 )
local dissector_table3 = DissectorTable.get("wtap_encap")
dissector_table3:add(1, protoRGERP)

and then I wrapped my code in the proto.dissector in an if:

function protoRGERP.dissector(buffer, pinfo, tree)
    if buffer(0xE,4):string()~='6b726e78' then
       ~code~
    else
        original_802_3_dissector:call(buffer,pinfo,tree)
    end
end

But this causes 'wireshark has stopped responding'. I couldn't find an error in a log yet.

(04 Apr '17, 08:48) nikdubois
1

So does this protocol run atop Ethernet?

If so, does it:

  1. have an Ethernet type value assigned to it;
  2. have an 802.2 DSAP assigned to it;
  3. have a SNAP OUI and protocol ID assigned to it;
  4. violate the Ethernet spec?

(All protocols that run atop Ethernet do one of those four things; i.e., if they don't have one of those values assigned to them, they're violating the Ethernet spec.)

(04 Apr '17, 18:05) Guy Harris ♦♦

I fear it is the last. I will raise the issue with the manufacturer, but I don't think this can/will be changed by them anytime soon.

My guess is that I will have to do the workaround using a chained dissector (my own into the ethernet if it is not my own protocol). So far this always crashes for me though, so if you have a working example using the ethernet dissector I would appreciate it!

(05 Apr '17, 00:15) nikdubois

I managed to get it working eventually, but make sure to read the comment of Guy Harris as he is right. What I used below is an ugly way to get around it and there are better solutions. Just posting this so others in a similar situation can get a workaround untill they fix it.

protoRGERP = Proto("RGERP", "RGERP", "Redundant Gigabit Ethernet Ring Protocol")

local f = protoRGERP.fields
local vs_ringState = {[0]="normal",[1]="abnormal"}
local vs_portState = {[0]="up",[1]="down"}

--f.packetSource = ProtoField.ether("protoRGERP.packetSource","Source")
--f.packetDest = ProtoField.ether("protoRGERP.packetSource","Destination")
f.packetType = ProtoField.string("protoRGERP.packetType","LLC Type")
f.ringId = ProtoField.uint16("protoRGERP.ringId", "Ring ID")
f.ringState = ProtoField.uint16("protoRGERP.ringState", "Ring State")
f.ringMaster = ProtoField.ether("protoRGERP.ringMaster","Ring Master")

f.portState = ProtoField.uint16("protoRGERP.portState", "Port State")
f.portId = ProtoField.uint16("protoRGERP.portId", "Port ID")
f.packetSender = ProtoField.ether("protoRGERP.packetSender","Packet Sender")

local packet_counter
function protoRGERP.init()
    packet_counter = 0
end

function protoRGERP.dissector(buffer, pinfo, tree)
    local subtree = tree:add(protoRGERP, buffer())

    --tree additions
    local packetType
    if string.sub(tostring(pinfo.cols.src),-1)=='2' then
        packetType="LINK_CHANGE_DOWN"
    elseif string.sub(tostring(pinfo.cols.dst),-1)=='3' then
        packetType="LINK_CHANGE_UP"
    else
        packetType="WATCHDOG"
    end
    subtree:add(f.packetType, packetType)

    local offset=0
    if packetType=="WATCHDOG" then
        local ringId = buffer(offset,1)
        subtree:add (f.ringId, ringId)
        offset=offset+1

        local ringState = buffer(offset,1)
        subtree:add(f.ringState, ringState)
        offset=offset+1

        local ringMaster = buffer(offset,6)
        subtree:add(f.ringMaster, ringMaster)
        offset=offset+6

        -- modify columns; replace LLC with custom
        pinfo.cols['protocol'] = "RGERP"
        pinfo.cols.info = "Ring ID: "
        pinfo.cols.info:append(ringId:uint())
        pinfo.cols.info:append(", ring status: ")
        pinfo.cols.info:append(vs_ringState[ringState:uint()])
        pinfo.cols.info:append(", packet type: "..packetType)
    else
        --linkchange
        local portState = buffer(offset,1)
        subtree:add (f.portState, portState)
        offset = offset+1

        local portId = buffer(offset,1)
        subtree:add (f.portId, portId)
        offset = offset+1

        local packetSender = buffer(offset,6)
        subtree:add (f.packetSender, packetSender)
        offset = offset+1

        local ringId = buffer(offset,1)
        subtree:add (f.ringId, ringId)
        offset=offset+1

        pinfo.cols['protocol'] = "RGERP"
        pinfo.cols.info = "Ring ID: "
        pinfo.cols.info:append(ringId:uint())
        pinfo.cols.info:append(", port ID: "..portId:uint().." is ")
        pinfo.cols.info:append(vs_portState[portState:uint()])
        pinfo.cols.info:append(", packet type: "..packetType)        
    end
end

local llc_table = DissectorTable.get("llc.dsap")
llc_table:add(0x6b, protoRGERP)
permanent link

answered 05 Apr '17, 02:13

nikdubois's gravatar image

nikdubois
6115
accept rate: 100%

edited 05 Apr '17, 02:15

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:

×637
×87
×16

question asked: 04 Apr '17, 08:10

question was seen: 1,290 times

last updated: 05 Apr '17, 02:15

p​o​w​e​r​e​d by O​S​Q​A