Commit 2dbbcd59 authored by aligungr's avatar aligungr

L3 RRC/NAS developments

parent 2342f910
--[[
--
-- Dissector for Radio Link Simulation Protocol
-- (used by UERANSIM <https://github.com/aligungr/UERANSIM>).
-- (UERANSIM project <https://github.com/aligungr/UERANSIM>).
--
-- CC0-1.0 2021 - Louis Royer (<https://github.com/louisroyer/RLS-wireshark-dissector>)
--
--]]
--[[
-- ProtoFields
--]]
local rls_protocol = Proto("RLS", "Radio Link Simulation Protocol")
local version_major = ProtoField.uint8("rls.version_major", "RLS Version Major", base.DEC)
local version_minor = ProtoField.uint8("rls.version_minor", "RLS Version Minor", base.DEC)
local version_patch = ProtoField.uint8("rls.version_patch", "RLS Version Patch", base.DEC)
local rlsProtocol = Proto("RLS", "UERANSIM Radio Link Simulation (RLS) Protocol")
local fields = rlsProtocol.fields
local message_type_name = {
[0] = "Reserved",
[1] = "Cell Info Request",
[2] = "Cell Info Response",
[3] = "PDU Delivery"
local msgTypeNames = {
[0] = "[Reserved]",
[1] = "[Reserved]",
[2] = "[Reserved]",
[3] = "[Reserved]",
[4] = "Heartbeat",
[5] = "Heartbeat ACK",
[6] = "PDU Transmission",
[7] = "PDU Transmission ACK",
}
local message_type = ProtoField.uint8("rls.message_type", "RLS Message Type", base.DEC, message_type_name)
local sti = ProtoField.uint64("rls.sti", "RLS Temporary Identifier", base.HEX)
-- For cell Info Request
local sim_pos_x = ProtoField.uint32("rls.sim_pos_x", "RLS Position X", base.DEC)
local sim_pos_y = ProtoField.uint32("rls.sim_pos_y", "RLS Position Y", base.DEC)
local sim_pos_z = ProtoField.uint32("rls.sim_pos_z", "RLS Position Z", base.DEC)
local pduTypeNames = {
[0] = "[Reserved]",
[1] = "RRC",
[2] = "Data"
}
-- For cell Info Response
local mcc = ProtoField.uint16("rls.mcc", "MCC", base.DEC)
local mnc = ProtoField.uint16("rls.mnc", "MNC", base.DEC)
local long_mnc = ProtoField.bool("rls.long_mnc", "MNC is 3-digit", base.BOOL)
local nci = ProtoField.uint64("rls.nci", "NR Cell Identity", base.HEX)
local tac = ProtoField.uint32("rls.tac", "Tracking Area Code", base.DEC)
local dbm = ProtoField.int32("rls.dbm", "RLS Signal Strength (dBm)", base.DEC)
local gnb_name = ProtoField.string("rls.gnb_name", "gNB Name")
local link_ip = ProtoField.string("rls.link_ip", "gNB Link IP")
local rrcMsgTypeNames = {
[0] = "BCCH-BCH",
[1] = "BCCH-DL-SCH",
[2] = "DL-CCCH",
[3] = "DL-DCCH",
[4] = "PCCH",
[5] = "UL-CCCH",
[6] = "UL-CCCH1",
[7] = "UL-DCCH",
}
-- For PDU Delivery
local pdu_type_name = {
[0] = "Reserved",
[1] = "RRC",
[2] = "Data"
local nrRrcDissectors = {
[0] = "nr-rrc.bcch.bch",
[1] = "nr-rrc.bcch.dl.sch",
[2] = "nr-rrc.dl.ccch",
[3] = "nr-rrc.dl.dcch",
[4] = "nr-rrc.pcch",
[5] = "nr-rrc.ul.ccch",
[6] = "nr-rrc.ul.ccch1",
[7] = "nr-rrc.ul.dcch",
}
local pdu_type = ProtoField.uint8("rls.pdu_type", "RLS PDU Type", base.DEC, pdu_type_name)
fields.Version = ProtoField.string("rls.version", "Version")
fields.MsgType = ProtoField.uint8("rls.message_type", "Message Type", base.DEC, msgTypeNames)
fields.Sti = ProtoField.uint64("rls.sti", "Sender Node Temporary ID", base.DEC)
fields.PduType = ProtoField.uint8("rls.pdu_type", "PDU Type", base.DEC, pduTypeNames)
fields.PduId = ProtoField.uint32("rls.pdu_id", "PDU ID", base.DEC)
fields.RrcMsgType = ProtoField.uint32("rls.rrc_message_type", "RRC Message Type", base.DEC, rrcMsgTypeNames)
fields.PduLength = ProtoField.uint32("rls.pdu_length", "PDU Length", base.DEC)
fields.PduSessionId = ProtoField.uint32("rls.pdu_session_id", "PDU Session ID", base.DEC)
fields.AcknowledgeItem = ProtoField.uint32("rls.ack_item", "PDU ID")
fields.Dbm = ProtoField.int32("rls.dbm", "RLS Signal Strength (dBm)", base.DEC)
fields.PosX = ProtoField.uint32("rls.pos_x", "RLS Position X", base.DEC)
fields.PosY = ProtoField.uint32("rls.pos_y", "RLS Position Y", base.DEC)
fields.PosZ = ProtoField.uint32("rls.pos_z", "RLS Position Z", base.DEC)
local rrc_channel_name = {
[0] = "BCCH-BCH",
[1] = "BCCH-DL-SCH",
[2] = "DL-CCCH",
[3] = "DL-DCCH",
[4] = "PCCH",
[5] = "UL-CCCH",
[6] = "UL-CCCH1",
[7] = "UL-DCCH",
}
function rlsProtocol.dissector(buffer, pinfo, tree)
if buffer:len() == 0 then return end
if buffer(0, 1):uint() ~= 0x03 then return end
local rrc_channel_dissector = {
[0] = "nr-rrc.bcch.bch",
[1] = "nr-rrc.bcch.dl.sch",
[2] = "nr-rrc.dl.ccch",
[3] = "nr-rrc.dl.dcch",
[4] = "nr-rrc.pcch",
[5] = "nr-rrc.ul.ccch",
[6] = "nr-rrc.ul.ccch1",
[7] = "nr-rrc.ul.dcch",
}
pinfo.cols.protocol = rlsProtocol.name
local rrc_channel = ProtoField.uint32("rls.rrc_channel", "RRC Channel", base.DEC, rrc_channel_name)
local session_id = ProtoField.uint32("rls.session_id", "PDU Session ID", base.DEC)
local versionNumber = buffer(1, 1):uint() .. "." .. buffer(2, 1):uint() .. "." .. buffer(3, 1):uint()
local subtree = tree:add(rlsProtocol, buffer(), "UERANSIM Radio Link Simulation (RLS) protocol")
--[[
-- Dissector definition
--]]
rls_protocol.fields = {
version_major, version_minor, version_patch, message_type, sti,
sim_pos_x, sim_pos_y, sim_pos_z,
mcc, mnc, long_mnc, nci, tac, dbm, gnb_name, link_ip,
pdu_type, rrc_channel, session_id,
}
subtree:add(fields.Version, buffer(1, 3), versionNumber)
subtree:add(fields.MsgType, buffer(4, 1))
local msgType = buffer(4, 1):uint()
function rls_protocol.dissector(buffer, pinfo, tree)
local length = buffer:len()
if length == 0 then return end
if buffer(0,1):uint() ~= 0x03 then return end
pinfo.cols.info = msgTypeNames[msgType]
subtree:add(fields.Sti, buffer(5, 8))
pinfo.cols.protocol = rls_protocol.name
local version_number = buffer(1,1):uint().."."
..buffer(2,1):uint().."."
..buffer(3,1):uint()
local subtree = tree:add(rls_protocol, buffer(), "RLS Protocol Version "..version_number)
local version = subtree:add(rls_protocol, buffer(2,3), "Version: "..version_number)
version:add(version_major, buffer(1,1))
version:add(version_minor, buffer(2,1))
version:add(version_patch, buffer(3,1))
subtree:add(message_type, buffer(4,1))
local msg_type = buffer(4,1):uint()
if msg_type <=0 or msg_type > 3 then return end
pinfo.cols.info = message_type_name[msg_type]
subtree:append_text(" - "..message_type_name[msg_type])
subtree:add(sti, buffer(5,8))
if msg_type == 1 then -- Cell Info Request
subtree:add(sim_pos_x, buffer(13,4))
subtree:add(sim_pos_y, buffer(17,4))
subtree:add(sim_pos_z, buffer(21,4))
elseif msg_type == 2 then -- Cell Info Response
subtree:add(mcc, buffer(13,2))
local mnc_tree = subtree:add(rls_protocol, buffer(15,3), "MNC: "..tostring(buffer(15,2):uint()))
mnc_tree:add(mnc, buffer(15,2))
mnc_tree:add(long_mnc, buffer(17,1))
subtree:add(nci, buffer(18,8))
subtree:add(tac, buffer(26,4))
subtree:add(dbm, buffer(30,4))
local gnb_name_len = buffer(34,4):uint()
subtree:add(gnb_name, buffer(38,gnb_name_len))
local link_ip_size = buffer(38+gnb_name_len,4):uint()
subtree:add(link_ip, buffer(42+gnb_name_len,link_ip_size))
elseif msg_type == 3 then -- PDU Delivery
subtree:add(pdu_type, buffer(13,1))
local pdu_type_value = buffer(13,1):uint()
local pdu_len = buffer(14,4):uint()
local payload_len = buffer(18+pdu_len,4):uint()
if pdu_type_value == 1 then -- RRC
subtree:add(rrc_channel, buffer(22+pdu_len,payload_len))
local channel = buffer(22+pdu_len,payload_len):uint()
Dissector.get(rrc_channel_dissector[channel]):call(buffer(18,pdu_len):tvb(), pinfo, tree)
elseif pdu_type_value == 2 then -- DATA
subtree:add(session_id, buffer(22+pdu_len,payload_len))
Dissector.get("ip"):call(buffer(18,pdu_len):tvb(), pinfo, tree)
end
end
if msgType == 4 then -- Heartbeat
subtree:add(fields.PosX, buffer(13,4))
subtree:add(fields.PosY, buffer(17,4))
subtree:add(fields.PosZ, buffer(21,4))
elseif msgType == 5 then -- Heartbeat ACK
subtree:add(fields.Dbm, buffer(13,4))
elseif msgType == 6 then -- PDU Transmission
local pduType = buffer(13, 1):uint()
subtree:add(fields.PduType, buffer(13, 1))
subtree:add(fields.PduId, buffer(14, 4))
if pduType == 1 then -- RRC PDU
local rrcMsgType = buffer(18, 4):uint()
local pduLength = buffer(22, 4):uint()
subtree:add(fields.RrcMsgType, buffer(18, 4))
subtree:add(fields.PduLength, buffer(22, 4))
Dissector.get(nrRrcDissectors[rrcMsgType]):call(buffer(26, pduLength):tvb(), pinfo, tree)
elseif (pduType == 2) then -- Data PDU
subtree:add(fields.PduSessionId, buffer(18, 4))
local pduLength = buffer(22, 4):uint()
subtree:add(fields.PduLength, buffer(22, 4))
Dissector.get("ip"):call(buffer(26, pduLength):tvb(), pinfo, tree)
end
elseif msgType == 7 then -- PDU Transmission ACK
local ackCount = buffer(13, 4):uint()
local ackArray = subtree:add(rlsProtocol, buffer(13, 4), "Acknowledge List (" .. ackCount .. ")")
for i = 1,ackCount,1 do
ackArray:add(fields.AcknowledgeItem, buffer(17 + (i - 1) * 4, 4))
end
end
end
local udp_port = DissectorTable.get("udp.port")
udp_port:add(4997, rls_protocol)
udp_port:add(4997, rlsProtocol)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment