Pemrograman IP Versi 6 dengan C 
author: ev1lut10n
pola pikir : 60 % teknis  , 40 % strategis (bisnis)
gopher: gopher://sdf.org/1/users/wisdomc0   (why  use gopher? it's because 
i still love old protocols)
blog: http://myw1sd0m.blogspot.com
motto: "berhubung pala lagi mumet gara 2 bikin botnet (almost 2 years) jd 
maen2 dulu bentar buat penyegaran "

* Sekilas IP Versi 6

ip versi 6 merupakan metode pengalamatan jaringan terbaru saat ini, 
setelah ip versi 4. beberapa os modern saat ini sudah support ip versi 6, 
untuk windows setau ane mulai support sejak vista.
ip versi 6 pengalamatanya berbeda dg ip versi 4, coba perhatikan (mesin 
harus dikonfigurasi untuk support ip versi 6, untuk konfigurasi tdk 
dibahas di sini krn bukan bagian permainan):

ip versi 4 (the kuno model):
-----------------
root@mywisdom-Vostro1310:/mnt/sda1/xampp/htdocs/gaharu# ping google.com
PING google.com (74.125.235.51) 56(84) bytes of data.
64 bytes from 74.125.235.51: icmp_req=1 ttl=55 time=19.5 ms
-------------------


ip versi 6:
-------------------------
root@mywisdom-Vostro1310:/mnt/sda1/xampp/htdocs/gaharu# ping6 
ipv6.google.com
PING ipv6.google.com(2404:6800:800b::68) 56 data bytes
64 bytes from 2404:6800:800b::68: icmp_seq=2 ttl=57 time=216 ms
64 bytes from 2404:6800:800b::68: icmp_seq=3 ttl=57 time=216 ms
--------------------------

dari hasil resolve di atas jelas keliatan beda model pengalamatanya.

ip versi empat modelnya : xxx.xxx.xxx.xxx di mana xxx adalah angka 0 
sampai dengan 255 desimal 


ip versi 6 contoh model pengalamatanya adalah:  
2001:0000:53aa:64c:383a:45ca:8977:b4db
setiap blok dipisahkan oleh : (titik dua), dengan jumlah blok 8 setiap 
blok merupakan angka hexadesimal, alamat di atas bisa dikompress menjadi: 
2001:0:53aa:64c:383a:45ca:8977:b4db atau 
2001::53aa:64c:383a:45ca:8977:b4db

perbedaan2 lain ip versi 4 dan 6
1. tidak ada broadcast  karena sudah ditangani oleh multicast
2. ip versi 4 panjangnya 32 bit , ip versi 6 hingga 128 bit (2 ^ 128 
alamat unik)
3. gak ada kelas
4. what about loopback??

alamat loopback (localhost yg biasa kita kenal dg 127.0.0.1) di ip versi 6 
adl: ::1
------------------
root@mywisdom-Vostro1310:/mnt/sda1/xampp/htdocs/gaharu# ping6 ::1
PING ::1(::1) 56 data bytes
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.026 ms
64 bytes from ::1: icmp_seq=2 ttl=64 time=0.033 ms

root@mywisdom-Vostro1310:/mnt/sda1/xampp/htdocs/gaharu# traceroute6 ::1
traceroute to ::1 (::1) from ::1, 30 hops max, 16 byte packets
 1  mywisdom-Vostro1310 (::1)  0.056 ms  0.03 ms  0.021 ms
root@mywisdom-Vostro1310:/mnt/sda1/xampp/htdocs/gaharu# 
---------------------


* ip versi 6 kita ???

root@mywisdom-Vostro1310:/home/mywisdom/asm# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:1c:23:56:0b:10  
          inet addr:118.136.75.36  Bcast:118.136.75.255  
Mask:255.255.255.0
          inet6 addr: fe80::21c:23ff:fe56:b10/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:158525 errors:0 dropped:0 overruns:0 frame:0
          TX packets:126790 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:186207641 (186.2 MB)  TX bytes:19747224 (19.7 MB)
          Interrupt:44 Base address:0xc000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:205839 errors:0 dropped:0 overruns:0 frame:0
          TX packets:205839 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:165648554 (165.6 MB)  TX bytes:165648554 (165.6 MB)

