blob: e14b5a6288c4e91f128b323380ce094f1550db7c [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 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
Junxiao Shi5e384792016-11-24 03:59:06 +0000104function getUriFromExclude(block)
105 -- @todo
106 return ""
107end
108
Zipeng Wang574eeb02016-10-05 21:46:02 -0700109function getNackReasonDetail(b)
110 local code = getNonNegativeInteger(b)
Junxiao Shi89db73c2018-05-27 15:22:49 +0000111 if code == UInt64(50) then return "Congestion"
112 elseif code == UInt64(100) then return "Duplicate"
113 elseif code == UInt64(150) then return "NoRoute"
114 else return tostring(code)
Zipeng Wang574eeb02016-10-05 21:46:02 -0700115 end
116end
117
118function getCachePolicyDetail(b)
119 local code = getNonNegativeInteger(b)
120 if (code == 1) then return "NoCache"
121 else return "Unknown"
122 end
123end
124
Junxiao Shi5e384792016-11-24 03:59:06 +0000125function getNonce(b)
126 assert(b.type == 10)
127 if (b.length ~= 4) then
128 return "invalid (should have 4 octets)"
129 end
130 return getValue(b):uint()
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700131end
132
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700133function getTrue(block)
134 return "Yes"
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700135end
136
Zipeng Wang574eeb02016-10-05 21:46:02 -0700137local AppPrivateBlock1 = 100
138local AppPrivateBlock2 = 800
139local AppPrivateBlock3 = 1000
140
141function canIgnoreTlvType(t)
142 if (t < AppPrivateBlock2 or t >= AppPrivateBlock3) then
143 return false
144 else
145 local mod = math.fmod(t, 2)
146 if (mod == 1) then
147 return true
148 else
149 return false
150 end
151 end
152end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700153
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700154function getGenericBlockInfo(block)
155 local name = ""
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700156
Zipeng Wang574eeb02016-10-05 21:46:02 -0700157 -- TODO: Properly format informational message based type value reservations
158 -- (http://named-data.net/doc/ndn-tlv/types.html#type-value-reservations)
159 if (block.type <= AppPrivateBlock1) then
160 name = "Unrecognized from the reserved range " .. 0 .. "-" .. AppPrivateBlock1 .. ""
161 elseif (AppPrivateBlock1 < block.type and block.type < AppPrivateBlock2) then
162 name = "Unrecognized from the reserved range " .. (AppPrivateBlock1 + 1) .. "-" .. (AppPrivateBlock2 - 1) .. ""
163 elseif (AppPrivateBlock2 <= block.type and block.type <= AppPrivateBlock3) then
164 if (canIgnoreTlvType(block.type)) then
165 name = "Unknown field (ignored)"
166 else
167 name = "Unknown field"
168 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700169 else
Zipeng Wang574eeb02016-10-05 21:46:02 -0700170 name = "RESERVED_3"
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700171 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700172
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700173 return name .. ", Type: " .. block.type .. ", Length: " .. block.length
174end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700175
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700176-----------------------------------------------------
177-----------------------------------------------------
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700178
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700179local NDN_DICT = {
Junxiao Shiac4b5462018-04-17 02:26:17 +0000180 -- Name and NameComponent
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700181 [7] = {name = "Name" , field = ProtoField.string("ndn.name", "Name") , value = getUriFromName},
182 [1] = {name = "ImplicitSha256DigestComponent", field = ProtoField.string("ndn.implicitsha256", "ImplicitSha256DigestComponent"), value = getUriFromNameComponent},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000183 [8] = {name = "GenericNameComponent" , field = ProtoField.string("ndn.namecomponent", "NameComponent") , value = getUriFromNameComponent},
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700184
Junxiao Shiac4b5462018-04-17 02:26:17 +0000185 -- Interest and its sub-elements in Packet Format v0.3
186 [5] = {name = "Interest" , summary = true},
187 [33] = {name = "CanBePrefix" , field = ProtoField.string("ndn.canbeprefix", "CanBePrefix") , value = getTrue},
188 [18] = {name = "MustBeFresh" , field = ProtoField.string("ndn.mustbefresh", "MustBeFresh") , value = getTrue},
189 -- [30] = {name = "ForwardingHint" , summary = true},
190 -- ForwardingHint and LinkPreference have the same TLV-TYPE number, so we can't recognize both for now (see #4185).
191 [31] = {name = "LinkDelegation" , summary = true},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000192 [30] = {name = "LinkPreference" , field = ProtoField.uint64("ndn.link_preference", "LinkPreference", base.DEC) , value = getNonNegativeInteger},
Junxiao Shi5e384792016-11-24 03:59:06 +0000193 [10] = {name = "Nonce" , field = ProtoField.uint32("ndn.nonce", "Nonce", base.HEX) , value = getNonce},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000194 [12] = {name = "InterestLifetime" , field = ProtoField.uint64("ndn.interestlifetime", "InterestLifetime", base.DEC) , value = getNonNegativeInteger},
195 [34] = {name = "HopLimit" , field = ProtoField.uint64("ndn.hoplimit", "HopLimit", base.DEC) , value = getNonNegativeInteger},
Davide Pesavento252b7072019-02-10 20:02:14 -0500196 [36] = {name = "Parameters" , field = ProtoField.string("ndn.parameters", "Parameters")},
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700197
Junxiao Shiac4b5462018-04-17 02:26:17 +0000198 -- Data and its sub-elements in Packet Format v0.3
199 [6] = {name = "Data" , summary = true},
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700200 [20] = {name = "MetaInfo" , summary = true},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000201 [24] = {name = "ContentType" , field = ProtoField.uint64("ndn.contenttype", "Content Type", base.DEC) , value = getNonNegativeInteger},
202 [25] = {name = "FreshnessPeriod" , field = ProtoField.uint64("ndn.freshnessperiod", "FreshnessPeriod", base.DEC) , value = getNonNegativeInteger},
Junxiao Shic687af62018-05-06 21:58:09 +0000203 [26] = {name = "FinalBlockId" , field = ProtoField.string("ndn.finalblockid", "FinalBlockId") , value = getUriFromFinalBlockId},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000204 [21] = {name = "Content" , field = ProtoField.string("ndn.content", "Content")},
205 [22] = {name = "SignatureInfo" , summary = true},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000206 [27] = {name = "SignatureType" , field = ProtoField.uint64("ndn.signaturetype", "SignatureType", base.DEC) , value = getNonNegativeInteger},
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700207 [28] = {name = "KeyLocator" , summary = true},
208 [29] = {name = "KeyDigest" , field = ProtoField.bytes("ndn.keydigest", "KeyDigest")},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000209 [23] = {name = "SignatureValue" , field = ProtoField.bytes("ndn.signaturevalue", "SignatureValue")},
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700210
Junxiao Shiac4b5462018-04-17 02:26:17 +0000211 -- NDNLPv2 headers
Zipeng Wang574eeb02016-10-05 21:46:02 -0700212 [80] = {name = "Fragment" },
Junxiao Shi89db73c2018-05-27 15:22:49 +0000213 [81] = {name = "Sequence" , field = ProtoField.uint64("ndn.sequence", "Sequence", base.DEC) , value = getNonNegativeInteger},
214 [82] = {name = "FragIndex" , field = ProtoField.uint64("ndn.fragindex", "FragIndex", base.DEC) , value = getNonNegativeInteger},
215 [83] = {name = "FragCount" , field = ProtoField.uint64("ndn.fragcount", "FragCount", base.DEC) , value = getNonNegativeInteger},
216 [98] = {name = "PitToken" , field = ProtoField.uint64("ndn.pit_token", "PitToken", base.DEC) , value = getNonNegativeInteger},
Zipeng Wang574eeb02016-10-05 21:46:02 -0700217 [100] = {name = "LpPacket" , summary = true},
218 [800] = {name = "Nack" , summary = true},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000219 [801] = {name = "NackReason" , field = ProtoField.string("ndn.nack_reason", "NackReason") , value = getNackReasonDetail},
220 [816] = {name = "NextHopFaceId" , field = ProtoField.uint64("ndn.nexthop_faceid", "NextHopFaceId", base.DEC) , value = getNonNegativeInteger},
221 [817] = {name = "IncomingFaceId" , field = ProtoField.uint64("ndn.incoming_faceid", "IncomingFaceId", base.DEC) , value = getNonNegativeInteger},
Zipeng Wang574eeb02016-10-05 21:46:02 -0700222 [820] = {name = "CachePolicy" , summary = true},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000223 [821] = {name = "CachePolicyType" , field = ProtoField.string("ndn.cachepolicy_type", "CachePolicyType") , value = getCachePolicyDetail},
224 [832] = {name = "CongestionMark" , field = ProtoField.uint64("ndn.congestion_mark", "CongestionMark", base.DEC) , value = getNonNegativeInteger},
225 [836] = {name = "Ack" , field = ProtoField.uint64("ndn.ack", "Ack", base.DEC) , value = getNonNegativeInteger},
226 [840] = {name = "TxSequence" , field = ProtoField.uint64("ndn.tx_sequence", "TxSequence", base.DEC) , value = getNonNegativeInteger},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000227
228 -- Deprecated elements
229 [9] = {name = "Selectors" , summary = true},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000230 [13] = {name = "MinSuffixComponents" , field = ProtoField.uint64("ndn.minsuffix", "MinSuffixComponents") , value = getNonNegativeInteger},
231 [14] = {name = "MaxSuffixComponents" , field = ProtoField.uint64("ndn.maxsuffix", "MaxSuffixComponents") , value = getNonNegativeInteger},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000232 [15] = {name = "PublisherPublicKeyLocator" , summary = true},
233 [16] = {name = "Exclude" , field = ProtoField.string("ndn.exclude", "Exclude") , value = getUriFromExclude},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000234 [17] = {name = "ChildSelector" , field = ProtoField.uint64("ndn.childselector", "ChildSelector", base.DEC) , value = getNonNegativeInteger},
Junxiao Shiac4b5462018-04-17 02:26:17 +0000235 [19] = {name = "Any" , field = ProtoField.string("ndn.any", "Any") , value = getTrue},
Junxiao Shi89db73c2018-05-27 15:22:49 +0000236 [32] = {name = "SelectedDelegation" , field = ProtoField.uint64("ndn.selected_delegation", "SelectedDelegation", base.DEC), value = getNonNegativeInteger},
Zipeng Wang574eeb02016-10-05 21:46:02 -0700237}
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700238
239-- -- Add protofields in NDN protocol
240ndn.fields = {
241}
242for key, value in pairs(NDN_DICT) do
243 table.insert(ndn.fields, value.field)
244end
245
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700246-----------------------------------------------------
247-----------------------------------------------------
248
249-- block
250-- .tvb
251-- .offset
252-- .type
253-- .typeLen
254-- .length
255-- .lengthLen
256-- .size = .typeLen + .lengthLen + .length
257
258function addInfo(block, root) -- may be add additional context later
259 local info = NDN_DICT[block.type]
260
261 if (info == nil) then
262 info = {}
263 info.value = getGenericBlockInfo
Zipeng Wang574eeb02016-10-05 21:46:02 -0700264 -- color
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700265 end
266
267 local treeInfo
268 if (info.value == nil) then
269
270 if (info.field ~= nil) then
271 treeInfo = root:add(info.field, block.tvb(block.offset, block.size))
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700272 else
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700273 treeInfo = root:add(block.tvb(block.offset, block.size), info.name)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700274 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700275
276 treeInfo:append_text(", Type: " .. block.type .. ", Length: " .. block.length)
277 else
278 block.value = info.value(block)
279
280 if (info.field ~= nil) then
281 treeInfo = root:add(info.field, block.tvb(block.offset, block.size), block.value)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700282 else
Zipeng Wang574eeb02016-10-05 21:46:02 -0700283 treeInfo = root:add(block.tvb(block.offset, block.size), block.value)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700284 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700285 end
286 block.root = treeInfo
287 return block.root
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700288end
289
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700290function addSummary(block)
291 if (block.elements == nil) then
292 return
293 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700294
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700295 local info = NDN_DICT[block.type]
296 if (info == nil or info.summary == nil) then
297 return
298 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700299
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700300 local summary = {}
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700301
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700302 for k, subblock in pairs(block.elements) do
303 if (subblock.value ~= nil) then
304 local info = NDN_DICT[subblock.type]
305 if (info ~= nil) then
306 table.insert(summary, info.name .. ": " .. subblock.value)
307 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700308 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700309 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700310
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700311 if (#summary > 0) then
312 block.summary = table.concat(summary, ", ")
313 if (block.value == nil) then
314 block.value = block.summary
315 end
316 block.root:append_text(", " .. block.summary)
317 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700318end
319
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700320-----------------------------------------------------
321-----------------------------------------------------
322
323function readVarNumber(tvb, offset)
Junxiao Shie65c6d72016-07-24 21:53:19 +0000324 if offset >= tvb:len() then
325 return 0, 0
326 end
327
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700328 local firstOctet = tvb(offset, 1):uint()
329 if (firstOctet < 253) then
330 return firstOctet, 1
Junxiao Shie65c6d72016-07-24 21:53:19 +0000331 elseif (firstOctet == 253) and (offset + 3 < tvb:len()) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700332 return tvb(offset + 1, 2):uint(), 3
Junxiao Shie65c6d72016-07-24 21:53:19 +0000333 elseif (firstOctet == 254) and (offset + 5 < tvb:len()) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700334 return tvb(offset + 1, 4):uint(), 5
Junxiao Shie65c6d72016-07-24 21:53:19 +0000335 elseif (firstOctet == 255) and (offset + 9 < tvb:len()) then
336 return tvb(offset + 1, 8):uint64(), 9
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700337 end
Junxiao Shie65c6d72016-07-24 21:53:19 +0000338
339 return 0, 0
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700340end
341
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700342function getBlock(tvb, offset)
343 local block = {}
344 block.tvb = tvb
345 block.offset = offset
346
347 block.type, block.typeLen = readVarNumber(block.tvb, block.offset)
Junxiao Shie65c6d72016-07-24 21:53:19 +0000348 if block.typeLen == 0 then
349 return nil
350 end
351
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700352 block.length, block.lengthLen = readVarNumber(block.tvb, block.offset + block.typeLen)
Junxiao Shie65c6d72016-07-24 21:53:19 +0000353 if block.lengthLen == 0 then
354 return nil
355 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700356
357 block.size = block.typeLen + block.lengthLen + block.length
358
359 return block
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700360end
361
Alexander Afanasyev7f43c532015-08-12 15:28:51 -0700362function canBeValidNdnPacket(block)
Zipeng Wang574eeb02016-10-05 21:46:02 -0700363 if ((block.type == 5 or block.type == 6 or block.type == 100) and block.length <= 8800) then
Alexander Afanasyev7f43c532015-08-12 15:28:51 -0700364 return true
365 else
366 return false
367 end
368end
369
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700370function findNdnPacket(tvb)
371 offset = 0
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700372
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700373 while offset + 2 < tvb:len() do
374 local block = getBlock(tvb, offset)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700375
Junxiao Shie65c6d72016-07-24 21:53:19 +0000376 if (block ~= nil) and canBeValidNdnPacket(block) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700377 return block
378 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700379
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700380 offset = offset + 1
381 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700382
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700383 return nil
384end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700385
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700386function getSubBlocks(block)
387 local valueLeft = block.length
388 local subBlocks = {}
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700389
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700390 while valueLeft > 0 do
Junxiao Shie65c6d72016-07-24 21:53:19 +0000391 local offset = block.offset + block.typeLen + block.lengthLen + (block.length - valueLeft)
392 local child = getBlock(block.tvb, offset)
393 if child == nil then
394 return nil
395 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700396
397 valueLeft = valueLeft - child.size
398 table.insert(subBlocks, child)
399 end
400
401 if (valueLeft == 0) then
402 return subBlocks
403 else
404 return nil
405 end
406end
407
408-----------------------------------------------------
409-----------------------------------------------------
410
411-- NDN protocol dissector function
412function ndn.dissector(tvb, pInfo, root) -- Tvb, Pinfo, TreeItem
413
414 if (tvb:len() ~= tvb:reported_len()) then
415 return 0 -- ignore partially captured packets
416 -- this can/may be re-enabled only for unfragmented UDP packets
417 end
418
419 local ok, block = pcall(findNdnPacket, tvb)
420 if (not ok) then
421 return 0
422 end
423
424 if (block == nil or block.offset == nil) then
425 -- no valid NDN packets found
426 return 0
427 end
428
429 local nBytesLeft = tvb:len() - block.offset
430 -- print (pInfo.number .. ":: Found block: " .. block.type .. " of length " .. block.size .. " bytesLeft: " .. nBytesLeft)
431
Junxiao Shi1fda67d2018-01-12 21:35:31 +0000432 local pktType = ""
433 local pktName = ""
434
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700435 while (block.size <= nBytesLeft) do
436 -- Create TreeItems
437 block.tree = root:add(ndn, tvb(block.offset, block.size))
438
439 local queue = {block}
440 while (#queue > 0) do
441 local block = queue[1]
442 table.remove(queue, 1)
443
444 block.elements = getSubBlocks(block)
445 local subtree = addInfo(block, block.tree)
446
447 if (block.elements ~= nil) then
448 for i, subBlock in pairs(block.elements) do
449 subBlock.tree = subtree
450 table.insert(queue, subBlock)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700451 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700452 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700453 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700454
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700455 -- Make summaries
456 local queue = {block}
457 while (#queue > 0) do
458 local block = queue[1]
459 if (block.visited ~= nil or block.elements == nil) then
460 -- try to make summary
461 table.remove(queue, 1)
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700462
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700463 addSummary(block)
464 else
465 for i, subBlock in pairs(block.elements) do
466 table.insert(queue, 1, subBlock)
467 end
468 block.visited = true
469 end
Junxiao Shi1fda67d2018-01-12 21:35:31 +0000470
471 -- prepare information to fill info column
472 if block.type == 5 and pktType ~= "Nack" then
473 pktType = "Interest"
474 elseif block.type == 6 then
475 pktType = "Data"
476 elseif block.type == 800 then
477 pktType = "Nack"
478 end
479
Alexander Afanasyev4fb67ea2018-08-02 08:18:28 -0600480 if block.type == 7 then
Junxiao Shi1fda67d2018-01-12 21:35:31 +0000481 pktName = getUriFromName(block)
482 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700483 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700484
485 local info = NDN_DICT[block.type]
486 if (info ~= nil) then
Zipeng Wang574eeb02016-10-05 21:46:02 -0700487 if (block.summary ~= nil) then
488 block.tree:append_text(", " .. NDN_DICT[block.type].name .. ", " .. block.summary)
489 else
490 block.tree:append_text(", " .. NDN_DICT[block.type].name)
491 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700492 end
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700493
494 nBytesLeft = nBytesLeft - block.size
495
496 if (nBytesLeft > 0) then
497 ok, block = pcall(getBlock, tvb, tvb:len() - nBytesLeft)
Zipeng Wang574eeb02016-10-05 21:46:02 -0700498 if (not ok or block == nil or not canBeValidNdnPacket(block)) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700499 break
500 end
501 end
Zipeng Wang574eeb02016-10-05 21:46:02 -0700502 end -- while(block.size <= nBytesLeft)
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700503
504 pInfo.cols.protocol = tostring(pInfo.cols.protocol) .. " (" .. ndn.name .. ")"
Junxiao Shi1fda67d2018-01-12 21:35:31 +0000505 pInfo.cols.info = pktType .. " " .. pktName
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700506
Alexander Afanasyev7f43c532015-08-12 15:28:51 -0700507 if (nBytesLeft > 0 and block ~= nil and block.size ~= nil and block.size > nBytesLeft) then
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700508 pInfo.desegment_offset = tvb:len() - nBytesLeft
509
510 -- Originally, I set desegment_len to the exact lenght, but it mysteriously didn't work for TCP
511 -- pInfo.desegment_len = block.size -- this will not work to desegment TCP streams
512 pInfo.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
513 end
Alexander Afanasyev6fbb7b42015-08-10 11:53:49 -0700514end
515
Alexander Afanasyev357c2052015-08-10 21:26:52 -0700516local udpDissectorTable = DissectorTable.get("udp.port")
517udpDissectorTable:add("6363", ndn)
518udpDissectorTable:add("56363", ndn)
519
520local tcpDissectorTable = DissectorTable.get("tcp.port")
521tcpDissectorTable:add("6363", ndn)
522
523local websocketDissectorTable = DissectorTable.get("ws.port")
524-- websocketDissectorTable:add("9696", ndn)
525websocketDissectorTable:add("1-65535", ndn)
526
Alexander Afanasyev7f43c532015-08-12 15:28:51 -0700527local ethernetDissectorTable = DissectorTable.get("ethertype")
528ethernetDissectorTable:add(0x8624, ndn)
529
Alexander Afanasyev4fb67ea2018-08-02 08:18:28 -0600530local pppDissectorTable = DissectorTable.get("ppp.protocol")
531pppDissectorTable:add(0x0077, ndn)
532
Junxiao Shiac4b5462018-04-17 02:26:17 +0000533io.stderr:write("NDN dissector successfully loaded\n")