-
Notifications
You must be signed in to change notification settings - Fork 97
RouterOS versions
Which RouterOS versions tik4net is tested against, what each transport needs as a minimum, and how the library copes with the differences between versions. Read it before pointing tik4net at a router that is not on the current RouterOS 7.
In short: tik4net is developed against the current stable RouterOS 7, where every transport runs the full test suite. It also runs on RouterOS 6.49 and on older 7.x, which the lab keeps routers for. It never asks the router for its version to decide what to send. It reads what the router actually has and falls back where a version answers differently.
The lab runs three virtual routers (CHR). Each version below is tested against a live router, not assumed.
| RouterOS | Router | What runs there |
|---|---|---|
| 7.24.4 (stable) | the main lab router | the full integration suite (~650 tests) on all 11 transports, for every non-trivial change |
| 7.21.5 (long-term) | second RouterOS 7 | the version-sensitive tests on every transport: flag fields against the binary API, and the transport-by-transport audit of every mapped path against the binary API |
| 6.49.13 (long-term) | the RouterOS 6 router | the smoke subset and the same version-sensitive tests on the 9 transports RouterOS 6 has (no REST); the audit of every mapped path; RoMON relaying to it; copying lists to it from 7.24.4 |
Anything else — 6.x before 6.49, and 7.x other than these — is not tested. It is expected to work where it answers like its neighbours, and the rules below are what makes that likely. It is not promised.
| Transport | Minimum |
|---|---|
Api |
any RouterOS the binary API exists on; both login handshakes (login versions) |
ApiSsl |
api-ssl service, RouterOS 6.1+ (API-SSL) |
Rest, RestSsl
|
RouterOS 7.1+ — the REST API does not exist on 6.x; a request there is refused as TikNoSuchCommandException naming the floor |
Telnet, Ssh
|
any — the CLI is read the way the connected router prints it |
MacTelnet, WinboxCliMac, WinboxNativeMac
|
RouterOS 6.43+ (EC-SRP5 login; the legacy MD5 login is not implemented on the MAC transports) |
WinboxCli |
6.43+ uses EC-SRP5; older firmware falls back to the legacy MD5 login |
WinboxNative |
the router's own WinBox catalog, downloaded from it on connect — see below |
Two features have a version floor of their own:
- Safe Mode unrolls in place only on 7.18+; before that the discard also ends the session.
-
CLI secrets are asked with
show-sensitiveon RouterOS 7. RouterOS 6 prints them anyway, and a menu that refuses the word is read without it.
One rule underneath all of it: read what the router has; never compare version numbers. A version check would be wrong on every release that changes its mind, and on every router whose version string was never measured. What the router answers is always the right answer for that router.
A few fields have a different name on RouterOS 6 and 7 — /ip/service address became available-from,
/tool/e-mail address became server. Such a property carries both names (AlternateNames on
[TikProperty]). It reads whichever name the row has, and a save sends the value
back under the name it was read under. The list is on Entity reference.
Two consequences:
- Load before saving to an older router. An entity that was never loaded has no name to go back to, so it saves under the first name, and the other version refuses that name.
- A filter uses one name. A filter on a name the router's version does not have matches nothing, and no error says so.
A field the router did not print reads absent (TikValue), never as an invented default. A loaded
entity saves only what changed. So reading a RouterOS 7 entity from a RouterOS 6 router and saving it back never
writes a 7.x-only field. An entity saved without loading sends every field it holds. If one of them is a 7.x-only
field, RouterOS 6 refuses the command (unknown parameter), and nothing is guessed. Where your code relies on a
field being there, check after the load: EnsureStrict(TikStrictness.Absent) refuses a field the row did not carry
(TikValue).
A value the enum has no member for is kept as the router's word (TikValue: unparsed), not coerced or lost. So a newer router's new value never breaks a read, and a save leaves an unparsed value you did not touch as it is. A value you assign is always one of the enum's own members.
Rarely, a menu is a different kind of thing on another version. /interface/ovpn-server/server is one unnamed
server on RouterOS 6 and a list of named servers on RouterOS 7. The entity maps the 7.x list. On 6.x it reads the
one server as a row with a null Id, which cannot be saved through the entity. Use the
ADO.NET-like API there.
These are detected on the connection, from the router's own answer, and remembered for that connection:
-
CLI transports (Telnet, SSH, MAC-Telnet, WinBox CLI):
- RouterOS 6 and 7.x before 7.20 leave flag fields (
disabled,running, …) out ofprint as-value. The flags are then read by name, or on RouterOS 6, which has noproplist=, as the ids each flag is set on. - A
printor monitor with noas-valueform (RouterOS 6/ping,/tool traceroute,/routing bgp advertisements) is read from its plain table. A value the table cuts to its column (lab-b...) reads absent rather than wrong. - On RouterOS 6, completion lists on a second Tab, and answers only for the space form of a menu path.
- RouterOS 7.19 prints
.ids in lowercase; they are normalised to the API's form.
Details: Command translation.
- RouterOS 6 and 7.x before 7.20 leave flag fields (
-
Binary API: RouterOS 6 stops a
.proplistat the first name the menu does not have and drops the rest. The library sends no.proplistof its own for an entity. In your own, put the names only the newer version has last. -
WinBox native downloads the router's own WinBox catalog when it connects, and maps paths and fields from that. Older labels, keys a version does not declare, and fields that moved between windows are resolved per router. A path no WinBox window carries on that version is refused by name. WinBox native.
SaveListDifferences and list merging work across versions. This is
measured by copying an address list and firewall rules from 7.24.4 to 6.49.13: a second sync finds nothing to
update. Ids belong to the router they were read from. A copy made for another router must not keep them, or it
updates whatever row the target has under that id. Match rows by a key of your own (TikListMerge),
or create them without ids.
- Entity reference — the renamed fields, per entity
- TikValue — absent, unparsed and present values
- Connection types and capabilities — what each transport can do
- History — when each of these arrived
Start here
- Getting started — first project
- Which API level?
- One task, every transport & level — 29 runnable programs
- CRUD examples, all levels
- Upgrading from 3.x · with an AI agent
- Upgrading from 4.x to 5.0 · with an AI agent — unreleased
API levels
-
High-level — O/R mapper
- Reading data
- CRUD · async CRUD
- Advanced — streaming, ordering
- Change tracking
- List merging
- ADO.NET-like — commands, parameters
- Low-level — raw sentences
- VB.NET example
Entities
- Entity reference — all 171 menus
- How the mapping works
- TikValue — what a loaded property holds, and why
- Custom entities
- Value types · helpers
- Scaffolding tools
Transports
- Types & capabilities — the matrix
- Threading & concurrency — sharing one connection
- API-SSL · login versions
- REST
- Telnet · SSH
- MAC-Telnet
- RoMON — through a neighbouring router
- WinBox CLI · over MAC
- WinBox native · over MAC
- Command translation
- MNDP discovery
- Writing your own transport
Safety & diagnostics
- Safe Mode — rollback protection
- Exception handling
- Communication debugging
- Testing without a router
Project
- RouterOS versions — what is tested, and how versions differ
- MCP server
- History / changelog