Friday, October 14, 2011

Installing the mrtg and the auto analyzer script

I want to explain the mrtg installation on Debian from scratch. It might be boring for expert users but anyway this article is said to be effective for beginners. Expert users may jump on text.

Download the last version of Debian for from the URL "http://cdimage.debian.org/debian-cd/6.0.2.1/i386/iso-cd/" and "debian-6.0.2.1-i386-netinst.iso" images. This version is the minimum in size. I selected that version, because I want to see/show all required packages and applications. I have Ubuntu 11.04 and VirtualBox 4.0.4 in my computer. I installed that Debian into the virtual host at VirtualBox with the default (only selected ssh server while installation) installation settings.


apt-get install mrtg


Mrtg is a perl script so the Perl interpreter is required. I'm checking the Perl interpreter:



a) I will need a http server to publish web pages that are generated by the Mrtg script.
b) I will need a php interpreter to analyze html outputs of mrtg script.
c) I will need a mysql database to save some options and data about auto alert generating.

I'm installing apache2, php5 and mysql-server5 for All that requirements;

apt-get install apache2 php5 mysql-server




After than installation, you can see used ports on your linux to check the status of Apache and Mysql services like following image:




You can check the Apache & Php status using the code below:

<?php phpinfo(); ?>


If the file name is "test.php" and path of the directory is "/var/www/", the phpinfo() function should send an output on your browser when you enter the http://youraddress/test.php address. The next step is to test the mysql server and to make a connection between php and mysql servers. You can use the following php script:

<?php
$link = mysql_connect("localhost","root","youPasswordOnPicture")
or die("Error: Can not establish connection to MySQL Server");
?>


If the file name is "testMySQL.php" and path of the directory is "/var/www/", you should not to see nothing on your browser when you enter the http://youraddress/testMySQL.php address. Having a message "Error: Can not establish connection to MySQL Server" means the database server connection is unsuccessful.

If have reached this line without any error/problem, we can jump to mrtg part again: The mrtg script queries your active network devices (routers, switches, firewalls etc.) via SNMP protocol. So you have to configure the snmp settings on your active network devices. I will add a basic snmp setup for some mostly used devices.

You can use following command to generate a mrtg configuration file.

cfgmaker CommunityString@deviceA.of.Ip.Address --output deviceA.cfg


This command creates a file with name "deviceA.cfg". We have to edit some lines in this file like following:

# Created by 
# /usr/bin/cfgmaker CmmntyString@172.28.201.10


### Global Config Options

# for UNIX
WorkDir: /var/www/html/mrtgGraphics/relatedDevice/

# or for NT
# WorkDir: c:\mrtgdata

### Global Defaults

# to get bits instead of bytes and graphs growing to the right
Options[_]: growright, bits

EnableIPv6: no
...
...
..


If you use MS Windows Operation System, simply uncomment the line "WorkDir: c:\mrtgdata" and put a '#' char to comment the line "WorkDir: /var/www/html/mrtgGraphics/relatedDevice/". We are capable to define directions of graphics and unit types of data. Possible choices for bit and byte for unit and frowright and growleft for direction. (Bunun frowright olduğuna emin misin? flowright olabilir mi?)

Each single interface is defined in this configuration file like following:

Target[3661-fasteth00-systemsegment]: 2:CmmntyString@172.28.201.10:
SetEnv[3661-fasteth00-systemsegment]: MRTG_INT_IP="172.28.201.10" MRTG_INT_DESCR="FastEthernet0/0"
MaxBytes[3661-fasteth00-systemsegment]: 12500000
Title[3661-fasteth00-systemsegment]: Traffic Analysis for 3661-FastEthernet0/0 SystemSegment
PageTop[3661-fasteth00-systemsegment]: <h1>Traffic Analysis for 3661-FastEthernet0/0 SystemSegment</h1>
<div id="sysdetails">
<table>
<tr>
<td>System:</td>
<td>UGC_Topkapi_3661 in </td>
</tr>
<tr>
<td>Maintainer:</td>
<td>Name of The Responsible Person</td>
</tr>
<tr>
<td>Description:</td>
<td>FastEthernet0/0 Connection to SYSTEM Segment </td>
</tr>
<tr>
<td>ifType:</td>
<td>ethernetCsmacd (6)</td>
</tr>
<tr>
<td>ifName:</td>
<td>Fa0/0</td>
</tr>
<tr>
<td>Max Speed:</td>
<td>12.5 MBytes/s</td>
</tr>
<tr>
<td>Ip:</td>
<td>172.28.201.10 ()</td>
</tr>
</table>
</div>


"3661-fasteth00-systemsegment" is the filename of generated html file in path "/var/www/html/mrtgGraphics/relatedDevice/". Each interface has got a different filename like "3661-fasteth00-systemsegment". We have to keep " 2:CmmntyString@172.28.201.10:" part in that configuration file but we can change the other parts such as title, pagetop, and other expressions between html tags.

When we finish editing the configuration file, we have to execute mrtg command with this configuration file as below:

/bin/env LANG=C /usr/bin/mrtg /etc/mrtg/cfg-files/3661.cfg


But the problem is, this command should be re-executed every 5 minutes to get statistics continuously. We can use crontab for this goal. The crontab line is like following for this sample,

*/5 * * * * /bin/env LANG=C /usr/bin/mrtg /etc/mrtg/cfg-files/3661.cfg >/dev/null 2<&1


My MRTG server has got a lot of cfg files and I prepared crontab lines are like this,

0,5,10,15,20,25,30,35,40,45,50,55 * * * * /bin/env LANG=C /usr/bin/mrtg /etc/mrtg/cfg-files/3661.cfg >/dev/null 2<&1
1,6,11,16,21,26,31,36,41,46,51,56 * * * * /bin/env LANG=C /usr/bin/mrtg /etc/mrtg/cfg-files/otherfile.cfg >/dev/null 2<&1
2,7,12,17,22,27,32,37,42,47,52,57 * * * * /bin/env LANG=C /usr/bin/mrtg /etc/mrtg/cfg-files/anotherfile.cfg >/dev/null 2<&1


At this point, our MRTG structure is ready for use. The generated html files are located in path "/var/www/html/mrtgGraphics/relatedDevice/".

[root@mrtg relatedDevice]# ls -l | grep 3661-fasteth00-systemsegment
-rw-r--r-- 1 root root 4649 2011-10-13 16:45 3661-fasteth00-systemsegment-day.png
-rw-r--r-- 1 root root 6951 2011-10-13 16:45 3661-fasteth00-systemsegment.html
-rw-r--r-- 1 root root 98062 2011-10-13 16:45 3661-fasteth00-systemsegment.log
-rw-r--r-- 1 root root 4548 2011-10-13 15:30 3661-fasteth00-systemsegment-month.png
-rw-r--r-- 1 root root 98062 2011-10-13 16:40 3661-fasteth00-systemsegment.old
-rw-r--r-- 1 root root 4337 2011-10-13 16:35 3661-fasteth00-systemsegment-week.png
-rw-r--r-- 1 root root 4756 2011-10-13 04:40 3661-fasteth00-systemsegment-year.png
[root@mrtg relatedDevice]#


If mrtg cfg file has got a lot of interface parts, so lots of html files will be generated. We will need an index page for this situation. We can use following command to generate an index page for our statistics pages.

indexmaker deviceA.cfg > index.html


This command will generate a file with name index.html. We have to move this file to "/var/www/html/mrtgGraphics/relatedDevice/" directory. 3661-fasteth00-systemsegment.html file has got a part like following:

