packetgen 3.2.0 → 3.2.1

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/bin/pgconsole +3 -3
  4. data/lib/packetgen/header/arp.rb +24 -13
  5. data/lib/packetgen/header/asn1_base.rb +2 -2
  6. data/lib/packetgen/header/base.rb +1 -1
  7. data/lib/packetgen/header/dhcpv6/option.rb +11 -13
  8. data/lib/packetgen/header/dns/opt.rb +2 -2
  9. data/lib/packetgen/header/dns/rr.rb +61 -28
  10. data/lib/packetgen/header/dns.rb +13 -6
  11. data/lib/packetgen/header/dot11/management.rb +2 -5
  12. data/lib/packetgen/header/dot11.rb +1 -1
  13. data/lib/packetgen/header/eap.rb +1 -1
  14. data/lib/packetgen/header/eth.rb +1 -1
  15. data/lib/packetgen/header/http/response.rb +43 -23
  16. data/lib/packetgen/header/igmp.rb +1 -1
  17. data/lib/packetgen/header/ip/option.rb +2 -1
  18. data/lib/packetgen/header/ipv6/addr.rb +3 -0
  19. data/lib/packetgen/header/mdns.rb +19 -25
  20. data/lib/packetgen/header/mld.rb +1 -1
  21. data/lib/packetgen/header/ospfv2/lsa_header.rb +2 -4
  22. data/lib/packetgen/header/ospfv2.rb +1 -1
  23. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +14 -5
  24. data/lib/packetgen/header/ospfv3/lsa.rb +1 -1
  25. data/lib/packetgen/header/ospfv3/lsa_header.rb +2 -4
  26. data/lib/packetgen/header/ospfv3.rb +1 -1
  27. data/lib/packetgen/header/snmp.rb +20 -14
  28. data/lib/packetgen/header/tcp/option.rb +1 -1
  29. data/lib/packetgen/header/tcp.rb +12 -5
  30. data/lib/packetgen/header/tftp.rb +15 -9
  31. data/lib/packetgen/inspect.rb +15 -9
  32. data/lib/packetgen/packet.rb +48 -2
  33. data/lib/packetgen/pcapng/file.rb +13 -13
  34. data/lib/packetgen/pcapng.rb +1 -0
  35. data/lib/packetgen/pcaprub_wrapper.rb +0 -4
  36. data/lib/packetgen/types/abstract_tlv.rb +1 -1
  37. data/lib/packetgen/types/array.rb +8 -1
  38. data/lib/packetgen/types/fields.rb +19 -19
  39. data/lib/packetgen/types/int.rb +7 -0
  40. data/lib/packetgen/types/oui.rb +1 -1
  41. data/lib/packetgen/types/tlv.rb +17 -9
  42. data/lib/packetgen/utils.rb +55 -21
  43. data/lib/packetgen/version.rb +1 -1
  44. data/lib/packetgen.rb +3 -3
  45. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f3faa715cd36e918df79355267c50690bdde15f1566e23947d26890e7b89a82
4
- data.tar.gz: d374447f230500b0c5be84b225d3a5576f019afc4870dc6512c659bc2e069d67
3
+ metadata.gz: 79dc573da10eb15bbd9f38e0c84ecdf9a92d076980628635d1b9e240e3ca2210
4
+ data.tar.gz: 0ae2bafa08e5a4a0b176276a141b8c8326265873bb20d86a75e07bb7018275ac
5
5
  SHA512:
