Class: PacketFu::EthHeader

Inherits:
Struct
  • Object
show all
Includes:
StructFu
Defined in:
lib/packetfu/protos/eth/header.rb

Overview

EthHeader is a complete Ethernet struct, used in EthPacket. It's the base header for all other protocols, such as IPHeader, TCPHeader, etc.

For more on the construction on MAC addresses, see en.wikipedia.org/wiki/MAC_address

TODO: Need to come up with a good way of dealing with vlan tagging. Having a usually empty struct member seems weird, but there may not be another way to do it if I want to preserve the Eth-ness of vlan-tagged 802.1Q packets. Also, may as well deal with 0x88a8 as well (en.wikipedia.org/wiki/802.1ad)

Header Definition

EthMac  :eth_dst                     # See EthMac
EthMac  :eth_src                     # See EthMac
Int16   :eth_proto, Default: 0x8000  # IP 0x0800, Arp 0x0806
String  :body

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from StructFu

#clone, #set_endianness, #sz, #typecast

Methods inherited from Struct

#force_binary

Constructor Details

#initialize(args = {}) ⇒ EthHeader

Returns a new instance of EthHeader


150
151
152
153
154
155
156
157
# File 'lib/packetfu/protos/eth/header.rb', line 150

def initialize(args={})
  super(
    EthMac.new.read(args[:eth_dst]),
    EthMac.new.read(args[:eth_src]),
    Int16.new(args[:eth_proto] || 0x0800),
    StructFu::String.new.read(args[:body])
  )
end

Instance Attribute Details

#bodyObject

Returns the value of attribute body

Returns:

  • (Object)

    the current value of body


147
148
149
# File 'lib/packetfu/protos/eth/header.rb', line 147

def body
  @body
end

#eth_dstObject

Getter for the Ethernet destination address.


147
148
149
# File 'lib/packetfu/protos/eth/header.rb', line 147

def eth_dst
  @eth_dst
end

#eth_protoObject

Getter for the Ethernet protocol number.


147
148
149
# File 'lib/packetfu/protos/eth/header.rb', line 147

def eth_proto
  @eth_proto
end

#eth_srcObject

Getter for the Ethernet source address.


147
148
149
# File 'lib/packetfu/protos/eth/header.rb', line 147

def eth_src
  @eth_src
end

Class Method Details

.mac2str(mac) ⇒ Object

Converts a readable MAC (11:22:33:44:55:66) to a binary string. Readable MAC's may be split on colons, dots, spaces, or underscores.

irb> PacketFu::EthHeader.mac2str(“11:22:33:44:55:66”)

#=> “021"3DUf”


194
195
196
197
198
199
200
201
# File 'lib/packetfu/protos/eth/header.rb', line 194

def self.mac2str(mac)
  if mac.split(/[:\x2d\x2e\x5f]+/).size == 6
    ret =	mac.split(/[:\x2d\x2e\x20\x5f]+/).collect {|x| x.to_i(16)}.pack("C6")
  else
    raise ArgumentError, "Unkown format for mac address."
  end
  return ret
end

.str2mac(mac = '') ⇒ Object

Converts a binary string to a readable MAC (11:22:33:44:55:66).

irb> PacketFu::EthHeader.str2mac(“x11x22x33x44x55x66”)

#=> “11:22:33:44:55:66”


208
209
210
211
212
# File 'lib/packetfu/protos/eth/header.rb', line 208

def self.str2mac(mac='')
  if mac.to_s.size == 6 && mac.kind_of?(::String)
    ret = mac.unpack("C6").map {|x| sprintf("%02x",x)}.join(":")
  end
end

Instance Method Details

#eth_daddrObject Also known as: eth_dst_readable

Gets the destination MAC address in a more readable way.


234
235
236
# File 'lib/packetfu/protos/eth/header.rb', line 234

def eth_daddr
  EthHeader.str2mac(self[:eth_dst].to_s)
end

#eth_daddr=(mac) ⇒ Object

Set the destination MAC address in a more readable way.


227
228
229
230
231
# File 'lib/packetfu/protos/eth/header.rb', line 227

def eth_daddr=(mac)
  mac = EthHeader.mac2str(mac)
  self[:eth_dst].read mac
  self[:eth_dst]
end

#eth_proto_readableObject


243
244
245
# File 'lib/packetfu/protos/eth/header.rb', line 243

def eth_proto_readable
  "0x%04x" % eth_proto
end

#eth_saddrObject Also known as: eth_src_readable

Gets the source MAC address in a more readable way.


222
223
224
# File 'lib/packetfu/protos/eth/header.rb', line 222

def eth_saddr
  EthHeader.str2mac(self[:eth_src].to_s)
end

#eth_saddr=(mac) ⇒ Object

Sets the source MAC address in a more readable way.


215
216
217
218
219
# File 'lib/packetfu/protos/eth/header.rb', line 215

def eth_saddr=(mac)
  mac = EthHeader.mac2str(mac)
  self[:eth_src].read mac
  self[:eth_src]
end

#read(str) ⇒ Object

Reads a string to populate the object.


178
179
180
181
182
183
184
185
186
# File 'lib/packetfu/protos/eth/header.rb', line 178

def read(str)
  force_binary(str)
  return self if str.nil?
  self[:eth_dst].read str[0,6]
  self[:eth_src].read str[6,6]
  self[:eth_proto].read str[12,2]
  self[:body].read str[14,str.size]
  self
end

#to_sObject

Returns the object in string form.


173
174
175
# File 'lib/packetfu/protos/eth/header.rb', line 173

def to_s
  self.to_a.map {|x| x.to_s}.join
end