teredo    Link encap:UNSPEC  HWaddr 
00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet6 addr: 2001:0:53aa:64c:383a:45ca:8977:b4db/32 Scope:Global
          inet6 addr: fe80::ffff:ffff:ffff/64 Scope:Link
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1280  Metric:1
          RX packets:32 errors:0 dropped:0 overruns:0 frame:0
          TX packets:61 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:5936 (5.9 KB)  TX bytes:6878 (6.8 KB)


ip versi 6 di mesin ini: 2001:0:53aa:64c:383a:45ca:8977:b4db

0010000000000001 0000000000000000  0101001110101010  0110010000001100 
0011100000111010 0100010111001010 1000100101110111 1011010011011011  

* cara mengakses ip versi 6 via browser ???

misal kita akan mengakses ip versi 6 dari ipv6.google.com via browser:
------------------------
root@mywisdom-Vostro1310:/home/mywisdom/asm# host ipv6.google.com
ipv6.google.com is an alias for ipv6.l.google.com.
ipv6.l.google.com has IPv6 address 2404:6800:800b::67
-----------------------
via web browser ketikkan url ini:

http://[2404:6800:800b::67]


untuk lebih mendalami ip versi 6 silahkan pelajari sendiri di 
http://www.apnic.net/community/ipv6-program


*. TCP klien untuk ip versi 6

jika kita lihat sebelumnya kita memrogram socket untuk ip versi 4; 
http://myw1sd0m.blogspot.com/2011/04/socket-programming-dengan-c-linux.html

untuk versi 6 teknik pemrogramanya agak sedikit berbeda.

berikut ini contoh untuk meresolve hostname devilzc0de.org utk mendapatkan 
ip versi 4 

ip versi 4 resolve , make stream socket  (we talk tcp here) and connect to 
spesific port by dom dom

filename: res4.c
---------------------------
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main()
{
int soket,target;
struct sockaddr_in server;
   if((target=gethostbyname("google.com")) == NULL)
    {
     printf("\n[-]fungsi gethostbyname gagal ! keluar dari program ! \n");
    exit(1);
    }
    else
    {
    printf ("\n[+]fungsi gethostbyname berhasil, ip google adalah: 
%u.%u.%u.%u\n",(unsigned char)target->h_addr[0],(unsigned 
char)target->h_addr[1],(unsigned char)target->h_addr[2],(unsigned 
char)target->h_addr[3]);
    
    }
    
    if((soket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  {
    printf("\ngagal menciptakan socket !! keluar dari program !\n");
    exit(1);
  }
 else
  {
  printf ("\n[+]di sini file deskriptor telah siap !! selanjutnya kita 
akan melakukan fungsi connect\n");
  }
  //kita isi struktur sockaddr_in, berupa sin_family=AF_INET untuk koneksi 
TCP/IP. sin_addr  data alamat ip,sin_port berisi nomor port
  server.sin_family=AF_INET;
  server.sin_addr.s_addr=*(long *)(target->h_addr);
  server.sin_port=htons(80);
  //setelah itu kita akan mencoba memanggil fungsi connect() untuk 
terhubung ke server
  if(connect(soket, (struct sockaddr *)&server, sizeof(struct sockaddr)) 
== -1)
    {
     printf("\n[-]koneksi ke google.com via port 80 gagal\n");
     exit(1);
     }
    else
     {
      printf("\n[+]fungsi connect() ke google.com via port 80 berhasil !!! 
selanjutnya kita akan bermain di send dan recv\n");
      }
}


---------------


kompile dan tes:
--------------
oot@mywisdom-Vostro1310:/home/mywisdom/asm# gcc -o res4 res4.c
root@mywisdom-Vostro1310:/home/mywisdom/asm# ./res4

[+]fungsi gethostbyname berhasil, ip google adalah: 74.125.235.52

[+]di sini file deskriptor telah siap !! selanjutnya kita akan melakukan 
fungsi connect

[+]fungsi connect() ke google.com via port 80 berhasil !!! selanjutnya 
kita akan bermain di send dan recv
root@mywisdom-Vostro1310:/home/mywisdom/asm# 

----------------


struktur ip versi 4 bisa dilihat di:  /usr/include/netinet/in.h sbb:
/* Structure describing an Internet socket address.  */
struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;			/* Port number.  */
    struct in_addr sin_addr;		/* Internet address.  */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr) -
			   __SOCKADDR_COMMON_SIZE -
			   sizeof (in_port_t) -
			   sizeof (struct in_addr)];
  };


