NAME

librouteros - Library for accessing MikroTik's RouterOS via its API


DESCRIPTION

librouteros is a library to communicate with RouterOS, the operating system of MikroTik's RouterBoards. It uses the ``API port'' provided by those systems to connect and talk to the devices. librouteros is a low-level library in that it abstracts the network protocol used but has next to no knowledge about the commands and responses available. Should such an high-level interface prove useful, it will be added as the need arises.


GENERAL USAGE

The interface of librouteros is designed to be lightweight and simple to use. The first thing when using the library is to create a connection object. Once a connection has been established and logging in succeeded, queries can be sent to the remote device. The library will encode and send the request, read back a reply, decode it and pass it to a callback function. The callback function has access to the parsed reply and can easily access all parts and parameters. It does not need to worry about memory management because everything provided to it will be freed by the library before returning to where the query was called from. When the application is done talking to the device and disconnects, the connection object will be freed.


INTERFACES

Connection

The connection to a RouterOS device is represented by a pointer to a ros_connection_t type. This is an opaque data type which cannot be dereferenced or manipulated directly.

Connection management is done with the following functions:

ros_connection_t *ros_connect (const char *node, const char *service, const char *username, const char *password)

Connects to the remote device using node as the address or hostname. If service is NULL, the standard port 8728 will be used. When a connection has been established, the library will try to authenticate using username and password.

On failure, NULL is returned and errno is set appropriately.

int ros_disconnect (ros_connection_t *c)

Disconnects from the device and frees all memory associated with the connection. After this call, c may not be used anymore.

Returns zero upon success and an error code otherwise.

General / low level queries

This interface abstracts the network protocol only and leaves actually formulating queries and interpreting replies to the calling code. This is meant for queries and features for which no higher level interface exists.

The query is sent to the daemon using the ros_query function. The reply is decoded and passed to a callback function with the following prototype, also called ros_reply_handler_t:

  int callback (ros_connection_t *c, const ros_reply_t *r, void *user_data);

The reply is broken into parts (or ``sentences'') and passed to the callback function as a linked list of type ros_reply_t. It is only called once for query and must traverse the linked list itself. The callback uses a couple of helper functions to iterate over this list and fetch parameters as necessary.

The first and second arguments are objects representing the connection and the reply respectively. user_data is a pointer as passed to ros_query (see below). The arguments c and r may not be modified or freed. They will be freed after the function returns, so pointers to this data are invalid after this.

The value returned by the callback function will be returned by ros_query to the calling code. To distinguish from error codes returned by ros_query upon errors, use negative values in the callback function.

Because the entire reply is read back from the connection before the callback function is called, it is legal for the callback function to send out another query.

General queries / replies are handled using the following functions:

int ros_query (ros_connection_t *c, const char *command, size_t args_num, const char * const *args, ros_reply_handler_t handler, void *user_data)

Sends the command command with the args_num arguments args via the connection c and reads back the reply. The reply is parsed and passed to the callback function handler. user_data is a pointer passed through to the callback function. Please note that the callback function is called only once, even if the reply consists of multiple parts. Use the ros_reply_next function (see below) to access the other parts.

Returns the value returned by the callback function upon success and an error code otherwise.

const ros_reply_t *ros_reply_next (const ros_reply_t *r)

Each reply can consist of several parts or ``sentences''. If there is more than one sentence returned by the device, this function will return the next part. When the end of the list is reached, NULL is returned.

int ros_reply_num (const ros_reply_t *r)

Returns the number of replies in the list pointed to by and including r.

const char *ros_reply_status (const ros_reply_t *r)

Returns the status message of this part or reply. This is usually ``re'' for data parts, ``done'' for the last part in a reply and ``trap'' for errors. The returned pointer must not be freed.

const char *ros_reply_param_key_by_index (const ros_reply_t *r, unsigned int index)

Returns the parameter key at index index (starting with zero) of reply r. If index is out of bounds, returns NULL. The returned pointer must not be freed.

