Joined: Mon Aug 21, 2006 1:57 am Posts: 631
Karma: 3
Location: Winnipeg, Manitoba, Canada
Something thrown together in vb.net. The only caveat is that if you optomize or enhance this code, please share on the wiki.
Public Class ApiRos Dim thisSocket As System.Net.Sockets.Socket Dim thisTag As Integer Dim thisStream As System.Net.Sockets.NetworkStream Dim attr(1024) As String, aval(1024) As String
Public Function hex2ascii(ByVal hextext As String) As Byte() Dim y As Integer Dim num As String Dim bytes((hextext.Length - 2) / 2) As Byte Dim value As String = "" Dim i As Integer = 0 For y = 0 To hextext.Length - 2 num = Mid(hextext, y + 1, 2) value = value & Chr(Val("&h" & num)) bytes(i) = Val("&h" & num) y = y + 1 i = i + 1 Next y Return bytes End Function
Private Function StringToHex(ByVal password As String) As String Dim retString As String = "" Dim stringBytes() As Byte = System.Text.ASCIIEncoding.ASCII.GetBytes(password) Dim i As Integer = 0 For i = 0 To stringBytes.Length - 1 Dim hexTmp As String = Hex(stringBytes(i)) If hexTmp.Length = 1 Then retString = retString & "0" & hexTmp Else retString = retString & hexTmp End If Next Return retString End Function
Public Sub New(ByVal sk As System.Net.Sockets.Socket) thisSocket = sk thisTag = 0 thisStream = New System.Net.Sockets.NetworkStream(thisSocket, True) End Sub
Public Sub login(ByVal username As String, ByVal pwd As String) Dim i As Integer Dim words(1) As String
Dim writebuffer(1024) As Byte Dim readbuffer(1024) As Byte
words(0) = "/login" talk(words, attr, aval)
Dim mymd5 As System.Security.Cryptography.MD5 = New System.Security.Cryptography.MD5CryptoServiceProvider 'writebuffer = hex2ascii("00" + aval(0) + StringToHex(pwd)) readbuffer.Initialize() readbuffer = hex2ascii("00" + StringToHex(pwd) + aval(0)) writebuffer = mymd5.ComputeHash(readbuffer)
Dim retresp As String
retresp = "=response=00" For i = 0 To writebuffer.Length - 1 retresp += Format(writebuffer(i), "X2") Next
Debug.Print("**** " + retresp)
ReDim words(3) words(0) = "/login" words(1) = "=name=" + username words(2) = retresp talk(words, attr, aval) End Sub
Public Sub talk(ByVal words() As String, ByRef attr() As String, ByRef aval() As String) Dim i As String = "" Dim r As String = ""
If writeSentence(words) = 0 Then attr(0) = "" aval(0) = "" Exit Sub End If
Dim attrcount As Integer = 0 Do While 1 i = readSentence() If Len(i) = 0 Then attr(attrcount) = "" aval(attrcount) = "" Exit Sub End If
Dim ipos As Integer = InStr(1, i, "=", CompareMethod.Text) Dim ipos2 As Integer = InStr(ipos + 1, i, "=", CompareMethod.Text) If ((ipos = 0) Or (ipos > i.Length)) And i(0) = "!" Then ipos = 1 attr(attrcount) = Mid(i, ipos, ipos2 - ipos + 1) aval(attrcount) = Mid(i, ipos2 + 1, Len(i) - ipos2) attrcount += 1 Loop End Sub
Public Function writeSentence(ByVal words() As String) As Integer Dim ret As Integer = 0 Dim st As String
For Each st In words If Not st Is Nothing Then writeWord(st) ret += 1 End If Next
writeWord("")
Return ret End Function
Public Function readSentence() As String Dim r As String = "" Dim w As String Dim i As Integer = 0 Do While 1 w = readWord() If w = "" Then Return r r += Trim(w) i += 1 Loop
Return r End Function
Public Sub writeWord(ByVal w As String) Debug.Print("<<< " + w) writeLen(Len(w)) writeStr(w) End Sub
Public Function readWord() As String Dim readbuffer(4096) As Byte Dim ret As String Dim dsize As Integer
Public Sub writeLen(ByVal l As Integer) If l < &H80 Then writeStr(Chr(l)) ElseIf l < &H4000 Then l = l Or &H8000 writeStr(Chr((l >> 8 ) & &HFF)) writeStr(Chr(l & &HFF)) ElseIf l < &H200000 Then l = l Or &HC00000 writeStr(Chr((l >> 16) & &HFF)) writeStr(Chr((l >> 8 ) & &HFF)) writeStr(Chr(l & &HFF)) ElseIf l < &H10000000 Then l = l Or &HE0000000 writeStr(Chr((l >> 24) & &HFF)) writeStr(Chr((l >> 16) & &HFF)) writeStr(Chr((l >> 8 ) & &HFF)) writeStr(Chr(l & &HFF)) Else writeStr(Chr(&HF0)) writeStr(Chr((l >> 24) & &HFF)) writeStr(Chr((l >> 16) & &HFF)) writeStr(Chr((l >> 8 ) & &HFF)) writeStr(Chr(l & &HFF)) End If End Sub
Public Function readLen() As Integer Dim cb As Byte() = readStr(1)
If cb.Length = 0 Then Return 0
Dim c As Integer = CInt(cb(0)) ') & &HFF
If (c And &H80) = &H0 Then ElseIf (c And &HC0) = &H80 Then c = c And (Not &HC0) c <<= 8 c += Convert.ToInt32(readStr(1)) & &HFF ElseIf (c And &HE0) = &HC0 Then c = c And (Not &HE0) c <<= 8 c += Convert.ToInt32(readStr(1)) & &HFF c <<= 8 c += Convert.ToInt32(readStr(1)) & &HFF ElseIf (c & &HF0) = &HE0 Then c &= (Not &HF0) c <<= 8 c += Convert.ToInt32(readStr(1)) & &HFF c <<= 8 c += Convert.ToInt32(readStr(1)) & &HFF c <<= 8 c += Convert.ToInt32(readStr(1)) & &HFF ElseIf (c & &HF8 ) = &HF0 Then c = Convert.ToInt32(readStr(1)) & &HFF c <<= 8 c += Convert.ToInt32(readStr(1)) & &HFF c <<= 8 c += Convert.ToInt32(readStr(1)) & &HFF c <<= 8 c += Convert.ToInt32(readStr(1)) & &HFF End If
Return c End Function
Public Sub writeStr(ByVal str As String) Dim writebuffer(Len(str)) As Byte
writebuffer = System.Text.Encoding.ASCII.GetBytes(str) If writebuffer.Length = 0 Then Exit Sub thisStream.Write(writebuffer, 0, writebuffer.Length) End Sub
Public Function readStr(ByVal length) As Byte() Dim readbuffer(4096) As Byte Dim s As Integer Dim xs As Integer = 0
Do If thisStream.DataAvailable = True Then Exit Do If xs >= 600000 Then Exit Do xs += 1 Loop
If thisStream.DataAvailable = False Then Array.Resize(readbuffer, 0) Return readbuffer End If If length > 0 Then s = thisStream.Read(readbuffer, 0, length) If s = 0 Then Array.Resize(readbuffer, 0)
Return readbuffer End Function
End Class
' ******* Sample:
Dim myipaddr As System.Net.IPAddress = System.Net.IPAddress.Parse("10.10.10.1") Dim mysock As System.Net.Sockets.Socket = New System.Net.Sockets.Socket(myipaddr.AddressFamily, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp) Dim myendpoint As System.Net.IPEndPoint = New System.Net.IPEndPoint(myipaddr, 8728)
mysock.Connect(myendpoint) Dim mystream As System.Net.Sockets.NetworkStream = New System.Net.Sockets.NetworkStream(mysock, True)
Dim apiros As ApiRos = New ApiRos(mysock) apiros.login("Admin", "PaSsWoRd")
Dim xwords(2) As String xwords(0) = "/tool/user-manager/user/pr" apiros.writeSentence(xwords)
Dim attr(1024) As String, aval(1024) As String Dim attrcount As Integer = 0 Dim ist As String Do While 1 ist = apiros.readSentence() If Len(ist) = 0 Then attr(attrcount) = "" aval(attrcount) = "" Exit Sub End If Loop
I think that problem is here: ASCIIEncoding.ASCII.GetBytes("00" + StringToHex(password) + ret);
Is "ASCIIEncoding.ASCII.GetBytes()" c# built in function? If so then you should write your own. Check out what value is returned by this function, probably it's not correct.
If you use Indy10, (downloadable for free) you can do something similar like I do in Delphi(Pascal): (Unedited)
function StrToHex(O:String):String; var i : Integer; begin Result:=''; for i:=1 to Length(O) do begin Result:=Result+lowercase(IntToHex(Integer(O[i]),2)); end; end;
Function GetMD5(Source:String):String; var MD5:TIdHashMessageDigest5; begin MD5:=TIdHashMessageDigest5.Create; try Result:=MD5.AsHex(MD5.HashValue(Source)); finally MD5.Free; end; end;
function TMikrotikAPI.Connect(TCPClient:TidTCPClient;Host:String;Port:Integer): Boolean; begin try Response.Clear; Log .Clear; Client:=TCPClient; Client.Host:=Host; Client.Port:=Port; Client.Connect; Result:=True except Result:=False; end; end;
function TMikrotikAPI.LogOn(Username,Password:String): Boolean; var S : String; IC: TIdOTPCalculator; begin Write('/login'); S:=ReadStr; (*!done*) S:=ReadStr; (*=ret*) ReadStr; (*0*)
Public Function GetDigest(ByVal ret As String, ByVal password As String) As String
Dim retbytes() As Byte = h2a("00" & StringToHex(password) & ret) 'convert hexadecimal string to ascii bytes Using md5 As New System.Security.Cryptography.MD5CryptoServiceProvider() Return "00" & a2h(md5.ComputeHash(retbytes)).ToLower End Using
End Function
Code:
Private Function StringToHex(ByVal password As String) As String Dim retString As String = "" Dim stringBytes() As Byte = System.Text.ASCIIEncoding.ASCII.GetBytes(password) Dim i As Integer = 0 For i = 0 To stringBytes.Length - 1 Dim hexTmp As String = Hex(stringBytes(i)) If hexTmp.Length = 1 Then retString = retString & "0" & hexTmp Else retString = retString & hexTmp End If Next Return retString End Function
Code:
Private Function a2h(ByVal ascii() As Byte) As String Dim i As Integer = 0 Dim ret As String = "" For i = 0 To ascii.Length - 1 Dim tmp As String = Hex(ascii(i)) If tmp.Length = 1 Then ret = ret & "0" & tmp Else ret = ret & tmp End If Next Return ret End Function
Private Function h2a(ByVal hextext As String) As Byte() Dim y As Integer Dim num As String Dim bytes(16) As Byte Dim value As String = "" Dim i As Integer = 0 For y = 0 To 32 num = Mid(hextext, y + 1, 2) value = value & Chr(CInt(Val("&h" & num))) bytes(i) = CByte(Val("&h" & num)) y += 1 i += 1 Next y Return bytes End Function
_________________ Colo and Wholesale Bandwidth Available! Sales at SanDiegoBroadband dot com
I try to make some HotSpotManager software in Delphi. I this post you write some code for connect and login to MT. If you can , please write code for sending commends like add/remove hotspot user, hotspot profile etc. Also you can send me on bojan@fakat.ba
This is taken from the wiki ( everything is explained ). # Protocol stream is formatted as a sequence of words. # Each word is encoded as length, followed by that many bytes of content. # Words are grouped into sentences. End of sentence is terminated by zero length word.
Are you a programmer or what? If you were able to send /login command and get response, then you already did what you are asking for, just check the code.
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum