C# API - tik4net on GitHub

tik4net 4.x is out — a big release for my API client for .NET. It still does what it always did: execution of parallel queries, easily handled thanks to an ADO.NET-like interface + O/R mapper-like extensions for a strong-typed experience (both single entity and lists of entities). What's new in 4.x is that it no longer talks only the native API — there are many new connection types (see below), all behind the same interface.

Please leave a message in this thread if you need some feature to be implemented or if you have any relevant question.

Repository: GitHub - danikf/tik4net: Manage mikrotik routers with .NET C# code via ADO.NET like API or enjoy O/R mapper like highlevel api. · GitHub
Wiki: Home · danikf/tik4net Wiki · GitHub
Getting started: Getting started · danikf/tik4net Wiki · GitHub
How to use: How to use tik4net library · danikf/tik4net Wiki · GitHub
Connection types & capabilities: Connection types and capabilities · danikf/tik4net Wiki · GitHub
Releases / version history: History · danikf/tik4net Wiki · GitHub
nuget package (recommended): https://www.nuget.org/packages/tik4net.entities/

Tested and debugged against RouterOS 7.21.4 (latest stable). Dlls target netstandard2.0, so tik4net runs on .NET Framework 4.6.1+, .NET Core 2.0+, .NET 5/6/7/8/9, Xamarin/Mono and Unity. Reference downloaded dlls only if you are not able to use the nuget package or the GitHub sources.

New in 4.x — many new connection types

All transports implement the same ITikConnection interface and the same O/R mapper (LoadAll<T>(), Save<T>(), …). You pick one via TikConnectionType and the rest of your code stays identical:

  • Api / ApiSsl — native MikroTik API (TCP 8728 / TLS 8729); the default, fastest transport, full Listen/streaming
  • Rest / RestSsl — REST API over HTTP/HTTPS (RouterOS 7.1+)
  • Ssh — RouterOS CLI over an SSH shell (TCP 22); full CRUD + Listen + Safe Mode (satellite package tik4net.ssh)
  • Telnet — RouterOS CLI over plain-text Telnet (TCP 23)
  • MacTelnet — CLI over MAC-Telnet; reach a router with no IP configured / no IP route (Layer 2)
  • WinboxCli / WinboxCliMac — CLI over the encrypted WinBox channel (TCP 8291 / MAC layer)
  • WinboxNative / WinboxNativeMac — structured WinBox M2 binary CRUD, no terminal (TCP 8291 / MAC layer)

As far as I know, tik4net is the only .NET library that speaks MAC-Telnet and the WinBox protocols.

Features

  • ITikConnection low-level API (send command / read response, async commands)
  • ADO.NET-like API (ITikCommand + various Execute… methods)
  • O/R mapper to/from entity classes (connection.LoadList<T>()), now with a much larger set of built-in strong-typed entities
  • Change tracking — the entity layer tracks which properties you changed; Save<T>() sends only the diff
  • Safe Mode across all transports (TakeSafeMode() / ReleaseSafeMode()), with auto-rollback on disconnect
  • Streaming monitors — async/listen for live data (torch, log, …)
  • Capability model — ask a connection what it supports: connection.Supports(TikConnectionCapability.Listen)
  • Raw command pass-throughExecuteRaw for anything not covered by the mapper
  • C# entity code generators — semi-automatic generation of custom entities from a running MikroTik router and from the MikroTik wiki (official documentation)
  • API-SSL support, plus the new MikroTik (from v6.43) login process
  • tik4net.testing package — TikFakeConnection lets you write unit tests with no live router
  • MCP server — a mikrotik_call tool that lets an AI assistant run commands against a live router over any tik4net transport

Examples

For read/write examples see the API comparison / CRUD examples wiki page: CRUD examples for all APIs · danikf/tik4net Wiki · GitHub

Read and print MikroTik router identity:

using (ITikConnection connection = ConnectionFactory.CreateConnection(TikConnectionType.Api))
{
  connection.Open(HOST, USER, PASS);
  ITikCommand cmd = connection.CreateCommand("/system/identity/print");
  Console.WriteLine(cmd.ExecuteScalar());
}

Same code over a different transport — just change the connection type (e.g. reach a router with no IP via MAC-Telnet):

using (ITikConnection connection = ConnectionFactory.CreateConnection(TikConnectionType.MacTelnet))
{
  connection.Open(MAC_ADDRESS, USER, PASS);
  Console.WriteLine(connection.CreateCommand("/system/identity/print").ExecuteScalar());
}

Example of async Torch command:

using (ITikConnection connection = ConnectionFactory.CreateConnection(TikConnectionType.Api))
{
  connection.Open(HOST, USER, PASS);
  var loadingContext = connection.LoadAsync<ToolTorch>(
    torchItem => Console.WriteLine(torchItem.ToString()),
    error => Console.WriteLine(error.ToString()),
    connection.CreateParameter("interface", interfaceName),
    connection.CreateParameter("port", "any"),
    connection.CreateParameter("src-address", "0.0.0.0/0"),
    connection.CreateParameter("dst-address", "0.0.0.0/0"));

  Console.ReadLine();
  loadingContext.Cancel();
}

Read all log entries:

var logs = connection.LoadList<Log>();
foreach (Log log in logs)
{
    Console.WriteLine("{0}[{1}]: {2}", log.Time, log.Topics, log.Message);
}

Firewall management:

//find first firewall rule
var firstFirewallRule = connection.LoadAll<FirewallFilter>().First();

// create new firewall rule as first rule in list
var firewallFilter = new FirewallFilter()
{
   Chain = FirewallFilter.ChainType.Forward,
   Action = FirewallFilter.ActionType.Accept,
};
connection.Save(firewallFilter);
connection.Move(firewallFilter, firstFirewallRule);

_NOTE: please do not use the deprecated 0.9.7 incompatible version of tik4net from https://code.google.com/p/mikrotik4net/._

Chupaka - thank you for inspiration how to handle paralel queries.

D
BTW: both your and mine code are not realy thread-safe :wink:

Released new version with updates. Added versions for .NET 3.5, .NET 4.0 and .NET 4.5.2

Released new version 1.2.0.0 with enum support (as field values) and with C# entity code generators.

Enjoy,
D

Example of highlevel API usage (dev branch on GitHub):

// renew IP on dhcp-client interface
connection.LoadAll<IpDhcpClient>().First().Release(connection);

This looks like a great project, and one that would be very useful. Thanks for sharing it with us.

I have just downloaded it and spent some time going through the samples and classes, but I did not notice anything to do with Hotspot, in particular creating and deleting user accounts. Is this functionality available in the library? If not, is it something you will be adding anytime soon?

Again, many thanks.

Mark

Hello,

I am going to import hotspot objects very soon (one week?), but I need betatesters, becase I am not using this feature. If you wold participate in betatesting, your help will be appreciated.

Or you can create your own classes (see TikEntity and TikProperty attributes) and use it with O/R mapper like extensions.

Or you can use ADO like api - handle hotspot management via standard “Execute” command interface like other libraries :slight_smile:

D

Released new version 1.2.2.0 with hotspot user entities (beta).

using tik4net.Objects;
using tik4net.Objects.Ip.Hotspot;



var user = new HotspotUser()
{
    Name = "TEST",
    LimitUptime = "1:00:00",
    Password = "secretpass"
};
_connection.Save(user);

Enjoy,
D

We have a test facility in our office here, and use the Hotspot functionality quite extensively, so would be happy to help test it for you.

Published version 1.3.0.0.

New highlevel entities:

  • Hotspot users
  • Interface (eth/wlan)
var list = Connection.LoadAll<InterfaceWireless.WirelessRegistrationTable>();

Enjoy,
D

Version 1.4.0.0 released:

  • Fixed word length calculation (credits: h44z)
  • Hotspot user management fixed
  • Async API refactoring (cleaning)

Enjoy,
D

Impressive work :smiley: I made use of the older deprecated version but this is awesome hands down! Now Testing!

