Skip to content

Roadmap 4x

Daniel Frantík edited this page Jun 17, 2026 · 10 revisions

Roadmap — tik4net 4.x

High-level overview of what is planned for future 4.x releases. The initial 4.0.0-alpha dropped all 9 new connection types, change tracking, Safe Mode, streaming monitors, and the MCP helper tool — see History for the full list.


✅ Change tracking

Automatic snapshot on load, diff-based save — only changed fields are sent to the router. No-op saves skip the API call entirely. Released in 4.0.0-alpha. See Change tracking.


TikLink — async fluent API

A new high-level entry point that wraps the existing connection and entity layers behind a clean, async-first interface:

await using var link = await TikLink.ConnectAsync("192.168.1.1", "admin", "pwd");

var rules = await link.Ip.Firewall.Filter
    .Where(r => r.Chain == "input")
    .ToListAsync();

var rule = await link.Ip.Firewall.Filter.GetAsync("*1");
rule.Comment = "WAN";
await link.SaveAsync(rule);   // uses change tracking

All operations are async/await. The existing synchronous ITikConnection API remains fully supported.


Path-based navigation

The TikLink object exposes a typed tree that mirrors the MikroTik CLI hierarchy — link.Ip.Firewall.Filter, link.System.Identity, link.Interface, etc. — instead of requiring a generic Query<T>() call.

Note: The tree will initially be hand-written for the most common paths (~50). Automatic generation from [TikEntity] attributes via a Roslyn source generator is planned as a follow-up step — we need to explore the complexity first.


Typed command wrappers

First-class wrappers for non-CRUD commands with fluent builders:

await link.System.Reboot.ExecuteAsync();

await foreach (var ping in link.Tool.Ping
    .Address("8.8.8.8").Count(5).ExecuteAsync(ct))
{
    Console.WriteLine(ping.Time);
}

SyncListAsync with reordering

Bulk sync of a local list against the router, including support for ordered entities (firewall rules, queue trees). Computes the minimal set of add / update / delete / move operations needed to bring the router to the desired state.


REST API transport

Support for the RouterOS 7.1+ HTTP REST API as an alternative transport behind the same TikLink / ITikConnection interface.

Note: We will first explore how well REST maps to the existing sentence-based model and what capability gaps exist (no /listen, limited streaming) before committing to a full implementation.


Dependency injection integration

IServiceCollection extension for ASP.NET Core / generic host applications:

services.AddTikLink(opt => {
    opt.Host = config["MikroTik:Host"];
    opt.User = config["MikroTik:User"];
    opt.Password = config["MikroTik:Password"];
});

Scoped lifetime (DbContext-style). Connection pooling TBD.


Platform targets cleanup

Drop legacy targets (net35 / net40 / netcoreapp1.x are already gone as of 3.6). For 4.x we plan to target net6.0 / net8.0 + netstandard2.0 / netstandard2.1, and enable #nullable reference types across the codebase.

.NET Framework 4.8 remains fully supported via netstandard2.0 and will continue to be tested.


✅ MAC-Telnet transport

Layer-2 communication with a router that has no IP connectivity — useful for recovery and bootstrap scenarios. Ships as part of the core tik4net package (no additional NuGet required).

TikConnectionType.MacTelnet — UDP port 20561, EC-SRP5 authentication, VT100 terminal session driven by the shared CLI layer. MNDP-based MAC discovery built in. See MAC-Telnet-connection.


✅ WinBox CLI transport

Encrypted CLI over the WinBox channel (TCP port 8291) — the same port the WinBox application uses. Drives the RouterOS CLI through the WinBox mepty terminal handler, so all CRUD works through the shared CLI layer. Ships as part of the core tik4net package (no additional NuGet required).

TikConnectionType.WinboxCli — EC-SRP5 authentication + AES-128-CBC encrypted session (legacy MD5 fallback for pre-6.43 firmware). Fully encrypted end to end without enabling API-SSL / certificates. See WinBox-CLI-connection.

This is the terminal-driven WinBox mode. Native-M2 (non-terminal structured CRUD) has since shipped — see the WinBox Native sections below.


✅ WinBox CLI over MAC transport

The same encrypted WinBox terminal CLI as above, but tunnelled over the MAC layer (UDP port 20561, client_type=0x0f90) — so it works without an IP route to the router, combining MAC-Telnet's reach with WinBox's encryption. Ships in the core tik4net package.

TikConnectionType.WinboxCliMac — the full WinBox protocol (EC-SRP5 handshake + chunked AES frames) carried over the proven MAC-layer reliable stream, sharing the same CLI engine as the TCP transport. MNDP-based MAC discovery built in. See WinBox-CLI-MAC-connection.


✅ WinBox Native (M2) transport ⚠️ alpha-preview

Structured CRUD over the encrypted WinBox channel (TCP port 8291) using the native M2 protocol — no terminal, no CLI screen-scraping. getall / get / set / add / remove / move map directly to the native handlers, with the API ↔ M2 field mapping reconstructed from the router's version-matched .jg catalog. Reports Crud | Listen | SafeMode. Ships in the core tik4net package.

