Giter Site home page Giter Site logo

mikrotik-java's Introduction

mikrotik-java

A Java client library implementation for the Mikrotik RouterOS API.

This project provides a Java client to manipulate Mikrotik routers using the remote API. Simple things must be easy to do, and complex things must be possible.

Versions

Java CI with Maven

The current stable version is 3.0.7

Version 3.0.7 fixes nested expressions when constructing complex queries using and and or expressions. See #72 for more information

Changes in version 3.0:

Version 3.0 addresses the problems the API had around TLS encryption. The way secure connections are implemented is changed so that the user has complete control over the creation of TLS sockets. To this end:

  • A new method, connect(SocketFactory fact, String host, int port, int timeout), was added to allow for better user control over sockets and especially encryption.
  • The connectTLS() API methods were removed.
  • Most of the overloaded connect() methods were removed.
  • Added a pre-built jar file to the downloads.

Further changes include:

  • The previously deprecated disconnect() method is removed.

Versions 1.x and 2.x

Versions 1 and 2 are considered obsolete and will no longer be supported or patched.

Getting the API

Maven users can use the artifact from Maven Central with this dependency:

<dependency>
  <groupId>me.legrange</groupId>
  <artifactId>mikrotik</artifactId>
  <version>3.0.7</version>
</dependency>

You can also download the pre-built jar file, or a zip or tar.gz file with the source for the latest release here

Asking for help or contributing

I welcome contributions, be it bug fixes or other improvements.

Please read CONTRIBUTING.md for information on how to contribute to this project.

Using the API

How to use the API is best illustrated by examples.

These examples should illustrate how to use this library. Please note that I assume that the user is proficient in Java and understands the Mikrotik command line syntax. The command line syntax gives you an indication of what commands you can pass, but the RouterOS API used by this library does not support everyting.

Some things to consider when debugging your API calls are:

  • The RouterOS API does not support auto-completion. You need to write out command and parameter names. For example, you can't say /ip/hotspot/user/add name=john add=10.0.0.1, you need to write out address.
  • You need to quote values with spaces in. You can't say name=Joe Blogs, you need to use name="Joe Blogs"
  • Exceptions with a root cause of ApiCommandException are errors received from the remote RouterOS device and contain the error message received.

Opening a connection

Here is a simple example: Connect to a router and reboot it.

ApiConnection con = ApiConnection.connect("10.0.1.1"); // connect to router
con.login("admin","password"); // log in to router
con.execute("/system/reboot"); // execute a command
con.close(); // disconnect from router

The above example shows a easy way of creating an unencrypted connection using the default API port and timeout, which is useful for development and testing.

TLS encryption

For production environments, encrypting API traffic is recommended. To do this you need to open a TLS connection to the router by passing an instance of the SocketFactory you wish to use to construct the TLS socket to the API:

ApiConnection con = ApiConnection.connect(SSLSocketFactory.getDefault(), "10.0.1.1", ApiConnection.DEFAULT_TLS_PORT, ApiConnection.DEFAULT_CONNECTION_TIMEOUT);

Above an instance of the default SSL socket factory is passed to the API. This will work as long as the router's certificate has been added to the local key store. Besides allowing the user to specify the socket factory, the above method also gives full control over the TCP Port and connection timeout.

RouterOS also supports anonymous TLS. An example showing how to create a socket factory for anonymous TLS is AnonymousSocketFactory in the examples directory.

Connection timeouts

By default, the API will generate an exception if it cannot connect to the specified router. This can take place immediately (typically if the OS returns a 'Connection refused' error), but can also take up to 60 seconds if the router host is firewalled or if there are other network problems. This 60 seconds is the 'default connection timeout' an can be overridded by passing the preferred timeout to the APi as last parameter in a connect() call. For example:

   ApiConnection con = ApiConnection.connect(SSLSocketFactory.getDefault(), "10.0.1.1", ApiConnection.DEFAULT_TLS_PORT, 2000); // connect to router on the default API port and fail in 2 seconds

Constants

Some constants are provided in ApiConnection to make it easier for users to construct connections with default ports and timeouts:

Constant Use for Value
DEFAULT_PORT Default TCP port value for unencrypyted connections 8728
DEFAULT_TLS_PORT Default TCP port value for encrypyted connections 8729
DEFAULT_CONNECTION_TIMEOUT Default connection timeout value (ms) 60000

