51 lines
1.3 KiB
Ruby
51 lines
1.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative 'proto_type'
|
|
require_relative 'arp_client'
|
|
require_relative 'interface_list'
|
|
|
|
require 'packetfu'
|
|
require_relative 'route'
|
|
|
|
# IPv4 layer implementation
|
|
module IPv4Layer
|
|
@handlers = {}
|
|
@ips = ['255.255.255.255']
|
|
@logger = Logger.new(STDOUT, progname: "ipv4", level: Logger::DEBUG)
|
|
|
|
def self.add_iface(iface)
|
|
iface.eth_device.register_handler(ProtoType::Ethernet::IPV4, self)
|
|
end
|
|
|
|
def self.add_ip(ip)
|
|
@ips.push ip
|
|
end
|
|
|
|
def self.del_ip(ip)
|
|
@ips.delete ip
|
|
end
|
|
|
|
def self.got_packet(packet)
|
|
dest = packet.ip_daddr
|
|
return unless @ips.include? dest
|
|
@logger.debug("Rcv: #{packet.peek}")
|
|
|
|
proto = packet.ip_proto
|
|
@handlers[[dest, proto]]&.each { _1.got_packet(packet)}
|
|
@handlers[['0.0.0.0', proto]]&.each { _1.got_packet(packet)}
|
|
end
|
|
|
|
def self.send_packet(packet)
|
|
route = Route.get_send_route(packet.ip_daddr)
|
|
packet.ip_saddr = route[:iface].ip
|
|
@logger.debug("Snd: #{packet.peek} out if #{route[:iface].name} using gw #{route[:gw] || 'None'}")
|
|
route[:iface].arp_device.send_packet(packet, route[:gw])
|
|
end
|
|
|
|
# :reek:DuplicateMethodCall
|
|
def self.register_handler(ip, type, handler)
|
|
@handlers[[ip, type]] = [] unless @handlers[type]
|
|
@handlers[[ip, type]].push handler
|
|
end
|
|
end
|