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]