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 `....(
[email protected]
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