6
- metadata.gz: de7911facea630eaa2d3d4afd2ae15e1cbd927241ebf0c63ec096c64eac31c58e519d379476763c50fc1b4290029cec4b14dbf9e96ae9aa05dc06701cf45af32
7
- data.tar.gz: 69881fc66b4af80177bdad4b5b2daa4bd28259596bbf8a36112998aa9a8c117c7c9898180372635fcc1b47376e2fab4fb5cece88be5c000277cdce825fb03168
6
+ metadata.gz: 7c405a57b79c4a9bf0d9032b34d7381b33e8c0705c554023f6a8131c19c48fb0118201d94da62e4f74b9d53551cdbcd434cb6363f27a84e5c3e8459cb28d613b
7
+ data.tar.gz: 835969235415864e05b227dd5f0fb48535e3f414e60852cf788d6d90bf29be9a3a8dcf9b636ce8d500d29720753246e11459da925fea3f72f6cb8e11291565b8
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  [![Gem Version](https://badge.fury.io/rb/packetgen.svg)](https://badge.fury.io/rb/packetgen)
3
-
3
+ [![Action status](https://github.com/sdaubert/packetgen/workflows/ci/badge.svg?branch=master)](https://github.com/sdaubert/packetgen/actions?query=workflow%3Aci)
4
4
  # PacketGen
5
5
 
6
6
  PacketGen provides simple ways to generate, send and capture network packets.
data/bin/pgconsole CHANGED
@@ -31,7 +31,7 @@ class PgConsole
31
31
  define_method m, Utils.method(m).to_proc
32
32
  end
33
33
 
34
- def get_binding
34
+ def console_binding
35
35
  binding
36
36
  end
37
37
  end
@@ -52,10 +52,10 @@ if use_pry
52
52
  }
53
53
  ]
54
54
  Pry.config.prompt_name = 'pg'
55
- PgConsole.new.get_binding.pry
55
+ PgConsole.new.console_binding.pry
56
56
  else
57
57
  IRB.setup nil
58
- irb = IRB::Irb.new(IRB::WorkSpace.new(PgConsole.new.get_binding))
58
+ irb = IRB::Irb.new(IRB::WorkSpace.new(PgConsole.new.console_binding))
59
59
  IRB.conf[:MAIN_CONTEXT] = irb.context
60
60
  irb.context.auto_indent_mode = true
61
61
  irb.context.prompt_i = 'pg> '
@@ -81,15 +81,7 @@ module PacketGen
81
81
  # @option options [String] :tha target hardware address
82
82
  # @option options [String] :tpa targetr internet address
83
83
  def initialize(options={})
84
- options[:hrd] ||= options[:htype]
85
- options[:pro] ||= options[:ptype]
86
- options[:hln] ||= options[:hlen]
87
- options[:pln] ||= options[:plen]
88
- options[:op] ||= options[:opcode]
89
- options[:sha] ||= options[:src_mac]
90
- options[:spa] ||= options[:src_ip]
91
- options[:tha] ||= options[:dst_mac]
92
- options[:tpa] ||= options[:dst_ip]
84
+ handle_options(options)
93
85
  super
94
86
  end
95
87
 
@@ -118,16 +110,35 @@ module PacketGen
118
110
  case opcode.to_i
119
111
  when 1
120
112
  self.opcode = 2
121
- self.spa, self.tpa = self.tpa, self.spa
122
- self.sha, self.tha = self.tha, self.sha
113
+ invert_addresses
123
114
  when 2
124
115
  self.opcode = 1
125
- self.spa, self.tpa = self.tpa, self.spa
126
- self.sha = self.tha
116
+ invert_addresses
127
117
  self[:tha].from_human('00:00:00:00:00:00')
128
118
  end
129
119
  self
130
120
  end
121
+
122
+ private
123
+
124
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
125
+ def handle_options(options)
126
+ options[:hrd] ||= options[:htype]
127
+ options[:pro] ||= options[:ptype]
128
+ options[:hln] ||= options[:hlen]
129
+ options[:pln] ||= options[:plen]
130
+ options[:op] ||= options[:opcode]
131
+ options[:sha] ||= options[:src_mac]
132
+ options[:spa] ||= options[:src_ip]
133
+ options[:tha] ||= options[:dst_mac]
134
+ options[:tpa] ||= options[:dst_ip]
135
+ end
136
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
137
+
138
+ def invert_addresses
139
+ self.spa, self.tpa = self.tpa, self.spa
140
+ self.sha, self.tha = self.tha, self.sha
141
+ end
131
142
  end
132
143
 
133
144
  self.add_class ARP
@@ -19,7 +19,7 @@ module PacketGen
19
19
  class ASN1Base < RASN1::Model
20
20
  include Headerable
21
21
 
22
- class <<self
22
+ class << self
23
23
  # Define some methods from given ASN.1 fields to mimic {Base} attributes
24
24
  # @param [Array<Symbol>] attributes
25
25
  # @return [void]
@@ -27,7 +27,7 @@ module PacketGen
27
27
  @attributes = attributes
28
28
  attributes.each do |attr|
29
29
  class_eval "def #{attr}; @elements[:#{attr}].value; end\n" \
30
- "def #{attr}=(v); @elements[:#{attr}].value = v; end"
30
+ "def #{attr}=(v); @elements[:#{attr}].value = v; end"
31
31
  end
32
32
  end
33
33
 
@@ -142,7 +142,7 @@ module PacketGen
142
142
  klass.class_eval { @known_headers = {} }
143
143
  end
144
144
 
145
- class <<self
145
+ class << self
146
146
  # @api private
147
147
  # Get known headers
148
148
  # @return [Hash] keys: header classes, values: hashes
@@ -53,19 +53,17 @@ module PacketGen
53
53
  # @param [Hash] options
54
54
  # @return [Option]
55
55
  def new(options={})
56
- if self == Option
57
- case options[:type]
58
- when Integer
59
- klass = Option.subclasses[options[:type]]
60
- klass&.new(options)
61
- when String
62
- if DHCPv6.const_defined?(options[:type])
63
- klass = DHCPv6.const_get(options[:type])
64
- options.delete :type
65
- klass.new(options) if klass < Option
66
- end
67
- else
68
- super
56
+ return super unless self == Option
57
+
58
+ case options[:type]
59
+ when Integer
60
+ klass = Option.subclasses[options[:type]]
61
+ klass&.new(options)
62
+ when String
63
+ if DHCPv6.const_defined?(options[:type])
64
+ klass = DHCPv6.const_get(options[:type])
65
+ options.delete :type
66
+ klass.new(options) if klass < Option
69
67
  end
70
68
  else
71
69
  super
@@ -125,8 +125,8 @@ module PacketGen
125
125
  # @return [String]
126
126
  def to_human
127
127
  "#{name} #{human_type} UDPsize:#{udp_size} " \
128
- "extRCODE:#{ext_rcode} EDNSversion:#{version} flags:#{human_flags} " \
129
- "options:#{options.empty? ? 'none' : options.to_human}"
128
+ "extRCODE:#{ext_rcode} EDNSversion:#{version} flags:#{human_flags} " \
129
+ "options:#{options.empty? ? 'none' : options.to_human}"
130
130
  end
131
131
  end
132
132
  end
@@ -50,48 +50,29 @@ module PacketGen
50
50
  self[:rdata].read data
51
51
  end
52
52
 
53
+ # rubocop:disable Metrics/AbcSize
54
+
53
55
  # Get human readable rdata
54
56
  # @return [String]
55
57
  def human_rdata
56
- str = self[:rdata].inspect
57
-
58
- # Need to mask: mDNS uses leftmost bit as a flag (CACHE FLUSH)
59
- if self.rrclass & 0x7fff == CLASSES['IN']
60
- case type
61
- when TYPES['A'], TYPES['AAAA']
62
- str = IPAddr.new_ntoh(self[:rdata]).to_s
63
- end
64
- end
58
+ str = human_ip_rdata || self[:rdata].inspect
65
59
 
66
- name = Name.new
67
- name.dns = self[:name].dns
68
60
  case type
69
61
  when TYPES['NS'], TYPES['PTR'], TYPES['CNAME']
62
+ name = Name.new
63
+ name.dns = self[:name].dns
70
64
  str = name.read(self[:rdata]).to_human
71
65
  when TYPES['SOA']
72
- mname = name.read(self[:rdata]).dup
73
- rname = name.read(self[:rdata][mname.sz..-1])
74
- serial = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz, 4])
75
- refresh = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 4, 4])
76
- retryi = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 8, 4])
77
- expire = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 12, 4])
78
- minimum = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 16, 4])
79
- str = "#{mname.to_human} #{rname.to_human} #{serial.to_i} #{refresh.to_i} " \
80
- "#{retryi.to_i} #{expire.to_i} #{minimum.to_i}"
66
+ str = human_soa_rdata
81
67
  when TYPES['MX']
