packetgen 3.1.1 → 3.1.6

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 (130) hide show
  1. checksums.yaml +4 -4
  2. data/bin/pgconsole +1 -0
  3. data/lib/packetgen.rb +33 -4
  4. data/lib/packetgen/capture.rb +51 -28
  5. data/lib/packetgen/config.rb +17 -11
  6. data/lib/packetgen/deprecation.rb +34 -8
  7. data/lib/packetgen/header.rb +2 -9
  8. data/lib/packetgen/header/arp.rb +2 -2
  9. data/lib/packetgen/header/asn1_base.rb +2 -2
  10. data/lib/packetgen/header/base.rb +70 -74
  11. data/lib/packetgen/header/bootp.rb +3 -3
  12. data/lib/packetgen/header/dhcp.rb +2 -2
  13. data/lib/packetgen/header/dhcp/option.rb +2 -2
  14. data/lib/packetgen/header/dhcp/options.rb +2 -2
  15. data/lib/packetgen/header/dhcpv6.rb +12 -12
  16. data/lib/packetgen/header/dhcpv6/duid.rb +11 -5
  17. data/lib/packetgen/header/dhcpv6/option.rb +8 -16
  18. data/lib/packetgen/header/dhcpv6/options.rb +2 -2
  19. data/lib/packetgen/header/dhcpv6/relay.rb +2 -2
  20. data/lib/packetgen/header/dns.rb +9 -9
  21. data/lib/packetgen/header/dns/name.rb +20 -9
  22. data/lib/packetgen/header/dns/opt.rb +2 -2
  23. data/lib/packetgen/header/dns/option.rb +2 -2
  24. data/lib/packetgen/header/dns/qdsection.rb +3 -3
  25. data/lib/packetgen/header/dns/question.rb +37 -35
  26. data/lib/packetgen/header/dns/rr.rb +3 -3
  27. data/lib/packetgen/header/dns/rrsection.rb +2 -2
  28. data/lib/packetgen/header/dot11.rb +30 -51
  29. data/lib/packetgen/header/dot11/control.rb +5 -5
  30. data/lib/packetgen/header/dot11/data.rb +11 -7
  31. data/lib/packetgen/header/dot11/element.rb +16 -16
  32. data/lib/packetgen/header/dot11/management.rb +2 -2
  33. data/lib/packetgen/header/dot11/sub_mngt.rb +2 -12
  34. data/lib/packetgen/header/dot1q.rb +2 -2
  35. data/lib/packetgen/header/dot1x.rb +7 -20
  36. data/lib/packetgen/header/eap.rb +30 -33
  37. data/lib/packetgen/header/eap/fast.rb +2 -2
  38. data/lib/packetgen/header/eap/md5.rb +2 -2
  39. data/lib/packetgen/header/eap/tls.rb +2 -2
  40. data/lib/packetgen/header/eap/ttls.rb +2 -2
  41. data/lib/packetgen/header/eth.rb +13 -11
  42. data/lib/packetgen/header/gre.rb +2 -2
  43. data/lib/packetgen/header/http.rb +2 -0
  44. data/lib/packetgen/header/http/headers.rb +6 -4
  45. data/lib/packetgen/header/http/request.rb +36 -21
  46. data/lib/packetgen/header/http/response.rb +7 -7
  47. data/lib/packetgen/header/http/verbs.rb +3 -3
  48. data/lib/packetgen/header/icmp.rb +2 -2
  49. data/lib/packetgen/header/icmpv6.rb +2 -2
  50. data/lib/packetgen/header/igmp.rb +4 -4
  51. data/lib/packetgen/header/igmpv3.rb +3 -3
  52. data/lib/packetgen/header/igmpv3/group_record.rb +8 -6
  53. data/lib/packetgen/header/igmpv3/mq.rb +2 -2
  54. data/lib/packetgen/header/igmpv3/mr.rb +2 -2
  55. data/lib/packetgen/header/ip.rb +30 -31
  56. data/lib/packetgen/header/ip/addr.rb +10 -3
  57. data/lib/packetgen/header/ip/option.rb +8 -10
  58. data/lib/packetgen/header/ip/options.rb +3 -5
  59. data/lib/packetgen/header/ipv6.rb +2 -2
  60. data/lib/packetgen/header/ipv6/addr.rb +9 -2
  61. data/lib/packetgen/header/ipv6/extension.rb +2 -2
  62. data/lib/packetgen/header/ipv6/hop_by_hop.rb +3 -3
  63. data/lib/packetgen/header/llc.rb +2 -2
  64. data/lib/packetgen/header/mdns.rb +2 -2
  65. data/lib/packetgen/header/mld.rb +2 -2
  66. data/lib/packetgen/header/mldv2.rb +2 -2
  67. data/lib/packetgen/header/mldv2/mcast_address_record.rb +4 -2
  68. data/lib/packetgen/header/mldv2/mlq.rb +2 -2
  69. data/lib/packetgen/header/mldv2/mlr.rb +2 -2
  70. data/lib/packetgen/header/ospfv2.rb +9 -9
  71. data/lib/packetgen/header/ospfv2/db_description.rb +2 -2
  72. data/lib/packetgen/header/ospfv2/hello.rb +2 -2
  73. data/lib/packetgen/header/ospfv2/ls_ack.rb +2 -2
  74. data/lib/packetgen/header/ospfv2/ls_request.rb +4 -2
  75. data/lib/packetgen/header/ospfv2/ls_update.rb +2 -2
  76. data/lib/packetgen/header/ospfv2/lsa.rb +9 -5
  77. data/lib/packetgen/header/ospfv2/lsa_header.rb +8 -7
  78. data/lib/packetgen/header/ospfv3.rb +2 -2
  79. data/lib/packetgen/header/ospfv3/db_description.rb +2 -2
  80. data/lib/packetgen/header/ospfv3/hello.rb +2 -2
  81. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +4 -2
  82. data/lib/packetgen/header/ospfv3/ls_ack.rb +2 -2
  83. data/lib/packetgen/header/ospfv3/ls_request.rb +4 -2
  84. data/lib/packetgen/header/ospfv3/ls_update.rb +2 -2
  85. data/lib/packetgen/header/ospfv3/lsa.rb +5 -5
  86. data/lib/packetgen/header/ospfv3/lsa_header.rb +9 -8
  87. data/lib/packetgen/header/snmp.rb +33 -29
  88. data/lib/packetgen/header/tcp.rb +4 -23
  89. data/lib/packetgen/header/tcp/option.rb +11 -11
  90. data/lib/packetgen/header/tcp/options.rb +2 -2
  91. data/lib/packetgen/header/tftp.rb +6 -6
  92. data/lib/packetgen/header/udp.rb +3 -3
  93. data/lib/packetgen/headerable.rb +5 -4
  94. data/lib/packetgen/inject.rb +23 -0
  95. data/lib/packetgen/inspect.rb +23 -20
  96. data/lib/packetgen/packet.rb +96 -53
  97. data/lib/packetgen/pcap.rb +29 -0
  98. data/lib/packetgen/pcapng.rb +13 -13
  99. data/lib/packetgen/pcapng/block.rb +26 -13
  100. data/lib/packetgen/pcapng/epb.rb +25 -22
  101. data/lib/packetgen/pcapng/file.rb +260 -138
  102. data/lib/packetgen/pcapng/idb.rb +36 -38
  103. data/lib/packetgen/pcapng/shb.rb +51 -53
  104. data/lib/packetgen/pcapng/spb.rb +19 -19
  105. data/lib/packetgen/pcapng/unknown_block.rb +5 -13
  106. data/lib/packetgen/pcaprub_wrapper.rb +81 -0
  107. data/lib/packetgen/proto.rb +2 -2
  108. data/lib/packetgen/types.rb +3 -0
  109. data/lib/packetgen/types/abstract_tlv.rb +28 -8
  110. data/lib/packetgen/types/array.rb +22 -15
  111. data/lib/packetgen/types/cstring.rb +40 -16
  112. data/lib/packetgen/types/enum.rb +8 -3
  113. data/lib/packetgen/types/fieldable.rb +65 -0
  114. data/lib/packetgen/types/fields.rb +182 -117
  115. data/lib/packetgen/types/int.rb +18 -6
  116. data/lib/packetgen/types/int_string.rb +10 -2
  117. data/lib/packetgen/types/length_from.rb +20 -12
  118. data/lib/packetgen/types/oui.rb +4 -2
  119. data/lib/packetgen/types/string.rb +46 -8
  120. data/lib/packetgen/types/tlv.rb +4 -2
  121. data/lib/packetgen/utils.rb +4 -4
  122. data/lib/packetgen/utils/arp_spoofer.rb +2 -2
  123. data/lib/packetgen/version.rb +3 -3
  124. metadata +35 -50
  125. data/.gitignore +0 -13
  126. data/.rubocop.yml +0 -28
  127. data/.travis.yml +0 -17
  128. data/Gemfile +0 -4
  129. data/Rakefile +0 -21
  130. data/packetgen.gemspec +0 -36
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module PcapNG
10
10
  # {IDB} represents a Interface Description Block (IDB) of a pcapng file.
