API multiplatform from townet

From MikroTik Wiki
Jump to: navigation, search

MKAPI: LIBRARY TO CONTROL MIKROTIK BOARDS

This article refers to the library developed by townet to control a mikrotik boad using the api, and to the example applications developed using the same library. The library is written in C++, and works under Linux and under Windows.

You can download the lybrary and the SKD, that contains also the manual at the address: www.wispmax.com/media/CPE_SDK.zip

The port used for the mikrotik API is the 8723. On the CPE machine te API needs to be enabled.

  1. define API_PORT 8728

This are some functions usable to read the parameters received in a message froma mikrotik board.

AnsiString parse_par(AnsiString stream, char* par, char* dest); AnsiString parse_line(char* reply);

class mikrotikBoard { public:

The one under is the login function, to start the connection. To do the login you needs to give the IP address, the username and the password. You will receive back an empty string it the login is correct, or a string that describe the error that caused the wrong login.

 AnsiString login(AnsiString remote, AnsiString user, AnsiString pass);

The “command” function is used to handle a transactional command. This function needs to have the command as a parameter, and gives back the reply received from the mikrotik board. If a “trap” is received, this mean that an error occoured, and a messageBox is shown to the user.

AnsiString command(AnsiString text);

The “xcommand” function allows, like the one before, to execute a transactional command, with the difference that in case of a trap no messagebox giving back the error is generated. The task of handling the error remain to te application’s programmer. The “xcommand” way is more flexible, and useful in case of a command that, may be, was allread given to the board.

 AnsiString xcommand(AnsiString text);

To handle interactive commands, like for example ‘scan’:

 void start_icommand(AnsiString cmd);   //Starts an interactive command
 AnsiString icommand();         //Reads part of the reply to the interactive command
 AnsiString end_icommand();    //This is called to close the icommand

};


USE OF MKAPI LIBRARY

To write a C program using MkApi you need to include the library when you compile your application, and yu need to add the source file “MkApi.h” to ypur C sources.

You need to istantiate an object of the class “mikrotikboard”:

 mikrotikboard mk; 

Then you need to ask for a login:

 AnsiString res = mk.login("192.168.1.1", "admin", "secret"); 

If there is an error you can signal it, and for example stop the application:

 if (res !=0) 
 { Application->MessageBox(res.c_str(), "Errore", MB_OK); 
   Application->Terminate(); 
 };

Now it’s possible to execute commands:

 AnsiString adrs = mk.command("/ip/address/print"); 
 Application->MessageBox(adrs.c_str(), "Assigned addresses", MB_OK); 

If you don’t want to receive a popup window in case of error you can use xcommand:

 AnsiString adrs = mk.xcommand("/ip/address/print"); 
 if (adrs.Pos("!trap") >0) { HANDLE THE ERROR };
 Application->MessageBox(adrs.c_str(), "Assigned addresses", MB_OK); 

You can handle interactive commands in this way:

 start_icommand("/interface/wireless/scan"); 
 int k; 
 for (k=0; k<10; k++) 
 { AnsiString obj = icommand(); 
   printf("NEIGHBORS: %s\n", obj.c_str()); 
 };
 end_icommand();   

A routine that execute a command gives back a string containing the reply of the mikrotik board. This string is non modified because the format is not standard, and can be slightly different from a command to another one. So we write two functions: parse_par and parse_line, that can be used to read the parameters returned from a mikrotik board without errors. Here wodn there is an example of code usable to read and write on the computer screen the ip addresses assigned to a mikrotik board.

 mikrotikboard mk; 
 AnsiString res=mk.login("192.168.1.1", "admin", "print"); 
 if (res="") 
 { AnsiString indirizzi =mk.command("/ip/address/print"); 
   //This copy the ansistring on a buffer of chars. 
   char c[10000]; strcpy(c, indirizzi.c_str()); 
   while (c[0]!=0) 
   { AnsiString line = parse_line(&c); 
     //Here the variable line contains only a line from the reply.
     char adr[30]; 
     char interf[20]; 
     parse_par(line, "address=", adr); 
     parse_par(line, "interface=", interf); 
     printf("Interface %s \taddress %s\n", interf, adr); 
   };
 };  

More easily the function parse_par can be used to read the first occourrence of a parameter and to cut the original string, so you can gradually read all the results, in this way:

 mikrotikboard mk; 
 AnsiString res=mk.login("192.168.1.1", "admin", "print"); 
 if (res="") 
 { AnsiString indirizzi =mk.command("/ip/address/print"); 

       //This copy the string on a buffer of chars
   char c[10000]; strcpy(c, indirizzi.c_str()); 
   while (indirizzi !="") 
   { char adr[30]; 
     char interf[20]; 
     line = parse_par(line, "address=", adr); 
     line=parse_par(line, "interface=", interf); 
     printf("Interfaccia %s \tindirizzo %s\n", interf, adr); 
   };
 };
 

Reading the reply you have to be careful for a thing: if the “interface” information is given in the reply before the “address”, the results can be printed in a wrong position.

The MkApi library define many other functions, but this are aminly low-level ones, and are used to build the ones we descrived before. So we decided not to give documentation about it. If you select to use the “DLL” version of the MkApi library you can write a similar program using any language, like for example basic or c#, without an excessive loose of speed. The same library work also under linux, and can be linked as an object file os as a .so dynamic linked library.


COMMAND LINE UTILITY TO HANDLE MIKROTIK BOARDS

