CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/proto/kademlia/message.rb
Views: 11703
1
# -*- coding: binary -*-
2
3
module Rex
4
module Proto
5
##
6
#
7
# Minimal support for the newer Kademlia protocol, referred to here and often
8
# elsewhere as Kademlia2. It is unclear how this differs from the old protocol.
9
#
10
# Protocol details are hard to come by because most documentation is academic
11
# in nature and glosses over the low-level network details. The best
12
# documents I found on the protocol are:
13
#
14
# http://gbmaster.wordpress.com/2013/05/05/botnets-surrounding-us-an-initial-focus-on-kad/
15
# http://gbmaster.wordpress.com/2013/06/16/botnets-surrounding-us-sending-kademlia2_bootstrap_req-kademlia2_hello_req-and-their-strict-cousins/
16
# http://gbmaster.wordpress.com/2013/11/23/botnets-surrounding-us-performing-requests-sending-out-kademlia2_req-and-asking-contact-where-art-thou/
17
#
18
##
19
module Kademlia
20
# A simple Kademlia message
21
class Message
22
# The header that non-compressed Kad messages use
23
STANDARD_PACKET = 0xE4
24
# The header that compressed Kad messages use, which is currently unsupported
25
COMPRESSED_PACKET = 0xE5
26
27
# @return [Integer] the message type
28
attr_reader :type
29
# @return [String] the message body
30
attr_reader :body
31
32
# Construct a new Message from the provided type and body
33
#
34
# @param type [String] the message type
35
# @param body [String] the message body
36
def initialize(type, body = '')
37
@type = type
38
@body = body
39
end
40
41
# Construct a new Message from the provided data
42
#
43
# @param data [String] the data to interpret as a Kademlia message
44
# @return [Message] the message if valid, nil otherwise
45
def self.from_data(data)
46
return if data.length < 2
47
header, type = data.unpack('CC')
48
if header == COMPRESSED_PACKET
49
fail NotImplementedError, "Unable to handle #{data.length}-byte compressed Kademlia message"
50
end
51
return if header != STANDARD_PACKET
52
Message.new(type, data[2, data.length])
53
end
54
55
# Get this Message as a String
56
#
57
# @return [String] the string representation of this Message
58
def to_str
59
[STANDARD_PACKET, @type].pack('CC') + @body
60
end
61
62
# Compares this Message and another Message for equality
63
#
64
# @param other [Message] the Message to compare
65
# @return [Boolean] true iff the two messages have equal types and bodies, false otherwise
66
def ==(other)
67
type == other.type && body == other.body
68
end
69
end
70
end
71
end
72
end
73
74