You could use a Lua script to do it.
For example the script below will create a fake "rtpdup" protocol for RTP packets, and set a new field called "rtpdup.duplicate" to true if it's a duplicate. That way you can filter on that field's value in Wireshark.
So just copy paste the below code into a new file with a .lua
extension (e.g., "rtpdup.lua
"), and put it in your Wireshark personal plugins directory; and then start Wireshark, load up your capture file, and use the display filter "rtpdup.duplicate == true
", and voilà you'll only see duplicate RTP packets. This script uses the combination of IP ID field, RTP sequence number, and RTP SSRC field... all three must match for another packet to be considered a duplicate. (or you can reduce it by changing the Lua code... it's fairly straightforward)
-- our new Proto object
local rtpdup = Proto("rtpdup","RTP Duplicates Protocol")
– new fields for our "rtpdup" protocol
– the purpose for these is so they can be filtered upon
local pf_is_dup = ProtoField.bool("rtpdup.duplicate", "Duplicated")
local pf_dup_frame = ProtoField.framenum("rtpdup.frame", "DupFrame", base.NONE)
– register the ProtoFields above
rtpdup.fields = { pf_is_dup, pf_dup_frame }
– some existing fields we need to extract from RTP packets, to determine duplicates
– all 3 of these must be the same for us to consider two packets duplicates
local f_ip_id = Field.new("ip.id")
local f_rtp_seq = Field.new("rtp.seq")
local f_rtp_ssrc = Field.new("rtp.ssrc")
– the table we use to track seen packet #s and seen field info
– we'll use this as both an array and map table
– the array portion is indexed by packet number
– the map portion is keyed by "ip.id:rtp.seq:rtp.ssrc"
– the resultant for both is the same instance of a subtable with the
– packet numbers of the dups in an array list
local packets = {}
local function generateKey(…)
local t = { … }
return table.concat(t, ':')
end
– adds the packet's number to both the array and map
– which is done when we see a particular set of fields for the first time
local function addPacketList(pnum, key)
local list = { pnum }
packets[key] = list
packets[pnum] = list
end
– adds the packet to the array part, using an existing list of dups
– also adds the packet's number to the list of dups
local function addPacket(pnum, list)
– add this packet's number to the array portion of the big table
packets[pnum] = list
– add this packet's number to the list of dups
list[#list + 1] = pnum
end
– whenever a new capture file is opened, we want to reset our table
– so we hook into the init() routine to do that
function rtpdup.init()
packets = {}
end
– some forward "declarations" of helper functions we use in the dissector
local createProtoTree
– our dissector function
function rtpdup.dissector(tvb, pinfo, tree)
– first, check if this is an rtp packet, by seeing if it has a rtp.seq
local rtp_seq = select(1, f_rtp_seq())
if not rtp_seq then
-- not an RTP packet
return
end
local pnum = pinfo.number
-- see if we've already processed this packet number
local list = packets[pnum]
if not list then
-- haven't processed this packet
-- see if the fields match another packet we've seen before
local ip_id = select(1, f_ip_id())
local rtp_ssrc = select(1, f_rtp_ssrc())
local key = generateKey(tostring(ip_id), tostring(rtp_seq), tostring(rtp_ssrc))
list = packets[key]
if not list then
-- haven't seen these fields before, so add it as a non-dup (so far)
addPacketList(pnum, key)
createProtoTree(pnum, tree)
else
-- we haven't processed this packet, but we have seen the same fields
-- so it's a duplicate. Add its number to the array and entry...
addPacket(pnum, list)
-- and now create its tree
createProtoTree(pnum, tree, list)
end
else
-- we found the packet number already in the table, which means
-- we've processed it before
createProtoTree(pnum, tree, list)
end
end
createProtoTree = function (pnum, root, list)
– add our "protocol"
local tree = root:add(rtpdup)
if not list or #list < 2 then
-- it's not a duplicate
tree:add(pf_is_dup, false):set_generated()
else
tree:add(pf_is_dup, true):set_generated()
-- now add the other packet numbers as reference tree item fields
for _, num in ipairs(list) do
if num ~= pnum then
tree:add(pf_dup_frame, num):set_generated()
end
end
end
end
– then we register rtpdup as a postdissector
register_postdissector(rtpdup)
answered 23 Dec ‘14, 00:39
Hadriel
2.7k●2●9●39
accept rate: 18%
Thanks Quadratic. We are able to identify the duplicate packets as you indicated above using similar methods, but we need help trying to Filter for all Duplicate RTP packets. There is a ton of data to parse through. We see there is a way to do that with TCP, but have not found a way to Filter specificlaly duplciate RTP packets. Thanks.
One method is simply to use editcap to filter them out. The '-d' option of editcap should do it if the duplicates are close together and truly identical (uses MD5 hash comparison to detect them):
https://www.wireshark.org/docs/man-pages/editcap.html
In that example: editcap -d capture.pcap capture_without_duplicates.pcap