82
- pref = Types::Int16.new.read(self[:rdata][0, 2])
83
- exchange = name.read(self[:rdata][2..-1]).to_human
84
- str = '%u %s' % [pref.to_i, exchange]
68
+ str = human_mx_data
85
69
  when TYPES['SRV']
86
- priority = Types::Int16.new.read(self[:rdata][0, 2])
87
- weight = Types::Int16.new.read(self[:rdata][2, 2])
88
- port = Types::Int16.new.read(self[:rdata][4, 2])
89
- target = name.read(self[:rdata][6, self[:rdata].size]).to_human
90
- str = "#{priority.to_i} #{weight.to_i} #{port.to_i} #{target}"
70
+ str = human_srv_data
91
71
  end
92
72
 
93
73
  str
94
74
  end
75
+ # rubocop:enable Metrics/AbcSize
95
76
 
96
77
  # Get human readable class
97
78
  # @return [String]
@@ -109,6 +90,58 @@ module PacketGen
109
90
  def to_human
110
91
  "#{human_type} #{human_rrclass} #{name} TTL #{ttl} #{human_rdata}"
111
92
  end
93
+
94
+ private
95
+
96
+ def human_ip_rdata
97
+ # Need to mask: mDNS uses leftmost bit as a flag (CACHE FLUSH)
98
+ return unless self.rrclass & 0x7fff == CLASSES['IN']
99
+
100
+ case type
101
+ when TYPES['A'], TYPES['AAAA']
102
+ IPAddr.new_ntoh(self[:rdata]).to_s
103
+ end
104
+ end
105
+
106
+ def human_mx_data
107
+ name = Name.new
108
+ name.dns = self[:name].dns
109
+
110
+ pref = Types::Int16.new.read(self[:rdata][0, 2])
111
+ exchange = name.read(self[:rdata][2..-1]).to_human
112
+
113
+ '%u %s' % [pref.to_i, exchange]
114
+ end
115
+
116
+ # rubocop:disable Metrics/AbcSize
117
+ def human_soa_rdata
118
+ name = Name.new
119
+ name.dns = self[:name].dns
120
+ mname = name.read(self[:rdata]).dup
121
+ rname = name.read(self[:rdata][mname.sz..-1])
122
+
123
+ serial = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz, 4])
124
+ refresh = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 4, 4])
125
+ retryi = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 8, 4])
126
+ expire = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 12, 4])
127
+ minimum = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 16, 4])
128
+
129
+ "#{mname.to_human} #{rname.to_human} #{serial.to_i} #{refresh.to_i} " \
130
+ "#{retryi.to_i} #{expire.to_i} #{minimum.to_i}"
131
+ end
132
+
133
+ def human_srv_data
134
+ name = Name.new
135
+ name.dns = self[:name].dns
136
+
137
+ priority = Types::Int16.new.read(self[:rdata][0, 2])
138
+ weight = Types::Int16.new.read(self[:rdata][2, 2])
139
+ port = Types::Int16.new.read(self[:rdata][4, 2])
140
+ target = name.read(self[:rdata][6, self[:rdata].size]).to_human
141
+
142
+ "#{priority.to_i} #{weight.to_i} #{port.to_i} #{target}"
143
+ end
144
+ # rubocop:enable Metrics/AbcSize
112
145
  end
