packet-protocols 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a27a85186048ae13c3b0c93579424cc9cae14e5b
4
+ data.tar.gz: b0e13d20586455d3346fd7aad8fe9105e3d4fc80
5
+ SHA512:
6
+ metadata.gz: 47b6ba39ff586bb1c66a33f66901ec981cca9a8253e0ca0516813e92f904c541c537767f7baee9e5f3a1affa11019ea5c73ddbec3245dc8d8bb9603a9c9756fb
7
+ data.tar.gz: edb2f47836f18c0a8d7cd4d732566ca8365e6c61ed433f01932f1c480b1e554cedb4567fbb35f0fc037a52a83ae0343ee44b99f0866e3a9de90eb2dce036a972
data/lib/arp.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'bindata-contrib'
2
+ require_relative 'mac_address'
3
+ require_relative 'ipv4_address'
4
+
5
+ class Arp < BinData::Record
6
+ HARDWARES = { ethernet: 1 }
7
+ PROTOCOLS = { ipv4: 0x0800 }
8
+ OPERATIONS = { request: 1, reply: 2 }
9
+
10
+ endian :big
11
+ enum16 :hardware, list: HARDWARES, initial_value: -> { :ethernet }
12
+ enum16 :protocol, list: PROTOCOLS, initial_value: -> { :ipv4 }
13
+ uint8 :hardware_length, initial_value: 6
14
+ uint8 :protocol_length, initial_value: 4
15
+ enum16 :operation, list: OPERATIONS, initial_value: -> { :request }
16
+ mac_address :mac_source, onlyif: :ipv4_in_ethernet?
17
+ ipv4_address :ip_source, onlyif: :ipv4_in_ethernet?
18
+ mac_address :mac_destination, onlyif: :ipv4_in_ethernet?
19
+ ipv4_address :ip_destination, onlyif: :ipv4_in_ethernet?
20
+
21
+ virtual assert: (proc do
22
+ !ipv4_in_ethernet? || (hardware_length == 6 && protocol_length == 4)
23
+ end)
24
+
25
+ def ipv4_in_ethernet?
26
+ hardware == :ethernet && protocol == :ipv4
27
+ end
28
+ end
data/lib/ethernet.rb ADDED
@@ -0,0 +1,40 @@
1
+ require_relative 'ipv4'
2
+ require_relative 'arp'
3
+
4
+ class Ethernet < BinData::Record
5
+ PROTOCOLS = {
6
+ ipv4: 0x0800,
7
+ arp: 0x0806,
8
+ vlan: 0x8100
9
+ }
10
+
11
+ endian :big
12
+ mac_address 'mac_destination'
13
+ mac_address 'mac_source'
14
+ enum16 :protocol_internal, list: PROTOCOLS, initial_value: -> { :ipv4 }
15
+
16
+ struct :vlan, onlyif: :has_vlan? do
17
+ bit3 :pcp, initial_value: 0
18
+ bit1 :cfi, initial_value: 0
19
+ bit12 :id, initial_value: 0
20
+ enum16 :protocol, list: PROTOCOLS, initial_value: -> { :ipv4 }
21
+ end
22
+
23
+ choice :payload, selection: -> { protocol.to_s } do
24
+ ipv4 'ipv4'
25
+ arp 'arp'
26
+ rest :default
27
+ end
28
+
29
+ def has_vlan?
30
+ protocol_internal == :vlan
31
+ end
32
+
33
+ def protocol
34
+ has_vlan? ? vlan.protocol : protocol_internal
35
+ end
36
+
37
+ def length
38
+ 14 + (has_vlan? ? 4 : 0) + payload.length
39
+ end
40
+ end
data/lib/icmp.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'bindata-contrib'
2
+
3
+ class Icmp < BinData::Record
4
+ TYPES = { echo_reply: 0, echo_request: 8 }
5
+
6
+ endian :big
7
+ enum8 :type, list: TYPES, initial_value: -> { :echo_request }
8
+ uint8 :code, initial_value: 0
9
+ uint16 :checksum
10
+
11
+ uint16 :identifier, onlyif: :echo?
12
+ uint16 :sequence_number, onlyif: :echo?
13
+ rest :data, onlyif: :echo?
14
+
15
+ def echo?
16
+ type == :echo_request || type == :echo_reply
17
+ end
18
+
19
+ def length
20
+ 4 + (echo? ? 4 + data.length : 0)
21
+ end
22
+ end
data/lib/ipv4.rb ADDED
@@ -0,0 +1,65 @@
1
+ require 'bindata-contrib'
2
+ require_relative 'ipv4_address'
3
+ require_relative 'icmp'
4
+ require_relative 'tcp'
5
+ require_relative 'udp'
6
+
7
+ class Ipv4 < BinData::Record
8
+ PROTOCOLS = { icmp: 1, tcp: 6, udp: 17 }
9
+
10
+ endian :big
11
+ bit4 :version, asserted_value: 4
12
+ bit4 :header_length, initial_value: 5
13
+ uint8 :tos
14
+ uint16 :total_length, initial_value: -> { header_length_in_bytes + payload.length }
15
+ uint16 :identifier
16
+ bit1 :reserved
17
+ bool :df
18
+ bool :mf
19
+ bit13 :fragment_offset
20
+ uint8 :time_to_live, initial_value: 64
21
+ enum8 :protocol, list: PROTOCOLS, initial_value: -> { :tcp }
22
+ uint16 :checksum#, initial_value: :compute_checksum
23
+ ipv4_address :ip_source
24
+ ipv4_address :ip_destination
25
+ string :options, read_length: :options_length_in_bytes
26
+ choice :payload, selection: -> { protocol.to_s } do
27
+ icmp 'icmp'
28
+ tcp 'tcp'
29
+ udp 'udp'
30
+ rest :default
31
+ end
32
+
33
+ # virtual assert: :checksum_valid?
34
+
35
+ def header_length_in_bytes
36
+ header_length * 4
37
+ end
38
+
39
+ def options_length_in_bytes
40
+ header_length_in_bytes - options.rel_offset
41
+ end
42
+
43
+ def length
44
+ total_length
45
+ end
46
+
47
+ # def compute_checksum
48
+ # self.checksum = 0
49
+ # self.checksum = checksum_function
50
+ # end
51
+ #
52
+ # def checksum_valid?
53
+ # checksum_function == 0
54
+ # end
55
+
56
+ # private
57
+ #
58
+ # def checksum_function
59
+ # bin = to_binary_s
60
+ # dbytes = bin.unpack('S>*')
61
+ # acc = dbytes.inject(:+)
62
+ # acc = ((acc >> 16) & 0xffff) + (acc & 0xffff)
63
+ # ~acc & 0xffff
64
+ # end
65
+ end
@@ -0,0 +1,14 @@
1
+ require 'bindata'
2
+
3
+ class Ipv4Address < BinData::Primitive
4
+ endian :big
5
+ array :octets, type: :uint8, initial_length: 4
6
+
7
+ def get
8
+ octets.map(&:to_s).join('.')
9
+ end
10
+
11
+ def set(value)
12
+ self.octets = value.split('.').map(&:to_i)
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'bindata'
2
+
3
+ class Ipv6Address < BinData::Primitive
4
+ endian :big
5
+ array :octets, type: :uint8, initial_length: 16
6
+
7
+ def get
8
+ octets.map { |o| o.to_s(16) }.join(':')
9
+ end
10
+
11
+ def set(value)
12
+ self.octets = value.split(':').map { |o| o.to_i(16) }
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'bindata'
2
+
3
+ class MacAddress < BinData::Primitive
4
+ endian :big
5
+ array :octets, type: :uint8, initial_length: 6
6
+
7
+ def get
8
+ octets.map { |octet| format('%02x', octet) }.join(':')
9
+ end
10
+
11
+ def set(value)
12
+ self.octets = value.split(':').map(&:hex)
13
+ end
14
+ end
@@ -0,0 +1 @@
1
+ require_relative 'ethernet'
data/lib/tcp.rb ADDED
@@ -0,0 +1,61 @@
1
+ require 'bindata'
2
+ require 'bindata-contrib'
3
+
4
+ class Tcp < BinData::Record
5
+ endian :big
6
+ uint16 :source_port
7
+ uint16 :destination_port
8
+ uint32 :sequence_number
9
+ uint32 :acknowledge_number
10
+ bit4 :data_offset, initial_value: -> { 5 + options.length / 4 }
11
+ bit3 :reserved
12
+ bool :ns
13
+ bool :cwr
14
+ bool :ece
15
+ bool :urg
16
+ bool :ack
17
+ bool :psh
18
+ bool :rst
19
+ bool :syn
20
+ bool :fin
21
+ uint16 :window_size
22
+ uint16 :checksum#, initial_value: :compute_checksum
23
+ uint16 :urgent_pointer
24
+ string :options, read_length: :options_length_in_bytes
25
+ rest :payload
26
+
27
+ # virtual assert: :checksum_valid?
28
+
29
+ def header_length_in_bytes
30
+ data_offset * 4
31
+ end
32
+
33
+ def options_length_in_bytes
34
+ header_length_in_bytes - options.rel_offset
35
+ end
36
+
37
+ def length
38
+ header_length_in_bytes + options_length_in_bytes + payload.length
39
+ end
40
+
41
+ # def compute_checksum
42
+ # self.checksum = 0
43
+ # self.checksum = checksum_function
44
+ # end
45
+ #
46
+ # def checksum_valid?
47
+ # checksum_function == 0
48
+ # end
49
+ #
50
+ # private
51
+ #
52
+ # def checksum_function
53
+ # bin = to_binary_s
54
+ # dbytes = bin.unpack('S>*')
55
+ # acc = dbytes.inject(:+)
56
+ # acc = ((acc >> 16) & 0xffff) + (acc & 0xffff)
57
+ # ~acc & 0xffff
58
+ # end
59
+
60
+ # TODO: need IP parent for checksum
61
+ end
data/lib/udp.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'bindata'
2
+
3
+ class Udp < BinData::Record
4
+ endian :big
5
+ uint16 :source_port
6
+ uint16 :destination_port
7
+ uint16 :len, initial_value: -> { 8 + payload.length }
8
+ uint16 :checksum
9
+ rest :payload
10
+
11
+ def length
12
+ len
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: packet-protocols
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Jérémy Pagé
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-18 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A Parser/Serializer for Packet protocols.
14
+ email:
15
+ - contact@jeremypage.me
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/arp.rb
21
+ - lib/ethernet.rb
22
+ - lib/icmp.rb
23
+ - lib/ipv4.rb
24
+ - lib/ipv4_address.rb
25
+ - lib/ipv6_address.rb
26
+ - lib/mac_address.rb
27
+ - lib/packet-protocols.rb
28
+ - lib/tcp.rb
29
+ - lib/udp.rb
30
+ homepage: https://github.com/jejepage/packet-protocols
31
+ licenses:
32
+ - MIT
33
+ metadata: {}
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements: []
49
+ rubyforge_project:
50
+ rubygems_version: 2.4.8
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: Packet Protocols
54
+ test_files: []