Mik utility is a ms-dos and linux command line application that allows to execute commands on a mikrotik board in a “batch” way. It’s possible to use it from the command line or using scripts written in many languages. Pratically all the programming languages have a shell construct (in basic for example the construct is “system”). SO it’ s possible to execute an external application and then resume the normal execution of a program. So this utility can be used to have a program written in any language that talks with routeros.

Launching the utility mik you will ever have two replies: a first line containing a number followed from the text Err or Ok , and he following lines containing a detailed reply.

If the details of the reply are not importants for the calling application, for example if mik is givin back his internal short manual, this details are not returned on the standard output but on the standard error.

./mik -1 Err Parametri errati

MKDeal - tool di interfaccia mikrotik uso: MKDeal ip utente password -c comando (per comandi one-shot) MKDeal ip utente password -i comando (per gestire comandi interattivi) MKDeal -f nomefile -c comando (per gestire comandi su piu' board)

      Il file deve avere come formato IP#USER#PASS su ogni riga

risposte: NUM Err oppure NUM Ok seguito dai dati -1 : parametri errati -2 connessione fallita -3 trap generica -4 password errata -5 trap su comando 0 corretto

Some example:

./mik 192.168.1.1 admin rtmtc -c /ip/address/print -2 Err L'indirizzo indicato non risponde

In the upper example the boars is not properly connected to the network or the API is disabled.

$ ./mik 192.168.1.39 admin "" -c /ip/adress/print -5 Err !trap =category=0 =message=no such command or directory (adress)

<STR>!trap =message=no such command prefix

<STR>!done <STR>

In the upper example we have a trap: the command i used is not existing (i wrote address with a single d).

$ ./mik 192.168.1.39 admin "" -c /ip/address/print [*** Errore ***] [This board is not enabled for API Townet]

This is what happens when the board is connected to the network, but the code to enable it for using the API townet is not installed. The MkApi library is in fact working only on townet/wispmax machines. Forother machine it’s possible to ask an activation code to townet giving us the serial number and license-id of the board, and the model. There isn’t an error code because the API didn’t return a result, non allowing the access.

$ ./mik 192.168.1.39 admin "" -c /ip/address/print 0 Ok !re =.id=*3 =comment=aaa =address=10.10.10.1/24 =network=10.10.10.0 =broadcast=10.10.10.255 =interface=ether1

<STR>!re =.id=*4 =comment=bbb =address=192.168.1.39/24 =network=192.168.1.0 =broadcast=192.168.1.255 =interface=ether1

<STR>!done

<STR>

Here is a correct example, and we can see the reply to the command. In this example we have two replies, and there is a tag “<STR>” that is used to show where is the end of a line. Each <STR> close a single reply. The command ever ends with a <STR> describing an empty reply.

$ ./mik 192.168.1.39 admin "" -c /ip/dns/set#=primary-dns=99.99.99.99 0 Ok !done

<STR>

$ ./mik 192.168.1.39 admin "" -c /ip/dns/print 0 Ok !re =primary-dns=99.99.99.99 =secondary-dns=62.94.0.2 =allow-remote-requests=false =max-udp-packet-size=512 =cache-size=2048 =cache-max-ttl=1w00:00:00 =cache-used=5

<STR>!done

<STR>

Now i used a command that has some parameter. For example i’m changing the primary-dns of the board, and then i print the new DNS configuration. The first command is a multirow. To write it on a single row under ms.dos we need to user the # character to signal the end of the line. Under linux, it’s a good thing to use the quotation marks around the last parameter.

The “mik” utility is written as a demo for the library MkApi.

An important note: The specification of the API mikrotik defines the command in a format that is slightly different than the ones used from the telnet interface. The ID of the network addresses, and in general of the objects given back from a command, are ever integer numbers, but this ones doesn’t start from the number zero, like working in telnet. To set the address of an ethernet port, for example, you may need to execute a print command to read all the id’s, and then to execute the “set” command passing the id of the line you really want to change. All the commands needs to be launched from the root of the command’s tree, so “/ip/address/print” is a valid command, while the two commands “/ip/address” and “print” can’t be separated. To separater the parts of the commands tou needs to use a slash “/” instead of the space, used in the telnet interface.

To see if there are other differences you can read the documentation of mikrotik api interface at the following address:

[[1]]


DLL MKAPI, TO CONTROL MIKROTIK BOARDS

The mikapi.dll is a dynamic loadable library based on mikrotik api, and allows to connect to a mikrotik board from pratically all the languages under windows. Due to the fact that MkApi is based on the mikrotikboard class and that a DLL is a set of functions and not a set of classes, the DLL hide the MikApi object and shows a list of functions to login, to execute commands and then to logout. The DLL library has the following interface:

AnsiString mk_parse_par(AnsiString stream, char* par, char* dest); AnsiString mk_parse_line(char* reply); AnsiString mk_login(AnsiString remote, AnsiString user, AnsiString pass); AnsiString mk_command(AnsiString text); AnsiString mk_xcommand(AnsiString text); void mk_start_icommand(AnsiString cmd); AnsiString mk_icommand(); AnsiString mk_end_icommand(); void mk_close();

This functions works exactly like the same functions of the original MkApi library. To connect to more than one board it’s possible to close the current connection with the instruction mk_close, and then to open a new one. This function is not necessary when the class MkApi is used directly because the mk_close is directly called when the object is deallocated.

See also