Wednesday, May 1, 2013

Hydroponic Plant pH and TDS

No comments :
List Hydroponic Plant for pH, cF, EC, and PPM meaasurement. Use your measurement tools to check your fertilizer.

PlantspHcFECPPM
Ambra radicchio5.5-6.5
Artichoke6.5-7.58-180.8-1.8560-1260
Asparagus6.0-6.814-181.4-1.8980-1260
Bean (Common)6.020-402-41400-2800
Beans (Italian bush) 6.0-6.5
Beans (Lima)6.0-6.5
Beans(Pole)6.0-6.5
Beetroot6.0-6.58-500.8-51260-3500
Broad Bean6.0-6.518-221.8-2.21260-1540
Broccoli6.0-6.528-352.8-3.51960-2450
Brussell Sprout6.5-7.525-302.5-3.01750-2100
Cabbage6.5-7.025-302.5-3.01750-2100
Capsicum6.0-6.518-221.8-2.21260-1540
Carrots6.316-201.6-2.01120-1400
Cauliflower6.0-7.05-200.5-2.01050-1400
Celery6.518-241.8- 2.41260-1680
Collardgreens6.5-7.5
Cucumber5.8-6.017-251.7-2.51190-1750
Eggplant5.5-6.525-352.5-3.51750-2450
Endive5.520-242.0-2.41400-1680
Fodder6.018-201.8-2.01260-1400
Garlic6.014-181.4-1.8980-1260
Leek6.5-7.014-181.4-1.8980-1260
Lettuce5.5-6.58-120.8-1.2560-840
Marrow6.018-241.8-2.41260-1680
Okra6.520-242.0-2.41400-1680
Onions6.0-6.714-181.4-1.8980-1260
Pak-choi7.015-201.5-2.01050-1400
Parsnip6.014-181.4-1.8980-1260
Pea6.0-7.08-180.8-1.8980-1260
Peas (Sugar)6.0-6.8
Pepino6.0-6.520-502.0-5.01400-3500
Peppers5.8-6.3
Bell peppers6.0-6.5
Hot Peppers6.0-6.5
Potato5.0-6.020-252.0-2.51400-1750
Pumpkin5.5-7.518-241.8-2.41260-1680
Radish6.0-7.016-221.6-2.2840-1540
Spinach5.5-6.618-231.8-2.31260-1610
Silverbeet6.0-7.018-231.8-2.31260-1610
Sweet Corn6.016-241.6-2.4840-1680
Sweet Potato5.5-6.020-252.0-2.51400-1750
Swisschard6.0 6.5
Squash (Summer)5.0-6.5
Squash (Winter)5.0-6.5
Taro5.0-5.525-302.5-3.01750-2100
Tomato5.5-6.520-502.0-5.01400-3500
Turnip6.0-6.518-241.8-2.41260-1680
Zucchini6.018-241.8-2.41260-1680
Read More

Tuesday, January 8, 2013

Gora, my old cat

No comments :
image



image



Thats my cat pictures, he was sick very badly... and whenever I take him to vet, all vet is not available... but I found people that know much about cat... So I give Gora to him, cause I know I cannot take care of him... very sad decission but thats good for Gora...
Read More

List Variable Global $_SERVER pada PHP 5

No comments :
PHP memiliki beberapa variable global yang jarang di perhatikan (ane sendiri kale....), salah satu varible global yang perlu diperhatikan lebih adalah $_SERVER. Mengapa? Karena begini gan... Situs php.net menjelaskan bahwa $_SERVER berisi informasi mengenai header, lokasi path, dan lokasi script yang dibangun oleh web server, sehingga informasi mengenai user yang mengakses web server dan apa yang sedang dijalankan web server bisa di dapatkan datanya menggunakan variable $_SERVER.

okeh tanpa bertele - tele lagi langsung saja jalankan script dibawah ini pada web server local anda...


';
echo '$_SERVER[\'PHP_SELF\']            : '.$_SERVER['PHP_SELF']." 
";
echo '$_SERVER[\'GATEWAY_INTERFACE\']   : '.$_SERVER['GATEWAY_INTERFACE']." 
";
echo '$_SERVER[\'SERVER_ADDR\']         : '.$_SERVER['SERVER_ADDR']." 
";
echo '$_SERVER[\'SERVER_NAME\']         : '.$_SERVER['SERVER_NAME']." 
";
echo '$_SERVER[\'SERVER_SOFTWARE\']     : '.$_SERVER['SERVER_SOFTWARE']." 
";
echo '$_SERVER[\'SERVER_PROTOCOL\']     : '.$_SERVER['SERVER_PROTOCOL']." 
";
echo '$_SERVER[\'REQUEST_METHOD\']      : '.$_SERVER['REQUEST_METHOD']." 
";
echo '$_SERVER[\'REQUEST_TIME\']        : '.$_SERVER['REQUEST_TIME']." 
";
echo '$_SERVER[\'QUERY_STRING\']        : '.$_SERVER['QUERY_STRING']." 
";
echo '$_SERVER[\'DOCUMENT_ROOT\']       : '.$_SERVER['DOCUMENT_ROOT']." 
";
echo '$_SERVER[\'HTTP_ACCEPT\']         : '.$_SERVER['HTTP_ACCEPT']." 
";
echo '$_SERVER[\'HTTP_ACCEPT_ENCODING\']    : '.$_SERVER['HTTP_ACCEPT_ENCODING']." 
";
echo '$_SERVER[\'HTTP_ACCEPT_LANGUAGE\']    : '.$_SERVER['HTTP_ACCEPT_LANGUAGE']." 
";
echo '$_SERVER[\'HTTP_CONNECTION\']         : '.$_SERVER['HTTP_CONNECTION']." 
";
echo '$_SERVER[\'HTTP_HOST\']           : '.$_SERVER['HTTP_HOST']." 
";
echo '$_SERVER[\'HTTP_USER_AGENT\']     : '.$_SERVER['HTTP_USER_AGENT']." 
";
echo '$_SERVER[\'REMOTE_ADDR\']         : '.$_SERVER['REMOTE_ADDR']." 
";
echo '$_SERVER[\'REMOTE_PORT\']         : '.$_SERVER['REMOTE_PORT']." 
";
echo '$_SERVER[\'SERVER_ADMIN\']        : '.$_SERVER['SERVER_ADMIN']." 
";
echo '$_SERVER[\'SERVER_PORT\']         : '.$_SERVER['SERVER_PORT']." 
";
echo '$_SERVER[\'SERVER_SIGNATURE\']    : '.$_SERVER['SERVER_SIGNATURE']." 
";
echo '$_SERVER[\'SCRIPT_NAME\']         : '.$_SERVER['SCRIPT_NAME']." 
";
echo '$_SERVER[\'REQUEST_URI\']         : '.$_SERVER['REQUEST_URI']." 
";
?>
output :
//List Variable $_SERVER 
$_SERVER['PHP_SELF']      : /test.php 
$_SERVER['GATEWAY_INTERFACE']    : CGI/1.1 
$_SERVER['SERVER_ADDR']     : ::1 
$_SERVER['SERVER_NAME']     : localhost 
$_SERVER['SERVER_SOFTWARE']     : Apache 
$_SERVER['SERVER_PROTOCOL']     : HTTP/1.1 
$_SERVER['REQUEST_METHOD']     : GET 
$_SERVER['REQUEST_TIME']     : 1334284051 
$_SERVER['QUERY_STRING']     : vthink=5&team=5 
$_SERVER['DOCUMENT_ROOT']     : /Applications/MAMP/htdocs 
$_SERVER['HTTP_ACCEPT']     : text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
$_SERVER['HTTP_ACCEPT_ENCODING']    : gzip, deflate 
$_SERVER['HTTP_ACCEPT_LANGUAGE']    : en-us 
$_SERVER['HTTP_CONNECTION']     : keep-alive 
$_SERVER['HTTP_HOST']     : localhost 
$_SERVER['HTTP_USER_AGENT']     : Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/534.51.22 (KHTML, like Gecko) Version/5.1.1 Safari/534.51.22 
$_SERVER['REMOTE_ADDR']     : ::1 
$_SERVER['REMOTE_PORT']     : 50032 
$_SERVER['SERVER_ADMIN']     : you@example.com 
$_SERVER['SERVER_PORT']     : 80 
$_SERVER['SERVER_SIGNATURE']     :  
$_SERVER['SCRIPT_NAME']     : /test.php 
$_SERVER['REQUEST_URI']     : /test.php?vthink=5&team=5
Nah, informasi yang anda lihat pada hasil output yang ditampilkan pada output diatas tentunya tidak sama dengan output pada web server local anda. Jadi, informasi yang dihasilkan oleh web server anda tergantung pada siapa yang membuka dan web server apa yang anda gunakan. Seperti pada bagian $_SERVER['HTTP_USER_AGENT'] anda bisa melihat bahwa saya sedang menggunakan web browser safari dengan system operasi Mac OSX versi Intel Max OS X 10.7.2. Kemudian pada output $_SERVER['REQUEST_URI'] anda bisa melihat saya mengakses melalui web browser dengan url /test.php?vthink=5&team=5 (yups, coz ane jalanin di http://localhost/test.php?vthink=5&team=5)..... Jika anda ingin mempersingkat penulisan sintaks diatas dan melihat beberapa variable $_SERVER yang belum ane tulis, silahkah tulis sintaks di bawah ini :

<PRE>

<?php

print_r($_SERVER);

?> 

</PRE>

output :

Array

(

[HTTP_HOST] => localhost

[HTTP_USER_AGENT] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/534.51.22 (KHTML, like Gecko) Version/5.1.1 Safari/534.51.22

[HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

[HTTP_CACHE_CONTROL] => max-age=0

[HTTP_ACCEPT_LANGUAGE] => en-us

[HTTP_ACCEPT_ENCODING] => gzip, deflate

[HTTP_CONNECTION] => keep-alive

[PATH] => /bin:/sbin:/usr/bin:/usr/sbin:/usr/libexec:/System/Library/CoreServices

[SERVER_SIGNATURE] => 

[SERVER_SOFTWARE] => Apache

[SERVER_NAME] => localhost

[SERVER_ADDR] => ::1

[SERVER_PORT] => 80

[REMOTE_ADDR] => ::1

[DOCUMENT_ROOT] => /Applications/MAMP/htdocs

[SERVER_ADMIN] => you@example.com

[SCRIPT_FILENAME] => /Applications/MAMP/htdocs/test.php

[REMOTE_PORT] => 50164

[GATEWAY_INTERFACE] => CGI/1.1

[SERVER_PROTOCOL] => HTTP/1.1

[REQUEST_METHOD] => GET

[QUERY_STRING] => vthink=5&team=5

[REQUEST_URI] => /test.php?vthink=5&team=5

[SCRIPT_NAME] => /test.php

[PHP_SELF] => /test.php

[REQUEST_TIME] => 1334284637

[argv] => Array

(

[0] => vthink=5&team=5

)



[argc] => 1

)

Okey, silahkan mencoba dan semoga beberapa variable diatas bisa bermanfaat untuk anda gunakan pada aplikasi web yang anda bangun (terutama yang tidak menggunakan framework)... sumber : http://www.php.net/manual/en/reserved.variables.server.php
Read More

Instalasi CodeIgniter Spark pada Ubuntu

No comments :
Salah satu framework PHP tercepat di dunia yang dinyatakan oleh founder bahasa pemrograman PHPRasmus Ledorf, telah merelease package management system yang dikenal dengan spark. Spark merupakan sebuah inovasi pemrograman pada CodeIgniter, karena dengan menggunakan spark programmer tidak perlu repot - repot menambah library pada codeigniter. Semua library bisa di install dengan menggunakan terminal pada Linux atau command prompt pada Windows. Dukungan list repository  pada situs http://getsparks.org memudahkan programmer untuk mencari library - library yang akan digunakan untuk integrasi maupun pengembangan aplikasi web yang mereka bangun.



Okey mari kita coba install spark, tetapi langkah yang saya bahas hanya berlaku pada sistem operasi linux.

Langkah pertama lakukan instalasi paket php5-curl agar spark paket management bisa digunakan oleh codeigniter spark:

apt-get install php5-curl

Setelah itu restart service apache anda dengan sitaks berikut ini :


service apache2 restart

Setelah itu, Download CodeIgniter Reactor pada link berikut ini : CodeIgniter-Reactor-v.2.0.3
Kemudian ekstrak file tersebut pada directory apache anda, misalnya seperti /var/www/ dan setelah itu ketik pada terminal anda perintah berikut ini :

cd /var/www/codeigniter/
php -r "$(curl -fsSL http://getsparks.org/go-sparks)"

Okey jika anda telah selesai maka sekarang anda bisa melakukan instalasi contoh paket spark dengan perintah berikut ini :

php tools/spark install -v1.0.0 example-spark



dalam proses instalasi kemungkinan anda akan melihat output pada terminal seperti ini :


[ SPARK ]  Retrieving spark detail from getsparks.org
[ SPARK ]  From Downtown! Retrieving spark from Mercurial repository at https://github.com/katzgrau/example-spark
[ SPARK ]  Installing spark
[ SPARK ]  Spark installed to ./sparks/example-spark/1.0.0 - You're on fire!

Okey, coba anda perhatikan susunan folder anda pada /var/www/codeigniter/, anda mungkin akan melihat susunan folder yang seperti berikut ini :
/var/www/codeigniter/application
/var/www/codeigniter/sparks
/var/www/codeigniter/system
/var/www/codeigniter/tools
/var/www/codeigniter/user_guide

okey, paket example-spark yang telah anda install dengan terminal tadi sudah berada pada folder /var/www/codeigniter/sparks/example-spark. soo, what the next??

selanjutnya adalah memanggil paket spark tadi dengan sintaks berikut pada controller anda :

Salah satu framework PHP tercepat di dunia yang dinyatakan oleh founder bahasa pemrograman PHPRasmus Ledorf, telah merelease package management system yang dikenal dengan spark. Spark merupakan sebuah inovasi pemrograman pada CodeIgniter, karena dengan menggunakan spark programmer tidak perlu repot - repot menambah library pada codeigniter. Semua library bisa di install dengan menggunakan terminal pada Linux atau command prompt pada Windows. Dukungan list repository  pada situs http://getsparks.org memudahkan programmer untuk mencari library - library yang akan digunakan untuk integrasi maupun pengembangan aplikasi web yang mereka bangun.



Okey mari kita coba install spark, tetapi langkah yang saya bahas hanya berlaku pada sistem operasi linux.

Langkah pertama lakukan instalasi paket php5-curl agar spark paket management bisa digunakan oleh codeigniter spark:
apt-get install php5-curl

Setelah itu restart service apache anda dengan sitaks berikut ini :
service apache2 restart

Setelah itu, Download CodeIgniter Reactor pada link berikut ini : CodeIgniter-Reactor-v.2.0.3
Kemudian ekstrak file tersebut pada directory apache anda, misalnya seperti /var/www/ dan setelah itu ketik pada terminal anda perintah berikut ini :
cd /var/www/codeigniter/
php -r "$(curl -fsSL http://getsparks.org/go-sparks)"

Okey jika anda telah selesai maka sekarang anda bisa melakukan instalasi contoh paket spark dengan perintah berikut ini :
php tools/spark install -v1.0.0 example-spark

dalam proses instalasi kemungkinan anda akan melihat output pada terminal seperti ini :

[ SPARK ]  Retrieving spark detail from getsparks.org
[ SPARK ]  From Downtown! Retrieving spark from Mercurial repository at https://github.com/katzgrau/example-spark
[ SPARK ]  Installing spark
[ SPARK ]  Spark installed to ./sparks/example-spark/1.0.0 - You're on fire!

Okey, coba anda perhatikan susunan folder anda pada /var/www/codeigniter/, anda mungkin akan melihat susunan folder yang seperti berikut ini :
/var/www/codeigniter/application
/var/www/codeigniter/sparks
/var/www/codeigniter/system
/var/www/codeigniter/tools
/var/www/codeigniter/user_guide

okey, paket example-spark yang telah anda install dengan terminal tadi sudah berada pada folder /var/www/codeigniter/sparks/example-spark. soo, what the next??

selanjutnya adalah memanggil paket spark tadi dengan sintaks berikut pada controller anda :

$this->load->sparks('example-spark/1.0.0');



ATAU

jika ingin menjalankan secara otomatis gunakan autoload pada folder /var/www/codeigniter/config/autoload.php, dan tambahkan sintaks berikut ini :

    $autoload['sparks']=array('example-spark/1.0.0');

Sekarang anda siap untuk beraksi...
silah mencoba.....

referensi : getsparks.org $this->load->sparks('example-spark/1.0.0');

ATAU

jika ingin menjalankan secara otomatis gunakan autoload pada folder /var/www/codeigniter/config/autoload.php, dan tambahkan sintaks berikut ini :

    $autoload['sparks']=array('example-spark/1.0.0');

Sekarang anda siap untuk beraksi...
silah mencoba.....

referensi : getsparks.org
Read More

Enkripsi MD5 dengan Java

No comments :
Okeh bagi - bagi source lagi ney... ane mau bagi enkripsi MD5 untuk agan - agan sekalian... tapi Enkripsi MD5 ini hanya untuk text aja, kalau untuk file silahkan kembangkan lagi dengan class FileInputStream dan StringBuilder... Java juga mendukung banyak jenis enkripsi pada kelasMesageDiggest dengan method getInstance(); . Soo silahkan coba - coba untuk membuat enkripsi yang lain. Suatu saat mungkin anda membutuhkan class yang telah anda buat.

Okeh ini sourcenya :

[sourcecode language="java"]
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
*
* @author Lalu Erfandi Maula Yusnu
*/
public class ConverterUtil {

/**
* This nethod is used for encrypt String to MD5
* @param text String
* @return String
*/
public static String MD5(String text){
String output = null;
try {
MessageDigest dg = MessageDigest.getInstance("MD5");
dg.reset();
dg.update(stringToBytes(text));
byte[] hasher = new byte[32];
hasher = dg.digest();
return bytesToHexString(hasher);
} catch (NoSuchAlgorithmException e) {
System.out.println("There is No MessageDigest Instance of MD5");
System.exit(1);
}

return output;
}

/**
* This method used for converting byte array to hex string
*
* @param hasher byte[]
* @return String
*/
public static String bytesToHexString(byte[] hasher){
String HEXES = "0123456789abcdef";
StringBuilder hex = new StringBuilder( 2 * hasher.length );
for ( final byte b : hasher ) {
hex.append(HEXES.charAt((b & 0xF0) >> 4))
.append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}

/**
* This method used for converting byte array to string
* @param hasher byte[]
* @return String
*/
public static String bytesToString(byte[] hasher){
String hex = bytesToHexString(hasher);
return hexToString(hex);
}

/**
* This method used for converting string to bytes
* @param str String
* @return byte[]
*/
public static byte[] stringToBytes(String str){
int len = str.length();
byte[] out = new byte[len];
for (int i=0; i<len; i++) out[i] = (byte) ( str.charAt(i) & 0xFF);
return out;
}


/**
* This method used for converting hex to string
* @param hexString String
* @return String
*/
public static String hexToString(String hexString){
StringBuilder sb = new StringBuilder();
for(int i=0; i<hexString.length()-1; i+=2 ){
int decimal = Integer.parseInt(hexString.substring(i, (i + 2)), 16);
sb.append((char)decimal);
}
return sb.toString();
}

}
[/sourcecode]

nah untuk menggunakan source ini ini sintaksnya:

[sourcecode language="java"]
Public class Test {
public static void main(String[] args){
String text="Ini text yang akan di enkripsi dengan MD5";
String md5 = ConverterUtil.MD5(text);
System.out.println(md5);
}
}
[/sourcecode]

Hasilnya kurang lebih seperti ini :
6ddc9d6e411d0dfe769750b07d5ffb08

Semoga bermanfaat, sekian dan terima kasih....
Read More

Ngoprek MikroTik Api Client Berbasis Python

No comments :
Okeh, jika anda ingin menjadi pengembang MikroTik API client sepertinya anda perlu mencoba MikroTik API client berbasis python untuk melakukan reverse engineering. Langkah ini diperlukan untuk mengetahui setiap inputan dan hasilnya...

Okeh script ini ane ambil dari http://wiki.mikrotik.com/wiki/Manual:API pada bagian paling bawah, berikut ini  scriptnya :

[sourcecode language="python"]
#!/usr/bin/python

import sys, posix, time, md5, binascii, socket, select

class ApiRos:
"Routeros api"
def __init__(self, sk):
self.sk = sk
self.currenttag = 0

def login(self, username, pwd):
for repl, attrs in self.talk(["/login"]):
chal = binascii.unhexlify(attrs['=ret'])
md = md5.new()
md.update('\x00')
md.update(pwd)
md.update(chal)
self.talk(["/login", "=name=" + username,
"=response=00" + binascii.hexlify(md.digest())])

def talk(self, words):
if self.writeSentence(words) == 0: return
r = []
while 1:
i = self.readSentence();
if len(i) == 0: continue
reply = i[0]
attrs = {}
for w in i[1:]:
j = w.find('=', 1)
if (j == -1):
attrs[w] = ''
else:
attrs[w[:j]] = w[j+1:]
r.append((reply, attrs))
if reply == '!done': return r

def writeSentence(self, words):
ret = 0
for w in words:
self.writeWord(w)
ret += 1
self.writeWord('')
return ret

def readSentence(self):
r = []
while 1:
w = self.readWord()
if w == '': return r
r.append(w)

def writeWord(self, w):
print "<<< " + w self.writeLen(len(w)) self.writeStr(w) def readWord(self): ret = self.readStr(self.readLen()) print ">>> " + ret
return ret

def writeLen(self, l):
if l < 0x80:
self.writeStr(chr(l))
elif l < 0x4000: l |= 0x8000 self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))
elif l < 0x200000: l |= 0xC00000 self.writeStr(chr((l >> 16) & 0xFF))
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))
elif l < 0x10000000: l |= 0xE0000000 self.writeStr(chr((l >> 24) & 0xFF))
self.writeStr(chr((l >> 16) & 0xFF))
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))
else:
self.writeStr(chr(0xF0))
self.writeStr(chr((l >> 24) & 0xFF))
self.writeStr(chr((l >> 16) & 0xFF))
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))

def readLen(self):
c = ord(self.readStr(1))
if (c & 0x80) == 0x00:
pass
elif (c & 0xC0) == 0x80:
c &= ~0xC0
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xE0) == 0xC0:
c &= ~0xE0
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xF0) == 0xE0:
c &= ~0xF0
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xF8) == 0xF0:
c = ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
return c

def writeStr(self, str):
n = 0;
while n < len(str):
r = self.sk.send(str[n:])
if r == 0: raise RuntimeError, "connection closed by remote end"
n += r

def readStr(self, length):
ret = ''
while len(ret) < length:
s = self.sk.recv(length - len(ret))
if s == '': raise RuntimeError, "connection closed by remote end"
ret += s
return ret

def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], 8728))
apiros = ApiRos(s);
apiros.login(sys.argv[2], sys.argv[3]);

inputsentence = []

while 1:
r = select.select([s, sys.stdin], [], [], None)
if s in r[0]:
# something to read in socket, read sentence
x = apiros.readSentence()

if sys.stdin in r[0]:
# read line from input and strip off newline
l = sys.stdin.readline()
l = l[:-1]

# if empty line, send sentence and start with new
# otherwise append to input sentence
if l == '':
apiros.writeSentence(inputsentence)
inputsentence = []
else:
inputsentence.append(l)

if __name__ == '__main__':
main()
[/sourcecode]

Simpan file diatas dengan nama routeros.py, dan untuk menjalankan nya masukan perintah berikut ini :

[sourcecode language="bash"]
chmod 777 routeros.py
python routeros.py 192.168.88.1 admin admin
[/sourcecode]


jika login anda benar maka akan muncul hasil seperti dibawah ini :

[sourcecode language="bash"]
<<< /login
<<< >>> !done
>>> =ret=3febe34367f76733cbece5c7822ebf7c
>>>
<<< /login
<<< =name=admin
<<< =response=0043af609b070655d06d5c1a7984377b6f
<<< >>> !done
>>>
[/sourcecode]

dan jika password anda salah maka akan tampil pesan berikut ini :

[sourcecode language="bash"]
<<< /login
<<< >>> !done
>>> =ret=8b5b3964ffd9422d920b6497960bfddd
>>>
<<< /login
<<< =name=admin
<<< =response=00f3f3219cdea9fc3861b19551f3457af6
<<< >>> !trap
>>> =message=cannot log in
>>>
>>> !done
>>>
[/sourcecode]

Okey, sekarang mari mencoba menampilakan semua interface pada mikrotik dengan MikroTik API client berbasis python ini. Ketik perintah dibawah ini dan ketik enter :

[sourcecode language="bash"]
/interface/print
[/sourcecode]

pada laptop ane muncul nya seperti ini,:

[sourcecode language="bash"]
/interface/print

<<< /interface/print
<<< >>> !re
>>> =.id=*1
>>> =comment=
>>> =name=ether1
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*2
>>> =comment=
>>> =name=ether2
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*3
>>> =comment=
>>> =name=ether3
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*4
>>> =comment=
>>> =name=ether4
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*5
>>> =comment=
>>> =name=ether5
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*6
>>> =comment=
>>> =name=vlan1
>>> =mtu=1500
>>> =type=vlan
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*7
>>> =comment=
>>> =name=vrrp1
>>> =mtu=1500
>>> =type=vrrp
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*8
>>> =comment=
>>> =name=vlan2
>>> =mtu=1500
>>> =type=vlan
>>> =dynamic=false
>>> =running=true
>>>
>>> !done
>>>
[/sourcecode]

bagaimana dengan laptop anda.....??? pengen tau, coba aja di ketik ...
Okey, kalau laptop ane, ada banyak interface yang sudah di add, jadi untuk memilih interface secara spesifik ketik perintah berikut :

[sourcecode language="bash"]
/interface/print
?=type=vlan
[/sourcecode]

Hasilnya anda akan menampilkan interface yang type vlan saja, berikut ini hasilnya :

[sourcecode language="bash"]
/interface/print
?=type=vlan

<<< /interface/print
<<< ?=type=vlan
<<< >>> !re
>>> =.id=*6
>>> =comment=
>>> =name=vlan1
>>> =mtu=1500
>>> =type=vlan
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*8
>>> =comment=
>>> =name=vlan2
>>> =mtu=1500
>>> =type=vlan
>>> =dynamic=false
>>> =running=true
>>>
>>> !done
>>>
[/sourcecode]

Okeh, sekarang bagaimana kalau ingin menampilkan interface ether1 dan ether2? coba ketik perintah berikut ini :

[sourcecode language="bash"]
/interface/print
?=name=ether1
?=name=ether2
?#|
[/sourcecode]

Hasilnya akan seperti ini :

[sourcecode language="bash"]
<<< /interface/print
<<< ?=name=ether1
<<< ?=name=ether2
<<< ?#|
<<< >>> !re
>>> =.id=*1
>>> =comment=
>>> =name=ether1
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*2
>>> =comment=
>>> =name=ether2
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !done
>>>
[/sourcecode]

Okeh, sekali lagi, bagaimana kalau ingin menampilkan interface ether saja dan selain daripada ether1 dan ether2? coba ketik perintah ini :

[sourcecode language="bash"]
/interface/print
?=type=ether
?#&
?=name=ether1
?#!
?=name=ether2
?#!
[/sourcecode]

maka hasilnya akan seperti dibawah ini :

[sourcecode language="bash"]
<<< /interface/print
<<< ?=type=ether
<<< ?#&
<<< ?=name=ether1
<<< ?#!
<<< ?=name=ether2
<<< ?#!
<<< >>> !re
>>> =.id=*3
>>> =comment=
>>> =name=ether3
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*4
>>> =comment=
>>> =name=ether4
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*5
>>> =comment=
>>> =name=ether5
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !done
>>>
[/sourcecode]

Mengapa hasilnya bisa seperti itu ??? bagaimana rumusan nya??? Topik apa yang sedang kita bahas saat ini???
Okey, jadi yang sedang ane uji coba sekarang ini adalah tentang MikroTik API bagian Queries yang hanya disupport pada RouterOS versi 3.22 ke atas...
begini rumusan nya (walaupun sebenarnya ane masih belum terlalu faham betul, but ini asumsi ane okeh!!)

kalau berdasarkan situs http://wiki.mikrotik.com/wiki/Manual:API, berikut keterangan nya:
Okeh, jadi kalau di terjemahkan (pake google translate and di perbaiki) :

QUERIES
perintah cetak menerima kata-kata yang telah di kirimkan dan akan mengatur ulang satu set kalimat . Fitur ini tersedia sejak RouterOS 3.21.


Query dimulai dengan tanda '?' (tanpa tanda petik)
Urutan kata - kata Query sifatnya signifikan. Query di evaluasi mulai dari kata pertama.
Query akan di evaluasi pertiap item yang berada dalam daftar, jika query berhasil, item akan diproses dan jika query gagal item akan diabaikan.
Query di evaluasi menggunakan tumpukan (stack) nilai boolean (true/false). Awalnya tumpukan (stack) berisi jumlah nilai 'true' tak terbatas. Pada akhir proses evaluasi, jika tumpukan (stack) berisi setidaknya satu nilai 'false' maka query menjadi gagal.
Pengoperasian kata - kata dalam query adalah berdasar pada aturan berikut ini :































QueryDesciption
?nameStack akan mengirim 'true' jika item mempunyai value (nilai) dari property name, dan Stack akan mengirim 'false' jika hal sebaliknya terjadi.
?-nameStack akan mengirim 'true' jika item tidak memiliki value (nilai) dari property name, dan Stack akan mengirim 'false' jika hal sebaliknya terjadi.
?name=x
?=name=x
Stack akan mengirim 'true' jika property name memiliki value (nilai) sama dengan x, dan Stack akan mengirim 'false' jika hal sebaliknya terjadi.
?<name=xStack akan mengirim 'true' jika property name memiliki nilai kurang dari x, dan Stack akan mengirim 'false' jika hal sebaliknya terjadi.
?>name=xStack akan mengirim 'true' jika property name lebih besar dari x, dan Stack akan mengirim 'false' jika hal sebaliknya terjadi.
?#operationsberikut ini aturan operasi yang berlaku dalam stack: string operasi di evaluasi dari kiri ke kanan.

urutan digit desimal di ikuti dengan sembarang karakter atau akhir kata ditafsirkan sebagai index stack dimana nilai index pada stack pertama adalah 0.

index  yang di ikuti oleh karakter akan mendorong salinan (copy) pada nilai tersebut. index yang di ikuti kata akhiran akan menggantikan semua nilai dengan nilai pada index tersebut.

'!' (not) karakter akan menggantikan nilai atas dengan nilai yang berlawanan dengan nya.

'&' (and) karakter akan membuang dua nilai (value) dan sebagai hasilnya karakter ini akan melakukan operasi logis 'and'.

'|' (or) karakter akan membuang dua nilai (value) dan sebagai hasilnya karakter ini akan melakukan operasi logis 'or'.

'.' (dot) karakter tidak akan menjadikan error

'.' (dot) karakter setelah karakter lain akan mendorong atau mengirim salinan pada nilai di bagian atas.

Audience : Wah masih bingung gan???
Penulis : Tenang ane juga bingung kok, abis bahasanya baku bangets... tapi mari kita bahas sama - sama siapa tau kita bisa mengerti...
jadi begini, misalnya ada sintaks seperti ini:

[sourcecode language="bash"]
/interface/print
?=type=vlan
?=type=ether
?#|
?=name=ether1
?#!
?#&
[/sourcecode]

kemudian misalnya, kita anggap masing - masing baris dengan kode seperti ini :
?=type=vlan adalah P1
?=type=ether adalah P2
?#| adalah L1
?=name=ether1 adalah P3
?#! adalah L2
?#& adalah L3

okey kalau kita susun dalam bentuk ke kanan jadinya seperti ini :
P1 P2 L1 P3 L2 L3

seperti yang telah dijelaskan dalam tabel diatas, setiap operasi yang ditandai dengan ?# maka dia memiliki rumusan sendiri. Dan setelah ane analisa maka bentuk tadi akan diubah menjadi seperti ini :
P1 L1 P2 L3 L2 P3

dan hasilnya akan menjadi seperti sintaks dibawah ini saat dibaca oleh MikroTik RouterOS :

[sourcecode language="bash"]
?=type=vlan
?#|
?=type=ether
?#&
?#!
?=name=ether1
[/sourcecode]

sehingga seolah - olah sintaks yang diterima oleh mikrotik menjadi seperti ini :

[sourcecode language="bash"]
?=type=vlan ?#| ?=type=ether ?#& ?#! ?=name=ether1
[/sourcecode]

masih belibet kan??? sama... tapi mari coba ubah bentuknya agar lebih mudah dimengerti menjadi seperti ini :

[sourcecode language="bash"]
type=vlan or type=ether and name!=ether1
[/sourcecode]

Pertanyaan nya adalah bagaimana bentuk seperti ini bisa di analogikan???
Hal ini karena mikrotik mengimplementasikan stack, yang mana setiap operasi logika and dan or akan membuang dua perintah dari stack dan akan mengubahnya menjadi bentuk operasi logis.
Nah itu asumsi ane... jadi benar atau salahnya masih belum bisa ane pertanggung jawabkan, untuk mendapat contoh - contoh yang lebih banyak silahkan buka link pada wiki mikrotik ini : http://wiki.mikrotik.com/wiki/API_command_notes

Okeh, semoga bermanfaat... sekian dan terima kasih...
Read More

Ngoprek MikroTik API Client Berbasis Python

No comments :
Okeh, jika anda ingin menjadi pengembang MikroTik API client sepertinya anda perlu mencoba MikroTik API client berbasis python untuk melakukan reverse engineering. Langkah ini diperlukan untuk mengetahui setiap inputan dan hasilnya...

Okeh script ini ane ambil dari http://wiki.mikrotik.com/wiki/Manual:API pada bagian paling bawah, berikut ini  scriptnya :

[sourcecode language="python"]
#!/usr/bin/python

import sys, posix, time, md5, binascii, socket, select

class ApiRos:
"Routeros api"
def __init__(self, sk):
self.sk = sk
self.currenttag = 0

def login(self, username, pwd):
for repl, attrs in self.talk(["/login"]):
chal = binascii.unhexlify(attrs['=ret'])
md = md5.new()
md.update('\x00')
md.update(pwd)
md.update(chal)
self.talk(["/login", "=name=" + username,
"=response=00" + binascii.hexlify(md.digest())])

def talk(self, words):
if self.writeSentence(words) == 0: return
r = []
while 1:
i = self.readSentence();
if len(i) == 0: continue
reply = i[0]
attrs = {}
for w in i[1:]:
j = w.find('=', 1)
if (j == -1):
attrs[w] = ''
else:
attrs[w[:j]] = w[j+1:]
r.append((reply, attrs))
if reply == '!done': return r

def writeSentence(self, words):
ret = 0
for w in words:
self.writeWord(w)
ret += 1
self.writeWord('')
return ret

def readSentence(self):
r = []
while 1:
w = self.readWord()
if w == '': return r
r.append(w)

def writeWord(self, w):
print "<<< " + w
self.writeLen(len(w))
self.writeStr(w)

def readWord(self):
ret = self.readStr(self.readLen())
print ">>> " + ret
return ret

def writeLen(self, l):
if l < 0x80:
self.writeStr(chr(l))
elif l < 0x4000:
l |= 0x8000
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))
elif l < 0x200000:
l |= 0xC00000
self.writeStr(chr((l >> 16) & 0xFF))
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))
elif l < 0x10000000:
l |= 0xE0000000
self.writeStr(chr((l >> 24) & 0xFF))
self.writeStr(chr((l >> 16) & 0xFF))
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))
else:
self.writeStr(chr(0xF0))
self.writeStr(chr((l >> 24) & 0xFF))
self.writeStr(chr((l >> 16) & 0xFF))
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))

def readLen(self):
c = ord(self.readStr(1))
if (c & 0x80) == 0x00:
pass
elif (c & 0xC0) == 0x80:
c &= ~0xC0
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xE0) == 0xC0:
c &= ~0xE0
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xF0) == 0xE0:
c &= ~0xF0
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xF8) == 0xF0:
c = ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
return c

def writeStr(self, str):
n = 0;
while n < len(str):
r = self.sk.send(str[n:])
if r == 0: raise RuntimeError, "connection closed by remote end"
n += r

def readStr(self, length):
ret = ''
while len(ret) < length:
s = self.sk.recv(length - len(ret))
if s == '': raise RuntimeError, "connection closed by remote end"
ret += s
return ret

def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], 8728))
apiros = ApiRos(s);
apiros.login(sys.argv[2], sys.argv[3]);

inputsentence = []

while 1:
r = select.select([s, sys.stdin], [], [], None)
if s in r[0]:
# something to read in socket, read sentence
x = apiros.readSentence()

if sys.stdin in r[0]:
# read line from input and strip off newline
l = sys.stdin.readline()
l = l[:-1]

# if empty line, send sentence and start with new
# otherwise append to input sentence
if l == '':
apiros.writeSentence(inputsentence)
inputsentence = []
else:
inputsentence.append(l)

if __name__ == '__main__':
main()
[/sourcecode]

Simpan file diatas dengan nama routeros.py, dan untuk menjalankan nya masukan perintah berikut ini :

[sourcecode language="bash"]
chmod 777 routeros.py
python routeros.py 192.168.88.1 admin admin
[/sourcecode]

[source
jika login anda benar maka akan muncul hasil seperti dibawah ini :
Read More

Wednesday, May 1, 2013

Hydroponic Plant pH and TDS

List Hydroponic Plant for pH, cF, EC, and PPM meaasurement. Use your measurement tools to check your fertilizer.

PlantspHcFECPPM
Ambra radicchio5.5-6.5
Artichoke6.5-7.58-180.8-1.8560-1260
Asparagus6.0-6.814-181.4-1.8980-1260
Bean (Common)6.020-402-41400-2800
Beans (Italian bush) 6.0-6.5
Beans (Lima)6.0-6.5
Beans(Pole)6.0-6.5
Beetroot6.0-6.58-500.8-51260-3500
Broad Bean6.0-6.518-221.8-2.21260-1540
Broccoli6.0-6.528-352.8-3.51960-2450
Brussell Sprout6.5-7.525-302.5-3.01750-2100
Cabbage6.5-7.025-302.5-3.01750-2100
Capsicum6.0-6.518-221.8-2.21260-1540
Carrots6.316-201.6-2.01120-1400
Cauliflower6.0-7.05-200.5-2.01050-1400
Celery6.518-241.8- 2.41260-1680
Collardgreens6.5-7.5
Cucumber5.8-6.017-251.7-2.51190-1750
Eggplant5.5-6.525-352.5-3.51750-2450
Endive5.520-242.0-2.41400-1680
Fodder6.018-201.8-2.01260-1400
Garlic6.014-181.4-1.8980-1260
Leek6.5-7.014-181.4-1.8980-1260
Lettuce5.5-6.58-120.8-1.2560-840
Marrow6.018-241.8-2.41260-1680
Okra6.520-242.0-2.41400-1680
Onions6.0-6.714-181.4-1.8980-1260
Pak-choi7.015-201.5-2.01050-1400
Parsnip6.014-181.4-1.8980-1260
Pea6.0-7.08-180.8-1.8980-1260
Peas (Sugar)6.0-6.8
Pepino6.0-6.520-502.0-5.01400-3500
Peppers5.8-6.3
Bell peppers6.0-6.5
Hot Peppers6.0-6.5
Potato5.0-6.020-252.0-2.51400-1750
Pumpkin5.5-7.518-241.8-2.41260-1680
Radish6.0-7.016-221.6-2.2840-1540
Spinach5.5-6.618-231.8-2.31260-1610
Silverbeet6.0-7.018-231.8-2.31260-1610
Sweet Corn6.016-241.6-2.4840-1680
Sweet Potato5.5-6.020-252.0-2.51400-1750
Swisschard6.0 6.5
Squash (Summer)5.0-6.5
Squash (Winter)5.0-6.5
Taro5.0-5.525-302.5-3.01750-2100
Tomato5.5-6.520-502.0-5.01400-3500
Turnip6.0-6.518-241.8-2.41260-1680
Zucchini6.018-241.8-2.41260-1680

Tuesday, January 8, 2013

Gora, my old cat

image



image



Thats my cat pictures, he was sick very badly... and whenever I take him to vet, all vet is not available... but I found people that know much about cat... So I give Gora to him, cause I know I cannot take care of him... very sad decission but thats good for Gora...

List Variable Global $_SERVER pada PHP 5

PHP memiliki beberapa variable global yang jarang di perhatikan (ane sendiri kale....), salah satu varible global yang perlu diperhatikan lebih adalah $_SERVER. Mengapa? Karena begini gan... Situs php.net menjelaskan bahwa $_SERVER berisi informasi mengenai header, lokasi path, dan lokasi script yang dibangun oleh web server, sehingga informasi mengenai user yang mengakses web server dan apa yang sedang dijalankan web server bisa di dapatkan datanya menggunakan variable $_SERVER.

okeh tanpa bertele - tele lagi langsung saja jalankan script dibawah ini pada web server local anda...


';
echo '$_SERVER[\'PHP_SELF\']            : '.$_SERVER['PHP_SELF']." 
";
echo '$_SERVER[\'GATEWAY_INTERFACE\']   : '.$_SERVER['GATEWAY_INTERFACE']." 
";
echo '$_SERVER[\'SERVER_ADDR\']         : '.$_SERVER['SERVER_ADDR']." 
";
echo '$_SERVER[\'SERVER_NAME\']         : '.$_SERVER['SERVER_NAME']." 
";
echo '$_SERVER[\'SERVER_SOFTWARE\']     : '.$_SERVER['SERVER_SOFTWARE']." 
";
echo '$_SERVER[\'SERVER_PROTOCOL\']     : '.$_SERVER['SERVER_PROTOCOL']." 
";
echo '$_SERVER[\'REQUEST_METHOD\']      : '.$_SERVER['REQUEST_METHOD']." 
";
echo '$_SERVER[\'REQUEST_TIME\']        : '.$_SERVER['REQUEST_TIME']." 
";
echo '$_SERVER[\'QUERY_STRING\']        : '.$_SERVER['QUERY_STRING']." 
";
echo '$_SERVER[\'DOCUMENT_ROOT\']       : '.$_SERVER['DOCUMENT_ROOT']." 
";
echo '$_SERVER[\'HTTP_ACCEPT\']         : '.$_SERVER['HTTP_ACCEPT']." 
";
echo '$_SERVER[\'HTTP_ACCEPT_ENCODING\']    : '.$_SERVER['HTTP_ACCEPT_ENCODING']." 
";
echo '$_SERVER[\'HTTP_ACCEPT_LANGUAGE\']    : '.$_SERVER['HTTP_ACCEPT_LANGUAGE']." 
";
echo '$_SERVER[\'HTTP_CONNECTION\']         : '.$_SERVER['HTTP_CONNECTION']." 
";
echo '$_SERVER[\'HTTP_HOST\']           : '.$_SERVER['HTTP_HOST']." 
";
echo '$_SERVER[\'HTTP_USER_AGENT\']     : '.$_SERVER['HTTP_USER_AGENT']." 
";
echo '$_SERVER[\'REMOTE_ADDR\']         : '.$_SERVER['REMOTE_ADDR']." 
";
echo '$_SERVER[\'REMOTE_PORT\']         : '.$_SERVER['REMOTE_PORT']." 
";
echo '$_SERVER[\'SERVER_ADMIN\']        : '.$_SERVER['SERVER_ADMIN']." 
";
echo '$_SERVER[\'SERVER_PORT\']         : '.$_SERVER['SERVER_PORT']." 
";
echo '$_SERVER[\'SERVER_SIGNATURE\']    : '.$_SERVER['SERVER_SIGNATURE']." 
";
echo '$_SERVER[\'SCRIPT_NAME\']         : '.$_SERVER['SCRIPT_NAME']." 
";
echo '$_SERVER[\'REQUEST_URI\']         : '.$_SERVER['REQUEST_URI']." 
";
?>
output :
//List Variable $_SERVER 
$_SERVER['PHP_SELF']      : /test.php 
$_SERVER['GATEWAY_INTERFACE']    : CGI/1.1 
$_SERVER['SERVER_ADDR']     : ::1 
$_SERVER['SERVER_NAME']     : localhost 
$_SERVER['SERVER_SOFTWARE']     : Apache 
$_SERVER['SERVER_PROTOCOL']     : HTTP/1.1 
$_SERVER['REQUEST_METHOD']     : GET 
$_SERVER['REQUEST_TIME']     : 1334284051 
$_SERVER['QUERY_STRING']     : vthink=5&team=5 
$_SERVER['DOCUMENT_ROOT']     : /Applications/MAMP/htdocs 
$_SERVER['HTTP_ACCEPT']     : text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
$_SERVER['HTTP_ACCEPT_ENCODING']    : gzip, deflate 
$_SERVER['HTTP_ACCEPT_LANGUAGE']    : en-us 
$_SERVER['HTTP_CONNECTION']     : keep-alive 
$_SERVER['HTTP_HOST']     : localhost 
$_SERVER['HTTP_USER_AGENT']     : Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/534.51.22 (KHTML, like Gecko) Version/5.1.1 Safari/534.51.22 
$_SERVER['REMOTE_ADDR']     : ::1 
$_SERVER['REMOTE_PORT']     : 50032 
$_SERVER['SERVER_ADMIN']     : you@example.com 
$_SERVER['SERVER_PORT']     : 80 
$_SERVER['SERVER_SIGNATURE']     :  
$_SERVER['SCRIPT_NAME']     : /test.php 
$_SERVER['REQUEST_URI']     : /test.php?vthink=5&team=5
Nah, informasi yang anda lihat pada hasil output yang ditampilkan pada output diatas tentunya tidak sama dengan output pada web server local anda. Jadi, informasi yang dihasilkan oleh web server anda tergantung pada siapa yang membuka dan web server apa yang anda gunakan. Seperti pada bagian $_SERVER['HTTP_USER_AGENT'] anda bisa melihat bahwa saya sedang menggunakan web browser safari dengan system operasi Mac OSX versi Intel Max OS X 10.7.2. Kemudian pada output $_SERVER['REQUEST_URI'] anda bisa melihat saya mengakses melalui web browser dengan url /test.php?vthink=5&team=5 (yups, coz ane jalanin di http://localhost/test.php?vthink=5&team=5)..... Jika anda ingin mempersingkat penulisan sintaks diatas dan melihat beberapa variable $_SERVER yang belum ane tulis, silahkah tulis sintaks di bawah ini :

<PRE>

<?php

print_r($_SERVER);

?> 

</PRE>

output :

Array

(

[HTTP_HOST] => localhost

[HTTP_USER_AGENT] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/534.51.22 (KHTML, like Gecko) Version/5.1.1 Safari/534.51.22

[HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

[HTTP_CACHE_CONTROL] => max-age=0

[HTTP_ACCEPT_LANGUAGE] => en-us

[HTTP_ACCEPT_ENCODING] => gzip, deflate

[HTTP_CONNECTION] => keep-alive

[PATH] => /bin:/sbin:/usr/bin:/usr/sbin:/usr/libexec:/System/Library/CoreServices

[SERVER_SIGNATURE] => 

[SERVER_SOFTWARE] => Apache

[SERVER_NAME] => localhost

[SERVER_ADDR] => ::1

[SERVER_PORT] => 80

[REMOTE_ADDR] => ::1

[DOCUMENT_ROOT] => /Applications/MAMP/htdocs

[SERVER_ADMIN] => you@example.com

[SCRIPT_FILENAME] => /Applications/MAMP/htdocs/test.php

[REMOTE_PORT] => 50164

[GATEWAY_INTERFACE] => CGI/1.1

[SERVER_PROTOCOL] => HTTP/1.1

[REQUEST_METHOD] => GET

[QUERY_STRING] => vthink=5&team=5

[REQUEST_URI] => /test.php?vthink=5&team=5

[SCRIPT_NAME] => /test.php

[PHP_SELF] => /test.php

[REQUEST_TIME] => 1334284637

[argv] => Array

(

[0] => vthink=5&team=5

)



[argc] => 1

)

Okey, silahkan mencoba dan semoga beberapa variable diatas bisa bermanfaat untuk anda gunakan pada aplikasi web yang anda bangun (terutama yang tidak menggunakan framework)... sumber : http://www.php.net/manual/en/reserved.variables.server.php

Instalasi CodeIgniter Spark pada Ubuntu

Salah satu framework PHP tercepat di dunia yang dinyatakan oleh founder bahasa pemrograman PHPRasmus Ledorf, telah merelease package management system yang dikenal dengan spark. Spark merupakan sebuah inovasi pemrograman pada CodeIgniter, karena dengan menggunakan spark programmer tidak perlu repot - repot menambah library pada codeigniter. Semua library bisa di install dengan menggunakan terminal pada Linux atau command prompt pada Windows. Dukungan list repository  pada situs http://getsparks.org memudahkan programmer untuk mencari library - library yang akan digunakan untuk integrasi maupun pengembangan aplikasi web yang mereka bangun.



Okey mari kita coba install spark, tetapi langkah yang saya bahas hanya berlaku pada sistem operasi linux.

Langkah pertama lakukan instalasi paket php5-curl agar spark paket management bisa digunakan oleh codeigniter spark:

apt-get install php5-curl

Setelah itu restart service apache anda dengan sitaks berikut ini :


service apache2 restart

Setelah itu, Download CodeIgniter Reactor pada link berikut ini : CodeIgniter-Reactor-v.2.0.3
Kemudian ekstrak file tersebut pada directory apache anda, misalnya seperti /var/www/ dan setelah itu ketik pada terminal anda perintah berikut ini :

cd /var/www/codeigniter/
php -r "$(curl -fsSL http://getsparks.org/go-sparks)"

Okey jika anda telah selesai maka sekarang anda bisa melakukan instalasi contoh paket spark dengan perintah berikut ini :

php tools/spark install -v1.0.0 example-spark



dalam proses instalasi kemungkinan anda akan melihat output pada terminal seperti ini :


[ SPARK ]  Retrieving spark detail from getsparks.org
[ SPARK ]  From Downtown! Retrieving spark from Mercurial repository at https://github.com/katzgrau/example-spark
[ SPARK ]  Installing spark
[ SPARK ]  Spark installed to ./sparks/example-spark/1.0.0 - You're on fire!

Okey, coba anda perhatikan susunan folder anda pada /var/www/codeigniter/, anda mungkin akan melihat susunan folder yang seperti berikut ini :
/var/www/codeigniter/application
/var/www/codeigniter/sparks
/var/www/codeigniter/system
/var/www/codeigniter/tools
/var/www/codeigniter/user_guide

okey, paket example-spark yang telah anda install dengan terminal tadi sudah berada pada folder /var/www/codeigniter/sparks/example-spark. soo, what the next??

selanjutnya adalah memanggil paket spark tadi dengan sintaks berikut pada controller anda :

Salah satu framework PHP tercepat di dunia yang dinyatakan oleh founder bahasa pemrograman PHPRasmus Ledorf, telah merelease package management system yang dikenal dengan spark. Spark merupakan sebuah inovasi pemrograman pada CodeIgniter, karena dengan menggunakan spark programmer tidak perlu repot - repot menambah library pada codeigniter. Semua library bisa di install dengan menggunakan terminal pada Linux atau command prompt pada Windows. Dukungan list repository  pada situs http://getsparks.org memudahkan programmer untuk mencari library - library yang akan digunakan untuk integrasi maupun pengembangan aplikasi web yang mereka bangun.



Okey mari kita coba install spark, tetapi langkah yang saya bahas hanya berlaku pada sistem operasi linux.

Langkah pertama lakukan instalasi paket php5-curl agar spark paket management bisa digunakan oleh codeigniter spark:
apt-get install php5-curl

Setelah itu restart service apache anda dengan sitaks berikut ini :
service apache2 restart

Setelah itu, Download CodeIgniter Reactor pada link berikut ini : CodeIgniter-Reactor-v.2.0.3
Kemudian ekstrak file tersebut pada directory apache anda, misalnya seperti /var/www/ dan setelah itu ketik pada terminal anda perintah berikut ini :
cd /var/www/codeigniter/
php -r "$(curl -fsSL http://getsparks.org/go-sparks)"

Okey jika anda telah selesai maka sekarang anda bisa melakukan instalasi contoh paket spark dengan perintah berikut ini :
php tools/spark install -v1.0.0 example-spark

dalam proses instalasi kemungkinan anda akan melihat output pada terminal seperti ini :

[ SPARK ]  Retrieving spark detail from getsparks.org
[ SPARK ]  From Downtown! Retrieving spark from Mercurial repository at https://github.com/katzgrau/example-spark
[ SPARK ]  Installing spark
[ SPARK ]  Spark installed to ./sparks/example-spark/1.0.0 - You're on fire!

Okey, coba anda perhatikan susunan folder anda pada /var/www/codeigniter/, anda mungkin akan melihat susunan folder yang seperti berikut ini :
/var/www/codeigniter/application
/var/www/codeigniter/sparks
/var/www/codeigniter/system
/var/www/codeigniter/tools
/var/www/codeigniter/user_guide

okey, paket example-spark yang telah anda install dengan terminal tadi sudah berada pada folder /var/www/codeigniter/sparks/example-spark. soo, what the next??

selanjutnya adalah memanggil paket spark tadi dengan sintaks berikut pada controller anda :

$this->load->sparks('example-spark/1.0.0');



ATAU

jika ingin menjalankan secara otomatis gunakan autoload pada folder /var/www/codeigniter/config/autoload.php, dan tambahkan sintaks berikut ini :

    $autoload['sparks']=array('example-spark/1.0.0');

Sekarang anda siap untuk beraksi...
silah mencoba.....

referensi : getsparks.org $this->load->sparks('example-spark/1.0.0');

ATAU

jika ingin menjalankan secara otomatis gunakan autoload pada folder /var/www/codeigniter/config/autoload.php, dan tambahkan sintaks berikut ini :

    $autoload['sparks']=array('example-spark/1.0.0');

Sekarang anda siap untuk beraksi...
silah mencoba.....

referensi : getsparks.org

Enkripsi MD5 dengan Java

Okeh bagi - bagi source lagi ney... ane mau bagi enkripsi MD5 untuk agan - agan sekalian... tapi Enkripsi MD5 ini hanya untuk text aja, kalau untuk file silahkan kembangkan lagi dengan class FileInputStream dan StringBuilder... Java juga mendukung banyak jenis enkripsi pada kelasMesageDiggest dengan method getInstance(); . Soo silahkan coba - coba untuk membuat enkripsi yang lain. Suatu saat mungkin anda membutuhkan class yang telah anda buat.

Okeh ini sourcenya :

[sourcecode language="java"]
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
*
* @author Lalu Erfandi Maula Yusnu
*/
public class ConverterUtil {

/**
* This nethod is used for encrypt String to MD5
* @param text String
* @return String
*/
public static String MD5(String text){
String output = null;
try {
MessageDigest dg = MessageDigest.getInstance("MD5");
dg.reset();
dg.update(stringToBytes(text));
byte[] hasher = new byte[32];
hasher = dg.digest();
return bytesToHexString(hasher);
} catch (NoSuchAlgorithmException e) {
System.out.println("There is No MessageDigest Instance of MD5");
System.exit(1);
}

return output;
}

/**
* This method used for converting byte array to hex string
*
* @param hasher byte[]
* @return String
*/
public static String bytesToHexString(byte[] hasher){
String HEXES = "0123456789abcdef";
StringBuilder hex = new StringBuilder( 2 * hasher.length );
for ( final byte b : hasher ) {
hex.append(HEXES.charAt((b & 0xF0) >> 4))
.append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}

/**
* This method used for converting byte array to string
* @param hasher byte[]
* @return String
*/
public static String bytesToString(byte[] hasher){
String hex = bytesToHexString(hasher);
return hexToString(hex);
}

/**
* This method used for converting string to bytes
* @param str String
* @return byte[]
*/
public static byte[] stringToBytes(String str){
int len = str.length();
byte[] out = new byte[len];
for (int i=0; i<len; i++) out[i] = (byte) ( str.charAt(i) & 0xFF);
return out;
}


/**
* This method used for converting hex to string
* @param hexString String
* @return String
*/
public static String hexToString(String hexString){
StringBuilder sb = new StringBuilder();
for(int i=0; i<hexString.length()-1; i+=2 ){
int decimal = Integer.parseInt(hexString.substring(i, (i + 2)), 16);
sb.append((char)decimal);
}
return sb.toString();
}

}
[/sourcecode]

nah untuk menggunakan source ini ini sintaksnya:

[sourcecode language="java"]
Public class Test {
public static void main(String[] args){
String text="Ini text yang akan di enkripsi dengan MD5";
String md5 = ConverterUtil.MD5(text);
System.out.println(md5);
}
}
[/sourcecode]

Hasilnya kurang lebih seperti ini :
6ddc9d6e411d0dfe769750b07d5ffb08

Semoga bermanfaat, sekian dan terima kasih....

Ngoprek MikroTik Api Client Berbasis Python

Okeh, jika anda ingin menjadi pengembang MikroTik API client sepertinya anda perlu mencoba MikroTik API client berbasis python untuk melakukan reverse engineering. Langkah ini diperlukan untuk mengetahui setiap inputan dan hasilnya...

Okeh script ini ane ambil dari http://wiki.mikrotik.com/wiki/Manual:API pada bagian paling bawah, berikut ini  scriptnya :

[sourcecode language="python"]
#!/usr/bin/python

import sys, posix, time, md5, binascii, socket, select

class ApiRos:
"Routeros api"
def __init__(self, sk):
self.sk = sk
self.currenttag = 0

def login(self, username, pwd):
for repl, attrs in self.talk(["/login"]):
chal = binascii.unhexlify(attrs['=ret'])
md = md5.new()
md.update('\x00')
md.update(pwd)
md.update(chal)
self.talk(["/login", "=name=" + username,
"=response=00" + binascii.hexlify(md.digest())])

def talk(self, words):
if self.writeSentence(words) == 0: return
r = []
while 1:
i = self.readSentence();
if len(i) == 0: continue
reply = i[0]
attrs = {}
for w in i[1:]:
j = w.find('=', 1)
if (j == -1):
attrs[w] = ''
else:
attrs[w[:j]] = w[j+1:]
r.append((reply, attrs))
if reply == '!done': return r

def writeSentence(self, words):
ret = 0
for w in words:
self.writeWord(w)
ret += 1
self.writeWord('')
return ret

def readSentence(self):
r = []
while 1:
w = self.readWord()
if w == '': return r
r.append(w)

def writeWord(self, w):
print "<<< " + w self.writeLen(len(w)) self.writeStr(w) def readWord(self): ret = self.readStr(self.readLen()) print ">>> " + ret
return ret

def writeLen(self, l):
if l < 0x80:
self.writeStr(chr(l))
elif l < 0x4000: l |= 0x8000 self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))
elif l < 0x200000: l |= 0xC00000 self.writeStr(chr((l >> 16) & 0xFF))
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))
elif l < 0x10000000: l |= 0xE0000000 self.writeStr(chr((l >> 24) & 0xFF))
self.writeStr(chr((l >> 16) & 0xFF))
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))
else:
self.writeStr(chr(0xF0))
self.writeStr(chr((l >> 24) & 0xFF))
self.writeStr(chr((l >> 16) & 0xFF))
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))

def readLen(self):
c = ord(self.readStr(1))
if (c & 0x80) == 0x00:
pass
elif (c & 0xC0) == 0x80:
c &= ~0xC0
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xE0) == 0xC0:
c &= ~0xE0
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xF0) == 0xE0:
c &= ~0xF0
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xF8) == 0xF0:
c = ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
return c

def writeStr(self, str):
n = 0;
while n < len(str):
r = self.sk.send(str[n:])
if r == 0: raise RuntimeError, "connection closed by remote end"
n += r

def readStr(self, length):
ret = ''
while len(ret) < length:
s = self.sk.recv(length - len(ret))
if s == '': raise RuntimeError, "connection closed by remote end"
ret += s
return ret

def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], 8728))
apiros = ApiRos(s);
apiros.login(sys.argv[2], sys.argv[3]);

inputsentence = []

while 1:
r = select.select([s, sys.stdin], [], [], None)
if s in r[0]:
# something to read in socket, read sentence
x = apiros.readSentence()

if sys.stdin in r[0]:
# read line from input and strip off newline
l = sys.stdin.readline()
l = l[:-1]

# if empty line, send sentence and start with new
# otherwise append to input sentence
if l == '':
apiros.writeSentence(inputsentence)
inputsentence = []
else:
inputsentence.append(l)