113
146
  end
114
147
  end
@@ -241,18 +241,25 @@ module PacketGen
241
241
  super do |attr|
242
242
  next unless attr == :u16
243
243
 
244
- flags = %i[qr aa tc rd ra].select! { |flag| send "#{flag}?" }
245
- .map(&:to_s).join(',')
246
- str = Inspect.shift_level
247
- str << Inspect::FMT_ATTR % ['Flags', 'flags', flags]
248
- opcode = '%-16s (%u)' % [OPCODES.key(self.opcode), self.opcode]
244
+ str = inspect_flags
245
+
249
246
  str << Inspect.shift_level
247
+ opcode = '%-16s (%u)' % [OPCODES.key(self.opcode), self.opcode]
250
248
  str << Inspect::FMT_ATTR % ['Integer', 'opcode', opcode]
251
- rcode = '%-16s (%u)' % [RCODES.key(self.rcode), self.rcode]
249
+
252
250
  str << Inspect.shift_level
251
+ rcode = '%-16s (%u)' % [RCODES.key(self.rcode), self.rcode]
253
252
  str << Inspect::FMT_ATTR % ['Integer', 'rcode', rcode]
254
253
  end
255
254
  end
255
+
256
+ private
257
+
258
+ def inspect_flags
259
+ flags = %i[qr aa tc rd ra].select! { |flag| send "#{flag}?" }.map(&:to_s).join(',')
260
+ str = Inspect.shift_level
261
+ str << Inspect::FMT_ATTR % ['Flags', 'flags', flags]
262
+ end
256
263
  end
