Skip to content

Commit

Permalink
🧹
Browse files Browse the repository at this point in the history
  • Loading branch information
ydah committed Nov 5, 2024
1 parent 9295cbb commit 27157c1
Show file tree
Hide file tree
Showing 19 changed files with 128 additions and 109 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
/pkg/
/spec/reports/
/tmp/
Gemfile.lock
1 change: 0 additions & 1 deletion .ruby-version

This file was deleted.

4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

source "https://rubygems.org"
source 'https://rubygems.org'

gem "rake", "~> 13.0"
gem 'rake', '~> 13.0'
14 changes: 0 additions & 14 deletions Gemfile.lock

This file was deleted.

2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# frozen_string_literal: true

require "bundler/gem_tasks"
require 'bundler/gem_tasks'
task default: %i[]
4 changes: 2 additions & 2 deletions exe/redhound
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

$LOAD_PATH << File.join(__dir__, "../lib")
require "redhound"
$LOAD_PATH << File.join(__dir__, '../lib')
require 'redhound'

Redhound::Command.new.run(ARGV.dup)
14 changes: 7 additions & 7 deletions lib/redhound.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# frozen_string_literal: true

require_relative "redhound/analyzer"
require_relative "redhound/command"
require_relative "redhound/header"
require_relative "redhound/packet_mreq"
require_relative "redhound/receiver"
require_relative "redhound/socket_builder"
require_relative "redhound/version"
require_relative 'redhound/analyzer'
require_relative 'redhound/command'
require_relative 'redhound/header'
require_relative 'redhound/packet_mreq'
require_relative 'redhound/receiver'
require_relative 'redhound/socket_builder'
require_relative 'redhound/version'
25 changes: 13 additions & 12 deletions lib/redhound/analyzer.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Redhound
class Analyzer
def self.analyze(msg:)
Expand All @@ -9,20 +11,19 @@ def initialize(msg:)
end

def analyze
puts "Analyzing..."
puts 'Analyzing...'
ether = Header::Ether.generate(bytes: @msg.bytes[0..13])
pp ether
ether.dump
if ether.ipv4?
ip = Header::Ipv4.generate(bytes: @msg.bytes[14..33])
ip.dump
if ip.udp?
udp = Header::Udp.generate(bytes: @msg.bytes[34..41])
udp.dump
elsif ip.icmp?
icmp = Header::Icmp.generate(bytes: @msg.bytes[34..41])
icmp.dump
end
return unless ether.ipv4?

ip = Header::Ipv4.generate(bytes: @msg.bytes[14..33])
ip.dump
if ip.udp?
udp = Header::Udp.generate(bytes: @msg.bytes[34..41])
udp.dump
elsif ip.icmp?
icmp = Header::Icmp.generate(bytes: @msg.bytes[34..41])
icmp.dump
end
end
end
Expand Down
29 changes: 20 additions & 9 deletions lib/redhound/command.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
require "optparse"
require "socket"
# frozen_string_literal: true

require 'optparse'
require 'socket'

module Redhound
class Command
Expand All @@ -10,7 +12,7 @@ def initialize
def run(argv)
parse(argv)
if @options[:ifname].nil?
warn "Error: interface is required"
warn 'Error: interface is required'
exit 1
end
Receiver.run(ifname: @options[:ifname])
Expand All @@ -30,12 +32,21 @@ def parse(argv)
Usage: redhound [options] ...
BANNER2
o.separator ""
o.separator "Options:"
o.on("-i", "--interface INTERFACE", "name or idx of interface") { |v| @options[:ifname] = v }
o.on("-D", "--list-interfaces", "print list of interfaces and exit") { list_interfaces; exit }
o.on("-h", "--help", "display this help and exit") { puts o; exit }
o.on("-v", "--version", "display version information and exit") { puts "Redhound #{Redhound::VERSION}"; exit }
o.separator ''
o.separator 'Options:'
o.on('-i', '--interface INTERFACE', 'name or idx of interface') { |v| @options[:ifname] = v }
o.on('-D', '--list-interfaces', 'print list of interfaces and exit') do
list_interfaces
exit
end
o.on('-h', '--help', 'display this help and exit') do
puts o
exit
end
o.on('-v', '--version', 'display version information and exit') do
puts "Redhound #{Redhound::VERSION}"
exit
end
o.on_tail
o.parse!(argv)
end
Expand Down
10 changes: 6 additions & 4 deletions lib/redhound/header.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
require_relative "header/ether"
require_relative "header/icmp"
require_relative "header/ipv4"
require_relative "header/udp"
# frozen_string_literal: true

require_relative 'header/ether'
require_relative 'header/icmp'
require_relative 'header/ipv4'
require_relative 'header/udp'
15 changes: 9 additions & 6 deletions lib/redhound/header/ether.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Redhound
class Header
class Ether
Expand All @@ -11,6 +13,7 @@ def generate(bytes:)

def initialize(bytes:)
raise ArgumentError, 'bytes must be 14 bytes' unless bytes.size == 14

