dnet-ffi 0.1.3 → 0.1.4

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,2 @@
1
+ === 0.1.4 / 2010-1-2
2
+ * Using ffi-packets collection for network packet structs
data/Rakefile CHANGED
@@ -13,7 +13,8 @@ begin
13
13
  gem.homepage = "http://github.com/emonti/dnet-ffi"
14
14
  gem.authors = ["Eric Monti"]
15
15
  gem.files.delete_if {|f| f =~ /^mirror\//}
16
- # gem.add_dependency "emonti-ffi_dry"
16
+ gem.add_dependency "ffi_dry"
17
+ gem.add_dependency "ffi-packets"
17
18
  gem.add_development_dependency "rspec"
18
19
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
19
20
  end
@@ -59,6 +60,7 @@ Rake::RDocTask.new do |rdoc|
59
60
  rdoc.rdoc_dir = 'rdoc'
60
61
  rdoc.title = "dnet-ffi #{version}"
61
62
  rdoc.rdoc_files.include('README*')
63
+ rdoc.rdoc_files.include('History.txt')
62
64
  rdoc.rdoc_files.include('lib/**/*.rb')
63
65
  end
64
66
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.1.4
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dnet-ffi}
8
- s.version = "0.1.3"
8
+ s.version = "0.1.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Eric Monti"]
12
- s.date = %q{2009-09-17}
12
+ s.date = %q{2010-01-02}
13
13
  s.description = %q{Ruby FFI bindings for the libdnet raw network library}
14
14
  s.email = %q{emonti@matasano.com}