257
264
 
258
265
  self.add_class DNS
@@ -53,12 +53,9 @@ module PacketGen
53
53
  # @return [self]
54
54
  # @since 2.1.3
55
55
  def add_element(type:, value:)
56
- if self[:body].is_a? SubMngt
57
- self[:body].elements << { type: type, value: value }
58
- else
59
- raise FormatError, 'Before adding an Element, you have to add a Dot11::SubMngt subclass instance'
60
- end
56
+ raise FormatError, 'Before adding an Element, you have to add a Dot11::SubMngt subclass instance' unless self[:body].is_a? SubMngt
61
57
 
58
+ self[:body].elements << { type: type, value: value }
62
59
  self
63
60
  end
64
61
 
@@ -355,7 +355,7 @@ module PacketGen
355
355
  def added_to_packet(packet)
356
356
  return if packet.respond_to? :dot11
357
357
 
358
- packet.instance_eval("def dot11(arg=nil); header(#{self.class}, arg); end")
358
+ packet.instance_eval("def dot11(arg=nil); header(#{self.class}, arg); end") # def dot11(arg=nil); header(Dot11, arg); end
359
359
  end
360
360
 
361
361
  private
@@ -218,7 +218,7 @@ module PacketGen
218
218
  def added_to_packet(packet)
219
219
  return if packet.respond_to? :eap
220
220
 
221
- packet.instance_eval("def eap(arg=nil); header(#{self.class}, arg); end")
221
+ packet.instance_eval("def eap(arg=nil); header(#{self.class}, arg); end") # def eap(arg=nil); header(EAP, arg); end
222
222
  end
223
223
 
224
224
  # Invert between a request and a response packet. Not action for
@@ -60,7 +60,7 @@ module PacketGen
60
60
  def from_human(str)
61
61
  return self if str.nil?
62
62
 
63
- bytes = str.split(/:/)
63
+ bytes = str.split(':')
64
64
  raise ArgumentError, 'not a MAC address' unless bytes.size == 6
65
65
 
66
66
  6.times do |i|
@@ -67,11 +67,42 @@ module PacketGen
67
67
  # Read in the HTTP portion of the packet, and parse it.
68
68
  # @return [PacketGen::HTTP::Response]
69
69
  def read(str)
70
- str = str.bytes.map!(&:chr).join unless str.valid_encoding?
71
- arr = str.split("\r\n")
70
+ headers, data = collect_headers_and_data(str)
71
+
72
+ unless headers.empty?
73
+ extract_info_from_first_line(headers)
74
+ self[:headers].read(headers.join("\n"))
75
+ end
76
+ self[:body].read data.join("\n")
77
+
78
+ self
79
+ end
80
+
81
+ def parse?
82
+ version.start_with?('HTTP/1.')
83
+ end
84
+
85
+ # String representation of data.
86
+ # @return [String]
87
+ def to_s
88
+ raise_on_bad_version_status
89
+
90
+ str = +''
91
+ str << self.version << ' ' << self.status_code << ' ' << self.status_mesg << "\r\n"
92
+ str << self[:headers].to_s if self[:headers].given?
93
+ str << self.body
94
+ end
95
+
96
+ private
97
+
98
+ def collect_headers_and_data(str)
72
99
  headers = [] # header stream
73
100
  data = [] # data stream
74
101
  switch = false
102
+
103
+ str = str.bytes.map!(&:chr).join unless str.valid_encoding?
104
+ arr = str.split("\r\n")
105
+
75
106
  arr.each do |line|
76
107
  if line.empty?
77
108
  data << line if switch # already done
@@ -85,34 +116,23 @@ module PacketGen
85
116
  headers << line
86
117
  end
87
118
  end
88
- unless headers.empty?
89
- first_line = headers.shift.split
90
- if first_line.size >= 3
91
- self[:version].read first_line[0]
92
- self[:status_code].read first_line[1]
93
- self[:status_mesg].read first_line[2..-1].join(' ')
94
- end
95
- self[:headers].read(headers.join("\n"))
96
- end
97
- self[:body].read data.join("\n")
98
- self
119
+
120
+ [headers, data]
99
121
  end
100
122
 