@bytes = bytes
end

Expand All @@ -27,7 +30,7 @@ def ipv4?
end

def dump
puts "ETHERNET HEADER----------------"
puts 'ETHERNET HEADER----------------'
puts self
end

Expand All @@ -40,25 +43,25 @@ def to_s
end

def dhost
@dhost.map { |b| b.to_s(16).rjust(2, "0") }.join(":")
@dhost.map { |b| b.to_s(16).rjust(2, '0') }.join(':')
end

def shost
@shost.map { |b| b.to_s(16).rjust(2, "0") }.join(":")
@shost.map { |b| b.to_s(16).rjust(2, '0') }.join(':')
end

def type
if ipv4?
"IPv4"
'IPv4'
else
"Unknown"
'Unknown'
end
end

private

def hex_type
@hex_type ||= @type.map { |b| b.to_s(16).rjust(2, "0") }.join.to_i(16)
@hex_type ||= @type.map { |b| b.to_s(16).rjust(2, '0') }.join.to_i(16)
end
end
end
Expand Down
21 changes: 12 additions & 9 deletions lib/redhound/header/icmp.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Redhound
class Header
class Icmp
Expand All @@ -9,6 +11,7 @@ def generate(bytes:)

def initialize(bytes:)
raise ArgumentError, 'bytes must be bigger than 8 bytes' unless bytes.size >= 8

@bytes = bytes
end

Expand All @@ -17,23 +20,23 @@ def generate
@code = @bytes[1]
@check = @bytes[2..3]
# refs: https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml#icmp-parameters-types
if @type == 0 || @type == 8
if @type.zero? || @type == 8
@id = @bytes[4..5]
@seq = @bytes[6..7]
@data = @bytes[8..-1]
@data = @bytes[8..]
else
@data = @bytes[4..-1]
@data = @bytes[4..]
end
self
end

def dump
puts "ICMP HEADER----------------"
puts 'ICMP HEADER----------------'
puts self
end

def to_s
if @type == 0 || @type == 8
if @type.zero? || @type == 8
<<~ICMP
Type: #{@type}
Code: #{@code}
Expand All @@ -55,19 +58,19 @@ def to_s
private

def check
@check.map { |b| b.to_s(16).rjust(2, "0") }.join
@check.map { |b| b.to_s(16).rjust(2, '0') }.join
end

def id
@id.map { |b| b.to_s(16).rjust(2, "0") }.join.to_i(16)
@id.map { |b| b.to_s(16).rjust(2, '0') }.join.to_i(16)
end

def seq
@seq.map { |b| b.to_s(16).rjust(2, "0") }.join.to_i(16)
@seq.map { |b| b.to_s(16).rjust(2, '0') }.join.to_i(16)
end

def data
@data.map { |b| b.chr }.join
@data.map(&:chr).join
end
end
end
Expand Down
23 changes: 13 additions & 10 deletions lib/redhound/header/ipv4.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Redhound
class Header
class Ipv4
Expand All @@ -13,6 +15,7 @@ def generate(bytes:)

def initialize(bytes:)
raise ArgumentError, 'bytes must be 20 bytes' unless bytes.size == 20

@bytes = bytes
end

Expand Down Expand Up @@ -40,7 +43,7 @@ def udp?
end

def dump
puts "IPv4 HEADER----------------"
puts 'IPv4 HEADER----------------'
puts self
end

Expand Down Expand Up @@ -71,38 +74,38 @@ def ihl
end

def tot_len
@tot_len.map { |b| b.to_s(16).rjust(2, "0") }.join.to_i(16)
@tot_len.map { |b| b.to_s(16).rjust(2, '0') }.join.to_i(16)
end

def id
@id.map { |b| b.to_s(16).rjust(2, "0") }.join.to_i(16)
@id.map { |b| b.to_s(16).rjust(2, '0') }.join.to_i(16)
end

def frag_off
@frag_off.map { |b| b.to_s(16).rjust(2, "0") }.join.to_i(16) & 0x1FFF
@frag_off.map { |b| b.to_s(16).rjust(2, '0') }.join.to_i(16) & 0x1FFF
end

def protocol
case @protocol
when ICMP
"ICMP"
'ICMP'
when UDP
"UDP"
'UDP'
else
"Unknown"
'Unknown'
end
end

def check
@check.map { |b| b.to_s(16).rjust(2, "0") }.join.to_i(16)
@check.map { |b| b.to_s(16).rjust(2, '0') }.join.to_i(16)
end

def saddr
@saddr.map { |b| b.to_s(16).rjust(2, "0") }.join(".")
@saddr.map { |b| b.to_s(16).rjust(2, '0') }.join('.')
end

def daddr
@daddr.map { |b| b.to_s(16).rjust(2, "0") }.join(".")
@daddr.map { |b| b.to_s(16).rjust(2, '0') }.join('.')
end
end
end
Expand Down
Loading

0 comments on commit 27157c1

Please sign in to comment.