Loading dissect/prrt.lua 0 → 100644 +201 −0 Original line number Diff line number Diff line -- For an excellent example script, see -- https://wiki.wireshark.org/Lua/Examples?action=AttachFile&do=get&target=dissector.lua -- declare our protocol local prrt_proto = Proto("prrt","Predictably Reliable Real-time Transport") local prrtPacketTypeNames = { [0] = "Data", [1] = "Repetition", [2] = "Redundancy", [3] = "Feedback", [4] = "Pre-sent Redundancy", [5] = "Channel Feedback" } -- create the fields local pf_type = ProtoField.uint8("prrt.type", "Type", base.DEC, prrtPacketTypeNames, 240) local pf_prio = ProtoField.uint8("prrt.priority", "Priority", base.DEC, nil, 15) local pf_idx = ProtoField.uint8("prrt.index", "Index") local pf_seqN = ProtoField.uint16("prrt.sequenceNumber", "Sequence Number") local pf_data = ProtoField.new("Data", "prrt.data", ftypes.BYTES, base.NONE) local pf_data_length = ProtoField.uint32("prrt.data.length", "Length") local pf_data_timestamp = ProtoField.uint32("prrt.data.timestamp", "Timestamp") local pf_data_groupRTprop = ProtoField.uint32("prrt.data.grouprtprop", "Group RTprop") local pf_data_packettimeout = ProtoField.uint32("prrt.data.packettimeout", "Packet Timeout") local pf_red = ProtoField.new("Redundancy", "prrt.redundancy", ftypes.BYTES, base.NONE) local pf_red_baseSeqN = ProtoField.uint16("prrt.redundancy.baseSequenceNumber", "Base Sequence Number", base.DEC) local pf_red_timestamp = ProtoField.uint32("prrt.redundancy.timestamp", "Timestamp") local pf_red_n = ProtoField.uint8("prrt.redundancy.n", "n") local pf_red_k = ProtoField.uint8("prrt.redundancy.k", "k") local pf_fb = ProtoField.new("Feedback", "prrt.feedback", ftypes.BYTES, base.NONE) local pf_fb_groupRTT = ProtoField.uint32("prrt.feedback.groupRTT", "Group RTT") local pf_fb_ftt = ProtoField.uint32("prrt.feedback.FTT", "FTT") local pf_fb_erasurecount = ProtoField.uint16("prrt.feedback.erasureCount", "Erasure count") local pf_fb_packetcount = ProtoField.uint16("prrt.feedback.packetCount", "Packet count") local pf_fb_gaplength = ProtoField.uint16("prrt.feedback.gapLength", "Gap length") local pf_fb_gapcount = ProtoField.uint16("prrt.feedback.gapCount", "Gap count") local pf_fb_burstlength = ProtoField.uint16("prrt.feedback.burstLength", "Burst length") local pf_fb_burstcount = ProtoField.uint16("prrt.feedback.burstCount", "Burst count") local pf_fb_acktype = ProtoField.uint8("prrt.feedback.ackPacketType", "Ack Packet Type", base.DEC, prrtPacketTypeNames) local pf_fb_ackSeqN = ProtoField.uint16("prrt.feedback.ackSequenceNumber", "Ack Sequence Number") -- add the fields to the protocol prrt_proto.fields = { pf_type, pf_prio, pf_idx, pf_seqN, pf_data, pf_data_length, pf_data_timestamp, pf_data_groupRTprop, pf_data_packettimeout, pf_red, pf_red_baseSeqN, pf_red_timestamp, pf_red_n, pf_red_k, pf_fb, pf_fb_groupRTT, pf_fb_ftt, pf_fb_erasurecount, pf_fb_packetcount, pf_fb_gaplength, pf_fb_gapcount, pf_fb_burstlength, pf_fb_burstcount, pf_fb_acktype, pf_fb_ackSeqN, } -- create expert info fields local ef_too_short = ProtoExpert.new("prrt.too_short.expert", "PRRT Packet too short", expert.group.MALFORMED, expert.severity.ERROR) prrt_proto.experts = { ef_too_short } -- Create extractor fields (for some reason this can't be done with the fields that already exist) local ex_type = Field.new("prrt.type") local function getType() return ex_type()() end local function getTypeName() return prrtPacketTypeNames[getType()] end local ex_data_length = Field.new("prrt.data.length") local function getDataLength() return ex_data_length()() end local ex_red_n = Field.new("prrt.redundancy.n") local function getRedN() return ex_red_n()() end local ex_red_k = Field.new("prrt.redundancy.k") local function getRedK() return ex_red_k()() end -- some constants local PRRT_MIN_SIZE = 8 -- create sub-dissectors for different types local function dissect_data(buffer, pinfo, root) local tree = root:add(pf_data, buffer:range(0)) tree:add(pf_data_length, buffer:range(0,4)) tree:add(pf_data_timestamp, buffer:range(4,4)) tree:add(pf_data_groupRTprop, buffer:range(8,4)) tree:add(pf_data_packettimeout, buffer:range(12,4)) local label = "DATA Len=" .. getDataLength() tree:set_text(label) pinfo.cols.info:set(label) end local function dissect_redundancy(buffer, pinfo, root) local tree = root:add(pf_red, buffer:range(0)) tree:add(pf_red_baseSeqN, buffer:range(0,2)) tree:add(pf_red_timestamp, buffer:range(2,4)) tree:add(pf_red_n, buffer:range(6,1)) tree:add(pf_red_k, buffer:range(7,1)) local label = "REDUNDANCY n=" .. getRedN() .. " k=" .. getRedK() tree:set_text(label) pinfo.cols.info:set(label) end local function dissect_feedback(buffer, pinfo, root) local tree = root:add(pf_fb, buffer:range(0)) tree:add(pf_fb_groupRTT, buffer:range(0,4)) tree:add(pf_fb_ftt, buffer:range(4,4)) tree:add(pf_fb_erasurecount, buffer:range(8,2)) tree:add(pf_fb_packetcount, buffer:range(10,2)) tree:add(pf_fb_gaplength, buffer:range(12,2)) tree:add(pf_fb_gapcount, buffer:range(14,2)) tree:add(pf_fb_burstlength, buffer:range(16,2)) tree:add(pf_fb_burstcount, buffer:range(18,2)) tree:add(pf_fb_acktype, buffer:range(20,1)) tree:add(pf_fb_ackSeqN, buffer:range(21, 2)) local label = "FEEDBACK" tree:set_text(label) pinfo.cols.info:set(label) end local subdissectors = { [0] = dissect_data, [2] = dissect_redundancy, [3] = dissect_feedback } -- create a function to dissect each frame function prrt_proto.dissector(buffer,pinfo,root) -- set the protocol column pinfo.cols.protocol:set("PRRT") local pktlen = buffer:reported_length_remaining() --[[ TODO parse whether the packet has a payload first if it has, do not use the entire buffer:range(0) in the tree label, but only up to the payload and add another "Data" subtree containing only the payload --]] local tree = root:add(prrt_proto, buffer:range(0)) if pktlen < PRRT_MIN_SIZE then tree:add_proto_expert_info(ef_too_short) return end tree:add(pf_type, buffer:range(0,1)) tree:add(pf_prio, buffer:range(0,1)) tree:add(pf_idx, buffer:range(1,1)) tree:add(pf_seqN, buffer:range(2,2)) if subdissectors[getType()] then subdissectors[getType()](buffer:range(4,nil):tvb(), pinfo, tree) end end local current_port = 6000 DissectorTable.get("udp.port"):add(current_port, prrt_proto) prrt_proto.prefs.port = Pref.uint("Port number", current_port, "The UDP Port number for PRRT") function prrt_proto.prefs_changed() if current_port ~= prrt_proto.prefs.port then if curent_port ~= 0 then DissectorTable.get("udp.port"):remove(current_port, prrt_proto) end current_port = prrt_proto.prefs.port if current_port ~= 0 then DissectorTable.get("udp.port"):add(current_port, prrt_proto) end end end prrt/proto/types/packet.c +1 −1 Original line number Diff line number Diff line Loading @@ -199,7 +199,7 @@ void *encode_data_header(void *buf_ptr, const void *payload) { PrrtPacketField_encode(data_payload, buf_ptr, prrtPacketLength_t, dataLength, htonl); PrrtPacketField_encode(data_payload, buf_ptr, prrtTimestamp_t, timestamp, htonl); PrrtPacketField_encode(data_payload, buf_ptr, prrtTimedelta_t, groupRTprop_us, htonl); PrrtPacketField_encode(data_payload, buf_ptr, prrtTimedelta_t, packetTimeout_us, htonl); PrrtPacketField_encode(data_payload, buf_ptr, prrtTimestamp_t, packetTimeout_us, htonl); prrtDeliveryRate_t *deliveryRate = (prrtDeliveryRate_t *) buf_ptr; *deliveryRate = htonl(data_payload->btlbw); Loading prrt/proto/types/packet.h +3 −3 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ typedef struct prrtPacketDataPayload { prrtTimedelta_t groupRTprop_us; prrtTimestamp_t packetTimeout_us; prrtDeliveryRate_t btlbw; } PrrtPacketDataPayload; } __attribute__((packed)) PrrtPacketDataPayload; #define PRRT_PACKET_DATA_HEADER_SIZE (\ sizeof(prrtPacketLength_t) + \ Loading @@ -74,7 +74,7 @@ typedef struct prrtPacketRedundancyPayload { prrtTimestamp_t timestamp; uint8_t n; uint8_t k; } PrrtPacketRedundancyPayload; } __attribute__((packed)) PrrtPacketRedundancyPayload; #define PRRT_PACKET_REDUNDANCY_HEADER_SIZE (\ sizeof(prrtSequenceNumber_t) + \ Loading @@ -94,7 +94,7 @@ typedef struct prrtPacketFeedbackPayload { prrtSequenceNumber_t ackSequenceNumber; prrtPacketType_t ackPacketType; PrrtIncompleteBlock *incompleteBlocks; } PrrtPacketFeedbackPayload; } __attribute__((packed)) PrrtPacketFeedbackPayload; #define PRRT_PACKET_FEEDBACK_HEADER_SIZE (\ sizeof(prrtTimedelta_t) + \ Loading Loading
dissect/prrt.lua 0 → 100644 +201 −0 Original line number Diff line number Diff line -- For an excellent example script, see -- https://wiki.wireshark.org/Lua/Examples?action=AttachFile&do=get&target=dissector.lua -- declare our protocol local prrt_proto = Proto("prrt","Predictably Reliable Real-time Transport") local prrtPacketTypeNames = { [0] = "Data", [1] = "Repetition", [2] = "Redundancy", [3] = "Feedback", [4] = "Pre-sent Redundancy", [5] = "Channel Feedback" } -- create the fields local pf_type = ProtoField.uint8("prrt.type", "Type", base.DEC, prrtPacketTypeNames, 240) local pf_prio = ProtoField.uint8("prrt.priority", "Priority", base.DEC, nil, 15) local pf_idx = ProtoField.uint8("prrt.index", "Index") local pf_seqN = ProtoField.uint16("prrt.sequenceNumber", "Sequence Number") local pf_data = ProtoField.new("Data", "prrt.data", ftypes.BYTES, base.NONE) local pf_data_length = ProtoField.uint32("prrt.data.length", "Length") local pf_data_timestamp = ProtoField.uint32("prrt.data.timestamp", "Timestamp") local pf_data_groupRTprop = ProtoField.uint32("prrt.data.grouprtprop", "Group RTprop") local pf_data_packettimeout = ProtoField.uint32("prrt.data.packettimeout", "Packet Timeout") local pf_red = ProtoField.new("Redundancy", "prrt.redundancy", ftypes.BYTES, base.NONE) local pf_red_baseSeqN = ProtoField.uint16("prrt.redundancy.baseSequenceNumber", "Base Sequence Number", base.DEC) local pf_red_timestamp = ProtoField.uint32("prrt.redundancy.timestamp", "Timestamp") local pf_red_n = ProtoField.uint8("prrt.redundancy.n", "n") local pf_red_k = ProtoField.uint8("prrt.redundancy.k", "k") local pf_fb = ProtoField.new("Feedback", "prrt.feedback", ftypes.BYTES, base.NONE) local pf_fb_groupRTT = ProtoField.uint32("prrt.feedback.groupRTT", "Group RTT") local pf_fb_ftt = ProtoField.uint32("prrt.feedback.FTT", "FTT") local pf_fb_erasurecount = ProtoField.uint16("prrt.feedback.erasureCount", "Erasure count") local pf_fb_packetcount = ProtoField.uint16("prrt.feedback.packetCount", "Packet count") local pf_fb_gaplength = ProtoField.uint16("prrt.feedback.gapLength", "Gap length") local pf_fb_gapcount = ProtoField.uint16("prrt.feedback.gapCount", "Gap count") local pf_fb_burstlength = ProtoField.uint16("prrt.feedback.burstLength", "Burst length") local pf_fb_burstcount = ProtoField.uint16("prrt.feedback.burstCount", "Burst count") local pf_fb_acktype = ProtoField.uint8("prrt.feedback.ackPacketType", "Ack Packet Type", base.DEC, prrtPacketTypeNames) local pf_fb_ackSeqN = ProtoField.uint16("prrt.feedback.ackSequenceNumber", "Ack Sequence Number") -- add the fields to the protocol prrt_proto.fields = { pf_type, pf_prio, pf_idx, pf_seqN, pf_data, pf_data_length, pf_data_timestamp, pf_data_groupRTprop, pf_data_packettimeout, pf_red, pf_red_baseSeqN, pf_red_timestamp, pf_red_n, pf_red_k, pf_fb, pf_fb_groupRTT, pf_fb_ftt, pf_fb_erasurecount, pf_fb_packetcount, pf_fb_gaplength, pf_fb_gapcount, pf_fb_burstlength, pf_fb_burstcount, pf_fb_acktype, pf_fb_ackSeqN, } -- create expert info fields local ef_too_short = ProtoExpert.new("prrt.too_short.expert", "PRRT Packet too short", expert.group.MALFORMED, expert.severity.ERROR) prrt_proto.experts = { ef_too_short } -- Create extractor fields (for some reason this can't be done with the fields that already exist) local ex_type = Field.new("prrt.type") local function getType() return ex_type()() end local function getTypeName() return prrtPacketTypeNames[getType()] end local ex_data_length = Field.new("prrt.data.length") local function getDataLength() return ex_data_length()() end local ex_red_n = Field.new("prrt.redundancy.n") local function getRedN() return ex_red_n()() end local ex_red_k = Field.new("prrt.redundancy.k") local function getRedK() return ex_red_k()() end -- some constants local PRRT_MIN_SIZE = 8 -- create sub-dissectors for different types local function dissect_data(buffer, pinfo, root) local tree = root:add(pf_data, buffer:range(0)) tree:add(pf_data_length, buffer:range(0,4)) tree:add(pf_data_timestamp, buffer:range(4,4)) tree:add(pf_data_groupRTprop, buffer:range(8,4)) tree:add(pf_data_packettimeout, buffer:range(12,4)) local label = "DATA Len=" .. getDataLength() tree:set_text(label) pinfo.cols.info:set(label) end local function dissect_redundancy(buffer, pinfo, root) local tree = root:add(pf_red, buffer:range(0)) tree:add(pf_red_baseSeqN, buffer:range(0,2)) tree:add(pf_red_timestamp, buffer:range(2,4)) tree:add(pf_red_n, buffer:range(6,1)) tree:add(pf_red_k, buffer:range(7,1)) local label = "REDUNDANCY n=" .. getRedN() .. " k=" .. getRedK() tree:set_text(label) pinfo.cols.info:set(label) end local function dissect_feedback(buffer, pinfo, root) local tree = root:add(pf_fb, buffer:range(0)) tree:add(pf_fb_groupRTT, buffer:range(0,4)) tree:add(pf_fb_ftt, buffer:range(4,4)) tree:add(pf_fb_erasurecount, buffer:range(8,2)) tree:add(pf_fb_packetcount, buffer:range(10,2)) tree:add(pf_fb_gaplength, buffer:range(12,2)) tree:add(pf_fb_gapcount, buffer:range(14,2)) tree:add(pf_fb_burstlength, buffer:range(16,2)) tree:add(pf_fb_burstcount, buffer:range(18,2)) tree:add(pf_fb_acktype, buffer:range(20,1)) tree:add(pf_fb_ackSeqN, buffer:range(21, 2)) local label = "FEEDBACK" tree:set_text(label) pinfo.cols.info:set(label) end local subdissectors = { [0] = dissect_data, [2] = dissect_redundancy, [3] = dissect_feedback } -- create a function to dissect each frame function prrt_proto.dissector(buffer,pinfo,root) -- set the protocol column pinfo.cols.protocol:set("PRRT") local pktlen = buffer:reported_length_remaining() --[[ TODO parse whether the packet has a payload first if it has, do not use the entire buffer:range(0) in the tree label, but only up to the payload and add another "Data" subtree containing only the payload --]] local tree = root:add(prrt_proto, buffer:range(0)) if pktlen < PRRT_MIN_SIZE then tree:add_proto_expert_info(ef_too_short) return end tree:add(pf_type, buffer:range(0,1)) tree:add(pf_prio, buffer:range(0,1)) tree:add(pf_idx, buffer:range(1,1)) tree:add(pf_seqN, buffer:range(2,2)) if subdissectors[getType()] then subdissectors[getType()](buffer:range(4,nil):tvb(), pinfo, tree) end end local current_port = 6000 DissectorTable.get("udp.port"):add(current_port, prrt_proto) prrt_proto.prefs.port = Pref.uint("Port number", current_port, "The UDP Port number for PRRT") function prrt_proto.prefs_changed() if current_port ~= prrt_proto.prefs.port then if curent_port ~= 0 then DissectorTable.get("udp.port"):remove(current_port, prrt_proto) end current_port = prrt_proto.prefs.port if current_port ~= 0 then DissectorTable.get("udp.port"):add(current_port, prrt_proto) end end end
prrt/proto/types/packet.c +1 −1 Original line number Diff line number Diff line Loading @@ -199,7 +199,7 @@ void *encode_data_header(void *buf_ptr, const void *payload) { PrrtPacketField_encode(data_payload, buf_ptr, prrtPacketLength_t, dataLength, htonl); PrrtPacketField_encode(data_payload, buf_ptr, prrtTimestamp_t, timestamp, htonl); PrrtPacketField_encode(data_payload, buf_ptr, prrtTimedelta_t, groupRTprop_us, htonl); PrrtPacketField_encode(data_payload, buf_ptr, prrtTimedelta_t, packetTimeout_us, htonl); PrrtPacketField_encode(data_payload, buf_ptr, prrtTimestamp_t, packetTimeout_us, htonl); prrtDeliveryRate_t *deliveryRate = (prrtDeliveryRate_t *) buf_ptr; *deliveryRate = htonl(data_payload->btlbw); Loading
prrt/proto/types/packet.h +3 −3 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ typedef struct prrtPacketDataPayload { prrtTimedelta_t groupRTprop_us; prrtTimestamp_t packetTimeout_us; prrtDeliveryRate_t btlbw; } PrrtPacketDataPayload; } __attribute__((packed)) PrrtPacketDataPayload; #define PRRT_PACKET_DATA_HEADER_SIZE (\ sizeof(prrtPacketLength_t) + \ Loading @@ -74,7 +74,7 @@ typedef struct prrtPacketRedundancyPayload { prrtTimestamp_t timestamp; uint8_t n; uint8_t k; } PrrtPacketRedundancyPayload; } __attribute__((packed)) PrrtPacketRedundancyPayload; #define PRRT_PACKET_REDUNDANCY_HEADER_SIZE (\ sizeof(prrtSequenceNumber_t) + \ Loading @@ -94,7 +94,7 @@ typedef struct prrtPacketFeedbackPayload { prrtSequenceNumber_t ackSequenceNumber; prrtPacketType_t ackPacketType; PrrtIncompleteBlock *incompleteBlocks; } PrrtPacketFeedbackPayload; } __attribute__((packed)) PrrtPacketFeedbackPayload; #define PRRT_PACKET_FEEDBACK_HEADER_SIZE (\ sizeof(prrtTimedelta_t) + \ Loading