pio 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +46 -12
  3. data/README.md +131 -116
  4. data/Rakefile +7 -92
  5. data/examples/arp_new.rb +16 -0
  6. data/examples/arp_read.rb +4 -0
  7. data/examples/dhcp_new.rb +30 -0
  8. data/examples/dhcp_read.rb +4 -0
  9. data/examples/icmp_new.rb +21 -0
  10. data/examples/icmp_read.rb +4 -0
  11. data/examples/lldp_new.rb +4 -0
  12. data/examples/lldp_read.rb +4 -0
  13. data/lib/pio.rb +6 -12
  14. data/lib/pio/arp.rb +7 -19
  15. data/lib/pio/arp/frame.rb +8 -12
  16. data/lib/pio/arp/message.rb +12 -25
  17. data/lib/pio/arp/reply.rb +30 -30
  18. data/lib/pio/arp/request.rb +30 -29
  19. data/lib/pio/dhcp.rb +58 -0
  20. data/lib/pio/dhcp/ack.rb +12 -0
  21. data/lib/pio/dhcp/boot_reply.rb +16 -0
  22. data/lib/pio/dhcp/boot_reply_options.rb +75 -0
  23. data/lib/pio/dhcp/boot_request.rb +16 -0
  24. data/lib/pio/dhcp/boot_request_options.rb +69 -0
  25. data/lib/pio/dhcp/common_options.rb +71 -0
  26. data/lib/pio/dhcp/csum_util.rb +83 -0
  27. data/lib/pio/dhcp/dhcp_field.rb +48 -0
  28. data/lib/pio/dhcp/dhcp_tlv_options.rb +84 -0
  29. data/lib/pio/dhcp/discover.rb +12 -0
  30. data/lib/pio/dhcp/field_util.rb +102 -0
  31. data/lib/pio/dhcp/frame.rb +95 -0
  32. data/lib/pio/dhcp/message.rb +79 -0
  33. data/lib/pio/dhcp/offer.rb +12 -0
  34. data/lib/pio/dhcp/optional_tlv.rb +74 -0
  35. data/lib/pio/dhcp/request.rb +12 -0
  36. data/lib/pio/dhcp/type/dhcp_client_id.rb +21 -0
  37. data/lib/pio/dhcp/type/dhcp_param_list.rb +22 -0
  38. data/lib/pio/dhcp/type/dhcp_string.rb +21 -0
  39. data/lib/pio/icmp.rb +7 -18
  40. data/lib/pio/icmp/frame.rb +38 -40
  41. data/lib/pio/icmp/message.rb +10 -61
  42. data/lib/pio/icmp/options.rb +25 -0
  43. data/lib/pio/icmp/reply.rb +34 -7
  44. data/lib/pio/icmp/request.rb +43 -7
  45. data/lib/pio/ipv4_address.rb +5 -8
  46. data/lib/pio/lldp.rb +22 -62
  47. data/lib/pio/lldp/chassis_id_tlv.rb +7 -13
  48. data/lib/pio/lldp/end_of_lldpdu_value.rb +3 -9
  49. data/lib/pio/lldp/frame.rb +6 -12
  50. data/lib/pio/lldp/management_address_value.rb +4 -10
  51. data/lib/pio/lldp/optional_tlv.rb +5 -10
  52. data/lib/pio/lldp/options.rb +37 -0
  53. data/lib/pio/lldp/organizationally_specific_value.rb +2 -8
  54. data/lib/pio/lldp/port_description_value.rb +2 -8
  55. data/lib/pio/lldp/port_id_tlv.rb +6 -12
  56. data/lib/pio/lldp/system_capabilities_value.rb +2 -8
  57. data/lib/pio/lldp/system_description_value.rb +2 -8
  58. data/lib/pio/lldp/system_name_value.rb +2 -8
  59. data/lib/pio/lldp/ttl_tlv.rb +5 -11
  60. data/lib/pio/mac.rb +4 -9
  61. data/lib/pio/message_type_selector.rb +22 -0
  62. data/lib/pio/options.rb +65 -0
  63. data/lib/pio/parse_error.rb +6 -0
  64. data/lib/pio/type/ethernet_header.rb +3 -2
  65. data/lib/pio/type/ip_address.rb +4 -9
  66. data/lib/pio/type/ipv4_header.rb +12 -17
  67. data/lib/pio/type/mac_address.rb +5 -10
  68. data/lib/pio/type/udp_header.rb +18 -0
  69. data/lib/pio/version.rb +3 -8
  70. data/pio.gemspec +12 -10
  71. data/spec/pio/arp/reply/options_spec.rb +145 -0
  72. data/spec/pio/arp/reply_spec.rb +77 -113
  73. data/spec/pio/arp/request/options_spec.rb +115 -0
  74. data/spec/pio/arp/request_spec.rb +74 -96
  75. data/spec/pio/arp_spec.rb +71 -105
  76. data/spec/pio/dhcp/ack_spec.rb +189 -0
  77. data/spec/pio/dhcp/discover_spec.rb +165 -0
  78. data/spec/pio/dhcp/offer_spec.rb +189 -0
  79. data/spec/pio/dhcp/request_spec.rb +173 -0
  80. data/spec/pio/dhcp_spec.rb +609 -0
  81. data/spec/pio/icmp/reply_spec.rb +102 -95
  82. data/spec/pio/icmp/request_spec.rb +86 -78
  83. data/spec/pio/icmp_spec.rb +153 -146
  84. data/spec/pio/ipv4_address_spec.rb +2 -7
  85. data/spec/pio/lldp/options_spec.rb +188 -0
  86. data/spec/pio/lldp_spec.rb +181 -208
  87. data/spec/pio/mac_spec.rb +3 -8
  88. data/spec/spec_helper.rb +4 -10
  89. metadata +69 -17
  90. data/.gitignore +0 -20
  91. data/.rspec +0 -3
  92. data/.rubocop.yml +0 -1
  93. data/.travis.yml +0 -13
  94. data/Gemfile +0 -37
  95. data/Guardfile +0 -24
  96. data/lib/pio/message_util.rb +0 -19
  97. data/lib/pio/type/config.reek +0 -4
  98. data/lib/pio/util.rb +0 -21
  99. data/pio.org +0 -668
  100. data/pio.org_archive +0 -943
  101. data/rubocop-todo.yml +0 -9
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pio/dhcp/boot_request'
4
+
5
+ module Pio
6
+ class Dhcp
7
+ # Dhcp Discover packet generator
8
+ class Discover < BootRequest
9
+ TYPE = 1
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,102 @@
1
+ # encoding: utf-8
2
+
3
+ module Pio
4
+ class Dhcp
5
+ # Dhcp Field Read Methods.
6
+ module FieldUtil
7
+ def message_type
8
+ get_tlv_field(53)
9
+ end
10
+
11
+ def server_identifier
12
+ get_tlv_field(54)
13
+ end
14
+
15
+ def client_identifier
16
+ get_tlv_field(61)
17
+ end
18
+
19
+ def renewal_time_value
20
+ get_tlv_field(58)
21
+ end
22
+
23
+ def rebinding_time_value
24
+ get_tlv_field(59)
25
+ end
26
+
27
+ def ip_address_lease_time
28
+ get_tlv_field(51)
29
+ end
30
+
31
+ def requested_ip_address
32
+ get_tlv_field(50)
33
+ end
34
+
35
+ def parameters_list
36
+ get_tlv_field(55)
37
+ end
38
+
39
+ def subnet_mask
40
+ get_tlv_field(1)
41
+ end
42
+
43
+ def hw_addr_type
44
+ dhcp.hw_addr_type
45
+ end
46
+
47
+ def hw_addr_len
48
+ dhcp.hw_addr_len
49
+ end
50
+
51
+ def hops
52
+ dhcp.hops
53
+ end
54
+
55
+ def transaction_id
56
+ dhcp.transaction_id
57
+ end
58
+
59
+ def seconds
60
+ dhcp.seconds
61
+ end
62
+
63
+ def bootp_flags
64
+ dhcp.bootp_flags
65
+ end
66
+
67
+ def client_ip_address
68
+ dhcp.client_ip_address
69
+ end
70
+
71
+ def your_ip_address
72
+ dhcp.your_ip_address
73
+ end
74
+
75
+ def next_server_ip_address
76
+ dhcp.next_server_ip_address
77
+ end
78
+
79
+ def relay_agent_ip_address
80
+ dhcp.relay_agent_ip_address
81
+ end
82
+
83
+ def client_mac_address
84
+ dhcp.client_mac_address
85
+ end
86
+
87
+ private
88
+
89
+ def get_tlv(tlv_type)
90
+ tlv = dhcp.optional_tlvs.find do | each |
91
+ each['tlv_type'] == tlv_type
92
+ end
93
+ tlv['tlv_value'] if tlv
94
+ end
95
+
96
+ def get_tlv_field(tlv_type)
97
+ tlv = get_tlv(tlv_type)
98
+ tlv.snapshot if tlv
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,95 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pio/type/ethernet_header'
4
+ require 'pio/type/ipv4_header'
5
+ require 'pio/type/udp_header'
6
+ require 'pio/dhcp/dhcp_field'
7
+ require 'pio/dhcp/field_util'
8
+ require 'pio/dhcp/csum_util'
9
+
10
+ module Pio
11
+ class Dhcp
12
+ # Dhcp frame parser.
13
+ class Frame < BinData::Record
14
+ extend Type::EthernetHeader
15
+ extend Type::IPv4Header
16
+ extend Type::UdpHeader
17
+ include FieldUtil
18
+ include CsumUtil
19
+
20
+ ETHER_TYPE_IP = 0x0800
21
+ IP_PROTOCOL_UDP = 17
22
+ IP_HEADER_LENGTH = 20
23
+ UDP_HEADER_LENGTH = 8
24
+ DHCP_OPTION_FIELD_LENGTH = 60
25
+
26
+ endian :big
27
+
28
+ ethernet_header ether_type: ETHER_TYPE_IP
29
+ ipv4_header ip_protocol: IP_PROTOCOL_UDP,
30
+ ip_header_checksum: -> { ip_sum },
31
+ ip_total_length: -> { ip_len }
32
+ udp_header udp_length: -> { udp_len },
33
+ udp_checksum: -> { udp_sum }
34
+ dhcp_field :dhcp
35
+
36
+ def ip_sum
37
+ ~((ip_csum & 0xffff) + (ip_csum >> 16)) & 0xffff
38
+ end
39
+
40
+ def udp_sum
41
+ ~((udp_csum & 0xffff) + (udp_csum >> 16)) & 0xffff
42
+ end
43
+
44
+ def ip_len
45
+ IP_HEADER_LENGTH + udp_len
46
+ end
47
+
48
+ def udp_len
49
+ UDP_HEADER_LENGTH + dhcp_len
50
+ end
51
+
52
+ def to_binary
53
+ to_binary_s + trail_data
54
+ end
55
+
56
+ private
57
+
58
+ def dhcp_len
59
+ dhcp.num_bytes + trail_data.bytesize
60
+ end
61
+
62
+ def dhcp_binary
63
+ dhcp.to_binary_s
64
+ end
65
+
66
+ def should_padding?
67
+ option_length < DHCP_OPTION_FIELD_LENGTH
68
+ end
69
+
70
+ def option_length
71
+ dhcp.optional_tlvs.num_bytes + 1
72
+ end
73
+
74
+ def trail_data
75
+ if should_padding?
76
+ end_of_pdu + padding
77
+ else
78
+ end_of_pdu
79
+ end
80
+ end
81
+
82
+ def end_of_pdu
83
+ [0xff].pack('C*')
84
+ end
85
+
86
+ def padding
87
+ [0x00].pack('C*') * padding_length
88
+ end
89
+
90
+ def padding_length
91
+ DHCP_OPTION_FIELD_LENGTH - option_length
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,79 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pio/dhcp/frame'
4
+ require 'forwardable'
5
+
6
+ module Pio
7
+ class Dhcp
8
+ # Base class of Dhcp Packet Generator and Parser.
9
+ class Message
10
+ extend Forwardable
11
+
12
+ def_delegators :@frame, :destination_mac
13
+ def_delegators :@frame, :source_mac
14
+ def_delegators :@frame, :ether_type
15
+ def_delegators :@frame, :ip_version
16
+ def_delegators :@frame, :ip_header_length
17
+ def_delegators :@frame, :ip_type_of_service
18
+ def_delegators :@frame, :ip_total_length
19
+ def_delegators :@frame, :ip_identifier
20
+ def_delegators :@frame, :ip_flag
21
+ def_delegators :@frame, :ip_fragment
22
+ def_delegators :@frame, :ip_ttl
23
+ def_delegators :@frame, :ip_protocol
24
+ def_delegators :@frame, :ip_header_checksum
25
+ def_delegators :@frame, :ip_source_address
26
+ def_delegators :@frame, :ip_destination_address
27
+ def_delegators :@frame, :udp_src_port
28
+ def_delegators :@frame, :udp_dst_port
29
+ def_delegators :@frame, :udp_length
30
+ def_delegators :@frame, :udp_checksum
31
+ def_delegators :@frame, :dhcp
32
+ def_delegators :@frame, :optioal_tlvs
33
+ def_delegators :@frame, :boot_message_type
34
+ def_delegators :@frame, :message_type
35
+ def_delegators :@frame, :hw_addr_type
36
+ def_delegators :@frame, :hw_addr_len
37
+ def_delegators :@frame, :hops
38
+ def_delegators :@frame, :transaction_id
39
+ def_delegators :@frame, :seconds
40
+ def_delegators :@frame, :bootp_flags
41
+ def_delegators :@frame, :client_ip_address
42
+ def_delegators :@frame, :your_ip_address
43
+ def_delegators :@frame, :next_server_ip_address
44
+ def_delegators :@frame, :relay_agent_ip_address
45
+ def_delegators :@frame, :client_mac_address
46
+ def_delegators :@frame, :server_host_name
47
+ def_delegators :@frame, :boot_file_name
48
+ def_delegators :@frame, :server_identifier
49
+ def_delegators :@frame, :renewal_time_value
50
+ def_delegators :@frame, :rebinding_time_value
51
+ def_delegators :@frame, :ip_address_lease_time
52
+ def_delegators :@frame, :subnet_mask
53
+ def_delegators :@frame, :client_identifier
54
+ def_delegators :@frame, :requested_ip_address
55
+ def_delegators :@frame, :parameters_list
56
+ def_delegators :@frame, :to_binary
57
+
58
+ def self.create_from(frame)
59
+ message = allocate
60
+ message.instance_variable_set :@frame, frame
61
+ message
62
+ end
63
+
64
+ def initialize(user_options)
65
+ type_merged_options = user_options.merge type: const_type
66
+ options = options_klass.new(type_merged_options)
67
+ @frame = Dhcp::Frame.new(options.to_hash)
68
+ end
69
+
70
+ def const_type
71
+ self.class::TYPE
72
+ end
73
+
74
+ def options_klass
75
+ self.class.const_get(:Options)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pio/dhcp/boot_reply'
4
+
5
+ module Pio
6
+ class Dhcp
7
+ # Dhcp Offer packet generator
8
+ class Offer < BootReply
9
+ TYPE = 2
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pio/dhcp/type/dhcp_param_list'
4
+ require 'pio/dhcp/type/dhcp_client_id'
5
+ require 'pio/dhcp/type/dhcp_string'
6
+ require 'pio/type/ip_address'
7
+
8
+ module Pio
9
+ # Dhcp parser and generator.
10
+ class Dhcp
11
+ # DHCP Optional TLV
12
+ class OptionalTlv < BinData::Record
13
+ DEFAULT = 'default'
14
+
15
+ endian :big
16
+
17
+ bit8 :tlv_type
18
+ bit8 :tlv_info_length,
19
+ onlyif: -> { !(end_of_dhcpdu?) }
20
+ choice :tlv_value,
21
+ onlyif: -> { !(end_of_dhcpdu?) },
22
+ selection: :chooser do
23
+ uint8 Dhcp::MESSAGE_TYPE_TLV
24
+ ip_address Dhcp::SERVER_IDENTIFIER_TLV
25
+ uint32be Dhcp::RENEWAL_TIME_VALUE_TLV
26
+ uint32be Dhcp::REBINDING_TIME_VALUE_TLV
27
+ uint32be Dhcp::IP_ADDRESS_LEASE_TIME_TLV
28
+ ip_address Dhcp::SUBNET_MASK_TLV
29
+ ip_address Dhcp::REQUESTED_IP_ADDRESS_TLV
30
+ client_id Dhcp::CLIENT_IDENTIFIER_TLV
31
+ parameter_list Dhcp::PARAMETERS_LIST_TLV
32
+ dhcp_string DEFAULT
33
+ end
34
+
35
+ def end_of_dhcptlv?
36
+ tlv_type == Dhcp::END_OF_TLV
37
+ end
38
+
39
+ def chooser
40
+ if valid_optional_tlv?
41
+ tlv_type
42
+ else
43
+ DEFAULT
44
+ end
45
+ end
46
+
47
+ def end_of_dhcpdu?
48
+ tlv_type == Dhcp::END_OF_TLV
49
+ end
50
+
51
+ private
52
+
53
+ def valid_optional_tlv?
54
+ optional_tlv? || end_of_dhcptlv?
55
+ end
56
+
57
+ # rubocop:disable MethodLength
58
+ def optional_tlv?
59
+ [
60
+ Dhcp::MESSAGE_TYPE_TLV,
61
+ Dhcp::SERVER_IDENTIFIER_TLV,
62
+ Dhcp::CLIENT_IDENTIFIER_TLV,
63
+ Dhcp::RENEWAL_TIME_VALUE_TLV,
64
+ Dhcp::REBINDING_TIME_VALUE_TLV,
65
+ Dhcp::REQUESTED_IP_ADDRESS_TLV,
66
+ Dhcp::PARAMETERS_LIST_TLV,
67
+ Dhcp::IP_ADDRESS_LEASE_TIME_TLV,
68
+ Dhcp::SUBNET_MASK_TLV
69
+ ].include?(tlv_type)
70
+ end
71
+ # rubocop:enable MethodLength
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pio/dhcp/boot_request'
4
+
5
+ module Pio
6
+ class Dhcp
7
+ # Dhcp Request packet generator
8
+ class Request < BootRequest
9
+ TYPE = 3
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pio/type/mac_address'
4
+
5
+ module Pio
6
+ class Dhcp
7
+ # Dhcp Client Id Format
8
+ class ClientId < BinData::Primitive
9
+ bit8 :hardwaretype, value: 1
10
+ mac_address :mac
11
+
12
+ def get
13
+ mac
14
+ end
15
+
16
+ def set(value)
17
+ self.mac = value
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bindata'
4
+
5
+ module Pio
6
+ module Type
7
+ # DHCP ParameterList Format.
8
+ class ParameterList < BinData::Primitive
9
+ array :octets,
10
+ type: :uint8,
11
+ initial_length: :tlv_info_length
12
+
13
+ def set(value)
14
+ self.octets = value
15
+ end
16
+
17
+ def get
18
+ octets
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bindata'
4
+
5
+ module Pio
6
+ module Type
7
+ # DHCP String Format.
8
+ class DhcpString < BinData::Primitive
9
+ string :dhcp_string,
10
+ read_length: :tlv_info_length
11
+
12
+ def set(value)
13
+ self.dhcp_string = value
14
+ end
15
+
16
+ def get
17
+ dhcp_string
18
+ end
19
+ end
20
+ end
21
+ end