ffi-packets 0.1.0
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.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +20 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/ffi-packets.gemspec +67 -0
- data/lib/ffi/packets.rb +14 -0
- data/lib/ffi/packets/arp.rb +60 -0
- data/lib/ffi/packets/constants.rb +478 -0
- data/lib/ffi/packets/eth.rb +74 -0
- data/lib/ffi/packets/icmp.rb +294 -0
- data/lib/ffi/packets/ip.rb +227 -0
- data/lib/ffi/packets/tcp.rb +104 -0
- data/lib/ffi/packets/udp.rb +30 -0
- data/lib/ffi/packets/util.rb +54 -0
- data/spec/ffi-packets_spec.rb +7 -0
- data/spec/spec_helper.rb +9 -0
- metadata +103 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
module FFI::Packets
|
2
|
+
module Tcp
|
3
|
+
|
4
|
+
# TCP header, without options
|
5
|
+
#
|
6
|
+
# field :sport, :uint16, :desc => 'source port'
|
7
|
+
# field :dport, :uint16, :desc => 'destination port'
|
8
|
+
# field :seq, :uint32, :desc => 'sequence number'
|
9
|
+
# field :ack, :uint32, :desc => 'acknowledgment number'
|
10
|
+
# field :off_x2, :uint8, :desc => 'data offset(& 0xf0) unused (& 0x0f)'
|
11
|
+
# field :flags, :uint8, :desc => 'control flags'
|
12
|
+
# field :win, :uint16, :desc => 'window'
|
13
|
+
# field :sum, :uint16, :desc => 'checksum'
|
14
|
+
# field :urgp, :uint16, :desc => 'urgent pointer'
|
15
|
+
#
|
16
|
+
class Hdr < ::FFI::Struct
|
17
|
+
include ::FFI::DRY::NetStructHelper
|
18
|
+
|
19
|
+
dsl_layout do
|
20
|
+
field :sport, :uint16, :desc => 'source port'
|
21
|
+
field :dport, :uint16, :desc => 'destination port'
|
22
|
+
field :seq, :uint32, :desc => 'sequence number'
|
23
|
+
field :ack, :uint32, :desc => 'acknowledgment number'
|
24
|
+
field :off_x2, :uint8, :desc => 'data offset(& 0xf0) unused (& 0x0f)'
|
25
|
+
field :flags, :uint8, :desc => 'control flags'
|
26
|
+
field :win, :uint16, :desc => 'window'
|
27
|
+
field :sum, :uint16, :desc => 'checksum'
|
28
|
+
field :urgp, :uint16, :desc => 'urgent pointer'
|
29
|
+
end
|
30
|
+
|
31
|
+
# TCP control flags (flags)
|
32
|
+
module Flags
|
33
|
+
include ::FFI::DRY::ConstFlagsMap
|
34
|
+
slurp_constants(Constants, "TH_")
|
35
|
+
def self.list; @@list ||= super() ; end
|
36
|
+
end
|
37
|
+
|
38
|
+
# #define \
|
39
|
+
# tcp_pack_hdr(hdr, sport, dport, seq, ack, flags, win, urp) do { \
|
40
|
+
# struct tcp_hdr *tcp_pack_p = (struct tcp_hdr *)(hdr); \
|
41
|
+
# tcp_pack_p->th_sport = htons(sport); \
|
42
|
+
# tcp_pack_p->th_dport = htons(dport); \
|
43
|
+
# tcp_pack_p->th_seq = htonl(seq); \
|
44
|
+
# tcp_pack_p->th_ack = htonl(ack); \
|
45
|
+
# tcp_pack_p->th_x2 = 0; tcp_pack_p->th_off = 5; \
|
46
|
+
# tcp_pack_p->th_flags = flags; \
|
47
|
+
# tcp_pack_p->th_win = htons(win); \
|
48
|
+
# tcp_pack_p->th_urp = htons(urp); \
|
49
|
+
# } while (0)
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# TCP option (following TCP header)
|
55
|
+
#
|
56
|
+
# struct tcp_opt {
|
57
|
+
# uint8_t opt_type; /* option type */
|
58
|
+
# uint8_t opt_len; /* option length >= TCP_OPT_LEN */
|
59
|
+
# union tcp_opt_data {
|
60
|
+
# uint16_t mss; /* TCP_OPT_MSS */
|
61
|
+
# uint8_t wscale; /* TCP_OPT_WSCALE */
|
62
|
+
# uint16_t sack[19]; /* TCP_OPT_SACK */
|
63
|
+
# uint32_t echo; /* TCP_OPT_ECHO{REPLY} */
|
64
|
+
# uint32_t timestamp[2]; /* TCP_OPT_TIMESTAMP */
|
65
|
+
# uint32_t cc; /* TCP_OPT_CC{NEW,ECHO} */
|
66
|
+
# uint8_t cksum; /* TCP_OPT_ALTSUM */
|
67
|
+
# uint8_t md5[16]; /* TCP_OPT_MD5 */
|
68
|
+
# uint8_t data8[TCP_OPT_LEN_MAX - TCP_OPT_LEN];
|
69
|
+
# } opt_data;
|
70
|
+
# } __attribute__((__packed__));
|
71
|
+
#
|
72
|
+
class Opt < ::FFI::Struct
|
73
|
+
include ::FFI::DRY::NetStructHelper
|
74
|
+
|
75
|
+
TCP_OPT_LEN = Constants::TCP_OPT_LEN
|
76
|
+
TCP_OPT_LEN_MAX = Constants::TCP_OPT_LEN_MAX
|
77
|
+
|
78
|
+
DATA_LEN = TCP_OPT_LEN_MAX - TCP_OPT_LEN
|
79
|
+
|
80
|
+
dsl_layout do
|
81
|
+
field :otype, :uint8
|
82
|
+
field :len, :uint8
|
83
|
+
array :data8, [:uint8, DATA_LEN]
|
84
|
+
end
|
85
|
+
|
86
|
+
# Options (otype) - http://www.iana.org/assignments/tcp-parameters
|
87
|
+
module Otype
|
88
|
+
include ::FFI::DRY::ConstMap
|
89
|
+
slurp_constants(Constants, "TCP_OTYPE_")
|
90
|
+
def self.list; @@list ||= super() ; end
|
91
|
+
end
|
92
|
+
|
93
|
+
end # class Opt
|
94
|
+
|
95
|
+
# TCP FSM states
|
96
|
+
module State
|
97
|
+
include ::FFI::DRY::ConstMap
|
98
|
+
slurp_constants(Constants, "TCP_STATE_")
|
99
|
+
def self.list; @@list ||= super() ; end
|
100
|
+
end
|
101
|
+
|
102
|
+
end # module Tcp
|
103
|
+
end
|
104
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module FFI::Packets
|
2
|
+
|
3
|
+
class Udp
|
4
|
+
class Hdr < ::FFI::Struct
|
5
|
+
include ::FFI::DRY::NetStructHelper
|
6
|
+
|
7
|
+
# struct udp_hdr {
|
8
|
+
# uint16_t uh_sport; /* source port */
|
9
|
+
# uint16_t uh_dport; /* destination port */
|
10
|
+
# uint16_t uh_ulen; /* udp length (including header) */
|
11
|
+
# uint16_t uh_sum; /* udp checksum */
|
12
|
+
# };
|
13
|
+
dsl_layout do
|
14
|
+
field :sport, :uint16
|
15
|
+
field :dport, :uint16
|
16
|
+
field :len, :uint16
|
17
|
+
field :sum, :uint16
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
# #define udp_pack_hdr(hdr, sport, dport, ulen) do { \
|
24
|
+
# struct udp_hdr *udp_pack_p = (struct udp_hdr *)(hdr); \
|
25
|
+
# udp_pack_p->uh_sport = htons(sport); \
|
26
|
+
# udp_pack_p->uh_dport = htons(dport); \
|
27
|
+
# udp_pack_p->uh_ulen = htons(ulen); \
|
28
|
+
# } while (0)
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
|
2
|
+
module FFI::Packets
|
3
|
+
module Util
|
4
|
+
|
5
|
+
RX_IP4_ADDR = /(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/
|
6
|
+
RX_MAC_ADDR = /(?:(?:[a-f0-9]{1,2}[:-])?{5}[a-f0-9]{1,2})/i
|
7
|
+
|
8
|
+
# takes a IPv4 number and returns it as a 32-bit number
|
9
|
+
def Util.ipv4_atol(str)
|
10
|
+
unless str =~ /^#{RX_IP4_ADDR}$/
|
11
|
+
raise(::ArgumentError, "invalid IP address #{str.inspect}")
|
12
|
+
else
|
13
|
+
u32=0
|
14
|
+
str.split('.',4).each {|o| u32 = ((u32 << 8) | o.to_i) }
|
15
|
+
return u32
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# takes a 32-bit number and returns it as an IPv4 address string.
|
20
|
+
def Util.ipv4_ltoa(int)
|
21
|
+
unless(int.is_a? Numeric and int <= 0xffffffff)
|
22
|
+
raise(::ArgumentError, "not a long integer: #{int.inspect}")
|
23
|
+
end
|
24
|
+
ret = []
|
25
|
+
4.times do
|
26
|
+
ret.unshift(int & 0xff)
|
27
|
+
int >>= 8
|
28
|
+
end
|
29
|
+
ret.join('.')
|
30
|
+
end
|
31
|
+
|
32
|
+
def Util.unhexify(str, d=/\s*/)
|
33
|
+
str.to_s.strip.gsub(/([A-Fa-f0-9]{1,2})#{d}?/) { $1.hex.chr }
|
34
|
+
end
|
35
|
+
|
36
|
+
def Util.htonl(*args)
|
37
|
+
FFI::DRY::NetEndian.htonl(*args)
|
38
|
+
end
|
39
|
+
|
40
|
+
def Util.htons(*args)
|
41
|
+
FFI::DRY::NetEndian.htons(*args)
|
42
|
+
end
|
43
|
+
|
44
|
+
def Util.ntohl(*args)
|
45
|
+
FFI::DRY::NetEndian.ntohl(*args)
|
46
|
+
end
|
47
|
+
|
48
|
+
def Util.ntohs(*args)
|
49
|
+
FFI::DRY::NetEndian.ntohs(*args)
|
50
|
+
end
|
51
|
+
|
52
|
+
end # module Util
|
53
|
+
|
54
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ffi-packets
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric Monti
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-02 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: ffi
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: ffi_dry
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rspec
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
description: A collection of common network packets structures in FFI::Struct form for use with bindings to raw network libraries such as libdnet, libnet, or libpcap.
|
46
|
+
email: emonti@matasano.com
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files:
|
52
|
+
- LICENSE
|
53
|
+
- README.rdoc
|
54
|
+
files:
|
55
|
+
- .document
|
56
|
+
- .gitignore
|
57
|
+
- LICENSE
|
58
|
+
- README.rdoc
|
59
|
+
- Rakefile
|
60
|
+
- VERSION
|
61
|
+
- ffi-packets.gemspec
|
62
|
+
- lib/ffi/packets.rb
|
63
|
+
- lib/ffi/packets/arp.rb
|
64
|
+
- lib/ffi/packets/constants.rb
|
65
|
+
- lib/ffi/packets/eth.rb
|
66
|
+
- lib/ffi/packets/icmp.rb
|
67
|
+
- lib/ffi/packets/ip.rb
|
68
|
+
- lib/ffi/packets/tcp.rb
|
69
|
+
- lib/ffi/packets/udp.rb
|
70
|
+
- lib/ffi/packets/util.rb
|
71
|
+
- spec/ffi-packets_spec.rb
|
72
|
+
- spec/spec_helper.rb
|
73
|
+
has_rdoc: true
|
74
|
+
homepage: http://github.com/emonti/ffi-packets
|
75
|
+
licenses: []
|
76
|
+
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options:
|
79
|
+
- --charset=UTF-8
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: "0"
|
87
|
+
version:
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: "0"
|
93
|
+
version:
|
94
|
+
requirements: []
|
95
|
+
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 1.3.5
|
98
|
+
signing_key:
|
99
|
+
specification_version: 3
|
100
|
+
summary: A collection of common network packets structures
|
101
|
+
test_files:
|
102
|
+
- spec/ffi-packets_spec.rb
|
103
|
+
- spec/spec_helper.rb
|