const char *ros_reply_param_val_by_index (const ros_reply_t *r, unsigned int index)

Returns the parameter value at index index (starting with zero) of reply r. If index is out of bounds, returns NULL. The returned pointer must not be freed.

const char *ros_reply_param_val_by_key (const ros_reply_t *r, const char *key)

Returns the parameter value corresponding to key key (or NULL if there is no such key) of reply r. The returned pointer must not be freed.

High level interface functions for ``interface''

This function and the associated struct provide basic information about the device's interfaces in an easy and intuitive to use form. It is equivalent to issuing the /interface/print command. As with the generic interface above, a query function is called with a pointer to a callback function. That callback function is then called with a list of ros_interface_t structures.

The query function has the following prototype:

 int ros_interface (ros_connection_t *c,
     ros_interface_handler_t handler, void *user_data);

c is a pointer to a connection object as returned by ros_connect.

handler is a function pointer to a callback function handling the result. The callback function must have the following prototype, called ros_interface_handler_t for convenience:

 int callback (ros_connection_t *c,
     const ros_interface_t *i, void *user_data);

The argument i is a pointer to the first element of the list of interfaces received from the device. This struct is defined in <routeros_api.h> and contains information such as the name of the device, received and transmitted bytes and whether or not the interface is currently running. No element of the list nor any of their members may be modified and will be freed when the callback returns.

High level interface functions for ``registration-table''

This high level interface makes it easy to access the ``registration table'', which holds active wireless lan connections. The data returned is equivalent to running /interface/wireless/registration-table/print. The parsed data is passed to a callback function in form of a ros_registration_table_t structure.

The query function has the following prototype:

 int ros_registration_table (ros_connection_t *c,
     ros_registration_table_handler_t handler, void *user_data);

c is the usual connection ocject. handler is a pointer to a function with the following prototype:

 int callback (ros_connection_t *c,
     const ros_registration_table_t *r, void *user_data);

The usual semantics apply: You may not alter r and the memory pointed to by r is freed after the callback returned.

High level interface functions for ``system resource''

This high level interface makes it easy to access several system related metrics, such as memory and disk space used. The data returned is equivalent to running /system/resource/print. The parsed data is passed to a callback function in form of a ros_system_resource_t structure.

The query function has the following prototype:

 int ros_system_resource (ros_connection_t *c,
     ros_system_resource_handler_t handler, void *user_data);

c is the usual connection ocject. handler is a pointer to a function with the following prototype:

 int callback (ros_connection_t *c,
     const ros_system_resource_t *r, void *user_data);

The usual semantics apply: You may not alter r and the memory pointed to by r is freed after the callback returned.

Versioning

The routeros library contains version information that can be used at compile time as well as at runtime.

At compile time, the version is available in form of two preprocessor defines, ROS_VERSION and ROS_VERSION_STRING. ROS_VERSION is a numeric value where the major version is multiplied by 10000 and the minor version is multiplied by 100. Version 1.2.3 would therefore be returned as 10203. ROS_VERSION_STRING is defined to be a string, for example ``1.2.3'' and can be used for printing a pretty version information.

The same information is available at run time using two functions which return the information. The function ros_version returns the numeric value of ROS_VERSION and ros_version_string returns the value of ROS_VERSION_STRING, making it possible to check the version of the actually used library.


ERROR HANDLING

Some of the functions above return an ``error code''. This error code can be transferred to a string describing the error using strerror(3) or strerror_r(3). Since the error codes are all positive integers, it is recommended to use negative return values in the callback functions to indicate custom errors if appropriate.


THREAD SAFETY

librouteros uses only thread-safe functions and does not store any global data itself. It is therefore fully thread and reentrant safe as long as you don't call any functions with the same connection object.


LICENSE

librouteros is licensed under the GPLv2. No other version of the license is applicable.


AUTHOR

librouteros is written by Florian octo Forster <octo at verplant.org>. Its homepage can be found at http://verplant.org/librouteros/.

(c) 2009 by Florian octo Forster.