redhound 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -2
  3. data/Dockerfile +1 -1
  4. data/README.md +10 -1
  5. data/Rakefile +12 -1
  6. data/Steepfile +4 -0
  7. data/lib/redhound/analyzer.rb +19 -15
  8. data/lib/redhound/builder/packet_mreq.rb +56 -0
  9. data/lib/redhound/builder/socket.rb +35 -0
  10. data/lib/redhound/builder.rb +4 -0
  11. data/lib/redhound/command.rb +8 -2
  12. data/lib/redhound/l2/ether.rb +68 -0
  13. data/lib/redhound/l2/protocol.rb +33 -0
  14. data/lib/redhound/l2.rb +4 -0
  15. data/lib/redhound/l3/arp.rb +114 -0
  16. data/lib/redhound/l3/base.rb +49 -0
  17. data/lib/redhound/{header → l3}/ipv4.rb +27 -44
  18. data/lib/redhound/l3/ipv6.rb +69 -0
  19. data/lib/redhound/l3/protocol.rb +173 -0
  20. data/lib/redhound/l3/resolver.rb +30 -0
  21. data/lib/redhound/l3.rb +8 -0
  22. data/lib/redhound/l4/base.rb +31 -0
  23. data/lib/redhound/{header → l4}/icmp.rb +20 -26
  24. data/lib/redhound/l4/resolver.rb +28 -0
  25. data/lib/redhound/{header → l4}/udp.rb +19 -19
  26. data/lib/redhound/l4.rb +6 -0
  27. data/lib/redhound/receiver.rb +26 -6
  28. data/lib/redhound/resolver.rb +22 -0
  29. data/lib/redhound/source/socket.rb +18 -0
  30. data/lib/redhound/source.rb +3 -0
  31. data/lib/redhound/version.rb +2 -1
  32. data/lib/redhound/writer.rb +53 -0
  33. data/lib/redhound.rb +7 -3
  34. data/rbs_collection.lock.yaml +20 -0
  35. data/rbs_collection.yaml +17 -0
  36. data/sig/generated/redhound/analyzer.rbs +14 -0
  37. data/sig/generated/redhound/builder/packet_mreq.rbs +39 -0
  38. data/sig/generated/redhound/builder/socket.rbs +24 -0
  39. data/sig/generated/redhound/command.rbs +19 -0
  40. data/sig/generated/redhound/l2/ether.rbs +41 -0
  41. data/sig/generated/redhound/l2/protocol.rbs +15 -0
  42. data/sig/generated/redhound/l3/arp.rbs +57 -0
  43. data/sig/generated/redhound/l3/base.rbs +28 -0
  44. data/sig/generated/redhound/l3/ipv4.rbs +53 -0
  45. data/sig/generated/redhound/l3/ipv6.rbs +38 -0
  46. data/sig/generated/redhound/l3/protocol.rbs +16 -0
  47. data/sig/generated/redhound/l3/resolver.rbs +16 -0
  48. data/sig/generated/redhound/l4/base.rbs +19 -0
  49. data/sig/generated/redhound/l4/icmp.rbs +33 -0
  50. data/sig/generated/redhound/l4/resolver.rbs +16 -0
  51. data/sig/generated/redhound/l4/udp.rbs +36 -0
  52. data/sig/generated/redhound/receiver.rbs +19 -0
  53. data/sig/generated/redhound/resolver.rbs +11 -0
  54. data/sig/generated/redhound/source/socket.rbs +13 -0
  55. data/sig/generated/redhound/version.rbs +5 -0
  56. data/sig/generated/redhound/writer.rbs +25 -0
  57. metadata +49 -11
  58. data/lib/redhound/header/ether.rb +0 -68
  59. data/lib/redhound/header.rb +0 -6
  60. data/lib/redhound/packet_mreq.rb +0 -46
  61. data/lib/redhound/socket_builder.rb +0 -30
  62. data/sig/redhound.rbs +0 -4
