Class: PacketGen::Header::Dot11 Abstract

Inherits:
Base show all
Defined in:
lib/packetgen/header/dot11.rb,
lib/packetgen/header/dot11/data.rb,
lib/packetgen/header/dot11/control.rb,
lib/packetgen/header/dot11/element.rb,
lib/packetgen/header/dot11/sub_mngt.rb,
lib/packetgen/header/dot11/management.rb

Overview

This class is abstract.

This is a base class to demultiplex different IEEE 802.11 frames when parsing.

IEEE 802.11 header A IEEE 802.11 header may consist of at least:

Depending on frame type and subtype, it may also contains:

Header accessors

As Dot11 header types are defined under Dot11 namespace, Dot11 header accessors have a specific name. By example, to access to a Beacon header, accessor is #dot11_beacon.

Create Dot11 packets

As Dot11 is an abstract class, you have to use one of its subclasses to instanciate a IEEE802.11 header.

IEEE802.11 control frames

Control frames may be created this way:

pkt = PacketGen.gen('Dot11::Control', subtype: 13) # Ack control frame
pkt.dot11_control     # => PacketGen::Header::Dot11::Control
# #dot11 is a shortcut for #dot11_control
pkt.dot11             # => PacketGen::Header::Dot11::Control

IEEE802.11 management frames

Management frames may be created this way:

pkt = PacketGen.gen('Dot11::Management')
pkt.dot11_management     # => PacketGen::Header::Dot11::Management
# #dot11 is a shortcut for #dot11_management
pkt.dot11                # => PacketGen::Header::Dot11::Management

Management frames are usually specialized, AssociationRequest by example:

pkt.add('Dot11::AssoReq')
pkt.dot11_assoreq        # => PacketGen::Header::Dot11::AssoReq

Management frames also may contain some elements (see IEEE 802.11 standard):

pkt.dot11_assoreq.add_elements(type: 'SSID', value: "My SSID")
pkt.dot11_assoreq.add_elements(type: 'Rates', value: supported_rates)

IEEE802.11 data frames

Data frames may be created this way:

pkt = PacketGen.gen('Dot11::Data')
pkt.dot11_data     # => PacketGen::Header::Dot11::Data
# #dot11 is a shortcut for #dot11_data
pkt.dot11          # => PacketGen::Header::Dot11::Data

Parse Dot11 packets

When parsing a Dot11 packet, Dot11 subclass is created from type value. Dot11 header should then be accessed through Packet#dot11, whatever the frame type is. But, specialized methods also exist: by example, for a control frame, Packet#dot11_control may also be used.

Send Dot11 packets

To send a Dot11 packet, a RadioTap header is needed:

pkt = PacketGen.gen('RadioTap')
pkt.add('Dot11::Management', mac1: client, mac2: bssid, mac3: bssid)
pkt.add('Dot11::Beacon')
pkt.dot11_beacon.add_element(type: 'SSID', value: 'My SSID')
pkt.dot11_beacon.add_element(type: 'Rates', value: "\x85\x0c")
pkt.calc
pkt.to_w('wlan0')

Author:

  • Sylvain Daubert

Since:

  • 1.4.0

Direct Known Subclasses

Control, Data, Management

Defined Under Namespace

Classes: ATIM, ArrayOfElements, AssoReq, AssoResp, Auth, Beacon, Control, Data, DeAuth, Disas, Element, Management, ProbeReq, ProbeResp, ReAssoReq, ReAssoResp, SubMngt

Constant Summary collapse

TYPES =

Frame types

Since:

  • 1.4.0

%w[Management Control Data Reserved].freeze

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

bind, calculate_and_set_length, #header_id, inherited, #ip_header, #ll_header

Methods included from PacketGen::Headerable

included, #method_name, #packet, #packet=, #parse?, #protocol_name

Methods inherited from Types::Fields

#[], #[]=, #bits_on, define_bit_fields_on, define_field, define_field_after, define_field_before, fields, inherited, #offset_of, #optional?, #optional_fields, #present?, remove_bit_fields_on, remove_field, #sz, #to_h, update_field

Constructor Details

#initialize(options = {}) ⇒ Dot11

Returns a new instance of Dot11.

Parameters:

  • options (Hash) (defaults to: {})

See Also:

Since:

  • 1.4.0



262
263
264
265
# File 'lib/packetgen/header/dot11.rb', line 262

