blob: 59420fd322e424a8a0680debb0927cbfd88fc11f [file] [log] [blame]
Davide Pesavento105cd9e2019-04-06 18:13:44 -04001-- Copyright (c) 2015-2019, Regents of the University of California.
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -07002--
3-- This file is part of ndn-tools (Named Data Networking Essential Tools).
4-- See AUTHORS.md for complete list of ndn-tools authors and contributors.
5--
6-- ndn-tools is free software: you can redistribute it and/or modify it under the terms
7-- of the GNU General Public License as published by the Free Software Foundation,
8-- either version 3 of the License, or (at your option) any later version.
9--
10-- ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12-- PURPOSE. See the GNU General Public License for more details.
13--
14-- You should have received a copy of the GNU General Public License along with
15-- ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
16--
17-- @author Qi Zhao <https://www.linkedin.com/pub/qi-zhao/73/835/9a3>
18-- @author Seunghyun Yoo <http://relue2718.com/>
19-- @author Seungbae Kim <https://sites.google.com/site/sbkimcv/>
Alexander Afanasyev357c2052015-08-10 21:26:52 -070020-- @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
Zipeng Wang574eeb02016-10-05 21:46:02 -070021-- @author Zipeng Wang
22-- @author Qianshan Yu
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -070023
24-- inspect.lua (https://github.com/kikito/inspect.lua) can be used for debugging.
25-- See more at http://stackoverflow.com/q/15175859/2150331
26-- local inspect = require('inspect')
27
28-- NDN protocol
Alexander Afanasyev357c2052015-08-10 21:26:52 -070029ndn = Proto("ndn", "Named Data Networking (NDN)")
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -070030
Zipeng Wang574eeb02016-10-05 21:46:02 -070031-- TODO with NDNLPv2 processing:
32-- * mark field "unknown" when the field is recognized but the relevant feature is disabled
33-- * colorize "unknown field"
34-- * for a field that appears out-of-order, display "out-of-order field " in red
35
Alexander Afanasyev357c2052015-08-10 21:26:52 -070036-----------------------------------------------------
37-----------------------------------------------------
38-- Field formatting helpers
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -070039
Junxiao Shi5e384792016-11-24 03:59:06 +000040-- @return TLV-VALUE portion of a TLV block
41function getValue(b)
42 return b.tvb(b.offset + b.typeLen + b.lengthLen, b.length)
43end
44
Junxiao Shi89db73c2018-05-27 15:22:49 +000045function getNonNegativeInteger(b)
46 if b.length == 1 or b.length == 2 or b.length == 4 or b.length == 8 then
47 return getValue(b):uint64()
48 end
49 return UInt64.max()
50end
51
Junxiao Shic687af62018-05-06 21:58:09 +000052function getUriFromImplicitSha256DigestComponent(b)
53 s = "sha256digest="
54 for i = 0, (b.length - 1) do
55 byte = b.tvb(b.offset + b.typeLen + b.lengthLen + i, 1)
56 s = s .. string.format("%02x", byte:uint())
57 end
58 return s
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -070059end
60
Junxiao Shic687af62018-05-06 21:58:09 +000061function getUriFromNameComponent(b)
62 if b.type == 1 then
63 return getUriFromImplicitSha256DigestComponent(b)
Alexander Afanasyev357c2052015-08-10 21:26:52 -070064 end
Junxiao Shic687af62018-05-06 21:58:09 +000065 s = ""
66 if b.type ~= 8 then
67 s = string.format("%d=", b.type)
68 end
69 hasNonPeriod = false
70 for i = 0, (b.length - 1) do
71 byte = b.tvb(b.offset + b.typeLen + b.lengthLen + i, 1)
72 ch = byte:uint()
73 hasNonPeriod = hasNonPeriod or ch ~= 0x2E
74 if (ch >= 0x41 and ch <= 0x5A) or (ch >= 0x61 and ch <= 0x7A) or (ch >= 0x30 and ch <= 0x39) or ch == 0x2D or ch == 0x2E or ch == 0x5F or ch == 0x7E then
75 s = s .. byte:string()
76 else
77 s = s .. string.format("%%%02X", ch)
78 end
79 end
80 if not hasNonPeriod then
81 s = s .. "..."
82 end
83 return s
84end
85
86function getUriFromName(b)
87 if b.elements == nil then
88 return "/"
89 end
90 components = {}
91 for i, comp in pairs(b.elements) do
92 table.insert(components, getUriFromNameComponent(comp))
93 end
94 return "/" .. table.concat(components, "/")
95end
96
97function getUriFromFinalBlockId(b)
98 if b.elements == nil then
99 return "/"
100 end
101 return getUriFromNameComponent(b.elements[1])
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700102end
103
Zipeng Wang574eeb02016-10-05 21:46:02 -0700104function getNackReasonDetail(b)
105 local code = getNonNegativeInteger(b)
Junxiao Shi89db73c2018-05-27 15:22:49 +0000106 if code == UInt64(50) then return "Congestion"
107 elseif code == UInt64(100) then return "Duplicate"
108 elseif code == UInt64(150) then return "NoRoute"
109 else return tostring(code)
Zipeng Wang574eeb02016-10-05 21:46:02 -0700110 end
111end
112
113function getCachePolicyDetail(b)
114 local code = getNonNegativeInteger(b)
115 if (code == 1) then return "NoCache"
116 else return "Unknown"
117 end
118end
119
Junxiao Shi5e384792016-11-24 03:59:06 +0000120function getNonce(b)
121 assert(b.type == 10)
122 if (b.length ~= 4) then
123 return "invalid (should have 4 octets)"
124 end
125 return getValue(b):uint()
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700126end
127
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700128function getTrue(block)
129 return "Yes"
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700130end
131
Zipeng Wang574eeb02016-10-05 21:46:02 -0700132local AppPrivateBlock1 = 100
133local AppPrivateBlock2 = 800
134local AppPrivateBlock3 = 1000
135
136function canIgnoreTlvType(t)
137 if (t < AppPrivateBlock2 or t >= AppPrivateBlock3) then
138 return false
139 else
140 local mod = math.fmod(t, 2)
141 if (mod == 1) then
142 return true
143 else
144 return false
145 end
146 end
147end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700148
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700149function getGenericBlockInfo(block)
150 local name = ""
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700151
Zipeng Wang574eeb02016-10-05 21:46:02 -0700152 -- TODO: Properly format informational message based type value reservations
153 -- (http://named-data.net/doc/ndn-tlv/types.html#type-value-reservations)
154 if (block.type <= AppPrivateBlock1) then
155 name = "Unrecognized from the reserved range " .. 0 .. "-" .. AppPrivateBlock1 .. ""
156 elseif (AppPrivateBlock1 < block.type and block.type < AppPrivateBlock2) then
157 name = "Unrecognized from the reserved range " .. (AppPrivateBlock1 + 1) .. "-" .. (AppPrivateBlock2 - 1) .. ""
158 elseif (AppPrivateBlock2 <= block.type and block.type <= AppPrivateBlock3) then
159 if (canIgnoreTlvType(block.type)) then
160 name = "Unknown field (ignored)"
161 else
162 name = "Unknown field"
163 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700164 else
Zipeng Wang574eeb02016-10-05 21:46:02 -0700165 name = "RESERVED_3"
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700166 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700167
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700168 return name .. ", Type: " .. block.type .. ", Length: " .. block.length
169end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700170
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700171-----------------------------------------------------
172-----------------------------------------------------
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700173
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700174local NDN_DICT = {
Davide Pesavento105cd9e2019-04-06 18:13:44 -0400175 -- Name and name components
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700176 [7] = {name = "Name" , field = ProtoField.string("ndn.name", "Name") , value = getUriFromName},
177 [1] = {name = "ImplicitSha256DigestComponent", field = ProtoField.string("ndn.implicitsha256", "ImplicitSha256DigestComponent"), value = getUriFromNameComponent},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000178 [8] = {name = "GenericNameComponent" , field = ProtoField.string("ndn.namecomponent", "NameComponent") , value = getUriFromNameComponent},
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700179
Junxiao Shiac4b5462018-04-17 02:26:17 +0000180 -- Interest and its sub-elements in Packet Format v0.3
181 [5] = {name = "Interest" , summary = true},
182 [33] = {name = "CanBePrefix" , field = ProtoField.string("ndn.canbeprefix", "CanBePrefix") , value = getTrue},
183 [18] = {name = "MustBeFresh" , field = ProtoField.string("ndn.mustbefresh", "MustBeFresh") , value = getTrue},
184 -- [30] = {name = "ForwardingHint" , summary = true},
185 -- ForwardingHint and LinkPreference have the same TLV-TYPE number, so we can't recognize both for now (see #4185).
186 [31] = {name = "LinkDelegation" , summary = true},
Davide Pesavento105cd9e2019-04-06 18:13:44 -0400187 [30] = {name = "LinkPreference" , field = ProtoField.uint64("ndn.linkpreference", "LinkPreference", base.DEC) , value = getNonNegativeInteger},
Junxiao Shi5e384792016-11-24 03:59:06 +0000188 [10] = {name = "Nonce" , field = ProtoField.uint32("ndn.nonce", "Nonce", base.HEX) , value = getNonce},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000189 [12] = {name = "InterestLifetime" , field = ProtoField.uint64("ndn.interestlifetime", "InterestLifetime", base.DEC) , value = getNonNegativeInteger},
190 [34] = {name = "HopLimit" , field = ProtoField.uint64("ndn.hoplimit", "HopLimit", base.DEC) , value = getNonNegativeInteger},
Davide Pesavento105cd9e2019-04-06 18:13:44 -0400191 [36] = {name = "ApplicationParameters" , field = ProtoField.string("ndn.applicationparameters", "ApplicationParameters")},
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700192
Junxiao Shiac4b5462018-04-17 02:26:17 +0000193 -- Data and its sub-elements in Packet Format v0.3
194 [6] = {name = "Data" , summary = true},
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700195 [20] = {name = "MetaInfo" , summary = true},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000196 [24] = {name = "ContentType" , field = ProtoField.uint64("ndn.contenttype", "Content Type", base.DEC) , value = getNonNegativeInteger},
197 [25] = {name = "FreshnessPeriod" , field = ProtoField.uint64("ndn.freshnessperiod", "FreshnessPeriod", base.DEC) , value = getNonNegativeInteger},
Junxiao Shic687af62018-05-06 21:58:09 +0000198 [26] = {name = "FinalBlockId" , field = ProtoField.string("ndn.finalblockid", "FinalBlockId") , value = getUriFromFinalBlockId},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000199 [21] = {name = "Content" , field = ProtoField.string("ndn.content", "Content")},
200 [22] = {name = "SignatureInfo" , summary = true},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000201 [27] = {name = "SignatureType" , field = ProtoField.uint64("ndn.signaturetype", "SignatureType", base.DEC) , value = getNonNegativeInteger},
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700202 [28] = {name = "KeyLocator" , summary = true},
203 [29] = {name = "KeyDigest" , field = ProtoField.bytes("ndn.keydigest", "KeyDigest")},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000204 [23] = {name = "SignatureValue" , field = ProtoField.bytes("ndn.signaturevalue", "SignatureValue")},
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700205
Junxiao Shiac4b5462018-04-17 02:26:17 +0000206 -- NDNLPv2 headers
Zipeng Wang574eeb02016-10-05 21:46:02 -0700207 [80] = {name = "Fragment" },
Junxiao Shi89db73c2018-05-27 15:22:49 +0000208 [81] = {name = "Sequence" , field = ProtoField.uint64("ndn.sequence", "Sequence", base.DEC) , value = getNonNegativeInteger},
209 [82] = {name = "FragIndex" , field = ProtoField.uint64("ndn.fragindex", "FragIndex", base.DEC) , value = getNonNegativeInteger},
210 [83] = {name = "FragCount" , field = ProtoField.uint64("ndn.fragcount", "FragCount", base.DEC) , value = getNonNegativeInteger},
211 [98] = {name = "PitToken" , field = ProtoField.uint64("ndn.pit_token", "PitToken", base.DEC) , value = getNonNegativeInteger},
Zipeng Wang574eeb02016-10-05 21:46:02 -0700212 [100] = {name = "LpPacket" , summary = true},
213 [800] = {name = "Nack" , summary = true},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000214 [801] = {name = "NackReason" , field = ProtoField.string("ndn.nack_reason", "NackReason") , value = getNackReasonDetail},
215 [816] = {name = "NextHopFaceId" , field = ProtoField.uint64("ndn.nexthop_faceid", "NextHopFaceId", base.DEC) , value = getNonNegativeInteger},
216 [817] = {name = "IncomingFaceId" , field = ProtoField.uint64("ndn.incoming_faceid", "IncomingFaceId", base.DEC) , value = getNonNegativeInteger},
Zipeng Wang574eeb02016-10-05 21:46:02 -0700217 [820] = {name = "CachePolicy" , summary = true},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000218 [821] = {name = "CachePolicyType" , field = ProtoField.string("ndn.cachepolicy_type", "CachePolicyType") , value = getCachePolicyDetail},
219 [832] = {name = "CongestionMark" , field = ProtoField.uint64("ndn.congestion_mark", "CongestionMark", base.DEC) , value = getNonNegativeInteger},
220 [836] = {name = "Ack" , field = ProtoField.uint64("ndn.ack", "Ack", base.DEC) , value = getNonNegativeInteger},
Davide Pesavento200014a2021-11-27 21:21:47 -0500221 [840] = {name = "TxSequence" , field = ProtoField.uint64("ndn.txseq", "TxSequence", base.DEC) , value = getNonNegativeInteger},
Zipeng Wang574eeb02016-10-05 21:46:02 -0700222}
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700223
224-- -- Add protofields in NDN protocol
Davide Pesavento200014a2021-11-27 21:21:47 -0500225ndn.fields = {}
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700226for key, value in pairs(NDN_DICT) do
227 table.insert(ndn.fields, value.field)
228end
229
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700230-----------------------------------------------------
231-----------------------------------------------------
232
233-- block
234-- .tvb
235-- .offset
236-- .type
237-- .typeLen
238-- .length
239-- .lengthLen
240-- .size = .typeLen + .lengthLen + .length
241
242function addInfo(block, root) -- may be add additional context later
243 local info = NDN_DICT[block.type]
244
245 if (info == nil) then
246 info = {}
247 info.value = getGenericBlockInfo
Zipeng Wang574eeb02016-10-05 21:46:02 -0700248 -- color
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700249 end
250
251 local treeInfo
252 if (info.value == nil) then
253
254 if (info.field ~= nil) then
255 treeInfo = root:add(info.field, block.tvb(block.offset, block.size))
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700256 else
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700257 treeInfo = root:add(block.tvb(block.offset, block.size), info.name)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700258 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700259
260 treeInfo:append_text(", Type: " .. block.type .. ", Length: " .. block.length)
261 else
262 block.value = info.value(block)
263
264 if (info.field ~= nil) then
265 treeInfo = root:add(info.field, block.tvb(block.offset, block.size), block.value)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700266 else
Zipeng Wang574eeb02016-10-05 21:46:02 -0700267 treeInfo = root:add(block.tvb(block.offset, block.size), block.value)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700268 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700269 end
270 block.root = treeInfo
271 return block.root
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700272end
273
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700274function addSummary(block)
275 if (block.elements == nil) then
276 return
277 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700278
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700279 local info = NDN_DICT[block.type]
280 if (info == nil or info.summary == nil) then
281 return
282 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700283
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700284 local summary = {}
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700285
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700286 for k, subblock in pairs(block.elements) do
287 if (subblock.value ~= nil) then
288 local info = NDN_DICT[subblock.type]
289 if (info ~= nil) then
290 table.insert(summary, info.name .. ": " .. subblock.value)
291 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700292 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700293 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700294
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700295 if (#summary > 0) then
296 block.summary = table.concat(summary, ", ")
297 if (block.value == nil) then
298 block.value = block.summary
299 end
300 block.root:append_text(", " .. block.summary)
301 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700302end
303
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700304-----------------------------------------------------
305-----------------------------------------------------
306
307function readVarNumber(tvb, offset)
Junxiao Shie65c6d72016-07-24 21:53:19 +0000308 if offset >= tvb:len() then
309 return 0, 0
310 end
311
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700312 local firstOctet = tvb(offset, 1):uint()
313 if (firstOctet < 253) then
314 return firstOctet, 1
Junxiao Shie65c6d72016-07-24 21:53:19 +0000315 elseif (firstOctet == 253) and (offset + 3 < tvb:len()) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700316 return tvb(offset + 1, 2):uint(), 3
Junxiao Shie65c6d72016-07-24 21:53:19 +0000317 elseif (firstOctet == 254) and (offset + 5 < tvb:len()) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700318 return tvb(offset + 1, 4):uint(), 5
Junxiao Shie65c6d72016-07-24 21:53:19 +0000319 elseif (firstOctet == 255) and (offset + 9 < tvb:len()) then
320 return tvb(offset + 1, 8):uint64(), 9
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700321 end
Junxiao Shie65c6d72016-07-24 21:53:19 +0000322
323 return 0, 0
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700324end
325
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700326function getBlock(tvb, offset)
327 local block = {}
328 block.tvb = tvb
329 block.offset = offset
330
331 block.type, block.typeLen = readVarNumber(block.tvb, block.offset)
Junxiao Shie65c6d72016-07-24 21:53:19 +0000332 if block.typeLen == 0 then
333 return nil
334 end
335
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700336 block.length, block.lengthLen = readVarNumber(block.tvb, block.offset + block.typeLen)
Junxiao Shie65c6d72016-07-24 21:53:19 +0000337 if block.lengthLen == 0 then
338 return nil
339 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700340
341 block.size = block.typeLen + block.lengthLen + block.length
342
343 return block
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700344end
345
Alexander Afanasyev7f43c532015-08-12 15:28:51 -0700346function canBeValidNdnPacket(block)
Zipeng Wang574eeb02016-10-05 21:46:02 -0700347 if ((block.type == 5 or block.type == 6 or block.type == 100) and block.length <= 8800) then
Alexander Afanasyev7f43c532015-08-12 15:28:51 -0700348 return true
349 else
350 return false
351 end
352end
353
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700354function findNdnPacket(tvb)
355 offset = 0
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700356
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700357 while offset + 2 < tvb:len() do
358 local block = getBlock(tvb, offset)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700359
Junxiao Shie65c6d72016-07-24 21:53:19 +0000360 if (block ~= nil) and canBeValidNdnPacket(block) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700361 return block
362 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700363
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700364 offset = offset + 1
365 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700366
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700367 return nil
368end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700369
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700370function getSubBlocks(block)
371 local valueLeft = block.length
372 local subBlocks = {}
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700373
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700374 while valueLeft > 0 do
Junxiao Shie65c6d72016-07-24 21:53:19 +0000375 local offset = block.offset + block.typeLen + block.lengthLen + (block.length - valueLeft)
376 local child = getBlock(block.tvb, offset)
377 if child == nil then
378 return nil
379 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700380
381 valueLeft = valueLeft - child.size
382 table.insert(subBlocks, child)
383 end
384
385 if (valueLeft == 0) then
386 return subBlocks
387 else
388 return nil
389 end
390end
391
392-----------------------------------------------------
393-----------------------------------------------------
394
395-- NDN protocol dissector function
396function ndn.dissector(tvb, pInfo, root) -- Tvb, Pinfo, TreeItem
397
398 if (tvb:len() ~= tvb:reported_len()) then
399 return 0 -- ignore partially captured packets
400 -- this can/may be re-enabled only for unfragmented UDP packets
401 end
402
403 local ok, block = pcall(findNdnPacket, tvb)
404 if (not ok) then
405 return 0
406 end
407
408 if (block == nil or block.offset == nil) then
409 -- no valid NDN packets found
410 return 0
411 end
412
413 local nBytesLeft = tvb:len() - block.offset
414 -- print (pInfo.number .. ":: Found block: " .. block.type .. " of length " .. block.size .. " bytesLeft: " .. nBytesLeft)
415
Junxiao Shi1fda67d2018-01-12 21:35:31 +0000416 local pktType = ""
417 local pktName = ""
418
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700419 while (block.size <= nBytesLeft) do
420 -- Create TreeItems
421 block.tree = root:add(ndn, tvb(block.offset, block.size))
422
423 local queue = {block}
424 while (#queue > 0) do
425 local block = queue[1]
426 table.remove(queue, 1)
427
428 block.elements = getSubBlocks(block)
429 local subtree = addInfo(block, block.tree)
430
431 if (block.elements ~= nil) then
432 for i, subBlock in pairs(block.elements) do
433 subBlock.tree = subtree
434 table.insert(queue, subBlock)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700435 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700436 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700437 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700438
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700439 -- Make summaries
440 local queue = {block}
441 while (#queue > 0) do
442 local block = queue[1]
443 if (block.visited ~= nil or block.elements == nil) then
444 -- try to make summary
445 table.remove(queue, 1)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700446
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700447 addSummary(block)
448 else
449 for i, subBlock in pairs(block.elements) do
450 table.insert(queue, 1, subBlock)
451 end
452 block.visited = true
453 end
Junxiao Shi1fda67d2018-01-12 21:35:31 +0000454
455 -- prepare information to fill info column
456 if block.type == 5 and pktType ~= "Nack" then
457 pktType = "Interest"
458 elseif block.type == 6 then
459 pktType = "Data"
460 elseif block.type == 800 then
461 pktType = "Nack"
462 end
463
Alexander Afanasyev4fb67ea2018-08-02 08:18:28 -0600464 if block.type == 7 then
Junxiao Shi1fda67d2018-01-12 21:35:31 +0000465 pktName = getUriFromName(block)
466 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700467 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700468
469 local info = NDN_DICT[block.type]
470 if (info ~= nil) then
Zipeng Wang574eeb02016-10-05 21:46:02 -0700471 if (block.summary ~= nil) then
472 block.tree:append_text(", " .. NDN_DICT[block.type].name .. ", " .. block.summary)
473 else
474 block.tree:append_text(", " .. NDN_DICT[block.type].name)
475 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700476 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700477
478 nBytesLeft = nBytesLeft - block.size
479
480 if (nBytesLeft > 0) then
481 ok, block = pcall(getBlock, tvb, tvb:len() - nBytesLeft)
Zipeng Wang574eeb02016-10-05 21:46:02 -0700482 if (not ok or block == nil or not canBeValidNdnPacket(block)) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700483 break
484 end
485 end
Zipeng Wang574eeb02016-10-05 21:46:02 -0700486 end -- while(block.size <= nBytesLeft)
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700487
488 pInfo.cols.protocol = tostring(pInfo.cols.protocol) .. " (" .. ndn.name .. ")"
Junxiao Shi1fda67d2018-01-12 21:35:31 +0000489 pInfo.cols.info = pktType .. " " .. pktName
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700490
Alexander Afanasyev7f43c532015-08-12 15:28:51 -0700491 if (nBytesLeft > 0 and block ~= nil and block.size ~= nil and block.size > nBytesLeft) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700492 pInfo.desegment_offset = tvb:len() - nBytesLeft
493
494 -- Originally, I set desegment_len to the exact lenght, but it mysteriously didn't work for TCP
495 -- pInfo.desegment_len = block.size -- this will not work to desegment TCP streams
496 pInfo.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
497 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700498end
499
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700500local udpDissectorTable = DissectorTable.get("udp.port")
501udpDissectorTable:add("6363", ndn)
502udpDissectorTable:add("56363", ndn)
503
504local tcpDissectorTable = DissectorTable.get("tcp.port")
505tcpDissectorTable:add("6363", ndn)
506
507local websocketDissectorTable = DissectorTable.get("ws.port")
508-- websocketDissectorTable:add("9696", ndn)
509websocketDissectorTable:add("1-65535", ndn)
510
Alexander Afanasyev7f43c532015-08-12 15:28:51 -0700511local ethernetDissectorTable = DissectorTable.get("ethertype")
512ethernetDissectorTable:add(0x8624, ndn)
513
Alexander Afanasyev4fb67ea2018-08-02 08:18:28 -0600514local pppDissectorTable = DissectorTable.get("ppp.protocol")
515pppDissectorTable:add(0x0077, ndn)
516
Junxiao Shiac4b5462018-04-17 02:26:17 +0000517io.stderr:write("NDN dissector successfully loaded\n")