mtik 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,37 @@
1
+ ############################################################################
2
+ ## A Ruby library implementing the Ruby MikroTik API
3
+ ############################################################################
4
+ ## Author:: Aaron D. Gifford - http://www.aarongifford.com/
5
+ ## Copyright:: Copyright (c) 2009-2010, InfoWest, Inc.
6
+ ## License:: BSD license
7
+ ##
8
+ ## Redistribution and use in source and binary forms, with or without
9
+ ## modification, are permitted provided that the following conditions
10
+ ## are met:
11
+ ## 1. Redistributions of source code must retain the above copyright
12
+ ## notice, the above list of authors and contributors, this list of
13
+ ## conditions and the following disclaimer.
14
+ ## 2. Redistributions in binary form must reproduce the above copyright
15
+ ## notice, this list of conditions and the following disclaimer in the
16
+ ## documentation and/or other materials provided with the distribution.
17
+ ## 3. Neither the name of the author(s) or copyright holder(s) nor the
18
+ ## names of any contributors may be used to endorse or promote products
19
+ ## derived from this software without specific prior written permission.
20
+ ##
21
+ ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S), AUTHOR(S) AND
22
+ ## CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
23
+ ## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
+ ## AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25
+ ## IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), AUTHOR(S), OR CONTRIBUTORS BE
26
+ ## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ ## DCONSEQUENTIAL AMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32
+ ## THE POSSIBILITY OF SUCH DAMAGE.
33
+ ############################################################################
34
+
35
+ ## Basic execption type raised by this code
36
+ class MTik::Error < RuntimeError ; end
37
+
@@ -0,0 +1,37 @@
1
+ ############################################################################
2
+ ## A Ruby library implementing the Ruby MikroTik API
3
+ ############################################################################
4
+ ## Author:: Aaron D. Gifford - http://www.aarongifford.com/
5
+ ## Copyright:: Copyright (c) 2009-2010, InfoWest, Inc.
6
+ ## License:: BSD license
7
+ ##
8
+ ## Redistribution and use in source and binary forms, with or without
9
+ ## modification, are permitted provided that the following conditions
10
+ ## are met:
11
+ ## 1. Redistributions of source code must retain the above copyright
12
+ ## notice, the above list of authors and contributors, this list of
13
+ ## conditions and the following disclaimer.
14
+ ## 2. Redistributions in binary form must reproduce the above copyright
15
+ ## notice, this list of conditions and the following disclaimer in the
16
+ ## documentation and/or other materials provided with the distribution.
17
+ ## 3. Neither the name of the author(s) or copyright holder(s) nor the
18
+ ## names of any contributors may be used to endorse or promote products
19
+ ## derived from this software without specific prior written permission.
20
+ ##
21
+ ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S), AUTHOR(S) AND
22
+ ## CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
23
+ ## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
+ ## AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25
+ ## IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), AUTHOR(S), OR CONTRIBUTORS BE
26
+ ## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ ## DCONSEQUENTIAL AMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32
+ ## THE POSSIBILITY OF SUCH DAMAGE.
33
+ ############################################################################
34
+
35
+ ## Execption raised when a '!fatal' response is received from a device
36
+ class MTik::FatalError < MTik::Error ; end
37
+
@@ -0,0 +1,50 @@
1
+ ############################################################################
2
+ ## A Ruby library implementing the Ruby MikroTik API
3
+ ############################################################################
4
+ ## Author:: Aaron D. Gifford - http://www.aarongifford.com/
5
+ ## Copyright:: Copyright (c) 2009-2010, InfoWest, Inc.
6
+ ## License:: BSD license
7
+ ##
8
+ ## Redistribution and use in source and binary forms, with or without
9
+ ## modification, are permitted provided that the following conditions
10
+ ## are met:
11
+ ## 1. Redistributions of source code must retain the above copyright
12
+ ## notice, the above list of authors and contributors, this list of
13
+ ## conditions and the following disclaimer.
14
+ ## 2. Redistributions in binary form must reproduce the above copyright
15
+ ## notice, this list of conditions and the following disclaimer in the
16
+ ## documentation and/or other materials provided with the distribution.
17
+ ## 3. Neither the name of the author(s) or copyright holder(s) nor the
18
+ ## names of any contributors may be used to endorse or promote products
19
+ ## derived from this software without specific prior written permission.
20
+ ##
21
+ ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S), AUTHOR(S) AND
22
+ ## CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
23
+ ## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
+ ## AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25
+ ## IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), AUTHOR(S), OR CONTRIBUTORS BE
26
+ ## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ ## DCONSEQUENTIAL AMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32
+ ## THE POSSIBILITY OF SUCH DAMAGE.
33
+ ############################################################################
34
+
35
+ ## A MikroTik API reply is stored as an array of response sentences. Each
36
+ ## sentence is a key/value Hash object. The MTik::Reply class is simply
37
+ ## a basic Ruby Array with a find_sentence method added.
38
+ class MTik::Reply < Array
39
+ def find_sentence(key)
40
+ i = 0
41
+ while i < self.length
42
+ if self[i].key?(key)
43
+ return self[i]
44
+ end
45
+ i += 1
46
+ end
47
+ return nil
48
+ end
49
+ end
50
+
@@ -0,0 +1,265 @@
1
+ ############################################################################
2
+ ## A Ruby library implementing the Ruby MikroTik API
3
+ ############################################################################
4
+ ## Author:: Aaron D. Gifford - http://www.aarongifford.com/
5
+ ## Copyright:: Copyright (c) 2009-2010, InfoWest, Inc.
6
+ ## License:: BSD license
7
+ ##
8
+ ## Redistribution and use in source and binary forms, with or without
9
+ ## modification, are permitted provided that the following conditions
10
+ ## are met:
11
+ ## 1. Redistributions of source code must retain the above copyright
12
+ ## notice, the above list of authors and contributors, this list of
13
+ ## conditions and the following disclaimer.
14
+ ## 2. Redistributions in binary form must reproduce the above copyright
15
+ ## notice, this list of conditions and the following disclaimer in the
16
+ ## documentation and/or other materials provided with the distribution.
17
+ ## 3. Neither the name of the author(s) or copyright holder(s) nor the
18
+ ## names of any contributors may be used to endorse or promote products
19
+ ## derived from this software without specific prior written permission.
20
+ ##
21
+ ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S), AUTHOR(S) AND
22
+ ## CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
23
+ ## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
+ ## AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25
+ ## IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), AUTHOR(S), OR CONTRIBUTORS BE
26
+ ## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ ## DCONSEQUENTIAL AMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32
+ ## THE POSSIBILITY OF SUCH DAMAGE.
33
+ ############################################################################
34
+
35
+ ## A MikroTik API request object is stored as an array of MikroTik
36
+ ## API-style words, the first word being the command, subsequent words
37
+ ## (if any) are command arguments. Each request will automatically
38
+ ## have a unique tag generated (so any +.tag=value+ arguments will be
39
+ ## ignored). A request is incomplete until the final +!done+ response
40
+ ## sentence has been received.
41
+ class MTik::Request < Array
42
+ @@tagspace = 0 ## Used to keep all tags unique.
43
+
44
+ ## Create a new MTik::Request.
45
+ ## +await_completion+ :: A boolean parameter indicating when callback(s)
46
+ ## should be called. A value of _true_ will result
47
+ ## in callback(s) only being called once, when the
48
+ ## final +!done+ response is received. A value of
49
+ ## _false_ means callback(s) will be called _each_
50
+ ## time a response sentence is received.
51
+ ## +command+ :: The MikroTik API command to execute (a String).
52
+ ## Examples:
53
+ ## * +"/interface/getall"+
54
+ ## * +"/ip/route/add"+
55
+ ## +args+ :: Zero or more String arguments for the command,
56
+ ## already encoded in +"=key=value"+, +".id=value"+
57
+ ## or +"?query"+ API format.
58
+ ## +callback+:: A Proc or code block may be passed which will
59
+ ## be called with two arguments:
60
+ ## 1. this MTik::Request object; and
61
+ ## 2. the most recently received response sentence.
62
+ ## When or how often callbacks are called depends on
63
+ ## whether the +await_completion+ parameter is _true_
64
+ ## or _false_ (see above).
65
+ def initialize(await_completion, command, *args, &callback)
66
+ @reply = MTik::Reply.new
67
+ @command = command
68
+ @await_completion = await_completion
69
+ @state = 'new' ## 'new', 'sent', 'cancelled', 'complete'
70
+ @conn = nil
71
+
72
+ args.flatten!
73
+ @callbacks = Array.new
74
+ if block_given?
75
+ @callbacks.push(callback)
76
+ elsif args.length > 0 && args[args.length-1].is_a?(Proc)
77
+ @callbacks.push(args.pop)
78
+ end
79
+
80
+ super(&nil)
81
+ ## Add command to the request sentence list:
82
+ self.push(command)
83
+
84
+ ## Add all arguments to the request sentence list:
85
+ self.addargs(*args)
86
+
87
+ ## Append a unique tag for the request:
88
+ @tag = @@tagspace.to_s
89
+ @@tagspace += 1
90
+ self.push(".tag=#{@tag}")
91
+ end
92
+
93
+ ## Add one or more callback Procs and/or a code block
94
+ ## to the callback(s) that will be executed upon reply
95
+ ## (either complete or partial, depending on the
96
+ ## _await_completion_ setting)
97
+ def append_callback(*callbacks, &callback)
98
+ callbacks.flatten!
99
+ callbacks.each do |cb|
100
+ @callbacks.push(cb)
101
+ end
102
+ if block_given?
103
+ @callbacks.push(callback)
104
+ end
105
+ end
106
+
107
+ ## Append one or more arguments to the not-yet-sent request
108
+ def addargs(*args)
109
+ ## Add all additional arguments to the request sentence list:
110
+ args.each do |arg|
111
+ if arg.is_a?(Hash)
112
+ ## Prepend argument keys that don't begin with the API-
113
+ ## command-specific parameter character '.', nor the
114
+ ## normal parameter charactre '=', nor the query character
115
+ ## '?' with the ordinary parameter character '=':
116
+ arg.each do |key, value|
117
+ key = '=' + key unless /^[\?\=\.]/.match(key)
118
+ addarg(key + '=' + value)
119
+ end
120
+ else
121
+ addarg(arg)
122
+ end
123
+ end
124
+ end
125
+
126
+ ## Append a single argument to the not-yet-sent request
127
+ def addarg(arg)
128
+ unless /^\.tag=/.match(arg)
129
+ self.push(arg)
130
+ end
131
+ end
132
+
133
+ ## Return the boolean completion status of the request,
134
+ ## _true_ if complete, _false_ if not-yet-complete.
135
+ def done?
136
+ return @state == 'complete'
137
+ end
138
+
139
+ attr_reader :command, :tag, :await_completion, :reply, :state
140
+
141
+ ## Execute all callbacks, passing _sentence_ along as
142
+ ## the second parameter to each callback.
143
+ def callback(sentence)
144
+ case @callbacks.length
145
+ when 0
146
+ return nil
147
+ when 1
148
+ return @callbacks[0].call(self, sentence)
149
+ else
150
+ result = Array.new
151
+ @callbacks.each do |cb|
152
+ result.push(cb.call(self, sentence))
153
+ end
154
+ return result
155
+ end
156
+ end
157
+
158
+ ## Utility method for packing an unsigned integer as
159
+ ## a binary byte string of variable length
160
+ def self.bytepack(num)
161
+ s = String.new
162
+ if RUBY_VERSIION >= '1.9.0'
163
+ s.force_encoding(Encoding::BINARY)
164
+ end
165
+ x = num < 0 ? -num : num ## Treat as unsigned
166
+ while x > 0
167
+ s += (x & 0xff).chr
168
+ x >>= 8
169
+ end
170
+ return s
171
+ end
172
+
173
+ ## Another utility method to encode a byte string as a
174
+ ## valid API _"word"_
175
+ def self.to_tikword(str)
176
+ str = str.dup
177
+ if RUBY_VERSION >= '1.9.0'
178
+ str.force_encoding(Encoding::BINARY)
179
+ end
180
+ if str.length < 0x80
181
+ return str.length.chr + str
182
+ elsif str.length < 0x4000
183
+ return bytepack(str.length | 0x8000) + str
184
+ elsif str.length < 0x200000
185
+ return bytepack(str.length | 0xc00000) + str
186
+ elsif str.length < 0x10000000
187
+ return bytepack(str.length | 0xe0000000) + str
188
+ elsif str.length < 0x0100000000
189
+ return 0xf0.chr + bytepack(str.length) + str
190
+ else
191
+ raise RuntimeError.new(
192
+ "String is too long to be encoded for " +
193
+ "the MikroTik API using a 4-byte length!"
194
+ )
195
+ end
196
+ end
197
+
198
+ ## Associate this request with a connection:
199
+ def conn(c)
200
+ unless c.is_a?(MTik::Connection)
201
+ raise RuntimeError.new(
202
+ "Unexpected class '#{c.class}' in MTik::Request#conn() " +
203
+ "(expected MTik::Connection)"
204
+ )
205
+ end
206
+ unless @conn.nil?
207
+ raise MTik::Error.new(
208
+ "Method MTik::Request#conn() called when MTik::Request " +
209
+ "is already associated with an MTik::Connection object."
210
+ )
211
+ end
212
+ @conn = c
213
+ end
214
+
215
+ ## Encode this request as a binary byte string ready for transmission
216
+ ## to a MikroTik device
217
+ def request
218
+ ## Encode the request for sending to the device:
219
+ return self.map {|w| MTik::Request::to_tikword(w)}.join + 0x00.chr
220
+ end
221
+
222
+ ## Send the request over the associated connection:
223
+ def send
224
+ if @conn.nil?
225
+ raise MTik::Error.new(
226
+ "Method MTik::Request#send() called when MTik::Request " +
227
+ "is not yet associated with an MTik::Connection object."
228
+ )
229
+ end
230
+ @state = 'sent'
231
+ return @conn.xmit(self)
232
+ end
233
+
234
+ ## Cancel a 'sent' request:
235
+ def cancel(&callback)
236
+ if @state != 'sent'
237
+ raise MTik::Error.new(
238
+ "Method MTik::Request#cancel() called with state '#{@state}' " +
239
+ "(should only call when state is 'sent')"
240
+ )
241
+ end
242
+ @conn.send_request(true, '/cancel', '=tag=' + @tag, &callback)
243
+ @state = 'cancelled'
244
+ end
245
+
246
+ ## Cancel a 'sent' request:
247
+ def cancel_each(&callback)
248
+ if @state != 'sent'
249
+ raise MTik::Error.new(
250
+ "Method MTik::Request#cancel() called with state '#{@state}' " +
251
+ "(should only call when state is 'sent')"
252
+ )
253
+ end
254
+ @conn.send_request(false, '/cancel', '=tag=' + @tag, &callback)
255
+ @state = 'cancelled'
256
+ end
257
+
258
+ ## Method the internal parser calls to flag this reply as completed
259
+ ## upon receipt of a +!done+ reply sentence.
260
+ def done!
261
+ @state = 'complete'
262
+ return true
263
+ end
264
+ end
265
+
@@ -0,0 +1,37 @@
1
+ ############################################################################
2
+ ## A Ruby library implementing the Ruby MikroTik API
3
+ ############################################################################
4
+ ## Author:: Aaron D. Gifford - http://www.aarongifford.com/
5
+ ## Copyright:: Copyright (c) 2009-2010, InfoWest, Inc.
6
+ ## License:: BSD license
7
+ ##
8
+ ## Redistribution and use in source and binary forms, with or without
9
+ ## modification, are permitted provided that the following conditions
10
+ ## are met:
11
+ ## 1. Redistributions of source code must retain the above copyright
12
+ ## notice, the above list of authors and contributors, this list of
13
+ ## conditions and the following disclaimer.
14
+ ## 2. Redistributions in binary form must reproduce the above copyright
15
+ ## notice, this list of conditions and the following disclaimer in the
16
+ ## documentation and/or other materials provided with the distribution.
17
+ ## 3. Neither the name of the author(s) or copyright holder(s) nor the
18
+ ## names of any contributors may be used to endorse or promote products
19
+ ## derived from this software without specific prior written permission.
20
+ ##
21
+ ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S), AUTHOR(S) AND
22
+ ## CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
23
+ ## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
+ ## AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25
+ ## IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), AUTHOR(S), OR CONTRIBUTORS BE
26
+ ## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ ## DCONSEQUENTIAL AMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32
+ ## THE POSSIBILITY OF SUCH DAMAGE.
33
+ ############################################################################
34
+
35
+ ## Exception raised upon timeout
36
+ class MTik::TimeoutError < MTik::Error ; end
37
+
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mtik
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Aaron D. Gifford
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-05 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: MTik implements the MikroTik RouterOS API for use in Ruby.
17
+ email: email_not_accepted@aarongifford.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.txt
24
+ files:
25
+ - CHANGELOG.txt
26
+ - LICENSE.txt
27
+ - README.txt
28
+ - VERSION.txt
29
+ - examples/tikcli.rb
30
+ - examples/tikcommand.rb
31
+ - examples/tikfetch.rb
32
+ - examples/tikjson.rb
33
+ - lib/mtik.rb
34
+ - lib/mtik/connection.rb
35
+ - lib/mtik/error.rb
36
+ - lib/mtik/fatalerror.rb
37
+ - lib/mtik/reply.rb
38
+ - lib/mtik/request.rb
39
+ - lib/mtik/timeouterror.rb
40
+ has_rdoc: true
41
+ homepage: http://www.aarongifford.com/computers/mtik/
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project: mtik
62
+ rubygems_version: 1.3.1
63
+ signing_key:
64
+ specification_version: 2
65
+ summary: MTik implements the MikroTik RouterOS API for use in Ruby.
66
+ test_files: []
67
+