Community discussions

MikroTik App
 
taz
just joined
Topic Author
Posts: 11
Joined: Thu Feb 03, 2005 6:16 pm

Mikrotik API and C# ?

Tue Dec 25, 2007 3:27 pm

Hi, any example for C-Sharp ?

thx
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: Mikrotik API and C# ?

Thu Feb 07, 2008 10:02 am

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
 
User avatar
tgrand
Long time Member
Long time Member
Posts: 667
Joined: Mon Aug 21, 2006 2:57 am
Location: Winnipeg, Manitoba, Canada

Re: Mikrotik API and C# ?

Thu Feb 07, 2008 1:17 pm

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..................
 
taz
just joined
Topic Author
Posts: 11
Joined: Thu Feb 03, 2005 6:16 pm

Re: Mikrotik API and C# ?

Thu Feb 07, 2008 9:08 pm

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
 
User avatar
tgrand
Long time Member
Long time Member
Posts: 667
Joined: Mon Aug 21, 2006 2:57 am
Location: Winnipeg, Manitoba, Canada

Re: Mikrotik API and C# ?

Sun Feb 10, 2008 2:47 pm

You have to use the hex to ascii function.
When I attempted to try ASCIIEncoding.ASCII.GetBytes it did not work.
 
User avatar
tgrand
Long time Member
Long time Member
Posts: 667
Joined: Mon Aug 21, 2006 2:57 am
Location: Winnipeg, Manitoba, Canada

Re: Mikrotik API and C# ?

Fri Feb 15, 2008 4:29 pm

Taz,

Did you get it working OK?
I have been using it for some time now, and it works great for me.

Todd
 
taz
just joined
Topic Author
Posts: 11
Joined: Thu Feb 03, 2005 6:16 pm

Re: Mikrotik API and C# ?

Fri Feb 15, 2008 4:40 pm

no :(
 
User avatar
mrz
MikroTik Support
MikroTik Support
Posts: 7188
Joined: Wed Feb 07, 2007 12:45 pm
Location: Latvia
Contact:

Re: Mikrotik API and C# ?

Fri Feb 15, 2008 5:10 pm

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.
 
taz
just joined
Topic Author
Posts: 11
Joined: Thu Feb 03, 2005 6:16 pm

Re: Mikrotik API and C# ?

Fri Feb 15, 2008 5:38 pm

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

:(
 
ekkas
Long time Member
Long time Member
Posts: 567
Joined: Mon Sep 26, 2005 1:01 pm
Location: South Africa

Re: Mikrotik API and C# ?

Fri Feb 15, 2008 9:22 pm

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...
 
changeip
Forum Guru
Forum Guru
Posts: 3833
Joined: Fri May 28, 2004 5:22 pm

Re: Mikrotik API and C# ?

Fri Feb 15, 2008 11:42 pm

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
 
codeb
just joined
Posts: 7
Joined: Fri Jun 08, 2007 4:48 pm

Re: Mikrotik API and C# ?

Tue Mar 04, 2008 4:32 pm

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
 
User avatar
mrz
MikroTik Support
MikroTik Support
Posts: 7188
Joined: Wed Feb 07, 2007 12:45 pm
Location: Latvia
Contact:

Re: Mikrotik API and C# ?

Tue Mar 04, 2008 5:35 pm

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.
 
ekkas
Long time Member
Long time Member
Posts: 567
Joined: Mon Sep 26, 2005 1:01 pm
Location: South Africa

Re: Mikrotik API and C# ?

Tue Mar 04, 2008 6:49 pm

If you use Indy, you can easily modify my Pascal code above.
Then commands are similar to console.
 
cheesegrits
just joined
Posts: 16
Joined: Fri Jun 01, 2007 11:17 pm

Re: Mikrotik API and C# ?

Mon Mar 24, 2008 6:24 pm

FYI, I posted a perl API client here:

http://forum.mikrotik.com/viewtopic.php?f=9&t=22744

-- hugh

Who is online

Users browsing this forum: arcc, dmho, doka, jvanhambelgium, mkx, Renfrew, seriosha, Techsystem and 36 guests