dnet-ffi 0.1.3 → 0.1.4

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