101
- def parse?
102
- version.start_with?('HTTP/1.')
123
+ def extract_info_from_first_line(headers)
124
+ first_line = headers.shift.split
125
+ return if first_line.size < 3
126
+
127
+ self[:version].read first_line[0]
128
+ self[:status_code].read first_line[1]
129
+ self[:status_mesg].read first_line[2..-1].join(' ')
103
130
  end
104
131
 
105
- # String representation of data.
106
- # @return [String]
107
- def to_s
132
+ def raise_on_bad_version_status
108
133
  raise FormatError, 'Missing #status_code.' if self.status_code.empty?
109
134
  raise FormatError, 'Missing #status_mesg.' if self.status_mesg.empty?
110
135
  raise FormatError, 'Missing #version.' if self.version.empty?
111
-
112
- str = +''
113
- str << self.version << ' ' << self.status_code << ' ' << self.status_mesg << "\r\n"
114
- str << self[:headers].to_s if self[:headers].given?
115
- str << self.body
116
136
  end
117
137
  end
118
138
  end
@@ -77,7 +77,7 @@ module PacketGen
77
77
  # directly called
78
78
  def added_to_packet(packet)
79
79
  igmp_idx = packet.headers.size
80
- packet.instance_eval "def igmpize() @headers[#{igmp_idx}].igmpize; end"
80
+ packet.instance_eval "def igmpize() @headers[#{igmp_idx}].igmpize; end" # def igmpize() @headers[2].igmpize; end
81
81
  end
82
82
 
83
83
  # Get human readbale type
@@ -55,7 +55,7 @@ module PacketGen
55
55
  # option data
56
56
  # @return [String]
57
57
  define_field :data, Types::String, optional: ->(h) { h.length > 2 },
58
- builder: ->(h, t) { t.new(length_from: -> { h.length - 2 }) }
58
+ builder: ->(h, t) { t.new(length_from: -> { h.length - 2 }) }
59
59
 
60
60
  # @!attribute copied
61
61
  # 1-bit copied flag from {#type} field
@@ -161,6 +161,7 @@ module PacketGen
161
161
 
162
162
  # Strict Source and Record Route IP option
163
163
  class SSRR < LSRR; end
164
+
164
165
  # Record Route IP option
165
166
  class RR < LSRR; end
166
167
 
@@ -49,6 +49,8 @@ module PacketGen
49
49
  # @return [Integer]
50
50
  define_field :a8, Types::Int16
51
51
 
52
+ # rubocop:disable Metrics/AbcSize
53
+
52
54
  # Read a colon-delimited address
53
55
  # @param [String] str
54
56
  # @return [self]
@@ -69,6 +71,7 @@ module PacketGen
69
71
  self.a8 = addri & 0xffff
70
72
  self
71
73
  end
74
+ # rubocop:enable Metrics/AbcSize
72
75
 
73
76
  # Addr6 in human readable form (colon-delimited hex string)
74
77
  # @return [String]
@@ -31,32 +31,10 @@ module PacketGen
31
31
  case iph
32
32
  when IP
33
33
  iph.dst = '224.0.0.251'
34
- llh = ll_header(self)
35
- mac = case llh
36
- when Eth
37
- llh[:dst]
38
- when Dot11
39
- if llh.to_ds?
40
- llh[:mac3]
41
- else
42
- llh[:mac1]
43
- end
44
- end
45
- mac.from_human('01:00:5E:00:00:FB')
34
+ dst_mac.from_human('01:00:5E:00:00:FB')
46
35
  when IPv6
47
36
  iph.dst = 'ff02::fb'
48
- llh = ll_header(self)
49
- mac = case llh
50
- when Eth
51
- llh[:dst]
52
- when Dot11
53
- if llh.to_ds?
54
- llh[:mac3]
55
- else
56
- llh[:mac1]
57
- end
58
- end
59
- mac.from_human('33:33:00:00:00:FB')
37
+ dst_mac.from_human('33:33:00:00:00:FB')
60
38
  end
61
39
  end
62
40
 
@@ -67,12 +45,28 @@ module PacketGen
67
45
  # Needed by new bind API.
68
46
  def added_to_packet(packet)
69
47
  mdns_idx = packet.headers.size
70
- packet.instance_eval "def mdnsize() @headers[#{mdns_idx}].mdnsize; end"
48
+ packet.instance_eval "def mdnsize() @headers[#{mdns_idx}].mdnsize; end" # def mdnsize() @headers[4].mdnsize; end
71
49
  return unless packet.is? 'UDP'