sedangkan struktur ip versi 6 juga bisa dilihat di 
/usr/include/netinet/in.h :
---------------
/* Ditto, for IPv6.  */
struct sockaddr_in6
  {
    __SOCKADDR_COMMON (sin6_);
    in_port_t sin6_port;	/* Transport layer port # */
    uint32_t sin6_flowinfo;	/* IPv6 flow information */
    struct in6_addr sin6_addr;	/* IPv6 address */
    uint32_t sin6_scope_id;	/* IPv6 scope-id */
  };
---------------

dari header ini kita tidak melihat adanya sin_family,jika kita lihat lebih 
jauh ke file /usr/include/bits/sockaddr.h kita bisa melihat makro sbb:
--------------------
#define __SOCKADDR_COMMON(sa_prefix) \
  sa_family_t sa_prefix##family
----------------------

di mana makro tersebut akan mengambil parameter dari sa_prefix dan 
menggabungkanya sehingga akan tercipta variabel baru sin_family untuk 
struktur sockaddr_in di ip versi 4 
-------------
sa_prefix##family-> sin_family
--------------

karena di ip versi 6 prefix adl: sin6_

maka kita pakai: sin6_family



untuk protokol family ( domain ) ip versi 6 kita akan pakai : 
---------------------------------------
root@mywisdom-Vostro1310:/home/mywisdom/asm# cat cat 
/usr/include/bits/socket.h | grep INET6
cat: cat: No such file or directory
#define	PF_INET6	10	/* IP version 6.  */
#define	AF_INET6	PF_INET6
root@mywisdom-Vostro1310:/home/mywisdom/asm# 
----------------------------------------

kita akan pakai AF_INET6	 atau aliasnya adalah PF_INET6	, untuk 
membuat socket di ip versi 4, berikut ini perbedaannya untuk pembuatan 
socket di ip v 4 dan ip v 6:

ip versi 4 :
socket(AF_INET, SOCK_STREAM, 0) klo di bawah 0 ret val berarti gagal

untuk ip versi 6:
socket(AF_INET6, SOCK_STREAM, 0) klo di bawah 0 retval berarti gagal


struktur untuk ip versi 4 di atas tadi kita pakai struktur  (misal untuk 
mengisi struktur target host (mangsa kita)):

 server.sin_family=AF_INET;
 server.sin_port=htons(80);

sedangkan untuk ip versi 6 akan kita modifikasi sedikit menjadi:

server.sin6_family = AF_INET6;                              //sin6_family 
kita gunakan PF_INET6
server.sin6_len = sizeof(struct in6_addr);

sedangkan untuk fungsi gethostbyname() bisa kita diganti dengan fungsi:  
getaddrinfo 

klo mao tetep paket gethostbyname tambahkan ini :

res_init();
_res.options |= RES_USE_INET6;

berarti untuk gethostbyname kita pakai opsi ip versi 6

dengan menambah header: #include <resolve.h>

contoh untuk resolve:
------------
oot@mywisdom-Vostro1310:/home/mywisdom/asm# cat res6.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <resolv.h>

