IPv6
- 작성자
- 고친과정
2008년 6월 24일 : 처음씀
2019년 5월 8일 : 최신 표준안을 기준으로 전체 내용 갱신
1.1. 개요
1.2. IPv6 (Internet Protocol v6) header
[PNG image (112.19 KB)]
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | Description | |
4bit Version | 8bit Traffic class | 20bit Flow labal | ↑↓8 bytes | ↑↓40 bytes(IPv6 header size) | |||||||||||||||||||||||||||||
16-bit Payload length | 8-bit Next header | 8bit Hop limit | |||||||||||||||||||||||||||||||
128bit Source address | ↑↓32 bytes | ||||||||||||||||||||||||||||||||
128bit Destination address | |||||||||||||||||||||||||||||||||
nexthdr | hdrlen | extension-header | ↑↓IPv6 extension header size | ↑↓Variable size | |||||||||||||||||||||||||||||
~ | |||||||||||||||||||||||||||||||||
nexthdr | hdrlen | extension-header | |||||||||||||||||||||||||||||||
~ | |||||||||||||||||||||||||||||||||
extension-header ... | |||||||||||||||||||||||||||||||||
Upper layer (ICMP/UDP/TCP/SCTP/AH/ESP/IPCOMP/...) | ↑↓Upper layer protocol |
- Version : IP version을 나타내며 IPv6의 경우 6
- Traffic class : Previously the type-of-service (ToS) field in IPv4, the traffic class field defines the class-of-service (CoS) priority of the packet. However, the semantics for this field (for example, DiffServ code points) are identical to IPv4.
- Flow label : The flow label identifies all packets belonging to a specific flow (that is, packet flows requiring a specific class of service CoS); routers can identify these packets and handle them in a similar fashion.
- Payload length : IPv6 payload의 크기를 나타냅니다. (즉, IPv6 기본 헤더를 제외한 IPv6 extension header 및 그 뒤에 오는 payload를 합산 크기)
- Next header : IPv6 header 바로 다음에 오는 프로토콜의 종류를 나타내는 번호를 나타냅니다.
- Hop limit : IPv4에서의 TTL(Time-To-Live)와 같은 개념으로 Hop 제한 개수를 나타냅니다.
- Source address : 출발지 주소
- Destination address : 목적지 주소
- extension-header : 확장헤더로써 필요에 의해서 nexthdr의 종류에 따라서 여러개를 덧붙여서 표현하며 사용되는 nexthdr 로는 NEXTHDR_HOP(0), NEXTHDR_ROUTING(43), NEXTHDR_FRAGMENT(44), NEXTHDR_AUTH(51), NEXTHDR_NONE(59), NEXTHDR_DEST(60) 등이 있습니다.
- IPv6 Fragmentation 에서는 NEXTHDR_HOP, NEXTHDR_ROUTING, NEXTHDR_DEST 등을 복사하고 NEXTHDR_FRAGMENT를 각 패킷에 추가삽입합니다.
- Upper layer : IPv6 header 와 IPv6 extension header 의 다음에는 상위계층의 프로토콜이 위치합니다.
IPv4 Header에서 IPv6 Header로의 변화에 있어서 Header는 다음과 같은 특징을 요약 할 수 있습니다.- IP Header Length 필드 제거
- ToS(Type of Service) 필드는 Traffic class 필드로 대체
- 전체 길이(Total Length) 필드는 Payload length 필드로 대체
- 식별(Identification), Flags, Fragment offset 필드 제거
- TTL(Time To Live) 필드는 Hop limit 이라고 명명
- Protocol 필드는 Next header 필드로 대체
- Option 필드는 확장 헤더(Extension header)로 구현
1.3. 주소표현 방법
- IPv6주소를 문자열로 표현하는 방법
- x:x:x:x:x:x:x:x형태로 표현되며 x는 16비트의 16진수로 표현합니다. 대소문자를 구분하지 않으며 각 항목의 상위 숫자 0은 생략해서 표기해도 되지만 각 항목에는 적어도 하나의 숫자가 있어야 합니다.
예1) fe80:0000:0000:0000:0213:d4ff:fe47:14d5 예2) fe80:0:0:0:213:d4ff:fe47:14d5
- 일반적으로 0비트가 많이 포함되므로 이를 간략히 표기할 방법을 나타내기 위해서 16비트 0의 연속된 항목을 "::" 기호로 대체할수 있습니다. 단, 이러한 축약기호는 단 한번만 사용할수 있습니다.
예1) fe80:0000:0000:0000:0213:d4ff:fe47:14d5 => fe80::213:d4ff:fe47:14d5 예2) 0:0:0:0:0:0:0:1 => ::1 예3) 0:0:0:0:0:0:0:0 => ::
- IPv4주소를 (포함하는) IPv6주소로 나타내는 경우 0:0:0:0:0:x:d.d.d.d 로 나타낼수 있습니다. 여기서 x는 16비트 16진수(0 또는 0xffff)이며 d는 8비트 10진수로 표현합니다.
- x:x:x:x:x:x:x:x형태로 표현되며 x는 16비트의 16진수로 표현합니다. 대소문자를 구분하지 않으며 각 항목의 상위 숫자 0은 생략해서 표기해도 되지만 각 항목에는 적어도 하나의 숫자가 있어야 합니다.
- 프리픽스(Prefix)주소 표현하는 방법
- 범주지정 주소 표현하는 방법 (참고: RFC4007 - IPv6 Scoped Address Architecture)
주소만으로는 어떤 범주인지를 명시하지 않았을 경우 오는 모호성을 해결할수 없는 경우가 있습니다. 이때 주소%영역 과 같이 표시하여 모호성을 해결합니다.
예1) fe80::213:d4ff:fe47:14d5%eth0
- C언어에서 관련 macro 또는 함수
- INET_ADDRSTRLEN : IPv4 주소문자열의 최대 길이 ("111.111.111.111", 15 + 1)
- INET6_ADDRSTRLEN : IPv6 주소문자열의 최대 길이 ("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255", 45 + 1)
- IN6_ARE_ADDR_EQUAL(a,b) : 두개의 IPv6 주소 비교
- int inet_pton(int af, const char *src, void *dst) : IPv4 및 IPv6 주소 문자열을 struct in_addr 및 struct in6_addr 구조체로 변경 (문자열 주소가 유효성 검사에 만족하지 않으면 -1 반환)
- const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) : IPv4 및 IPv6 주소가 저장된 struct in_addr 및 struct in6_addr 구조체를 문자열로 변경
1.4. 프리픽스 유형
주소유형 | 프리픽스 | 관련 C macro 또는 전역상수 | 비고(참고) |
미지정(Unspecified) | ::/128 | IN6_IS_ADDR_UNSPECIFIED(a), IN6ADDR_ANY_INIT, struct in6_addr in6addr_any | RFC4291 |
루프백(Lookback) | ::1/128 | IN6_IS_ADDR_LOOPBACK(a), IN6ADDR_LOOPBACK_INIT, struct in6_addr in6addr_loopback | RFC4291 |
IPv4 호환 IPv6 주소(IPv4-compatible IPv6 address) | ::<IPv4-address>/96, Ex) ::123.123.123.123 | IN6_IS_ADDR_V4COMPAT(a) | deprecated by RFC4291 |
IPv4 맵핑 IPv6 주소(IPv4-mapped IPv6 address) | ::ffff:<IPv4-address>/96, Ex) ::ffff:123.123.123.123 | IN6_IS_ADDR_V4MAPPED(a) | RFC4291 |
Well Known Prefix (IPv4-IPv6 Translation) | 64:ff9b::/96 | RFC6052 | |
Well Known Prefix (Local-Use IPv4-IPv6 Translation) | 64:ff9b:1::/48 | RFC8215 | |
Discard-Only Address Block | 100::/64 | RFC6666 | |
IETF Protocol Assignments | 2001::/23 | RFC2928 | |
TEREDO | 2001::/32 | RFC4380, RFC8190 | |
Port Control Protocol Anycast | 2001:1::1/128 | RFC7723 | |
Traversal Using Relays around NAT Anycast | 2001:1::2/128 | RFC8155 | |
Benchmarking | 2001:2::/48 | RFC5180, RFC Errata 1752 | |
AMT | 2001:3::/32 | RFC7450 | |
AS112-v6 | 2001:4:112::/48 | RFC7535 | |
Deprecated (previously ORCHID) | 2001:10::/28 | RFC4843 | |
ORCHIDv2 | 2001:20::/28 | RFC7343 | |
문서에만 사용할 목적의 전역 유니캐스트(Global unicast for document only) | 2001:db8::/32 | RFC3849 | |
6to4 | 2002::/16 | RFC3056 | |
Direct Delegation AS112 Service | 2620:4f:8000::/48 | RFC7534 | |
로컬 유니캐스트(Local unicast, Unique-Local) | fc00::/7 | RFC4193, RFC8190 | |
링크로컬 유니캐스트(Link-Local unicast) | fe80::/10 | IN6_IS_ADDR_LINKLOCAL(a) | RFC3513, RFC4291 |
사이트로컬 유니캐스트(Site-Local unicast) | fec0::/10 | IN6_IS_ADDR_SITELOCAL(a) | RFC4291, RFC3879 - Deprecating Site Local Addresses |
멀티캐스트(Multicast) | ff00::/8 | IN6_IS_ADDR_MULTICAST(a), IN6_IS_ADDR_MC_NODELOCAL(a), IN6_IS_ADDR_MC_LINKLOCAL(a), IN6_IS_ADDR_MC_SITELOCAL(a), IN6_IS_ADDR_MC_ORGLOCAL(a), IN6_IS_ADDR_MC_GLOBAL(a) | RFC3513, RFC4291 |
전역 유니캐스트(Global unicast) | 위의 유형을 제외한 나머지 모든 비트 | RFC4291 |
1.5. 미지정(Unspecified) 주소
주소 ::는 미지정 주소라고 하는데 이 주소는 할당되어서는 안되는 주소이며 자신의 주소가 없는 상태일때 임의로 패킷을 발송하기 위해서 사용할수 있는 경우가 있습니다. 이 주소는 결코 IPv6 라우터에 의해서 포워딩 되어서는 안됩니다.
1.6. 루프백(Loopback) 주소
주소 ::1는 루프백 주소로 자기자신과 통신할때 사용합니다. 이 주소는 어떠한 물리적 인터페이스장치에도 할당할수 없으며 가상 loopback 인터페이스에 할당됩니다. 목적지가 loopback 주소인 경우 외부로의 전송이 이루어질수 없으며 IPv6 라우터에 의해서 포워딩되지 않습니다.
1.8. 로컬 유니캐스트 주소(Local unicast address)
로컬 유니캐스트 주소는 링크(Link)와 사이트(Site) 두가지의 유형이 존재합니다.
- 로컬 유니캐스트 주소 (Local unicast address)
로컬 유니캐스트 주소 (Local unicast address) 7bits 1bit 40bits 16bits 64bits 1111 110 (fc00::/7) L Global ID Subnet ID Interface ID - Prefix: "FC00::/7"은 Local unicast address 임을 의미
- (IPv6-address & FE00::) == FC00::
- L: 1인 경우 지역내의 사용을 목적으로 할당된 경우를 의미, 0인 경우는 RFC4193 Section-3.2을 참고
- Global ID: 전역 식별자로 사용 (RFC4193 Section-3.2 참고)
- Subnet ID: 서브넷
- Interface ID: 인터페이스 식별부분
- Prefix: "FC00::/7"은 Local unicast address 임을 의미
- 링크 로컬 주소 (Link-local unicast address)
인접탐색과 자동주소와 같은 목적을 하기위해서 단일링크상에 라우터가 없는 경우를 위해서 사용됩니다. 라우터는 이 주소를 출발지 또는 목적지로 갖는 패킷을 다른 링크로 포워딩 하지 않아야 합니다.링크 로컬 주소 (Link-local unicast address) 10bits 54bits 64bits 1111 1110 10 (fe80::/10) 0 Interface ID 동일 링크(구역) 내에서 구별가능한 고유한 ID (Interface ID)를 생성하는 방법에는 크게 4가지를 생각해볼 수 있습니다.- 수동 구성 (Manually Configured: 직접 구역내 고유한 ID를 관리하여 설정)
- 수정 EUI-64로 생성하여 관리 (Modified EUI-64)
- MAC 주소(EUI-48) 로부터 EUI-64로 변환 (이 때 중간에 FF FE 를 채워 넣습니다.)
- "u" (universal/local) bit (상위 7번째 bit) 를 반전(또는 MAC인 경우는 universal 하므로 1로 set) 시킵니다.
- 예) 만약 내 PC의 인터페이스 eth0의 MAC 주소가 "6C:62:6D:A9:7E:D0" 인 경우 "fe80::6e62:6dff:fea9:7ed0/64"가 assign 될 수 있는 주소가 됩니다.
- MAC 주소는 48bits(6bytes)를 해당 인터페이스 eth0로부터 확인합니다.
48bits MAC 주소 "6C:62:6D:A9:7E:D0" MAC Address (EUI-48) OUI (Organizationally Unique Identifier) NIC(Network Interface Controller) Specific 0110 1100 0110 0010 0110 1101 1010 1001 0111 1110 1101 0000 (6C) (62) (6D) (A9) (7E) (D0) - 해당 MAC 주소를 상위 24 bits(3 bytes)와 하위 24 bits(3 bytes) 로 분리하고 그 사이에 FF FE 값 16 bits 를 추가합니다.
48bits MAC 주소를 상위 24bits와 하위 24bits로 분리하고 사이에 16bits인 FF FE 추가 상위 24bits Mark 16bits (FF FE) 하위 24bits OUI (Organizationally Unique Identifier) NIC(Network Interface Controller) Specific 0110 1100 0110 0010 0110 1101 1111 1111 1111 1110 1010 1001 0111 1110 1101 0000 (6C) (62) (6D) (FF) (FE) (A9) (7E) (D0) - 상위(MSB)에서 7번째 bit를 1로 set 합니다. (이 bit를 universal/local bit 라고 합니다. => 참고: RFC4291 IP Version 6 Addressing Architecture)
상위(MSB)에서 7번째 bit(universal/local bit)를 1로 set EUI-64 상위 24bits Mark 16bits (FF FE) 하위 24bits 상위(MSB) 7번째 bit set 0110 1110 0110 0010 0110 1101 1111 1111 1111 1110 1010 1001 0111 1110 1101 0000 (6E) (62) (6D) (FF) (FE) (A9) (7E) (D0) - 이제 IPv6 주소로 상위 10bit를 fe80::/10 으로 하고 하위 64bits를 위에서 계산한 Modified EUI-64 값으로 채워 넣으므로써 링크로컬 유일한 자동주소값이 만들어집니다. (최종 링크로컬 주소의 prefix는 64입니다.)
생성된 최종 Assign될 주소 "fe80::6e62:6dff:fea9:7ed0/64" IPv6 Link-local address by EUI-64 Prefix (fe80::/10) 0 상위 24bits Mark 16bits (FF FE) 하위 24bits 1111 1110 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0110 1110 0110 0010 0110 1101 1111 1111 1111 1110 1010 1001 0111 1110 1101 0000 (FE) (80) (00) (00) (00) (00) (00) (00) (6E) (62) (6D) (FF) (FE) (A9) (7E) (D0)
- MAC 주소는 48bits(6bytes)를 해당 인터페이스 eth0로부터 확인합니다.
- DHCPv6 서버에 의해서 관리 (DHCPv6 server)
- 임의의 수를 생성하여 관리 (Auto-generated pseudo random number)
- 사이트 로컬 주소 (Site-local unicast address)
전역 프리픽스 없이 사이트 내에서 통신하기 위해서 사용합니다. IPv4망에서의 사설망과 흡사하다고 보면 될듯 합니다.사이트 로컬 주소 (Site-local unicast address) 10bits 54bits 64bits 1111 1110 11 (fec0::/10) Subnet ID Interface ID
1.9. 애니캐스트(Anycast) 주소
애니캐스트는 여러 주소유형중에서 하나를 사용하여 유니캐스트 주소공간으로부터 할당됩니다. 때문에 애니캐스트 주소는 유니캐스트 주소와 식별이 안됩니다.
NOTE: 필자는 현재 애니캐스트를 구체적으로 머리속에 그리지 못하고 있습니다. 여러가지 제약적 조건이 발생될수 있는 사항에 대해서도 복잡할뿐. 좀더 공부후에 정리계획입니다.
NOTE: 필자는 현재 애니캐스트를 구체적으로 머리속에 그리지 못하고 있습니다. 여러가지 제약적 조건이 발생될수 있는 사항에 대해서도 복잡할뿐. 좀더 공부후에 정리계획입니다.
1.10. 멀티캐스트(Multicast) 주소
멀티캐스트 주소는 다음과 같은 포맷으로 구성됩니다. (RFC3306)
멀티캐스트 주소는 다음과 같은 새로운 포맷으로 구성됩니다. (RFC3306)
flags의 4개 bits 는 다음과 같이 구성됩니다.
T가 0인 경우 IANA가 영구적으로 할당한 멀티캐스트 주소임을 표시합니다. 1인 경우는 그 외의 멀티캐스트 주소를 의미합니다. PIM6-SSM 의 경우 P와 T가 모두 1인 주소(ff3x::/32) 를 사용합니다.
8bits | 4bits | 4bits | 112bits |
1111 1111 | flags | scope | Group ID |
8bits | 4bits | 4bits | 8bits | 8bits | 64bits | 32bits |
1111 1111 | flags | scope | reserved(MUST be zero) | plen | network prefix | group ID |
- P 가 0인 경우 : indicates a multicast address that is not assigned based on the network prefix.
- P 가 1인 경우 : indicates a multicast address that is assigned based on the network prefix. (이 경우 반드시 T는 함께 1이어야 함)
scope는 다음과 같이 범주를 제한하는 용도로 사용됩니다.Scope 값 값 설명 비고(참고) 0 예약 (reserved) RFC4291, RFC7346 1 로컬 범위의 인터페이스 (interface-local scope) RFC4291, RFC7346 2 로컬 범위의 링크 (link-local scope) RFC4291, RFC7346 3 예약 (reserved) / 로컬 범위의 서브넷 (subnet) / Realm-Local scope RFC4291, RFC7346 4 로컬 범위의 관리 (admin-local scope) RFC4291, RFC7346 5 로컬 범위의 사이트 (site-local scope) RFC4291, RFC7346 6 할당되지 않음 (unassigned) 7 할당되지 않음 (unassigned) 8 로컬 범위의 조직 (organization-local scope) RFC4291, RFC7346 9 할당되지 않음 (unassigned) 10 할당되지 않음 (unassigned) 11 할당되지 않음 (unassigned) 12 할당되지 않음 (unassigned) 13 할당되지 않음 (unassigned) 14 글로벌 범위 (global scope) RFC4291, RFC7346 15 예약 (reserved) RFC4291, RFC7346
1.11. 프로그래밍 관점에서의 포팅
IPv6로의 포팅에서의 주요 핵심 키워드 AF_INET, AF_INET6, PF_INET, PF_INET6, IPPROTO_IP, IPPROTO_IPV6, IP_ADD_MEMBERSHIP, IPV6_JOIN_GROUP, IP_TTL, IP_MULTICAST_TTL, IPV6_UNICAST_HOPS, IPV6_MULTICAST_HOPS, struct sockaddr_storage, struct sockaddr_in, struct sockaddr_in6, struct in_addr, struct in6_addr, getaddrinfo, struct addrinfo
- getaddrinfo 사용예제
- getaddrinfo.tar.gz (1.44 KB)
- getaddrinfo.tar.gz (1.44 KB)
- TCP 연결 흐름구조
iec_sockaddr_t s_remote, s_bind; iec_socket_t s_socket; iec_const_string_t s_remote_address; iec_socket_t s_socket; s_remote_address = "http://test.minzkn.com:80/index.php"; /* 먼저 remote 주소의 sockaddr을 설정한다. (node는 uri를 허용한다) */ if(iec_xapi_resolve_sockaddr(AF_UNSPEC, (iec_sockaddr_t *)(&s_remote), s_remote_address, iec_xapi_int_const(80), def_iec_true) == def_iec_true) { /* 설정된 s_remote의 family를 bind address family 로 결정한다. (node는 uri를 허용하지 않는다) */ if(iec_xapi_resolve_sockaddr(s_remote.ss.ss_family, (iec_sockaddr_t *)(&s_bind), def_iec_null_string, iec_xapi_int_const(0), def_iec_false) != def_iec_error) { /* 결정된 bind address family에 맞는 소켓을 연다. */ s_socket = iec_xapi_socket(s_bind.ss.ss_family, SOCK_STREAM, IPPROTO_TCP); if(s_socket != def_iec_invalid_socket) { if(iec_xapi_bind(s_socket, (iec_sockaddr_t *)(&s_bind)) == def_iec_true) { if(iec_xapi_connect(s_socket, (iec_sockaddr_t *)(&s_remote), s_timeout) == def_iec_true) { /* connected */ } } s_socket = iec_xapi_closesocket(s_socket); } } }
- TCP listen과정
iec_const_string_t s_bind_address; iec_int_t s_bind_port; iec_sockaddr_t s_sockaddr_bind, s_sockaddr_accept; iec_socket_t s_listen_socket, s_accept_socket; iec_socklen_t s_socklen; if(iec_xapi_resolve_sockaddr(AF_UNSPEC, (iec_sockaddr_t *)(&s_sockaddr_bind), s_bind_address, s_bind_port, def_iec_false) == def_iec_true) { s_listen_socket = iec_xapi_socket(s_sockaddr_bind.ss_family, SOCK_STREAM, IPPROTO_TCP); if(s_listen_socket != def_iec_invalid_socket) { if(iec_xapi_bind(s_listen_socket, (iec_sockaddr_t *)(&s_sockaddr_bind), (iec_socklen_t)sizeof(s_sockaddr_bind)) == def_iec_true) { if(iec_xapi_listen(s_listen_socket, def_iec_max_backlog) == def_iec_true) { for(; /* exit condition */ ;) { s_socklen = (iec_socklen_t)sizeof(s_sockaddr_accept); s_accept_socket = iec_xapi_accept(s_listen_socket, (iec_sockaddr_t *)(&s_sockaddr_accept), (iec_socklen_t *)(&s_socklen), 0/* timeout */); if(s_accept_socket != def_iec_invalid_socket) { if(s_sockaddr_accept.ss_family == AF_INET) { /* IPv4 accept process */ } else if(s_sockaddr_accept.ss_family == AF_INET6) { /* IPv6 accept process */ } else { /* Unspec accept process */ } iec_xapi_closesocket(s_accept_socket); } else { iec_xapi_load_balance(); } } } } iec_xapi_closesocket(s_listen_socket); } }
- Multicast join
- IPv4 multicast join : IPv4에서는 interface의 IP를 이용하여 join한다.
struct ip_mreq { struct in_addr imr_multiaddr; /* IP multicast address of group */ struct in_addr imr_interface; /* local IP address of interface */ }; setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (struct ip_mreq *)(&r), sizeof(struct ip_mreq));
- IPv6 multicast join : ifindex 로 interface를 join한다는 점이 IPv4와 다름.
struct ipv6_mreq { /* IPv6 multicast address of group */ struct in6_addr ipv6mr_multiaddr; /* local IPv6 address of interface */ int ipv6mr_ifindex; }; setsockopt(socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, (struct ipv6_mreq *)(&r), sizeof(struct ipv6_mreq));
- IPv4 multicast join : IPv4에서는 interface의 IP를 이용하여 join한다.
- UDP TTL(HOPS)
- IPv4에서의 TTL
int s_ttl; /* unicast ttl */ setsockopt(socket, IPPROTO_IP, IP_TTL, &s_ttl, sizeof(s_ttl)); /* multicast ttl */ setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL, &s_ttl, sizeof(s_ttl));
- IPv6에서의 HOPS
int s_hops; /* unicast ttl */ setsockopt(socket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &s_hops, sizeof(s_hops)); /* multicast ttl */ setsockopt(socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &s_hops, sizeof(s_hops));
- IPv4에서의 TTL
- FTP protocol 의 확장
기존의 PORT, PASV가 IPv4만을 위한 사양이기에 이에 대한 확장이 요구되었는데 새롭게 EPRT, EPSV로 정의된 명령이 추가되어 IPv6에서의 FTP data session을 명시할수 있게 되었습니다. FTP protocol의 IPv6에 관한 확장 프로토콜에 대한 표준은 rfc2428.txt 에서 명시하고 있습니다.
EPRT<space><d><net-prt><d><net-addr><d><tcp-port><d> 여기서 <d>는 구분자로써 '|'을 사용하는것으로 되어 있습니다. <net-prt>는 '1'은 IPv4를 의미하고 '2'는 IPv6를 의미합니다. EPSV<space><net-prt> 229 Entering Extended Passive Mode (|||<tcp-port>|) EPSV에 대한 응답형식은 EPRT와 유사합니다. EPSV의 <net-prt>에는 '1', '2', 'ALL'이 사용될수 있다고 합니다. 하지만 실험결과 'ALL'은 제대로 동작하지 않는 경우가 많았습니다.
- Linux Kernel 에서의 IPv6 extension header 접근에 대한 간략한 예시
/* s_ipv6hdr : IPv6 Header에 대한 pointer 입력 s_nexthdr_ptr : nexthdr 가 명시된 부분에 대한 pointer 입력 반환 : IPv6 extension header 의 크기 반환 */ size_t hwport_ipv6_extension_header_size(struct ipv6hdr *s_ipv6hdr, u8 *s_nexthdr_ptr) { size_t s_offset = (size_t)0; /* payload start offset == 40 */ u8 *s_u8_ptr = (u8 *)(&s_ipv6hdr[1]); /* payload start entry */ u8 s_nexthdr = s_ipv6hdr->nexthdr; struct ipv6_opt_hdr *s_exthdr; size_t s_exthdr_size; while(ipv6_ext_hdr(s_nexthdr)) { if(s_nexthdr == NEXTHDR_NONE) { break; } if(unlikely((s_offset + sizeof(struct ipv6_opt_hdr)) > ((size_t)s_ipv6hdr->payload_len))) { /* invalid extension header coding */ s_offset = (size_t)s_ipv6hdr->payload_len; s_nexthdr = NEXTHDR_NONE; break; } s_exthdr = (struct ipv6_opt_hdr *)(&s_u8_ptr[s_offset]); if(s_nexthdr == NEXTHDR_FRAGMENT) { s_exthdr_size = (size_t)8u; } else if(s_nexthdr == NEXTHDR_AUTH) { /* AH header */ s_exthdr_size = (s_exthdr->hdrlen + 2) << 2; } else { s_exthdr_size = ipv6_optlen(s_exthdr); } if(unlikely((s_offset + s_exthdr_size) > ((size_t)s_ipv6hdr->payload_len))) { /* invalid extension header size coding */ s_offset = (size_t)s_ipv6hdr->payload_len; s_nexthdr = NEXTHDR_NONE; break; } s_nexthdr = s_exthdr->nexthdr; s_offset += s_exthdr_size; } if(s_nexthdr_ptr != ((u8 *)0)) { *s_nexthdr_ptr = s_nexthdr; } return(s_offset); } /* s_ipv6hdr : IPv6 Header에 대한 pointer 입력 s_transport_size_ptr : Transport layer 의 크기를 반환 (IPv6 Header 및 IPv6 extension header를 제외한 IPv6 payload 의 크기) s_nexthdr_ptr : nexthdr 가 명시된 부분에 대한 pointer 입력 반환 : Transport layer에 대한 pointer 반환 */ void *hwport_ipv6_transport_entry(struct ipv6hdr *s_ipv6hdr, size_t *s_transport_size_ptr, u8 *s_nexthdr_ptr) { u8 *s_u8_ptr = (u8 *)s_ipv6hdr; size_t s_header_size = sizeof(struct ipv6hdr); size_t s_ext_header_size = hwport_ipv6_extension_header_size(s_ipv6hdr, s_nexthdr_ptr); if(s_transport_size_ptr != ((size_t *)0)) { *s_transport_size_ptr = ((size_t)s_ipv6hdr->payload_len) - s_ext_header_size; } return((void *)(&s_u8_ptr[s_header_size + s_ext_header_size])); } /* 사용예 */ struct sk_buff *skb; /* 인입된 패킷을 담고 있는 skbuff pointer */ size_t s_ipv6h_size = sizeof(struct ipv6hdr); /* IPv6 Header 크기 (IPv6 extension header는 제외) */ struct ipv6hdr *s_ipv6hdr = ip_hdr(skb); /* skb로부터 IPv4/IPv6 Header 위치 pointer */ u8 s_nexthdr; /* IPv6 externsion header 를 건너뛰고 마지막 nexthdr */ size_t s_ipv6h_ext_size; /* IPv6 extension header 크기 */ void *s_transport_entry; /* Transport layer entry pointer */ size_t s_transport_size; /* Transport layer 크기 */ ASSERT(s_ipv6hdr->version == 6); s_ipv6h_ext_size = hwport_ipv6_extension_header_size(s_ipv6hdr, (u8 *)(&s_nexthdr)); s_transport_entry = hwport_ipv6_transport_entry(s_ipv6hdr, (size_t *)(&s_transport_size), (u8 *)(&s_nexthdr)); if(s_nexthdr == IPPROTO_TCP) { struct tcphdr *s_tcphdr = (struct tcphdr *)s_transport_entry; } else if(s_nexthdr == IPPROTO_UDP) { } else { ... }
1.12. 참고자료
- OSI 7 계층모델
- IPv4
- Computing the Internet Checksum (RFC1071)
- TCP(Transmission Control Protocol)
- ASCII 표
- Ethernet frame
- https://en.wikipedia.org/wiki/Address_Resolution_Protocol
- https://en.wikipedia.org/wiki/Reverse_Address_Resolution_Protocol
- https://www.juniper.net/documentation/en_US/junose10.3/information-products/topic-collections/swconfig-ip-ipv6/id-37225a.html
- http://www.cisco.com/en/US/technologies/tk648/tk872/technologies_white_paper0900aecd8054d37d.html
- RFC791 - INTERNET PROTOCOL / DARPA INTERNET PROGRAM / PROTOCOL SPECIFICATION
- RFC826 - An Ethernet Address Resolution Protocol or Converting Network Protocol Addresses to 48.bit Ethernet Address for Transmission on Ethernet Hardware
- RFC903 - A Reverse Address Resolution Protocol
- RFC1112 - Host Extensions for IP Multicasting
- RFC1466 - Guidelines for Management of IP Address Space
- RFC1770 - ASSIGNED NUMBERS
- RFC1884 - IP Version 6 Addressing Architecture
- RFC2365 - Administratively Scoped IP Multicast
- RFC2373 - IP Version 6 Addressing Architecture
- RFC2390 - Inverse Address Resolution Protocol
- RFC2460 - Internet Protocol, Version 6 (IPv6) Specification
- RFC2928 - Initial IPv6 Sub-TLA ID Assignments
- RFC3041 - Privacy Extensions for Stateless Address Autoconfiguration in IPv6
- RFC3053 - IPv6 Tunnel Broker
- RFC3056 - Connection of IPv6 Domains via IPv4 Clouds
- RFC3306 - Unicast-Prefix-based IPv6 Multicast Addresses
- RFC3344 - IP Mobility Support for IPv4
- RFC3484 - Default Address Selection for Internet Protocol version 6 (IPv6)
- RFC3513 - Internet Protocol Version 6 (IPv6) Addressing Architecture
- RFC3633 - IPv6 Prefix Options for Dynamic Host Configuration Protocol (DHCP) version 6
- RFC3849 - IPv6 Address Prefix Reserved for Documentation
- RFC3879 - Deprecating Site Local Addresses
- RFC3927 - Dynamic Configuration of IPv4 Link-Local Addresses
- RFC3956 - Embedding the Rendezvous Point (RP) Address in an IPv6 Multicast Address
- RFC4007 - IPv6 Scoped Address Architecture
- RFC4122 - A Universally Unique IDentifier (UUID) URN Namespace
- RFC4193 - Unique Local IPv6 Unicast Addresses
- RFC4291 - IP Version 6 Addressing Architecture
- RFC4380 - Teredo: Tunneling IPv6 over UDP through Network Address Translations (NATs)
- RFC4607 - Source-Specific Multicast for IP
- RFC4843 - An IPv6 Prefix for Overlay Routable Cryptographic Hash Identifiers (ORCHID)
- RFC4941 - Privacy Extensions for Stateless Address Autoconfiguration in IPv6
- RFC5180 - IPv6 Benchmarking Methodology for Network Interconnect Devices
- RFC5214 - Intra-Site Automatic Tunnel Addressing Protocol (ISATAP)
- RFC5227 - IPv4 Address Conflict Detection
- RFC5342 - IANA Considerations and IETF Protocol Usage for IEEE 802 Parameters
- RFC5942 - IPv6 Subnet Model: The Relationship between Links and Subnet Prefixes
- RFC5952 - A Recommendation for IPv6 Address Text Representation
- RFC6052 - IPv6 Addressing of IPv4/IPv6 Translators
- RFC6294 - Survey of Proposed Use Cases for the IPv6 Flow Label
- RFC6603 - Prefix Exclude Option for DHCPv6-based Prefix Delegation
- RFC6437 - IPv6 Flow Label Specification
- RFC6666 - A Discard Prefix for IPv6
- RFC6724 - Default Address Selection for Internet Protocol Version 6 (IPv6)
- 출발지 주소 선택 기준
- 동일한 주소 선호 (즉, 출발지 IP = 목적지 IP)
- 적절한 범위(scope)를 선호하십시오.
- 비추천(deprecated) 주소 피하기
- 홈 주소 선호 (모바일 IPv6)
- 나가는 인터페이스 (즉, 내부 전달(forward) 인터페이스) 선호
- 5에서 다음 홉 광고 된 프리픽스 주소 선호
- 일치하는 레이블(label) 선호
- 임시(Temporary) 주소 선호
- 가장 긴 일치하는 접두어 사용 (Longest matching prefix)
- 출발지 주소 선택 기준
- RFC7136 - Significance of IPv6 Interface Identifiers
- RFC7343 - An IPv6 Prefix for Overlay Routable Cryptographic Hash Identifiers Version 2 (ORCHIDv2)
- RFC7346 - IPv6 Multicast Address Scopes
- RFC7371 - Updates to the IPv6 Multicast Addressing Architecture
- RFC7450 - Automatic Multicast Tunneling
- RFC7534 - AS112 Nameserver Operations
- RFC7535 - AS112 Redirection Using DNAME
- RFC7723 - Port Control Protocol (PCP) Anycast Addresses
- RFC7954 - Locator/ID Separation Protocol (LISP) Endpoint Identifier (EID) Block
- RFC8064 - Recommendation on Stable IPv6 Interface Identifiers
- RFC8155 - Traversal Using Relays around NAT (TURN) Server Auto Discovery
- RFC8190 - Updates to the Special-Purpose IP Address Registries
- RFC8215 - Local-Use IPv4/IPv6 Translation Prefix
- IANA IPv4 Address Space Registry
- Internet Protocol Version 6 Address Space
- IANA IPv4 Special-Purpose Address Registry
- IANA IPv6 Special-Purpose Address Registry
- IPv6 Global Unicast Address Assignments
- https://developers.cloudflare.com/1.1.1.1/setting-up-1.1.1.1/
- Interface ID, Interface Identifier
- The ipv6calc Homepage
- Understanding IPv6 EUI-64 Bit Address
- Organizationally unique identifier
- Guidelines for Use of Extended Unique Identifier (EUI), Organizationally Unique Identifier (OUI), and Company ID (CID)
- Windows에서의 Dual-Stack IP 프로그래밍에서의 IPV6_V6ONLY socket option에 대하여
- 이더넷 (Ethernet)
- ICMP
- NAT(Network Address Translation)
- IPv6를 지원하는 URL주소들 목록
- https://vsix.kr/frt/biz/bbs/layout01/selectBoardArticle.do?bbsId=BBSMSTR_000000000022&nttId=20019
- https://www.cisco.com/en/US/technologies/tk648/tk872/technologies_white_paper0900aecd8054d37d.html
- http://www.ipv6forum.com/
- https://yurmagccie.wordpress.com/2016/11/05/ipv6-part-1/
- https://m.blog.naver.com/PostView.nhn?blogId=ree31206&logNo=44158348&proxyReferer=https%3A%2F%2Fwww.google.com%2F
- https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/ipv6/configuration/15-2mt/ip6-15-2mt-book/ip6-uni-routing.html
- https://vincent.bernat.ch/en/blog/2017-ipv6-route-lookup-linux
- https://etherealmind.com/ipv6-which-address-multiple-ipv6-address-default-address-selection/
- http://biplane.com.au/blog/?p=22
- http://egloos.zum.com/dstein/v/2324104
- https://blog.bravi.org/?p=506
- http://computer-outlines.over-blog.com/article-static-ipv6-networking-part-10-address-selection-rfc-6724-119131859.html
- https://mirrors.deepspace6.net/Linux+IPv6-HOWTO/resolver.html
- https://vsix.kr/frt/biz/contents/0000000008/getContents.do
- Service Name and Transport Protocol Port Number Registry
- https://m.blog.naver.com/PostView.nhn?blogId=nackji80&logNo=220525751654&proxyReferer=https%3A%2F%2Fwww.google.com%2F
- http://www.ktword.co.kr/abbr_view.php?m_temp1=5236
- Multicast Routing Protocol, Multicast Routing
- IPv6 Multicast Address IPv6 멀티캐스트 주소
- IPv6 기반 SSM 기술 동향!
- MLDv2 linux kernel
- IP Multicast: PIM Configuration Guide, Cisco IOS XE Release 3S
- IPv6 멀티캐스트 망 구축 및 IPv6 멀티캐스트 응용 설치
- IPv6 Multicast Over TEIN - 테스트 환경 정보
- IPv6 Multicast Test Tools (ssmpingd, asmping/ssmping)
- IPv6 Multicast Test Tools (ssm-iperf)
- Source-specific multicast
- PIM-Static-Sparse-Mode-PIM-SSM-2 Bidir
- PIM-SSM은 오직 (S,G) PIM-State 만 사용함. (즉, Shared Tree를 사용하지 않음)
- How to build an IPv6 tunnel over IPv4 GRE and IPSec or Set up your own 6in4 tunnel broker with Free Software
- https://github.com/troglobit/pim6sd
- https://github.com/Quagga/quagga/blob/master/pimd/CAVEATS
- https://github.com/hugosantos/mrd6
- ISC - DHCPv6 Prefix Length Mode
- Chapter: IPv6 Multicast: PIM Source-Specific Multicast
- https://www.calix.com/content/calix/en/site-prod/library-html/systems-products/e-series/sysop/leg-e-ud/4-1e3-35/ug/index.htm?toc36210203.htm?63338_1.htm
- IPv6 Extension Header, Route Header 패킷 분석 - 땅콩킹땅콩