class Mu::Pcap::Ethernet
Constants
- ADDR_TO_BYTES
- ETHERTYPE_802_1Q
- ETHERTYPE_ARP
- ETHERTYPE_IP
- ETHERTYPE_IP6
- ETHERTYPE_PPPOE_SESSION
- FMT_HEADER
- FMT_MAC
- FMT_n
- MAC_TEMPLATE
- PPP_IP
- PPP_IPV6
Attributes
dst[RW]
src[RW]
type[RW]
vlan[RW]
Public Class Methods
from_bytes(bytes)
click to toggle source
# File lib/woolen_common/pcap/mu/pcap/ethernet.rb, line 46 def self.from_bytes bytes if bytes.length < 14 raise ParseError, "Truncated Ethernet header: expected 14 bytes, got #{bytes.length} bytes" end dst = bytes.slice!(0, 6).unpack FMT_MAC dst = MAC_TEMPLATE % dst src = bytes.slice!(0, 6).unpack FMT_MAC src = MAC_TEMPLATE % src type = bytes.slice!(0, 2).unpack(FMT_n)[0] if type == ETHERTYPE_802_1Q @vlan = true else @vlan = false end while (type == ETHERTYPE_802_1Q) # Skip 4 bytes for 802.1q vlan tag field bytes.slice!(0, 2) type = bytes.slice!(0, 2).unpack(FMT_n)[0] end ethernet = Ethernet.new src, dst, type ethernet.vlan = @vlan ethernet.payload = bytes ethernet.payload_raw = bytes begin case type when ETHERTYPE_IP ethernet.payload = IPv4.from_bytes bytes when ETHERTYPE_IP6 ethernet.payload = IPv6.from_bytes bytes when ETHERTYPE_PPPOE_SESSION # Remove PPPoE/PPP session layer ethernet.payload = bytes ethernet.remove_pppoe! else ethernet.payload = bytes end rescue ParseError => e Pcap.warning e end return ethernet end
new(src=nil, dst=nil, type=0)
click to toggle source
Calls superclass method
# File lib/woolen_common/pcap/mu/pcap/ethernet.rb, line 20 def initialize src=nil, dst=nil, type=0 super() @src = src @dst = dst @type = type @vlan = false end
Public Instance Methods
==(other)
click to toggle source
Calls superclass method
# File lib/woolen_common/pcap/mu/pcap/ethernet.rb, line 154 def == other return super && self.src == other.src && self.dst == other.dst && self.type == other.type end
flow_id()
click to toggle source
# File lib/woolen_common/pcap/mu/pcap/ethernet.rb, line 34 def flow_id if not @payload or @payload.is_a? String return [:ethernet, @src, @dst, @type] else return @payload.flow_id end end
ip?()
click to toggle source
# File lib/woolen_common/pcap/mu/pcap/ethernet.rb, line 89 def ip? return payload.is_a?(IP) end
remove_pppoe!()
click to toggle source
Remove the PPPoE and PPP headers. PPPoE is documented in RFC 2516.
# File lib/woolen_common/pcap/mu/pcap/ethernet.rb, line 109 def remove_pppoe! bytes = self.payload_raw # Remove PPPoE header Pcap.assert bytes.length >= 6, 'Truncated PPPoE header: ' + "expected at least 6 bytes, got #{bytes.length} bytes" version_type, code, session_id, length = bytes.unpack 'CCnn' version = version_type >> 4 & 0b1111 type = version_type & 0b1111 Pcap.assert version == 1, "Unknown PPPoE version: #{version}" Pcap.assert type == 1, "Unknown PPPoE type: #{type}" Pcap.assert code == 0, "Unknown PPPoE code: #{code}" bytes = bytes[6..-1] Pcap.assert bytes.length >= length, 'Truncated PPoE packet: ' + "expected #{length} bytes, got #{bytes.length} bytes" # Remove PPP header Pcap.assert bytes.length >= 2, 'Truncated PPP packet: ' + "expected at least bytes, got #{bytes.length} bytes" protocol_id, = bytes.unpack 'n' bytes = bytes[2..-1] case protocol_id when PPP_IP self.payload = IPv4.from_bytes bytes self.payload_raw = bytes self.type = ETHERTYPE_IP when PPP_IPV6 self.payload = IPv6.from_bytes bytes self.payload_raw = bytes self.type = ETHERTYPE_IP6 else # Failed. Don't update payload or type. raise ParseError, "Unknown PPP protocol: 0x#{'%04x' % protocol_id}" end end
to_s()
click to toggle source
# File lib/woolen_common/pcap/mu/pcap/ethernet.rb, line 145 def to_s if @payload.is_a? String payload = @payload.inspect else payload = @payload.to_s end return "ethernet(%s, %s, %d, %s)" % [@src, @dst, @type, payload] end
vlan?()
click to toggle source
# File lib/woolen_common/pcap/mu/pcap/ethernet.rb, line 30 def vlan? vlan end
write(io)
click to toggle source
# File lib/woolen_common/pcap/mu/pcap/ethernet.rb, line 96 def write io dst_mac = ADDR_TO_BYTES[@dst] ||= @dst.split(':').inject('') { |m, b| m << b.to_i(16).chr } src_mac = ADDR_TO_BYTES[@src] ||= @src.split(':').inject('') { |m, b| m << b.to_i(16).chr } bytes = [dst_mac, src_mac, @type].pack(FMT_HEADER) io.write bytes if @payload.is_a? String io.write @payload else @payload.write io end end