if __name__ == '__main__':
main()
[/sourcecode]

Simpan file diatas dengan nama routeros.py, dan untuk menjalankan nya masukan perintah berikut ini :

[sourcecode language="bash"]
chmod 777 routeros.py
python routeros.py 192.168.88.1 admin admin
[/sourcecode]


jika login anda benar maka akan muncul hasil seperti dibawah ini :

[sourcecode language="bash"]
<<< /login
<<< >>> !done
>>> =ret=3febe34367f76733cbece5c7822ebf7c
>>>
<<< /login
<<< =name=admin
<<< =response=0043af609b070655d06d5c1a7984377b6f
<<< >>> !done
>>>
[/sourcecode]

dan jika password anda salah maka akan tampil pesan berikut ini :

[sourcecode language="bash"]
<<< /login
<<< >>> !done
>>> =ret=8b5b3964ffd9422d920b6497960bfddd
>>>
<<< /login
<<< =name=admin
<<< =response=00f3f3219cdea9fc3861b19551f3457af6
<<< >>> !trap
>>> =message=cannot log in
>>>
>>> !done
>>>
[/sourcecode]

Okey, sekarang mari mencoba menampilakan semua interface pada mikrotik dengan MikroTik API client berbasis python ini. Ketik perintah dibawah ini dan ketik enter :

[sourcecode language="bash"]
/interface/print
[/sourcecode]

pada laptop ane muncul nya seperti ini,:

[sourcecode language="bash"]
/interface/print

<<< /interface/print
<<< >>> !re
>>> =.id=*1
>>> =comment=
>>> =name=ether1
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*2
>>> =comment=
>>> =name=ether2
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*3
>>> =comment=
>>> =name=ether3
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*4
>>> =comment=
>>> =name=ether4
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*5
>>> =comment=
>>> =name=ether5
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*6
>>> =comment=
>>> =name=vlan1
>>> =mtu=1500
>>> =type=vlan
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*7
>>> =comment=
>>> =name=vrrp1
>>> =mtu=1500
>>> =type=vrrp
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*8
>>> =comment=
>>> =name=vlan2
>>> =mtu=1500
>>> =type=vlan
>>> =dynamic=false
>>> =running=true
>>>
>>> !done
>>>
[/sourcecode]

bagaimana dengan laptop anda.....??? pengen tau, coba aja di ketik ...
Okey, kalau laptop ane, ada banyak interface yang sudah di add, jadi untuk memilih interface secara spesifik ketik perintah berikut :

[sourcecode language="bash"]
/interface/print
?=type=vlan
[/sourcecode]

Hasilnya anda akan menampilkan interface yang type vlan saja, berikut ini hasilnya :

[sourcecode language="bash"]
/interface/print
?=type=vlan

<<< /interface/print
<<< ?=type=vlan
<<< >>> !re
>>> =.id=*6
>>> =comment=
>>> =name=vlan1
>>> =mtu=1500
>>> =type=vlan
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*8
>>> =comment=
>>> =name=vlan2
>>> =mtu=1500
>>> =type=vlan
>>> =dynamic=false
>>> =running=true
>>>
>>> !done
>>>
[/sourcecode]

Okeh, sekarang bagaimana kalau ingin menampilkan interface ether1 dan ether2? coba ketik perintah berikut ini :

[sourcecode language="bash"]
/interface/print
?=name=ether1
?=name=ether2
?#|
[/sourcecode]

Hasilnya akan seperti ini :

[sourcecode language="bash"]
<<< /interface/print
<<< ?=name=ether1
<<< ?=name=ether2
<<< ?#|
<<< >>> !re
>>> =.id=*1
>>> =comment=
>>> =name=ether1
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*2
>>> =comment=
>>> =name=ether2
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !done
>>>
[/sourcecode]

Okeh, sekali lagi, bagaimana kalau ingin menampilkan interface ether saja dan selain daripada ether1 dan ether2? coba ketik perintah ini :

[sourcecode language="bash"]
/interface/print
?=type=ether
?#&
?=name=ether1
?#!
?=name=ether2
?#!
[/sourcecode]

maka hasilnya akan seperti dibawah ini :

[sourcecode language="bash"]
<<< /interface/print
<<< ?=type=ether
<<< ?#&
<<< ?=name=ether1
<<< ?#!
<<< ?=name=ether2
<<< ?#!
<<< >>> !re
>>> =.id=*3
>>> =comment=
>>> =name=ether3
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*4
>>> =comment=
>>> =name=ether4
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !re
>>> =.id=*5
>>> =comment=
>>> =name=ether5
>>> =mtu=1500
>>> =type=ether
>>> =dynamic=false
>>> =running=true
>>>
>>> !done
>>>
[/sourcecode]

Mengapa hasilnya bisa seperti itu ??? bagaimana rumusan nya??? Topik apa yang sedang kita bahas saat ini???
Okey, jadi yang sedang ane uji coba sekarang ini adalah tentang MikroTik API bagian Queries yang hanya disupport pada RouterOS versi 3.22 ke atas...
begini rumusan nya (walaupun sebenarnya ane masih belum terlalu faham betul, but ini asumsi ane okeh!!)