15
15
  s.extra_rdoc_files = [
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.files = [
20
20
  ".document",
21
21
  ".gitignore",
22
+ "History.txt",
22
23
  "LICENSE",
23
24
  "README.rdoc",
24
25
  "Rakefile",
@@ -65,7 +66,7 @@ Gem::Specification.new do |s|
65
66
  s.homepage = %q{http://github.com/emonti/dnet-ffi}
66
67
  s.rdoc_options = ["--charset=UTF-8"]
67
68
  s.require_paths = ["lib"]
68
- s.rubygems_version = %q{1.3.4}
69
+ s.rubygems_version = %q{1.3.5}
69
70
  s.summary = %q{Ruby FFI bindings for libdnet}
70
71
  s.test_files = [
71
72
  "spec/addr_spec.rb",
@@ -89,11 +90,17 @@ Gem::Specification.new do |s|
89
90
  s.specification_version = 3
90
91
 
91
92
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
93
+ s.add_runtime_dependency(%q<ffi_dry>, [">= 0"])
94
+ s.add_runtime_dependency(%q<ffi-packets>, [">= 0"])
92
95
  s.add_development_dependency(%q<rspec>, [">= 0"])
93
96
  else
97
+ s.add_dependency(%q<ffi_dry>, [">= 0"])
98
+ s.add_dependency(%q<ffi-packets>, [">= 0"])
94
99
  s.add_dependency(%q<rspec>, [">= 0"])
95
100
  end
96
101
  else
102
+ s.add_dependency(%q<ffi_dry>, [">= 0"])
103
+ s.add_dependency(%q<ffi-packets>, [">= 0"])
97
104
  s.add_dependency(%q<rspec>, [">= 0"])
98
105
  end
99
106
  end
@@ -4,6 +4,7 @@ rescue LoadError
4
4
  end
5
5
  require 'ffi'
6
6
  require 'ffi/dry'
7
+ require 'ffi/packets'
7
8
 
8
9
  module Dnet
9
10
  extend FFI::Library
@@ -2,58 +2,7 @@
2
2
 
3
3
  module Dnet
4
4
  module Arp
5
- # ARP header
6
- #
7
- # field :hrd, :uint16, :desc => 'format of hardware address'
8
- # field :pro, :uint16, :desc => 'format of protocol address'
9
- # field :hln, :uint16, :desc => 'length of hw address (ETH_ADDR_LEN)'
10
- # field :pln, :uint16, :desc => 'length of proto address (IP_ADDR_LEN)'
11
- # field :op, :uint16, :desc => 'operation'
12
- class Hdr < ::FFI::Struct
13
- include ::FFI::DRY::StructHelper
14
- include ::Dnet::NetEndianHelper
15
-
16
- dsl_layout do
17
- field :hrd, :uint16, :desc => 'format of hardware address'
18
- field :pro, :uint16, :desc => 'format of protocol address'
19
- field :hln, :uint16, :desc => 'length of hw address (ETH_ADDR_LEN)'
20
- field :pln, :uint16, :desc => 'length of proto address (IP_ADDR_LEN)'
21
- field :op, :uint16, :desc => 'operation'
22
- end
23
-
24
- # ARP operations
25
- module Op
26
- ::Dnet.constants.grep(/^(ARP_OP_([A-Z][A-Z0-9_]+))$/) do
27
- self.const_set $2, ::Dnet.const_get($1)
28
- end
29
-
30
- module_function
31
- def list
32
- @@list ||= constants.inject({}){|h,c| h.merge! c => const_get(c) }
33
- end
34
- end # Op
35
- end # Hdr
36
-
37
- # Ethernet/IP ARP message
38
- #
39
- # array :sha, [:uint8, ETH_ADDR_LEN], :desc => 'sender hardware address'
40
- # array :spa, [:uint8, IP_ADDR_LEN], :desc => 'sender protocol address'
41
- # array :tha, [:uint8, ETH_ADDR_LEN], :desc => 'target hardware address'
42
- # array :tpa, [:uint8, IP_ADDR_LEN], :desc => 'target protocol address'
43
- #
44
- class Ethip < ::FFI::Struct
45
- include ::FFI::DRY::StructHelper
46
- include ::Dnet::NetEndianHelper
47
-
48
- dsl_layout do
49
- array :sha, [:uint8, ETH_ADDR_LEN], :desc => 'sender hardware address'
50
- array :spa, [:uint8, IP_ADDR_LEN], :desc => 'sender protocol address'
51
- array :tha, [:uint8, ETH_ADDR_LEN], :desc => 'target hardware address'
52
- array :tpa, [:uint8, IP_ADDR_LEN], :desc => 'target protocol address'
53
- end
54
-
55
- end # Ethip
56
-
5
+ include FFI::Packets::Arp
57
6
 
58
7
  # FFI mapping to libdnet's "arp_entry" struct.
59
8
  #
@@ -2,77 +2,9 @@
2
2
 
3
3
  module Dnet
4
4
 
5
- # FFI implementation of dnet(3)'s eth_addr struct.
6
- class EthAddr < ::FFI::Struct
7
- include ::FFI::DRY::StructHelper
8
-
9
- # struct eth_addr { ... } eth_addr_t;
10
- dsl_layout{ array :data, [:uchar, ETH_ADDR_LEN] }
11
-
12
- # Adds the ability to initialize a new EthAddr with a mac address
13
- # string such as 'de:ad:be:ef:ba:be'. This argument is only parsed
14
- # if it is passed as the only String argument.
15
- def initialize(*args)
16
- if args.size == 1 and (s=args[0]).is_a? String
17
- super()
18
- self.addr = s
19
- else
20
- super(*args)
21
- end
22
- end
23
-
24
- def addr=(val)
25
- unless val.to_s =~ /^#{Dnet::Util::RX_MAC_ADDR}$/
26
- raise(ArgumentError, "invalid mac address #{val.inspect}")
27
- end
28
- raw = ::Dnet::Util.unhexify(val, /[:-]/)
29
- self[:data].to_ptr.write_string(raw, ETH_ADDR_LEN)
30
- end
31
-
32
- # Returns the MAC address as an array of unsigned char values.
33
- def chars; self[:data].to_a ; end
34
-
35
- # Returns the MAC address as a string with colon-separated hex-bytes.
36
- def string; chars.map {|x| "%0.2x" % x }.join(':'); end
37
- end
38
-
39
-
40
5
  module Eth
41
- #
42
- # struct :dst, EthAddr, :desc => 'destination address'
43
- # struct :src, EthAddr, :desc => 'source address'
44
- # field :etype, :ushort, :desc => 'ethernet payload type'
45
- #
46
- class Hdr < ::FFI::Struct
47
- include ::FFI::DRY::StructHelper
48
- include ::Dnet::NetEndianHelper
49
-
50
- module Etype
51
- include ::FFI::DRY::ConstMap
52
- slurp_constants ::Dnet, "ETH_TYPE_"
53
- def list; @@list ||= super(); end
54
- end
55
-
56
- dsl_layout do
57
- struct :dst, EthAddr, :desc => 'destination address'
58
- struct :src, EthAddr, :desc => 'source address'
59
- field :etype, :ushort, :desc => 'ethernet payload type'
60
- end
61
-
62
- def lookup_etype
63
- Etype[ self.etype ]
64
- end
65
-
66
- alias _divert_set_eth etype=
67
-
68
- def etype=(val)
69
- if val.kind_of? String or val.kind_of? Symbol
70
- val = Etype[ val ] or raise(ArgumentError, "invalid eth type #{val}")
71
- end
72
- _divert_set_eth(val)
73
- end
74
- end
75
-
6
+ include FFI::Packets::Eth
7
+
76
8
  # Obtains a new handle to transmit raw Ethernet frames via the specified
77
9
  # network device.
78
10
  #
@@ -131,6 +63,9 @@ module Dnet
131
63
  end
132
64
  end # Eth
133
65
 
66
+ # This is just an alias for ::Dnet::Eth::EthAddr
67
+ EthAddr = Eth::EthAddr
68
+
134
69
  # This is just an alias for ::Dnet::Eth::Handle
135
70
  EthHandle = Eth::Handle
136
71
 
@@ -2,11 +2,6 @@
2
2
  # throughout the Dnet FFI bindings.
3
3
 
4
4
  module Dnet
5
- attach_function :htons, [:uint16], :uint16
6
- attach_function :ntohs, [:uint16], :uint16
7
- attach_function :htonl, [:uint32], :uint32
8
- attach_function :ntohl, [:uint32], :uint32
9
-
10
5
 
11
6
  # Produces a null-terminated string from 'val', if max is supplied,
12
7
  # it is taken as a maximum length. If 'val' is longer than max, it will
@@ -99,66 +94,10 @@ module Dnet
99
94
 
100
95
  end # LoopableHandle
101
96
 
102
- # A special helper for network packet structures which use big-endian or
103
- # "network" byte-order. This helper generates read/write accessors that
104
- # automatically call the appropriate byte conversion function, ntohs/ntohl
105
- # for 'reading' a 16/32 bit field, and htons/htonl for writing to one.
106
- #
107
- # NOTE this helper does not currently do anything special for 64-bit values
108
- # at all.
109
- #
110
- # This helper relies on a included loaded FFI::DRY::StructHelper module
111
- # to do its magic. Always include this module as follows:
112
- #
113
- # class YourStruct < ::FFI::Struct # or ::FFI::ManagedStruct, (or Union?)
114
- # include ::FFI::DRY::StructHelper
115
- # include ::Dnet::NetEndianHelper
116
- # ...
117
- #
118
- module NetEndianHelper
119
-
120
- I16_convert = [::Dnet.method(:ntohs), ::Dnet.method(:htons)]
121
- U16_convert = [::Dnet.method(:ntohs), ::Dnet.method(:htons)]
122
- I32_convert = [::Dnet.method(:ntohl), ::Dnet.method(:htonl)]
123
- U32_convert = [::Dnet.method(:ntohl), ::Dnet.method(:htonl)]
124
-
125
- BYTE_ORDER_METH = {
126
- Dnet.find_type(:uint16) => I16_convert,
127
- Dnet.find_type(:int16) => I16_convert,
128
- Dnet.find_type(:int32) => I32_convert,
129
- Dnet.find_type(:uint32) => I32_convert,
130
- }
131
-
132
- module ClassMethods
133
- private
134
- def _class_meths_from_dsl_metadata(meta)
135
- (@dsl_metadata = meta).each do |spec|
136
- name = spec[:name]
137
- type = spec[:type]
138
- if type.kind_of? Symbol and mp=BYTE_ORDER_METH[ Dnet.find_type(type) ]
139
- unless instance_methods.include?(:"#{name}")
140
- define_method(:"#{name}"){ mp[0].call(self[name]) }
141
- end
142
- unless instance_methods.include?(:"#{name}=")
143
- define_method(:"#{name}="){|val| self[name] = mp[1].call(val) }
144
- end
145
- else
146
- unless instance_methods.include?(:"#{name}")
147
- define_method(:"#{name}"){ self[name] }
148
- end
149
- unless instance_methods.include?(:"#{name}=")
150
- define_method(:"#{name}="){|val| self[name]=val }
151
- end
152
- end
153
- end
154
- end
155
- end
156
-
157
- def self.included(base)
158
- base.extend(ClassMethods)
159
- end
160
-
161
- end
97
+ attach_function :htons, [:uint16], :uint16
98
+ attach_function :ntohs, [:uint16], :uint16
99
+ attach_function :htonl, [:uint32], :uint32
100
+ attach_function :ntohl, [:uint32], :uint32
162
101
 
163
102
  end
164
103
 
@@ -1,304 +1,5 @@
1
1
 
2
2
  module Dnet::Icmp
3
-
4
- # ICMP header structure
5
- #
6
- # struct icmp_hdr {
7
- # uint8_t icmp_type; /* type of message */
8
- # uint8_t icmp_code; /* type sub code */
9
- # uint16_t icmp_cksum; /* ones complement cksum of struct */
10
- # };
11
- #
12
- class Hdr < ::FFI::Struct
13
- include ::FFI::DRY::StructHelper
14
- include ::Dnet::NetEndianHelper
15
-
16
- dsl_layout do
17
- field :icmp_type, :uint8
18
- field :icmp_code, :uint8
19
- field :icmp_cksum, :uint16
20
- end
21
-
22
- module IcmpType
23
- include ::FFI::DRY::ConstFlagsMap
24
- slurp_constants(::Dnet, "ICMP_TYPE_")
25
- def list; @@list ||= super(); end
26
- end
27
-
28
- module IcmpCode
29
- module UNREACH
30
- include ::FFI::DRY::ConstFlagsMap
31
- slurp_constants(::Dnet, "ICMP_UNREACH_")
32
- def list; @@list ||= super(); end
33
- end
34
-
35
- module REDIRECT
36
- include ::FFI::DRY::ConstFlagsMap
37
- slurp_constants(::Dnet, "ICMP_REDIRECT_")
38
- def list; @@list ||= super(); end
39
- end
40
-
41
- module RTRADVERT
42
- include ::FFI::DRY::ConstFlagsMap
43
- slurp_constants(::Dnet, "ICMP_RTRADVERT_")
44
- def list; @@list ||= super(); end
45
- end
46
-
47
- module TIMEEXCEED
48
- include ::FFI::DRY::ConstFlagsMap
49
- slurp_constants(::Dnet, "ICMP_TIMEEXCEED_")
50
- def list; @@list ||= super(); end
51
- end
52
-
53
- module PARAMPROB
54
- include ::FFI::DRY::ConstFlagsMap
55
- slurp_constants(::Dnet, "ICMP_PARAMPROB_")
56
- def list; @@list ||= super(); end
57
- end
58
-
59
- module PHOTURIS
60
- include ::FFI::DRY::ConstFlagsMap
61
- slurp_constants(::Dnet, "ICMP_PHOTURIS_")
62
- def list; @@list ||= super(); end
63
- end
64
-
65
- end # module IcmpCode
66
-
67
- # Various ICMP message structures
68
- module Msg
69
-
70
- # Echo message data structure
71
- #
72
- # struct icmp_msg_echo {
73
- # uint16_t icmp_id;
74
- # uint16_t icmp_seq;
75
- # uint8_t icmp_data __flexarr; /* optional data */
76
- # };
77
- #
78
- class Echo < ::FFI::Struct
79
- include ::FFI::DRY::StructHelper
80
- include ::Dnet::NetEndianHelper
81
-
82
- dsl_layout do
83
- field :icmp_id, :uint16
84
- field :seq, :uint16
85
- field :data, :uint8 # flexarr ... optional data
86
- end
87
- end
88
-
89
- # Fragmentation-needed (unreachable) message data structure
90
- #
91
- # struct icmp_msg_needfrag {
92
- # uint16_t icmp_void; /* must be zero */
93
- # uint16_t icmp_mtu; /* MTU of next-hop network */
94
- # uint8_t icmp_ip __flexarr; /* IP hdr + 8 bytes of pkt */
95
- # };
96
- #
97
- class NeedFrag < ::FFI::Struct
98
- include ::FFI::DRY::StructHelper
99
- include ::Dnet::NetEndianHelper
100
-
101
- dsl_layout do
102
- field :icmp_void, :uint16
103
- field :mtu, :uint16
104
- field :ip, :uint8 # flexarr ... IP hdr + 8 bytes of pkt
105
- end
106
- end
107
-
108
- # Unreachable, source quench, redirect, time exceeded,
109
- # parameter problem message data structure
110
- #
111
- # struct icmp_msg_quote {
112
- # uint32_t icmp_void; /* must be zero */
113
- # uint8_t icmp_ip __flexarr; /* IP hdr + 8 bytes of pkt */
114
- # };
115
- #
116
- class Quote < ::FFI::Struct
117
- include ::FFI::DRY::StructHelper
118
- include ::Dnet::NetEndianHelper
119
-
120
- dsl_layout do
121
- field :icmp_void, :uint32
122
- field :ip, :uint8 # flexxarr ... IP hdr + 8 bytes of pkt
123
- end
124
- end
125
-
126
- # Router advertisement message data structure, RFC 1256
127
- #
128
- # struct icmp_msg_rtradvert {
129
- # uint8_t icmp_num_addrs; /* # of address / pref pairs */
130
- # uint8_t icmp_wpa; /* words / address == 2 */
131
- # uint16_t icmp_lifetime; /* route lifetime in seconds */
132
- # struct icmp_msg_rtr_data {
133
- # uint32_t icmp_void;
134
- # uint32_t icmp_pref; /* router preference (usu 0) */
135
- # } icmp_rtr __flexarr; /* variable # of routers */
136
- # };
137
- #
138
- class RtrAdvert < ::FFI::Struct
139
- include ::FFI::DRY::StructHelper
140
- include ::Dnet::NetEndianHelper
141
-
142
- class RtrData < ::FFI::Struct
143
- include ::FFI::DRY::StructHelper
144
- include ::Dnet::NetEndianHelper
145
-
146
- dsl_layout do
147
- field :icmp_void, :uint32
148
- field :pref, :uint32
149
- end
150
- end
151
-
152
- dsl_layout do
153
- field :num_addrs, :uint8
154
- field :wpa, :uint8
155
- field :lifetime, :uint16
156
- struct :router, RtrData # flexarr ... variable # of routers
157
- end
158
- end
159
-
160
- # Timestamp message data structure
161
- #
162
- # struct icmp_msg_tstamp {
163
- # uint32_t icmp_id; /* identifier */
164
- # uint32_t icmp_seq; /* sequence number */
165
- # uint32_t icmp_ts_orig; /* originate timestamp */
166
- # uint32_t icmp_ts_rx; /* receive timestamp */
167
- # uint32_t icmp_ts_tx; /* transmit timestamp */
168
- # };
169
- #
170
- class Timestamp < ::FFI::Struct
171
- include ::FFI::DRY::StructHelper
172
- include ::Dnet::NetEndianHelper
173
-
174
- dsl_layout do
175
- field :icmp_id, :uint32
176
- field :seq, :uint32
177
- field :ts_orig, :uint32
178
- field :ts_rx, :uint32
179
- field :ts_tx, :uint32
180
- end
181
- end
182
-
183
- # Address mask message data structure, RFC 950
184
- #
185
- # struct icmp_msg_mask {
186
- # uint32_t icmp_id; /* identifier */
187
- # uint32_t icmp_seq; /* sequence number */
188
- # uint32_t icmp_mask; /* address mask */
189
- # };
190
- #
191
- class Mask < ::FFI::Struct
192
- include ::FFI::DRY::StructHelper
193
- include ::Dnet::NetEndianHelper
194
-
195
- dsl_layout do
196
- field :icmp_id, :uint32
197
- field :seq, :uint32
198
- field :mask, :uint32
199
- end
200
- end
201
-
202
- # Traceroute message data structure, RFC 1393, RFC 1812
203
- #
204
- # struct icmp_msg_traceroute {
205
- # uint16_t icmp_id; /* identifier */
206
- # uint16_t icmp_void; /* unused */
207
- # uint16_t icmp_ohc; /* outbound hop count */
208
- # uint16_t icmp_rhc; /* return hop count */
209
- # uint32_t icmp_speed; /* link speed, bytes/sec */
210
- # uint32_t icmp_mtu; /* MTU in bytes */
211
- # };
212
- #
213
- class Traceroute < ::FFI::Struct
214
- include ::FFI::DRY::StructHelper
215
- include ::Dnet::NetEndianHelper
216
-
217
- dsl_layout do
218
- field :icmp_id, :uint16
219
- field :icmp_void, :uint16
220
- field :ohc, :uint16
221
- field :rhc, :uint16
222
- field :speed, :uint16
223
- field :mtu, :uint16
224
- end
225
- end
226
-
227
- # Domain name reply message data structure, RFC 1788
228
- #
229
- # struct icmp_msg_dnsreply {
230
- # uint16_t icmp_id; /* identifier */
231
- # uint16_t icmp_seq; /* sequence number */
232
- # uint32_t icmp_ttl; /* time-to-live */
233
- # uint8_t icmp_names __flexarr; /* variable number of names */
234
- # };
235
- #
236
- class DnsReply < ::FFI::Struct
237
- include ::FFI::DRY::StructHelper
238
- include ::Dnet::NetEndianHelper
239
-
240
- dsl_layout do
241
- field :icmp_id, :uint16
242
- field :seq, :uint16
243
- field :ttl, :uint16
244
- field :names, :uint8 # flexarr ... variable # of names
245
- end
246
- end
247
-
248
- # Generic identifier, sequence number data structure
249
- #
250
- # struct icmp_msg_idseq {
251
- # uint16_t icmp_id;
252
- # uint16_t icmp_seq;
253
- # };
254
- #
255
- class IdSeq < ::FFI::Struct
256
- include ::FFI::DRY::StructHelper
257
- include ::Dnet::NetEndianHelper
258
-
259
- dsl_layout do
260
- field :icmp_id, :uint16
261
- field :seq, :uint16
262
- end
263
- end
264
-
265
- end # module Msg
266
- end
267
-
268
- # /*
269
- # * ICMP message union
270
- # */
271
- # union icmp_msg {
272
- # struct icmp_msg_echo echo; /* ICMP_ECHO{REPLY} */
273
- # struct icmp_msg_quote unreach; /* ICMP_UNREACH */
274
- # struct icmp_msg_needfrag needfrag; /* ICMP_UNREACH_NEEDFRAG */
275
- # struct icmp_msg_quote srcquench; /* ICMP_SRCQUENCH */
276
- # struct icmp_msg_quote redirect; /* ICMP_REDIRECT (set to 0) */
277
- # uint32_t rtrsolicit; /* ICMP_RTRSOLICIT */
278
- # struct icmp_msg_rtradvert rtradvert; /* ICMP_RTRADVERT */
279
- # struct icmp_msg_quote timexceed; /* ICMP_TIMEXCEED */
280
- # struct icmp_msg_quote paramprob; /* ICMP_PARAMPROB */
281
- # struct icmp_msg_tstamp tstamp; /* ICMP_TSTAMP{REPLY} */
282
- # struct icmp_msg_idseq info; /* ICMP_INFO{REPLY} */
283
- # struct icmp_msg_mask mask; /* ICMP_MASK{REPLY} */
284
- # struct icmp_msg_traceroute traceroute; /* ICMP_TRACEROUTE */
285
- # struct icmp_msg_idseq dns; /* ICMP_DNS */
286
- # struct icmp_msg_dnsreply dnsreply; /* ICMP_DNSREPLY */
287
- # };
288
-
289
- # #define icmp_pack_hdr(hdr, type, code) do { \
290
- # struct icmp_hdr *icmp_pack_p = (struct icmp_hdr *)(hdr); \
291
- # icmp_pack_p->icmp_type = type; icmp_pack_p->icmp_code = code; \
292
- # } while (0)
293
-
294
- # #define icmp_pack_hdr_echo(hdr, type, code, id, seq, data, len) do { \
295
- # struct icmp_msg_echo *echo_pack_p = (struct icmp_msg_echo *) \
296
- # ((uint8_t *)(hdr) + ICMP_HDR_LEN); \
297
- # icmp_pack_hdr(hdr, type, code); \
298
- # echo_pack_p->icmp_id = htons(id); \
299
- # echo_pack_p->icmp_seq = htons(seq); \
300
- # memmove(echo_pack_p->icmp_data, data, len); \
301
- # } while (0)
302
-
303
-
3
+ include FFI::Packets::Icmp
4
+
304
5
  end # module Dnet::Icmp
@@ -4,228 +4,8 @@
4
4
  module Dnet
5
5
 
6
6
  module Ip
7
- # Protocols (proto) - http://www.iana.org/assignments/protocol-numbers
8
- #
9
- # Contains mappings for all the IP_PROTO_[A-Z].* constants
10
- # (defined in constants.rb)
11
- module Proto
12
- include ::FFI::DRY::ConstMap
13
- slurp_constants(::Dnet, "IP_PROTO_")
14
- def self.list; @@list ||= super(); end
15
- end
16
-
17
- # IP header, without options
18
- #
19
- # field :v_hl, :uint8, :desc => 'v=vers(. & 0xf0) / '+
20
- # 'hl=hdr len(. & 0x0f)'
21
- # field :tos, :uint8, :desc => 'type of service'
22
- # field :len, :uint16, :desc => 'total length (incl header)'
23
- # field :id, :uint16, :desc => 'identification'
24
- # field :off, :uint16, :desc => 'fragment offset and flags'
25
- # field :ttl, :uint8, :desc => 'time to live'
26
- # field :proto, :uint8, :desc => 'protocol'
27
- # field :sum, :uint16, :desc => 'checksum'
28
- # field :src, :uint32, :desc => 'source address'
29
- # field :dst, :uint32, :desc => 'destination address'
30
- #
31
- class Hdr < ::FFI::Struct
32
- include ::FFI::DRY::StructHelper
33
- include ::Dnet::NetEndianHelper
34
-
35
- dsl_layout do
36
- field :v_hl, :uint8, :desc => 'v=vers(. & 0xf0) / '+
37
- 'hl=hdr len(. & 0x0f)'
38
- field :tos, :uint8, :desc => 'type of service'
39
- field :len, :uint16, :desc => 'total length (incl header)'
40
- field :id, :uint16, :desc => 'identification'
41
- field :off, :uint16, :desc => 'fragment offset and flags'
42
- field :ttl, :uint8, :desc => 'time to live'
43
- field :proto, :uint8, :desc => 'protocol'
44
- field :sum, :uint16, :desc => 'checksum'
45
- field :src, :uint32, :desc => 'source address'
46
- field :dst, :uint32, :desc => 'destination address'
47
- end
48
-
49
- # Overrides set_fields to supply a default value for the 'v_hl' field.
50
- #
51
- # v = 4
52
- # hl = 5 # number of 32-bit words - 20 bytes (size of hdr without opts)
53
- #
54
- def set_fields(params=nil)
55
- params ||= {}
56
- super({:v_hl => 0x45}.merge(params))
57
- end
58
-
59
- # Sets the value of the hl field. This field is a 4-bit value occupying
60
- # the lower 4 bits of the 'v_hl' field.
61
- #
62
- # This value is the size of the IP header (including opts if present)
63
- # in 32-bit words. The byte size maximum is 15*4 - 60 bytes.
64
- def hl=(val)
65
- raise(ArgumentError, "value for header length too high") if val > 0xf
66
- self[:v_hl] &= 0xf0
67
- self[:v_hl] += val
68
- end
69
-
70
- # Returns the value of the hl field. This field is a 4-bit value occupying
71
- # the lower 4 bits of the 'v_hl' field.
72
- #
73
- # This value is the size of the IP header (including opts if present)
74
- # in 32-bit words. The byte size maximum is 15*4 - 60 bytes.
75
- def hl
76
- self[:v_hl] & 0x0f
77
- end
78
-
79
- # Type of service (ip_tos), RFC 1349 ("obsoleted by RFC 2474")
80
- #
81
- # Contains mappings for all the IP_TOS_[A-Z].* flags constants
82
- module Tos
83
- include ::FFI::DRY::ConstFlagsMap
84
- slurp_constants(::Dnet, "IP_TOS_")
85
- def self.list; @@list ||= super(); end
86
- end
87
-
88
- def lookup_tos; Tos[ self.tos ]; end
89
-
90
- # Alias to ::Dnet::Ip::Proto
91
- Proto = ::Dnet::Ip::Proto
92
-
93
- def lookup_proto; Proto[ self.proto ]; end
94
-
95
- # Sets source IP address in the header from an IPv4 address string or
96
- # 32-bit number.
97
- def src=(val)
98
- val = ::Dnet::Util.ipv4_atol(val) if val.kind_of? String
99
- self[:src] = ::Dnet.htonl(val)
100
- end
101
-
102
- # Returns the source IP address as an IPv4 address string as an IPv4
103
- # address string.
104
- def src
105
- ::Dnet::Util.ipv4_ltoa( ::Dnet.ntohl( self[:src] ))
106
- end
107
-
108
- # Sets destination IP address in the header from an IPv4 address string
109
- # or 32-bit number.
110
- def dst=(val)
111
- val = ::Dnet::Util.ipv4_atol(val) if val.kind_of? String
112
- self[:dst] = ::Dnet.htonl(val)
113
- end
114
-
115
- # Returns the destination IP address from the header as an IPv4 address
116
- # string.
117
- def dst
118
- ::Dnet::Util.ipv4_ltoa( ::Dnet.ntohl( self[:dst] ))
119
- end
120
-
121
- end # class Hdr
122
-
123
-
124
- # IP option (following IP header)
125
- #
126
- # array :otype, :uint8, :desc => 'option type'
127
- # array :len, :uint8, :desc => 'option length >= IP_OPE_LEN'
128
- # array :data, [:uint8, DATA_LEN], :desc => 'option message data '
129
- #
130
- class Opt < ::FFI::Struct
131
- include ::FFI::DRY::StructHelper
132
- include ::Dnet::NetEndianHelper
133
-
134
- DATA_LEN = IP_OPT_LEN_MAX - IP_OPT_LEN
135
-
136
- dsl_layout do
137
- field :otype, :uint8, :desc => 'option type'
138
- field :len, :uint8, :desc => 'option length >= IP_OPE_LEN'
139
- array :data, [:uint8, DATA_LEN], :desc => 'option message data '
140
- end
141
-
142
- # Option types (otype) - http://www.iana.org/assignments/ip-parameters
143
- #
144
- # Contains mappings for all the IP_OTYPE_[A-Z].* constants
145
- module Otype
146
- include ::FFI::DRY::ConstMap
147
- slurp_constants(::Dnet, "IP_OTYPE_")
148
- def self.list; @@list ||= super(); end
149
- end
150
-
151
- # Security option data - RFC 791, 3.1
152
- #
153
- # field :sec, :uint16, :desc => 'security'
154
- # field :cpt, :uint16, :desc => 'compartments'
155
- # field :hr, :uint16, :desc => 'handling restrictions'
156
- # array :tcc, [:uint8, 3], :desc => 'transmission control code'
157
- #
158
- class DataSEC < ::FFI::Struct
159
- include ::FFI::DRY::StructHelper
160
- include ::Dnet::NetEndianHelper
161
-
162
- dsl_layout do
163
- field :sec, :uint16, :desc => 'security'
164
- field :cpt, :uint16, :desc => 'compartments'
165
- field :hr, :uint16, :desc => 'handling restrictions'
166
- array :tcc, [:uint8, 3], :desc => 'transmission control code'
167
- end
168
-
169
- end
170
-
171
- # Timestamp option data - RFC 791, 3.1
172
- #
173
- # field :ptr, :uint8, :desc => 'from start of option'
174
- # field :oflw_flg, :uint8, :desc => 'oflw = number of IPs skipped /'+
175
- # 'flg = address/timestamp flag'
176
- # field :iptspairs, :uint32, :desc => 'IP addr/ts pairs, var-length'
177
- #
178
- class DataTS < ::FFI::Struct
179
- include ::FFI::DRY::StructHelper
180
- include ::Dnet::NetEndianHelper
181
- dsl_layout do
182
- field :ptr, :uint8, :desc => 'from start of option'
183
- field :oflw_flg, :uint8, :desc => 'oflw = number of IPs skipped /'+
184
- 'flg = address/timestamp flag'
185
- field :iptspairs, :uint32, :desc => 'IP addr/ts pairs, var-length'
186
- end
187
-
188
- end
189
-
190
- # (Loose Source/Record/Strict Source) Route option data - RFC 791, 3.1
191
- #
192
- # field :ptr, :uint8, :desc => 'from start of option'
193
- # field :iplist, :uint32, :desc => 'var-length list of IPs'
194
- #
195
- class DataRR < ::FFI::Struct
196
- include ::FFI::DRY::StructHelper
197
- include ::Dnet::NetEndianHelper
198
-
199
- dsl_layout do
200
- field :ptr, :uint8, :desc => 'from start of option'
201
- field :iplist, :uint32, :desc => 'var-length list of IPs'
202
- end
203
-
204
- end
205
-
206
- # Traceroute option data - RFC 1393, 2.2
207
- #
208
- # struct ip_opt_data_tr {
209
- # uint16_t id; /* ID number */
210
- # uint16_t ohc; /* outbound hop count */
211
- # uint16_t rhc; /* return hop count */
212
- # uint32_t origip; /* originator IP address */
213
- # } __attribute__((__packed__));
214
- #
215
- class DataTR < ::FFI::Struct
216
- include ::FFI::DRY::StructHelper
217
- include ::Dnet::NetEndianHelper
218
-
219
- dsl_layout do
220
- field :id, :uint16, :desc => 'ID number'
221
- field :ohc, :uint16, :desc => 'outbound hop count'
222
- field :rhc, :uint16, :desc => 'return hop count'
223
- field :origip, :uint32, :desc => 'originator IP address'
224
- end
225
- end
226
-
227
- end # class Opt
228
7
 
8
+ include FFI::Packets::Ip
229
9
 
230
10
  # Abstraction around dnet(3)'s ip_t handle for transmitting raw IP packets
231
11
  # routed by the kernel.
@@ -1,103 +1,6 @@
1
1
  module Dnet
2
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::StructHelper
18
- include ::Dnet::NetEndianHelper
19
-
20
- dsl_layout do
21
- field :sport, :uint16, :desc => 'source port'
22
- field :dport, :uint16, :desc => 'destination port'
23
- field :seq, :uint32, :desc => 'sequence number'
24
- field :ack, :uint32, :desc => 'acknowledgment number'
25
- field :off_x2, :uint8, :desc => 'data offset(& 0xf0) unused (& 0x0f)'
26
- field :flags, :uint8, :desc => 'control flags'
27
- field :win, :uint16, :desc => 'window'
28
- field :sum, :uint16, :desc => 'checksum'
29
- field :urgp, :uint16, :desc => 'urgent pointer'
30
- end
31
-
32
- # TCP control flags (flags)
33
- module Flags
34
- include ::FFI::DRY::ConstFlagsMap
35
- slurp_constants(::Dnet, "TH_")
36
- def self.list; @@list ||= super() ; end
37
- end
38
-
39
- # #define \
40
- # tcp_pack_hdr(hdr, sport, dport, seq, ack, flags, win, urp) do { \
41
- # struct tcp_hdr *tcp_pack_p = (struct tcp_hdr *)(hdr); \
42
- # tcp_pack_p->th_sport = htons(sport); \
43
- # tcp_pack_p->th_dport = htons(dport); \
44
- # tcp_pack_p->th_seq = htonl(seq); \
45
- # tcp_pack_p->th_ack = htonl(ack); \
46
- # tcp_pack_p->th_x2 = 0; tcp_pack_p->th_off = 5; \
47
- # tcp_pack_p->th_flags = flags; \
48
- # tcp_pack_p->th_win = htons(win); \
49
- # tcp_pack_p->th_urp = htons(urp); \
50
- # } while (0)
51
-
52
- end
53
-
54
- #
55
- # TCP option (following TCP header)
56
- #
57
- # struct tcp_opt {
58
- # uint8_t opt_type; /* option type */
59
- # uint8_t opt_len; /* option length >= TCP_OPT_LEN */
60
- # union tcp_opt_data {
61
- # uint16_t mss; /* TCP_OPT_MSS */
62
- # uint8_t wscale; /* TCP_OPT_WSCALE */
63
- # uint16_t sack[19]; /* TCP_OPT_SACK */
64
- # uint32_t echo; /* TCP_OPT_ECHO{REPLY} */
65
- # uint32_t timestamp[2]; /* TCP_OPT_TIMESTAMP */
66
- # uint32_t cc; /* TCP_OPT_CC{NEW,ECHO} */
67
- # uint8_t cksum; /* TCP_OPT_ALTSUM */
68
- # uint8_t md5[16]; /* TCP_OPT_MD5 */
69
- # uint8_t data8[TCP_OPT_LEN_MAX - TCP_OPT_LEN];
70
- # } opt_data;
71
- # } __attribute__((__packed__));
72
- #
73
- class Opt < ::FFI::Struct
74
- include ::FFI::DRY::StructHelper
75
- include ::Dnet::NetEndianHelper
76
-
77
- DATA_LEN = TCP_OPT_LEN_MAX - TCP_OPT_LEN
78
-
79
- dsl_layout do
80
- field :otype, :uint8
81
- field :len, :uint8
82
- array :data8, [:uint8, DATA_LEN]
83
- end
84
-
85
- # Options (otype) - http://www.iana.org/assignments/tcp-parameters
86
- module Otype
87
- include ::FFI::DRY::ConstMap
88
- slurp_constants(::Dnet, "TCP_OTYPE_")
89
- def self.list; @@list ||= super() ; end
90
- end
91
-
92
- end # class Opt
93
-
94
- # TCP FSM states
95
- module State
96
- include ::FFI::DRY::ConstMap
97
- slurp_constants(::Dnet, "TCP_STATE_")
98
- def self.list; @@list ||= super() ; end
99
- end
100
-
3
+ include FFI::Packets::Tcp
101
4
  end # module Tcp
102
5
  end # module Dnet
103
6
 
@@ -1,24 +1,6 @@
1
1
  module Dnet
2
2
 
3
- class Udp
4
- class Hdr < ::FFI::Struct
5
- include ::FFI::DRY::StructHelper
6
- include ::Dnet::NetEndianHelper
7
-
8
- # struct udp_hdr {
9
- # uint16_t uh_sport; /* source port */
10
- # uint16_t uh_dport; /* destination port */
11
- # uint16_t uh_ulen; /* udp length (including header) */
12
- # uint16_t uh_sum; /* udp checksum */
13
- # };
14
- dsl_layout do
15
- field :sport, :uint16
16
- field :dport, :uint16
17
- field :len, :uint16
18
- field :sum, :uint16
19
- end
20
- end
21
- end
3
+ Udp = FFI::Packets::Udp
22
4
 
23
5
 
24
6
  # #define udp_pack_hdr(hdr, sport, dport, ulen) do { \
@@ -8,10 +8,6 @@ module Dnet
8
8
  # or module
9
9
  module Helpers
10
10
 
11
- def unhexify(str, d=/\s*/)
12
- str.to_s.strip.gsub(/([A-Fa-f0-9]{1,2})#{d}?/) { $1.hex.chr }
13
- end
14
-
15
11
  # Attempts to derive a memory pointer and length from an "anonymous" object.
16
12
  # Returns an an array object containing [len, pointer]
17
13
  #
@@ -38,30 +34,6 @@ module Dnet
38
34
  return [pbuf, bsz]
39
35
  end
40
36
 
41
- # takes a IPv4 number and returns it as a 32-bit number
42
- def ipv4_atol(str)
43
- unless str =~ /^#{::Dnet::Util::RX_IP4_ADDR}$/
44
- raise(::ArgumentError, "invalid IP address #{str.inspect}")
45
- else
46
- u32=0
47
- str.split('.',4).each {|o| u32 = ((u32 << 8) | o.to_i) }
48
- return u32
49
- end
50
- end
51
-
52
- # takes a 32-bit number and returns it as an IPv4 address string.
53
- def ipv4_ltoa(int)
54
- unless(int.is_a? Numeric and int <= 0xffffffff)
55
- raise(::ArgumentError, "not a long integer: #{int.inspect}")
56
- end
57
- ret = []
58
- 4.times do
59
- ret.unshift(int & 0xff)
60
- int >>= 8
61
- end
62
- ret.join('.')
63
- end
64
-
65
37
  end # module Helpers
66
38
 
67
39
  extend(::Dnet::Util::Helpers)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dnet-ffi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Monti
@@ -9,9 +9,29 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-17 00:00:00 -04:00
12
+ date: 2010-01-02 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ffi_dry
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-packets
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:
15
35
  - !ruby/object:Gem::Dependency
16
36
  name: rspec
17
37
  type: :development
@@ -34,6 +54,7 @@ extra_rdoc_files:
34
54
  files:
35
55
  - .document
36
56
  - .gitignore
57
+ - History.txt
37
58
  - LICENSE
38
59
  - README.rdoc
39
60
  - Rakefile
@@ -100,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
121
  requirements: []
101
122
 
102
123
  rubyforge_project:
103
- rubygems_version: 1.3.4
124
+ rubygems_version: 1.3.5
104
125
  signing_key:
105
126
  specification_version: 3
106
127
  summary: Ruby FFI bindings for libdnet