Try with resources

The API can also be used in a "try with resources" statement which will ensure that the connection is closed:

        try (ApiConnection con = ApiConnection.connect(SocketFactory.getDefault(), Config.HOST, ApiConnection.DEFAULT_PORT, 2000)) {
            con.login(Config.USERNAME, Config.PASSWORD);
            con.execute("/user/add name=eric");
        }

In following examples the connection, login and disconnection code will not be repeated. In all cases it is assumed that an ApiConnection has been established, login() has been called, and that the connection is called con.

Reading data

A simple example that returns a result - Print all interfaces:

List<Map<String, String>> rs = con.execute("/interface/print");
for (Map<String,String> r : rs) {
  System.out.println(r);
}

Results are returned as a list of maps of String key/value pairs. The reason for this is that a command can return multiple results, which have multpile variables. For example, to print the names of all the interfaces returned in the command above, do:

for (Map<String, String> map : rs) { 
  System.out.println(map.get("name"));
}

Filtering results

The same query, but with the results filtered: Print all interfaces of type 'vlan'.

List<Map<String, String>> rs = con.execute("/interface/print where type=vlan");

Selecting returned fields

The same query, but we only want certain result fields names: Print all interfaces of type 'vlan' and return just their name:

List<Map<String, String>> rs = con.execute("/interface/print where type=vlan return name");

Writing data

Creating, modifying and deleting configuration objects is of course possible.

Creating an object

This example shows how to create a new GRE interface:

con.execute("/interface/gre/add remote-address=192.168.1.1 name=gre1 keepalive=10");

Modify an existing object

Change the IP address in the object created by the above example:

con.execute("/interface/gre/set .id=gre1 remote-address=10.0.1.1"); 

Remove an existing object

And now remove the object:

con.execute("/interface/gre/remove .id=gre1"); 

Un-setting a variable on an object

Un-setting a variable is a bit different, and you need to use a parameter called value-name. This isn't well documented. Let's say you have a firewall rule that was set up like this:

con.execute("/ip/firewall/filter/add action=accept chain=forward time=00:00:01-01,mon")

Assuming the rule can be accessed as .id=*1, you un-set it by using value-name as seen below:

con.execute("/ip/firewall/filter/unset .id=*1 value-name=time");

Asynchronous commands

We can run some commands asynchronously in order to continue receiving updates:

This example shows how to run '/interface wireless monitor' and have the result sent to a listener object, which prints it:

String tag = con.execute("/interface/wireless/monitor .id=wlan1 return signal-to-noise", 
      new ResultListener() {

            public void receive(Map<String, String> result) {
                System.out.println(result);
            }

           public void error(MikrotikApiException e) {
               System.out.println("An error occurred: " + e.getMessage());
           }

           public void completed() {
                System.out.println("Asynchronous command has finished"); 
           }
            
        }
  );

The ResultListener interface has three methods the user needs to implement:

  • receive() is called to receive results produced by the router from the API.
  • error() is called when an exception is raised based on a 'trap' received from the router or another (typically connection) problem.
  • completed() is called when the router has indicated that the command has completed or has been cancelled.

The above command will run and send results asynchronously as they become available, until it is canceled. The command (identified by the unique String returned) is canceled like this:

con.cancel(tag);

Command timeouts

Command timeouts can be used to make sure that synchronous commands either return or fail within a specific time. Command timeouts are separate from the connection timeout used in connect(), and can be set using setTimeout(). Here is an example:

ApiConnection con = ApiConnection.connect("10.0.1.1"); // connect to router
con.setTimeout(5000); // set command timeout to 5 seconds
con.login("admin","password"); // log in to router
con.execute("/system/reboot"); // execute a command

It is important to note that command timeouts can be set before login() is called, and can therefore influence the behaviour of login.

The default command timeout, if none is set by the user, is 60 seconds.

References

The RouterOS API is documented here: http://wiki.mikrotik.com/wiki/Manual:API

Licence

This library is released under the Apache 2.0 licence. See the LICENCE.md file

mikrotik-java's People

Contributors

aro1976 avatar buckett avatar dependabot[bot] avatar gideonlegrange avatar metori avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mikrotik-java's Issues

Problems with special caracters

When I try to add a username that contains a special caracter like 'รงรฃรกรต' the api is replacing to '?'.
But when i put this special caracteres direct in the winbox it works ok.