kalau berdasarkan situs http://wiki.mikrotik.com/wiki/Manual:API, berikut keterangan nya:
Okeh, jadi kalau di terjemahkan (pake google translate and di perbaiki) :

QUERIES
perintah cetak menerima kata-kata yang telah di kirimkan dan akan mengatur ulang satu set kalimat . Fitur ini tersedia sejak RouterOS 3.21.


Query dimulai dengan tanda '?' (tanpa tanda petik)
Urutan kata - kata Query sifatnya signifikan. Query di evaluasi mulai dari kata pertama.
Query akan di evaluasi pertiap item yang berada dalam daftar, jika query berhasil, item akan diproses dan jika query gagal item akan diabaikan.
Query di evaluasi menggunakan tumpukan (stack) nilai boolean (true/false). Awalnya tumpukan (stack) berisi jumlah nilai 'true' tak terbatas. Pada akhir proses evaluasi, jika tumpukan (stack) berisi setidaknya satu nilai 'false' maka query menjadi gagal.
Pengoperasian kata - kata dalam query adalah berdasar pada aturan berikut ini :































QueryDesciption
?nameStack akan mengirim 'true' jika item mempunyai value (nilai) dari property name, dan Stack akan mengirim 'false' jika hal sebaliknya terjadi.
?-nameStack akan mengirim 'true' jika item tidak memiliki value (nilai) dari property name, dan Stack akan mengirim 'false' jika hal sebaliknya terjadi.
?name=x
?=name=x
Stack akan mengirim 'true' jika property name memiliki value (nilai) sama dengan x, dan Stack akan mengirim 'false' jika hal sebaliknya terjadi.
?<name=xStack akan mengirim 'true' jika property name memiliki nilai kurang dari x, dan Stack akan mengirim 'false' jika hal sebaliknya terjadi.
?>name=xStack akan mengirim 'true' jika property name lebih besar dari x, dan Stack akan mengirim 'false' jika hal sebaliknya terjadi.
?#operationsberikut ini aturan operasi yang berlaku dalam stack: string operasi di evaluasi dari kiri ke kanan.

urutan digit desimal di ikuti dengan sembarang karakter atau akhir kata ditafsirkan sebagai index stack dimana nilai index pada stack pertama adalah 0.

index  yang di ikuti oleh karakter akan mendorong salinan (copy) pada nilai tersebut. index yang di ikuti kata akhiran akan menggantikan semua nilai dengan nilai pada index tersebut.

'!' (not) karakter akan menggantikan nilai atas dengan nilai yang berlawanan dengan nya.

'&' (and) karakter akan membuang dua nilai (value) dan sebagai hasilnya karakter ini akan melakukan operasi logis 'and'.

'|' (or) karakter akan membuang dua nilai (value) dan sebagai hasilnya karakter ini akan melakukan operasi logis 'or'.

'.' (dot) karakter tidak akan menjadikan error

'.' (dot) karakter setelah karakter lain akan mendorong atau mengirim salinan pada nilai di bagian atas.

Audience : Wah masih bingung gan???
Penulis : Tenang ane juga bingung kok, abis bahasanya baku bangets... tapi mari kita bahas sama - sama siapa tau kita bisa mengerti...
jadi begini, misalnya ada sintaks seperti ini:

[sourcecode language="bash"]
/interface/print
?=type=vlan
?=type=ether
?#|
?=name=ether1
?#!
?#&
[/sourcecode]

kemudian misalnya, kita anggap masing - masing baris dengan kode seperti ini :
?=type=vlan adalah P1
?=type=ether adalah P2
?#| adalah L1
?=name=ether1 adalah P3
?#! adalah L2
?#& adalah L3

okey kalau kita susun dalam bentuk ke kanan jadinya seperti ini :
P1 P2 L1 P3 L2 L3

seperti yang telah dijelaskan dalam tabel diatas, setiap operasi yang ditandai dengan ?# maka dia memiliki rumusan sendiri. Dan setelah ane analisa maka bentuk tadi akan diubah menjadi seperti ini :
P1 L1 P2 L3 L2 P3

dan hasilnya akan menjadi seperti sintaks dibawah ini saat dibaca oleh MikroTik RouterOS :

[sourcecode language="bash"]
?=type=vlan
?#|
?=type=ether
?#&
?#!
?=name=ether1
[/sourcecode]

sehingga seolah - olah sintaks yang diterima oleh mikrotik menjadi seperti ini :

[sourcecode language="bash"]
?=type=vlan ?#| ?=type=ether ?#& ?#! ?=name=ether1
[/sourcecode]

masih belibet kan??? sama... tapi mari coba ubah bentuknya agar lebih mudah dimengerti menjadi seperti ini :

[sourcecode language="bash"]
type=vlan or type=ether and name!=ether1
[/sourcecode]

Pertanyaan nya adalah bagaimana bentuk seperti ini bisa di analogikan???
Hal ini karena mikrotik mengimplementasikan stack, yang mana setiap operasi logika and dan or akan membuang dua perintah dari stack dan akan mengubahnya menjadi bentuk operasi logis.
Nah itu asumsi ane... jadi benar atau salahnya masih belum bisa ane pertanggung jawabkan, untuk mendapat contoh - contoh yang lebih banyak silahkan buka link pada wiki mikrotik ini : http://wiki.mikrotik.com/wiki/API_command_notes

Okeh, semoga bermanfaat... sekian dan terima kasih...

Ngoprek MikroTik API Client Berbasis Python

Okeh, jika anda ingin menjadi pengembang MikroTik API client sepertinya anda perlu mencoba MikroTik API client berbasis python untuk melakukan reverse engineering. Langkah ini diperlukan untuk mengetahui setiap inputan dan hasilnya...

Okeh script ini ane ambil dari http://wiki.mikrotik.com/wiki/Manual:API pada bagian paling bawah, berikut ini  scriptnya :

[sourcecode language="python"]
#!/usr/bin/python

import sys, posix, time, md5, binascii, socket, select

class ApiRos:
"Routeros api"
def __init__(self, sk):
self.sk = sk
self.currenttag = 0

def login(self, username, pwd):
for repl, attrs in self.talk(["/login"]):
chal = binascii.unhexlify(attrs['=ret'])
md = md5.new()
md.update('\x00')
md.update(pwd)
md.update(chal)
self.talk(["/login", "=name=" + username,
"=response=00" + binascii.hexlify(md.digest())])

def talk(self, words):
if self.writeSentence(words) == 0: return
r = []
while 1:
i = self.readSentence();
if len(i) == 0: continue
reply = i[0]
attrs = {}
for w in i[1:]:
j = w.find('=', 1)
if (j == -1):
attrs[w] = ''
else:
attrs[w[:j]] = w[j+1:]
r.append((reply, attrs))
if reply == '!done': return r

def writeSentence(self, words):
ret = 0
for w in words:
self.writeWord(w)
ret += 1
self.writeWord('')
return ret

def readSentence(self):
r = []
while 1:
w = self.readWord()
if w == '': return r
r.append(w)

def writeWord(self, w):
print "<<< " + w
self.writeLen(len(w))
self.writeStr(w)

def readWord(self):
ret = self.readStr(self.readLen())
print ">>> " + ret
return ret

def writeLen(self, l):
if l < 0x80:
self.writeStr(chr(l))
elif l < 0x4000:
l |= 0x8000
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))
elif l < 0x200000:
l |= 0xC00000
self.writeStr(chr((l >> 16) & 0xFF))
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))
elif l < 0x10000000:
l |= 0xE0000000
self.writeStr(chr((l >> 24) & 0xFF))
self.writeStr(chr((l >> 16) & 0xFF))
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))
else:
self.writeStr(chr(0xF0))
self.writeStr(chr((l >> 24) & 0xFF))
self.writeStr(chr((l >> 16) & 0xFF))
self.writeStr(chr((l >> 8) & 0xFF))
self.writeStr(chr(l & 0xFF))

def readLen(self):
c = ord(self.readStr(1))
if (c & 0x80) == 0x00:
pass
elif (c & 0xC0) == 0x80:
c &= ~0xC0
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xE0) == 0xC0:
c &= ~0xE0
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xF0) == 0xE0:
c &= ~0xF0
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xF8) == 0xF0:
c = ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
return c

def writeStr(self, str):
n = 0;
while n < len(str):
r = self.sk.send(str[n:])
if r == 0: raise RuntimeError, "connection closed by remote end"
n += r

def readStr(self, length):
ret = ''
while len(ret) < length:
s = self.sk.recv(length - len(ret))
if s == '': raise RuntimeError, "connection closed by remote end"
ret += s
return ret

def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], 8728))
apiros = ApiRos(s);
apiros.login(sys.argv[2], sys.argv[3]);

inputsentence = []

while 1:
r = select.select([s, sys.stdin], [], [], None)
if s in r[0]:
# something to read in socket, read sentence
x = apiros.readSentence()

if sys.stdin in r[0]:
# read line from input and strip off newline
l = sys.stdin.readline()
l = l[:-1]

# if empty line, send sentence and start with new
# otherwise append to input sentence
if l == '':
apiros.writeSentence(inputsentence)
inputsentence = []
else:
inputsentence.append(l)

if __name__ == '__main__':
main()
[/sourcecode]

Simpan file diatas dengan nama routeros.py, dan untuk menjalankan nya masukan perintah berikut ini :

[sourcecode language="bash"]
chmod 777 routeros.py
python routeros.py 192.168.88.1 admin admin
[/sourcecode]

[source
jika login anda benar maka akan muncul hasil seperti dibawah ini :