mtik 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,29 @@
1
+ 2010-02-05 (05 FEB 2010) VERSION 3.0.2 Aaron D. Gifford (http://www.aarongifford.com)
2
+ * Typo fixes to example tikfetch.rb
3
+ * Multi-command functionality added to interactive client and to tikcommand.rb example
4
+ * Removed kludge path stuff for author's broken FreeBSD Ruby 1.9.1 gem system
5
+ * Removed lame JSON-ifier from example and switched to require 'json' instead
6
+
7
+ 2010-01-19 (19 JAN 2010) VERSION 3.0.1 Aaron D. Gifford (http://www.aarongifford.com/)
8
+ * Added support for '/tool/fetch' 'requesting' state
9
+ * Added auto-cancel of finished '/tool/fetch' command in MTik#command()
10
+ * Added MTik::Request#cancel() method
11
+ * Added MTik::Request#state() attr_reader (and new @state object property to replace
12
+ the @completed boolean property)
13
+ * MTik::Request objects now associate with the appropriate MTik::Connection object
14
+ upon MTik::Connection transmitting the request to a device (which facilities)
15
+ the MTik::Request@cancel() method
16
+ * Removed gem root directory mtik.rb file that was acting as a kludge for the author's
17
+ messed-up FreeBSD Ruby 1.9 installation
18
+ * Renamed examples with a 'tik' prefix
19
+
20
+ 2010-01-15 (15 JAN 2010) VERSION 3.0.0 Aaron D. Gifford (http://www.aarongifford.com/)
21
+ * Bumped the version to 3.0.0 due to modularization and gemification changes
22
+ that break any software using the older Ruby API classes.
23
+ * Split out (as separate files) and added a few more examples:
24
+ cli.rb
25
+ command.rb
26
+ json.rb
27
+ fetch.rb
28
+ * Added VERSION.txt, CHANGELOG.txt, README.txt, LICENSE.txt, and *.gemspec files, moved
29
+ the example files into the bin subdirectory
@@ -0,0 +1,36 @@
1
+ ########################################################################
2
+ #--
3
+ #
4
+ # GEM: MTik -- A Ruby gem implementing the MikroTik RouterOS API
5
+ #
6
+ #++
7
+ # Author:: Aaron D. Gifford - http://www.aarongifford.com/
8
+ # Copyright:: Copyright (c) 2009-2010, InfoWest, Inc.
9
+ # License:: BSD license
10
+ #--
11
+ # Redistribution and use in source and binary forms, with or without
12
+ # modification, are permitted provided that the following conditions
13
+ # are met:
14
+ # 1. Redistributions of source code must retain the above copyright
15
+ # notice, the above list of authors and contributors, this list of
16
+ # conditions and the following disclaimer.
17
+ # 2. Redistributions in binary form must reproduce the above copyright
18
+ # notice, this list of conditions and the following disclaimer in the
19
+ # documentation and/or other materials provided with the distribution.
20
+ # 3. Neither the name of the author(s) or copyright holder(s) nor the
21
+ # names of any contributors may be used to endorse or promote products
22
+ # derived from this software without specific prior written permission.
23
+ #
24
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S), AUTHOR(S) AND
25
+ # CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
26
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
28
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), AUTHOR(S), OR CONTRIBUTORS BE
29
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30
+ # DCONSEQUENTIAL AMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35
+ # THE POSSIBILITY OF SUCH DAMAGE.
36
+ ########################################################################
@@ -0,0 +1,64 @@
1
+ = MTik -- A Ruby implementation of the MikroTik RouterOS API
2
+
3
+ The MTik gem implements the MikroTik RouterOS API for connecting to
4
+ devices running RouterOS (with the API enabled) over the network.
5
+
6
+
7
+ == Examples
8
+
9
+ Included in the examples subdirectory are four example ruby scripts
10
+ that use the Ruby API implementation:
11
+
12
+ tikcli.rb:: A command-line-like API interface
13
+ tikcommand.rb:: A tool for executing a single API command from
14
+ a unix command-line
15
+ tikfetch.rb:: A tool for instructing devices to download files
16
+ from specified URLs (unix command-line tool)
17
+ tikjson.rb:: Like 'command.rb' a tool for executing a single
18
+ API command, except the output is formatted in
19
+ JSON-style
20
+
21
+
22
+ == Download
23
+
24
+ The latest version of MTik can be found at
25
+
26
+ * http://www.aarongifford.com/computers/mtik/
27
+
28
+ Ruby RDoc documentation can be found online at
29
+
30
+ * http://www.aarongifford.com/computers/mtik/latest/doc/
31
+
32
+ Additional documentation is available at
33
+
34
+ * http://www.aarongifford.com/computers/mtik/
35
+ * http://wiki.mikrotik.com/wiki/API_Ruby_class
36
+
37
+ For documentation on the MikroTik RouterOS APi, see
38
+
39
+ * http://wiki.mikrotik.com/wiki/API
40
+
41
+
42
+ == Installation
43
+
44
+ To install MTik is through its GEM file:
45
+
46
+ % [sudo] gem install mtik-3.3.0.gem
47
+
48
+ == License
49
+
50
+ This gem and all other scripts and documentation files are licensed
51
+ under a BSD-style license. (See the LICENSE.txt file.)
52
+
53
+
54
+ == Report Bugs
55
+
56
+ Please report bugs by going to the author's web site and clicking on the
57
+ "Contact Me" link in the left-hand menu. The direct URL is:
58
+
59
+ * http://www.aarongifford.com/leaveanote.html
60
+
61
+ Thank you!
62
+
63
+ -- Aaron D. Gifford
64
+
@@ -0,0 +1 @@
1
+ 3.0.2
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+ ########################################################################
3
+ #--
4
+ #
5
+ # FILE: tikcli.rb -- Example of using the Ruby MikroTik API in Ruby
6
+ #
7
+ #++
8
+ # Author:: Aaron D. Gifford - http://www.aarongifford.com/
9
+ # Copyright:: Copyright (c) 2009-2010, InfoWest, Inc.
10
+ # License:: BSD license
11
+ #--
12
+ # Redistribution and use in source and binary forms, with or without
13
+ # modification, are permitted provided that the following conditions
14
+ # are met:
15
+ # 1. Redistributions of source code must retain the above copyright
16
+ # notice, the above list of authors and contributors, this list of
17
+ # conditions and the following disclaimer.
18
+ # 2. Redistributions in binary form must reproduce the above copyright
19
+ # notice, this list of conditions and the following disclaimer in the
20
+ # documentation and/or other materials provided with the distribution.
21
+ # 3. Neither the name of the author(s) or copyright holder(s) nor the
22
+ # names of any contributors may be used to endorse or promote products
23
+ # derived from this software without specific prior written permission.
24
+ #
25
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S), AUTHOR(S) AND
26
+ # CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
27
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), AUTHOR(S), OR CONTRIBUTORS BE
30
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31
+ # DCONSEQUENTIAL AMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36
+ # THE POSSIBILITY OF SUCH DAMAGE.
37
+ ########################################################################
38
+ $LOAD_PATH.unshift(File.dirname(__FILE__)+'/../lib')
39
+
40
+ require 'rubygems'
41
+ require 'mtik'
42
+
43
+ unless ARGV.length == 3
44
+ STDERR.print("Usage: #{$0} <host> <user> <pass>\n")
45
+ exit(-1)
46
+ end
47
+
48
+ MTik::interactive_client(ARGV[0], ARGV[1], ARGV[2])
49
+
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env ruby
2
+ ########################################################################
3
+ #--
4
+ #
5
+ # FILE: command.rb -- Example of using the Ruby MikroTik API in Ruby
6
+ #
7
+ #++
8
+ # Author:: Aaron D. Gifford - http://www.aarongifford.com/
9
+ # Copyright:: Copyright (c) 2009-2010, InfoWest, Inc.
10
+ # License:: BSD license
11
+ #--
12
+ # Redistribution and use in source and binary forms, with or without
13
+ # modification, are permitted provided that the following conditions
14
+ # are met:
15
+ # 1. Redistributions of source code must retain the above copyright
16
+ # notice, the above list of authors and contributors, this list of
17
+ # conditions and the following disclaimer.
18
+ # 2. Redistributions in binary form must reproduce the above copyright
19
+ # notice, this list of conditions and the following disclaimer in the
20
+ # documentation and/or other materials provided with the distribution.
21
+ # 3. Neither the name of the author(s) or copyright holder(s) nor the
22
+ # names of any contributors may be used to endorse or promote products
23
+ # derived from this software without specific prior written permission.
24
+ #
25
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S), AUTHOR(S) AND
26
+ # CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
27
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), AUTHOR(S), OR CONTRIBUTORS BE
30
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31
+ # DCONSEQUENTIAL AMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36
+ # THE POSSIBILITY OF SUCH DAMAGE.
37
+ ########################################################################
38
+ $LOAD_PATH.unshift(File.dirname(__FILE__)+'/../lib')
39
+
40
+ require 'rubygems'
41
+ require 'mtik'
42
+
43
+ unless ARGV.length > 3
44
+ STDERR.print("Usage: #{$0} <host> <user> <pass> <command> [<args>...] [<command> [<args> ...]]\n")
45
+ exit(-1)
46
+ end
47
+
48
+ MTik::verbose = true ## Set how you want
49
+
50
+ ## Detect multiple command sequences and build an array of arrays
51
+ ## where each outer array element is a command plus arguments:
52
+ command = Array.new
53
+ i = 3
54
+ while i < ARGV.length
55
+ if ARGV[i][0,1] == '/' ## Command detected...
56
+ command << [ ARGV[i] ]
57
+ else
58
+ command[command.length-1] << ARGV[i]
59
+ end
60
+ i += 1
61
+ end
62
+
63
+ p MTik::command(
64
+ :host=>ARGV[0],
65
+ :user=>ARGV[1],
66
+ :pass=>ARGV[2],
67
+ :command=>command
68
+ )
69
+
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+ ########################################################################
3
+ #--
4
+ #
5
+ # FILE: fetch.rb -- Example of using the Ruby MikroTik API in Ruby
6
+ #
7
+ #++
8
+ # Author:: Aaron D. Gifford - http://www.aarongifford.com/
9
+ # Copyright:: Copyright (c) 2009-2010, InfoWest, Inc.
10
+ # License:: BSD license
11
+ #--
12
+ # Redistribution and use in source and binary forms, with or without
13
+ # modification, are permitted provided that the following conditions
14
+ # are met:
15
+ # 1. Redistributions of source code must retain the above copyright
16
+ # notice, the above list of authors and contributors, this list of
17
+ # conditions and the following disclaimer.
18
+ # 2. Redistributions in binary form must reproduce the above copyright
19
+ # notice, this list of conditions and the following disclaimer in the
20
+ # documentation and/or other materials provided with the distribution.
21
+ # 3. Neither the name of the author(s) or copyright holder(s) nor the
22
+ # names of any contributors may be used to endorse or promote products
23
+ # derived from this software without specific prior written permission.
24
+ #
25
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S), AUTHOR(S) AND
26
+ # CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
27
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), AUTHOR(S), OR CONTRIBUTORS BE
30
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31
+ # DCONSEQUENTIAL AMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36
+ # THE POSSIBILITY OF SUCH DAMAGE.
37
+ ########################################################################
38
+ $LOAD_PATH.unshift(File.dirname(__FILE__)+'/../lib')
39
+
40
+ require 'rubygems'
41
+ require 'mtik'
42
+
43
+ ## Uncomment this (set $VERBOSE to true) if you want crazy verbose
44
+ ## output of all API interactions:
45
+ #MTik::verbose = true
46
+
47
+ if ARGV.length < 5 || ARGV.length % 2 != 1
48
+ print "Usage: #{$0} <device> <user> <pass> <url> <localfilename> [<url> <localfilename>...]\n"
49
+ exit
50
+ end
51
+
52
+ host = ARGV.shift
53
+ user = ARGV.shift
54
+ pass = ARGV.shift
55
+ begin
56
+ mt = MTik::Connection.new(:host=>host, :user=>user, :pass=>pass)
57
+ rescue Errno::ETIMEDOUT, Errno::ENETUNREACH, Errno::EHOSTUNREACH, MTik::Error => e
58
+ print ">>> ERROR CONNECTING: #{e}"
59
+ exit
60
+ end
61
+
62
+ ## List all files:
63
+ files = Hash.new
64
+ mt.get_reply_each('/file/getall') do |req, s|
65
+ unless s.key?('!done')
66
+ files[s['name']] = true
67
+ end
68
+ end
69
+
70
+ while ARGV.length > 0
71
+ url, filename = ARGV.shift, ARGV.shift
72
+ if files.key?(filename)
73
+ print ">>> ERROR: There is a file named '#{filename}' already on the device.\n"
74
+ else
75
+ print ">>> OK: Fetching file '#{filename}' from URL '#{url}'...\n"
76
+ mt.fetch(url, filename) do |status, total, bytes|
77
+ case status
78
+ when 'failed'
79
+ print ">>> ERROR: File '#{filename}' download failed!\n"
80
+ when 'finished'
81
+ print ">>> OK: File '#{filename}' download finished.\n"
82
+ when 'connecting'
83
+ print ">>> OK: Connecting to '#{url}' to download file '#{filename}'\n"
84
+ when 'downloading'
85
+ print ">>> OK: Downloaded #{bytes} bytes of #{total} of file " +
86
+ "'#{filename}' " +
87
+ (total > 0 ? '%0.2f' % (100.0*bytes/total) : '0') +
88
+ "%\n"
89
+ else
90
+ print ">>> ERROR: The following trap error occured: #{status}\n"
91
+ end
92
+ end
93
+ end
94
+ end
95
+ mt.wait_all
96
+
97
+ print "\n"
98
+ print "SIZE CREATED FILENAME\n"
99
+ print "====================================================================\n"
100
+ mt.get_reply_each('/file/getall') do |req, s|
101
+ unless s.key?('!done')
102
+ print "#{(s['size']+' ')[0,10]} #{s['creation-time']} #{s['name']}\n"
103
+ end
104
+ end
105
+
106
+ print "\n"
107
+
108
+ mt.close
109
+
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env ruby
2
+ ########################################################################
3
+ #--
4
+ #
5
+ # FILE: json.rb -- Example of using the Ruby MikroTik API in Ruby
6
+ #
7
+ #++
8
+ # Author:: Aaron D. Gifford - http://www.aarongifford.com/
9
+ # Copyright:: Copyright (c) 2009-2010, InfoWest, Inc.
10
+ # License:: BSD license
11
+ #--
12
+ # Redistribution and use in source and binary forms, with or without
13
+ # modification, are permitted provided that the following conditions
14
+ # are met:
15
+ # 1. Redistributions of source code must retain the above copyright
16
+ # notice, the above list of authors and contributors, this list of
17
+ # conditions and the following disclaimer.
18
+ # 2. Redistributions in binary form must reproduce the above copyright
19
+ # notice, this list of conditions and the following disclaimer in the
20
+ # documentation and/or other materials provided with the distribution.
21
+ # 3. Neither the name of the author(s) or copyright holder(s) nor the
22
+ # names of any contributors may be used to endorse or promote products
23
+ # derived from this software without specific prior written permission.
24
+ #
25
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S), AUTHOR(S) AND
26
+ # CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
27
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), AUTHOR(S), OR CONTRIBUTORS BE
30
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31
+ # DCONSEQUENTIAL AMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36
+ # THE POSSIBILITY OF SUCH DAMAGE.
37
+ ########################################################################
38
+ $LOAD_PATH.unshift(File.dirname(__FILE__)+'/../lib')
39
+
40
+ require 'rubygems'
41
+ require 'mtik'
42
+ require 'json'
43
+
44
+ unless ARGV.length > 3
45
+ STDERR.print("Usage: #{$0} <host> <user> <pass> <command> [<args>...] [<command> [<args> ...]]\n")
46
+ exit(-1)
47
+ end
48
+
49
+ ## Detect multiple command sequences and build an array of arrays
50
+ ## where each outer array element is a command plus arguments:
51
+ command = Array.new
52
+ i = 3
53
+ while i < ARGV.length
54
+ if ARGV[i][0,1] == '/' ## Command detected...
55
+ command << [ ARGV[i] ]
56
+ else
57
+ command[command.length-1] << ARGV[i]
58
+ end
59
+ i += 1
60
+ end
61
+
62
+ print MTik::command(
63
+ :host=>ARGV[0],
64
+ :user=>ARGV[1],
65
+ :pass=>ARGV[2],
66
+ :command=>command
67
+ ).to_json + "\n"
68
+
@@ -0,0 +1,244 @@
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
+ module MTik
35
+ require 'mtik/error.rb'
36
+ require 'mtik/fatalerror.rb'
37
+ require 'mtik/timeouterror.rb'
38
+ require 'mtik/request.rb'
39
+ require 'mtik/reply.rb'
40
+ require 'mtik/connection.rb'
41
+
42
+ ## Default MikroTik RouterOS API TCP port:
43
+ PORT = 8728
44
+ ## Default username to use if none is specified:
45
+ USER = 'admin'
46
+ ## Default password to use if none is specified:
47
+ PASS = ''
48
+ ## Connection timeout default -- *NOT USED*
49
+ CONN_TIMEOUT = 60
50
+ ## Command timeout -- The maximum number of seconds to wait for more
51
+ ## API data when expecting one or more command responses.
52
+ CMD_TIMEOUT = 60
53
+
54
+ @verbose = false
55
+ @debug = false
56
+
57
+ ## Access the current verbose setting (boolean)
58
+ def self.verbose
59
+ return @verbose
60
+ end
61
+
62
+ ## Change the current verbose setting (boolean)
63
+ def self.verbose=(x)
64
+ return @verbose = x
65
+ end
66
+
67
+ ## Access the current debug setting (boolean)
68
+ def self.debug
69
+ return @debug
70
+ end
71
+
72
+ ## Change the current debug setting (boolean)
73
+ def self.debug=(x)
74
+ return @debug = x
75
+ end
76
+
77
+
78
+ ## Act as an interactive client with the device, accepting user
79
+ ## input from STDIN.
80
+ def self.interactive_client(host, user, pass)
81
+ old_verbose = MTik::verbose
82
+ MTik::verbose = true
83
+ begin
84
+ tk = MTik::Connection.new(:host => host, :user => user, :pass => pass)
85
+ rescue MTik::Error, Errno::ECONNREFUSED => e
86
+ print "=== LOGIN ERROR: #{e.message}\n"
87
+ exit
88
+ end
89
+
90
+ while true
91
+ print "\nCommand (/quit to end): "
92
+ cmd = STDIN.gets.sub(/^\s+/, '').sub(/\s*[\r\n]*$/, '')
93
+ maxreply = 0
94
+ m = /^(\d+):/.match(cmd)
95
+ unless m.nil?
96
+ maxreply = m[1].to_i
97
+ cmd.sub!(/^\d+:/, '')
98
+ end
99
+ args = cmd.split(/\s+/)
100
+ cmd = args.shift
101
+ next if cmd == ''
102
+ break if cmd == '/quit'
103
+ unless /^(?:\/[a-zA-Z0-9]+)+$/.match(cmd)
104
+ print "=== INVALID COMMAND: #{cmd}\n" if MTik::debug || MTik::verbose
105
+ break
106
+ end
107
+ print "=== COMMAND: #{cmd}\n" if MTik::debug || MTik::verbose
108
+ trap = false
109
+ count = 0
110
+ state = 0
111
+ begin
112
+ tk.send_request(false, cmd, args) do |req, sentence|
113
+ if sentence.key?('!trap')
114
+ trap = sentence
115
+ print "=== TRAP: '" + (trap.key?('message') ? trap['message'] : "UNKNOWN") + "'\n\n"
116
+ elsif sentence.key?('!re')
117
+ count += 1
118
+ ## Auto-cancel any '/tool/fetch' commands that have finished,
119
+ ## or commands that have received the specified number of
120
+ ## replies:
121
+ if req.state != 'cancelled' && (
122
+ cmd == '/tool/fetch' && sentence.key?('status') && sentence['status'] == 'finished'
123
+ ) || (maxreply > 0 && count == maxreply)
124
+ state = 2
125
+ req.cancel do |req, sentence|
126
+ state = 1
127
+ end
128
+ end
129
+ elsif !sentence.key?('!done') && !sentence.key?('!fatal')
130
+ raise MTik::Error.new("Unknown or unexpected reply sentence type.")
131
+ end
132
+ if state == 0 && req.done?
133
+ state = 1
134
+ end
135
+ end
136
+ while state != 1
137
+ tk.wait_for_reply
138
+ end
139
+ rescue MTik::Error => e
140
+ print "=== ERROR: #{e.message}\n"
141
+ end
142
+ unless tk.connected?
143
+ begin
144
+ tk.login
145
+ rescue MTik::Error => e
146
+ print "=== LOGIN ERROR: #{e.message}\n"
147
+ tk.close
148
+ exit
149
+ end
150
+ end
151
+ end
152
+
153
+ reply = tk.get_reply('/quit')
154
+ unless reply[0].key?('!fatal')
155
+ raise MTik::Error.new("Unexpected response to '/quit' command.")
156
+ end
157
+
158
+ ## Extract any device-provided message from the '!fatal' response
159
+ ## to the /quit command:
160
+ print "=== SESSION TERMINATED"
161
+ message = ''
162
+ reply[0].each_key do |key|
163
+ next if key == '!fatal'
164
+ message += "'#{key}'"
165
+ unless reply[0][key].nil?
166
+ message += " => '#{reply[0][key]}'"
167
+ end
168
+ end
169
+ if message.length > 0
170
+ print ": " + message
171
+ else
172
+ print " ==="
173
+ end
174
+ print "\n\n"
175
+
176
+ unless tk.connected?
177
+ print "=== Disconnected ===\n\n"
178
+ else
179
+ ## In theory, this should never execute:
180
+ tk.close
181
+ end
182
+
183
+ MTik::verbose = old_verbose
184
+ end
185
+
186
+
187
+ ## An all-in-one function to instantiate, connect, send one or
188
+ ## more commands, retrieve the response(s), close the connection,
189
+ ## and return the response(s).
190
+ ##
191
+ ## *WARNING* :: If you use this call with an API command like
192
+ ## +/tool/fetch+ it will forever keep reading replies, never
193
+ ## returning. So do _NOT_ use this with any API command that does
194
+ ## not complete with a "!done" with no additional interaction.
195
+ def self.command(args)
196
+ tk = MTik::Connection.new(
197
+ :host => args[:host],
198
+ :user => args[:user],
199
+ :pass => args[:pass],
200
+ :port => args[:port],
201
+ :conn_timeout => args[:conn_timeout],
202
+ :cmd_timeout => args[:cmd_timeout]
203
+ )
204
+ cmd = args[:command]
205
+ replies = Array.new
206
+ if cmd.is_a?(String)
207
+ ## Single command, no arguments
208
+ cmd = [ [ cmd ] ]
209
+ elsif cmd.is_a?(Array) && !cmd[0].is_a?(Array)
210
+ ## Single command, possibly arguments
211
+ cmd = [ cmd ]
212
+ end
213
+
214
+ cmd.each do |c|
215
+ replycount = 1
216
+ tk.send_request(false, c[0], c[1,c.length-1]) do |req, sentence|
217
+ replycount += 1
218
+ if c[0] == '/tool/fetch'
219
+ if (
220
+ sentence.key?('status') &&
221
+ sentence['status'] == 'finished' &&
222
+ req.state != 'cancelled'
223
+ )
224
+ ## Cancel 'finished' fetch commands
225
+ req.cancel
226
+ end
227
+ elsif replycount >= 1000 && req.state != 'cancelled'
228
+ ## Auto-cancel any command after 1,000 replies:
229
+ req.cancel
230
+ end
231
+ if sentence.key?('!done')
232
+ replies.push(req.reply)
233
+ end
234
+ end
235
+ end
236
+
237
+ tk.wait_all ## Event loop -- wait for all commands
238
+ tk.get_reply('/quit')
239
+ tk.close
240
+ return replies
241
+ end
242
+
243
+ end
244
+