api_handler¶
-
struct
mikrotik::api::api_handler¶ Handles all interaction with the MikroTik API.
The class which is used to connect to, log into, then send to and receive sentences from the MikroTik device of your dreams, or at least the one on your shelf.
Its lifetime is equivalent to the lifetime of the connection, it this dies, the connection is killed with it.
The constructor takes the IP address of the device, only IPv4 at the moment, the user to log in as, and the password to do so. If any of them is incorrect an exception will be thrown: If the IP is ill-formed, then during creation, otherwise when trying to use the incorrect data to connect: in this case a timeout is likely to occur, which will result in an exception, but will also halt the program for some time, before the resident socket library realizes data’s incorrect.
The public API allows sending and receiving sentences. A sentence according to the MikroTik API docs, is a list of words, where a word is just a string. A sentence contains a command and some additional words. For a more comprehensive documentation see the sentence docs.
If you want to explicitly disconnect, use the disconnect() member function. This does all the things the destructor would do without requiring fancy tricks with scopes to get the lifetime just right.
Example usage:
This program simply restarts the MikroTik device, provided the credentials are correct. Then it proceeds to ignore the response. Don’t do that, be nice and tell your users that things didn’t go the way you wanted it to.#include <mikrotik/api/api_handler.hpp> #include <mikrotik/api/command.hpp> namespace mt = mikrotik::api; using namespace mt::literals; int main() { mt::api_handler api("192.168.1.1"); // user = "admin" // passwd = "" api.send("system"_cmd / "restart"); api.read(); }
Note
If the code is compiled for Windows, it’ll use WinSock2 as the resident socket library. This, contrary to POSIX socket implementations, requires an initializer and finisher function call (
WSAStartupandWSACleanup). If the executable relying on this library also wishes to deal with WinSock2, they should callWSAStartupbefore instantiating an object from this class and callWSACleanupafter the object has been destructed. While this may not be necessary, behavior may be surprising when the call toWSACleanupdoes nothing and the executable’s sockets only get cleaned when this object gets destructed.Warning
Currently, SSL is not supported, it’s in the works, but don’t use this to connect through public networks yet.
- Since
v1.0.0
Public Functions
-
void
send(const sentence &snt)¶ Sends a sentence through the open connection.
Takes a sentence and sends it through the open socket to the MikroTik device. The sentence does not need to be terminated with the empty word, the function will always send it after sending the contents of the sentence.
Warning
This function does not deal with the reply just sends the sentence and it’s done with it. To ensure no reply data gets lost, or dislocated from its sent sentence, always make sure to call read after using this function to get the device’s reply.
- Since
v1.0.0
- Parameters
snt: The sentence to send
-
mikrotik::api::reply
read()¶ Reads the reply sentence from the connection.
Reads a reply sentence from the open connection. This contains the response type, and an optional list of response contents stored as strings.
For example let’s see the following exchange:
The lines beginning with>>> /user/print >>> <<< !re <<< =.id=*1 <<< =name=admin <<< =group=full <<< =address= <<< =last-logged-in=jun/29/2020 23:22:47 <<< =disabled=false <<< =comment=system default user <<< !done
>>>are the words of the sent sentence, while lines with a leading<<<are the words of the reply sentence.There are two reply sentences here. A reply sentence will contain the response type and a vector of strings. The vector will contain the meaningful content of the
!rereply sentence. ({"=.id=*1", "=name=admin", etc...})More about what is a sentence, a reply sentence, and their differences in their appropriate documentation.
- Return
The reply from the MikroTik device
- Since
v1.0.0
-
int
disconnect() noexcept¶ Disconnects from the MikroTik device.
Implements the disconnection procedure to end the communication with the MikroTik device. The destructor relies on this function to call the appropriate syscalls to kill the connection.
On POSIX socket implementations, this closes the socket.
On WinSock2, this closes the socket and calls the cleanup function
WSACleanup.- Return
The return value from the function that closes the socket. (
closeorclosesocket).- Since
v1.0.0
-
api_handler(ip_address address = "192.168.88.1", std::string_view user = "admin", std::string_view pass = "")¶ Connects to and logs into the MikroTik device at the specified address.
Establishes a socket connection with the device, then sends the provided user credentials. If the IP address is invalid, the program will halt until the resident socket implementation decides to give up with a timeout error, then throws. If the credentials are incorrect the function throws.
- Since
v1.0.0
- Exceptions
bad_ip_format: If the provided IP address does not follow the x.x.x.x format. IPv6 is currently not supported.bad_socket: If an error arises from the resident socket implementation: cannot create socket, cannot connect, or cannot send/read data.
- Parameters
address: The IPv4 address of the MikroTik device to connect to.user: The username to log in aspass: The password of the provided user
-
~api_handler() noexcept¶ Destructor that terminates connection.
When the object is destroyed, the connection to the MikroTik device is terminated, which in turn causes the user to log out as well.
Warning
To make the destructor not throw, since that can case interesting problems, the disconnect() member function which implements the termination of the connection does not throw. If you think there is a chance of the connection not getting terminated properly, and there is something you can do about that, call the disconnect() member function directly, which returns the return value of the call that closed the socket. Otherwise, any errors are silently discarded by the destructor.
- Since
v1.0.0