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