Do you have an idea about what should be the problem???

Unkown parameter when parameter has multiple values

I dont know if it is a bug or I'm using this API wrong, but when I try to execute this command:
"/ip/firewall/filter/add action=drop chain=forward in-interface=aps_hs protocol=udp dst-port=78,80,32"
I got an unknown parameter exception.

When I put just one port or a range like 80-89 works fine.

Unset Command not working

Hi All,

I am trying to remove the time schedule from a firewall filter.

This can be easily done in the terminal with the following command:
/ip/firewall/filter/unset number=4 time
This removes the time schedule for rule number 4.

Using the API, I tried following the same command format, using the .id instead of number:
ip/firewall/filter/unset .id=*9 time

However, it keeps failing. I do not want to remove the entire firewall rule, just the time schedule.
Is there a different way to achieve this from the API?

Thanks

Rgs
Etienne

Reader + Processor threads

Hi,
first of all I want to thank you for this great api implementation, I really appreciate it.

I'm using your api for managing devices over small city network (about 1500 devices). For that purpouse, I wrote small java program, that provides batch changes. Problem I got is about closing/terminating your Reader and Processor threads. After running one of my jobs, which checks configuration of 739 devices, there are 216 threads alive just before program ends, which is problem, because my monitoring server runs out of resources. Here you can see screen captured from VisualVM on my development PC
image
For sending commands through your api, I am using following code
image

I am suspicious of that problem occures when there is some connection problem like ip unreachable, timeout or unable to login. Thats where some inner exception occures and after that, close method does not work properly and threads stuck on reading from empty stream.

Thanks in advance for your help.

MikrotikApiException Messages

Hi,

I am using this API well for a couple of month now and all is working great.

The only problem I have is when users fail to connect due to a bad user name or password, the MikrotikApiException message is always "cannot log in".

Is there a way to get more details such as bad password or invalid user?

Also, where can I find a list of messages for MikrotikApiException?

Thanks for your support.

Rgs
Etienne

Adding User and getting exception.

Hello I am using the following code to add user from java:
con.execute("/ip/hotspot/user/add name="+username+" password="+password);
And I am getting the following exception:
mikrotik.MikrotikApiException: unknown parameter at mikrotik.impl.ApiConnectionImpl$SyncListener.getResults(ApiConnectionImpl.java:511) at mikrotik.impl.ApiConnectionImpl$SyncListener.access$1(ApiConnectionImpl.java:500) at mikrotik.impl.ApiConnectionImpl.execute(ApiConnectionImpl.java:146) at mikrotik.impl.ApiConnectionImpl.execute(ApiConnectionImpl.java:113) at mikrotik.Disconnect.addUser(Disconnect.java:110) <-- This is the above line of code. .......
I have syntax error? Or I missing something else?

Thanks for your attention and time.

Error using not operator '!'

this is my command

List<Map<String, String>> pingCon = con.execute("/ip/firewall/mangle/print where protocol=!icmp and new-connection-mark=icmp-lokal-jinom");

and i get this error
Expected [TEXT] but found ! at position 43

/queue simple remove

How to execute command /queue/simple/remove [/queue/simple/find comment={comment}] with java API?
As a result of executing the command, I get an exception:

me.legrange.mikrotik.impl.ApiCommandException: unknown parameter
	at me.legrange.mikrotik.impl.ApiConnectionImpl$Processor.run(ApiConnectionImpl.java:263)

Encrypted connection

I use this API implementation in my android Mikrotik config tool. And it seems that Google restricted use of anonymous TLS in Android 6.
Is there any workaround for this? Or, Gideon, Do you have plans to implement encrypted connection with certificates?

Thanks.

exception while trying to connect using ssl

When I try to connect using ssl api I get the following exception?

Do you happen to know what's going on?