72
50
  return unless packet.udp.sport.zero?
73
51
 
74
52
  packet.udp.sport = UDP_PORT
75
53
  end
54
+
55
+ private
56
+
57
+ def dst_mac
58
+ llh = ll_header(self)
59
+ case llh
60
+ when Eth
61
+ llh[:dst]
62
+ when Dot11
63
+ if llh.to_ds?
64
+ llh[:mac3]
65
+ else
66
+ llh[:mac1]
67
+ end
68
+ end
69
+ end
76
70
  end
77
71
 
78
72
  self.add_class MDNS
@@ -68,7 +68,7 @@ module PacketGen
68
68
  # directly called
69
69
  def added_to_packet(packet)
70
70
  mld_idx = packet.headers.size
71
- packet.instance_eval "def mldize() @headers[#{mld_idx}].mldize; end"
71
+ packet.instance_eval "def mldize() @headers[#{mld_idx}].mldize; end" # def mldize() @headers[3].mldize; end
72
72
  end
73
73
 
74
74
  # Fixup IP header according to RFC 2710:
@@ -77,17 +77,15 @@ module PacketGen
77
77
  # Compute and set Fletcher-16 checksum on LSA
78
78
  # @return [Integer]
79
79
  def calc_checksum
80
- bytes = to_s[2..-1].unpack('C*')
81
-
82
80
  c0 = c1 = 0
83
- bytes.each do |byte|
81
+ to_s[2..-1].unpack('C*').each do |byte|
84
82
  c0 += byte
85
83
  c1 += c0
86
84
  end
87
85
  c0 %= 255
88
86
  c1 %= 255
89
87
 
90
- x = ((sz - 16 - 1) * c0 - c1) % 255
88
+ x = ((sz - 17) * c0 - c1) % 255
91
89
  x += 255 if x <= 0
92
90
  y = 255 * 2 - c0 - x
93
91
  y -= 255 if y > 255
@@ -167,7 +167,7 @@ module PacketGen
167
167
  # directly called
168
168
  def added_to_packet(packet)
169
169
  ospf_idx = packet.headers.size
170
- packet.instance_eval "def ospfize(**kwargs) @headers[#{ospf_idx}].ospfize(**kwargs); end"
170
+ packet.instance_eval "def ospfize(**kwargs) @headers[#{ospf_idx}].ospfize(**kwargs); end" # def ospfize(**kwargs) @headers[2].ospfize(**kwargs); end
171
171
  end
172
172
 
173
173
  # Compute checksum and set +checksum+ field
@@ -71,11 +71,8 @@ module PacketGen
71
71
  # @param [String] str
72
72
  # @return [void]
73
73
  def from_human(str)
74
- pfx, len = str.split('/')
75
- len = (len || 128).to_i
76
- addr = IPv6::Addr.new.from_human(pfx)
77
- ary_size = (len + 31) / 32
78
- ary = addr.to_a[0...ary_size * 2]
74
+ ary, len = ary_and_prefix_len_from_str(str)
75
+
79
76
  self.prefix.clear
80
77
  ary.each_with_index do |v, i|
81
78
  if i.even?
@@ -86,6 +83,18 @@ module PacketGen
86
83
  end
87
84
  self.length = len
88
85
  end
86
+
87
+ private
88
+
89
+ def ary_and_prefix_len_from_str(str)
90
+ pfx, len = str.split('/')
91
+ len = (len || 128).to_i
92
+ addr = IPv6::Addr.new.from_human(pfx)
93
+ ary_size = (len + 31) / 32
94
+ ary = addr.to_a[0...ary_size * 2]
95
+
96
+ [ary, len]
97
+ end
89
98
  end
90
99
 
91
100
  # Array of {IPv6Prefix}
@@ -35,7 +35,7 @@ module PacketGen
35
35
  # @return [String]
36
36
  def to_human
37
37
  "Link<type:#{type},metric:#{metric},id:#{interface_id}," \
38
- "neighbor_id:#{neighbor_interface_id},neighbor_router:#{neighbor_router_id}>"
38
+ "neighbor_id:#{neighbor_interface_id},neighbor_router:#{neighbor_router_id}>"
39
39
  end
40
40
  end
41
41