|
| 1 | +--[[ |
| 2 | +-- |
| 3 | +-- Dissector for Radio Link Simulation Protocol version 3.1.x |
| 4 | +-- (UERANSIM project <https://github.com/aligungr/UERANSIM>). |
| 5 | +-- |
| 6 | +-- CC0-1.0 2021 - Louis Royer (<https://github.com/louisroyer/RLS-wireshark-dissector>) |
| 7 | +-- |
| 8 | +--]] |
| 9 | +require("rls") |
| 10 | + |
| 11 | +local rlsProtocol31 = Proto("RLS-3.1", "UERANSIM 3.1.x Radio Link Simulation (RLS) Protocol") |
| 12 | +local fields = rlsProtocol31.fields |
| 13 | + |
| 14 | +local msgTypeNames = { |
| 15 | + [0] = "[Reserved]", |
| 16 | + [1] = "Cell Info Request", |
| 17 | + [2] = "Cell Info Response", |
| 18 | + [3] = "PDU Delivery", |
| 19 | +} |
| 20 | + |
| 21 | +local pduTypeNames = { |
| 22 | + [0] = "[Reserved]", |
| 23 | + [1] = "RRC", |
| 24 | + [2] = "Data" |
| 25 | +} |
| 26 | + |
| 27 | +local rrcMsgTypeNames = { |
| 28 | + [0] = "BCCH-BCH", |
| 29 | + [1] = "BCCH-DL-SCH", |
| 30 | + [2] = "DL-CCCH", |
| 31 | + [3] = "DL-DCCH", |
| 32 | + [4] = "PCCH", |
| 33 | + [5] = "UL-CCCH", |
| 34 | + [6] = "UL-CCCH1", |
| 35 | + [7] = "UL-DCCH", |
| 36 | +} |
| 37 | + |
| 38 | +local nrRrcDissectors = { |
| 39 | + [0] = "nr-rrc.bcch.bch", |
| 40 | + [1] = "nr-rrc.bcch.dl.sch", |
| 41 | + [2] = "nr-rrc.dl.ccch", |
| 42 | + [3] = "nr-rrc.dl.dcch", |
| 43 | + [4] = "nr-rrc.pcch", |
| 44 | + [5] = "nr-rrc.ul.ccch", |
| 45 | + [6] = "nr-rrc.ul.ccch1", |
| 46 | + [7] = "nr-rrc.ul.dcch", |
| 47 | +} |
| 48 | + |
| 49 | +fields.Version = ProtoField.string("rls.version", "Version") |
| 50 | +fields.MsgType = ProtoField.uint8("rls.message_type", "Message Type", base.DEC, msgTypeNames) |
| 51 | +fields.Sti = ProtoField.uint64("rls.sti", "Sender Node Temporary ID", base.DEC) |
| 52 | +fields.PduType = ProtoField.uint8("rls.pdu_type", "PDU Type", base.DEC, pduTypeNames) |
| 53 | +fields.RrcMsgType = ProtoField.uint32("rls.rrc_message_type", "RRC Message Type", base.DEC, rrcMsgTypeNames) |
| 54 | +fields.PduLength = ProtoField.uint32("rls.pdu_length", "PDU Length", base.DEC) |
| 55 | +fields.PduSessionId = ProtoField.uint32("rls.pdu_session_id", "PDU Session ID", base.DEC) |
| 56 | +fields.Dbm = ProtoField.int32("rls.dbm", "RLS Signal Strength (dBm)", base.DEC) |
| 57 | +fields.PosX = ProtoField.uint32("rls.pos_x", "RLS Position X", base.DEC) |
| 58 | +fields.PosY = ProtoField.uint32("rls.pos_y", "RLS Position Y", base.DEC) |
| 59 | +fields.PosZ = ProtoField.uint32("rls.pos_z", "RLS Position Z", base.DEC) |
| 60 | +fields.Mcc = ProtoField.uint16("rls.mcc", "MCC", base.DEC) |
| 61 | +fields.Mnc = ProtoField.uint16("rls.mnc", "MNC", base.DEC) |
| 62 | +fields.LongMnc = ProtoField.bool("rls.long_mnc", "MNC is 3-digit", base.BOOL) |
| 63 | +fields.Nci = ProtoField.uint64("rls.nci", "NR Cell Identity", base.HEX) |
| 64 | +fields.Tac = ProtoField.uint32("rls.tac", "Tracking Area Code", base.DEC) |
| 65 | +fields.GnbName = ProtoField.string("rls.gnb_name", "gNB Name") |
| 66 | +fields.LinkIp = ProtoField.string("rls.link_ip", "gNB Link IP") |
| 67 | + |
| 68 | +function rlsProtocol31.dissector(buffer, pinfo, tree) |
| 69 | + if buffer:len() == 0 then return false end |
| 70 | + if buffer(0, 1):uint() ~= 0x03 then return false end |
| 71 | + if buffer(1, 2):uint() > 0x0301 then return false end |
| 72 | + |
| 73 | + pinfo.cols.protocol = rlsProtocol31.name |
| 74 | + |
| 75 | + local versionNumber = buffer(1, 1):uint() .. "." .. buffer(2, 1):uint() .. "." .. buffer(3, 1):uint() |
| 76 | + local subtree = tree:add(rlsProtocol31, buffer(), "UERANSIM Radio Link Simulation (RLS) protocol") |
| 77 | + |
| 78 | + subtree:add(fields.Version, buffer(1, 3), versionNumber) |
| 79 | + subtree:add(fields.MsgType, buffer(4, 1)) |
| 80 | + local msgType = buffer(4, 1):uint() |
| 81 | + |
| 82 | + pinfo.cols.info = msgTypeNames[msgType] |
| 83 | + subtree:add(fields.Sti, buffer(5, 8)) |
| 84 | + |
| 85 | + if msgType == 1 then -- Cell Info Request |
| 86 | + subtree:add(fields.PosX, buffer(13,4)) |
| 87 | + subtree:add(fields.PosY, buffer(17,4)) |
| 88 | + subtree:add(fields.PosZ, buffer(21,4)) |
| 89 | + elseif msgType == 2 then -- Cell Info Response |
| 90 | + subtree:add(fields.Mcc, buffer(13,2)) |
| 91 | + local mnc_tree = subtree:add(rlsProtocol31, buffer(15,3), "MNC: "..tostring(buffer(15,2):uint())) |
| 92 | + mnc_tree:add(fields.Mnc, buffer(15,2)) |
| 93 | + mnc_tree:add(fields.LongMnc, buffer(17,1)) |
| 94 | + subtree:add(fields.Nci, buffer(18,8)) |
| 95 | + subtree:add(fields.Tac, buffer(26,4)) |
| 96 | + subtree:add(fields.Dbm, buffer(30,4)) |
| 97 | + local gnbNameLength = buffer(34,4):uint() |
| 98 | + subtree:add(fields.GnbName, buffer(38,gnbNameLength)) |
| 99 | + local linkIpLength = buffer(38+gnbNameLength,4):uint() |
| 100 | + subtree:add(fields.LinkIp, buffer(42+gnbNameLength,linkIpLength)) |
| 101 | + elseif msgType == 3 then -- PDU Delivery |
| 102 | + subtree:add(fields.PduType, buffer(13,1)) |
| 103 | + local pduType = buffer(13,1):uint() |
| 104 | + local pduLength = buffer(14,4):uint() |
| 105 | + local payloadLength = buffer(18+pduLength,4):uint() |
| 106 | + if pduType == 1 then -- RRC |
| 107 | + local rrcMsgType = buffer(22+pduLength,payloadLength):uint() |
| 108 | + subtree:add(fields.RrcMsgType, buffer(22+pduLength,payloadLength)) |
| 109 | + subtree:add(fields.PduLength, buffer(14,4)) |
| 110 | + -- Old versions of Wireshark (< 3.0.0) cannot handle NR-RRC correctly |
| 111 | + local dissector |
| 112 | + local function get_dissector() |
| 113 | + dissector = Dissector.get(nrRrcDissectors[rrcMsgType]) |
| 114 | + end |
| 115 | + if pcall(get_dissector) then |
| 116 | + dissector:call(buffer(18, pduLength):tvb(), pinfo, tree) |
| 117 | + else |
| 118 | + pinfo.cols.info = msgTypeNames[msgType] |
| 119 | + .. " - " .. rrcMsgTypeNames[rrcMsgType] |
| 120 | + .. " - Cannot decode" |
| 121 | + return false |
| 122 | + end |
| 123 | + elseif pduType == 2 then -- DATA |
| 124 | + subtree:add(fields.PduSessionId, buffer(22+pduLength,payloadLength)) |
| 125 | + subtree:add(fields.PduLength, buffer(14,4)) |
| 126 | + Dissector.get("ip"):call(buffer(18,pduLength):tvb(), pinfo, tree) |
| 127 | + end |
| 128 | + end |
| 129 | +end |
| 130 | + |
| 131 | +local rls = DissectorTable.get("rls") |
| 132 | +rls:add(0x0301, rlsProtocol31) |
| 133 | +local udp_port = DissectorTable.get("udp.port") |
| 134 | +udp_port:add_for_decode_as(rlsProtocol31) |
0 commit comments