@@ -60,7 +60,7 @@ module PacketGen
60
60
  # @option options [Integer] :block_len2 block total length
61
61
  def initialize(options={})
62
62
  super
63
- set_endianness(options[:endian] || :little)
63
+ endianness(options[:endian] || :little)
64
64
  @packets = []
65
65
  @options_decoded = false
66
66
  recalc_block_len
@@ -71,22 +71,15 @@ module PacketGen
71
71
  # @param [::String,IO] str_or_io
72
72
  # @return [self]
73
73
  def read(str_or_io)
74
- io = if str_or_io.respond_to? :read
75
- str_or_io
76
- else
77
- StringIO.new(force_binary(str_or_io.to_s))
78
- end
74
+ io = to_io(str_or_io)
79
75
  return self if io.eof?
80
76
 
81
- self[:type].read io.read(4)
82
- self[:block_len].read io.read(4)
83
- self[:link_type].read io.read(2)
84
- self[:reserved].read io.read(2)
85
- self[:snaplen].read io.read(4)
77
+ %i[type block_len link_type reserved snaplen].each do |attr|
78
+ self[attr].read io.read(self[attr].sz)
79
+ end
86
80
  self[:options].read io.read(self.block_len - MIN_SIZE)
87
- self[:block_len2].read io.read(4)
81
+ read_blocklen2_and_check(io)
88
82
 
