IPv6

IPv6 (Internet Protocol v6) header


IPv6 Header 구조
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
16-bit Payload length 8-bit Next header 8bit Hop limit
128bit Source address ↑↓32 bytes
128bit Destination address

  • Version : Indicates the version of the Internet Protocol.
  • 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 : Previously the total length field in IPv4, the payload length field specifies the length of the IPv6 payload.
  • Next header : Previously the protocol field in IPv4, the Next Header field indicates the next extension header to examine.
  • Hop limit : Previously the time-to-live (TTL) field in IPv4, the hop limit indicates the maximum number of hops allowed.
  • Source address : Identifies the address of the source node sending the packet.
  • Destination address : Identifies the final destination node address for the packet.

주소표현 방법

  • IPv6주소를 문자열로 표현하는 방법

    1. 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

    2. 일반적으로 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 => ::

    3. IPv4주소를 (포함하는) IPv6주소로 나타내는 경우 x:x:x:x:x:x:d.d.d.d 로 나타낼수 있습니다. 여기서 x는 16비트 16진수이며 d는 8비트 10진수로 표현합니다.

      예1) 0:0:0:0:0:0:192.168.0.1 => ::192.168.0.1 예2) 0:0:0:0:0:ffff:192.168.0.2 => ::ffff:192.168.0.2

  • 프리픽스(Prefix)주소 표현하는 방법
    "IPv6주소/프리픽스길이" 로 표현하며 IPv4의 CIDR표현과 매우 유사한 방법으로 인접한 IP대역을 그룹화 하여 가르킬때 사용합니다. 프리픽스 표현에서 선행하는 0은 축약하여 표현할수 있지만 후행 0은 생략해서는 안됩니다.

    예1) fe80:0000:0000:0000:0213:d4ff:fe47:14d5/64 => fe80::215:17ff:fe26:c3ed/64

  • 범주지정 주소 표현하는 방법

    주소만으로는 어떤 범주인지를 명시하지 않았을 경우 오는 모호성을 해결할수 없는 경우가 있습니다. 이때 주소%영역 과 같이 표시하여 모호성을 해결합니다.

    예1) fe80::213:d4ff:fe47:14d5%eth0

프리픽스 유형

IPv6 주소 Scope
주소유형 프리픽스
미지정 ::/128
루프백 ::1/128
멀티캐스트 ff00::/8
로컬 유니캐스트(링크) fe80::/10
로컬 유니캐스트(사이트) fec0::/10
전역 유니캐스트(Global) 위의 유형을 제외한 나머지 모든 비트

미지정(Unspecified) 주소

주소 ::는 미지정 주소라고 하는데 이 주소는 할당되어서는 안되는 주소이며 자신의 주소가 없는 상태일때 임의로 패킷을 발송하기 위해서 사용할수 있는 경우가 있습니다. 이 주소는 결코 IPv6 라우터에 의해서 포워딩 되어서는 안됩니다.

루프백(Loopback) 주소

주소 ::1는 루프백 주소로 자기자신과 통신할때 사용합니다. 이 주소는 어떠한 물리적 인터페이스장치에도 할당할수 없으며 가상 loopback 인터페이스에 할당됩니다. 목적지가 loopback 주소인 경우 외부로의 전송이 이루어질수 없으며 IPv6 라우터에 의해서 포워딩되지 않습니다.

IPv4주소를 포함하는 IPv6주소

IPv4주소를 포함하는 IPv6주소의 유형은 두가지가 존재합니다.

  1. IPv4 망내에서 IPv6 패킷을 터널링하기위한 기술에 사용되는 IPv4 호환 IPv6주소
    0:0:0:0:0:0000:IPv4주소

  2. 전역 IPv4주소를 IPv6로 표현하기 위한 IPv4 맵드 IPv6주소
    0:0:0:0:0:ffff:IPv4주소

로컬 유니캐스트 주소

로컬 유니캐스트 주소는 링크와 사이트 두가지의 유형이 존재합니다.

  1. 링크 로컬 주소

    인접탐색과 자동주소와 같은 목적을 하기위해서 단일링크상에 라우터가 없는 경우를 위해서 사용됩니다.
    10bits 54bits 64bits
    1111 1110 10 0 Interface ID

  2. 사이트 로컬 주소

    전역 프리픽스 없이 사이트 내에서 통신하기 위해서 사용합니다. IPv4망에서의 사설망과 흡사하다고 보면 될듯 합니다.
    10bits 38bits 16bits 64bits
    1111 1110 11 0 Subnet ID Interface ID

애니캐스트 주소

애니캐스트는 여러 주소유형중에서 하나를 사용하여 유니캐스트 주소공간으로부터 할당됩니다. 때문에 애니캐스트 주소는 유니캐스트 주소와 식별이 안됩니다.

NOTE: 필자는 현재 애니캐스트를 구체적으로 머리속에 그리지 못하고 있습니다. 여러가지 제약적 조건이 발생될수 있는 사항에 대해서도 복잡할뿐. 좀더 공부후에 정리계획입니다.

멀티캐스트 주소

멀티캐스트 주소는 다음과 같은 포맷으로 구성됩니다.
8bits 4bits 4bits 112bits
1111 1111 flags scope Group ID

flags는 다음과 같이 구성됩니다.
0 0 0 I
상위 3개비트는 0으로 예약되어 있으며 I는 0인 경우 IANA가 영구적으로 할당한 멀티캐스트 주소임을 표시합니다. 1인 경우는 그 외의 멀티캐스트 주소를 의미합니다.

scope는 다음과 같이 범주를 제한하는 용도로 사용됩니다.
Scope 값
설명
0 예약
1 로컬 범위의 인터페이스 (interface-local)
2 로컬 범위의 링크 (link-local)
3 로컬 범위의 서브넷 (subnet)
4 로컬 범위의 관리 (admin-local)
5 로컬 범위의 사이트 (site-local)
6 할당되지 않음
7 할당되지 않음
8 로컬 범위의 조직 (organization-local)
9 할당되지 않음
10 할당되지 않음
11 할당되지 않음
12 할당되지 않음
13 할당되지 않음
14 글로벌 범위 (global)
15 예약

프로그래밍 관점에서의 포팅

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 사용예제
  • 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));
      


  • 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));
      


  • 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'은 제대로 동작하지 않는 경우가 많았습니다.
    





/*

[ FrontPage | PrintView | RawView | RSS ]

Copyright ⓒ MINZKN.COM
All Rights Reserved.

MINZKN

----

*/