packet-protocols 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: []