@@ -0,0 +1,36 @@
1
+ # Generated from lib/redhound/l4/udp.rb with RBS::Inline
2
+
3
+ module Redhound
4
+ class L4
5
+ class Udp < Base
6
+ # @rbs (bytes: Array[Integer]) -> void
7
+ def initialize: (bytes: Array[Integer]) -> void
8
+
9
+ # @rbs () -> Redhound::L4::Udp
10
+ def generate: () -> Redhound::L4::Udp
11
+
12
+ # @rbs () -> Integer
13
+ def size: () -> Integer
14
+
15
+ # @rbs () -> String
16
+ def to_s: () -> String
17
+
18
+ private
19
+
20
+ # @rbs () -> Integer
21
+ def sport: () -> Integer
22
+
23
+ # @rbs () -> Integer
24
+ def dport: () -> Integer
25
+
26
+ # @rbs () -> Integer
27
+ def len: () -> Integer
28
+
29
+ # @rbs () -> Integer
30
+ def check: () -> Integer
31
+
32
+ # @rbs () -> String
33
+ def data: () -> String
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,19 @@
1
+ # Generated from lib/redhound/receiver.rb with RBS::Inline
2
+
3
+ module Redhound
4
+ class Receiver
5
+ # @rbs (ifname: String, filename: String) -> void
6
+ def self.run: (ifname: String, filename: String) -> void
7
+
8
+ # @rbs (ifname: String, filename: String) -> void
9
+ def initialize: (ifname: String, filename: String) -> void
10
+
11
+ # @rbs () -> void
12
+ def run: () -> void
13
+
14
+ private
15
+
16
+ # @rbs () -> Integer
17
+ def increment: () -> Integer
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ # Generated from lib/redhound/resolver.rb with RBS::Inline
2
+
3
+ module Redhound
4
+ class Resolver
5
+ # @rbs (ifname: String) -> void
6
+ def self.resolve: (ifname: String) -> void
7
+
8
+ # @rbs (ifname: String) -> Redhound::Source::Socket
9
+ def resolve: (ifname: String) -> Redhound::Source::Socket
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # Generated from lib/redhound/source/socket.rb with RBS::Inline
2
+
3
+ module Redhound
4
+ module Source
5
+ class Socket
6
+ # @rbs (socket: ::Socket) -> void
7
+ def initialize: (socket: ::Socket) -> void
8
+
9
+ # @rbs (Integer size) -> [String, Addrinfo]
10
+ def next_packet: (Integer size) -> [ String, Addrinfo ]
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ # Generated from lib/redhound/version.rb with RBS::Inline
2
+
3
+ module Redhound
4
+ VERSION: ::String
5
+ end
@@ -0,0 +1,25 @@
1
+ # Generated from lib/redhound/writer.rb with RBS::Inline
2
+
3
+ module Redhound
4
+ class Writer
5
+ # @rbs (filename: String) -> void
6
+ def initialize: (filename: String) -> void
7
+
8
+ # @rbs () -> void
9
+ def start: () -> void
10
+
11
+ # @rbs (msg: String) -> void
12
+ def write: (msg: String) -> void
13
+
14
+ # @rbs () -> void
15
+ def stop: () -> void
16
+
17
+ private
18
+
19
+ # @rbs () -> String
20
+ def file_header: () -> String
21
+
22
+ # @rbs (Time timestamp, Integer captured_length, Integer original_length) -> String
23
+ def packet_record: (Time timestamp, Integer captured_length, Integer original_length) -> String
24
+ end
25
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redhound
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yudai Takada
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2024-11-05 00:00:00.000000000 Z
10
+ date: 2025-01-17 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: Redhound is a pure Ruby packet analyzer that can be used to capture and
13
13
  analyze network packets.
@@ -24,21 +24,59 @@ files:
24
24
  - LICENSE.txt
25
25
  - README.md
26
26
  - Rakefile
27
+ - Steepfile
27
28
  - docker-compose.yml
28
29
  - exe/redhound
29
30
  - lib/redhound.rb
30
31
  - lib/redhound/analyzer.rb
