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.
@@ -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
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "FfiPackets" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'ffi/packets'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
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