me.legrange.mikrotik.ApiConnectionException: java.lang.RuntimeException: Could not generate DH keypair
at me.legrange.mikrotik.impl.ApiConnectionImpl.execute(ApiConnectionImpl.java:131)
at me.legrange.mikrotik.impl.ApiConnectionImpl.execute(ApiConnectionImpl.java:118)
at me.legrange.mikrotik.impl.ApiConnectionImpl.execute(ApiConnectionImpl.java:94)
at me.legrange.mikrotik.impl.ApiConnectionImpl.login(ApiConnectionImpl.java:79)
at me.legrange.mikrotik.ApiConnectionTest.testConnectTLSStringInt(ApiConnectionTest.java:16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1842)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1825)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1751)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:113)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:69)
at java.io.FilterInputStream.read(FilterInputStream.java:83)
at me.legrange.mikrotik.impl.Util.readLen(Util.java:169)
at me.legrange.mikrotik.impl.Util.decode(Util.java:64)
at me.legrange.mikrotik.impl.Util.decode(Util.java:55)
at me.legrange.mikrotik.impl.ApiConnectionImpl$Reader.run(ApiConnectionImpl.java:244)
Caused by: java.lang.RuntimeException: Could not generate DH keypair
at sun.security.ssl.DHCrypt.(DHCrypt.java:136)
at sun.security.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:621)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:196)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:882)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
... 6 more
Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DHKeyPairGenerator.java:120)
at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:658)
at sun.security.ssl.DHCrypt.(DHCrypt.java:127)
... 14 more

UTF-8 Encoding Arabic Support

As i know The API sends and receives the raw bytes

But when i try to display the arabic words correctly, it displays like "๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ" which seems to be "ISO-8859-1" or maybe "windows-1252" i don't know.

Is there an option allows me to change the API Charset Encoding to UTF-8? like the Pear2/RouterOS PHP API? (see the link).

or maybe convert the (diamond question marks) to "UTF-8" in Java? if so, please post an example!

I really need to correctly display arabic words, thanks.

Problem 'where' with ' != not equal'

I'm trying to return all hotspot users that have uptime != "00:00:00"
So in mikrotik terminal im using this command with success:
/ip hotspot user print where uptime!="00:00:00"

But using the API and the command bellow it doesn't work.
/ip/hotspot/user/print where uptime!="00:00:00"

I Know i could do an IF expression to do the filter but it would be more cleaner.

Unknown Parameter for Adding User Hotspot Profile

I want to add User Hotspot Profile with some values:

  1. name
  2. address pool
  3. mac cookie timeout

Environment:

<dependency>
    <groupId>me.legrange</groupId>
    <artifactId>mikrotik</artifactId>
    <version>3.0.1</version>
</dependency>

Router OS 6.35.4

hAP lite RB941-2nD-TC

The code:

connection.execute(String.format("/ip/hotspot/user/profile/add name=%s add=%s", "userprofile", "rudipool"));

and I got error:

me.legrange.mikrotik.MikrotikApiException: unknown parameter
    at me.legrange.mikrotik.impl.ApiConnectionImpl$SyncListener.getResults(ApiConnectionImpl.java:471)
    at me.legrange.mikrotik.impl.ApiConnectionImpl$SyncListener.access$100(ApiConnectionImpl.java:425)
    at me.legrange.mikrotik.impl.ApiConnectionImpl.execute(ApiConnectionImpl.java:110)
    at me.legrange.mikrotik.impl.ApiConnectionImpl.execute(ApiConnectionImpl.java:68)
    at com.rudiwijaya.payment.dao.MikroTikManagerImpl.createHotspotUserProfile(MikroTikManagerImpl.java:92)
    at com.rudiwijaya.payment.dao.MikroTikManagerTest.addUserHotspotProfile(MikroTikManagerTest.java:55)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: me.legrange.mikrotik.impl.ApiCommandException: unknown parameter
    at me.legrange.mikrotik.impl.ApiConnectionImpl$Processor.run(ApiConnectionImpl.java:257)

But, I has code like:

connection.execute(String.format("/ip/hotspot/user/profile/add name=%s","userprofile"));

there was no error and it was created.

And in the terminal for script:

ip hotspot user profile add name=hsptest add=default mac="5d 00:00:00"

uses fields: name, add, and mac. It was success with specified 3 values..

The new stacktrace is quite annoying

Each time we close a connection we now get this stacktrace printed out due to interruptedException.

Please refer to this method of ApiConnectionImpl.Reader

@Override
        public void run() {
            while (connected) {
                try {
                    String s = Util.decode(in);
                    if (s != null) {
                        queue.put(s);
                    }
                } catch (ApiDataException ex) {
                    try {
                        queue.put(ex);
                    } catch (InterruptedException ex2) {
                    }
                } catch (ApiConnectionException | InterruptedException ex) {
                    ex.printStackTrace(); // HERE
                }
            }
        }

This was not present in 2.2. I don't really know what should be done to identify that it comes from a disconnect's interrupt. If you have any idea just let me know and I'll submit a PR

No support for /interface/monitor-traffic?

Hello! I am trying to implement a tool that reads the total traffic of a Bridge on a Mikrotik Device, however when i try to do the following
List<Map<String, String>> res = api.execute("/interface/monitor-traffic/wlan-bridge/once");
I get the following error:
me.legrange.mikrotik.MikrotikApiException: no such command prefix at me.legrange.mikrotik.impl.ApiConnectionImpl$SyncListener.getResults(ApiConnectionImpl.java:472) at me.legrange.mikrotik.impl.ApiConnectionImpl$SyncListener.access$100(ApiConnectionImpl.java:426) at me.legrange.mikrotik.impl.ApiConnectionImpl.execute(ApiConnectionImpl.java:110) at me.legrange.mikrotik.impl.ApiConnectionImpl.execute(ApiConnectionImpl.java:68) at at.klu.nos.mikrotik.CAPsMAN.pollUsage(CAPsMAN.java:222) at at.klu.nos.context.BackgroundContext.lambda$1(BackgroundContext.java:73) at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)

Grammar invalid

Im trying to use the following commands bellow but i'm getting a grammar error:
/ip/dhcp-server/lease/print where comment ~'#Router#'
/ip/dhcp-server/lease/print where comment ~'^#Router#'

(The first command lists registers that contains the string "#Router#" inside the comments and the second the registers that starts with this string.)

It works OK in winbox:
/ip dhcp-server lease print where comment ~"#Router#"
/ip dhcp-server lease print where comment ~"^#Router#"

Is it an API limitation or a bug???

Thanks.

Processor thread spins indefinitely if it receives unexpected data from router

If Processor.unpack() is called when line is set to an unexpected, non-null value, it will throw an ApiDataException. This is caught in Processor.run(), which causes the while loop to continue. The catch clause handles the case where the Processor thread is interrupted and connected has been set to false (see bug #13), but in this case, the cycle just repeats indefinitely.

I run into this issue when I execute a reboot command; line is set to an empty string on return from nextLine(). I'm not sure if there are other cases where unexpected values might be returned. In case it's relevant, I'm using an RB493AH with RouterOS 5.26.

Force close in android on connect

I'm trying to use mikrotik api Java in android, but when i downloaded it and added it in android studio project and used it the app forced to close!

imports in the begging of the MainActivity:
import me.legrange.mikrotik.MikrotikApiException; import me.legrange.mikrotik.ApiConnection; import me.legrange.mikrotik.ResultListener;
my java code to Connect:
ApiConnection con = ApiConnection.connect("10.0.1.1");
This is My Files: http://i.stack.imgur.com/3XYlk.png

thanks.

How to add and modify IP -> Pool

Hi..

How to add and modify IP Pool with values:

  1. name
  2. addresses

I have tried like this:

@Test
public void addIpPool() throws MikrotikApiException {
    final MikroTikIPPool upIpPool = new MikroTikIPPool();
    upIpPool.setAddresses("192.168.12.10-192.168.12.254");
    upIpPool.setName("ipp_ri1");

    final List<Map<String, String>> result = conn.
            execute(String.format("/ip/pool/add name=\"%s\" addresses=\"%s\"",
                    upIpPool.getName(), upIpPool.getAddresses()));
}

It is not works..

Unknown Parameter for command "/put message=[resolve www.facebook.com]"

Hi;

"/put message=[resolve www.facebook.com]"

While trying to run the above command, i keep getting the error me.legrange.mikrotik.MikrotikApiException: unknown parameter. Please is this a known behavior and is there a work around? Or is my command wrong??

This command works when tested through CMD

Connection by ssh

Dear Sir,

Can you give me a way to remote Mikrotik router by SSH ?

Thank you

Problem to remove active users command

I'm trying to remove active users from hotspot but its not working.
I've tried this commands:

(I need to remove all the active users from hotspot where the field user="teste")

This works on mikrotik:
/ip hotspot active remove [find user="teste"]

Using the API i've tried:
/ip/hotspot/active/remove [find user='teste']
/ip/hotspot/active/remove user='teste'
/ip/hotspot/active/remove [find user="teste"]
/ip/hotspot/active/remove user="teste"

There is a bug or limitation here or i'm doing something wrong here???

Thanks in advance.

Using API on google appengine server

Hi. While this issue might have been previously discussed and solved, i can't seem to find the issue in which it was discussed. Sorry if i am repeating. I'm connecting to a router os running in virtual machine on my pc from a locally deployed google appengine server. But i keep getting 'Connection Refused' error. Please what is the proper way of setting it up? Thank you.

Distribute JAR files

Maven is good and all...

But I know many Java users (myself included) that find it easier to include a JAR file in the library list of an IDE.

Those same users find it equally easy to include the source, but... That's messy IMHO. I for one hate doing that. Having JARs allows easier upgrades (which I realize is Maven's goal - to make upgrades painless), while still keeping things simple (or at least simpler than Maven), even if more error prone.