def initialize(options={})
  super
  @applicable_fields = old_fields
end

Class Attribute Details

.fcsBoolean Also known as: fcs?

Set a flag for parsing Dot11 packets. If set to true, parse FCS field, else don’t. Default is true.

Returns:

  • (Boolean)

Since:

  • 1.4.0



184
185
186
# File 'lib/packetgen/header/dot11.rb', line 184

def fcs
  @fcs
end

Instance Attribute Details

#bodyTypes::String

Returns:



218
# File 'lib/packetgen/header/dot11.rb', line 218

define_field :body, Types::String

#fcsTypes::Int32le

Returns:



221
# File 'lib/packetgen/header/dot11.rb', line 221

define_field :fcs, Types::Int32le

#fragment_numberInteger (readonly)

Returns:

  • (Integer)

Since:

  • 2.1.3



254
# File 'lib/packetgen/header/dot11.rb', line 254

define_bit_fields_on :sequence_ctrl, :sequence_number, 12, :fragment_number, 4

#frame_ctrlInteger

Returns 16-bit frame control word.

Returns:

  • (Integer)

    16-bit frame control word



191
# File 'lib/packetgen/header/dot11.rb', line 191

define_field :frame_ctrl, Types::Int16, default: 0

#from_dsBoolean

Returns from_ds flag from #frame_ctrl.

Returns:



245
246
# File 'lib/packetgen/header/dot11.rb', line 245

define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds

#ht_ctrlInteger

Returns 16-bit HT control word.

Returns:

  • (Integer)

    16-bit HT control word



215
# File 'lib/packetgen/header/dot11.rb', line 215

define_field :ht_ctrl, Types::Int32

#idInteger Also known as: duration

Returns 16-bit ID/Duration word.

Returns:

  • (Integer)

    16-bit ID/Duration word



194
# File 'lib/packetgen/header/dot11.rb', line 194

define_field :id, Types::Int16le, default: 0

#mac1Eth::MacAddr

Returns:



197
# File 'lib/packetgen/header/dot11.rb', line 197

define_field :mac1, Eth::MacAddr

#mac2Eth::MacAddr

Returns:



200
# File 'lib/packetgen/header/dot11.rb', line 200

define_field :mac2, Eth::MacAddr

#mac3Eth::MacAddr

Returns:



203
# File 'lib/packetgen/header/dot11.rb', line 203

define_field :mac3, Eth::MacAddr

#mac4Eth::MacAddr

Returns:



209
# File 'lib/packetgen/header/dot11.rb', line 209

define_field :mac4, Eth::MacAddr

#mdBoolean

Returns md flag from #frame_ctrl.

Returns:



245
246
# File 'lib/packetgen/header/dot11.rb', line 245

define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds

#mfBoolean

Returns mf flag from #frame_ctrl.

Returns:



245
246
# File 'lib/packetgen/header/dot11.rb', line 245

define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds

#orderBoolean

Returns order flag from #frame_ctrl.

Returns:



245
246
# File 'lib/packetgen/header/dot11.rb', line 245

define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds

#proto_versionInteger

Returns 2-bit protocol version from #frame_ctrl.

Returns:

  • (Integer)

    2-bit protocol version from #frame_ctrl



245
246
# File 'lib/packetgen/header/dot11.rb', line 245

define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds

#pwmngtBoolean

Returns pwmngt flag from #frame_ctrl.

Returns:



245
246
# File 'lib/packetgen/header/dot11.rb', line 245

define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds

#qos_ctrlInteger

Returns 16-bit QoS control word.

Returns:

  • (Integer)

    16-bit QoS control word



212
# File 'lib/packetgen/header/dot11.rb', line 212

define_field :qos_ctrl, Types::Int16

#retryBoolean

Returns retry flag from #frame_ctrl.

Returns:



245
246
# File 'lib/packetgen/header/dot11.rb', line 245

define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds

#sequence_ctrlInteger

Returns 16-bit sequence control word.

Returns:

  • (Integer)

    16-bit sequence control word



206
# File 'lib/packetgen/header/dot11.rb', line 206

define_field :sequence_ctrl, Types::Int16le, default: 0

#sequence_numberInteger (readonly)

Returns:

  • (Integer)

Since:

  • 2.1.3



254
# File 'lib/packetgen/header/dot11.rb', line 254

