Commit 535cf490 authored by Andreas Schmidt's avatar Andreas Schmidt
Browse files

Merge branch 'develop' into feature/congestionControl

parents 45693578 bdbe1ac2
Loading
Loading
Loading
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
+1 −1
Original line number Diff line number Diff line
@@ -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);
+3 −3
Original line number Diff line number Diff line
@@ -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) + \
@@ -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) + \
@@ -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) + \