lib/packetgen/header/eth.rb in packetgen-0.3.0 vs lib/packetgen/header/eth.rb in packetgen-1.0.0
- old
+ new
@@ -1,11 +1,36 @@
+# This file is part of PacketGen
+# See https://github.com/sdaubert/packetgen for more informations
+# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
+# This program is published under MIT license.
+
module PacketGen
module Header
- # Ethernet header class
+ # An Ethernet header consists of:
+ # * a destination MAC address ({MacAddr}),
+ # * a source MAC address (MacAddr),
+ # * a {#ethertype} ({Int16}),
+ # * and a body (a {String} or another Header class).
+ #
+ # == Create a Ethernet header
+ # # standalone
+ # eth = PacketGen::Header::Eth.new
+ # # in a packet
+ # pkt = PacketGen.gen('Eth')
+ # # access to Ethernet header
+ # pkt.eth # => PacketGen::Header::Eth
+ #
+ # == Ethernet attributes
+ # eth.dst = "00:01:02:03:04:05'
+ # eth.src # => "00:01:01:01:01:01"
+ # eth[:src] # => PacketGen::Header::Eth::MacAddr
+ # eth.ethertype # => 16-bit Integer
+ # eth.body = "This is a body"
+ #
# @author Sylvain Daubert
- class Eth < Struct.new(:dst, :src, :proto, :body)
+ class Eth < Struct.new(:dst, :src, :ethertype, :body)
include StructFu
include HeaderMethods
extend HeaderClassMethods
# Ethernet MAC address, as a group of 6 bytes
@@ -28,14 +53,14 @@
Int8.new(options[:a4]),
Int8.new(options[:a5])
end
- # Parse a string to populate MacAddr
+ # Read a human-readable string to populate +MacAddr+
# @param [String] str
# @return [self]
- def parse(str)
+ def from_human(str)
return self if str.nil?
bytes = str.split(/:/)
unless bytes.size == 6
raise ArgumentError, 'not a MAC address'
end
@@ -46,11 +71,11 @@
self[:a4].read(bytes[4].to_i(16))
self[:a5].read(bytes[5].to_i(16))
self
end
- # Read a MacAddr from a string
+ # Read a +MacAddr+ from a binary string
# @param [String] str binary string
# @return [self]
def read(str)
return self if str.nil?
raise ParseError, 'string too short for Eth' if str.size < self.sz
@@ -63,13 +88,13 @@
[:a0, :a1, :a2, :a3, :a4, :a5].each do |sym|
class_eval "def #{sym}; self[:#{sym}].to_i; end\n" \
"def #{sym}=(v); self[:#{sym}].read v; end"
end
- # Addr in human readable form (dotted format)
+ # +MacAddr+ in human readable form (colon format)
# @return [String]
- def to_x
+ def to_human
members.map { |m| "#{'%02x' % self[m]}" }.join(':')
end
end
# @private snap length for PCAPRUB
@@ -80,15 +105,15 @@
PCAP_TIMEOUT = 1
# @param [Hash] options
# @option options [String] :dst MAC destination address
# @option options [String] :src MAC source address
- # @option options [Integer] :proto
+ # @option options [Integer] :ethertype
def initialize(options={})
- super MacAddr.new.parse(options[:dst] || '00:00:00:00:00:00'),
- MacAddr.new.parse(options[:src] || '00:00:00:00:00:00'),
- Int16.new(options[:proto] || 0),
+ super MacAddr.new.from_human(options[:dst] || '00:00:00:00:00:00'),
+ MacAddr.new.from_human(options[:src] || '00:00:00:00:00:00'),
+ Int16.new(options[:ethertype] || 0),
StructFu::String.new.read(options[:body])
end
# Read a Eth header from a string
# @param [String] str binary string
@@ -97,51 +122,51 @@
return self if str.nil?
raise ParseError, 'string too short for Eth' if str.size < self.sz
force_binary str
self[:dst].read str[0, 6]
self[:src].read str[6, 6]
- self[:proto].read str[12, 2]
+ self[:ethertype].read str[12, 2]
self[:body].read str[14..-1]
self
end
# Get MAC destination address
# @return [String]
def dst
- self[:dst].to_x
+ self[:dst].to_human
end
# Set MAC destination address
# @param [String] addr
# @return [String]
def dst=(addr)
- self[:dst].parse addr
+ self[:dst].from_human addr
end
# Get MAC source address
# @return [String]
def src
- self[:src].to_x
+ self[:src].to_human
end
# Set MAC source address
# @param [String] addr
# @return [String]
def src=(addr)
- self[:src].parse addr
+ self[:src].from_human addr
end
- # Get protocol field
+ # Get ethertype field
# @return [Integer]
- def proto
- self[:proto].to_i
+ def ethertype
+ self[:ethertype].to_i
end
- # Set protocol field
- # @param [Integer] proto
+ # Set ethertype field
+ # @param [Integer] type
# @return [Integer]
- def proto=(proto)
- self[:proto].value = proto
+ def ethertype=(type)
+ self[:ethertype].value = type
end
# send Eth packet on wire.
# @param [String] iface interface name
# @return [void]