<!-- Begin `Daily' Graph (5 Minute -->
<div class="graph">
<h2>`Daily' Graph (5 Minute Average)</h2>
<img src="3661-fasteth00-systemsegment-day.png" title="day" alt="day" />
<table>
<tr>
<th></th>
<th scope="col">Max</th>
<th scope="col">Average</th>
<th scope="col">Current</th>
</tr>
<tr class="in">
<th scope="row">In</th>
<td>9117.6 kb/s (9.1%)</td>
<td>3139.1 kb/s (3.1%) </td>
<td>5966.2 kb/s (6.0%) </td>
</tr>
<tr class="out">
<th scope="row">Out</th>
<td>9144.2 kb/s (9.1%) </td>
<td>3159.9 kb/s (3.2%) </td>
<td>6001.8 kb/s (6.0%) </td>
</tr>
</table>
</div>
<!-- End `Daily' Graph (5 Minute -->



This part contains numeric values of usage of related interface. We can capture these values every 5 minutes and write to mysql table. Also we can define some limits about that line and compare actual value and limit value. If actual value reaches limit value, the script will be able to generate an alert message. This article is only about the installation of MRTG, Apache http server, php5 and Mysql-Server. The next article will about "how to auto analyze mrtg results with php scripts".

Wednesday, October 12, 2011

Making a Simple Form Module on Drupal 7.8

We have created a simple module before, that is here. But if you build a web site, you'll need to use forms. For that reason, i'll show you about making a simple form module in this article. Let's remember which files we've got when we create module on drupal.

Mymodule (folder)
  • mymodule.info
  • mymodule.module
  • mymodule.inc
"mymodule.info" file is for settings of the module, that's why we don't use it for this article. Other ones also are so important now.

If you check this article out, can remember what the system of drupal's work. When we code, we call the function which will use. Well, then code your mymodule.inc and mymodule.module pages:


mymodule.module page
function honda_menu() {
  $items['honda/hrv'] = array(
    'title' => 'Honda HR-V',
    'page callback' => 'honda_form',
    'access arguments' => array('access content'),
    'file' => 'honda.inc',
  );
  return $items;
}

As you see the bold row's got our function for the module with "page callback". honda_form() function is in;

mymodule.inc page


function honda_form() {
 return drupal_get_form('form_for_honda'); //This is the function that will use
}
function form_for_honda($form_state) {
 $form['text'] = array(
  '#type' => 'textfield', //Input type
  '#title' => t(Write something..'), Input label
 );
 $form['Okey'] = array(
  '#type' => 'submit', //Input type
  '#value' => 'I am Ok!', //Button value
 );
 return $form;
}

When we go to honda/hrv direction, we're going to see it like down here;

Output

Well done! Our form is ready to use. I've just added a textfield and submit button. If you want to add something else, you should add elements for array. For example;

'#type' => 'checkbox',
'#type' => 'fieldset',
'#type' => 'file',
'#type' => 'radios',

If you want to see more information about Drupal forms API, you can visit forms API.

We'll see you next article!

Wednesday, October 5, 2011

Using Taxonomy to Post Contents on Drupal

Some of us have no idea about taxonomy. Actually i didn't know either what taxonomy was. When i built my drupal project, i recognized that i had to use it. I think, taxonomy is one of the most important features of drupal. Because, all content of your site, can be available with terms, verbs and tags on taxonomy.

So, imagine that you've just added content to your drupal site. If this content is a special of you, you'll want people to find it easly, right? Yes! Well, you need to use taxonomy now!

Step 1 : Select the content type you'll add a new field to.
Step 2 : You go manage fields and add a field on it for taxonomy.
Step 3 : Create a new verbs and add tags on it.
Step 4 : Your vocabulary is ready to use now! Add a new content and select tags from vocabulary!

Step 1

My choice is Basic Page content type. You need to click this path :
Click to the manage fields
After clicking; Step 2


As you see it up here, site is waiting for us to add a new field for our taxonomy. Adding is so easy. Just type like;

Label : "tax" //tax is my choice. You can change it
Field name : "field_"tax" //This name is for machine, generally select it like your label name
Type of data to store : "Term reference"
Form element to edit the data : "Autocomplete term widget (tagging)" //If you select it like this, you can add tag multiple, so this would be better?

And click Save button.

Selecting Vocabulary
Step 3

Well done! We create a new field for our tags. But the system asks us to select a vocabulary. Don't do anything on this page and open a new tab on your browser. Because of this, we are going to create a new vocabulary. The direction you'll go to is, "admin/structure/taxonomy/add".

add a new vocabulary for the field

Name : "Testing" //You can change it.
Description : "This is very important!"

And click Save button.


Click the add terms link.

When adding term

Type "php" for "Name" textfield and click the save button. And after that add: "ajax", "sql", "mysql", "dom", "c", "java", etc.
Now, turn back to the page we have to select a vocabulary for new field(tax) and refresh!

Select testing and Click Save Field Setting button.

For testing this vocabulary, add a new content. For that, use this path : "node/add/page".




Like you see, when i type something for tags, ready with Autocomplete term widget.


We'll see you next article!

Form Validation Using AJAX and PHP

In this article, we'll show you something about form validation, namely form control solutions using AJAX and PHP. As you know, we can submit a form without refreshing page with Ajax. So, we should use this tech.

NOTE : Ajax is not one technology, but a group of technologies. Ajax uses HTML, JavaScript, CSS, XML etc.

This example, shows the relationship between getting data of form and checking:

Step 1 is, users type something or not!

Step 2 is, the system checks what the data is or, is there any typed data?

Well, let's do our pages. For that we create three files,
  1. example.html
  2. kitchen.php
  3. lib.ajax.js
lib.ajax.js
// JavaScript Document
	//What does JaX stand for? is the function we use for ajax object
function JaX() {
	var httpObject = null;
	var httpBrowser = navigator.appName;
	
	if(httpBrowser == "Microsoft Internet Explorer") {
		httpObject = new ActiveXObject("Microsoft.XMLHTTP");	
	} else {
		httpObject = new XMLHttpRequest();	
	}
	return httpObject;
}

function UJaX(subject, method, path, more, func, statu) {
	//subject is object of ajax
	//method is the method of getting variables
	//path is the path of file
	//func is the function you use on it
	//statu can be true or false
	ajaxObject = JaX();
	
	if(method == 'POST') {
		if(ajaxObject != null) {
			ajaxObject.onreadystatechange = func;
			ajaxObject.open('POST', path, statu);
			header = "application/x-www-form-urlencoded";
			ajaxObject.setRequestHeader("Content-Type", header);
			ajaxObject.send(more);
		} else {
			alert("Error(1)->The System Cannot Be Opened!");	
		}
	} else {
		if(ajaxObject != null) {
			ajaxObject.onreadystatechange = func;
			ajaxObject.open('GET', path+'?'+more, statu);
			ajaxObject.send(null);
		} else {
			alert("Error(2)->The System Cannot Be Opened!");	
		}
	}
}


example.html

var ajaxObject;

function CheckItOut() {
	subject = ajaxObject;
	method = 'GET';
	path = 'kitchen.php';
	func = sonuc;
	dataMore = document.getElementById("data").value;
	more = 'data=' + dataMore;
	statu = "true";
	
	UJaX(subject, method, path, more, func, statu);
}

function sonuc() {
	if(ajaxObject.readyState == 4) {
		if(ajaxObject.status == 200) {
			DM = ajaxObject.responseText;
			//DM = document.form1.data.value;
			if(DM == "You must write something!")
				document.getElementById("MyButton").disabled = true;	
			else
				document.getElementById("MyButton").disabled = false;	
		} else
			DM = "Error = Nu/1";	
	} else
		DM = "Loading...";	
		document.getElementById("MyLabel").innerHTML = DM;
}

< form name="form1" method="GET">
< input name="data" type="text" id="data" onChange="CheckItOut();">
< input name="MyButton" type="button" id="MyButton" value="I'm Ok!">
< /form>

Preview example.html page

And php page, kitchen.php


$DataOfForm = $_REQUEST["data"];
if(!$DataOfForm == 1) {
	print "You must write something!";
} else {
	print "You said:".$DataOfForm."";	
}

And yes! We just finished our script! go to example.html page and write something;

When you typing

If we don't type anything on this, we'll see like down here:

When you type none.

Like you see, "Button" is disabled when you type none. Because of it is DM variable of javascript.

If you want to see this project, you can click Demo!

We'll see you next article!


hook_help() function on Drupal: 'helping menu' for Our Module

We've learnt how to create a new module on Drupal before, here is How to create a new module! We'll been added new features on it after this article.

As first, we should explain what our module is. For that reason, can put a helping menu. We'd said there were so much functions on Drupal library, hook_help() is just one of'em. If we want to realize what this article says, must implements hook_help() function.

mymodule.module


* Implements hook_help().
*/
function honda_help($path, $arg) {
 if($path == 'admin/help#honda') { //The direction
  return t('<a href=honda/hrv>CLICK FAQ</a> for HONDA HR-V.'); //We help here!
 }
}
When checked t() function out, can see that able to use HTML tags, here is <a href=honda/hrv>CLICK FAQ</a>.


Click the "help?"!

We'll see you next article!

Tuesday, October 4, 2011

Creating a Basic Drupal Module!

It is quite easy creating a drupal module. The rule what you have to know is just selecting the function you need to use. Because, Drupal has got so many functions that you can use. But before coding, we must create a folder for our module. This folder has two important files:

  1. Mymodule (folder)
    • mymodule.info (must)
    • mymodule.module (must)
    • mymodule.inc
Let's view!


For step 1;

mymodule.info includes;

name = Honda HR-V //this is the name of the module
description = HONDA HR-V car is the best i have ever seen in this world! //the description
package = packageName //which package the module is in
core = 7.x //the core number
version = 7.8 //the version
files[] = honda.module //files that'll include to
dependencies[] = views //the modules which we must include



 
For step 2;

mymodule.module details are;

When we code a module of Drupal, we should know how to use the PHP tags. After the end of our code, we don't put the "<?>" tag on it.

    function honda_menu() {
      $items['honda/hrv'] = array(
        'title' => 'Honda HR-V',
        'page callback' => 'honda_page',
        'access arguments' => array('access content'),
        'file' => 'honda.inc',
      );
      return $items;
    }
    
     Please check "honda/hrv" out. This is the direction we go on the browser. If we click this, it's going to start on "honda.inc" page. Here is one of the most important things we have to know on drupal, is the way of how Drupal's work. "honda_page" is a function actually. When the module opened, this function'll be started.

    For step 3;

    Then let me show you the page which's name is honda.inc:

    function honda_page() {
      return t('This is the first module i created!');
    }
    
    As you see here, we've never used the ending tag ,"? >".
    This honda_page function's been used before When we coding mymodule.module page, page callback.


    By the way, you may ask me what the "t" is. t() is a function that used on drupal. This method handles the outputting works including the multilingual operations.

    If you want to see more information about t() function, you can visit official web site, here is api.drupal.org/t .


    We'll see you next article!

    Thursday, September 29, 2011

    Contribute to Practical Code Solutions

    Practical Code Solutions has three active authors now and they post blog entries about programming, open source software, networking, scripting and other issues about computers. Since it is not a private site,we are calling new participants which have aimed to write about the issues stated above.

    Also the authors which are interested in web programming, desktop programming, databases, operating systems, compilers and interpreters, algorithms, statistics, operations research are welcome!. Requirements are average level of plain English and being a professional or hobbyist on one or more of the subjects described.

    Please contact one of the authors of Practical Code Solutions or leave a message under this post to participate. Do not hesitate to share new ideas with us.

    DHCP server configuration on Linux.



    This page is about configuring a dhcp3-server on a Debian system. You can install the service library with following command;



    sudo atp-get install dhcp3-server


    When you install dhcp3-server service, you will see dhcp3 directory in folder /etc. That directory contains dhcp3-server configuration file dhcpd.conf. My dhcp3-server service configuration file seems like this;


    ddns-update-style none;
    option domain-name "sample-dom.sample-com";
    option domain-name-servers 172.28.202.143, 172.28.202.142;

    default-lease-time 600;
    max-lease-time 7200;

    subnet 172.28.24.0 netmask 255.255.255.0 {
    range 172.28.24.10 172.28.24.254;
    option subnet-mask 255.255.255.0;
    option broadcast-address 172.28.24.255;
    option routers 172.28.24.1;
    }

    host printer {
    hardware ethernet 00:26:73:04:08:3f;
    fixed-address 172.28.24.37;
    }

    host printer1 {
    hardware ethernet 00:00:f0:a6:ef:5b;
    fixed-address 172.28.24.90;
    }

    host AccessPoint_Symbol {
    hardware ethernet 00:A0:F8:A7:77:88;
    fixed-address 172.28.24.70;
    }
    authoritative;

    log-facility local7;


    First 3 lines are abo ut dn s settings. You can set the domain in domain-name line and you can set dns servers on domai-name-servers line. You can also set multiple dns servers in a single line. If a client gets an ip address and never opens it for 7200 seconds, all information will be deleted for that client. So this date is called expiration date. subnet 172.28.24.0 netmask 255.255.255.0 part defines a scope between "{" and "}" characters. Scope properties are located between parentheses. For example, I want service to distribute ips only from the range of 172.28.24.10 and 172.28.24.254. I don't want the service to distribute ips from the range of 172.28.24.1 and 172.28.24.9. I also want to use this range to special purposes. And then, there are other options needed. subnet-mask, broadcast address and router address. Router address is usually called default gateway.

    Host part is used for reservation. printer, printer1 and AccessPoint_Sympol parts are name of the reservations. You have to define a MAC address in a hardware ethernet line and you have to define some reserved ip addresses in fixed-address line. if you use "authoritative" line (you can delete it), all of the clients will record themself to dns server. The last line is just for defining the logging level.

    Finally, you will need to start the service. You can use /etc/init.d/dhcp3-server shell script with start, stop, restart, force-reload or status options. If you execute that script without any parameter, it cats the possible options defined below:

    /etc/init.d/dhcp3-server
    Usage: /etc/init.d/dhcp3-server {start|stop|restart|force-reload|status}

    Wednesday, September 28, 2011

    How to configure site to site VPN profile on Linux,

    In this little page I will describe how to configure a vpn connection between two different networks. This connection is usually called site2site vpn.


    I used ipsectools and recoon projects to establish a vpn tunnel. In Debian distributions, to install required packages we type:

    # sudo apt-get install ipsec-tools racoon



    We have to edit some configuration files. I want to explain the related services using the sample configuration. We call Branche Office for the node on the left and central office for the other one. The vpn tunnel is shown in the picture above. The branche office, which is the one we are talking about is a Linux installed machine and the central office is using Nortel Contivity 1740 VPN BOX. The branch office has got 172.28.24.0 / 24 network address. The central office has got 172.28.0.0 / 16 network address. 172.28.0.0 / 16 is for to contain the brache office segment.

    But as you know, If you look at from branch office, all other branch offices are behind the central office. So first of all, we have to fix this problem.

    The problem is that, if we will define the destination network as 172.28.0.0/16, our vpn box device sends packets through the tunnel interface for accessing to 172.28.24.0 / 24 segment. But 172.28.24.0 / 24 segment is already connected to itself! In this sample, our vpn destination network is 0.0.0.0 / 0. Because, this is a branch office and we want to have full control on internet access requests from the branch office. The spd.conf file (/etc/spd.conf) seems like that;

    spdadd 172.28.24.0/24 172.28.24.0/24 any -P in none;
    spdadd 172.28.24.0/24 172.28.24.0/24 any -P out none;
    spdadd 172.28.24.0/24 0.0.0.0/0 any -P out ipsec ah/tunnel/bb.bb.bb.bb-aa.aa.aa.aa/require;
    spdadd 0.0.0.0/0 172.28.24.0/24 any -P in ipsec ah/tunnel/aa.aa.aa.aa-bb.bb.bb.bb/require;



    first two lines are required to fix the problem. Last two lines are required to establish vpn tunnel. These are define tunnel source/destination networks and tunnel source/destinatio ends. (aa.aa.aa.aa is ip address of vpn catcher device on the central office and bb.bb.bb.bb is ip address of branch office box. So it is our linux ip address.)

    This site to site vpn tunnel is using pre-shared key mechanism. So we need a pre-shared key configuration file. The file seems like that;

    aa.aa.aa.aa [pre-shared key]



    This file must be located in /etc/racoon directory in our defined system. The other configuration file that located in /etc/rac oon directory is racoon.conf:

    listen {
    adminsock "/var/run/racoon.sock" "root" "wheel" 0660;
    }
    path pre_shared_key "/etc/racoon/psk.txt";

    path certificate "/etc";

    remote aa.aa.aa.aa {
    exchange_mode aggressive;
    my_identifier fqdn "BranchOfficeName";

    peers_identifier address aa.aa.aa.aa;
    initial_contact on;
    ike_frag on;
    support_proxy on;
    proposal_check obey;

    proposal {
    encryption_algorithm 3des;
    hash_algorithm md5;
    authentication_method pre_shared_key;
    dh_group 2;
    }
    }

    sainfo address 172.28.24.0/24 any address 0.0.0.0/0 any {
    encryption_algorithm des,3des;
    authentication_algorithm hmac_sha1,hmac_md5;
    compression_algorithm deflate;
    lifetime time 5 min;
    pfs_group 2;
    }



    the racoon.conf file contains this tunnel configuration, source and destionation network addresses and some ipsec option selections. So you can select different encryption options in this file. But the important point is, each ends should have the same selections. bb.bb.bb.bb might be a problem for you if it's changeable. If this ip address is changeable, you have to recognize the current value and you have to update it in /etc/spd.conf file. And then, you have to update it on the running service. You can use setkey command to manage tunnel properties.

    setkey -D
    setkey -DP
    setkey -F
    /etc/init.d/setkey {start|stop|restart|force-reload}



    -D Dump the SAD entries, -F Flush the SAD entries and /etc/init.d/setkey is initialize shell script.

    If you create new spd.conf file in different path, you have to kill existing setkey process (or you can use '/usr/sbin/setkey -F -FP' command) and load new conf file with following command:

    kill existing setkey process;

    /usr/sbin/setkey -F -FP



    start setkey with new spd.conf file

    /usr/sbin/setkey -f /etc/spd.conf



    Finally, if your Linux box's public ip address is changable you can sense current ip address on external interface and update spd.conf file with following php script. It reads some informations from racoon.conf file. If you don't need these parts, you can mark the line with "#" to make it commented.

    The filename is createSpd.php (full path: /root/fwscripts/createSpd.php):

    #!/usr/bin/php
    <?php
    $k = 0;
    $i = 1;
    while($k < 5){
    $lan = exec("/sbin/ifconfig eth0 | /bin/grep 'inet addr' | /usr/bin/gawk -F ' ' '{print $2}' | /usr/bin/gawk -F ':' '{print $2}'");
    $wan = exec("/sbin/ifconfig ppp0 | /bin/grep 'inet addr' | /usr/bin/gawk -F ' ' '{print $2}' | /usr/bin/gawk -F ':' '{print $2}'");
    //$peer = 'aa.aa.aa.aa'; // you can use this line or following line.
    $peer = exec("/bin/grep remote /etc/racoon/racoon.conf | /usr/bin/gawk -F ' ' '{ print $2 }'");

    $localNet = exec("/bin/grep sainfo /etc/racoon/racoon.conf | /usr/bin/gawk -F ' ' '{ print $3 }'");
    $remoteNet = exec("/bin/grep sainfo /etc/racoon/racoon.conf | /usr/bin/gawk -F ' ' '{ print $6 }'");

    $blan = strlen($lan);
    $bwan = strlen($wan);

    echo "strlen($lan):$blan,strlen($wan):$bwan \n";

    if($blan < "6" || $bwan < "6" ) {
    echo "LAN or WAN hasn't got usable ip address.\n";
    echo "The script wait and will be try again!!! ($i) # # # # # # # # # # # \n";
    $i++;
    sleep(10);
    } else {
    echo "writing to /etc/spd.conf file as collected information:\n";
    exec("/bin/rm -rf /etc/spd.conf.old;/bin/mv /etc/spd.conf /etc/spd.conf.old");
    exec("echo 'spdadd 172.28.10.254/32 0.0.0.0/0 any -P out none;' > /etc/spd.conf");
    exec("echo 'spdadd 0.0.0.0/0 172.28.10.254/32 any -P in none;' >> /etc/spd.conf");
    exec("echo 'spdadd $localNet $localNet any -P in none;' >> /etc/spd.conf");
    exec("echo 'spdadd $localNet $localNet any -P out none;' >> /etc/spd.conf");
    exec("echo 'spdadd $localNet $remoteNet any -P out ipsec ah/tunnel/$wan-$peer/require;' >> /etc/spd.conf");
    exec("echo 'spdadd $remoteNet $localNet any -P in ipsec ah/tunnel/$peer-$wan/require;' >> /etc/spd.conf");
    $k = 5;
    }
    if($i > 5){
    $k = 7;
    }
    }
    echo "FNSH\n";
    ?>


    If you want to manage the setkey process with a shell script, you can practically use the following script.

    #!/bin/sh

    case "$1" in
    start)
    echo "Running ipsec VPN rules file: /etc/spd.conf";
    /root/fwscripts/createSpd.php
    /usr/sbin/setkey -f /etc/spd.conf
    ;;
    stop)
    echo "Remove ipsec VPN rules file: /etc/spd.conf"
    /usr/sbin/setkey -F -FP
    ;;
    restart)
    echo "Remove ipsec VPN rules file: /etc/spd.conf"
    /usr/sbin/setkey -F -FP
    echo "Running ipsec VPN rules file: /etc/spd.conf";
    /root/fwscripts/createSpd.php
    /usr/sbin/setkey -f /etc/spd.conf
    ;;
    *)
    echo "Usage: /etc/init.d/setkeyHandle {start|stop|restart}"
    ;;
    esac

    exit 0


    And then, if you want to add this script to boot progress, you can use update-rc.d command in Debian based Linuxs like following,

    # update-rc.d setkeyHandle defaults
    Adding system startup for /etc/init.d/setkeyHandle ...
    /etc/rc0.d/K20setkeyHandle -> ../init.d/setkeyHandle
    /etc/rc1.d/K20setkeyHandle -> ../init.d/setkeyHandle
    /etc/rc6.d/K20setkeyHandle -> ../init.d/setkeyHandle
    /etc/rc2.d/S20setkeyHandle -> ../init.d/setkeyHandle
    /etc/rc3.d/S20setkeyHandle -> ../init.d/setkeyHandle
    /etc/rc4.d/S20setkeyHandle -> ../init.d/setkeyHandle
    /etc/rc5.d/S20setkeyHandle -> ../init.d/setkeyHandle


    If you don't want to use default values, you can define your values in the update-rc.d command like following;

    # update-rc.d setkeyHandle start 20 2 3 4 5 . stop 80 0 1 6 .

    Passing plain Java objects to R using RCaller

    Well, you are using RCaller for your statistical calculations. Probably, you are passing your double arrays to R and type some R commands in order to get the desired outputs. After a calculation process, you handle the returned arrays through the parser. This is the general use of RCaller.

    Suppose that you have got a Java class which has got some variables with data types int, short, long, float, double and String. This class also includes some arrays of types int[], double[], ..., String[]. Of course it may include some functions, constructors or anything else. But we don't care about this for now.  How about passing this class with its publicly defined variables to R? Yeah! It is possible in its last submitted revision.

    Have a look at the Java class below:


    class TestClass {
    
      public int i = 9;
      public float f = 10.0f;
      public double d = 3.14;
      public boolean b = true;
      public String s = "test";
    }
    

    This class simply includes five publicly defined variables with basic data types. Our other class inherits the TestClass and defines some additional arrays:


    class TestClassWithArrays extends TestClass {
    
      public int[] ia = new int[]{1, 2, 3, 4, 5};
      public double[] da = new double[]{1.0, 2.0, 3.0, 4.0, 9.9, 10.1};
      public String[] sa = new String[]{"One", "Two", "Three"};
      public boolean[] ba = new boolean[]{true, true, false};
    }
    

    Ok, they are very simple but there is no reason those classes not to have any methods. Whatever those classes have methods, we consider them as data structures.

    Lets pass this data structure to R:


    TestClassWithArrays tcwa = new TestClassWithArrays();
        JavaObject jo = new JavaObject("tcwa", tcwa);
    
        RCaller rcaller = new RCaller();
        rcaller.setRscriptExecutable("/usr/bin/Rscript");
        rcaller.cleanRCode();
    
        rcaller.addRCode(jo.produceRCode());
        rcaller.runAndReturnResult("tcwa");
    


    Well, if there is no expection we have the results in a R list named "tcwa". This R list includes all of the elements that included in TestClassWithArrays and TestClass with their values.

    This is an example of proof, the related @Test method is ready for browsing in the Google Code:

    @Test
      public void TestClassWithArrays() throws IllegalAccessException, IOException {
        TestClassWithArrays tcwa = new TestClassWithArrays();
        JavaObject jo = new JavaObject("tcwa", tcwa);
    
        RCaller rcaller = new RCaller();
        rcaller.setRscriptExecutable("/usr/bin/Rscript");
        rcaller.cleanRCode();
    
        rcaller.addRCode(jo.produceRCode());
        rcaller.runAndReturnResult("tcwa");
    
        int[] expectedIntArray = rcaller.getParser().getAsIntArray("ia");
        for (int i = 0; i < tcwa.ia.length; i++) {
          assertEquals(expectedIntArray[i], tcwa.ia[i]);
        }
    
    
        double[] expectedDoubleArray = rcaller.getParser().getAsDoubleArray("da");
        for (int i = 0; i < tcwa.da.length; i++) {
          assertEquals(expectedDoubleArray[i], tcwa.da[i], delta);
        }
    
        String[] expectedStringArray = rcaller.getParser().getAsStringArray("sa");
        for (int i = 0; i < tcwa.sa.length; i++) {
          assertEquals(expectedStringArray[i], tcwa.sa[i]);
        }
    
      }
    

    It is shown that in examples, in R side, we can access to elements with their original names that defined in the Java class. That sounds good.

    Finally, we can pass our Java objects with defined contents. This use of RCaller narrows the code of addDoubleArray, addIntArray and reduce all of them to simple command of

     JavaObject jo = new JavaObject("tcwa", tcwa);
    .
    .
    .
    rcaller.addRCode ( jo.produceRCode() );
     
    
    It is simplicity...
    

    Friday, September 23, 2011

    How to follow up temperature of system room,

    able to visit following link For more example and with different devices like hp, cisco, netscreen..;
    http://stdioe.blogspot.com/2011/10/checking-system-room-temperature-with.html
    also should be check http://stdioe.blogspot.com/2011/11/nokia-application-for-system-room.html article. This article contain a mobile phone client application to follow up to system room temperature..


    I needed to find a solution for the question above for the company which I'm working for. I wanna talk about my quick solution in this article.

    There are several IMB Blade chassis, cisco routers, Juniper devices, HP / IBM rock mountable servers, Cisco/Hp/Nortel swithces etc. in my system room.. Actually, there are many alternatives but I selected the IBM Blade chassis to read data of temperature. Because, It contains a lot of blade servers and they are really business critical. Somehow that blade chassis should always be powered on..

    I have a Linux server for monitoring the network and something like that. It has got Apache Http Server, MySQL server, a Perl interpreter, a Php interpreter installed. I created a DB and a table to record temperature values. I wrote a script to connect to IBM blade chassis and get temperature value. This script gets the values and record them to a text file;

    Read data from IBM Blade Chassis (read.pl);

    #!/usr/bin/perl
    use Net::Telnet ();
    $t = new Net::Telnet (Timeout => 10);
    $t->open("x.x.x.x");
    $t->login("USERID", "password");
    $t->cmd("env -T system:mt[1]");
    @lines = $t->cmd("temps");
    #print @lines;

    open (HEDEF, ">/root/ibmTemperature/lastTemp.txt") || die ("Could not open file
    $!");
    print HEDEF "@lines";
    close (HEDEF);


    recorded data to the lastTemp.txt file is like this;

                  Warning
    Value Warning Reset
    ----- ------- -------
    25.00 38.00 33.00
    ...
    ..
    .


    I need the first value; the value of 25.00 at line 1. Use following command to eleminate unwanted parts.

    echo `/usr/bin/head -4 /root/ibmTemperature/lastTemp.txt | /usr/bin/tail -1 | /usr/bin/gawk -F ' ' ' {print $1} '`> /root/ibmTemperature/tempfile.txt

    Write data to MySQL table (write.php);

    I decide to use different languages for each step. The following php script reads the data from blade chassis, writes the data to mysql database server

    #!/usr/bin/php


    I did set to execution permission to the script given above. I also wrote the interpreter path to head of the script source. So therefore, I can execute it directly. I also have to say, I almost always use the full path names in all scripts. Because, if I use relative paths in the scripts, I need login on the treminal / console to execute it to get $PATH variable value from environmental values structure. But, If I use full path in my scripts, I can execute it from everywhere (for example, execute from crontab)

    shell script for execute all (run.sh),

    #!/bin/bash
    /root/ibmTemperature/read.pl
    echo `/usr/bin/head -4 /root/ibmTemperature/lastTemp.txt | /usr/bin/tail -1 | /usr/bin/gawk -F ' ' ' {print $1} '`> /root/ibmTemperature/tempfile.txt
    /root/ibmTemperature/write.php



    Now, I can add run.sh script in the crontab for executing it once a minute and run.sh script to be able to trigger the read.pl, write.php and some linux commands. And now, I have to explain that linux commands;

    a) The head is captured from first 4 lines of lastTemp.txt text file. The pipe captures an output from that head and inputs to tail command. So tail command captures the last line from the output of head command and next pipe creates an input for gawk..

    This structure is being executed once a minute for adding the current temperature information to MySQL table with mktime date/time format. The following php script creates a clear output for users on a web-page. (my webpage hosted on /systemRoom/ directory in web root directory.)


     









    System room temperature graphic (Last 24 Hours):";
    echo "";
    echo "";
    echo "\n";
    $k = 0;
    while($line = mysql_fetch_array($result)) {
    $current = (3*$line["temp"]);
    $current_temp = $line["temp"];

    if($current < "72") { $color = "lightblue.PNG"; } elseif($current < "85") { $color = "blue.PNG"; } else { $color = "red.PNG"; } if($k == 0) { $now = $line["date"]; } else { if(strlen($line["date"]) > 5) {
    $end = $line["date"];
    }
    }

    echo "\n";
    }
    echo "";
    //echo "";
    echo "

    ";
    echo "";
    echo "";
    //echo "Now (0 point on graphic): ".date("Y/m/d - H:i:s", $now)."
    Oldest (End point on graphic): ".date("Y/m/d - H:i:s", $end)."
    ";
    ?>


    ";
    echo "";
    echo "





    : Recommended Values Range

    : Acceptable Values Range

    : Dangerous Values Range

    Thursday, September 22, 2011

    How to Connect Juniper Netscreen Device using Perl Scripts

    The site http://search.cpan.org contains a usable and easy library to connect netscreen devices. Name of the library is Net::Telnet::Netscreen. Its use is straightforward:

    #!/usr/bin/perl
    use Net::Telnet ();
    $t = new Net::Telnet (Timeout => 10,
    Prompt => '/ns5gt-adsl->/');

    $t->open("IP_ADDR_of_NetscreenDevice");
    $t->login(netscreenUsername, Password);
    @lines = $t->cmd("get policy id X");
    print @lines;
    $t->cmd("exit");
    $t->cmd("exit");


    IP_ADDR_of_NetscreenDevice, netscreenUsername and Password expressions can be replaced with an address, an username and a password, respectively.

    How to Connect Cisco Router with Perl Scripts

    ( Click for PHP version: http://stdioe.blogspot.com/2011/11/how-to-connect-cisco-router-with-php.html )

    First of all, I have to explain how to configure the Cisco router for telnet connectivity. Because, the Cisco router supports the telnet password and privilege password, It also supports username and password combination for logging in. So there are two different type to logging in.

    The following explanation of Cisco router configurations are from stratch. So we have to connect to router via console cable (rollover cable) and serial port on computer and terminal application. If you use MS Windows operating system, you can use Hyper terminal or different third party terminal applications. If you use Linux operating system, you have several choices. I usually use the minicom in my personel use laptop . But the problem is that It hasn't got any serial ports. The solution is to use the usb to serial converter adapter with requisite drivers installed in my Linux.

    Router-A Configuration:
    Router> Enable
    Router# configure Terminal
    Enter configuration commands, one per line. End with CNTL/Z.
    Router(config)# enable secret 0 cisco
    Router(config)# line vty 0 4
    Router(config-line)#login
    % Login disabled on line 6, until 'password' is set
    % Login disabled on line 7, until 'password' is set
    % Login disabled on line 8, until 'password' is set
    % Login disabled on line 9, until 'password' is set
    % Login disabled on line 10, until 'password' is set
    Router(config-line)#password cisco
    00:00:54: %SYS-5-CONFIG_I: Configured from console by console
    Router(config-line)# ^Z
    Router#write memory

    The following perl script to connect to Router-A without AAA;

    #!/usr/bin/perl

    use Net::Telnet::Cisco;
    my $session = Net::Telnet::Cisco->new(Host => 'x.x.x.x');
    $session->login('', 'password');

    # Execute a command
    my @output = $session->cmd('show version');
    print @output;

    # Enable mode
    if ($session->enable("enable_password") ) {
    @output = $session->cmd('show privilege');
    print "My privileges: @output\n";
    } else {
    warn "Can't enable: " . $session->errmsg;
    }

    $session->close;

    After than write this perl script above, of course you have to add execution permission to script file. For example, if the file name of this script is sample.pl then simply type

    chmod +x sample.pl

    Router-B Configuration (Updating to AAA model):

    Router(config)#aaa new-model
    Router(config)#username TelnetUser privilege 15 password 0 TelnetPassword

    The following perl script to connect to Router-B;

    The difference between the first sample and the second sample is that,
    first router configuration is done with telnet password and password.

    Anyway you can use the Net::Telnet::Cisco Library which is written in Perl. If you are using a Linux Distro, probably your package manager already contains it.

    #!/usr/bin/perl

    use Net::Telnet::Cisco;

    my $session = Net::Telnet::Cisco->new(Host => 'x.x.x.x');
    $session->login('TelnetUser', 'TelnetPassword');

    # Execute a command
    my @output = $session->cmd('show version');
    print @output;

    # Enable mode
    @output = $session-> cmd('show privilege');
    print "My privileges: @output\n";
    $session->close;

    If you want to add "Net::Telnet:Cisco" or something like that manually, you can search the related perl library on site http://search.cpan.org.
    For Example http://search.cpan.org/~joshua/Net-Telnet-Cisco-1.10/Cisco.pm link is used in the sample we have just given.
    And you can also download http://search.cpan.org/CPAN/authors/id/J/JO/JOSHUA/Net-Telnet-Cisco-1.10.tar.gz compressed file.

    Note:
    After extracting it, enter extracted directory. Execute perl Makefile.PL.
    The "make" and "make install" commands produces the output below:

    user@hostn:~/DIR> tar xvfz Net-Telnet-Cisco-1.10.tar.gz 
    Net-Telnet-Cisco-1.10/
    Net-Telnet-Cisco-1.10/README
    Net-Telnet-Cisco-1.10/Cisco.pm
    Net-Telnet-Cisco-1.10/.cvsignore
    Net-Telnet-Cisco-1.10/MANIFEST
    Net-Telnet-Cisco-1.10/test.pl
    Net-Telnet-Cisco-1.10/MANIFEST.SKIP
    Net-Telnet-Cisco-1.10/Changes
    Net-Telnet-Cisco-1.10/INSTALL
    Net-Telnet-Cisco-1.10/Makefile.PL
    Net-Telnet-Cisco-1.10/TODO
    user@hostn:~/DIR> cd Net-Telnet-Cisco-1.10/
    user@hostn:~/DIR/Net-Telnet-Cisco-1.10> perl Makefile.PL

    Checking if your kit is complete...
    Looks good
    Writing Makefile for Net::Telnet::Cisco
    user@hostn:~/DIR/Net-Telnet-Cisco-1.10> make
    cp Cisco.pm blib/lib/Net/Telnet/Cisco.pm
    AutoSplitting blib/lib/Net/Telnet/Cisco.pm (blib/lib/auto/Net/Telnet/Cisco)
    Manifying blib/man3/Net::Telnet::Cisco.3pm
    user@hostn:~/DIR/Net-Telnet-Cisco-1.10> make install
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ERROR: Can't create '/usr/lib/perl5/site_perl/5.12.3/Net/Telnet'
    Do not have write permissions on '/usr/lib/perl5/site_perl/5.12.3/Net/Telnet'
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    at -e line 1
    make: *** [pure_site_install] Error 13
    user@hostn:~/DIR/Net-Telnet-Cisco-1.10> sudo make install
    root's password:
    Appending installation info to /usr/lib/perl5/5.12.3/i586-linux-thread-multi/perllocal.pod
    user@hostn:~/DIR/Net-Telnet-Cisco-1.10>

    The last step is installing which is required root permissions. So When used without root permission, It returned an error than used "sudo" to get root permission, It finally successful.

    Saturday, September 17, 2011

    RCaller: Support for sequential commands with a single process

    I think, this revision will be the foundation of the version  2.1. RCaller is supposed to be slow but the easiest way of calling R from Java.

    Finally I have implemented the method runAndReturnResultOnline() for running sequential commands in a single process. What does this stand for? Let me give an example to explain this:

    Suppose that you want to perform a simulation study to measure the success of your new procedure. For this, you decide to draw random numbers from a distribution and calculate something and handle the results in Java. RCaller creates  Rscript processes for each single iteration. This cause to too many operating system calls.

    Latest release of RCaller includes the method for this. Lets have a look at the Test file:


    @Test
      public void onlineCalculationTest() {
        RCaller rcaller = new RCaller();
        rcaller.setRExecutable("/usr/bin/R");
        rcaller.cleanRCode();
        rcaller.addRCode("a<-1:10");
        rcaller.runAndReturnResultOnline("a");
        assertEquals(rcaller.getParser().getAsIntArray("a")[0], 1);
    
        rcaller.cleanRCode();
        rcaller.addRCode("b<-1:10");
        rcaller.addRCode("m<-mean(b)");
        rcaller.runAndReturnResultOnline("m");
        assertEquals(rcaller.getParser().getAsDoubleArray("m")[0], 5.5, 0.000001);
    
        rcaller.cleanRCode();
        rcaller.addRCode("a<-1:99");
        rcaller.addRCode("k<-median(a)");
        rcaller.runAndReturnResultOnline("k");
        assertEquals(rcaller.getParser().getAsDoubleArray("k")[0], 50.0, 0.000001);
      }
      }
     
    
    In first stage,we are creating an integer vector and getting the first element. In the second one, we are creating the same integer vector with a different name and calculating the arithmetic mean. In the last one, we are recreating the vector a and getting the median, which is equal to 50.

    This example uses the same RCaller object. In first stage, the R executable file (it is /usr/bin/R in my Ubuntu Linux) is created once. In second stage the same R file is used and no longer processes are created again. In this stage, the vector a is accessible and still remains alive. At the last stage, b is alive again and a is recreated. So this example does not cause the R to open and close three times but only once.

    This modification speeds up the RCaller, but it can be still considered as slow.
    However, it is still easy to implement and much more faster than the previous implementation.

    Have Fun!