心想事成 发表于 2009-5-12 20:29:28

routeros api执行工具程序及源码

routeros在3.0版以上,新增了一个api功能。通过开启api功能,可以使用一个外部程序直接控制routeros。
默认的API 端口是 8728. 默认情况下API功能是关闭的,要使用以下的命令开启:
/ip service enable api
然后再使用api工具就可以直接连到roueros中了。
附件中的程序就是这样的工具,大家可以测试下。

ksw520 发表于 2009-5-12 21:56:33

支持。。。

seignior 发表于 2009-5-12 22:13:09

本帖最后由 seignior 于 2009-5-12 22:33 编辑

有没有vc或者vb的源码参考....

P.S:官方的没看明白,希望能求个相对完整的代码,例如这个demo的vc、vb版

soft_route 发表于 2009-5-12 22:16:01

顶:)

心想事成 发表于 2009-5-12 22:50:27

有没有vc或者vb的源码参考....

P.S:官方的没看明白,希望能求个相对完整的代码,例如这个demo的vc、vb版
seignior 发表于 2009-5-12 22:13 http://bbs.routerclub.com/images/common/back.gif


API client realization for Delphi7. It implements execution of parallel queries which are easily handled due to database-like interface

心想事成 发表于 2009-5-12 22:51:23

我自己用c也写了一个,在linux 下调试通过。

seignior 发表于 2009-5-12 22:55:28

本帖最后由 seignior 于 2009-5-12 23:00 编辑

我已经反复看
http://forum.mikrotik.com/viewtopic.php?f=9&t=31555
http://wiki.mikrotik.com/wiki/API_Delphi

但无奈c,basic本身就是半桶水,delphi就更一头雾水~~~~还是求你的c code吧