89
- check_len_coherency
90
83
  self
91
84
  end
92
85
 
@@ -95,6 +88,7 @@ module PacketGen
95
88
  # @return [self]
96
89
  def <<(xpb)
97
90
  @packets << xpb
91
+ xpb.interface = self
98
92
  self
99
93
  end
100
94
 
@@ -105,29 +99,7 @@ module PacketGen
105
99
  if @options_decoded && !force
106
100
  @ts_resol
107
101
  else
108
- packstr = endian == :little ? 'v' : 'n'
109
- idx = 0
110
- options = self[:options]
111
-
112
- while idx < options.length
113
- opt_code, opt_len = options[idx, 4].unpack("#{packstr}2")
114
- if opt_code == OPTION_IF_TSRESOL && opt_len == 1
115
- tsresol = options[idx + 4, 1].unpack('C').first
116
- @ts_resol = if (tsresol & 0x80).zero?
117
- 10**-tsresol
118
- else
119
- 2**-(tsresol & 0x7f)
120
- end
121
-
122
- @options_decoded = true
123
- return @ts_resol
124
- else
125
- idx += 4 + opt_len
126
- end
127
- end
128
-
129
- @options_decoded = true
130
- @ts_resol = 1E-6 # default value
102
+ decode_ts_resol
131
103
  end
132
104
  end
133
105
 
@@ -138,6 +110,32 @@ module PacketGen
138
110
  recalc_block_len
139
111
  super << @packets.map(&:to_s).join
140
112
  end
113
+
114
+ private
115
+
116
+ def decode_ts_resol
117
+ tsresol = search_for_ts_resol_opt(self[:options])
118
+ @options_decoded = true
119
+ return @ts_resol = 1E-6 if tsresol.nil?
120
+
121
+ @ts_resol = if (tsresol & 0x80).zero?
122
+ 10**-tsresol
123
+ else
124
+ 2**-(tsresol & 0x7f)
125
+ end
126
+ end
127
+
128
+ def search_for_ts_resol_opt(options)
129
+ packstr = endian == :little ? 'v' : 'n'
130
+ idx = 0
131
+
132
+ while idx < options.length
133
+ opt_code, opt_len = options[idx, 4].unpack("#{packstr}2")
134
+ return options[idx + 4, 1].unpack1('C') if opt_code == OPTION_IF_TSRESOL && opt_len == 1
135
+
136
+ idx += 4 + opt_len
137
+ end
138
+ end
141
139
  end
142
140
  end
143
141
  end
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module PcapNG
10
10
  # {SHB} represents a Section Header Block (SHB) of a pcapng file.
@@ -80,7 +80,7 @@ module PacketGen
80
80
  super
81
81
  @interfaces = []
82
82
  @unknown_blocks = []
83
- set_endianness(options[:endian] || :little)
83
+ endianness(options[:endian] || :little)
84
84
  recalc_block_len
85
85
  self.type = options[:type] || PcapNG::SHB_TYPE.to_i
86
86
  end
@@ -89,51 +89,18 @@ module PacketGen
89
89
  # @param [::String,IO] str_or_io
90
90
  # @return [self]
91
91
  def read(str_or_io)
92
- io = if str_or_io.respond_to? :read
93
- str_or_io
94
- else
95
- StringIO.new(force_binary(str_or_io.to_s))
96
- end
92
+ io = to_io(str_or_io)
97
93
  return self if io.eof?
98
94
 
99
- type_str = io.read(4)
100
- unless type_str == PcapNG::SHB_TYPE.to_s
101
- type = type_str.unpack('H*').join
102
- raise InvalidFileError, "Incorrect type (#{type})for Section Header Block"
103
- end
104
-
105
- block_len_str = io.read(4)
106
-
107
- magic_str = io.read(4)
108
- case @endian
109
- when :little
110
- case magic_str
111
- when MAGIC_LITTLE
112
- when MAGIC_BIG
113
- force_endianness :big
114
- else
115
- raise InvalidFileError, 'Incorrect magic for Section Header Block'
116
- end
117
- when :big
118
- case magic_str
119
- when MAGIC_BIG
120
- when MAGIC_LITTLE
121
- force_endianness :little
122
- else
123
- raise InvalidFileError, 'Incorrect magic for Section Header Block'
124
- end
95
+ self[:type].read check_shb(io)
96
+ %i[block_len magic ver_major ver_minor section_len].each do |attr|
97
+ self[attr].read io.read(self[attr].sz)
125
98
  end
99
+ handle_magic_and_check(self[:magic].to_s)
126
100
 
127
- self[:type].read type_str
128
- self[:block_len].read block_len_str
129
- self[:magic].read magic_str
130
- self[:ver_major].read io.read(2)
131
- self[:ver_minor].read io.read(2)
132
- self[:section_len].read io.read(8)
133
- self[:options].read io.read(self.block_len - MIN_SIZE)
134
- self[:block_len2].read io.read(4)
101
+ read_options(io)
102
+ read_blocklen2_and_check(io)
135
103
 
136
- check_len_coherency
137
104
  self
138
105
  end
139
106
 
@@ -142,6 +109,7 @@ module PacketGen
142
109
  # @return [self]
143
110
  def <<(idb)
144
111
  @interfaces << idb
112
+ idb.section = self
145
113
  self
146
114
  end
147
115
 
@@ -149,25 +117,55 @@ module PacketGen
149
117
  # @return [String]
150
118
  def to_s
151
119
  body = @interfaces.map(&:to_s).join
152
- unless self.section_len == SECTION_LEN_UNDEFINED
153
- self.section_len = body.size
154
- end
120
+ self.section_len = body.size unless self.section_len == SECTION_LEN_UNDEFINED
121
+
155
122
  pad_field :options
156
123
  recalc_block_len
157
124
  super + body
158
125
  end
159
126
 
127
+ def add_unknown_block(block)
128
+ self.unknown_blocks << block
129
+ block.section = self
130
+ end
131
+
160
132
  private
161
133
 
162
134
  def force_endianness(endian)
163
135
  @endian = endian
164
- self[:type] = Types::Int32.new(self[:type].to_i, endian)
165
- self[:block_len] = Types::Int32.new(self[:block_len].to_i, endian)
166
- self[:magic] = Types::Int32.new(self[:magic].to_i, endian)
167
- self[:ver_major] = Types::Int16.new(self[:ver_major].to_i, endian)
168
- self[:ver_minor] = Types::Int16.new(self[:ver_minor].to_i, endian)
169
- self[:section_len] = Types::Int64.new(self[:section_len].to_i, endian)
170
- self[:block_len2] = Types::Int32.new(self[:block_len2].to_i, endian)
136
+ %i[type block_len magic block_len2].each do |attr|
137
+ self[attr] = Types::Int32.new(0, endian).read(self[attr].to_s)
138
+ end
139
+ %i[ver_major ver_minor].each do |attr|
140
+ self[attr] = Types::Int16.new(0, endian).read(self[attr].to_s)
141
+ end
142
+ self[:section_len] = Types::Int64.new(0, endian).read(self[:section_len].to_s)
143
+ end
144
+
145
+ # Check io contains a SHB
146
+ # @param [IO] io
147
+ # @return [String] type string
148
+ def check_shb(io)
149
+ type_str = io.read(4)
150
+ return type_str if type_str == PcapNG::SHB_TYPE.to_s
151
+
152
+ type = type_str.unpack('H*').join
153
+ raise InvalidFileError, "Incorrect type (#{type})for Section Header Block"
154
+ end
155
+
156
+ def handle_magic_and_check(magic_str)
157
+ case magic_str
158
+ when MAGIC_LITTLE
159
+ force_endianness :little if endian == :big
160
+ when MAGIC_BIG
161
+ force_endianness :big if endian == :little
162
+ else
163
+ raise InvalidFileError, 'Incorrect magic for Section Header Block'
164
+ end
165
+ end
166
+
167
+ def read_options(io)
168
+ self[:options].read io.read(self.block_len - MIN_SIZE)
171
169
  end
172
170
  end
173
171
  end
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module PcapNG
10
10
  # {SPB} represents a Section Simple Packet Block (SPB) of a pcapng file.
@@ -44,7 +44,7 @@ module PacketGen
44
44
  # @option options [Integer] :block_len2 block total length
45
45
  def initialize(options={})
46
46
  super
47
- set_endianness(options[:endian] || :little)
47
+ endianness(options[:endian] || :little)
48
48
  recalc_block_len
49
49
  self.type = options[:type] || PcapNG::SPB_TYPE.to_i
50
50
  end
@@ -60,29 +60,17 @@ module PacketGen
60
60
  # @param [::String,IO] str_or_io
61
61
  # @return [self]
62
62
  def read(str_or_io)
63
- io = if str_or_io.respond_to? :read
64
- str_or_io
65
- else
66
- StringIO.new(force_binary(str_or_io.to_s))
67
- end
63
+ io = to_io(str_or_io)
68
64
  return self if io.eof?
69
65
 
70
66
  self[:type].read io.read(4)
71
67
  self[:block_len].read io.read(4)
72
68
  self[:orig_len].read io.read(4)
73
- # Take care of IDB snaplen
74
- # CAUTION: snaplen == 0 -> no capture limit
75
- data_len = if interface && (interface.snaplen.to_i > 0)
76
- [self[:orig_len].to_i, interface.snaplen.to_i].min
77
- else
78
- self[:orig_len].to_i
79
- end
80
- data_pad_len = (4 - (data_len % 4)) % 4
69
+ data_len = compute_data_len
81
70
  self[:data].read io.read(data_len)
82
- io.read data_pad_len
83
- self[:block_len2].read io.read(4)
71
+ remove_padding(io, data_len)
72
+ read_blocklen2_and_check(io)
84
73
 
85
- check_len_coherency
86
74
  self.type ||= PcapNG::IDB_TYPE.to_i
87
75
  self
88
76
  end
@@ -94,6 +82,18 @@ module PacketGen
94
82
  recalc_block_len
95
83
  super
96
84
  end
85
+
86
+ private
87
+
88
+ # Take care of IDB snaplen
89
+ # CAUTION: snaplen == 0 -> no capture limit
90
+ def compute_data_len
91
+ if interface && interface.snaplen.to_i.positive?
92
+ [self[:orig_len].to_i, interface.snaplen.to_i].min
93
+ else
94
+ self[:orig_len].to_i
95
+ end
96
+ end
97
97
  end
98
98
  end
99
99
  end
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module PcapNG
10
10
  # {UnknownBlock} is used to handle unsupported blocks of a pcapng file.
@@ -29,7 +29,7 @@ module PacketGen
29
29
  # @option options [Integer] :block_len2 block total length
30
30
  def initialize(options={})
31
31
  super
32
- set_endianness(options[:endian] || :little)
32
+ endianness(options[:endian] || :little)
33
33
  recalc_block_len
34
34
  end
35
35
 
@@ -44,21 +44,13 @@ module PacketGen
44
44
  # @param [::String,IO] str_or_io
45
45
  # @return [self]
46
46
  def read(str_or_io)
47
- io = if str_or_io.respond_to? :read
48
- str_or_io
49
- else
50
- StringIO.new(force_binary(str_or_io.to_s))
51
- end
47
+ io = to_io(str_or_io)
52
48
  return self if io.eof?
53
49
 
54
50
  self[:type].read io.read(4)
55
51
  self[:block_len].read io.read(4)
56
52
  self[:body].read io.read(self[:block_len].to_i - MIN_SIZE)
57
- self[:block_len2].read io.read(4)
58
-
59
- unless self[:block_len].to_i == self[:block_len2].to_i
60
- raise InvalidFileError, 'Incoherency in Header Block'
61
- end
53
+ read_blocklen2_and_check(io)
62
54
 
63
55
  self
64
56
  end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is part of PacketGen
4
+ # See https://github.com/sdaubert/packetgen for more informations
5
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
6
+ # This program is published under MIT license.
7
+ require 'pcaprub'
8
+
9
+ module PacketGen
10
+ # Wrapper around PCAPRUB
11
+ # @author Sylvain Daubert
12
+ # @api private
13
+ # @since 3.1.4
14
+ module PCAPRUBWrapper
15
+ # timeout for PCAPRUB
16
+ TIMEOUT = 1
17
+ # Default snaplen to use
18
+ DEFAULT_SNAPLEN = 0xffff
19
+ # Default promisc value to use
20
+ DEFAULT_PROMISC = false
21
+
22
+ # Open an interface for capturing
23
+ # @param [String] iface interface name
24
+ # @param [Integer] snaplen
25
+ # @param [Boolean] promisc
26
+ # @param [Boolean] monitor
27
+ # @return [PCAPRUB::Pcap]
28
+ # @author Sylvain Daubert
29
+ # @author optix2000 - add support for setting monitor mode
30
+ # @since 3.1.5 add monitor argument
31
+ def self.open_iface(iface:, snaplen: DEFAULT_SNAPLEN, promisc: DEFAULT_PROMISC, monitor: nil)
32
+ pcap = PCAPRUB::Pcap.create(iface)
33
+ pcap.setsnaplen(snaplen)
34
+ pcap.setpromisc(promisc)
35
+ pcap.settimeout(TIMEOUT)
36
+ # Monitor MUST be set before pcap is activated
37
+ pcap.setmonitor monitor unless monitor.nil?
38
+ pcap.activate
39
+ end
40
+
41
+ # rubocop:disable Metrics/ParameterLists
42
+
43
+ # Capture packets from a network interface
44
+ # @param [String] iface interface name
45
+ # @param [Integer] snaplen
46
+ # @param [Boolean] promisc
47
+ # @param [String] filter BPF filter
48
+ # @param [Boolean] monitor
49
+ # @yieldparam [String] packet_data binary packet data
50
+ # @return [void]
51
+ # @author Sylvain Daubert
52
+ # @author optix2000 - add support for setting monitor mode
53
+ # @since 3.1.5 add monitor argument
54
+ def self.capture(iface:, snaplen: DEFAULT_SNAPLEN, promisc: DEFAULT_PROMISC, filter: nil, monitor: nil, &block)
55
+ pcap = self.open_iface(iface: iface, snaplen: snaplen, promisc: promisc, monitor: monitor)
56
+ pcap.setfilter filter unless filter.nil?
57
+ pcap.each(&block)
58
+ end
59
+
60
+ # rubocop:enable Metrics/ParameterLists
61
+
62
+ # Inject given data onto wire
63
+ # @param [String] iface interface name
64
+ # @param [String] data to inject
65
+ # @return [void]
66
+ def self.inject(iface:, data:)
67
+ pcap = self.open_iface(iface: iface)
68
+ pcap.inject(data)
69
+ pcap.close
70
+ end
71
+
72
+ # Read a PCAP file
73
+ # @param [String] filename
74
+ # @yieldparam [String] data binary packet data
75
+ # @return [void]
76
+ # @author Kent Gruber
77
+ def self.read_pcap(filename:, &block)
78
+ PCAPRUB::Pcap.open_offline(filename).each_packet(&block)
79
+ end
80
+ end
81
+ end