-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
280 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
Feature: EthernetHeader | ||
Scenario: create an Ethernet header | ||
When I create a packet with: | ||
"""ruby | ||
Pio::EthernetHeader.new( | ||
destination_mac: 'ff:ff:ff:ff:ff:ff', | ||
source_mac: '00:26:82:eb:ea:d1', | ||
ether_type: Pio::Ethernet::Type::IPV4 | ||
) | ||
""" | ||
Then the packet has the following fields and values: | ||
| field | value | | ||
| class | Pio::EthernetHeader | | ||
| destination_mac | ff:ff:ff:ff:ff:ff | | ||
| source_mac | 00:26:82:eb:ea:d1 | | ||
| ether_type.to_hex | 0x08, 0x00 | | ||
|
||
Scenario: create a VLAN-tagged Ethernet header | ||
When I create a packet with: | ||
"""ruby | ||
Pio::EthernetHeader.new( | ||
destination_mac: 'ff:ff:ff:ff:ff:ff', | ||
source_mac: '00:26:82:eb:ea:d1', | ||
ether_type: Pio::Ethernet::Type::VLAN, | ||
vlan_pcp: 5, | ||
vlan_cfi: 0, | ||
vlan_vid: 100 | ||
) | ||
""" | ||
Then the packet has the following fields and values: | ||
| field | value | | ||
| class | Pio::EthernetHeader | | ||
| destination_mac | ff:ff:ff:ff:ff:ff | | ||
| source_mac | 00:26:82:eb:ea:d1 | | ||
| ether_type.to_hex | 0x81, 0x00 | | ||
| vlan_pcp | 5 | | ||
| vlan_cfi | 0 | | ||
| vlan_vid | 100 | | ||
|
||
Scenario: read an Ethernet header | ||
Given I use the fixture "ethernet_header" | ||
When I create a packet with: | ||
"""ruby | ||
Pio::EthernetHeader.read(eval(IO.read('ethernet_header.rb'))) | ||
""" | ||
Then the packet has the following fields and values: | ||
| field | value | | ||
| class | Pio::EthernetHeader | | ||
| destination_mac | ff:ff:ff:ff:ff:ff | | ||
| source_mac | 00:26:82:eb:ea:d1 | | ||
| ether_type.to_hex | 0x08, 0x00 | | ||
|
||
Scenario: read a VLAN-tagged Ethernet header | ||
Given I use the fixture "ethernet_header" | ||
When I create a packet with: | ||
"""ruby | ||
Pio::EthernetHeader.read(eval(IO.read('vlan_ethernet_header.rb'))) | ||
""" | ||
Then the packet has the following fields and values: | ||
| field | value | | ||
| class | Pio::EthernetHeader | | ||
| destination_mac | ff:ff:ff:ff:ff:ff | | ||
| source_mac | 00:26:82:eb:ea:d1 | | ||
| ether_type.to_hex | 0x81, 0x00 | | ||
| vlan_pcp | 5 | | ||
| vlan_cfi | 0 | | ||
| vlan_vid | 100 | | ||
|
||
Scenario: convert Ethernet header to Ruby code | ||
When I eval the following Ruby code: | ||
"""ruby | ||
Pio::EthernetHeader.new( | ||
destination_mac: 'ff:ff:ff:ff:ff:ff', | ||
source_mac: '00:26:82:eb:ea:d1', | ||
ether_type: Pio::Ethernet::Type::IPV4 | ||
).to_ruby | ||
""" | ||
Then the result of eval should be: | ||
"""ruby | ||
[ | ||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # destination_mac | ||
0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # source_mac | ||
0x08, 0x00, # ether_type | ||
].pack('C14') | ||
""" | ||
|
||
Scenario: convert VLAN-tagged Ethernet header to Ruby code | ||
When I eval the following Ruby code: | ||
"""ruby | ||
Pio::EthernetHeader.new( | ||
destination_mac: 'ff:ff:ff:ff:ff:ff', | ||
source_mac: '00:26:82:eb:ea:d1', | ||
ether_type: Pio::Ethernet::Type::VLAN, | ||
vlan_pcp: 5, | ||
vlan_cfi: 0, | ||
vlan_vid: 100 | ||
).to_ruby | ||
""" | ||
Then the result of eval should be: | ||
"""ruby | ||
[ | ||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # destination_mac | ||
0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # source_mac | ||
0x81, 0x00, # ether_type | ||
0b101_0_000001100100, # vlan_pcp, vlan_cfi, vlan_vid | ||
0x81, 0x00, # ether_type_vlan | ||
].pack('C14nC2') | ||
""" | ||
|
||
Scenario: EthernetHeader instance inspection | ||
When I eval the following Ruby code: | ||
"""ruby | ||
Pio::EthernetHeader.new( | ||
destination_mac: 'ff:ff:ff:ff:ff:ff', | ||
source_mac: '00:26:82:eb:ea:d1', | ||
ether_type: Pio::Ethernet::Type::IPV4, | ||
).inspect | ||
""" | ||
Then the result of eval should be: | ||
""" | ||
#<EthernetHeader destination_mac: "ff:ff:ff:ff:ff:ff", source_mac: "00:26:82:eb:ea:d1", ether_type: 0x0800> | ||
""" | ||
|
||
Scenario: VLAN-tagged EthernetHeader instance inspection | ||
When I eval the following Ruby code: | ||
"""ruby | ||
Pio::EthernetHeader.new( | ||
destination_mac: 'ff:ff:ff:ff:ff:ff', | ||
source_mac: '00:26:82:eb:ea:d1', | ||
ether_type: Pio::Ethernet::Type::VLAN, | ||
vlan_pcp: 5, | ||
vlan_cfi: 0, | ||
vlan_vid: 100 | ||
).inspect | ||
""" | ||
Then the result of eval should be: | ||
""" | ||
#<EthernetHeader destination_mac: "ff:ff:ff:ff:ff:ff", source_mac: "00:26:82:eb:ea:d1", ether_type: 0x8100, vlan_pcp: 5, vlan_cfi: 0, vlan_vid: 100> | ||
""" | ||
|
||
Scenario: EthernetHeader class inspection | ||
When I eval the following Ruby code: | ||
"""ruby | ||
Pio::EthernetHeader.inspect | ||
""" | ||
Then the result of eval should be: | ||
""" | ||
EthernetHeader(destination_mac: mac_address, source_mac: mac_address, ether_type: uint16, vlan_pcp: bit3, vlan_cfi: bit1, vlan_vid: bit12) | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[ | ||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # destination_mac | ||
0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # source_mac | ||
0x08, 0x00, # ether_type | ||
].pack('C*') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[ | ||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # destination_mac | ||
0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # source_mac | ||
0x81, 0x00, # ether_type | ||
0b101_0_000001100100, # vlan_pcp, vlan_cfi, vlan_vid | ||
0x81, 0x00, # ether_type_vlan | ||
].pack('C14nC2') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,66 @@ | ||
require 'pio/ruby_dumper' | ||
require 'pio/type/mac_address' | ||
|
||
module Pio | ||
# Adds ethernet_header macro. | ||
module EthernetHeader | ||
# EtherType constants for ethernet_header.ether_type. | ||
module EtherType | ||
module Ethernet | ||
# EtherType constants | ||
module Type | ||
ARP = 0x0806 | ||
IPV4 = 0x0800 | ||
VLAN = 0x8100 | ||
LLDP = 0x88cc | ||
end | ||
|
||
# Ethernet header parser | ||
class Parser < BinData::Record | ||
endian :big | ||
|
||
mac_address :destination_mac | ||
mac_address :source_mac | ||
uint16 :ether_type | ||
bit3 :vlan_pcp_internal, onlyif: :vlan? | ||
bit1 :vlan_cfi, onlyif: :vlan? | ||
bit12 :vlan_vid_internal, onlyif: :vlan? | ||
uint16 :ether_type_vlan, value: :ether_type, onlyif: :vlan? | ||
end | ||
|
||
# This method smells of :reek:TooManyStatements | ||
# rubocop:disable MethodLength | ||
def self.included(klass) | ||
def klass.ethernet_header(options) | ||
def klass.ethernet_header(options = nil) | ||
mac_address :destination_mac | ||
mac_address :source_mac | ||
uint16 :ether_type, value: options.fetch(:ether_type) | ||
bit3 :vlan_pcp_internal, onlyif: :vlan? | ||
if options | ||
uint16 :ether_type, value: options.fetch(:ether_type) | ||
else | ||
uint16 :ether_type | ||
end | ||
bit3 :vlan_pcp, onlyif: :vlan? | ||
bit1 :vlan_cfi, onlyif: :vlan? | ||
bit12 :vlan_vid_internal, onlyif: :vlan? | ||
bit12 :vlan_vid, onlyif: :vlan? | ||
uint16 :ether_type_vlan, value: :ether_type, onlyif: :vlan? | ||
end | ||
end | ||
# rubocop:enable MethodLength | ||
|
||
def ethernet_header | ||
Parser.new(destination_mac: destination_mac, | ||
source_mac: source_mac, | ||
ether_type: ether_type) | ||
end | ||
private | ||
|
||
def vlan_vid | ||
vlan? ? vlan_vid_internal : 0xffff | ||
def vlan? | ||
ether_type == Type::VLAN | ||
end | ||
end | ||
|
||
def vlan_pcp | ||
vlan? ? vlan_pcp_internal : 0 | ||
# Ethernet header generator/parser | ||
class EthernetHeader < BinData::Record | ||
include Ethernet | ||
include RubyDumper | ||
|
||
endian :big | ||
|
||
ethernet_header | ||
|
||
# rubocop:disable LineLength | ||
def self.inspect | ||
'EthernetHeader(destination_mac: mac_address, source_mac: mac_address, ether_type: uint16, vlan_pcp: bit3, vlan_cfi: bit1, vlan_vid: bit12)' | ||
end | ||
# rubocop:enable LineLength | ||
|
||
def vlan? | ||
ether_type == EtherType::VLAN | ||
# rubocop:disable LineLength | ||
def inspect | ||
if vlan? | ||
%(#<EthernetHeader destination_mac: "#{destination_mac}", source_mac: "#{source_mac}", ether_type: #{format('0x%04x', ether_type)}, vlan_pcp: #{vlan_pcp}, vlan_cfi: #{vlan_cfi}, vlan_vid: #{vlan_vid}>) | ||
else | ||
%(#<EthernetHeader destination_mac: "#{destination_mac}", source_mac: "#{source_mac}", ether_type: #{format('0x%04x', ether_type)}>) | ||
end | ||
end | ||
# rubocop:enable LineLength | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.