Page 1 of 1
Mikrotik API and C# ?
Posted: Tue Dec 25, 2007 3:27 pm
by taz
Hi, any example for C-Sharp ?
thx
Re: Mikrotik API and C# ?
Posted: Thu Feb 07, 2008 10:02 am
by janisk
ok it is not C# but plain java example on how to get that
API thing working
http://forum.mikrotik.com/viewtopic.php ... 07#p103407
Re: Mikrotik API and C# ?
Posted: Thu Feb 07, 2008 1:17 pm
by tgrand
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
dsize = readLen()
ReDim readbuffer(dsize)
readbuffer = readStr(dsize)
ret = System.Text.Encoding.ASCII.GetString(readbuffer, 0, dsize)
Debug.Print(">>> " + ret)
Return Trim(ret)
End Function
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
Remember to share..................
Re: Mikrotik API and C# ?
Posted: Thu Feb 07, 2008 9:08 pm
by taz
hi,
can you use this ret,password and generate md5 hash (from your working script)? I check this with my md5 algoritm.
string password = 1234
string ret = 8376e40609025e92aabad58d80600888
string HexPass = Hex(password) // result is 31323334
byte[] Bytes = ASCIIEncoding.ASCII.GetBytes("00" + StringToHex(password) + ret);
byte[] md5Hash = md5.ComputeHash(Bytes);
result = md5.ComputeHash(Bytes);
my result > 36a5dc4461c692a2fde146772beefd50
thx
Re: Mikrotik API and C# ?
Posted: Sun Feb 10, 2008 2:47 pm
by tgrand
You have to use the hex to ascii function.
When I attempted to try ASCIIEncoding.ASCII.GetBytes it did not work.
Re: Mikrotik API and C# ?
Posted: Fri Feb 15, 2008 4:29 pm
by tgrand
Taz,
Did you get it working OK?
I have been using it for some time now, and it works great for me.
Todd
Re: Mikrotik API and C# ?
Posted: Fri Feb 15, 2008 4:40 pm
by taz
no
Re: Mikrotik API and C# ?
Posted: Fri Feb 15, 2008 5:10 pm
by mrz
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.
Re: Mikrotik API and C# ?
Posted: Fri Feb 15, 2008 5:38 pm
by taz
yes,
ASCIIEncoding.ASCII.GetBytes is built in function . If i use System.text.Encoding.GetBytes , result is identical
how i check value form this function ? what confront ?
string ret = "8376e40609025e92aabad58d80600888";
string password = "1234";
StringToHex(password) return 31323334
byte[] Bytes = ASCIIEncoding.ASCII.GetBytes("00" + StringToHex(password) + ret);
byte[] Bytes1 = System.Text.Encoding.ASCII.GetBytes("00" + StringToHex(password) + ret);
byte[] md5Hash = md5.ComputeHash(Bytes);
string md5New = BitConverter.ToString(md5Hash);
byte[] md5Hash1 = md5.ComputeHash(Bytes1);
string md5New1 = BitConverter.ToString(md5Hash1);
first four byte from md5New > 48-48-51-49
md5New return > 36a5dc4461c692a2fde146772beefd50
first four byte from md5New1 > 48-48-51-49
md5New1 return > 36a5dc4461c692a2fde146772beefd50
if a check output from script and sniffer data on mikrotik its right
Re: Mikrotik API and C# ?
Posted: Fri Feb 15, 2008 9:22 pm
by ekkas
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),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*)
S:=Copy(S,6,Length(S));
S:=HexToAscii(S);
S:='=response=00'+GetMD5(#0+password+S);
Write('/login'#13#10'=name='+username+#13#10+S);
Read;
Result:=Response[0]='!done';
end;
If you want more, just ask...
Re: Mikrotik API and C# ?
Posted: Fri Feb 15, 2008 11:42 pm
by changeip
My contribution for
vb.net below:
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
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
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
Re: Mikrotik API and C# ?
Posted: Tue Mar 04, 2008 4:32 pm
by codeb
Question for ekkas
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
P.S. Sorry on bad English
Re: Mikrotik API and C# ?
Posted: Tue Mar 04, 2008 5:35 pm
by mrz
Please read
api documentation:
http://wiki.mikrotik.com/wiki/API
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.
Re: Mikrotik API and C# ?
Posted: Tue Mar 04, 2008 6:49 pm
by ekkas
If you use Indy, you can easily modify my Pascal code above.
Then commands are similar to console.
Re: Mikrotik API and C# ?
Posted: Mon Mar 24, 2008 6:24 pm
by cheesegrits