1-- (C) 2019 - ntop.org and contributors
2
3n2n = Proto("n2n", "n2n Protocol")
4
5-- #############################################
6
7PKT_TYPE_PING               = 0
8PKT_TYPE_REGISTER           = 1
9PKT_TYPE_DEREGISTER         = 2
10PKT_TYPE_PACKET             = 3
11PKT_TYPE_REGISTER_ACK       = 4
12PKT_TYPE_REGISTER_SUPER     = 5
13PKT_TYPE_REGISTER_SUPER_ACK = 6
14PKT_TYPE_REGISTER_SUPER_NAK = 7
15PKT_TYPE_FEDERATION         = 8
16PKT_TYPE_PEER_INFO          = 9
17PKT_TYPE_QUERY_PEER         = 10
18
19PKT_TRANSFORM_NULL      = 1
20PKT_TRANSFORM_TWOFISH   = 2
21PKT_TRANSFORM_AESCBC    = 3
22
23FLAG_FROM_SUPERNODE   = 0x0020
24FLAG_SOCKET           = 0x0040
25FLAG_OPTIONS          = 0x0080
26
27SOCKET_FAMILY_AF_INET  = 0x0000
28SOCKET_FAMILY_AF_INET6 = 0x8000
29
30-- #############################################
31
32version = ProtoField.uint8("n2n.version", "version", base.DEC)
33ttl = ProtoField.uint8("n2n.ttl", "ttl", base.DEC)
34
35packet_type_mask = 0x001f
36pkt_type_2_str = {
37  [PKT_TYPE_PING] = "ping",
38  [PKT_TYPE_REGISTER] = "register",
39  [PKT_TYPE_DEREGISTER] = "deregister",
40  [PKT_TYPE_PACKET] = "packet",
41  [PKT_TYPE_REGISTER_ACK] = "register_ack",
42  [PKT_TYPE_REGISTER_SUPER] = "register_super",
43  [PKT_TYPE_REGISTER_SUPER_ACK] = "register_super_ack",
44  [PKT_TYPE_REGISTER_SUPER_NAK] = "register_super_nak",
45  [PKT_TYPE_FEDERATION] = "federation",
46  [PKT_TYPE_PEER_INFO] = "peer_info",
47  [PKT_TYPE_QUERY_PEER] = "query_peer",
48}
49packet_type = ProtoField.uint8("n2n.packet_type", "packetType", base.HEX, pkt_type_2_str, packet_type_mask)
50
51flags_mask = 0xffe0
52flags = ProtoField.uint16("n2n.flags", "Flags", base.HEX, nil, flags_mask)
53from_supernode_flag = ProtoField.uint16("n2n.flags.from_supernode", "from_supernode", base.BOOLEAN, nil, FLAG_FROM_SUPERNODE)
54socket_flag = ProtoField.uint16("n2n.flags.socket", "socket", base.BOOLEAN, nil, FLAG_SOCKET)
55options_flag = ProtoField.uint16("n2n.flags.options", "options", base.BOOLEAN, nil, FLAG_OPTIONS)
56community = ProtoField.string("n2n.community", "Community", base.ASCII)
57
58-- #############################################
59
60src_mac = ProtoField.ether("n2n.src_mac", "Source")
61dst_mac = ProtoField.ether("n2n.dst_mac", "Destination")
62socket_info = ProtoField.none("n2n.socket", "Socket Info")
63socket_family = ProtoField.uint16("n2n.socket.family", "Family", base.HEX, {
64  [0] = "AF_INET",
65})
66socket_port = ProtoField.uint16("n2n.socket.port", "Port")
67socket_ipv4 = ProtoField.ipv4("n2n.socket.ipv4", "IPv4")
68socket_ipv6 = ProtoField.ipv6("n2n.socket.ipv6", "IPv6")
69
70-- #############################################
71
72peer_info_field = ProtoField.none("n2n.peer_info", "PeerInfo")
73peer_info_flags = ProtoField.uint16("n2n.peer_info.flags", "Flags")
74peer_info_mac = ProtoField.ether("n2n.peer_info.query_mac", "Query")
75
76query_peer_field = ProtoField.none("n2n.query_peer", "QueryPeer")
77
78-- #############################################
79
80
81
82packet_field = ProtoField.none("n2n.packet", "Packet")
83packet_transform = ProtoField.uint16("n2n.packet.transform", "Transform", base.HEX, {
84  [PKT_TRANSFORM_NULL] = "Plaintext",
85  [PKT_TRANSFORM_TWOFISH] = "TwoFish",
86  [PKT_TRANSFORM_AESCBC] = "AES CBC",
87})
88packet_payload = ProtoField.bytes("n2n.packet.payload", "Payload")
89
90-- #############################################
91
92register_field = ProtoField.none("n2n.register", "Register")
93register_cookie = ProtoField.uint32("n2n.register.cookie", "Cookie", base.HEX)
94
95register_ack_field = ProtoField.none("n2n.register_ack", "RegisterACK")
96register_ack_cookie = ProtoField.uint32("n2n.register_ack.cookie", "Cookie", base.HEX)
97
98register_super_field = ProtoField.none("n2n.register_super", "RegisterSuper")
99register_super_cookie = ProtoField.uint32("n2n.register_super.cookie", "Cookie", base.HEX)
100register_super_auth_schema = ProtoField.uint16("n2n.register_super.auth.schema", "AuthSchema", base.HEX)
101register_super_auth_data = ProtoField.uint16("n2n.register_super.auth.data", "AuthData", base.HEX)
102
103register_super_ack_field = ProtoField.none("n2n.register_super_ack", "RegisterSuperACK")
104register_super_ack_cookie = ProtoField.uint32("n2n.register_super_ack.cookie", "Cookie", base.HEX)
105register_super_ack_lifetime = ProtoField.uint16("n2n.register_super_ack.lifetime", "Registration Lifetime", base.DEC)
106register_super_ack_num_sn = ProtoField.uint8("n2n.register_super_ack.num_sn", "Num Supernodes", base.DEC)
107
108-- #############################################
109
110n2n.fields = {
111  version, ttl, packet_type,
112  flags, from_supernode_flag, socket_flag, options_flag,
113  community,
114
115  -- Generic
116  src_mac, dst_mac,
117  socket_info, socket_family, socket_port, socket_ipv4, socket_ipv6,
118
119  -- PKT_TYPE_REGISTER
120  register_field, register_cookie,
121  -- PKT_TYPE_PACKET
122  packet_field, packet_transform, packet_payload,
123  -- PKT_TYPE_REGISTER_ACK
124  register_ack_field, register_ack_cookie,
125  -- PKT_TYPE_REGISTER_SUPER
126  register_super_field, register_super_cookie, register_super_auth_schema, register_super_auth_data,
127  -- PKT_TYPE_REGISTER_SUPER_ACK
128  register_super_ack_field, register_super_ack_cookie, register_super_ack_lifetime, register_super_ack_num_sn,
129  -- PKT_TYPE_PEER_INFO
130  peer_info_field, peer_info_flags, peer_info_mac,
131  -- PKT_TYPE_QUERY_PEER
132  query_peer_field,
133}
134
135-- #############################################
136
137function dissect_socket(subtree, buffer, offset)
138  local sock_baselen = 4
139  local sock_protolen = 0
140  buffer = buffer(offset)
141  local sock_family = bit.band(buffer(0,4):uint(), 0xFFFF0000)
142
143  if(sock_family == SOCKET_FAMILY_AF_INET) then
144    sock_protolen = 4
145  elseif(sock_family == SOCKET_FAMILY_AF_INET6) then
146    sock_protolen = 16
147  end
148
149  local totlen = sock_baselen + sock_protolen
150  local socktree = subtree:add(socket_info, buffer(0, totlen))
151
152  socktree:add(socket_family, buffer(0, 2))
153  socktree:add(socket_port, buffer(2, 2))
154
155  if(sock_family == SOCKET_FAMILY_AF_INET) then
156    socktree:add(socket_ipv4, buffer(4, sock_protolen))
157  elseif(sock_family == SOCKET_FAMILY_AF_INET6) then
158    socktree:add(socket_ipv6, buffer(4, sock_protolen))
159  end
160
161  return offset+totlen, socktree
162end
163
164-- #############################################
165
166function dissect_register(subtree, buffer, flags)
167  local regtree = subtree:add(register_field, buffer)
168
169  regtree:add(register_cookie, buffer(0,4))
170  regtree:add(src_mac, buffer(4,6))
171  regtree:add(dst_mac, buffer(10,6))
172
173  if(bit.band(flags, FLAG_SOCKET) == FLAG_SOCKET) then
174    dissect_socket(regtree, buffer, 16)
175  end
176
177  return regtree
178end
179
180-- #############################################
181
182function dissect_register_ack(subtree, buffer, flags)
183  local regtree = subtree:add(register_ack_field, buffer)
184
185  regtree:add(register_ack_cookie, buffer(0,4))
186  regtree:add(src_mac, buffer(4,6))
187  regtree:add(dst_mac, buffer(10,6))
188
189  return regtree
190end
191
192-- #############################################
193
194function dissect_packet(subtree, buffer, flags, pinfo)
195  local pktree = subtree:add(packet_field, buffer)
196
197  pktree:add(src_mac, buffer(0,6))
198  pktree:add(dst_mac, buffer(6,6))
199
200  if(bit.band(flags, FLAG_SOCKET) == FLAG_SOCKET) then
201    idx = dissect_socket(pktree, buffer, 12)
202  else
203    idx = 12
204  end
205
206  pktree:add(packet_transform, buffer(idx,2))
207  local payload = pktree:add(packet_payload, buffer(idx+2))
208  local transform = buffer(idx,2):uint()
209
210  -- Can only dissect unencrypted data
211  if(transform == PKT_TRANSFORM_NULL) then
212    Dissector.get("eth_withoutfcs"):call(buffer(idx+2):tvb(), pinfo, payload)
213  end
214
215  return pktree
216end
217
218-- #############################################
219
220function dissect_register_super(subtree, buffer, flags)
221  local regtree = subtree:add(register_super_field, buffer)
222
223  regtree:add(register_super_cookie, buffer(0,4))
224  regtree:add(src_mac, buffer(4,6))
225  regtree:add(register_super_auth_schema, buffer(10,2))
226  regtree:add(register_super_auth_data, buffer(12,2))
227
228  return regtree
229end
230
231-- #############################################
232
233function dissect_register_super_ack(subtree, buffer, flags)
234  local regtree = subtree:add(register_super_ack_field, buffer)
235
236  regtree:add(register_super_ack_cookie, buffer(0,4))
237  regtree:add(dst_mac, buffer(4,6))
238  regtree:add(register_super_ack_lifetime, buffer(10,2))
239  local idx = dissect_socket(regtree, buffer, 12)
240  regtree:add(register_super_ack_num_sn, buffer(idx, 1))
241
242  return regtree
243end
244
245-- #############################################
246
247function dissect_peer_info(subtree, buffer, flags)
248  local peertree = subtree:add(peer_info_field, buffer)
249
250  peertree:add(peer_info_flags, buffer(0,2))
251  peertree:add(peer_info_mac, buffer(2,6))
252  dissect_socket(peertree, buffer, 8)
253
254  return peertree
255end
256
257-- #############################################
258
259function dissect_query_peer(subtree, buffer, flags)
260  local peertree = subtree:add(query_peer_field, buffer)
261
262  peertree:add(src_mac, buffer(0,6))
263  peertree:add(dst_mac, buffer(6,6))
264
265  return peertree
266end
267
268-- #############################################
269
270function n2n.dissector(buffer, pinfo, tree)
271  local length = buffer:len()
272  if length < 20 then return end
273
274  pinfo.cols.protocol = n2n.name
275
276  local pkt_type = bit.band(buffer(2,2):uint(), packet_type_mask)
277  local subtree = tree:add(n2n, buffer(), string.format("n2n Protocol, Type: %s", pkt_type_2_str[pkt_type] or "Unknown"))
278
279  -- Common
280  subtree:add(version, buffer(0,1))
281  subtree:add(ttl, buffer(1,1))
282  subtree:add(packet_type, buffer(2,2))
283  local flags_buffer = buffer(2,2)
284  local flags_tree = subtree:add(flags, flags_buffer)
285  subtree:add(community, buffer(4,16))
286
287  -- Flags
288  flags_tree:add(from_supernode_flag, flags_buffer)
289  flags_tree:add(socket_flag, flags_buffer)
290  flags_tree:add(options_flag, flags_buffer)
291
292  -- Packet specific
293  local flags = bit.band(buffer(2,2):uint(), flags_mask)
294  local typebuf = buffer(20)
295
296  if(pkt_type == PKT_TYPE_REGISTER) then
297    dissect_register(subtree, typebuf, flags)
298  elseif(pkt_type == PKT_TYPE_REGISTER) then
299    dissect_register_ack(subtree, typebuf, flags)
300  elseif(pkt_type == PKT_TYPE_PACKET) then
301    dissect_packet(subtree, typebuf, flags, pinfo)
302  elseif(pkt_type == PKT_TYPE_REGISTER_SUPER) then
303    dissect_register_super(subtree, typebuf, flags)
304  elseif(pkt_type == PKT_TYPE_REGISTER_SUPER_ACK) then
305    dissect_register_super_ack(subtree, typebuf, flags)
306  elseif(pkt_type == PKT_TYPE_PEER_INFO) then
307    dissect_peer_info(subtree, typebuf, flags)
308  elseif(pkt_type == PKT_TYPE_QUERY_PEER) then
309    dissect_query_peer(subtree, typebuf, flags)
310  end
311end
312
313-- #############################################
314
315local udp_port = DissectorTable.get("udp.port")
316udp_port:add(50001, n2n)
317