实际就是不想让基层直接操作ros,倒不是操守上的信任问题,主要是操作技能上的信任不够(那帮小崽子连自己在做什么都不清楚-_-"),想自己写个有限制的client给他们用。

心想事成 发表于 2009-5-12 23:09:01

VB.NET版本的RouterOS API程式碼如下Imports System.Net.Sockets
Imports System.IO
Imports System.Text

Class MK_ROS
    Private connection As Stream
    Private con As TcpClient

    Public Sub New(ByVal ip As String)
      con = New TcpClient()
      con.Connect(ip, 8728)
      connection = DirectCast(con.GetStream(), Stream)
    End Sub
    Public Sub Close()
      connection.Close()
      con.Close()
    End Sub
    Public Function Login(ByVal username As String, ByVal password As String) As Boolean
      Send("/login", True)
      Dim hash As String = Read()(0).Split(New String() {"ret="}, StringSplitOptions.None)(1)
      Send("/login")
      Send("=name=" & username)
      Send("=response=00" & EncodePassword(password, hash), True)
      If Read()(0) = "!done" Then
            Return True
      Else
            Return False
      End If
    End Function
    Public Sub Send(ByVal co As String)
      Dim bajty As Byte() = Encoding.ASCII.GetBytes(co.ToCharArray())
      Dim velikost As Byte() = EncodeLength(bajty.Length)

      connection.Write(velikost, 0, velikost.Length)
      connection.Write(bajty, 0, bajty.Length)
    End Sub
    Public Sub Send(ByVal co As String, ByVal endsentence As Boolean)
      Dim bajty As Byte() = Encoding.ASCII.GetBytes(co.ToCharArray())
      Dim velikost As Byte() = EncodeLength(bajty.Length)
      connection.Write(velikost, 0, velikost.Length)
      connection.Write(bajty, 0, bajty.Length)
      connection.WriteByte(0)
    End Sub
    Public Function Read() As List(Of String)
      Dim output As New List(Of String)()
      Dim o As String = ""
      Dim tmp As Byte() = New Byte(3) {}
      Dim count As Long
      While True
            tmp(3) = CByte(connection.ReadByte())
            'if(tmp == 220) tmp = (byte)connection.ReadByte(); it sometimes happend to me that
            'mikrotik send 220 as some kind of "bonus" between words, this fixed things, not sure about it though
            If tmp(3) = 0 Then
                output.Add(o)
                If o.Substring(0, 5) = "!done" Then
                  Exit While
                Else
                  o = ""
                  Continue While
                End If
            Else
                If tmp(3) < &H80 Then
                  count = tmp(3)
                Else
                  If tmp(3) < &HC0 Then
                        Dim tmpi As Integer = BitConverter.ToInt32(New Byte() {CByte(connection.ReadByte()), tmp(3), 0, 0}, 0)
                        count = tmpi Xor &H8000
                  Else
                        If tmp(3) < &HE0 Then
                            tmp(2) = CByte(connection.ReadByte())
                            Dim tmpi As Integer = BitConverter.ToInt32(New Byte() {CByte(connection.ReadByte()), tmp(2), tmp(3), 0}, 0)
                            count = tmpi Xor &HC00000
                        Else
                            If tmp(3) < &HF0 Then
                              tmp(2) = CByte(connection.ReadByte())
                              tmp(1) = CByte(connection.ReadByte())
                              Dim tmpi As Integer = BitConverter.ToInt32(New Byte() {CByte(connection.ReadByte()), tmp(1), tmp(2), tmp(3)}, 0)
                              count = tmpi Xor &HE0000000
                            Else
                              If tmp(3) = &HF0 Then
                                    tmp(3) = CByte(connection.ReadByte())
                                    tmp(2) = CByte(connection.ReadByte())
                                    tmp(1) = CByte(connection.ReadByte())
                                    tmp(0) = CByte(connection.ReadByte())
                                    count = BitConverter.ToInt32(tmp, 0)
                              Else
                                    'Error in packet reception, unknown length
                                    Exit While
                              End If
                            End If
                        End If
                  End If
                End If
            End If

            For i As Integer = 0 To count - 1
                o += ChrW(connection.ReadByte())
            Next
      End While
      Return output
    End Function
    Private Function EncodeLength(ByVal delka As Integer) As Byte()
      If delka < &H80 Then
            Dim tmp As Byte() = BitConverter.GetBytes(delka)
            Return New Byte(0) {tmp(0)}
      End If
      If delka < &H4000 Then
            Dim tmp As Byte() = BitConverter.GetBytes(delka Or &H8000)
            Return New Byte(1) {tmp(1), tmp(0)}
      End If
      If delka < &H200000 Then
            Dim tmp As Byte() = BitConverter.GetBytes(delka Or &HC00000)
            Return New Byte(2) {tmp(2), tmp(1), tmp(0)}
      End If
      If delka < &H10000000 Then
            Dim tmp As Byte() = BitConverter.GetBytes(delka Or &HE0000000)
            Return New Byte(3) {tmp(3), tmp(2), tmp(1), tmp(0)}
      Else
            Dim tmp As Byte() = BitConverter.GetBytes(delka)
            Return New Byte(4) {&HF0, tmp(3), tmp(2), tmp(1), tmp(0)}
      End If
    End Function

    Public Function EncodePassword(ByVal Password As String, ByVal hash As String) As String
      Dim hash_byte As Byte() = New Byte(hash.Length / 2 - 1) {}
      For i As Integer = 0 To hash.Length - 2 Step 2
            hash_byte(i / 2) = .Parse(hash.Substring(i, 2), System.Globalization.NumberStyles.HexNumber)
      Next
      Dim heslo As Byte() = New Byte(1 + Password.Length + (hash_byte.Length - 1)) {}
      heslo(0) = 0
      Encoding.ASCII.GetBytes(Password.ToCharArray()).CopyTo(heslo, 1)
      hash_byte.CopyTo(heslo, 1 + Password.Length)

      Dim hotovo As Byte()
      Dim md5 As System.Security.Cryptography.MD5

      md5 = New System.Security.Cryptography.MD5CryptoServiceProvider()

      hotovo = md5.ComputeHash(heslo)

      'Convert encoded bytes back to a 'readable' string
      Dim navrat As String = ""
      For Each h As Byte In hotovo
            navrat += h.ToString("x2")
      Next
      Return navrat
    End Function
End Class使用方式如下:Dim mikrotik As New MK_ROS("主機位置(可為IP或Domain)")
If Not mikrotik.Login("帳號", "密碼") Then
    TextBox1.Text &= ("連線失敗")
    mikrotik.Close()
    Return
End If
'要下的指令
mikrotik.Send("/system/identity/print", True)
For Each h As String In mikrotik.Read()
    TextBox1.Text &= h
Next

seignior 发表于 2009-5-12 23:30:11

谢谢,容易理解很多了,但依然在翻书-_-"

winkw 发表于 2009-5-13 01:32:06

留个记号,慢慢学习!!

专卖精品 发表于 2009-5-13 20:08:17

先下载了看看

politank 发表于 2009-5-13 20:11:37

有空研究研究

tpy372 发表于 2009-5-13 22:48:09

顶啊

木木 发表于 2009-5-13 22:59:31

几个月前已经通过api连上ros,下一步主要做应用了。

pxyq 发表于 2009-5-14 12:18:44

有VC的源代码就好了
页: [1] 2
查看完整版本: routeros api执行工具程序及源码