32
+ - lib/redhound/builder.rb
33
+ - lib/redhound/builder/packet_mreq.rb
34
+ - lib/redhound/builder/socket.rb
31
35
  - lib/redhound/command.rb
32
- - lib/redhound/header.rb
33
- - lib/redhound/header/ether.rb
34
- - lib/redhound/header/icmp.rb
35
- - lib/redhound/header/ipv4.rb
36
- - lib/redhound/header/udp.rb
37
- - lib/redhound/packet_mreq.rb
36
+ - lib/redhound/l2.rb
37
+ - lib/redhound/l2/ether.rb
38
+ - lib/redhound/l2/protocol.rb
39
+ - lib/redhound/l3.rb
40
+ - lib/redhound/l3/arp.rb
41
+ - lib/redhound/l3/base.rb
42
+ - lib/redhound/l3/ipv4.rb
43
+ - lib/redhound/l3/ipv6.rb
44
+ - lib/redhound/l3/protocol.rb
45
+ - lib/redhound/l3/resolver.rb
46
+ - lib/redhound/l4.rb
47
+ - lib/redhound/l4/base.rb
48
+ - lib/redhound/l4/icmp.rb
49
+ - lib/redhound/l4/resolver.rb
50
+ - lib/redhound/l4/udp.rb
38
51
  - lib/redhound/receiver.rb
39
- - lib/redhound/socket_builder.rb
52
+ - lib/redhound/resolver.rb
53
+ - lib/redhound/source.rb
54
+ - lib/redhound/source/socket.rb
40
55
  - lib/redhound/version.rb
41
- - sig/redhound.rbs
56
+ - lib/redhound/writer.rb
57
+ - rbs_collection.lock.yaml
58
+ - rbs_collection.yaml
59
+ - sig/generated/redhound/analyzer.rbs
60
+ - sig/generated/redhound/builder/packet_mreq.rbs
61
+ - sig/generated/redhound/builder/socket.rbs
62
+ - sig/generated/redhound/command.rbs
63
+ - sig/generated/redhound/l2/ether.rbs
64
+ - sig/generated/redhound/l2/protocol.rbs
65
+ - sig/generated/redhound/l3/arp.rbs
66
+ - sig/generated/redhound/l3/base.rbs
67
+ - sig/generated/redhound/l3/ipv4.rbs
68
+ - sig/generated/redhound/l3/ipv6.rbs
69
+ - sig/generated/redhound/l3/protocol.rbs
70
+ - sig/generated/redhound/l3/resolver.rbs
71
+ - sig/generated/redhound/l4/base.rbs
72
+ - sig/generated/redhound/l4/icmp.rbs
73
+ - sig/generated/redhound/l4/resolver.rbs
74
+ - sig/generated/redhound/l4/udp.rbs
75
+ - sig/generated/redhound/receiver.rbs
76
+ - sig/generated/redhound/resolver.rbs
77
+ - sig/generated/redhound/source/socket.rbs
78
+ - sig/generated/redhound/version.rbs
79
+ - sig/generated/redhound/writer.rbs
42
80
  homepage: https://github.com/ydah/redhound
43
81
  licenses:
44
82
  - MIT
@@ -63,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
101
  - !ruby/object:Gem::Version
64
102
  version: '0'
65
103
  requirements: []
66
- rubygems_version: 3.6.0.dev
104
+ rubygems_version: 3.7.0.dev
67
105
  specification_version: 4
68
106
  summary: Pure Ruby packet analyzer
