packetgen 3.2.0 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
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