packet-protocols 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/arp.rb +28 -0
- data/lib/ethernet.rb +40 -0
- data/lib/icmp.rb +22 -0
- data/lib/ipv4.rb +65 -0
- data/lib/ipv4_address.rb +14 -0
- data/lib/ipv6_address.rb +14 -0
- data/lib/mac_address.rb +14 -0
- data/lib/packet-protocols.rb +1 -0
- data/lib/tcp.rb +61 -0
- data/lib/udp.rb +14 -0
- metadata +54 -0
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
|
data/lib/ipv4_address.rb
ADDED
@@ -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
|
data/lib/ipv6_address.rb
ADDED
@@ -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
|
data/lib/mac_address.rb
ADDED
@@ -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
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: []
|