69
107
  test_files: []
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Redhound
4
- class Header
5
- class Ether
6
- ETH_P_IP = 0x0800
7
-
8
- class << self
9
- def generate(bytes:)
10
- new(bytes:).generate
11
- end
12
- end
13
-
14
- def initialize(bytes:)
15
- raise ArgumentError, 'bytes must be 14 bytes' unless bytes.size == 14
16
-
17
- @bytes = bytes
18
- end
19
-
20
- def generate
21
- pp @bytes[0..5]
22
- @dhost = @bytes[0..5]
23
- @shost = @bytes[6..11]
24
- @type = @bytes[12..13]
25
- self
26
- end
27
-
28
- def ipv4?
29
- hex_type == ETH_P_IP
30
- end
31
-
32
- def dump
33
- puts 'ETHERNET HEADER----------------'
34
- puts self
35
- end
36
-
37
- def to_s
38
- <<~ETHER
39
- Destination MAC: #{dhost}
40
- Source MAC: #{shost}
41
- Type: #{type}
42
- ETHER
43
- end
44
-
45
- def dhost
46
- @dhost.map { |b| b.to_s(16).rjust(2, '0') }.join(':')
47
- end
48
-
49
- def shost
50
- @shost.map { |b| b.to_s(16).rjust(2, '0') }.join(':')
51
- end
52
-
53
- def type
54
- if ipv4?
55
- 'IPv4'
56
- else
57
- 'Unknown'
58
- end
59
- end
60
-
61
- private
62
-
63
- def hex_type
64
- @hex_type ||= @type.map { |b| b.to_s(16).rjust(2, '0') }.join.to_i(16)
65
- end
66
- end
67
- end
68
- end
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'header/ether'
4
- require_relative 'header/icmp'
5
- require_relative 'header/ipv4'
6
- require_relative 'header/udp'
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'socket'
4
-
5
- module Redhound
6
- class PacketMreq
7
- PACKET_MR_PROMISC = 0x0001 # NOTE: netpacket/packet.h
8
-
9
- def initialize(ifname:)
10
- @ifname = ifname
11
- end
12
-
13
- # see: https://man7.org/linux/man-pages/man7/packet.7.html
14
- # struct packet_mreq {
15
- # int mr_ifindex; /* interface index */
16
- # unsigned short mr_type; /* action */
17
- # unsigned short mr_alen; /* address length */
18
- # unsigned char mr_address[8]; /* physical-layer address */
19
- # };
20
- def generate
21
- mr_ifindex + mr_type + mr_alen + mr_address
22
- end
23
-
24
- def mr_ifindex
25
- @mr_ifindex ||= [[index].pack('c')].pack('a4')
26
- end
27
-
28
- private
29
-
30
- def index
31
- ::Socket.getifaddrs.find { |ifaddr| ifaddr.name == @ifname }&.ifindex
32
- end
33
-
34
- def mr_type
35
- @mr_type ||= [PACKET_MR_PROMISC].pack('S')
36
- end
37
-
38
- def mr_alen
39
- @mr_alen ||= [0].pack('S')
40
- end
41
-
42
- def mr_address
43
- @mr_address ||= [0].pack('C') * 8
44
- end
45
- end
46
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'socket'
4
-
5
- module Redhound
6
- class SocketBuilder
7
- class << self
8
- def build(ifname:)
9
- new(ifname:).build
10
- end
11
- end
12
-
13
- SOL_PACKET = 0x0107 # bits/socket.h
14
- PACKET_ADD_MEMBERSHIP = 0x0001 # NOTE: netpacket/packet.h
15
- ETH_P_ALL = 768 # NOTE: htons(ETH_P_ALL) => linux/if_ether.h
16
- PACKED_ETH_P_ALL = [ETH_P_ALL].pack('S').unpack1('S>')
17
-
18
- def initialize(ifname:)
19
- @ifname = ifname
20
- @mq_req = PacketMreq.new(ifname: @ifname)
21
- end
22
-
23
- def build
24
- socket = Socket.new(Socket::AF_PACKET, Socket::SOCK_RAW, ETH_P_ALL)
25
- socket.bind([Socket::AF_PACKET, PACKED_ETH_P_ALL, @mq_req.mr_ifindex].pack('SS>a16'))
26
- socket.setsockopt(SOL_PACKET, PACKET_ADD_MEMBERSHIP, @mq_req.generate)
27
- socket
28
- end
29
- end
30
- end
data/sig/redhound.rbs DELETED
@@ -1,4 +0,0 @@
1
- module Redhound
2
- VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
- end