thongkorn โพสต์ 2020-1-13 12:55:49

[VB.NET] โค้ดโปรแกรมการเชื่อมต่อกับ MikroTik และการสั่งรัน Command

http://www.g2gnet.com/webboard/images/vbnet/connectmikrotik.png


ปฐมบทชุดแรกที่แอดมินก็พึ่งได้เคยทำการเขียนโค้ดโปรแกรมด้วย VB.NET เพื่อทำการเชื่อมต่อเข้ากับ MikroTik และทำการรันทดสอบคอมมานด์ เพื่อดูคุณสมบัติต่างๆภายในตัว MikroTik


มาดูโค้ดกันเถอะ ...
Public Class frmConnectMikroTik

    Private Sub frmConnectMikroTik_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
      txtIPAddress.Text = "IP ADDRESS"
      txtPort.Text = "8728"
      txtUsername.Text = "admin"
      txtPassword.Text = "PASSWORD"
      Call OnOff(False)
    End Sub

    Sub OnOff(ByVal blnState As Boolean)
      If blnState Then
            GroupBox1.Text = " Connect to MikroTik ... "
            txtIPAddress.Enabled = False
            txtPort.Enabled = False
            txtUsername.Enabled = False
            txtPassword.Enabled = False
            btnConnect.Enabled = False
            btnClear.Enabled = True
            btnSend.Enabled = True
            txtCmd.Enabled = True
      Else
            GroupBox1.Text = " Log in "
            txtIPAddress.Enabled = True
            txtPort.Enabled = True
            txtUsername.Enabled = True
            txtPassword.Enabled = True
            btnConnect.Enabled = True
            btnClear.Enabled = False
            btnSend.Enabled = False
            txtCmd.Enabled = False
      End If
    End Sub

    Function LoginMikrotik(ByVal IP As String, ByVal UN As String, ByVal PW As String) As Boolean
      Dim IPAddress As System.Net.IPAddress = System.Net.IPAddress.Parse(IP)
      Dim mk = New Mikrotik(IPAddress, 8728)
      If Not mk.Login(Trim(txtUsername.Text), Trim(txtPassword.Text)) Then
            Return False
      Else
            Return True
      End If
    End Function

    Private Sub btnConnect_Click(sender As System.Object, e As System.EventArgs) Handles btnConnect.Click
      If Not LoginMikrotik(txtIPAddress.Text.Trim, (txtUsername.Text), Trim(txtPassword.Text)) Then
            OnOff(False)
            MessageBox.Show("Sorry !!! You can't log in.", "Report Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Return
      Else
            'MessageBox.Show("Welcome to Mikrotik system.", "Report Status", MessageBoxButtons.OK, MessageBoxIcon.Information)
            OnOff(True)
            txtCmd.Focus()
            '// SAMPLE
            ' /interface/print
            '/ip/arp/print
            '/system/resource/getall
            txtCmd.Text = "/system/resource/print"
      End If
    End Sub

    Private Sub txtData_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtResult.KeyPress
      e.Handled = True
    End Sub

    Private Sub btnSend_Click(sender As System.Object, e As System.EventArgs) Handles btnSend.Click
      If txtCmd.Text.Trim.Length = 0 Then Return
      '//
      Dim IPAddress As System.Net.IPAddress = System.Net.IPAddress.Parse(Trim(txtIPAddress.Text))
      Dim mk = New Mikrotik(IPAddress, 8728)
      Try
            If mk.Login(Trim(txtUsername.Text), Trim(txtPassword.Text)) Then
                txtResult.Clear()
                mk.Send(Trim(txtCmd.Text), True)
                Dim strLog As String = String.Empty
                For Each row In mk.Read
                  strLog = strLog & row & vbCrLf
                Next
                txtResult.Text = strLog
            End If

      Catch ex As Exception
            MessageBox.Show(ex.Message)
      End Try
    End Sub

    Private Sub btnClear_Click(sender As System.Object, e As System.EventArgs) Handles btnClear.Click
      OnOff(False)
      txtResult.Clear()
    End Sub
End Class


API in VB dot NET ... (https://wiki.mikrotik.com/wiki/API_in_VB_dot_NET)
'// ORIGINAL ... https://wiki.mikrotik.com/wiki/API_in_VB_dot_NET

Public Class Mikrotik
    Dim tcpStream As IO.Stream
    Dim tcpCon As New Net.Sockets.TcpClient

    Public Sub New(ByVal IPAddr As System.Net.IPAddress, Optional ByVal port As Integer = -1)
      tcpCon.Connect(IPAddr, If(port = -1, 8728, port))
      tcpStream = tcpCon.GetStream()
    End Sub

    Public Sub Close()
      tcpStream.Close()
      tcpCon.Close()
    End Sub

    Public Function Login(ByVal user As String, ByVal pass As String) As Boolean
      Send("/login", True)
      Dim hash = Read()(0).Split(New String() {"ret="}, StringSplitOptions.None)(1)
      Send("/login")
      Send("=name=" + user)
      Send("=response=00" + EncodePassword(pass, hash), True)
      Dim res = Read()
      If (res(0) = "!done") Then Return True Else Return False
    End Function

    Function EncodePassword(ByVal pass As String, ByVal challange As String) As String
      Dim hash_byte(challange.Length / 2 - 1) As Byte
      For i = 0 To challange.Length - 2 Step 2
            hash_byte(i / 2) = Byte.Parse(challange.Substring(i, 2), Globalization.NumberStyles.HexNumber)
      Next
      Dim response(pass.Length + hash_byte.Length) As Byte
      response(0) = 0
      System.Text.Encoding.ASCII.GetBytes(pass.ToCharArray()).CopyTo(response, 1)
      hash_byte.CopyTo(response, 1 + pass.Length)


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

      Dim hash = md5.ComputeHash(response)

      Dim hashStr As New System.Text.StringBuilder()
      For Each h In hash
            hashStr.Append(h.ToString("x2"))
      Next
      Return hashStr.ToString()
    End Function

    Public Sub Send(ByVal command As String, Optional ByVal EndSentence As Boolean = False)
      Dim bytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray())
      Dim size = EncodeLength(bytes.Length)

      tcpStream.Write(size, 0, size.Length)
      tcpStream.Write(bytes, 0, bytes.Length)
      If EndSentence Then tcpStream.WriteByte(0)
    End Sub

    Public Function Read() As List(Of String)
      Dim output As New List(Of String)
      Dim o = ""
      Dim tmp(4) As Byte
      Dim count As Long

      While True
            tmp(3) = tcpStream.ReadByte()
            Select Case tmp(3)
                Case 0
                  output.Add(o)
                  If o.Substring(0, 5) = "!done" Then
                        Exit While
                  Else
                        o = ""
                        Continue While
                  End If
                Case Is < &H80
                  count = tmp(3)
                Case Is < &HC0
                  count = BitConverter.ToInt32(New Byte() {tcpStream.ReadByte(), tmp(3), 0, 0}, 0) ^ &H8000
                Case Is < &HE0
                  tmp(2) = tcpStream.ReadByte()
                  count = BitConverter.ToInt32(New Byte() {tcpStream.ReadByte(), tmp(2), tmp(3), 0}, 0) ^ &HC00000
                Case Is < &HF0
                  tmp(2) = tcpStream.ReadByte()
                  tmp(1) = tcpStream.ReadByte()
                  count = BitConverter.ToInt32(New Byte() {tcpStream.ReadByte(), tmp(1), tmp(2), tmp(3)}, 0) ^ &HE0000000
                Case &HF0
                  tmp(3) = tcpStream.ReadByte()
                  tmp(2) = tcpStream.ReadByte()
                  tmp(1) = tcpStream.ReadByte()
                  tmp(0) = tcpStream.ReadByte()
                  count = BitConverter.ToInt32(tmp, 0)
                Case Else
                  Exit While   'err
            End Select

            For i = 0 To count - 1
                o += ChrW(tcpStream.ReadByte())
            Next
      End While
      Return output
    End Function

    Function EncodeLength(ByVal l As Integer) As Byte()
      If l < &H80 Then
            Dim tmp = BitConverter.GetBytes(l)
            Return New Byte() {tmp(0)}
      ElseIf l < &H4000 Then
            Dim tmp = BitConverter.GetBytes(l Or &H8000)
            Return New Byte() {tmp(1), tmp(0)}
      ElseIf l < &H200000 Then
            Dim tmp = BitConverter.GetBytes(l Or &HC00000)
            Return New Byte() {tmp(2), tmp(1), tmp(0)}
      ElseIf l < &H10000000 Then
            Dim tmp = BitConverter.GetBytes(l Or &HE0000000)
            Return New Byte() {tmp(3), tmp(2), tmp(1), tmp(0)}
      Else
            Dim tmp = BitConverter.GetBytes(l)
            Return New Byte() {&HF0, tmp(3), tmp(2), tmp(1), tmp(0)}
      End If
    End Function
End Class

ดาวน์โหลดโค้ดฉบับเต็ม VB.NET (2010) ได้ที่นี่ ...

g2gsoftuser โพสต์ 2022-10-25 15:38:11

ขอบคุณครับ
หน้า: [1]
ดูในรูปแบบกติ: [VB.NET] โค้ดโปรแกรมการเชื่อมต่อกับ MikroTik และการสั่งรัน Command