blob: 91ab21cb17b95e5764a98e116069959fad00d8a7 [file] [log] [blame]
Junxiao Shi1fda67d2018-01-12 21:35:31 +00001-- Copyright (c) 2015-2018, 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 Shic687af62018-05-06 21:58:09 +000045function getUriFromImplicitSha256DigestComponent(b)
46 s = "sha256digest="
47 for i = 0, (b.length - 1) do
48 byte = b.tvb(b.offset + b.typeLen + b.lengthLen + i, 1)
49 s = s .. string.format("%02x", byte:uint())
50 end
51 return s
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -070052end
53
Junxiao Shic687af62018-05-06 21:58:09 +000054function getUriFromNameComponent(b)
55 if b.type == 1 then
56 return getUriFromImplicitSha256DigestComponent(b)
Alexander Afanasyev357c2052015-08-10 21:26:52 -070057 end
Junxiao Shic687af62018-05-06 21:58:09 +000058 s = ""
59 if b.type ~= 8 then
60 s = string.format("%d=", b.type)
61 end
62 hasNonPeriod = false
63 for i = 0, (b.length - 1) do
64 byte = b.tvb(b.offset + b.typeLen + b.lengthLen + i, 1)
65 ch = byte:uint()
66 hasNonPeriod = hasNonPeriod or ch ~= 0x2E
67 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
68 s = s .. byte:string()
69 else
70 s = s .. string.format("%%%02X", ch)
71 end
72 end
73 if not hasNonPeriod then
74 s = s .. "..."
75 end
76 return s
77end
78
79function getUriFromName(b)
80 if b.elements == nil then
81 return "/"
82 end
83 components = {}
84 for i, comp in pairs(b.elements) do
85 table.insert(components, getUriFromNameComponent(comp))
86 end
87 return "/" .. table.concat(components, "/")
88end
89
90function getUriFromFinalBlockId(b)
91 if b.elements == nil then
92 return "/"
93 end
94 return getUriFromNameComponent(b.elements[1])
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -070095end
96
Junxiao Shi5e384792016-11-24 03:59:06 +000097function getUriFromExclude(block)
98 -- @todo
99 return ""
100end
101
Zipeng Wang574eeb02016-10-05 21:46:02 -0700102function getNackReasonDetail(b)
103 local code = getNonNegativeInteger(b)
104 if (code == 0) then return "None"
105 elseif (code == 50) then return "Congestion"
106 elseif (code == 100) then return "Duplicate"
107 elseif (code == 150) then return "NoRoute"
108 else return "Unknown"
109 end
110end
111
112function getCachePolicyDetail(b)
113 local code = getNonNegativeInteger(b)
114 if (code == 1) then return "NoCache"
115 else return "Unknown"
116 end
117end
118
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700119function getNonNegativeInteger(b)
Junxiao Shi5e384792016-11-24 03:59:06 +0000120 if (b.length == 1 or b.length == 2 or b.length == 4) then
121 return getValue(b):uint()
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700122 -- Something strange with uint64, not supporting it for now
123 -- elseif (b.length == 8) then
124 -- return b.tvb(b.offset + b.typeLen + b.lengthLen, 8):uint64()
125 else
126 return 0xFFFFFFFF;
127 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700128end
129
Junxiao Shi5e384792016-11-24 03:59:06 +0000130function getNonce(b)
131 assert(b.type == 10)
132 if (b.length ~= 4) then
133 return "invalid (should have 4 octets)"
134 end
135 return getValue(b):uint()
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700136end
137
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700138function getTrue(block)
139 return "Yes"
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700140end
141
Zipeng Wang574eeb02016-10-05 21:46:02 -0700142local AppPrivateBlock1 = 100
143local AppPrivateBlock2 = 800
144local AppPrivateBlock3 = 1000
145
146function canIgnoreTlvType(t)
147 if (t < AppPrivateBlock2 or t >= AppPrivateBlock3) then
148 return false
149 else
150 local mod = math.fmod(t, 2)
151 if (mod == 1) then
152 return true
153 else
154 return false
155 end
156 end
157end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700158
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700159function getGenericBlockInfo(block)
160 local name = ""
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700161
Zipeng Wang574eeb02016-10-05 21:46:02 -0700162 -- TODO: Properly format informational message based type value reservations
163 -- (http://named-data.net/doc/ndn-tlv/types.html#type-value-reservations)
164 if (block.type <= AppPrivateBlock1) then
165 name = "Unrecognized from the reserved range " .. 0 .. "-" .. AppPrivateBlock1 .. ""
166 elseif (AppPrivateBlock1 < block.type and block.type < AppPrivateBlock2) then
167 name = "Unrecognized from the reserved range " .. (AppPrivateBlock1 + 1) .. "-" .. (AppPrivateBlock2 - 1) .. ""
168 elseif (AppPrivateBlock2 <= block.type and block.type <= AppPrivateBlock3) then
169 if (canIgnoreTlvType(block.type)) then
170 name = "Unknown field (ignored)"
171 else
172 name = "Unknown field"
173 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700174 else
Zipeng Wang574eeb02016-10-05 21:46:02 -0700175 name = "RESERVED_3"
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700176 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700177
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700178 return name .. ", Type: " .. block.type .. ", Length: " .. block.length
179end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700180
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700181-----------------------------------------------------
182-----------------------------------------------------
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700183
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700184local NDN_DICT = {
Junxiao Shiac4b5462018-04-17 02:26:17 +0000185 -- Name and NameComponent
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700186 [7] = {name = "Name" , field = ProtoField.string("ndn.name", "Name") , value = getUriFromName},
187 [1] = {name = "ImplicitSha256DigestComponent", field = ProtoField.string("ndn.implicitsha256", "ImplicitSha256DigestComponent"), value = getUriFromNameComponent},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000188 [8] = {name = "GenericNameComponent" , field = ProtoField.string("ndn.namecomponent", "NameComponent") , value = getUriFromNameComponent},
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700189
Junxiao Shiac4b5462018-04-17 02:26:17 +0000190 -- Interest and its sub-elements in Packet Format v0.3
191 [5] = {name = "Interest" , summary = true},
192 [33] = {name = "CanBePrefix" , field = ProtoField.string("ndn.canbeprefix", "CanBePrefix") , value = getTrue},
193 [18] = {name = "MustBeFresh" , field = ProtoField.string("ndn.mustbefresh", "MustBeFresh") , value = getTrue},
194 -- [30] = {name = "ForwardingHint" , summary = true},
195 -- ForwardingHint and LinkPreference have the same TLV-TYPE number, so we can't recognize both for now (see #4185).
196 [31] = {name = "LinkDelegation" , summary = true},
197 [30] = {name = "LinkPreference" , field = ProtoField.uint32("ndn.link_preference", "LinkPreference", base.DEC) , value = getNonNegativeInteger},
Junxiao Shi5e384792016-11-24 03:59:06 +0000198 [10] = {name = "Nonce" , field = ProtoField.uint32("ndn.nonce", "Nonce", base.HEX) , value = getNonce},
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700199 [12] = {name = "InterestLifetime" , field = ProtoField.uint32("ndn.interestlifetime", "InterestLifetime", base.DEC) , value = getNonNegativeInteger},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000200 [34] = {name = "HopLimit" , field = ProtoField.uint32("ndn.hoplimit", "HopLimit", base.DEC) , value = getNonNegativeInteger},
201 [35] = {name = "Parameters" , field = ProtoField.string("ndn.parameters", "Parameters")},
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700202
Junxiao Shiac4b5462018-04-17 02:26:17 +0000203 -- Data and its sub-elements in Packet Format v0.3
204 [6] = {name = "Data" , summary = true},
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700205 [20] = {name = "MetaInfo" , summary = true},
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700206 [24] = {name = "ContentType" , field = ProtoField.uint32("ndn.contenttype", "Content Type", base.DEC) , value = getNonNegativeInteger},
207 [25] = {name = "FreshnessPeriod" , field = ProtoField.uint32("ndn.freshnessperiod", "FreshnessPeriod", base.DEC) , value = getNonNegativeInteger},
Junxiao Shic687af62018-05-06 21:58:09 +0000208 [26] = {name = "FinalBlockId" , field = ProtoField.string("ndn.finalblockid", "FinalBlockId") , value = getUriFromFinalBlockId},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000209 [21] = {name = "Content" , field = ProtoField.string("ndn.content", "Content")},
210 [22] = {name = "SignatureInfo" , summary = true},
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700211 [27] = {name = "SignatureType" , field = ProtoField.uint32("ndn.signaturetype", "SignatureType", base.DEC) , value = getNonNegativeInteger},
212 [28] = {name = "KeyLocator" , summary = true},
213 [29] = {name = "KeyDigest" , field = ProtoField.bytes("ndn.keydigest", "KeyDigest")},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000214 [23] = {name = "SignatureValue" , field = ProtoField.bytes("ndn.signaturevalue", "SignatureValue")},
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700215
Junxiao Shiac4b5462018-04-17 02:26:17 +0000216 -- NDNLPv2 headers
Zipeng Wang574eeb02016-10-05 21:46:02 -0700217 [80] = {name = "Fragment" },
218 [81] = {name = "Sequence" , field = ProtoField.uint32("ndn.sequence", "Sequence", base.DEC), value = getNonNegativeInteger},
219 [82] = {name = "FragIndex" , field = ProtoField.uint32("ndn.fragindex", "FragIndex", base.DEC), value = getNonNegativeInteger},
220 [83] = {name = "FragCount" , field = ProtoField.uint32("ndn.fragcount", "FragCount", base.DEC), value = getNonNegativeInteger},
221 [100] = {name = "LpPacket" , summary = true},
222 [800] = {name = "Nack" , summary = true},
223 [801] = {name = "NackReason" , field = ProtoField.string("ndn.nack_reason", "NackReason"), value = getNackReasonDetail},
224 [816] = {name = "NextHopFaceId" , field = ProtoField.uint32("ndn.nexthop_faceid", "NextHopFaceId", base.DEC), value = getNonNegativeInteger},
225 [817] = {name = "IncomingFaceId" , field = ProtoField.uint32("ndn.incoming_faceid", "IncomingFaceId", base.DEC), value = getNonNegativeInteger},
226 [820] = {name = "CachePolicy" , summary = true},
227 [821] = {name = "CachePolicyType" , field = ProtoField.string("ndn.cachepolicy_type", "CachePolicyType"), value = getCachePolicyDetail},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000228
229 -- Deprecated elements
230 [9] = {name = "Selectors" , summary = true},
231 [13] = {name = "MinSuffixComponents" , field = ProtoField.uint32("ndn.minsuffix", "MinSuffixComponents") , value = getNonNegativeInteger},
232 [14] = {name = "MaxSuffixComponents" , field = ProtoField.uint32("ndn.maxsuffix", "MaxSuffixComponents") , value = getNonNegativeInteger},
233 [15] = {name = "PublisherPublicKeyLocator" , summary = true},
234 [16] = {name = "Exclude" , field = ProtoField.string("ndn.exclude", "Exclude") , value = getUriFromExclude},
235 [17] = {name = "ChildSelector" , field = ProtoField.uint32("ndn.childselector", "ChildSelector", base.DEC) , value = getNonNegativeInteger},
236 [19] = {name = "Any" , field = ProtoField.string("ndn.any", "Any") , value = getTrue},
237 [32] = {name = "SelectedDelegation" , field = ProtoField.uint32("ndn.selected_delegation", "SelectedDelegation", base.DEC), value = getNonNegativeInteger},
Zipeng Wang574eeb02016-10-05 21:46:02 -0700238}
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700239
240-- -- Add protofields in NDN protocol
241ndn.fields = {
242}
243for key, value in pairs(NDN_DICT) do
244 table.insert(ndn.fields, value.field)
245end
246
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700247-----------------------------------------------------
248-----------------------------------------------------
249
250-- block
251-- .tvb
252-- .offset
253-- .type
254-- .typeLen
255-- .length
256-- .lengthLen
257-- .size = .typeLen + .lengthLen + .length
258
259function addInfo(block, root) -- may be add additional context later
260 local info = NDN_DICT[block.type]
261
262 if (info == nil) then
263 info = {}
264 info.value = getGenericBlockInfo
Zipeng Wang574eeb02016-10-05 21:46:02 -0700265 -- color
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700266 end
267
268 local treeInfo
269 if (info.value == nil) then
270
271 if (info.field ~= nil) then
272 treeInfo = root:add(info.field, block.tvb(block.offset, block.size))
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700273 else
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700274 treeInfo = root:add(block.tvb(block.offset, block.size), info.name)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700275 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700276
277 treeInfo:append_text(", Type: " .. block.type .. ", Length: " .. block.length)
278 else
279 block.value = info.value(block)
280
281 if (info.field ~= nil) then
282 treeInfo = root:add(info.field, block.tvb(block.offset, block.size), block.value)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700283 else
Zipeng Wang574eeb02016-10-05 21:46:02 -0700284 treeInfo = root:add(block.tvb(block.offset, block.size), block.value)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700285 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700286 end
287 block.root = treeInfo
288 return block.root
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700289end
290
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700291function addSummary(block)
292 if (block.elements == nil) then
293 return
294 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700295
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700296 local info = NDN_DICT[block.type]
297 if (info == nil or info.summary == nil) then
298 return
299 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700300
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700301 local summary = {}
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700302
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700303 for k, subblock in pairs(block.elements) do
304 if (subblock.value ~= nil) then
305 local info = NDN_DICT[subblock.type]
306 if (info ~= nil) then
307 table.insert(summary, info.name .. ": " .. subblock.value)
308 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700309 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700310 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700311
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700312 if (#summary > 0) then
313 block.summary = table.concat(summary, ", ")
314 if (block.value == nil) then
315 block.value = block.summary
316 end
317 block.root:append_text(", " .. block.summary)
318 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700319end
320
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700321-----------------------------------------------------
322-----------------------------------------------------
323
324function readVarNumber(tvb, offset)
Junxiao Shie65c6d72016-07-24 21:53:19 +0000325 if offset >= tvb:len() then
326 return 0, 0
327 end
328
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700329 local firstOctet = tvb(offset, 1):uint()
330 if (firstOctet < 253) then
331 return firstOctet, 1
Junxiao Shie65c6d72016-07-24 21:53:19 +0000332 elseif (firstOctet == 253) and (offset + 3 < tvb:len()) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700333 return tvb(offset + 1, 2):uint(), 3
Junxiao Shie65c6d72016-07-24 21:53:19 +0000334 elseif (firstOctet == 254) and (offset + 5 < tvb:len()) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700335 return tvb(offset + 1, 4):uint(), 5
Junxiao Shie65c6d72016-07-24 21:53:19 +0000336 elseif (firstOctet == 255) and (offset + 9 < tvb:len()) then
337 return tvb(offset + 1, 8):uint64(), 9
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700338 end
Junxiao Shie65c6d72016-07-24 21:53:19 +0000339
340 return 0, 0
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700341end
342
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700343function getBlock(tvb, offset)
344 local block = {}
345 block.tvb = tvb
346 block.offset = offset
347
348 block.type, block.typeLen = readVarNumber(block.tvb, block.offset)
Junxiao Shie65c6d72016-07-24 21:53:19 +0000349 if block.typeLen == 0 then
350 return nil
351 end
352
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700353 block.length, block.lengthLen = readVarNumber(block.tvb, block.offset + block.typeLen)
Junxiao Shie65c6d72016-07-24 21:53:19 +0000354 if block.lengthLen == 0 then
355 return nil
356 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700357
358 block.size = block.typeLen + block.lengthLen + block.length
359
360 return block
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700361end
362
Alexander Afanasyev7f43c532015-08-12 15:28:51 -0700363function canBeValidNdnPacket(block)
Zipeng Wang574eeb02016-10-05 21:46:02 -0700364 if ((block.type == 5 or block.type == 6 or block.type == 100) and block.length <= 8800) then
Alexander Afanasyev7f43c532015-08-12 15:28:51 -0700365 return true
366 else
367 return false
368 end
369end
370
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700371function findNdnPacket(tvb)
372 offset = 0
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700373
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700374 while offset + 2 < tvb:len() do
375 local block = getBlock(tvb, offset)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700376
Junxiao Shie65c6d72016-07-24 21:53:19 +0000377 if (block ~= nil) and canBeValidNdnPacket(block) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700378 return block
379 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700380
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700381 offset = offset + 1
382 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700383
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700384 return nil
385end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700386
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700387function getSubBlocks(block)
388 local valueLeft = block.length
389 local subBlocks = {}
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700390
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700391 while valueLeft > 0 do
Junxiao Shie65c6d72016-07-24 21:53:19 +0000392 local offset = block.offset + block.typeLen + block.lengthLen + (block.length - valueLeft)
393 local child = getBlock(block.tvb, offset)
394 if child == nil then
395 return nil
396 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700397
398 valueLeft = valueLeft - child.size
399 table.insert(subBlocks, child)
400 end
401
402 if (valueLeft == 0) then
403 return subBlocks
404 else
405 return nil
406 end
407end
408
409-----------------------------------------------------
410-----------------------------------------------------
411
412-- NDN protocol dissector function
413function ndn.dissector(tvb, pInfo, root) -- Tvb, Pinfo, TreeItem
414
415 if (tvb:len() ~= tvb:reported_len()) then
416 return 0 -- ignore partially captured packets
417 -- this can/may be re-enabled only for unfragmented UDP packets
418 end
419
420 local ok, block = pcall(findNdnPacket, tvb)
421 if (not ok) then
422 return 0
423 end
424
425 if (block == nil or block.offset == nil) then
426 -- no valid NDN packets found
427 return 0
428 end
429
430 local nBytesLeft = tvb:len() - block.offset
431 -- print (pInfo.number .. ":: Found block: " .. block.type .. " of length " .. block.size .. " bytesLeft: " .. nBytesLeft)
432
Junxiao Shi1fda67d2018-01-12 21:35:31 +0000433 local pktType = ""
434 local pktName = ""
435
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700436 while (block.size <= nBytesLeft) do
437 -- Create TreeItems
438 block.tree = root:add(ndn, tvb(block.offset, block.size))
439
440 local queue = {block}
441 while (#queue > 0) do
442 local block = queue[1]
443 table.remove(queue, 1)
444
445 block.elements = getSubBlocks(block)
446 local subtree = addInfo(block, block.tree)
447
448 if (block.elements ~= nil) then
449 for i, subBlock in pairs(block.elements) do
450 subBlock.tree = subtree
451 table.insert(queue, subBlock)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700452 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700453 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700454 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700455
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700456 -- Make summaries
457 local queue = {block}
458 while (#queue > 0) do
459 local block = queue[1]
460 if (block.visited ~= nil or block.elements == nil) then
461 -- try to make summary
462 table.remove(queue, 1)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700463
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700464 addSummary(block)
465 else
466 for i, subBlock in pairs(block.elements) do
467 table.insert(queue, 1, subBlock)
468 end
469 block.visited = true
470 end
Junxiao Shi1fda67d2018-01-12 21:35:31 +0000471
472 -- prepare information to fill info column
473 if block.type == 5 and pktType ~= "Nack" then
474 pktType = "Interest"
475 elseif block.type == 6 then
476 pktType = "Data"
477 elseif block.type == 800 then
478 pktType = "Nack"
479 end
480
481 if pktName == "" and block.type == 7 then
482 pktName = getUriFromName(block)
483 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700484 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700485
486 local info = NDN_DICT[block.type]
487 if (info ~= nil) then
Zipeng Wang574eeb02016-10-05 21:46:02 -0700488 if (block.summary ~= nil) then
489 block.tree:append_text(", " .. NDN_DICT[block.type].name .. ", " .. block.summary)
490 else
491 block.tree:append_text(", " .. NDN_DICT[block.type].name)
492 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700493 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700494
495 nBytesLeft = nBytesLeft - block.size
496
497 if (nBytesLeft > 0) then
498 ok, block = pcall(getBlock, tvb, tvb:len() - nBytesLeft)
Zipeng Wang574eeb02016-10-05 21:46:02 -0700499 if (not ok or block == nil or not canBeValidNdnPacket(block)) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700500 break
501 end
502 end
Zipeng Wang574eeb02016-10-05 21:46:02 -0700503 end -- while(block.size <= nBytesLeft)
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700504
505 pInfo.cols.protocol = tostring(pInfo.cols.protocol) .. " (" .. ndn.name .. ")"
Junxiao Shi1fda67d2018-01-12 21:35:31 +0000506 pInfo.cols.info = pktType .. " " .. pktName
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700507
Alexander Afanasyev7f43c532015-08-12 15:28:51 -0700508 if (nBytesLeft > 0 and block ~= nil and block.size ~= nil and block.size > nBytesLeft) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700509 pInfo.desegment_offset = tvb:len() - nBytesLeft
510
511 -- Originally, I set desegment_len to the exact lenght, but it mysteriously didn't work for TCP
512 -- pInfo.desegment_len = block.size -- this will not work to desegment TCP streams
513 pInfo.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
514 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700515end
516
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700517local udpDissectorTable = DissectorTable.get("udp.port")
518udpDissectorTable:add("6363", ndn)
519udpDissectorTable:add("56363", ndn)
520
521local tcpDissectorTable = DissectorTable.get("tcp.port")
522tcpDissectorTable:add("6363", ndn)
523
524local websocketDissectorTable = DissectorTable.get("ws.port")
525-- websocketDissectorTable:add("9696", ndn)
526websocketDissectorTable:add("1-65535", ndn)
527
Alexander Afanasyev7f43c532015-08-12 15:28:51 -0700528local ethernetDissectorTable = DissectorTable.get("ethertype")
529ethernetDissectorTable:add(0x8624, ndn)
530
Junxiao Shiac4b5462018-04-17 02:26:17 +0000531io.stderr:write("NDN dissector successfully loaded\n")