TikConnectionType.WinboxNative — same EC-SRP5 + AES channel as WinBox CLI, structured M2 above it. See WinBox-Native-connection.


✅ WinBox Native (M2) over MAC transport ⚠️ alpha-preview

The same structured native-M2 CRUD as above, but carried over the MAC layer (UDP port 20561, client_type=0x0f90) — so it works without an IP route to the router. Implemented by swapping the M2 channel to the MAC-layer session; the entire native engine (.jg resolver, encode/decode, streaming monitors, Safe Mode) is shared with the TCP transport. Ships in the core tik4net package.

TikConnectionType.WinboxNativeMac — MNDP-based MAC discovery built in (RouterMac bypasses it). See WinBox-Native-MAC-connection.


✅ SSH transport

Drives the RouterOS CLI over an interactive SSH PTY shell (TCP port 22), reusing the same CLI layer as Telnet/MAC-Telnet (print as-value parsing, paging prevention, VT100 handling). Reports Crud | Listen | SafeMode. Ships as the satellite package tik4net.ssh (separate because of its Renci.SshNet dependency — core stays dependency-free).

TikConnectionType.Sshnew SshConnection(), setup.CreateSshConnection(), or ConnectionFactory after Tik4NetSsh.Register(). Safe-mode unroll uses the scriptable /safe-mode/unroll command (RouterOS 7.18+) because the terminal Ctrl+D is the SSH EOF convention. See SSH-connection.


✅ Raw command pass-through

An opt-in conn.CreateRawCommand(raw) that sends a raw payload in the transport's own dialect, bypassing the structured command builder/mapper — for non-CRUD commands, one-off snippets and debugging. The payload is an API sentence on the binary API (lossless, real !re rows) or a verbatim CLI line on the CLI transports (Telnet / SSH / MAC-Telnet / WinBox CLI ±Mac). It keeps the normal ITikCommand / ITikReSentence model (ExecuteList → parsed sentences, ExecuteScalar → raw text) rather than a separate string-only API; raw-ness is a per-command kind, not a connection mode. Gated by the RawCommand capability — REST and WinBox Native don't declare it (the latter's "raw" would be a numeric M2 message, not a string; use WinBox CLI for raw over that channel), so they fail closed. The structured ExecuteXxx path stays the default. Available now on the 4.x branch. See Command translation on non-API transports.


✅ WinBox Native addressing by GUI names

WinBox Native can resolve paths/fields by the label you see in the WinBox GUI (spaces or underscores folded to -, abbreviation dots dropped, any case) in addition to the exact API name — reusing the existing label normalizer on the input side. Opt-in per connection (connection.UseGuiNames = true), so strict API-name resolution stays the default; session FieldOverride/PathOverride still win, and decoded output always uses canonical API names. Available now on the 4.x branch. See Command translation on non-API transports.


TikValue — flexible property model (under consideration)

MikroTik increasingly uses property values that typed enums cannot represent: negations (!dynamic), comma-separated combinations, version-dependent strings. A TikValue wrapper struct could expose these naturally while staying implicit-convertible from string.

This would be a breaking change to the entity model. We will evaluate scope and migration cost before committing.


⚠️ Breaking changes (for release notes)

Running list of behavioural / API-surface changes on the 4.x line that need to be called out in the 4.0 release notes. Most are source-compatible for typical try/catch usage; the binary-compatibility notes matter only for plugins/assemblies compiled against 3.x.

Exception model

  • TikSentenceException now derives from TikConnectionException (was System.Exception). Catching TikConnectionException now also catches malformed-sentence errors — the documented "one root catches everything" contract. Source-compatible (a widening: existing catch (TikSentenceException) / catch (Exception) still work); binary-breaking (base type changed).
  • Exception serialization removed. [Serializable], the ISerializable/SerializationInfo constructors and GetObjectData were dropped from TikConnectionException and TikConnectionCapabilityNotSupportedException (the plumbing was incomplete across leaf types, carried non-serializable members, and BinaryFormatter is obsolete on the netstandard2.0/2.1 targets). Code relying on binary/remoting serialization of tik4net exceptions must use ToString() / structured logging instead.
  • WinBox Native error mapping changed. An unrecognized router-reported M2 error now surfaces as TikCommandTrapException instead of TikCommandUnexpectedResponseException, matching the API/CLI/REST generic-error fallback. Callers that special-cased TikCommandUnexpectedResponseException for WinBox-native router errors should catch TikCommandTrapException (or its base TikCommandException) instead.

See Exception handling for the full tree and per-type semantics.

Platform targets

  • Legacy targets dropped; 4.x targets net6.0 / net8.0 + netstandard2.0 / netstandard2.1 with #nullable enabled. .NET Framework 4.8 remains supported via netstandard2.0. (See Platform targets cleanup above.)

Clone this wiki locally