Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/proto/kademlia/bootstrap_response.rb
Views: 11704
# -*- coding: binary -*-123module Rex4module Proto5module Kademlia6# Opcode for a bootstrap response7BOOTSTRAP_RESPONSE = 0x0989# A Kademlia bootstrap response message10class BootstrapResponse < Message11# @return [String] the ID of the peer that send the bootstrap response12attr_reader :peer_id13# @return [Integer] the TCP port that the responding peer is listening on14attr_reader :tcp_port15# @return [Integer] the version of this peer16attr_reader :version17# @return [Array<Hash<String, Object>>] the peer ID, IP address, UDP/TCP ports and version of each peer18attr_reader :peers1920# Constructs a new bootstrap response21#22# @param peer_id [String] the ID of this peer23# @param tcp_port [Integer] the TCP port that this peer is listening on24# @param version [Integer] the version of this peer25# @param peers [Array<Hash<String, Object>>] the peer ID, IP address, UDP/TCP ports and version of each peer26def initialize(peer_id, tcp_port, version, peers)27@peer_id = peer_id28@tcp_port = tcp_port29@version = version30@peers = peers31end3233# The minimum size of a peer in a KADEMLIA2_BOOTSTRAP_RES message:34# peer ID (16-bytes), IP (4 bytes), UDP port (2 bytes), TCP port (2 bytes)35# and version (1 byte)36BOOTSTRAP_PEER_SIZE = 253738# Builds a bootstrap response from given data39#40# @param data [String] the data to decode41# @return [BootstrapResponse] the bootstrap response if the data is valid, nil otherwise42def self.from_data(data)43message = Message.from_data(data)44# abort if this isn't a valid response45return unless message46return unless message.type == BOOTSTRAP_RESPONSE47return unless message.body.size >= 2348bootstrap_peer_id = Rex::Proto::Kademlia.decode_peer_id(message.body.slice!(0, 16))49bootstrap_tcp_port, bootstrap_version, num_peers = message.body.slice!(0, 5).unpack('vCv')50# protocol says there are no peers and the body confirms this, so just return with no peers51if num_peers == 0 && message.body.to_s.strip.empty?52peers = []53else54peers_data = message.body55# peers data is too long/short, abort56return if peers_data.size % BOOTSTRAP_PEER_SIZE != 057peers = []58until peers_data.to_s.strip.empty?59peer_data = peers_data.slice!(0, BOOTSTRAP_PEER_SIZE)60peer_id = Rex::Proto::Kademlia.decode_peer_id(peer_data.slice!(0, 16))61ip, udp_port, tcp_port, version = peer_data.unpack('VvvC')62peers << {63id: peer_id,64ip: Rex::Socket.addr_itoa(ip),65tcp_port: tcp_port,66udp_port: udp_port,67version: version68}69end70end71BootstrapResponse.new(bootstrap_peer_id, bootstrap_tcp_port, bootstrap_version, peers)72end73end74end75end76end777879