forked from sbyx/hnetd
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhnetd_wireshark.lua
More file actions
175 lines (157 loc) · 5.15 KB
/
hnetd_wireshark.lua
File metadata and controls
175 lines (157 loc) · 5.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
-- -*-lua-*-
--
-- $Id: hnetd_wireshark.lua $
--
-- Author: Markus Stenberg <mstenber@cisco.com>
--
-- Copyright (c) 2013 cisco Systems, Inc.
--
-- Created: Tue Dec 3 11:13:05 2013 mstenber
-- Last modified: Sat Jul 14 08:36:53 2018 mstenber
-- Edit time: 123 min
--
-- This is Lua module which provides VERY basic dissector for TLVs we
-- transmit.
-- Usage: wireshark -X lua_script:hnetd_wireshark.lua
p_hncp = Proto("hncp", "Homenet Control Protocol")
local f_id = ProtoField.uint16('hncp.id', 'TLV id')
local f_len = ProtoField.uint16('hncp.len', 'TLV len')
local f_data = ProtoField.bytes('hncp.data', 'TLV data')
local f_nid_hash = ProtoField.bytes('hncp.node_identifier_hash',
'Node identifier')
local f_data_hash = ProtoField.bytes('hncp.data_hash',
'Node data hash')
local f_network_hash = ProtoField.bytes('hncp.network_hash',
'Network state hash')
local f_lid = ProtoField.uint32('hncp.llid', 'Local link identifier')
local f_rlid = ProtoField.uint32('hncp.rlid', 'Remote link identifier')
local f_upd = ProtoField.uint32('hncp.update_number', 'Update number')
local f_ms = ProtoField.uint32('hncp.ms_since_origination',
'Time since origination (ms)')
local f_interval_ms = ProtoField.uint32('hncp.keepalive_interval',
'Keep-alive interval (ms)')
p_hncp.fields = {f_id, f_len, f_data,
f_nid_hash, f_data_hash, f_network_hash,
f_lid, f_rlid, f_upd, f_ms, f_interval_ms}
local tlvs = {
-- dncp content
[1]={name='req-net-state'},
[2]={name='req-node-state',
contents={{4, f_nid_hash}},
},
[3]={name='endpoint-id',
contents={{4, f_nid_hash},
{4, f_lid}},
},
[4]={name='net-state',
contents={{8, f_network_hash}}},
[5]={name='node-state',
contents={{4, f_nid_hash},
{4, f_upd},
{4, f_ms},
{8, f_data_hash},
},
recurse=true
},
-- historic never deployed [6]={name='custom'},
-- historic never deployed [7]={name='fragment-count'},
[8]={name='neighbor', contents={{4, f_nid_hash},
{4, f_rlid},
{4, f_lid},
},
},
[9]={name='keepalive-interval', contents={{4, f_lid},
{4, f_interval_ms}},
},
[10]={name='trust-verdict'},
-- hncp content
[32]={name='version'},
[33]={name='external-connection', contents={}, recurse=true},
[34]={name='delegated-prefix'},
[35]={name='assigned-prefix'},
[36]={name='router-address'},
[37]={name='dhcpv4-options'},
[38]={name='dhcpv6-options'},
[39]={name='dns-delegated-zone'},
[40]={name='dns-domain-name'},
[41]={name='dns-node-name'},
[42]={name='managed-psk'},
[43]={name='prefix-policy'},
-- does not seem to exist anymore in the wild:
-- [199]={name='routing-protocol'},
}
function p_hncp.dissector(buffer, pinfo, tree)
pinfo.cols.protocol = 'hncp'
local rec_decode
local function data_decode(ofs, left, tlv, tree)
for i, v in ipairs(tlv.contents)
do
local elen, ef = unpack(v)
if elen > left
then
tree:append_text(string.format(' (!!! missing data - %d > %d (%s))',
elen, left, v))
return
end
tree:add(ef, buffer(ofs, elen))
left = left - elen
ofs = ofs + elen
end
if tlv.recurse
then
rec_decode(ofs, left, tree)
end
end
rec_decode = function (ofs, left, tree)
if left < 4
then
return
end
local partial
local rid = buffer(ofs, 2)
local rlen = buffer(ofs+2, 2)
local id = rid:uint()
local len = rlen:uint()
local bs = ''
local ps = ''
local tlv = tlvs[id] or {}
if tlv.name
then
bs = ' (' .. tlv.name .. ')'
end
if (len + 4) > left
then
len = left - 4
ps = ' (partial)'
partial = true
end
local tree2 = tree:add(buffer(ofs, len + 4),
string.format('TLV %d%s - %d value bytes%s',
id, bs, len, ps))
if partial
then
return
end
local fid = tree2:add(f_id, rid)
fid:append_text(bs)
local flen = tree2:add(f_len, rlen)
if len > 0
then
local fdata = tree2:add(f_data, buffer(ofs + 4, len))
if tlv.contents
then
-- skip the tlv header (that's why +- 4)
data_decode(ofs + 4, len, tlv, fdata)
end
end
-- recursively decode the rest too, hrr :)
-- (note that we have to round it up to next /4 boundary; stupid
-- alignment..)
len = math.floor((len + 3)/4) * 4
rec_decode(ofs + len + 4, left - len - 4, tree)
end
rec_decode(0, buffer:len(), tree:add(p_hncp, buffer()))
end
-- register as udp dissector
udp_table = DissectorTable.get("udp.port")
udp_table:add(8231, p_hncp)