define_bit_fields_on :sequence_ctrl, :sequence_number, 12, :fragment_number, 4

#subtypeInteger

Returns 4-bit frame subtype from #frame_ctrl.

Returns:



245
246
# File 'lib/packetgen/header/dot11.rb', line 245

define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds

#to_dsBoolean

Returns to_ds flag from #frame_ctrl.

Returns:



245
246
# File 'lib/packetgen/header/dot11.rb', line 245

define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds

#typeInteger

Returns 2-bit frame type from #frame_ctrl.

Returns:



245
246
# File 'lib/packetgen/header/dot11.rb', line 245

define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds

#wepBoolean

Returns wep flag from #frame_ctrl.

Returns:



245
246
# File 'lib/packetgen/header/dot11.rb', line 245

define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds

Instance Method Details

#added_to_packet(packet) ⇒ void

This method returns an undefined value.

Callback called when a Dot11 header is added to a packet Here, add #dot11 method as a shortcut to existing #dot11_(control|management|data).

Parameters:

Since:

  • 1.4.0



355
356
357
358
359
# File 'lib/packetgen/header/dot11.rb', line 355

def added_to_packet(packet)
  return if packet.respond_to? :dot11

  packet.instance_eval("def dot11(arg=nil); header(#{self.class}, arg); end") # def dot11(arg=nil); header(Dot11, arg); end
end

#calc_checksumInteger

Compute checksum and set fcs field

Returns:

  • (Integer)

Since:

  • 1.4.0



306
307
308
309
310
# File 'lib/packetgen/header/dot11.rb', line 306

def calc_checksum
  fcs = Zlib.crc32(to_s[0...-4])
  self.fcs = fcs
  fcs
end

#fieldsArray<Symbol>

Get all used field names

Returns:

  • (Array<Symbol>)

Since:

  • 1.4.0



269
270
271
# File 'lib/packetgen/header/dot11.rb', line 269

def fields
  @applicable_fields
end

#human_typeString

Get human readable type

Returns:

  • (String)

Since:

  • 1.4.0



320
321
322
# File 'lib/packetgen/header/dot11.rb', line 320

def human_type
  TYPES[type]
end

#inspectString

Returns:

  • (String)

Since:

  • 1.4.0



325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/packetgen/header/dot11.rb', line 325

def inspect
  str = if self.instance_of? Dot11
          Inspect.dashed_line("#{self.class} #{human_type}", 1)
        elsif self.respond_to? :human_subtype
          Inspect.dashed_line("#{self.class} #{human_subtype}", 1)
        else
          Inspect.dashed_line(self.class.to_s, 1)
        end

  define_applicable_fields
  @applicable_fields.each do |attr|
    next if attr == :body

    str << Inspect.inspect_attribute(attr, @fields[attr], 1)
  end
  str
end

#old_fieldsObject

Since:

  • 1.4.0



258
# File 'lib/packetgen/header/dot11.rb', line 258

alias old_fields fields

#old_readObject

Since:

  • 1.4.0



274
# File 'lib/packetgen/header/dot11.rb', line 274

alias old_read read

#read(str) ⇒ Dot11

Populate object from a binary string

Parameters:

  • str (String)

Returns:

  • (Dot11)

    may return a subclass object if a more specific class may be determined

Since:

  • 1.4.0



280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/packetgen/header/dot11.rb', line 280

def read(str)
  fcs = Dot11.fcs?

  if self.instance_of? Dot11
    return self if str.nil?

    force_binary str
    self[:frame_ctrl].read str[0, 2]

    case type
    when 0
      Dot11::Management.new.read str
    when 1
      Dot11::Control.new.read str
    when 2
      Dot11::Data.new.read str
    else
      private_read str, fcs
    end
  else
    private_read str, fcs
  end
end

#to_sString

Returns:

  • (String)

Since:

  • 1.4.0



313
314
315
316
# File 'lib/packetgen/header/dot11.rb', line 313

def to_s
  define_applicable_fields
  @applicable_fields.map { |f| force_binary @fields[f].to_s }.join
end

#to_w(iface) ⇒ void

This method returns an undefined value.

send Dot11 packet on wire.

Parameters:

  • iface (String)

    interface name

Since:

  • 1.4.0



346
347
348
# File 'lib/packetgen/header/dot11.rb', line 346

def to_w(iface)
  Inject.inject(iface: iface, data: self)
end