good evening…
Must capture all connections from an IP address /ip/firewall/connections/print where src-address ~192.168.2.2 . How could perform it? thank you

good evening…
I can not run /IP/firewall/connection/print where src-address ~ “192.168.2.2”.
I need to capture the dst -address.

Obrigado .

Hi,

there are many ways how to handle this task:

using (ITikConnection connection = ConnectionFactory.CreateConnection(TikConnectionType.Api))
{
  connection.Open(HOST, USER, PASS);
  1. Via direct API call (low-level access):
  string[] command = new string[]
  {
    "/ip/firewall/connection/print",
    "?src-address=192.168.3.103"
  };
  var result = connection.CallCommandSync(command);
  1. Via ADO.NET like API:
  var command = connection.CreateCommandAndParameters("/ip/firewall/connection/print",
    "src-address", "192.168.3.103");
  var result = command.ExecuteList();
  1. Via highlevel O/R mapper like API:
  // This class will be part of the next release, but you can just put it in your code
    [TikEntity("ip/firewall/connection")]
    public class FirewallConnection
    {
        [TikProperty(".id", IsReadOnly = true, IsMandatory = true)]
        public string Id { get; private set; }

        [TikProperty("connection-mark", IsReadOnly = true)]
        public string ConnectionMark { get; private set; }

        [TikProperty("connection-type", IsReadOnly = true)]
        public string ConnectionType { get; private set; }

        [TikProperty("dst-address", IsReadOnly = true)]
        public string DstAddress { get; private set; }

        [TikProperty("protocol", IsReadOnly = true)]
        public string Protocol { get; private set; }

        [TikProperty("src-address", IsReadOnly = true)]
        public string SrcAddress { get; private set; }

        [TikProperty("tcp-state", IsReadOnly = true)]
        public string TcpState { get; private set; }

        [TikProperty("timeout", IsReadOnly = true)]
        public string Timeout { get; private set; }
    }

  // And the code:
  using tik4net.Objects;
  ...
  var result = connection. LoadList<FirewallConnection>(
    connection.CreateParameter("src-address", "192.168.3.103"));
  1. You can skip filtering part, select all connection items and filter them via C# code (LINQ?). Slow, but simple…

Enjoy,
D

good Morning…
I performed a test as follows

using (ITikConnection connection = ConnectionFactory.CreateConnection(TikConnectionType.Api))
{
connection.Open(HOST, USER, PASS);
var command = connection.CreateCommandAndParameters(“/ip/firewall/connection/print”,“src-address”,“192.168.3.69”);
var result = command.ExecuteList();

foreach (var c in result)
{
listBox1.Items.Add(c);
}
}

however I have no result

Probably there is no active connection from ip 192.168.3.69 to router (or connection tracking is switched off in mikrotik configuration).

Try to load all connections without filter:

var command = connection.CreateCommandAndParameters("/ip/firewall/connection/print"); 
var result = command.ExecuteList();

Enjoy,
D

Released new version 1.5.0.0.

Whats new:

Enjoy,
D

Hi danikf
Good work man, Thanks for sharing it.
I am using your dll in vb.net project, can you explain how to set ?#operations by CreateCommandAndParameters to applies operations to the values in the stack.
Example to execute this query.

/interface/print
?type=ether
?type=vlan
?#|

Hi,
I have just updated github sources (update will be part of the next release). With updated version you can simply format command text with filter.

Untyped version:

            var cmd = Connection.CreateCommandAndParameters(@"/interface/print
                            ?type=ether
                            ?type=wlan
                            ?#|");
            var list = cmd.ExecuteList();

Strong-typed version

            var cmd = Connection.CreateCommandAndParameters(@"/interface/print
                            ?type=ether
                            ?type=wlan
                            ?#|");
            var list = cmd.LoadList<Interface>();

The main reasson why parameters stack is not supported is that it will bring high complexity into API (expression trees?). So, I will decide (for this time) not to support this construction via parameters (may be in the future).

Enjoy,
D