int main()
{
int soket,target;
//struktur hostent bisa dilihat di /usr/include/netdb.h , berguna untuk 
mengirimkan dns query
struct sockaddr_in6 addr;

//perhatikan di sini kita pakai res_init() dan _res.option kita pakai 
untuk support ip versi 6
res_init();
_res.options |= RES_USE_INET6;
   if((target=gethostbyname("ipv6.google.com")) == NULL)
    {
     printf("\n[-]fungsi gethostbyname gagal ! keluar dari program ! \n");
    exit(1);
    }
    else
    {
    printf ("\n[+]fungsi gethostbyname berhasil");
   
    
    }
      if((soket = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
  {
    printf("\ngagal menciptakan socket !! keluar dari program !\n");
    exit(1);
  }
 else
  {
  printf ("\n[+]di sini file deskriptor telah siap !! selanjutnya kita 
akan melakukan fungsi connect\n");
  }



}
root@mywisdom-Vostro1310:/home/mywisdom/asm# 
-----------------------------------



berikut ini adl sample klien dari artikel ipv6 socket programming (joonbok 
lee):

----------------
int main(int argc, char **argv){

  char Buffer[BUFFER_SIZE];
  char *Server = DEFAULT_SERVER;  
         /* "143.248.226.231"
             "2001:320:1a10:3:204:76ff:fe2f:cc34"
             "cosmos.kaist.ac.kr" */
  int Family = DEFAULT_FAMILY;
         /* AF_INET, AF_INET6,  AF_UNSPEC */
  int SocketType = DEFAULT_SOCKTYPE;
         /* SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, ... */
  char *Port = DEFAULT_PORT;
  int i, RetVal, AddrLen, AmountToSend;
  struct addrinfo Hints, *AddrInfo, *AI;
  socket ConnSocket;
  struct sockaddr_storage Addr;
  
  memset(&Hints, 0, sizeof(Hints));
Hints.ai_family = AF_UNSPEC;
  /* AF_INET: IPv4 address, AF_INET6: IPv6 address, AF_UNSPEC: IPv4 and 
IPv6 address */
Hints.ai_socktype = SOCK_STREAM;
  /* SOCK_STREAM: TCP, SOCK_DGRAM: UDP */
RetVal = getaddrinfo(Server, Port, &Hints, &AddrInfo);
if (RetVal != 0) {
  fprintf(stderr, "Cannot resolve address [%s] and port [%s], error %d: 
%s\n", Server, Port, RetVal, gai_strerror(RetVal));
  return -1;
}

for (AI = AddrInfo; AI != NULL; AI = AI->ai_next) {
  // Open a socket with the correct address family for this address.
  
 // if( AI->ai_family == AF_INET6 ){
    ConnSocket = socket(AI->ai_family, AI->ai_socktype, AI-> ai_protocol);
    if (ConnSocket == INVALID_SOCKET) continue;

    if (connect(ConnSocket, AI->ai_addr, AI->ai_addrlen) != SOCKET_ERROR) 
break;
 // }

}

freeaddrinfo(Addrinfo);

strcpy(Buffer, "Hello, world");
AmmountToSend = strlen(Buffer);
RetVal = send(ConnSocket, Buffer, AmmountToSend, 0);
RetVal = recv(ConnSocket, Buffer, Buffer, BUFFER_SIZE, 0);

closesocket(ConnSocket);

}
------------------------------


jadi untuk konek ke ipv6.google.com via port 80, kurang lebih 
implementasinya seperti ini :


pertama 2 kita tes resolve:
-------------------------------
/**ip versi 6 - klien - resolve only
resolv_ip_v6.c
modif sample klien dari artikel ipv6 socket programming (joonbok lee) **/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <resolv.h>
int main(int argc, char **argv)
{
  int Family = PF_INET6;
  int SocketType = SOCK_STREAM;
  int i, RetVal, AddrLen, AmountToSend;
  struct addrinfo Hints, *AddrInfo, *AI;
  int ConnSocket;
  struct sockaddr_storage Addr;
    memset(&Hints, 0, sizeof(Hints));
   Hints.ai_family = AF_INET6;
   Hints.ai_socktype = SOCK_STREAM;
    RetVal = getaddrinfo(argv[1], argv[2], &Hints, &AddrInfo);
if (RetVal != 0) 
 {
  fprintf(stderr, "Cannot resolve address [%s] and port [%s], error %d: 
%s\n", argv[1], argv[2], RetVal, gai_strerror(RetVal));
  exit(0);
  }
  else
  {
	printf("\n[+]getaddrinfo success !!!\n");  
	  
  }
}
-------------------------

tes getaddrinfo:
-----
root@mywisdom-Vostro1310:/home/mywisdom/asm# gcc -o resolve_ip_v6 
resolve_ip_v6.c
root@mywisdom-Vostro1310:/home/mywisdom/asm# ./resolve_ip_v6 
ipv6.google.com 80

[+]getaddrinfo success !!!
root@mywisdom-Vostro1310:/home/mywisdom/asm# 
---------


ok berikut ini adalah kode selengkapnya untuk konek ke ipv6.google.com :

-----------------
/**ip versi 6 - klien - resolve and connect to ipv6.google.com
konek_ip_v6.c
modif sample klien dari artikel ipv6 socket programming (joonbok lee) **/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <netdb.h>

int main()
{
	const char *target="ipv6.google.com";
	const char *port="80";

 int soket,  retval, retval2, addrlen;
 struct addrinfo Hints, *AddrInfo, *AI;
 memset(&Hints,0,sizeof(Hints));
 Hints.ai_family = AF_UNSPEC;
 Hints.ai_socktype = SOCK_STREAM;
 retval = getaddrinfo(target,port, &Hints, &AddrInfo);
 if(retval!=0)
	 {
  printf("Cannot resolve requested address\n");
  exit(0);
         }
	 else
	 {
		 printf("\n[+]getaddrinfo sukses");
	 }
 
 for(AI=AddrInfo;AI!=NULL;AI=AI->ai_next)
    {
    if(AI->ai_family==AF_INET6)
	    {
                 
if((soket=socket(AI->ai_family,AI->ai_socktype,AI->ai_protocol))<0)
			{
                 printf("\n[-] sorry seems like no ip v 6 support on tis 
box !\n");
                 exit(0);
                        }
   retval2=connect(soket,AI->ai_addr,AI->ai_addrlen);
   if(retval2<0)
           {
	        printf ("\n[-] sorry failed to connect !!!\n");
		   exit(0);
           }
	   else
	   {
                 printf("\n[+] ip v 6 connect to %s via port %s success 
!!!\n",target,port);
           }
  freeaddrinfo(AddrInfo);
 }
 }

}
----------------


selanjutnya persiapkan tcpdump untuk mengetes program ini:
------------------------------------
root@mywisdom-Vostro1310:/home/mywisdom/public_html/.backups# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:1c:23:56:0b:10  
          inet addr:118.136.75.36  Bcast:118.136.75.255  
Mask:255.255.255.0
          inet6 addr: fe80::21c:23ff:fe56:b10/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:327977 errors:0 dropped:0 overruns:0 frame:0
          TX packets:247696 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:424522875 (424.5 MB)  TX bytes:29671615 (29.6 MB)
          Interrupt:44 Base address:0xc000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:262330 errors:0 dropped:0 overruns:0 frame:0
          TX packets:262330 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:202463181 (202.4 MB)  TX bytes:202463181 (202.4 MB)

teredo    Link encap:UNSPEC  HWaddr 
00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet6 addr: 2001:0:53aa:64c:383a:45ca:8977:b4db/32 Scope:Global
          inet6 addr: fe80::ffff:ffff:ffff/64 Scope:Link
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1280  Metric:1
          RX packets:222 errors:0 dropped:0 overruns:0 frame:0
          TX packets:283 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:182160 (182.1 KB)  TX bytes:34097 (34.0 KB)

root@mywisdom-Vostro1310:/home/mywisdom/public_html/.backups# tcpdump -n 
-f -s 0 -X -vvv -i teredo port 80
tcpdump: WARNING: teredo: no IPv4 address assigned
tcpdump: listening on teredo, link-type RAW (Raw IP), capture size 65535 
bytes
---------------------------------------------------------

kompile dan jalankan:

----------------------

root@mywisdom-Vostro1310:/home/mywisdom/asm# gcc -o konek_ip_v6 
konek_ip_v6.c
root@mywisdom-Vostro1310:/home/mywisdom/asm# ./konek_ip_v6

[+]getaddrinfo sukses
[+] ip v 6 connect to ipv6.google.com via port 80 success !!!
root@mywisdom-Vostro1310:/home/mywisdom/asm# 
-----------------------------


ok di jendela tcpdump kita bisa lihat koneksi berhasil:

-------------------------------------------
06:47:42.105853 IP6 (hlim 64, next-header TCP (6) payload length: 40) 
2001:0:53aa:64c:383a:45ca:8977:b4db.43693 > 2404:6800:800b::93.80: Flags 
[S], cksum 0x6aa9 (correct), seq 3170785082, win 4880, options [mss 
1220,sackOK,TS val 6342831 ecr 0,nop,wscale 6], length 0
	0x0000:  6000 0000 0028 0640 2001 0000 53aa 064c  `....(.@....S..L
	0x0010:  383a 45ca 8977 b4db 2404 6800 800b 0000  8:E..w..$.h.....
	0x0020:  0000 0000 0000 0093 aaad 0050 bcfe 573a  ...........P..W:
	0x0030:  0000 0000 a002 1310 6aa9 0000 0204 04c4  ........j.......
	0x0040:  0402 080a 0060 c8af 0000 0000 0103 0306  .....`..........
---------------------------------------


kita bisa lihat 2001:0:53aa:64c:383a:45ca:8977:b4db.43693 > 
2404:6800:800b::93.80

ip v 6 kita: 2001:0:53aa:64c:383a:45ca:8977:b4db via source port 43693 
melakukan koneksi ke ip v 6 google:  2404:6800:800b::93 via destiantion 
port: 80


ok sy lanjutkan lain waktu jika ada kesempatan, see u