problems reading user profile in hotspot

hello I have problems reading user profile in hotspot
my code:

public ArrayList<Perfil> obtenerListaPerfiles() throws MikrotikApiException{
        String cmd= "/ip/hotspot/user/profile/getall";
        List<Map<String, String>> rs = con.execute(cmd);
        ArrayList<Perfil> perfiles= new ArrayList<Perfil>();
        for (Map<String,String> r : rs) {
             perfiles.add(
                 new Perfil(
                     "",
                     r.get("name"),
                     r.get("session-timeout"),
                     r.get("rate-limit")
                 )
             );
        }
        System.out.println(cmd);
        return perfiles;
    }

the problem occurs when I put a script in some user profile

profile

  • When off the script code works.

ResultListener not receives .dead replies if where statement used

If I send "/interface/pppoe-server/server/listen return .id,.dead,disabled,service-name,interface,max-mtu,max-mru,mrru,default-profile,authentication" to the Router and set ResultListener to this query then I will receive all listen data (changed comments, new items, .dead items etc).

But if I send "/interface/listen where type=l2tp-in or type=l2tp-out or type=ovpn-in or type=ovpn-out or type=ppp-in or type=ppp-out or type=pppoe-in or type=pppoe-out or type=pptp-in or type=pptp-out or type=sstp-in or type=sstp-out return .id,.dead,.nextid,disabled,dynamic,running,slave,name,type,comment" and set ResultListener then .dead replies is not receiving at all. All other listen replies are okay in this situation.

Sorry for my english.

Unknown parametr response

This code always produce an exception

api = ApiConnection.connectTLS(host)
api.login(USERNAME, pass)
api.execute("/delay 200ms")
api.disconnect()

Caused by: me.legrange.mikrotik.impl.ApiCommandException: unknown parameter
at me.legrange.mikrotik.impl.ApiConnectionImpl$Processor.run(ApiConnectionImpl.java:299) ~[mikrotik-2.0.2.jar:na]

Did I do something wrong?

Problem when interface name has "_" into it

When I try to run this command for exemple:

/ip/firewall/filter/add action=drop chain=forward in-interface=aps_hs protocol=udp src-port=67,68

the API just freeze and nothing happens. When I changed the interface name to something like aps-hs, the API run fine.

Single quotes in command line cause 'freeze'

Having a command line with single quotes in causes the API to 'freeze' or go into a tight loop. The following is enough to break it:

/interface/gre/add remote-address=1.2.3.4 name='foo' keepalive=10

/file/print command timeout

When i try to run the command "/file/print" the connection returns nothing until timeout. I increased the timeout but still the same. Please is there anyway around this? Thanks

Question about specific query

Hi,

I'm trying to make a specific query to the router, and it seems that the parser doesn't supports or I'm doing something wrong. Here's an example:

ip dhcp-server lease print where dynamic=no and active-address in 192.168.88.0/24

This works from the terminal or in a ssh session. The invalid bit seems to be and active-address in 192.168.88.0/24.
Is there a way to do this? I skimmed through the API documentation but I still can't figure out. Thanks in advance!

Unknown parameter on regular expression

hey Gideon
Trying to add a layer7 protocol but the regular expression throws unknown parameter error...

<<>>>
List<Map<String, String>> e = con.execute("/ip/firewall/layer7-protocol/add regexp="+reg+"");
reg="^(\x13bittorrent protocol|azver\x01$|get /scrape\?info_hash=get /announce\?info_hash=|get /client/bitcomet/|GET data\?fid=)|d1:ad2:id20:|\x08'7P\)[RP]"

Android Application has stopped

Developing an android application testing the connection to the RouterOS using this API

Added the Maven compile code to the build.gradle in my android app :

compile 'me.legrange:mikrotik:2.2'

Imported the Class of the API :

import me.legrange.mikrotik.ApiConnection;
import me.legrange.mikrotik.MikrotikApiException;

And here's my code in the MainActivity :

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
            ApiConnection.connect("192.168.1.2");
        } catch (MikrotikApiException e) {
            e.printStackTrace();
        }
    }
}
As we see it's very simple, nothing complicated just trying to connect

The problem is when i test the app it's crashing and saying

Unfortunetly App has stopped

Note : i'm testing the App live on my smartphone not in the Android studio AVD machine
Note : I'm asking for internet access permession in the installation process

I assume i'm using the API the right way, so how to fix this problem?

Error with where and operator <

List<Map<String,String>> rs = router.execute("/ipv6 / dhcp-server / binding / print detail where prefix-pool=PoolPD last-seen<6m");

me.legrange.mikrotik.impl.ParseException: Expected [EOL] but found TEXT at position 80
at me.legrange.mikrotik.impl.Parser.expect(Parser.java:183)
at me.legrange.mikrotik.impl.Parser.parse(Parser.java:32)
at me.legrange.mikrotik.impl.Parser.parse(Parser.java:17)
at me.legrange.mikrotik.impl.ApiConnectionImpl.execute(ApiConnectionImpl.java:68)

The functionality for operator use has not yet been implemented in the API or is a command writing error.
If it is a writing error how should I do it?

ApiConnectionImpl.disconnect() does not stop Processor thread

ApiConnectionImpl.connect() starts two threads: a Reader and a Processor. ApiConnectionImpl.disconnect() causes the Reader thread to exit, but the Processor stays alive.

It looks like ApiConnectionImpl.disconnect() calls reader.interrupt(), which causes the Reader thread to stop. However, if the Processor thread is blocked on a reader.take() call in its unpack() method, its thread will continue to wait forever. A quick test shows that adding a processor.interrupt() in the disconnect() method fixes it, though I'm not sure if this has any unintended side-effects.

Problem with " " (white space) for adding user hotspot

Relates to #3

Environment:

<dependency>
    <groupId>me.legrange</groupId>
    <artifactId>mikrotik</artifactId>
    <version>3.0.1</version>
</dependency>

Router OS 6.35.4

hAP lite RB941-2nD-TC

The code WITH With Space:

connection.execute(String.format("/ip/hotspot/user/add name=%s password=%s profile=%s", "rudi wijaya", "rudi wijaya", "default"));

and I got error:

me.legrange.mikrotik.MikrotikApiException: unknown parameter
    at me.legrange.mikrotik.impl.ApiConnectionImpl$SyncListener.getResults(ApiConnectionImpl.java:471)
    at me.legrange.mikrotik.impl.ApiConnectionImpl$SyncListener.access$100(ApiConnectionImpl.java:425)
    at me.legrange.mikrotik.impl.ApiConnectionImpl.execute(ApiConnectionImpl.java:110)
    at me.legrange.mikrotik.impl.ApiConnectionImpl.execute(ApiConnectionImpl.java:68)
    at com.rudiwijaya.payment.dao.MikroTikManagerImpl.createUserHotspot(MikroTikManagerImpl.java:78)
    at com.rudiwijaya.payment.dao.MikroTikManagerTest.addUserHotspot(MikroTikManagerTest.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: me.legrange.mikrotik.impl.ApiCommandException: unknown parameter
    at me.legrange.mikrotik.impl.ApiConnectionImpl$Processor.run(ApiConnectionImpl.java:257)

If mycode (with NO White Space):

connection.execute(String.format("/ip/hotspot/user/add name=%s password=%s profile=%s","rudiwijaya", "rudiwijaya", "default"));

There was no problem..

Unknown Parameter when using find into brackets

Hi.
I am having problems when i use the brackets as parameter for remove and editing users of user-manager in ROS.

Versions: ROS 6.38.1 x86, mikrotik-java 3.0.3 jar file, Oracle JDK 8u101

I made some tests with commands below:
conn.execute("/tool/user-manager/user disable [/tool/user-manager/user/find username=ggg]");
conn.execute("/tool/user-manager/user disable [/tool user-manager user find username=ggg]");
conn.execute("/tool/user-manager/user disable [/tool/user-manager/user/find/username=ggg]");

Returns: me.legrange.mikrotik.MikrotikApiException: unknown parameter
Executing into SSH or cli in the ROS was not found problems and works fine (/tool user-manager user disable [/tool user-manager user find username=ggg]).

I ask, has a correct syntax to use brackets with this API? Or simply not works due limitations? Or should i use SSH for this?

Thanks for the helping!

how to change frequency over API?

Hi,

I can run following code on terminal successfully,

/interface wireless set wlan1 frequency=2412

but when I try to run over API, with the following code:
ApiConnection con = ApiConnection.connect("192.168.88.1"); // connect to router
con.login("admin",""); // log in to router
con.execute("/interface wireless set wlan1 frequency=2457"); // execute a command
con.close(); // disconnect from router
it gives me the following error:
me.legrange.mikrotik.impl.ParseException: Expected [TEXT] but found EOL at position 27

How can change frequency via API?

Cheers,

Can't exec cmd1 [cmd2] and cmd param(no name)

Can't exec cmd1 [cmd2] and cmd param(no name)
like:
/ip/hotspot/active/remove [/ip/hotspot/active/print where mac-address="00:xx:CC:xx:xx:xx"]

and
/ip/hotspot/active/remove 0
/ip/hotspot/active/remove *F90410AC
*F90410AC is exec /ip/hotspot/active/print where mac-address="00:xx:CC:xx:xx:xx" command's .id

helpplease

unknown paramater when adding variable into command

Hi,
i'm having problem when adding variable into command.
this is command that i've trouble with:
con.execute("/interface/ppp-client/add add-default-route=no apn="+interface_Apn1+" dial-on-demand=no use-peer-dns=no disabled=no add-default-route=no keepalive-timeout=0 name="+interface_PPP_Out1+" data-channel="+interface_dChannel1+" info-channel="+interface_iChannel1+" phone="+interface_dNumber1+" port=usb1");

i've added "+" (plus) sign between variable, but i keep getting this error me.legrange.mikrotik.MikrotikApiException: unknown parameter.

Thanks for helping.

use netty by this code

hallo , what need i nodify in this code for netty use
and can I use this code in eclipse

SSL connection is slow

Hi Gideon,
I have moved my app to using tls using a 4096 key generated using openssl on my linux machine. however the app has become considerably slower more than 6-8 seconds slower ...
any suggestions ..i thought of expected since there is more overhead.
Also this might be my code thats misbehaving but i get random command timeouts, i am using one instance of the ssl connection to do short commands using async task and runnables/threads.
I make a ssl connection once on app lunch then keep using Config.con to execute queries.

    private SocketFactory ssl;
    public static ApiConnection con;
    public Config(Context mcontext){
        this.mcontext=mcontext;
        try {
            ssl = ssl();
            con = connect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected SocketFactory ssl() throws Exception{
        // Load CAs from an InputStream
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        //local cert
        InputStream caInput = new BufferedInputStream(mcontext.getAssets().open("router.crt"));
        Certificate ca1;
        try {
            ca1 = cf.generateCertificate(caInput);
        } finally {
            caInput.close();
        }

        // Create a KeyStore containing our trusted CAs
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca1", ca1);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        // Create an SSLContext that uses our TrustManager
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);


        return new TLSFact(context);
    }

    protected  ApiConnection connect() throws Exception {
        ApiConnection con = ApiConnection.connect(ssl, HOST, ApiConnection.DEFAULT_TLS_PORT, ApiConnection.DEFAULT_CONNECTION_TIMEOUT);
        con.login(USERNAME, PASSWORD);
        return con;
    }

Problem when using NOT operator "!"

I dont know if is a problem or if I using it wrong:

/ip/firewall/filter/add chain=forward hotspot=!auth protocol=tcp src-port=8000-8084

But when I try to use the operator NOT "!" API freezes.

Error when parameter has space in it

Hi Gideon,

When i run command "/interface/bridge/port/print where interface=Public Area", I receive the error "me.legrange.mikrotik.impl.ParseException: Expected [EOL] but found TEXT at position 56" which falls at the space position. I read through issue #3 which seems to report the exact same problem but no solution there that i can understand.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.