[要約] RFC 2292はIPv6のための高度なソケットAPIであり、IPv6ネットワークでのソケット通信をサポートするための機能を提供します。このRFCの目的は、IPv6の普及とネットワーク通信の進化を促進することです。

Network Working Group                                        W. Stevens
Request for Comments: 2292                                   Consultant
Category: Informational                                       M. Thomas
                                                              AltaVista
                                                          February 1998
        

Advanced Sockets API for IPv6

IPv6用の高度なソケットAPI

Status of this Memo

本文書の状態

This memo provides information for the Internet community. It does not specify an Internet standard of any kind. Distribution of this memo is unlimited.

このメモは、インターネットコミュニティに情報を提供します。いかなる種類のインターネット標準も規定していません。このメモの配布は無制限です。

Copyright Notice

著作権表示

Copyright (C) The Internet Society (1998). All Rights Reserved.

Copyright(C)The Internet Society(1998)。全著作権所有。

Abstract

概要

Specifications are in progress for changes to the sockets API to support IP version 6 [RFC-2133]. These changes are for TCP and UDP-based applications and will support most end-user applications in use today: Telnet and FTP clients and servers, HTTP clients and servers, and the like.

IPバージョン6 [RFC-2133]をサポートするためのソケットAPIの変更に関する仕様が進行中です。これらの変更はTCPおよびUDPベースのアプリケーションに対するものであり、現在使用されているほとんどのエンドユーザーアプリケーション(TelnetおよびFTPクライアントとサーバー、HTTPクライアントとサーバーなど)をサポートします。

But another class of applications exists that will also be run under IPv6. We call these "advanced" applications and today this includes programs such as Ping, Traceroute, routing daemons, multicast routing daemons, router discovery daemons, and the like. The API feature typically used by these programs that make them "advanced" is a raw socket to access ICMPv4, IGMPv4, or IPv4, along with some knowledge of the packet header formats used by these protocols. To provide portability for applications that use raw sockets under IPv6, some standardization is needed for the advanced API features.

しかし、IPv6で実行される別のクラスのアプリケーションが存在します。これらを「高度な」アプリケーションと呼びます。現在、これには、Ping、Traceroute、ルーティングデーモン、マルチキャストルーティングデーモン、ルーター検出デーモンなどのプログラムが含まれています。これらのプログラムで通常使用されるAPI機能は、これらを「高度」にして、ICMPv4、IGMPv4、またはIPv4にアクセスするためのrawソケットであり、これらのプロトコルで使用されるパケットヘッダー形式に関する知識も備えています。 IPv6でrawソケットを使用するアプリケーションに移植性を提供するには、高度なAPI機能の標準化が必要です。

There are other features of IPv6 that some applications will need to access: interface identification (specifying the outgoing interface and determining the incoming interface) and IPv6 extension headers that are not addressed in [RFC-2133]: Hop-by-Hop options, Destination options, and the Routing header (source routing). This document provides API access to these features too.

一部のアプリケーションがアクセスする必要があるIPv6の他の機能があります。インターフェイス識別(発信インターフェイスの指定と着信インターフェイスの決定)および[RFC-2133]でアドレス指定されていないIPv6拡張ヘッダー:ホップバイホップオプション、宛先オプション、およびルーティングヘッダー(ソースルーティング)。このドキュメントは、これらの機能へのAPIアクセスも提供します。

Table of Contents

目次

    1.  Introduction ................................................3
    2.  Common Structures and Definitions ...........................5
       2.1.  The ip6_hdr Structure ..................................5
            2.1.1.  IPv6 Next Header Values .........................6
            2.1.2.  IPv6 Extension Headers ..........................6
       2.2.  The icmp6_hdr Structure ................................8
            2.2.1.  ICMPv6 Type and Code Values .....................8
            2.2.2.  ICMPv6 Neighbor Discovery Type and Code Values ..9
       2.3.  Address Testing Macros .................................12
       2.4.  Protocols File .........................................12
    3.  IPv6 Raw Sockets ............................................13
       3.1.  Checksums ..............................................14
       3.2.  ICMPv6 Type Filtering ..................................14
    4.  Ancillary Data ..............................................17
       4.1.  The msghdr Structure ...................................18
       4.2.  The cmsghdr Structure ..................................18
       4.3.  Ancillary Data Object Macros ...........................19
            4.3.1.  CMSG_FIRSTHDR ...................................20
            4.3.2.  CMSG_NXTHDR .....................................22
            4.3.3.  CMSG_DATA .......................................22
            4.3.4.  CMSG_SPACE ......................................22
            4.3.5.  CMSG_LEN ........................................22
       4.4.  Summary of Options Described Using Ancillary Data ......23
       4.5.  IPV6_PKTOPTIONS Socket Option ..........................24
            4.5.1.  TCP Sticky Options ..............................25
            4.5.2.  UDP and Raw Socket Sticky Options ...............26
    5.  Packet Information ..........................................26
       5.1.  Specifying/Receiving the Interface .....................27
       5.2.  Specifying/Receiving Source/Destination Address ........27
       5.3.  Specifying/Receiving the Hop Limit .....................28
       5.4.  Specifying the Next Hop Address ........................29
       5.5.  Additional Errors with sendmsg() .......................29
    6.  Hop-By-Hop Options ..........................................30
       6.1.  Receiving Hop-by-Hop Options ...........................31
       6.2.  Sending Hop-by-Hop Options .............................31
       6.3.  Hop-by-Hop and Destination Options Processing ..........32
            6.3.1.  inet6_option_space ..............................32
            6.3.2.  inet6_option_init ...............................32
            6.3.3.  inet6_option_append .............................33
            6.3.4.  inet6_option_alloc ..............................33
            6.3.5.  inet6_option_next ...............................34
            6.3.6.  inet6_option_find ...............................35
            6.3.7.  Options Examples ................................35
    7.  Destination Options .........................................42
       7.1.  Receiving Destination Options ..........................42
       7.2.  Sending Destination Options ............................43
        
    8.  Routing Header Option .......................................43
       8.1.  inet6_rthdr_space ......................................44
       8.2.  inet6_rthdr_init .......................................45
       8.3.  inet6_rthdr_add ........................................45
       8.4.  inet6_rthdr_lasthop ....................................46
       8.5.  inet6_rthdr_reverse ....................................46
       8.6.  inet6_rthdr_segments ...................................46
       8.7.  inet6_rthdr_getaddr ....................................46
       8.8.  inet6_rthdr_getflags ...................................47
       8.9.  Routing Header Example .................................47
    9.  Ordering of Ancillary Data and IPv6 Extension Headers .......53
   10.  IPv6-Specific Options with IPv4-Mapped IPv6 Addresses .......54
   11.  rresvport_af ................................................55
   12.  Future Items ................................................55
       12.1.  Flow Labels ...........................................55
       12.2.  Path MTU Discovery and UDP ............................56
       12.3.  Neighbor Reachability and UDP .........................56
   13.  Summary of New Definitions ..................................56
   14.  Security Considerations .....................................59
   15.  Change History ..............................................59
   16.  References ..................................................65
   17.  Acknowledgments .............................................65
   18.  Authors' Addresses ..........................................66
   19.  Full Copyright Statement ....................................67
        
1. Introduction
1. はじめに

Specifications are in progress for changes to the sockets API to support IP version 6 [RFC-2133]. These changes are for TCP and UDP-based applications. The current document defines some the "advanced" features of the sockets API that are required for applications to take advantage of additional features of IPv6.

IPバージョン6 [RFC-2133]をサポートするためのソケットAPIの変更に関する仕様が進行中です。これらの変更は、TCPおよびUDPベースのアプリケーション用です。現在のドキュメントでは、アプリケーションがIPv6の追加機能を利用するために必要なソケットAPIの「高度な」機能をいくつか定義しています。

Today, the portability of applications using IPv4 raw sockets is quite high, but this is mainly because most IPv4 implementations started from a common base (the Berkeley source code) or at least started with the Berkeley headers. This allows programs such as Ping and Traceroute, for example, to compile with minimal effort on many hosts that support the sockets API. With IPv6, however, there is no common source code base that implementors are starting from, and the possibility for divergence at this level between different implementations is high. To avoid a complete lack of portability amongst applications that use raw IPv6 sockets, some standardization is necessary.

今日、IPv4 rawソケットを使用するアプリケーションの移植性は非常に高いですが、これは主に、ほとんどのIPv4実装が共通のベース(バークレーソースコード)から始まったか、少なくともバークレーヘッダーから始まったためです。これにより、たとえば、PingやTracerouteなどのプログラムを、ソケットAPIをサポートする多くのホストで最小限の労力でコンパイルできます。ただし、IPv6では、実装者が開始する共通のソースコードベースがなく、異なるレベルの実装間でこのレベルで相違する可能性が高くなります。未加工のIPv6ソケットを使用するアプリケーション間の移植性の完全な欠如を回避するには、いくつかの標準化が必要です。

There are also features from the basic IPv6 specification that are not addressed in [RFC-2133]: sending and receiving Hop-by-Hop options, Destination options, and Routing headers, specifying the outgoing interface, and being told of the receiving interface.

[RFC-2133]で扱われていない基本的なIPv6仕様の機能もあります。ホップバイホップオプションの送信と受信、宛先オプション、ルーティングヘッダー、送信インターフェースの指定、受信インターフェースの通知です。

This document can be divided into the following main sections.

このドキュメントは、次の主要セクションに分割できます。

1. Definitions of the basic constants and structures required for applications to use raw IPv6 sockets. This includes structure definitions for the IPv6 and ICMPv6 headers and all associated constants (e.g., values for the Next Header field).

1. アプリケーションが生のIPv6ソケットを使用するために必要な基本定数と構造の定義。これには、IPv6ヘッダーとICMPv6ヘッダーの構造定義、および関連するすべての定数(次のヘッダーフィールドの値など)が含まれます。

2. Some basic semantic definitions for IPv6 raw sockets. For example, a raw ICMPv4 socket requires the application to calculate and store the ICMPv4 header checksum. But with IPv6 this would require the application to choose the source IPv6 address because the source address is part of the pseudo header that ICMPv6 now uses for its checksum computation. It should be defined that with a raw ICMPv6 socket the kernel always calculates and stores the ICMPv6 header checksum.

2. IPv6 RAWソケットのいくつかの基本的なセマンティック定義。たとえば、未加工のICMPv4ソケットでは、アプリケーションがICMPv4ヘッダーチェックサムを計算して保存する必要があります。ただし、IPv6の場合、ソースアドレスはICMPv6がチェックサム計算に使用する疑似ヘッダーの一部であるため、アプリケーションはソースIPv6アドレスを選択する必要があります。生のICMPv6ソケットでは、カーネルが常にICMPv6ヘッダーチェックサムを計算して保存することを定義する必要があります。

3. Packet information: how applications can obtain the received interface, destination address, and received hop limit, along with specifying these values on a per-packet basis. There are a class of applications that need this capability and the technique should be portable.

3. パケット情報:アプリケーションが受信したインターフェイス、宛先アドレス、受信したホップ制限を取得する方法と、これらの値をパケットごとに指定します。この機能を必要とするアプリケーションのクラスがあり、この手法は移植可能でなければなりません。

4. Access to the optional Hop-by-Hop, Destination, and Routing headers.

4. オプションのホップバイホップ、宛先、ルーティングヘッダーへのアクセス。

5. Additional features required for IPv6 application portability.

5. IPv6アプリケーションの移植性に必要な追加機能。

The packet information along with access to the extension headers (Hop-by-Hop options, Destination options, and Routing header) are specified using the "ancillary data" fields that were added to the 4.3BSD Reno sockets API in 1990. The reason is that these ancillary data fields are part of the Posix.1g standard (which should be approved in 1997) and should therefore be adopted by most vendors.

パケット情報と拡張ヘッダー(ホップバイホップオプション、宛先オプション、ルーティングヘッダー)へのアクセスは、1990年に4.3BSD RenoソケットAPIに追加された「補助データ」フィールドを使用して指定されます。理由はこれらの補助データフィールドは、Posix.1g標準(1997年に承認されるはずです)の一部であり、したがって、ほとんどのベンダーが採用する必要があることに注意してください。

This document does not address application access to either the authentication header or the encapsulating security payload header.

このドキュメントでは、認証ヘッダーまたはカプセル化セキュリティペイロードヘッダーへのアプリケーションアクセスについては扱いません。

All examples in this document omit error checking in favor of brevity and clarity.

このドキュメントのすべての例では、簡潔さと明確さを優先してエラーチェックを省略しています。

We note that many of the functions and socket options defined in this document may have error returns that are not defined in this document. Many of these possible error returns will be recognized only as implementations proceed.

このドキュメントで定義されている関数とソケットオプションの多くには、このドキュメントで定義されていないエラーが返される場合があります。これらの考えられるエラーの戻りの多くは、実装の進行中にのみ認識されます。

Datatypes in this document follow the Posix.1g format: intN_t means a signed integer of exactly N bits (e.g., int16_t) and uintN_t means an unsigned integer of exactly N bits (e.g., uint32_t).

このドキュメントのデータ型はPosix.1g形式に従います。intN_tは正確にNビットの符号付き整数(たとえば、int16_t)を意味し、uintN_tは正確にNビットの符号なし整数(たとえば、uint32_t)を意味します。

Note that we use the (unofficial) terminology ICMPv4, IGMPv4, and ARPv4 to avoid any confusion with the newer ICMPv6 protocol.

新しいICMPv6プロトコルとの混乱を避けるために、(非公式の)用語ICMPv4、IGMPv4、およびARPv4を使用していることに注意してください。

2. Common Structures and Definitions
2. 一般的な構造と定義

Many advanced applications examine fields in the IPv6 header and set and examine fields in the various ICMPv6 headers. Common structure definitions for these headers are required, along with common constant definitions for the structure members.

多くの高度なアプリケーションは、IPv6ヘッダーのフィールドを調べ、さまざまなICMPv6ヘッダーのフィールドを設定して調べます。これらのヘッダーの共通の構造定義と、構造メンバーの共通の定数定義が必要です。

Two new headers are defined: <netinet/ip6.h> and <netinet/icmp6.h>.

<netinet / ip6.h>と<netinet / icmp6.h>という2つの新しいヘッダーが定義されています。

When an include file is specified, that include file is allowed to include other files that do the actual declaration or definition.

インクルードファイルを指定すると、そのインクルードファイルは、実際の宣言または定義を行う他のファイルをインクルードすることが許可されます。

2.1. The ip6_hdr Structure
2.1. ip6_hdr構造

The following structure is defined as a result of including <netinet/ip6.h>. Note that this is a new header.

<netinet / ip6.h>をインクルードした結果、以下の構造が定義されます。これは新しいヘッダーであることに注意してください。

    struct ip6_hdr {
      union {
        struct ip6_hdrctl {
          uint32_t ip6_un1_flow;   /* 24 bits of flow-ID */
          uint16_t ip6_un1_plen;   /* payload length */
          uint8_t  ip6_un1_nxt;    /* next header */
          uint8_t  ip6_un1_hlim;   /* hop limit */
        } ip6_un1;
        uint8_t ip6_un2_vfc;       /* 4 bits version, 4 bits priority */
      } ip6_ctlun;
      struct in6_addr ip6_src;      /* source address */
      struct in6_addr ip6_dst;      /* destination address */
    };
        

#define ip6_vfc ip6_ctlun.ip6_un2_vfc #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen #define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt #define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim

#define ip6_vfc ip6_ctlun.ip6_un2_vfc #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen #define ip6_6_ip__6_ip__ip6_ip6_ip6_ip6_ip6_un6ipun6unun6ipun6unun6ipun6unun6ipun6un1un6ipun6ip1un6un1

#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim

#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim

2.1.1. IPv6 Next Header Values
2.1.1. IPv6次ヘッダー値

IPv6 defines many new values for the Next Header field. The following constants are defined as a result of including <netinet/in.h>.

IPv6では、次のヘッダーフィールドに多くの新しい値が定義されています。次の定数は、<netinet / in.h>を組み込んだ結果として定義されています。

   #define IPPROTO_HOPOPTS        0 /* IPv6 Hop-by-Hop options */
   #define IPPROTO_IPV6          41 /* IPv6 header */
   #define IPPROTO_ROUTING       43 /* IPv6 Routing header */
   #define IPPROTO_FRAGMENT      44 /* IPv6 fragmentation header */
   #define IPPROTO_ESP           50 /* encapsulating security payload */
   #define IPPROTO_AH            51 /* authentication header */
   #define IPPROTO_ICMPV6        58 /* ICMPv6 */
   #define IPPROTO_NONE          59 /* IPv6 no next header */
   #define IPPROTO_DSTOPTS       60 /* IPv6 Destination options */
        

Berkeley-derived IPv4 implementations also define IPPROTO_IP to be 0. This should not be a problem since IPPROTO_IP is used only with IPv4 sockets and IPPROTO_HOPOPTS only with IPv6 sockets.

Berkeley派生のIPv4実装でもIPPROTO_IPを0と定義しています。IPPROTO_IPはIPv4ソケットでのみ使用され、IPPROTO_HOPOPTSはIPv6ソケットでのみ使用されるため、これは問題にはなりません。

2.1.2. IPv6 Extension Headers
2.1.2. IPv6拡張ヘッダー

Six extension headers are defined for IPv6. We define structures for all except the Authentication header and Encapsulating Security Payload header, both of which are beyond the scope of this document. The following structures are defined as a result of including <netinet/ip6.h>.

IPv6には6つの拡張ヘッダーが定義されています。 AuthenticationヘッダーとEncapsulating Security Payloadヘッダーを除くすべての構造を定義します。どちらもこのドキュメントの範囲を超えています。 <netinet / ip6.h>をインクルードした結果、以下の構造が定義されます。

   /* Hop-by-Hop options header */
   /* XXX should we pad it to force alignment on an 8-byte boundary? */
   struct ip6_hbh {
     uint8_t  ip6h_nxt;        /* next header */
     uint8_t  ip6h_len;        /* length in units of 8 octets */
       /* followed by options */
   };
        
   /* Destination options header */
   /* XXX should we pad it to force alignment on an 8-byte boundary? */
   struct ip6_dest {
     uint8_t  ip6d_nxt;        /* next header */
     uint8_t  ip6d_len;        /* length in units of 8 octets */
       /* followed by options */
   };
        
   /* Routing header */
   struct ip6_rthdr {
        
     uint8_t  ip6r_nxt;        /* next header */
     uint8_t  ip6r_len;        /* length in units of 8 octets */
     uint8_t  ip6r_type;       /* routing type */
     uint8_t  ip6r_segleft;    /* segments left */
       /* followed by routing type specific data */
   };
        
   /* Type 0 Routing header */
   struct ip6_rthdr0 {
     uint8_t  ip6r0_nxt;       /* next header */
     uint8_t  ip6r0_len;       /* length in units of 8 octets */
     uint8_t  ip6r0_type;      /* always zero */
     uint8_t  ip6r0_segleft;   /* segments left */
     uint8_t  ip6r0_reserved;  /* reserved field */
     uint8_t  ip6r0_slmap[3];  /* strict/loose bit map */
     struct in6_addr  ip6r0_addr[1];  /* up to 23 addresses */
   };
        
   /* Fragment header */
   struct ip6_frag {
     uint8_t   ip6f_nxt;       /* next header */
     uint8_t   ip6f_reserved;  /* reserved field */
     uint16_t  ip6f_offlg;     /* offset, reserved, and flag */
     uint32_t  ip6f_ident;     /* identification */
   };
        
   #if     BYTE_ORDER == BIG_ENDIAN
   #define IP6F_OFF_MASK       0xfff8  /* mask out offset from _offlg */
   #define IP6F_RESERVED_MASK  0x0006  /* reserved bits in ip6f_offlg */
   #define IP6F_MORE_FRAG      0x0001  /* more-fragments flag */
   #else   /* BYTE_ORDER == LITTLE_ENDIAN */
   #define IP6F_OFF_MASK       0xf8ff  /* mask out offset from _offlg */
   #define IP6F_RESERVED_MASK  0x0600  /* reserved bits in ip6f_offlg */
   #define IP6F_MORE_FRAG      0x0100  /* more-fragments flag */
   #endif
        

Defined constants for fields larger than 1 byte depend on the byte ordering that is used. This API assumes that the fields in the protocol headers are left in the network byte order, which is big-endian for the Internet protocols. If not, then either these constants or the fields being tested must be converted at run-time, using something like htons() or htonl().

1バイトより大きいフィールドの定義済み定数は、使用されるバイト順序によって異なります。このAPIは、プロトコルヘッダーのフィールドがネットワークバイトオーダーのままであると想定しています。これは、インターネットプロトコルのビッグエンディアンです。そうでない場合は、これらの定数またはテストされるフィールドのいずれかを、htons()またはhtonl()などを使用して実行時に変換する必要があります。

(Note: We show an implementation that supports both big-endian and little-endian byte ordering, assuming a hypothetical compile-time #if test to determine the byte ordering. The constant that we show, BYTE_ORDER, with values of BIG_ENDIAN and LITTLE_ENDIAN, are for example purposes only. If an implementation runs on only one type of hardware it need only define the set of constants for that hardware's byte ordering.)

(注:ビッグエンディアンとリトルエンディアンの両方のバイトオーダーをサポートする実装を示します。仮定のコンパイル時の#ifテストでバイトオーダーを決定することを想定しています。ここで示す定数BYTE_ORDERは、BIG_ENDIANとLITTLE_ENDIANの値で、は例示のみを目的としています。1つのタイプのハードウェアのみで実装を実行する場合、そのハードウェアのバイト順序の定数のセットを定義するだけで済みます。

2.2. The icmp6_hdr Structure
2.2. icmp6_hdr構造

The ICMPv6 header is needed by numerous IPv6 applications including Ping, Traceroute, router discovery daemons, and neighbor discovery daemons. The following structure is defined as a result of including <netinet/icmp6.h>. Note that this is a new header.

ICMPv6ヘッダーは、Ping、Traceroute、ルーター検出デーモン、ネイバー検出デーモンなど、多数のIPv6アプリケーションで必要です。 <netinet / icmp6.h>をインクルードした結果、以下の構造が定義されます。これは新しいヘッダーであることに注意してください。

   struct icmp6_hdr {
     uint8_t     icmp6_type;   /* type field */
     uint8_t     icmp6_code;   /* code field */
     uint16_t    icmp6_cksum;  /* checksum field */
     union {
       uint32_t  icmp6_un_data32[1]; /* type-specific field */
       uint16_t  icmp6_un_data16[2]; /* type-specific field */
       uint8_t   icmp6_un_data8[4];  /* type-specific field */
     } icmp6_dataun;
   };
        
   #define icmp6_data32    icmp6_dataun.icmp6_un_data32
   #define icmp6_data16    icmp6_dataun.icmp6_un_data16
   #define icmp6_data8     icmp6_dataun.icmp6_un_data8
   #define icmp6_pptr      icmp6_data32[0]  /* parameter prob */
   #define icmp6_mtu       icmp6_data32[0]  /* packet too big */
   #define icmp6_id        icmp6_data16[0]  /* echo request/reply */
   #define icmp6_seq       icmp6_data16[1]  /* echo request/reply */
   #define icmp6_maxdelay  icmp6_data16[0]  /* mcast group membership */
        
2.2.1. ICMPv6 Type and Code Values
2.2.1. ICMPv6タイプとコード値

In addition to a common structure for the ICMPv6 header, common definitions are required for the ICMPv6 type and code fields. The following constants are also defined as a result of including <netinet/icmp6.h>.

ICMPv6ヘッダーの共通構造に加えて、ICMPv6タイプおよびコードフィールドには共通の定義が必要です。次の定数も、<netinet / icmp6.h>をインクルードした結果として定義されています。

#define ICMP6_DST_UNREACH 1 #define ICMP6_PACKET_TOO_BIG 2 #define ICMP6_TIME_EXCEEDED 3 #define ICMP6_PARAM_PROB 4

#define ICMP6_DST_UNREACH 1 #define ICMP6_PACKET_TOO_BIG 2 #define ICMP6_TIME_EXCEEDED 3 #define ICMP6_PARAM_PROB 4

#define ICMP6_INFOMSG_MASK  0x80    /* all informational messages */
        

#define ICMP6_ECHO_REQUEST 128 #define ICMP6_ECHO_REPLY 129

#define ICMP6_ECHO_REQUEST 128 #define ICMP6_ECHO_REPLY 129

#define ICMP6_MEMBERSHIP_QUERY 130 #define ICMP6_MEMBERSHIP_REPORT 131 #define ICMP6_MEMBERSHIP_REDUCTION 132

#define ICMP6_MEMBERSHIP_QUERY 130 #define ICMP6_MEMBERSHIP_REPORT 131 #define ICMP6_MEMBERSHIP_REDUCTION 132

#define ICMP6_DST_UNREACH_NOROUTE     0 /* no route to destination */
#define ICMP6_DST_UNREACH_ADMIN       1 /* communication with */
                                        /* destination */
                                        /* administratively */
                                        /* prohibited */
#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor */
#define ICMP6_DST_UNREACH_ADDR        3 /* address unreachable */
#define ICMP6_DST_UNREACH_NOPORT      4 /* bad port */
        
#define ICMP6_TIME_EXCEED_TRANSIT     0 /* Hop Limit == 0 in transit */
#define ICMP6_TIME_EXCEED_REASSEMBLY  1 /* Reassembly time out */
        
#define ICMP6_PARAMPROB_HEADER        0 /* erroneous header field */
#define ICMP6_PARAMPROB_NEXTHEADER    1 /* unrecognized Next Header */
#define ICMP6_PARAMPROB_OPTION        2 /* unrecognized IPv6 option */
        

The five ICMP message types defined by IPv6 neighbor discovery (133- 137) are defined in the next section.

IPv6ネイバー探索(133〜137)によって定義される5つのICMPメッセージタイプは、次のセクションで定義されます。

2.2.2. ICMPv6 Neighbor Discovery Type and Code Values
2.2.2. ICMPv6ネイバー探索タイプとコード値

The following structures and definitions are defined as a result of including <netinet/icmp6.h>.

以下の構造と定義は、<netinet / icmp6.h>をインクルードした結果として定義されています。

#define ND_ROUTER_SOLICIT 133 #define ND_ROUTER_ADVERT 134 #define ND_NEIGHBOR_SOLICIT 135 #define ND_NEIGHBOR_ADVERT 136 #define ND_REDIRECT 137

#define ND_ROUTER_SOLICIT 133 #define ND_ROUTER_ADVERT 134 #define ND_NEIGHBOR_SOLICIT 135 #define ND_NEIGHBOR_ADVERT 136 #define ND_REDIRECT 137

   struct nd_router_solicit {     /* router solicitation */
     struct icmp6_hdr  nd_rs_hdr;
       /* could be followed by options */
   };
        

#define nd_rs_type nd_rs_hdr.icmp6_type #define nd_rs_code nd_rs_hdr.icmp6_code #define nd_rs_cksum nd_rs_hdr.icmp6_cksum #define nd_rs_reserved nd_rs_hdr.icmp6_data32[0]

#define nd_rs_type nd_rs_hdr.icmp6_type #define nd_rs_code nd_rs_hdr.icmp6_code #define nd_rs_cksum nd_rs_hdr.icmp6_cksum #define nd_rs_reserved nd_rs_hdr.icmp6_data32 [0]

   struct nd_router_advert {      /* router advertisement */
     struct icmp6_hdr  nd_ra_hdr;
     uint32_t   nd_ra_reachable;   /* reachable time */
     uint32_t   nd_ra_retransmit;  /* retransmit timer */
        
       /* could be followed by options */
   };
        
   #define nd_ra_type               nd_ra_hdr.icmp6_type
   #define nd_ra_code               nd_ra_hdr.icmp6_code
   #define nd_ra_cksum              nd_ra_hdr.icmp6_cksum
   #define nd_ra_curhoplimit        nd_ra_hdr.icmp6_data8[0]
   #define nd_ra_flags_reserved     nd_ra_hdr.icmp6_data8[1]
   #define ND_RA_FLAG_MANAGED       0x80
   #define ND_RA_FLAG_OTHER         0x40
   #define nd_ra_router_lifetime    nd_ra_hdr.icmp6_data16[1]
        
   struct nd_neighbor_solicit {   /* neighbor solicitation */
     struct icmp6_hdr  nd_ns_hdr;
     struct in6_addr   nd_ns_target; /* target address */
       /* could be followed by options */
   };
        

#define nd_ns_type nd_ns_hdr.icmp6_type #define nd_ns_code nd_ns_hdr.icmp6_code #define nd_ns_cksum nd_ns_hdr.icmp6_cksum #define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]

#define nd_ns_type nd_ns_hdr.icmp6_type #define nd_ns_code nd_ns_hdr.icmp6_code #define nd_ns_cksum nd_ns_hdr.icmp6_cksum #define nd_ns_reserved nd_ns_hdr.icmp6_data32 [0]

   struct nd_neighbor_advert {    /* neighbor advertisement */
     struct icmp6_hdr  nd_na_hdr;
     struct in6_addr   nd_na_target; /* target address */
       /* could be followed by options */
   };
        
   #define nd_na_type               nd_na_hdr.icmp6_type
   #define nd_na_code               nd_na_hdr.icmp6_code
   #define nd_na_cksum              nd_na_hdr.icmp6_cksum
   #define nd_na_flags_reserved     nd_na_hdr.icmp6_data32[0]
   #if     BYTE_ORDER == BIG_ENDIAN
   #define ND_NA_FLAG_ROUTER        0x80000000
   #define ND_NA_FLAG_SOLICITED     0x40000000
   #define ND_NA_FLAG_OVERRIDE      0x20000000
   #else   /* BYTE_ORDER == LITTLE_ENDIAN */
   #define ND_NA_FLAG_ROUTER        0x00000080
   #define ND_NA_FLAG_SOLICITED     0x00000040
   #define ND_NA_FLAG_OVERRIDE      0x00000020
   #endif
        
   struct nd_redirect {           /* redirect */
     struct icmp6_hdr  nd_rd_hdr;
     struct in6_addr   nd_rd_target; /* target address */
     struct in6_addr   nd_rd_dst;    /* destination address */
       /* could be followed by options */
        

};

};

#define nd_rd_type nd_rd_hdr.icmp6_type #define nd_rd_code nd_rd_hdr.icmp6_code #define nd_rd_cksum nd_rd_hdr.icmp6_cksum #define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]

#define nd_rd_type nd_rd_hdr.icmp6_type #define nd_rd_code nd_rd_hdr.icmp6_code #define nd_rd_cksum nd_rd_hdr.icmp6_cksum #define nd_rd_reserved nd_rd_hdr.icmp6_data32 [0]

   struct nd_opt_hdr {           /* Neighbor discovery option header */
     uint8_t  nd_opt_type;
     uint8_t  nd_opt_len;        /* in units of 8 octets */
       /* followed by option specific data */
   };
        

#define ND_OPT_SOURCE_LINKADDR 1 #define ND_OPT_TARGET_LINKADDR 2 #define ND_OPT_PREFIX_INFORMATION 3 #define ND_OPT_REDIRECTED_HEADER 4 #define ND_OPT_MTU 5

#define ND_OPT_SOURCE_LINKADDR 1 #define ND_OPT_TARGET_LINKADDR 2 #define ND_OPT_PREFIX_INFORMATION 3 #define ND_OPT_REDIRECTED_HEADER 4 #define ND_OPT_MTU 5

   struct nd_opt_prefix_info {    /* prefix information */
     uint8_t   nd_opt_pi_type;
     uint8_t   nd_opt_pi_len;
     uint8_t   nd_opt_pi_prefix_len;
     uint8_t   nd_opt_pi_flags_reserved;
     uint32_t  nd_opt_pi_valid_time;
     uint32_t  nd_opt_pi_preferred_time;
     uint32_t  nd_opt_pi_reserved2;
     struct in6_addr  nd_opt_pi_prefix;
   };
        

#define ND_OPT_PI_FLAG_ONLINK 0x80 #define ND_OPT_PI_FLAG_AUTO 0x40

#define ND_OPT_PI_FLAG_ONLINK 0x80 #define ND_OPT_PI_FLAG_AUTO 0x40

   struct nd_opt_rd_hdr {         /* redirected header */
     uint8_t   nd_opt_rh_type;
     uint8_t   nd_opt_rh_len;
     uint16_t  nd_opt_rh_reserved1;
     uint32_t  nd_opt_rh_reserved2;
       /* followed by IP header and data */
   };
        
   struct nd_opt_mtu {            /* MTU option */
     uint8_t   nd_opt_mtu_type;
     uint8_t   nd_opt_mtu_len;
     uint16_t  nd_opt_mtu_reserved;
     uint32_t  nd_opt_mtu_mtu;
   };
        

We note that the nd_na_flags_reserved flags have the same byte ordering problems as we discussed with ip6f_offlg.

nd_na_flags_reservedフラグには、ip6f_offlgで説明したのと同じバイト順序の問題があることに注意してください。

2.3. Address Testing Macros
2.3. アドレステストマクロ

The basic API ([RFC-2133]) defines some macros for testing an IPv6 address for certain properties. This API extends those definitions with additional address testing macros, defined as a result of including <netinet/in.h>.

基本API([RFC-2133])は、特定のプロパティのIPv6アドレスをテストするためのいくつかのマクロを定義します。このAPIは、<netinet / in.h>を組み込んだ結果として定義された追加のアドレステストマクロでこれらの定義を拡張します。

    int  IN6_ARE_ADDR_EQUAL(const struct in6_addr *,
                            const struct in6_addr *);
        
2.4. Protocols File
2.4. プロトコルファイル

Many hosts provide the file /etc/protocols that contains the names of the various IP protocols and their protocol number (e.g., the value of the protocol field in the IPv4 header for that protocol, such as 1 for ICMP). Some programs then call the function getprotobyname() to obtain the protocol value that is then specified as the third argument to the socket() function. For example, the Ping program contains code of the form

多くのホストは、さまざまなIPプロトコルの名前とそのプロトコル番号(たとえば、ICMPの1など、そのプロトコルのIPv4ヘッダーのプロトコルフィールドの値)を含む/ etc / protocolsファイルを提供します。次に、一部のプログラムは、関数getprotobyname()を呼び出して、socket()関数の3番目の引数として指定されているプロトコル値を取得します。たとえば、Pingプログラムには次の形式のコードが含まれています。

struct protoent *proto;

struct protoent * proto;

       proto = getprotobyname("icmp");
        
       s = socket(AF_INET, SOCK_RAW, proto->p_proto);
        

Common names are required for the new IPv6 protocols in this file, to provide portability of applications that call the getprotoXXX() functions.

このファイルの新しいIPv6プロトコルには、getprotoXXX()関数を呼び出すアプリケーションの移植性を提供するために、共通名が必要です。

We define the following protocol names with the values shown. These are taken from ftp://ftp.isi.edu/in-notes/iana/assignments/protocol-numbers.

次のプロトコル名を、示されている値で定義します。これらはftp://ftp.isi.edu/in-notes/iana/assignments/protocol-numbersから取得されます。

hopopt 0 # hop-by-hop options for ipv6 ipv6 41 # ipv6 ipv6-route 43 # routing header for ipv6 ipv6-frag 44 # fragment header for ipv6 esp 50 # encapsulating security payload for ipv6 ah 51 # authentication header for ipv6 ipv6-icmp 58 # icmp for ipv6 ipv6-nonxt 59 # no next header for ipv6 ipv6-opts 60 # destination options for ipv6

hopopt 0#ipv6 ipv6 41のホップバイホップオプション#ipv6 ipv6-route 43#ipv6 ipv6-frag 44のルーティングヘッダー#ipv6 esp 50のフラグメントヘッダー#ipv6 ah 51のカプセル化セキュリティペイロード#ipv6 ipv6-の認証ヘッダーicmp 58#ipv6のicmp ipv6-nonxt 59#ipv6の次のヘッダーなしipv6-opts 60#ipv6の宛先オプション

3. IPv6 Raw Sockets
3. IPv6 RAWソケット

Raw sockets bypass the transport layer (TCP or UDP). With IPv4, raw sockets are used to access ICMPv4, IGMPv4, and to read and write IPv4 datagrams containing a protocol field that the kernel does not process. An example of the latter is a routing daemon for OSPF, since it uses IPv4 protocol field 89. With IPv6 raw sockets will be used for ICMPv6 and to read and write IPv6 datagrams containing a Next Header field that the kernel does not process. Examples of the latter are a routing daemon for OSPF for IPv6 and RSVP (protocol field 46).

rawソケットはトランスポート層(TCPまたはUDP)をバイパスします。 IPv4では、生のソケットを使用してICMPv4、IGMPv4にアクセスし、カーネルが処理しないプロトコルフィールドを含むIPv4データグラムを読み書きします。後者の例は、IPv4プロトコルフィールド89を使用するため、OSPFのルーティングデーモンです。IPv6を使用すると、ICMPv6と、カーネルが処理しない次のヘッダーフィールドを含むIPv6データグラムの読み取りと書き込みに、生のソケットが使用されます。後者の例は、OSPF for IPv6およびRSVPのルーティングデーモンです(プロトコルフィールド46)。

All data sent via raw sockets MUST be in network byte order and all data received via raw sockets will be in network byte order. This differs from the IPv4 raw sockets, which did not specify a byte ordering and typically used the host's byte order.

rawソケットを介して送信されるすべてのデータはネットワークバイトオーダーでなければならず、rawソケットを介して受信されるすべてのデータはネットワークバイトオーダーになります。これは、バイト順を指定せず、通常ホストのバイト順を使用するIPv4のrawソケットとは異なります。

Another difference from IPv4 raw sockets is that complete packets (that is, IPv6 packets with extension headers) cannot be read or written using the IPv6 raw sockets API. Instead, ancillary data objects are used to transfer the extension headers, as described later in this document. Should an application need access to the complete IPv6 packet, some other technique, such as the datalink interfaces BPF or DLPI, must be used.

IPv4 RAWソケットとのもう1つの違いは、IPv6 RAWソケットAPIを使用して完全なパケット(つまり、拡張ヘッダー付きのIPv6パケット)を読み書きできないことです。代わりに、このドキュメントで後述するように、補助データオブジェクトを使用して拡張ヘッダーを転送します。アプリケーションが完全なIPv6パケットにアクセスする必要がある場合は、データリンクインターフェイスBPFやDLPIなどの他の手法を使用する必要があります。

All fields in the IPv6 header that an application might want to change (i.e., everything other than the version number) can be modified using ancillary data and/or socket options by the application for output. All fields in a received IPv6 header (other than the version number and Next Header fields) and all extension headers are also made available to the application as ancillary data on input. Hence there is no need for a socket option similar to the IPv4 IP_HDRINCL socket option.

アプリケーションが変更する可能性のあるIPv6ヘッダーのすべてのフィールド(つまり、バージョン番号以外のすべてのフィールド)は、出力用のアプリケーションで補助データやソケットオプションを使用して変更できます。受信したIPv6ヘッダーのすべてのフィールド(バージョン番号と次のヘッダーフィールドを除く)とすべての拡張ヘッダーも、入力時に補助データとしてアプリケーションで使用できます。したがって、IPv4 IP_HDRINCLソケットオプションのようなソケットオプションは必要ありません。

When writing to a raw socket the kernel will automatically fragment the packet if its size exceeds the path MTU, inserting the required fragmentation headers. On input the kernel reassembles received fragments, so the reader of a raw socket never sees any fragment headers.

生のソケットに書き込むとき、カーネルはパケットのサイズがパスMTUを超えると自動的にパケットを断片化し、必要な断片化ヘッダーを挿入します。入力では、カーネルは受信したフラグメントを再構成するため、rawソケットのリーダーはフラグメントヘッダーを決して見ません。

When we say "an ICMPv6 raw socket" we mean a socket created by calling the socket function with the three arguments PF_INET6, SOCK_RAW, and IPPROTO_ICMPV6.

「ICMPv6 rawソケット」とは、PF_INET6、SOCK_RAW、IPPROTO_ICMPV6の3つの引数を使用してソケット関数を呼び出すことによって作成されたソケットを意味します。

Most IPv4 implementations give special treatment to a raw socket created with a third argument to socket() of IPPROTO_RAW, whose value is normally 255. We note that this value has no special meaning to an IPv6 raw socket (and the IANA currently reserves the value of 255 when used as a next-header field). (Note: This feature was added to IPv4 in 1988 by Van Jacobson to support traceroute, allowing a complete IP header to be passed by the application, before the IP_HDRINCL socket option was added.)

ほとんどのIPv4実装は、IPPROTO_RAWのsocket()への3番目の引数で作成されたrawソケットに特別な扱いをします。その値は通常255です。この値はIPv6 rawソケットに特別な意味はありません(IANAは現在値を予約しています)次のヘッダーフィールドとして使用する場合は255。 (注:この機能は、1988年にVan JacobsonによってtracerouteをサポートするためにIPv4に追加されました。これにより、IP_HDRINCLソケットオプションが追加される前に、完全なIPヘッダーをアプリケーションから渡すことができます。)

3.1. Checksums
3.1. チェックサム

The kernel will calculate and insert the ICMPv6 checksum for ICMPv6 raw sockets, since this checksum is mandatory.

このチェックサムは必須であるため、カーネルはICMPv6 rawソケットのICMPv6チェックサムを計算して挿入します。

For other raw IPv6 sockets (that is, for raw IPv6 sockets created with a third argument other than IPPROTO_ICMPV6), the application must set the new IPV6_CHECKSUM socket option to have the kernel (1) compute and store a checksum for output, and (2) verify the received checksum on input, discarding the packet if the checksum is in error. This option prevents applications from having to perform source address selection on the packets they send. The checksum will incorporate the IPv6 pseudo-header, defined in Section 8.1 of [RFC-1883]. This new socket option also specifies an integer offset into the user data of where the checksum is located.

他の生のIPv6ソケットの場合(つまり、IPPROTO_ICMPV6以外の3番目の引数で作成された生のIPv6ソケットの場合)、アプリケーションは、新しいIPV6_CHECKSUMソケットオプションを設定して、カーネルに(1)出力のチェックサムを計算および保存し、(2 )入力で受信したチェックサムを確認し、チェックサムにエラーがある場合はパケットを破棄します。このオプションは、アプリケーションが送信するパケットに対してソースアドレス選択を実行する必要がないようにします。チェックサムには、[RFC-1883]のセクション8.1で定義されているIPv6疑似ヘッダーが組み込まれます。この新しいソケットオプションは、チェックサムが配置されている場所のユーザーデータへの整数オフセットも指定します。

    int  offset = 2;
    setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset));
        

By default, this socket option is disabled. Setting the offset to -1 also disables the option. By disabled we mean (1) the kernel will not calculate and store a checksum for outgoing packets, and (2) the kernel will not verify a checksum for received packets.

デフォルトでは、このソケットオプションは無効になっています。オフセットを-1に設定すると、オプションも無効になります。無効とは、(1)カーネルが送信パケットのチェックサムを計算および保存しないこと、(2)カーネルが受信パケットのチェックサムを検証しないことを意味します。

(Note: Since the checksum is always calculated by the kernel for an ICMPv6 socket, applications are not able to generate ICMPv6 packets with incorrect checksums (presumably for testing purposes) using this API.)

(注:チェックサムは常にICMPv6ソケットのカーネルによって計算されるため、アプリケーションはこのAPIを使用して(おそらくテスト目的で)不正なチェックサムを持つICMPv6パケットを生成できません。)

3.2. ICMPv6 Type Filtering
3.2. ICMPv6タイプのフィルタリング

ICMPv4 raw sockets receive most ICMPv4 messages received by the kernel. (We say "most" and not "all" because Berkeley-derived kernels never pass echo requests, timestamp requests, or address mask requests to a raw socket. Instead these three messages are processed entirely by the kernel.) But ICMPv6 is a superset of ICMPv4, also including the functionality of IGMPv4 and ARPv4. This means that an ICMPv6 raw socket can potentially receive many more messages than would be received with an ICMPv4 raw socket: ICMP messages similar to ICMPv4, along with neighbor solicitations, neighbor advertisements, and the three group membership messages.

ICMPv4 rawソケットは、カーネルが受信したほとんどのICMPv4メッセージを受信します。 (バークレー由来のカーネルがエコー要求、タイムスタンプ要求、またはアドレスマスク要求をrawソケットに渡さないため、「すべて」ではなく「ほとんど」と言います。代わりに、これらの3つのメッセージはカーネルによって完全に処理されます。 ICMPv4の機能、IGMPv4およびARPv4の機能も含まれます。つまり、ICMPv6のrawソケットは、ICMPv4のrawソケットで受信するよりもはるかに多くのメッセージを受信できる可能性があります。

Most applications using an ICMPv6 raw socket care about only a small subset of the ICMPv6 message types. To transfer extraneous ICMPv6 messages from the kernel to user can incur a significant overhead. Therefore this API includes a method of filtering ICMPv6 messages by the ICMPv6 type field.

ICMPv6 rawソケットを使用するほとんどのアプリケーションは、ICMPv6メッセージタイプのごく一部のみを対象とします。カーネルからユーザーに無関係なICMPv6メッセージを転送すると、かなりのオーバーヘッドが発生する可能性があります。したがって、このAPIには、ICMPv6タイプフィールドでICMPv6メッセージをフィルタリングするメソッドが含まれています。

Each ICMPv6 raw socket has an associated filter whose datatype is defined as

各ICMPv6 rawソケットには、データ型が次のように定義されている関連フィルターがあります。

struct icmp6_filter;

struct icmp6_filter;

This structure, along with the macros and constants defined later in this section, are defined as a result of including the <netinet/icmp6.h> header.

この構造は、このセクションの後半で定義されるマクロと定数とともに、<netinet / icmp6.h>ヘッダーを組み込んだ結果として定義されます。

The current filter is fetched and stored using getsockopt() and setsockopt() with a level of IPPROTO_ICMPV6 and an option name of ICMP6_FILTER.

現在のフィルターは、getsockopt()およびsetsockopt()を使用して、レベルがIPPROTO_ICMPV6で、オプション名がICMP6_FILTERでフェッチおよび格納されます。

Six macros operate on an icmp6_filter structure:

6つのマクロがicmp6_filter構造体を操作します。

       void ICMP6_FILTER_SETPASSALL (struct icmp6_filter *);
       void ICMP6_FILTER_SETBLOCKALL(struct icmp6_filter *);
        
       void ICMP6_FILTER_SETPASS ( int, struct icmp6_filter *);
       void ICMP6_FILTER_SETBLOCK( int, struct icmp6_filter *);
        
       int  ICMP6_FILTER_WILLPASS (int, const struct icmp6_filter *);
       int  ICMP6_FILTER_WILLBLOCK(int, const struct icmp6_filter *);
        

The first argument to the last four macros (an integer) is an ICMPv6 message type, between 0 and 255. The pointer argument to all six macros is a pointer to a filter that is modified by the first four macros examined by the last two macros.

最後の4つのマクロへの最初の引数(整数)は、0〜255のICMPv6メッセージタイプです。6つすべてのマクロへのポインター引数は、最後の2つのマクロによって検査された最初の4つのマクロによって変更されるフィルターへのポインターです。 。

The first two macros, SETPASSALL and SETBLOCKALL, let us specify that all ICMPv6 messages are passed to the application or that all ICMPv6 messages are blocked from being passed to the application.

最初の2つのマクロ、SETPASSALLおよびSETBLOCKALLでは、すべてのICMPv6メッセージがアプリケーションに渡されるか、またはすべてのICMPv6メッセージがアプリケーションに渡されないようにブロックされているかを指定します。

The next two macros, SETPASS and SETBLOCK, let us specify that messages of a given ICMPv6 type should be passed to the application or not passed to the application (blocked).

次の2つのマクロ、SETPASSおよびSETBLOCKは、特定のICMPv6タイプのメッセージをアプリケーションに渡すか、アプリケーションに渡さない(ブロックする)かを指定します。

The final two macros, WILLPASS and WILLBLOCK, return true or false depending whether the specified message type is passed to the application or blocked from being passed to the application by the filter pointed to by the second argument.

最後の2つのマクロWILLPASSとWILLBLOCKは、指定されたメッセージタイプがアプリケーションに渡されるか、2番目の引数が指すフィルターによってアプリケーションに渡されないようにするかによって、trueまたはfalseを返します。

When an ICMPv6 raw socket is created, it will by default pass all ICMPv6 message types to the application.

ICMPv6 rawソケットが作成されると、デフォルトですべてのICMPv6メッセージタイプがアプリケーションに渡されます。

As an example, a program that wants to receive only router advertisements could execute the following:

例として、ルータアドバタイズメントのみを受信したいプログラムは、以下を実行できます。

struct icmp6_filter myfilt;

struct icmp6_filter myfilt;

fd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
        
ICMP6_FILTER_SETBLOCKALL(&myfilt);
ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &myfilt);
setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &myfilt, sizeof(myfilt));
        

The filter structure is declared and then initialized to block all messages types. The filter structure is then changed to allow router advertisement messages to be passed to the application and the filter is installed using setsockopt().

フィルター構造が宣言され、すべてのメッセージタイプをブロックするように初期化されます。次にフィルター構造が変更され、ルーター通知メッセージをアプリケーションに渡せるようになり、フィルターはsetsockopt()を使用してインストールされます。

The icmp6_filter structure is similar to the fd_set datatype used with the select() function in the sockets API. The icmp6_filter structure is an opaque datatype and the application should not care how it is implemented. All the application does with this datatype is allocate a variable of this type, pass a pointer to a variable of this type to getsockopt() and setsockopt(), and operate on a variable of this type using the six macros that we just defined.

icmp6_filter構造は、ソケットAPIのselect()関数で使用されるfd_setデータ型に似ています。 icmp6_filter構造体は不透明なデータ型であり、アプリケーションはそれがどのように実装されているかを気にする必要はありません。アプリケーションがこのデータ型で行うすべてのことは、この型の変数を割り当て、この型の変数へのポインターをgetsockopt()およびsetsockopt()に渡し、定義した6つのマクロを使用してこの型の変数を操作することです。

Nevertheless, it is worth showing a simple implementation of this datatype and the six macros.

それでも、このデータ型と6つのマクロの簡単な実装を示す価値はあります。

struct icmp6_filter {
  uint32_t  icmp6_filt[8];  /* 8*32 = 256 bits */
};
        
#define ICMP6_FILTER_WILLPASS(type, filterp) \
    ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
    ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
#define ICMP6_FILTER_SETPASS(type, filterp) \
    ((((filterp)->icmp6_filt[(type) >> 5]) |=  (1 << ((type) & 31))))
#define ICMP6_FILTER_SETBLOCK(type, filterp) \
    ((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31))))
#define ICMP6_FILTER_SETPASSALL(filterp) \
    memset((filterp), 0xFF, sizeof(struct icmp6_filter))
#define ICMP6_FILTER_SETBLOCKALL(filterp) \
    memset((filterp), 0, sizeof(struct icmp6_filter))
        

(Note: These sample definitions have two limitations that an implementation may want to change. The first four macros evaluate their first argument two times. The second two macros require the inclusion of the <string.h> header for the memset() function.)

(注:これらのサンプル定義には、実装で変更したい2つの制限があります。最初の4つのマクロは、最初の引数を2回評価します。2番目の2つのマクロは、memset()関数の<string.h>ヘッダーを含める必要があります。 )

4. Ancillary Data
4. 補助データ

4.2BSD allowed file descriptors to be transferred between separate processes across a UNIX domain socket using the sendmsg() and recvmsg() functions. Two members of the msghdr structure, msg_accrights and msg_accrightslen, were used to send and receive the descriptors. When the OSI protocols were added to 4.3BSD Reno in 1990 the names of these two fields in the msghdr structure were changed to msg_control and msg_controllen, because they were used by the OSI protocols for "control information", although the comments in the source code call this "ancillary data".

4.2BSDでは、sendmsg()関数とrecvmsg()関数を使用して、UNIXドメインソケット全体の個別のプロセス間でファイル記述子を転送できました。 msghdr構造体の2つのメンバー、msg_accrightsおよびmsg_accrightslenは、記述子の送受信に使用されました。 OSIプロトコルが1990年に4.3BSD Renoに追加されたとき、msghdr構造体のこれらの2つのフィールドの名前はmsg_controlおよびmsg_controllenに変更されました。これは、OSIプロトコルが「制御情報」として使用していたためです。これを「補助データ」と呼びます。

Other than the OSI protocols, the use of ancillary data has been rare. In 4.4BSD, for example, the only use of ancillary data with IPv4 is to return the destination address of a received UDP datagram if the IP_RECVDSTADDR socket option is set. With Unix domain sockets ancillary data is still used to send and receive descriptors.

OSIプロトコル以外では、補助データの使用はまれです。たとえば、4.4BSDでは、IPv_4での補助データの唯一の使用は、IP_RECVDSTADDRソケットオプションが設定されている場合、受信したUDPデータグラムの宛先アドレスを返すことです。 Unixドメインソケットでは、記述子の送受信に補助データが引き続き使用されます。

Nevertheless the ancillary data fields of the msghdr structure provide a clean way to pass information in addition to the data that is being read or written. The inclusion of the msg_control and msg_controllen members of the msghdr structure along with the cmsghdr structure that is pointed to by the msg_control member is required by the Posix.1g sockets API standard (which should be completed during 1997).

それにもかかわらず、msghdr構造の補助データフィールドは、読み取りまたは書き込み中のデータに加えて情報を渡すためのクリーンな方法を提供します。 msghdr構造体のmsg_controlメンバーとmsg_controllenメンバー、およびmsg_controlメンバーが指すcmsghdr構造体を含めることは、Posix.1gソケットAPI標準(1997年中に完了する必要がある)で必要です。

In this document ancillary data is used to exchange the following optional information between the application and the kernel:

このドキュメントでは、補助データを使用して、アプリケーションとカーネルの間で次のオプション情報を交換します。

1. the send/receive interface and source/destination address, 2. the hop limit, 3. next hop address, 4. Hop-by-Hop options, 5. Destination options, and 6. Routing header.

1. 送信/受信インターフェイスと送信元/宛先アドレス、2。ホップ制限、3。次ホップアドレス、4。ホップバイホップオプション、5。宛先オプション、6。ルーティングヘッダー。

Before describing these uses in detail, we review the definition of the msghdr structure itself, the cmsghdr structure that defines an ancillary data object, and some functions that operate on the ancillary data objects.

これらの用途を詳細に説明する前に、msghdr構造自体の定義、補助データオブジェクトを定義するcmsghdr構造、および補助データオブジェクトを操作するいくつかの関数を確認します。

4.1. The msghdr Structure
4.1. msghdr構造

The msghdr structure is used by the recvmsg() and sendmsg() functions. Its Posix.1g definition is:

msghdr構造体は、recvmsg()およびsendmsg()関数によって使用されます。そのPosix.1g定義は次のとおりです。

    struct msghdr {
      void      *msg_name;        /* ptr to socket address structure */
      socklen_t  msg_namelen;     /* size of socket address structure */
      struct iovec  *msg_iov;     /* scatter/gather array */
      size_t     msg_iovlen;      /* # elements in msg_iov */
      void      *msg_control;     /* ancillary data */
      socklen_t  msg_controllen;  /* ancillary data buffer length */
      int        msg_flags;       /* flags on received message */
    };
        

The structure is declared as a result of including <sys/socket.h>.

構造体は、<sys / socket.h>をインクルードした結果として宣言されています。

(Note: Before Posix.1g the two "void *" pointers were typically "char *", and the two socklen_t members and the size_t member were typically integers. Earlier drafts of Posix.1g had the two socklen_t members as size_t, but Draft 6.6 of Posix.1g, apparently the final draft, changed these to socklen_t to simplify binary portability for 64-bit implementations and to align Posix.1g with X/Open's Networking Services, Issue 5. The change in msg_control to a "void *" pointer affects any code that increments this pointer.)

(注:Posix.1gより前は、2つの「void *」ポインタは通常「char *」であり、2つのsocklen_tメンバーとsize_tメンバーは通常整数でした。Posix.1gの以前のドラフトでは、2つのsocklen_tメンバーがsize_tでしたが、Draft Posix.1gの6.6(明らかに最終ドラフト)では、これらをsocklen_tに変更して、64ビット実装のバイナリ移植性を簡素化し、Posix.1gをX / Openのネットワークサービスの第5号に合わせました。msg_controlの「void *」への変更ポインターは、このポインターをインクリメントするすべてのコードに影響します。)

Most Berkeley-derived implementations limit the amount of ancillary data in a call to sendmsg() to no more than 108 bytes (an mbuf). This API requires a minimum of 10240 bytes of ancillary data, but it is recommended that the amount be limited only by the buffer space reserved by the socket (which can be modified by the SO_SNDBUF socket option). (Note: This magic number 10240 was picked as a value that should always be large enough. 108 bytes is clearly too small as the maximum size of a Type 0 Routing header is 376 bytes.)

ほとんどのBerkeley派生の実装では、sendmsg()への呼び出しの補助データの量を108バイト(mbuf)以下に制限しています。このAPIには最低10240バイトの補助データが必要ですが、その量は、ソケットによって予約されたバッファースペース(SO_SNDBUFソケットオプションで変更可能)によってのみ制限されることをお勧めします。 (注:このマジック番号10240は、常に十分に大きい値として選択されています。タイプ0ルーティングヘッダーの最大サイズが376バイトであるため、108バイトは明らかに小さすぎます。)

4.2. The cmsghdr Structure
4.2. cmsghdr構造

The cmsghdr structure describes ancillary data objects transferred by recvmsg() and sendmsg(). Its Posix.1g definition is:

cmsghdr構造体は、recvmsg()およびsendmsg()によって転送される補助データオブジェクトを記述します。そのPosix.1g定義は次のとおりです。

    struct cmsghdr {
      socklen_t  cmsg_len;   /* #bytes, including this header */
      int        cmsg_level; /* originating protocol */
      int        cmsg_type;  /* protocol-specific type */
                 /* followed by unsigned char cmsg_data[]; */
    };
        

This structure is declared as a result of including <sys/socket.h>.

この構造体は、<sys / socket.h>を組み込んだ結果として宣言されています。

As shown in this definition, normally there is no member with the name cmsg_data[]. Instead, the data portion is accessed using the CMSG_xxx() macros, as described shortly. Nevertheless, it is common to refer to the cmsg_data[] member.

この定義に示されているように、通常、cmsg_data []という名前のメンバーはありません。代わりに、データ部分には、CMSG_xxx()マクロを使用してアクセスします。それにもかかわらず、cmsg_data []メンバーを参照することは一般的です。

(Note: Before Posix.1g the cmsg_len member was an integer, and not a socklen_t. See the Note in the previous section for why socklen_t is used here.)

(注:Posix.1gより前は、cmsg_lenメンバーは整数であり、socklen_tではありませんでした。ここでsocklen_tが使用される理由については、前のセクションの注を参照してください。)

When ancillary data is sent or received, any number of ancillary data objects can be specified by the msg_control and msg_controllen members of the msghdr structure, because each object is preceded by a cmsghdr structure defining the object's length (the cmsg_len member). Historically Berkeley-derived implementations have passed only one object at a time, but this API allows multiple objects to be passed in a single call to sendmsg() or recvmsg(). The following example shows two ancillary data objects in a control buffer.

補助データが送信または受信されると、msghdr構造のmsg_controlメンバーとmsg_controllenメンバーによって任意の数の補助データオブジェクトを指定できます。これは、各オブジェクトの前に、オブジェクトの長さを定義するcmsghdr構造(cmsg_lenメンバー)があるためです。歴史的には、Berkeley派生の実装は一度に1つのオブジェクトのみを渡していましたが、このAPIでは、sendmsg()またはrecvmsg()への1回の呼び出しで複数のオブジェクトを渡すことができます。次の例は、制御バッファー内の2つの補助データオブジェクトを示しています。

|<--------------------------- msg_controllen -------------------------->|
|                                                                       |
|<----- ancillary data object ----->|<----- ancillary data object ----->|
|<---------- CMSG_SPACE() --------->|<---------- CMSG_SPACE() --------->|
|                                   |                                   |
|<---------- cmsg_len ---------->|  |<--------- cmsg_len ----------->|  |
|<--------- CMSG_LEN() --------->|  |<-------- CMSG_LEN() ---------->|  |
|                                |  |                                |  |
+-----+-----+-----+--+-----------+--+-----+-----+-----+--+-----------+--+
|cmsg_|cmsg_|cmsg_|XX|           |XX|cmsg_|cmsg_|cmsg_|XX|           |XX|
|len  |level|type |XX|cmsg_data[]|XX|len  |level|type |XX|cmsg_data[]|XX|
+-----+-----+-----+--+-----------+--+-----+-----+-----+--+-----------+--+
 ^
 |
msg_control
points here
        

The fields shown as "XX" are possible padding, between the cmsghdr structure and the data, and between the data and the next cmsghdr structure, if required by the implementation.

"XX"として示されているフィールドは、cmsghdr構造体とデータの間、およびデータと次のcmsghdr構造体の間で、実装で必要な場合に可能なパディングです。

4.3. Ancillary Data Object Macros
4.3. 補助データオブジェクトマクロ

To aid in the manipulation of ancillary data objects, three macros from 4.4BSD are defined by Posix.1g: CMSG_DATA(), CMSG_NXTHDR(), and CMSG_FIRSTHDR(). Before describing these macros, we show the following example of how they might be used with a call to recvmsg().

補助データオブジェクトの操作を支援するために、4.4BSDの3つのマクロがPosix.1gで定義されています:CMSG_DATA()、CMSG_NXTHDR()、およびCMSG_FIRSTHDR()。これらのマクロを説明する前に、recvmsg()の呼び出しでこれらのマクロを使用する方法の次の例を示します。

    struct msghdr   msg;
    struct cmsghdr  *cmsgptr;
        
    /* fill in msg */
        
    /* call recvmsg() */
        
    for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
         cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
        if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) {
            u_char  *ptr;
        
            ptr = CMSG_DATA(cmsgptr);
            /* process data pointed to by ptr */
        }
    }
        

We now describe the three Posix.1g macros, followed by two more that are new with this API: CMSG_SPACE() and CMSG_LEN(). All these macros are defined as a result of including <sys/socket.h>.

3つのPosix.1gマクロについて説明し、続いてこのAPIで新しく追加された2つのマクロCMSG_SPACE()とCMSG_LEN()について説明します。これらのマクロはすべて、<sys / socket.h>を組み込んだ結果として定義されています。

4.3.1. CMSG_FIRSTHDR
4.3.1. CMSG_FIRSTHDR
       struct cmsghdr *CMSG_FIRSTHDR(const struct msghdr *mhdr);
        

CMSG_FIRSTHDR() returns a pointer to the first cmsghdr structure in the msghdr structure pointed to by mhdr. The macro returns NULL if there is no ancillary data pointed to the by msghdr structure (that is, if either msg_control is NULL or if msg_controllen is less than the size of a cmsghdr structure).

CMSG_FIRSTHDR()は、mhdrが指すmsghdr構造体の最初のcmsghdr構造体へのポインターを返します。 msghdr構造体が指す補助データがない場合(つまり、msg_controlがNULLであるか、msg_controllenがcmsghdr構造体のサイズより小さい場合)、マクロはNULLを返します。

One possible implementation could be

1つの可能な実装は、

       #define CMSG_FIRSTHDR(mhdr) \
           ( (mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
             (struct cmsghdr *)(mhdr)->msg_control : \
             (struct cmsghdr *)NULL )
        

(Note: Most existing implementations do not test the value of msg_controllen, and just return the value of msg_control. The value of msg_controllen must be tested, because if the application asks recvmsg() to return ancillary data, by setting msg_control to point to the application's buffer and setting msg_controllen to the length of this buffer, the kernel indicates that no ancillary data is available by setting msg_controllen to 0 on return. It is also easier to put this test into this macro, than making the application perform the test.)

(注:ほとんどの既存の実装はmsg_controllenの値をテストせず、msg_controlの値を返すだけです。アプリケーションが補助データを返すようにアプリケーションがrecvmsg()に要求する場合、msg_controlがアプリケーションのバッファーとmsg_controllenをこのバッファーの長さに設定すると、カーネルは、戻り時にmsg_controllenを0に設定することにより、補助データが利用できないことを示します。アプリケーションにテストを実行させるよりも、このマクロをこのマクロに入れる方が簡単です。)

4.3.2. CMSG_NXTHDR
4.3.2. CMSG_NXTHDR
       struct cmsghdr *CMSG_NXTHDR(const struct msghdr *mhdr,
                                   const struct cmsghdr *cmsg);
        

CMSG_NXTHDR() returns a pointer to the cmsghdr structure describing the next ancillary data object. mhdr is a pointer to a msghdr structure and cmsg is a pointer to a cmsghdr structure. If there is not another ancillary data object, the return value is NULL.

CMSG_NXTHDR()は、次の補助データオブジェクトを記述するcmsghdr構造へのポインタを返します。 mhdrはmsghdr構造体へのポインターで、cmsgはcmsghdr構造体へのポインターです。別の補助データオブジェクトがない場合、戻り値はNULLです。

The following behavior of this macro is new to this API: if the value of the cmsg pointer is NULL, a pointer to the cmsghdr structure describing the first ancillary data object is returned. That is, CMSG_NXTHDR(mhdr, NULL) is equivalent to CMSG_FIRSTHDR(mhdr). If there are no ancillary data objects, the return value is NULL. This provides an alternative way of coding the processing loop shown earlier:

このマクロの次の動作は、このAPIの新機能です。cmsgポインターの値がNULLの場合、最初の補助データオブジェクトを記述するcmsghdr構造へのポインターが返されます。つまり、CMSG_NXTHDR(mhdr、NULL)はCMSG_FIRSTHDR(mhdr)と同等です。補助データオブジェクトがない場合、戻り値はNULLです。これにより、前に示した処理ループをコーディングする別の方法が提供されます。

struct msghdr  msg;
struct cmsghdr  *cmsgptr = NULL;
        
/* fill in msg */
        
/* call recvmsg() */
        
while ((cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) != NULL) {
    if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) {
        u_char  *ptr;
        
        ptr = CMSG_DATA(cmsgptr);
        /* process data pointed to by ptr */
    }
}
        

One possible implementation could be:

可能な実装の1つは次のとおりです。

    #define CMSG_NXTHDR(mhdr, cmsg) \
        ( ((cmsg) == NULL) ? CMSG_FIRSTHDR(mhdr) : \
          (((u_char *)(cmsg) + ALIGN((cmsg)->cmsg_len) \
                             + ALIGN(sizeof(struct cmsghdr)) > \
            (u_char *)((mhdr)->msg_control) + (mhdr)->msg_controllen) ? \
           (struct cmsghdr *)NULL : \
           (struct cmsghdr *)((u_char *)(cmsg) + ALIGN((cmsg)->cmsg_len))) )
        

The macro ALIGN(), which is implementation dependent, rounds its argument up to the next even multiple of whatever alignment is required (probably a multiple of 4 or 8 bytes).

実装に依存するマクロALIGN()は、必要な整列の倍数(おそらく4または8バイトの倍数)まで、引数を次の倍数に切り上げます。

4.3.3. CMSG_DATA
4.3.3. CMSG_DATA
       unsigned char *CMSG_DATA(const struct cmsghdr *cmsg);
        

CMSG_DATA() returns a pointer to the data (what is called the cmsg_data[] member, even though such a member is not defined in the structure) following a cmsghdr structure.

CMSG_DATA()は、cmsghdr構造体に続くデータ(そのようなメンバーが構造体で定義されていなくても、cmsg_data []メンバーと呼ばれるもの)へのポインターを返します。

One possible implementation could be:

可能な実装の1つは次のとおりです。

       #define CMSG_DATA(cmsg) ( (u_char *)(cmsg) + \
                                 ALIGN(sizeof(struct cmsghdr)) )
        
4.3.4. CMSG_SPACE
4.3.4. CMSG_SPACE

unsigned int CMSG_SPACE(unsigned int length);

unsigned int CMSG_SPACE(unsigned int length);

This macro is new with this API. Given the length of an ancillary data object, CMSG_SPACE() returns the space required by the object and its cmsghdr structure, including any padding needed to satisfy alignment requirements. This macro can be used, for example, to allocate space dynamically for the ancillary data. This macro should not be used to initialize the cmsg_len member of a cmsghdr structure; instead use the CMSG_LEN() macro.

このマクロは、このAPIで新しく追加されました。補助データオブジェクトの長さを指定すると、CMSG_SPACE()は、オブジェクトとそのcmsghdr構造体で必要なスペースを返します。これには、配置要件を満たすために必要なパディングも含まれます。このマクロは、たとえば、補助データに動的にスペースを割り当てるために使用できます。このマクロを使用して、cmsghdr構造体のcmsg_lenメンバーを初期化しないでください。代わりにCMSG_LEN()マクロを使用してください。

One possible implementation could be:

可能な実装の1つは次のとおりです。

       #define CMSG_SPACE(length) ( ALIGN(sizeof(struct cmsghdr)) + \
                                    ALIGN(length) )
        
4.3.5. CMSG_LEN
4.3.5. CMSG_LEN

unsigned int CMSG_LEN(unsigned int length);

unsigned int CMSG_LEN(unsigned int length);

This macro is new with this API. Given the length of an ancillary data object, CMSG_LEN() returns the value to store in the cmsg_len member of the cmsghdr structure, taking into account any padding needed to satisfy alignment requirements.

このマクロは、このAPIで新しく追加されました。補助データオブジェクトの長さを指定すると、CMSG_LEN()は、アライメント要件を満たすために必要なパディングを考慮して、cmsghdr構造体のcmsg_lenメンバーに格納する値を返します。

One possible implementation could be:

可能な実装の1つは次のとおりです。

       #define CMSG_LEN(length) ( ALIGN(sizeof(struct cmsghdr)) + length
       )
        

Note the difference between CMSG_SPACE() and CMSG_LEN(), shown also in the figure in Section 4.2: the former accounts for any required padding at the end of the ancillary data object and the latter is the actual length to store in the cmsg_len member of the ancillary data object.

セクション4.2の図にも示されているCMSG_SPACE()とCMSG_LEN()の違いに注意してください。前者は補助データオブジェクトの終わりに必要なパディングを説明し、後者はのcmsg_lenメンバーに格納する実際の長さです補助データオブジェクト。

4.4. Summary of Options Described Using Ancillary Data
4.4. 補助データを使用して説明されているオプションの概要

There are six types of optional information described in this document that are passed between the application and the kernel using ancillary data:

このドキュメントで説明されているオプションの情報には、アプリケーションとカーネルの間で補助データを使用して渡される6つのタイプがあります。

1. the send/receive interface and source/destination address, 2. the hop limit, 3. next hop address, 4. Hop-by-Hop options, 5. Destination options, and 6. Routing header.

1. 送信/受信インターフェイスと送信元/宛先アドレス、2。ホップ制限、3。次ホップアドレス、4。ホップバイホップオプション、5。宛先オプション、6。ルーティングヘッダー。

First, to receive any of this optional information (other than the next hop address, which can only be set), the application must call setsockopt() to turn on the corresponding flag:

まず、このオプション情報(設定のみ可能なネクストホップアドレス以外)を受信するには、アプリケーションはsetsockopt()を呼び出して対応するフラグをオンにする必要があります。

int on = 1;

int on = 1;

       setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO,  &on, sizeof(on));
       setsockopt(fd, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on));
       setsockopt(fd, IPPROTO_IPV6, IPV6_HOPOPTS,  &on, sizeof(on));
       setsockopt(fd, IPPROTO_IPV6, IPV6_DSTOPTS,  &on, sizeof(on));
       setsockopt(fd, IPPROTO_IPV6, IPV6_RTHDR,    &on, sizeof(on));
        

When any of these options are enabled, the corresponding data is returned as control information by recvmsg(), as one or more ancillary data objects.

これらのオプションのいずれかが有効になっている場合、対応するデータは、recvmsg()によって制御情報として、1つ以上の補助データオブジェクトとして返されます。

Nothing special need be done to send any of this optional information; the application just calls sendmsg() and specifies one or more ancillary data objects as control information.

このオプション情報を送信するために特別なことを行う必要はありません。アプリケーションは単にsendmsg()を呼び出し、制御情報として1つ以上の補助データオブジェクトを指定します。

We also summarize the three cmsghdr fields that describe the ancillary data objects:

また、補助データオブジェクトを説明する3つのcmsghdrフィールドも要約します。

       cmsg_level    cmsg_type      cmsg_data[]               #times
       ------------  ------------   ------------------------  ------
       IPPROTO_IPV6  IPV6_PKTINFO   in6_pktinfo structure     once
       IPPROTO_IPV6  IPV6_HOPLIMIT  int                       once
       IPPROTO_IPV6  IPV6_NEXTHOP   socket address structure  once
       IPPROTO_IPV6  IPV6_HOPOPTS   implementation dependent  mult.
        

IPPROTO_IPV6 IPV6_DSTOPTS implementation dependent mult. IPPROTO_IPV6 IPV6_RTHDR implementation dependent once

IPPROTO_IPV6 IPV6_DSTOPTS実装に依存するマルチ。 IPPROTO_IPV6 IPV6_RTHDR実装は1回のみ依存

The final column indicates how many times an ancillary data object of that type can appear as control information. The Hop-by-Hop and Destination options can appear multiple times, while all the others can appear only one time.

最後の列は、そのタイプの補助データオブジェクトが制御情報として表示できる回数を示しています。ホップバイホップオプションと宛先オプションは複数回表示できますが、その他のオプションはすべて1回しか表示できません。

All these options are described in detail in following sections. All the constants beginning with IPV6_ are defined as a result of including the <netinet/in.h> header.

これらすべてのオプションについては、次のセクションで詳しく説明します。 IPV6_で始まるすべての定数は、<netinet / in.h>ヘッダーを組み込んだ結果として定義されています。

(Note: We intentionally use the same constant for the cmsg_level member as is used as the second argument to getsockopt() and setsockopt() (what is called the "level"), and the same constant for the cmsg_type member as is used as the third argument to getsockopt() and setsockopt() (what is called the "option name"). This is consistent with the existing use of ancillary data in 4.4BSD: returning the destination address of an IPv4 datagram.)

(注:getsockopt()およびsetsockopt()の2番目の引数(「レベル」と呼ばれる)と同じ定数をcmsg_levelメンバーに意図的に使用し、cmsg_typeメンバーにも同じ定数を使用しています。 getsockopt()およびsetsockopt()の3番目の引数(「オプション名」と呼ばれるもの)。これは、4.4BSDでの補助データの既存の使用と一致しています。IPv4データグラムの宛先アドレスを返します。)

(Note: It is up to the implementation what it passes as ancillary data for the Hop-by-Hop option, Destination option, and Routing header option, since the API to these features is through a set of inet6_option_XXX() and inet6_rthdr_XXX() functions that we define later. These functions serve two purposes: to simplify the interface to these features (instead of requiring the application to know the intimate details of the extension header formats), and to hide the actual implementation from the application. Nevertheless, we show some examples of these features that store the actual extension header as the ancillary data. Implementations need not use this technique.)

(注:これらの機能へのAPIはinet6_option_XXX()とinet6_rthdr_XXX()のセットを介するため、ホップバイホップオプション、宛先オプション、およびルーティングヘッダーオプションの補助データとして何を渡すかは、実装次第です。後で定義する関数です。これらの関数には2つの目的があります。これらの機能へのインターフェースを簡素化する(アプリケーションが拡張ヘッダー形式の詳細を知る必要がない)ことと、実際の実装をアプリケーションから隠すことです。それにもかかわらず、は、実際の拡張ヘッダーを補助データとして保存するこれらの機能の例をいくつか示しています。実装では、この手法を使用する必要はありません。)

4.5. IPV6_PKTOPTIONS Socket Option
4.5. IPV6_PKTOPTIONSソケットオプション

The summary in the previous section assumes a UDP socket. Sending and receiving ancillary data is easy with UDP: the application calls sendmsg() and recvmsg() instead of sendto() and recvfrom().

前のセクションの要約では、UDPソケットを想定しています。 UDPを使用すると、補助データの送受信が簡単です。アプリケーションは、sendto()とrecvfrom()の代わりにsendmsg()とrecvmsg()を呼び出します。

But there might be cases where a TCP application wants to send or receive this optional information. For example, a TCP client might want to specify a Routing header and this needs to be done before calling connect(). Similarly a TCP server might want to know the received interface after accept() returns along with any Destination options.

ただし、TCPアプリケーションがこのオプション情報を送信または受信したい場合があります。たとえば、TCPクライアントはルーティングヘッダーを指定する必要があり、これはconnect()を呼び出す前に行う必要があります。同様に、TCPサーバーは、destinationオプションとともにaccept()が戻った後に、受信したインターフェースを知りたい場合があります。

A new socket option is defined that provides access to the optional information described in the previous section, but without using recvmsg() and sendmsg(). Setting the socket option specifies any of the optional output fields:

前のセクションで説明したオプション情報へのアクセスを提供する新しいソケットオプションが定義されていますが、recvmsg()およびsendmsg()は使用していません。ソケットオプションを設定すると、オプションの出力フィールドが指定されます。

setsockopt(fd, IPPROTO_IPV6, IPV6_PKTOPTIONS, &buf, len);

setsockopt(fd、IPPROTO_IPV6、IPV6_PKTOPTIONS、&buf、len);

The fourth argument points to a buffer containing one or more ancillary data objects, and the fifth argument is the total length of all these objects. The application fills in this buffer exactly as if the buffer were being passed to sendmsg() as control information.

4番目の引数は、1つ以上の補助データオブジェクトを含むバッファを指し、5番目の引数は、これらすべてのオブジェクトの全長です。アプリケーションは、バッファーが制御情報としてsendmsg()に渡された場合とまったく同じように、このバッファーを埋めます。

The options set by calling setsockopt() for IPV6_PKTOPTIONS are called "sticky" options because once set they apply to all packets sent on that socket. The application can call setsockopt() again to change all the sticky options, or it can call setsockopt() with a length of 0 to remove all the sticky options for the socket.

IPV6_PKTOPTIONSに対してsetsockopt()を呼び出して設定されたオプションは、一度設定するとそのソケットで送信されるすべてのパケットに適用されるため、「スティッキー」オプションと呼ばれます。アプリケーションは、setsockopt()を再度呼び出してすべてのスティッキーオプションを変更するか、長さが0のsetsockopt()を呼び出してソケットのすべてのスティッキーオプションを削除できます。

The corresponding receive option

対応する受信オプション

getsockopt(fd, IPPROTO_IPV6, IPV6_PKTOPTIONS, &buf, &len);

getsockopt(fd、IPPROTO_IPV6、IPV6_PKTOPTIONS、&buf、&len);

returns a buffer with one or more ancillary data objects for all the optional receive information that the application has previously specified that it wants to receive. The fourth argument points to the buffer that is filled in by the call. The fifth argument is a pointer to a value-result integer: when the function is called the integer specifies the size of the buffer pointed to by the fourth argument, and on return this integer contains the actual number of bytes that were returned. The application processes this buffer exactly as if the buffer were returned by recvmsg() as control information.

アプリケーションが以前に受信したいことを指定したすべてのオプションの受信情報の1つ以上の補助データオブジェクトを含むバッファを返します。 4番目の引数は、呼び出しによって埋められるバッファーを指します。 5番目の引数は、値と結果の整数へのポインタです。関数が呼び出されると、整数は4番目の引数が指すバッファのサイズを指定し、戻り時に、この整数には返された実際のバイト数が含まれます。アプリケーションは、制御情報としてrecvmsg()によってバッファーが返された場合とまったく同じように、このバッファーを処理します。

To simplify this document, in the remaining sections when we say "can be specified as ancillary data to sendmsg()" we mean "can be specified as ancillary data to sendmsg() or specified as a sticky option using setsockopt() and the IPV6_PKTOPTIONS socket option". Similarly when we say "can be returned as ancillary data by recvmsg()" we mean "can be returned as ancillary data by recvmsg() or returned by getsockopt() with the IPV6_PKTOPTIONS socket option".

このドキュメントを簡略化するために、残りのセクションで「sendmsg()の補助データとして指定できる」と言うときは、「sendmsg()の補助データとして指定できるか、setsockopt()とIPV6_PKTOPTIONSを使用してスティッキーオプションとして指定できる」という意味です。ソケットオプション」。同様に、「recvmsg()によって補助データとして返される可能性がある」とは、「recvmsg()によって補助データとして返されるか、IPV6_PKTOPTIONSソケットオプションを指定したgetsockopt()によって返される」ことを意味します。

4.5.1. TCP Sticky Options
4.5.1. TCPスティッキオプション

When using getsockopt() with the IPV6_PKTOPTIONS option and a TCP socket, only the options from the most recently received segment are retained and returned to the caller, and only after the socket option has been set. That is, TCP need not start saving a copy of the options until the application says to do so.

IPV6_PKTOPTIONSオプションとTCPソケットを指定してgetsockopt()を使用する場合、最後に受信したセグメントのオプションのみが保持され、ソケットオプションが設定された後にのみ、呼び出し元に返されます。つまり、アプリケーションから指示があるまで、TCPはオプションのコピーの保存を開始する必要はありません。

The application is not allowed to specify ancillary data in a call to sendmsg() on a TCP socket, and none of the ancillary data that we describe in this document is ever returned as control information by recvmsg() on a TCP socket.

アプリケーションは、TCPソケットのsendmsg()の呼び出しで補助データを指定することはできません。また、このドキュメントで説明する補助データは、TCPソケットのrecvmsg()によって制御情報として返されることはありません。

4.5.2. UDP and Raw Socket Sticky Options
4.5.2. UDPおよびRawソケットスティッキオプション

The IPV6_PKTOPTIONS socket option can also be used with a UDP socket or with a raw IPv6 socket, normally to set some of the options once, instead of with each call to sendmsg().

IPV6_PKTOPTIONSソケットオプションは、UDPソケットまたはraw IPv6ソケットでも使用できます。通常、sendmsg()を呼び出すたびにではなく、一部のオプションを1回だけ設定します。

Unlike the TCP case, the sticky options can be overridden on a per-packet basis with ancillary data specified in a call to sendmsg() on a UDP or raw IPv6 socket. If any ancillary data is specified in a call to sendmsg(), none of the sticky options are sent with that datagram.

TCPの場合とは異なり、スティッキーオプションは、UDPまたはraw IPv6ソケットのsendmsg()への呼び出しで指定された補助データでパケットごとにオーバーライドできます。 sendmsg()の呼び出しで補助データが指定されている場合、そのデータグラムではスティッキーオプションは送信されません。

5. Packet Information
5. パケット情報

There are four pieces of information that an application can specify for an outgoing packet using ancillary data:

アプリケーションが補助データを使用して発信パケットに指定できる情報は4つあります。

1. the source IPv6 address, 2. the outgoing interface index, 3. the outgoing hop limit, and 4. the next hop address.

1. 送信元IPv6アドレス、2。送信インターフェイスインデックス、3。送信ホップ制限、4。次ホップアドレス。

Three similar pieces of information can be returned for a received packet as ancillary data:

受信したパケットに対して、3つの同様の情報を補助データとして返すことができます。

1. the destination IPv6 address, 2. the arriving interface index, and 3. the arriving hop limit.

1. 宛先IPv6アドレス、2。到着インターフェースインデックス、3。到着ホップリミット。

The first two pieces of information are contained in an in6_pktinfo structure that is sent as ancillary data with sendmsg() and received as ancillary data with recvmsg(). This structure is defined as a result of including the <netinet/in.h> header.

最初の2つの情報は、sinmsg()で補助データとして送信され、recvmsg()で補助データとして受信されるin6_pktinfo構造に含まれています。この構造は、<netinet / in.h>ヘッダーを組み込んだ結果として定義されています。

       struct in6_pktinfo {
         struct in6_addr ipi6_addr;    /* src/dst IPv6 address */
         unsigned int    ipi6_ifindex; /* send/recv interface index */
       };
        

In the cmsghdr structure containing this ancillary data, the cmsg_level member will be IPPROTO_IPV6, the cmsg_type member will be IPV6_PKTINFO, and the first byte of cmsg_data[] will be the first byte of the in6_pktinfo structure.

この補助データを含むcmsghdr構造では、cmsg_levelメンバーはIPPROTO_IPV6になり、cmsg_typeメンバーはIPV6_PKTINFOになり、cmsg_data []の最初のバイトはin6_pktinfo構造の最初のバイトになります。

This information is returned as ancillary data by recvmsg() only if the application has enabled the IPV6_PKTINFO socket option:

この情報は、アプリケーションがIPV6_PKTINFOソケットオプションを有効にしている場合にのみ、recvmsg()によって補助データとして返されます。

       int  on = 1;
       setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on));
        

Nothing special need be done to send this information: just specify the control information as ancillary data for sendmsg().

この情報を送信するために特別なことを行う必要はありません。制御情報をsendmsg()の補助データとして指定するだけです。

(Note: The hop limit is not contained in the in6_pktinfo structure for the following reason. Some UDP servers want to respond to client requests by sending their reply out the same interface on which the request was received and with the source IPv6 address of the reply equal to the destination IPv6 address of the request. To do this the application can enable just the IPV6_PKTINFO socket option and then use the received control information from recvmsg() as the outgoing control information for sendmsg(). The application need not examine or modify the in6_pktinfo structure at all. But if the hop limit were contained in this structure, the application would have to parse the received control information and change the hop limit member, since the received hop limit is not the desired value for an outgoing packet.)

(注:次の理由により、ホップ制限はin6_pktinfo構造に含まれていません。一部のUDPサーバーは、要求が受信されたのと同じインターフェースと、応答のソースIPv6アドレスを使用して応答を送信することにより、クライアント要求に応答します。要求の宛先IPv6アドレスと同じです。これを行うには、アプリケーションでIPV6_PKTINFOソケットオプションのみを有効にしてから、recvmsg()から受信した制御情報をsendmsg(の送信制御情報として使用します。アプリケーションで検査または変更する必要はありません。 in6_pktinfo構造。ただし、この構造にホップ制限が含まれている場合、受信したホップ制限は送信パケットに必要な値ではないため、アプリケーションは受信した制御情報を解析してホップ制限メンバーを変更する必要があります。)

5.1. Specifying/Receiving the Interface
5.1. インターフェイスの指定/受信

Interfaces on an IPv6 node are identified by a small positive integer, as described in Section 4 of [RFC-2133]. That document also describes a function to map an interface name to its interface index, a function to map an interface index to its interface name, and a function to return all the interface names and indexes. Notice from this document that no interface is ever assigned an index of 0.

[RFC-2133]のセクション4で説明されているように、IPv6ノードのインターフェースは小さな正の整数で識別されます。そのドキュメントでは、インターフェイス名をそのインターフェイスインデックスにマップする関数、インターフェイスインデックスをそのインターフェイス名にマップする関数、すべてのインターフェイス名とインデックスを返す関数についても説明しています。このドキュメントから、どのインデックスにも0のインデックスが割り当てられていないことに注意してください。

When specifying the outgoing interface, if the ipi6_ifindex value is 0, the kernel will choose the outgoing interface. If the application specifies an outgoing interface for a multicast packet, the interface specified by the ancillary data overrides any interface specified by the IPV6_MULTICAST_IF socket option (described in [RFC-2133]), for that call to sendmsg() only.

発信インターフェースを指定するときに、ipi6_ifindex値が0の場合、カーネルは発信インターフェースを選択します。アプリケーションがマルチキャストパケットの発信インターフェイスを指定する場合、sendmsg()への呼び出しについてのみ、補助データで指定されたインターフェイスが、IPV6_MULTICAST_IFソケットオプション([RFC-2133]で説明)で指定されたインターフェイスをオーバーライドします。

When the IPV6_PKTINFO socket option is enabled, the received interface index is always returned as the ipi6_ifindex member of the in6_pktinfo structure.

IPV6_PKTINFOソケットオプションが有効な場合、受信したインターフェイスインデックスは常に、in6_pktinfo構造体のipi6_ifindexメンバーとして返されます。

5.2. Specifying/Receiving Source/Destination Address
5.2. 発信元/宛先アドレスの指定/受信

The source IPv6 address can be specified by calling bind() before each output operation, but supplying the source address together with the data requires less overhead (i.e., fewer system calls) and requires less state to be stored and protected in a multithreaded application.

送信元IPv6アドレスは、各出力操作の前にbind()を呼び出すことで指定できますが、送信元アドレスをデータと一緒に指定すると、オーバーヘッドが少なくなり(つまり、システムコールが減り)、マルチスレッドアプリケーションに格納および保護する状態が少なくなります。

When specifying the source IPv6 address as ancillary data, if the ipi6_addr member of the in6_pktinfo structure is the unspecified address (IN6ADDR_ANY_INIT), then (a) if an address is currently bound to the socket, it is used as the source address, or (b) if no address is currently bound to the socket, the kernel will choose the source address. If the ipi6_addr member is not the unspecified address, but the socket has already bound a source address, then the ipi6_addr value overrides the already-bound source address for this output operation only.

ソースIPv6アドレスを補助データとして指定するときに、in6_pktinfo構造体のipi6_addrメンバーが未指定アドレス(IN6ADDR_ANY_INIT)である場合、(a)アドレスが現在ソケットにバインドされている場合は、それがソースアドレスとして使用されるか、または( b)現在ソケットにバインドされているアドレスがない場合、カーネルはソースアドレスを選択します。 ipi6_addrメンバーが未指定のアドレスではないが、ソケットがすでに送信元アドレスをバインドしている場合、ipi6_addr値は、この出力操作に対してのみ、すでにバインドされている送信元アドレスをオーバーライドします。

The kernel must verify that the requested source address is indeed a unicast address assigned to the node.

カーネルは、要求されたソースアドレスが実際にノードに割り当てられたユニキャストアドレスであることを確認する必要があります。

When the in6_pktinfo structure is returned as ancillary data by recvmsg(), the ipi6_addr member contains the destination IPv6 address from the received packet.

in6_pktinfo構造がrecvmsg()によって補助データとして返される場合、ipi6_addrメンバーには、受信したパケットからの宛先IPv6アドレスが含まれます。

5.3. Specifying/Receiving the Hop Limit
5.3. ホップリミットの指定/受信

The outgoing hop limit is normally specified with either the IPV6_UNICAST_HOPS socket option or the IPV6_MULTICAST_HOPS socket option, both of which are described in [RFC-2133]. Specifying the hop limit as ancillary data lets the application override either the kernel's default or a previously specified value, for either a unicast destination or a multicast destination, for a single output operation. Returning the received hop limit is useful for programs such as Traceroute and for IPv6 applications that need to verify that the received hop limit is 255 (e.g., that the packet has not been forwarded).

発信ホップ制限は通常、IPV6_UNICAST_HOPSソケットオプションまたはIPV6_MULTICAST_HOPSソケットオプションのいずれかで指定されます。これらは両方とも[RFC-2133]で説明されています。ホップ制限を補助データとして指定すると、アプリケーションは、単一の出力操作について、カーネルのデフォルトまたはユニキャスト宛先またはマルチキャスト宛先の以前に指定された値をオーバーライドできます。受信したホップ制限を返すことは、Tracerouteなどのプログラムや、受信したホップ制限が255であることを確認する必要があるIPv6アプリケーション(パケットが転送されていないなど)に役立ちます。

The received hop limit is returned as ancillary data by recvmsg() only if the application has enabled the IPV6_HOPLIMIT socket option:

受信したホップ制限は、アプリケーションがIPV6_HOPLIMITソケットオプションを有効にしている場合にのみ、recvmsg()によって補助データとして返されます。

       int  on = 1;
       setsockopt(fd, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on));
        

In the cmsghdr structure containing this ancillary data, the cmsg_level member will be IPPROTO_IPV6, the cmsg_type member will be IPV6_HOPLIMIT, and the first byte of cmsg_data[] will be the first byte of the integer hop limit.

この補助データを含むcmsghdr構造では、cmsg_levelメンバーはIPPROTO_IPV6になり、cmsg_typeメンバーはIPV6_HOPLIMITになり、cmsg_data []の最初のバイトは整数ホップ制限の最初のバイトになります。

Nothing special need be done to specify the outgoing hop limit: just specify the control information as ancillary data for sendmsg(). As specified in [RFC-2133], the interpretation of the integer hop limit value is

発信ホップ制限を指定するために特別なことを行う必要はありません。制御情報をsendmsg()の補助データとして指定するだけです。 [RFC-2133]で指定されているように、整数ホップ制限値の解釈は次のとおりです。

       x < -1:        return an error of EINVAL
       x == -1:       use kernel default
       0 <= x <= 255: use x
       x >= 256:      return an error of EINVAL
        
5.4. Specifying the Next Hop Address
5.4. ネクストホップアドレスの指定

The IPV6_NEXTHOP ancillary data object specifies the next hop for the datagram as a socket address structure. In the cmsghdr structure containing this ancillary data, the cmsg_level member will be IPPROTO_IPV6, the cmsg_type member will be IPV6_NEXTHOP, and the first byte of cmsg_data[] will be the first byte of the socket address structure.

IPV6_NEXTHOP補助データオブジェクトは、データグラムのネクストホップをソケットアドレス構造として指定します。この補助データを含むcmsghdr構造では、cmsg_levelメンバーはIPPROTO_IPV6になり、cmsg_typeメンバーはIPV6_NEXTHOPになり、cmsg_data []の最初のバイトはソケットアドレス構造の最初のバイトになります。

This is a privileged option. (Note: It is implementation defined and beyond the scope of this document to define what "privileged" means. Unix systems use this term to mean the process must have an effective user ID of 0.)

これは特権オプションです。 (注:「特権」の意味を定義するのは、このドキュメントの範囲を超える実装定義です。UNIXシステムでは、この用語を使用して、プロセスの実効ユーザーIDが0でなければならないことを意味します。

If the socket address structure contains an IPv6 address (e.g., the sin6_family member is AF_INET6), then the node identified by that address must be a neighbor of the sending host. If that address equals the destination IPv6 address of the datagram, then this is equivalent to the existing SO_DONTROUTE socket option.

ソケットアドレス構造にIPv6アドレスが含まれている場合(たとえば、sin6_familyメンバーがAF_INET6である場合)、そのアドレスで識別されるノードは送信ホストのネイバーである必要があります。そのアドレスがデータグラムの宛先IPv6アドレスと等しい場合、これは既存のSO_DONTROUTEソケットオプションと同等です。

5.5. Additional Errors with sendmsg()
5.5. sendmsg()のその他のエラー

With the IPV6_PKTINFO socket option there are no additional errors possible with the call to recvmsg(). But when specifying the outgoing interface or the source address, additional errors are possible from sendmsg(). The following are examples, but some of these may not be provided by some implementations, and some implementations may define additional errors:

IPV6_PKTINFOソケットオプションを使用すると、recvmsg()の呼び出しで発生する可能性のある追加のエラーはありません。ただし、発信インターフェースまたは送信元アドレスを指定すると、sendmsg()からさらにエラーが発生する可能性があります。以下は例ですが、一部の実装ではこれらの一部が提供されない場合があり、一部の実装では追加のエラーが定義される場合があります。

ENXIO The interface specified by ipi6_ifindex does not exist.

ENXIO ipi6_ifindexで指定されたインターフェイスは存在しません。

ENETDOWN The interface specified by ipi6_ifindex is not enabled for IPv6 use.

ENETDOWN ipi6_ifindexで指定されたインターフェースは、IPv6の使用に対して有効になっていません。

EADDRNOTAVAIL ipi6_ifindex specifies an interface but the address ipi6_addr is not available for use on that interface.

EADDRNOTAVAIL ipi6_ifindexはインターフェースを指定しますが、アドレスipi6_addrはそのインターフェースで使用できません。

EHOSTUNREACH No route to the destination exists over the interface specified by ifi6_ifindex.

EHOSTUNREACH ifi6_ifindexで指定されたインターフェース上に宛先へのルートが存在しません。

6. Hop-By-Hop Options
6. ホップバイホップオプション

A variable number of Hop-by-Hop options can appear in a single Hop-by-Hop options header. Each option in the header is TLV-encoded with a type, length, and value.

可変数のホップバイホップオプションは、単一のホップバイホップオプションヘッダーに表示できます。ヘッダーの各オプションは、タイプ、長さ、および値でTLVエンコードされています。

Today only three Hop-by-Hop options are defined for IPv6 [RFC-1883]: Jumbo Payload, Pad1, and PadN, although a proposal exists for a router-alert Hop-by-Hop option. The Jumbo Payload option should not be passed back to an application and an application should receive an error if it attempts to set it. This option is processed entirely by the kernel. It is indirectly specified by datagram-based applications as the size of the datagram to send and indirectly passed back to these applications as the length of the received datagram. The two pad options are for alignment purposes and are automatically inserted by a sending kernel when needed and ignored by

今日、IPv6 [RFC-1883]には3つのホップバイホップオプションのみが定義されています。ジャンパーペイロード、Pad1、およびPadNですが、ルーターアラートホップバイホップオプションの提案が存在します。ジャンボペイロードオプションをアプリケーションに戻さないでください。アプリケーションが設定しようとすると、エラーが発生します。このオプションは、カーネルによって完全に処理されます。これは、送信するデータグラムのサイズとしてデータグラムベースのアプリケーションによって間接的に指定され、受信したデータグラムの長さとしてこれらのアプリケーションに間接的に返されます。 2つのパッドオプションは位置合わせのためのものであり、必要なときに送信カーネルによって自動的に挿入され、

the receiving kernel. This section of the API is therefore defined for future Hop-by-Hop options that an application may need to specify and receive.

受信カーネル。したがって、APIのこのセクションは、アプリケーションが指定および受信する必要がある将来のホップバイホップオプション用に定義されています。

Individual Hop-by-Hop options (and Destination options, which are described shortly, and which are similar to the Hop-by-Hop options) may have specific alignment requirements. For example, the 4-byte Jumbo Payload length should appear on a 4-byte boundary, and IPv6 addresses are normally aligned on an 8-byte boundary. These requirements and the terminology used with these options are discussed in Section 4.2 and Appendix A of [RFC-1883]. The alignment of each option is specified by two values, called x and y, written as "xn + y". This states that the option must appear at an integer multiple of x bytes from the beginning of the options header (x can have the values 1, 2, 4, or 8), plus y bytes (y can have a value between 0 and 7, inclusive). The Pad1 and PadN options are inserted as needed to maintain the required alignment. Whatever code builds either a Hop-by-Hop options header or a Destination options header must know the values of x and y for each option.

個々のホップバイホップオプション(および簡単に説明され、ホップバイホップオプションと同様の宛先オプション)には、特定の配置要件がある場合があります。たとえば、4バイトのジャンボペイロードの長さは4バイトの境界に表示され、IPv6アドレスは通常8バイトの境界に配置されます。これらの要件とこれらのオプションで使用される用語については、[RFC-1883]のセクション4.2と付録Aで説明しています。各オプションの配置は、xとyと呼ばれる「xn + y」と書かれた2つの値で指定されます。これは、オプションがオプションヘッダーの先頭からxバイトの整数倍で出現する必要があることを示します(xは1、2、4、または8の値を持つことができます)、さらにyバイト(yは0から7の値を持つことができます)を含みます)。必要な配置を維持するために、必要に応じてPad1およびPadNオプションが挿入されます。ホップバイホップオプションヘッダーまたは宛先オプションヘッダーを構築するコードは、各オプションのxとyの値を知っている必要があります。

Multiple Hop-by-Hop options can be specified by the application. Normally one ancillary data object describes all the Hop-by-Hop options (since each option is itself TLV-encoded) but the application can specify multiple ancillary data objects for the Hop-by-Hop options, each object specifying one or more options. Care must be taken designing the API for these options since

アプリケーションでは、複数のホップバイホップオプションを指定できます。通常、1つの補助データオブジェクトはすべてのホップバイホップオプションを記述しますが(各オプションはそれ自体がTLVエンコードされているため)、アプリケーションはホップバイホップオプションに対して複数の補助データオブジェクトを指定でき、各オブジェクトは1つ以上のオプションを指定します。これらのオプションのAPIの設計には注意が必要です。

1. it may be possible for some future Hop-by-Hop options to be generated by the application and processed entirely by the application (e.g., the kernel may not know the alignment restrictions for the option),

1. 将来のいくつかのホップバイホップオプションがアプリケーションによって生成され、アプリケーションによって完全に処理される可能性があります(たとえば、カーネルがオプションの配置制限を認識していない可能性があります)。

2. it must be possible for the kernel to insert its own Hop-by-Hop options in an outgoing packet (e.g., the Jumbo Payload option),

2. カーネルが送信パケットに独自のホップバイホップオプションを挿入できる必要があります(ジャンボペイロードオプションなど)。

3. the application can place one or more Hop-by-Hop options into a single ancillary data object,

3. アプリケーションは、1つ以上のホップバイホップオプションを単一の補助データオブジェクトに配置できます。

4. if the application specifies multiple ancillary data objects, each containing one or more Hop-by-Hop options, the kernel must combine these a single Hop-by-Hop options header, and

4. アプリケーションが複数の補助データオブジェクトを指定し、それぞれに1つ以上のホップバイホップオプションが含まれている場合、カーネルはこれらを単一のホップバイホップオプションヘッダーと組み合わせる必要があります。

5. it must be possible for the kernel to remove some Hop-by-Hop options from a received packet before returning the remaining Hop-by-Hop options to the application. (This removal might consist of the kernel converting the option into a pad option of the same length.)

5. カーネルが、受信したパケットからホップバイホップオプションをいくつか削除してから、残りのホップバイホップオプションをアプリケーションに返すことが可能でなければなりません。 (この削除は、オプションを同じ長さのパッドオプションに変換するカーネルで構成される場合があります。)

Finally, we note that access to some Hop-by-Hop options or to some Destination options, might require special privilege. That is, normal applications (without special privilege) might be forbidden from setting certain options in outgoing packets, and might never see certain options in received packets.

最後に、一部のホップバイホップオプションまたは一部の宛先オプションへのアクセスには、特別な権限が必要になる場合があることに注意してください。つまり、通常のアプリケーション(特別な特権のない)は、送信パケットに特定のオプションを設定することを禁止され、受信パケットに特定のオプションを表示しない場合があります。

6.1. Receiving Hop-by-Hop Options
6.1. ホップバイホップオプションの受信

To receive Hop-by-Hop options the application must enable the IPV6_HOPOPTS socket option:

ホップバイホップオプションを受信するには、アプリケーションでIPV6_HOPOPTSソケットオプションを有効にする必要があります。

       int  on = 1;
       setsockopt(fd, IPPROTO_IPV6, IPV6_HOPOPTS, &on, sizeof(on));
        

All the Hop-by-Hop options are returned as one ancillary data object described by a cmsghdr structure. The cmsg_level member will be IPPROTO_IPV6 and the cmsg_type member will be IPV6_HOPOPTS. These options are then processed by calling the inet6_option_next() and inet6_option_find() functions, described shortly.

すべてのホップバイホップオプションは、cmsghdr構造体で記述された1つの補助データオブジェクトとして返されます。 cmsg_levelメンバーはIPPROTO_IPV6になり、cmsg_typeメンバーはIPV6_HOPOPTSになります。これらのオプションは、後で説明するinet6_option_next()およびinet6_option_find()関数を呼び出すことによって処理されます。

6.2. Sending Hop-by-Hop Options
6.2. ホップバイホップオプションの送信

To send one or more Hop-by-Hop options, the application just specifies them as ancillary data in a call to sendmsg(). No socket option need be set.

1つ以上のホップバイホップオプションを送信するために、アプリケーションはsendmsg()の呼び出しでそれらを補助データとして指定するだけです。ソケットオプションを設定する必要はありません。

Normally all the Hop-by-Hop options are specified by a single ancillary data object. Multiple ancillary data objects, each containing one or more Hop-by-Hop options, can also be specified, in which case the kernel will combine all the Hop-by-Hop options into a single Hop-by-Hop extension header. But it should be more efficient to use a single ancillary data object to describe all the Hop-by-Hop options. The cmsg_level member is set to IPPROTO_IPV6 and the cmsg_type member is set to IPV6_HOPOPTS. The option is normally constructed using the inet6_option_init(), inet6_option_append(), and inet6_option_alloc() functions, described shortly.

通常、すべてのホップバイホップオプションは、単一の補助データオブジェクトによって指定されます。それぞれが1つ以上のホップバイホップオプションを含む複数の補助データオブジェクトを指定することもできます。その場合、カーネルはすべてのホップバイホップオプションを1つのホップバイホップ拡張ヘッダーに結合します。ただし、単一の補助データオブジェクトを使用してすべてのホップバイホップオプションを説明する方が効率的です。 cmsg_levelメンバーはIPPROTO_IPV6に設定され、cmsg_typeメンバーはIPV6_HOPOPTSに設定されます。オプションは通常、後で説明するinet6_option_init()、inet6_option_append()、およびinet6_option_alloc()関数を使用して構築されます。

Additional errors may be possible from sendmsg() if the specified option is in error.

指定されたオプションにエラーがある場合、sendmsg()から追加のエラーが発生する可能性があります。

6.3. Hop-by-Hop and Destination Options Processing
6.3. ホップバイホップおよび宛先オプションの処理

Building and parsing the Hop-by-Hop and Destination options is complicated for the reasons given earlier. We therefore define a set of functions to help the application. The function prototypes for these functions are all in the <netinet/in.h> header.

前述の理由により、ホップバイホップオプションと宛先オプションの構築と解析は複雑です。したがって、アプリケーションを支援する一連の関数を定義します。これらの関数の関数プロトタイプはすべて<netinet / in.h>ヘッダーにあります。

6.3.1. inet6_option_space
6.3.1. inet6_option_space

int inet6_option_space(int nbytes);

int inet6_option_space(int nbytes);

This function returns the number of bytes required to hold an option when it is stored as ancillary data, including the cmsghdr structure at the beginning, and any padding at the end (to make its size a multiple of 8 bytes). The argument is the size of the structure defining the option, which must include any pad bytes at the beginning (the value y in the alignment term "xn + y"), the type byte, the length byte, and the option data.

この関数は、最初のcmsghdr構造と最後のパディング(サイズを8バイトの倍数にするため)を含め、オプションが補助データとして格納されるときにオプションを保持するために必要なバイト数を返します。引数は、オプションを定義する構造体のサイズです。これには、先​​頭のパッドバイト(アライメント用語「xn + y」の値y)、タイプバイト、長さバイト、およびオプションデータが含まれている必要があります。

(Note: If multiple options are stored in a single ancillary data object, which is the recommended technique, this function overestimates the amount of space required by the size of N-1 cmsghdr structures, where N is the number of options to be stored in the object. This is of little consequence, since it is assumed that most Hop-by-Hop option headers and Destination option headers carry only one option (p. 33 of [RFC-1883]).)

(注:複数のオプションが単一の補助データオブジェクトに格納されている場合(これは推奨される手法です)、この関数はN-1 cmsghdr構造体のサイズが必要とするスペースの量を過大評価します。ここで、Nは格納されるオプションの数です。ほとんどのホップバイホップオプションヘッダーと宛先オプションヘッダーは1つのオプションのみを運ぶと想定されているため([RFC-1883]の33ページ))、これはほとんど重要ではありません。

6.3.2. inet6_option_init
6.3.2. inet6_option_init
       int inet6_option_init(void *bp, struct cmsghdr **cmsgp, int
       type);
        

This function is called once per ancillary data object that will contain either Hop-by-Hop or Destination options. It returns 0 on success or -1 on an error.

この関数は、ホップバイホップオプションまたは宛先オプションのいずれかを含む補助データオブジェクトごとに1回呼び出されます。成功した場合は0を返し、エラーの場合は-1を返します。

bp is a pointer to previously allocated space that will contain the ancillary data object. It must be large enough to contain all the individual options to be added by later calls to inet6_option_append() and inet6_option_alloc().

bpは、補助データオブジェクトを含む、以前に割り当てられた領域へのポインタです。後でinet6_option_append()およびinet6_option_alloc()を呼び出して追加される個々のオプションをすべて含めるのに十分な大きさである必要があります。

cmsgp is a pointer to a pointer to a cmsghdr structure. *cmsgp is initialized by this function to point to the cmsghdr structure constructed by this function in the buffer pointed to by bp.

cmsgpは、cmsghdr構造へのポインターへのポインターです。 * cmsgpは、この関数によって初期化され、bpが指すバッファー内のこの関数によって構築されるcmsghdr構造を指します。

type is either IPV6_HOPOPTS or IPV6_DSTOPTS. This type is stored in the cmsg_type member of the cmsghdr structure pointed to by *cmsgp.

タイプはIPV6_HOPOPTSまたはIPV6_DSTOPTSのいずれかです。このタイプは、* cmsgpが指すcmsghdr構造のcmsg_typeメンバーに保管されます。

6.3.3. inet6_option_append
6.3.3. inet6_option_append
       int inet6_option_append(struct cmsghdr *cmsg, const uint8_t *typep,
                               int multx, int plusy);
        

This function appends a Hop-by-Hop option or a Destination option into an ancillary data object that has been initialized by inet6_option_init(). This function returns 0 if it succeeds or -1 on an error.

この関数は、ホップバイホップオプションまたは宛先オプションを、inet6_option_init()によって初期化された補助データオブジェクトに追加します。この関数は、成功した場合は0を返し、エラーの場合は-1を返します。

cmsg is a pointer to the cmsghdr structure that must have been initialized by inet6_option_init().

cmsgは、inet6_option_init()によって初期化されている必要があるcmsghdr構造体へのポインターです。

typep is a pointer to the 8-bit option type. It is assumed that this field is immediately followed by the 8-bit option data length field, which is then followed immediately by the option data. The caller initializes these three fields (the type-length-value, or TLV) before calling this function.

typepは、8ビットオプションタイプへのポインタです。このフィールドの直後に8ビットのオプションデータ長フィールドが続き、その後にオプションデータが続くと想定されています。呼び出し元は、この関数を呼び出す前に、これら3つのフィールド(type-length-value、またはTLV)を初期化します。

The option type must have a value from 2 to 255, inclusive. (0 and 1 are reserved for the Pad1 and PadN options, respectively.)

オプションタイプには、2〜255の値が必要です。 (0および1は、それぞれPad1およびPadNオプション用に予約されています。)

The option data length must have a value between 0 and 255, inclusive, and is the length of the option data that follows.

オプションデータの長さは0から255までの値である必要があり、それに続くオプションデータの長さです。

multx is the value x in the alignment term "xn + y" described earlier. It must have a value of 1, 2, 4, or 8.

multxは、前述の「xn + y」アラインメント項の値xです。 1、2、4、または8の値が必要です。

plusy is the value y in the alignment term "xn + y" described earlier. It must have a value between 0 and 7, inclusive.

plusyは、前に説明したアライメント用語「xn + y」の値yです。 0から7までの値でなければなりません。

6.3.4. inet6_option_alloc
6.3.4. inet6_option_alloc
       uint8_t *inet6_option_alloc(struct cmsghdr *cmsg, int datalen,
                                    int multx, int plusy);
        

This function appends a Hop-by-Hop option or a Destination option into an ancillary data object that has been initialized by inet6_option_init(). This function returns a pointer to the 8-bit option type field that starts the option on success, or NULL on an error.

この関数は、ホップバイホップオプションまたは宛先オプションを、inet6_option_init()によって初期化された補助データオブジェクトに追加します。この関数は、成功時にオプションを開始する8ビットのオプションタイプフィールドへのポインタ、またはエラー時にNULLを返します。

The difference between this function and inet6_option_append() is that the latter copies the contents of a previously built option into the ancillary data object while the current function returns a pointer to the space in the data object where the option's TLV must then be built by the caller.

この関数とinet6_option_append()の違いは、後者は以前に構築されたオプションの内容を補助データオブジェクトにコピーするのに対し、現在の関数はデータオブジェクト内のスペースへのポインターを返し、そこでオプションのTLVが発信者。

cmsg is a pointer to the cmsghdr structure that must have been initialized by inet6_option_init().

cmsgは、inet6_option_init()によって初期化されている必要があるcmsghdr構造体へのポインターです。

datalen is the value of the option data length byte for this option. This value is required as an argument to allow the function to determine if padding must be appended at the end of the option. (The inet6_option_append() function does not need a data length argument since the option data length must already be stored by the caller.)

datalenは、このオプションのオプションデータ長バイトの値です。この値は、オプションの末尾にパディングを追加する必要があるかどうかを関数が判別できるようにするための引数として必要です。 (inet6_option_append()関数は、オプションのデータ長が呼び出し元によってすでに格納されている必要があるため、データ長引数は必要ありません。)

multx is the value x in the alignment term "xn + y" described earlier. It must have a value of 1, 2, 4, or 8.

multxは、前述の「xn + y」アラインメント項の値xです。 1、2、4、または8の値が必要です。

plusy is the value y in the alignment term "xn + y" described earlier. It must have a value between 0 and 7, inclusive.

plusyは、前に説明したアライメント用語「xn + y」の値yです。 0から7までの値でなければなりません。

6.3.5. inet6_option_next
6.3.5. inet6_option_next
       int inet6_option_next(const struct cmsghdr *cmsg, uint8_t
       **tptrp);
        

This function processes the next Hop-by-Hop option or Destination option in an ancillary data object. If another option remains to be processed, the return value of the function is 0 and *tptrp points to the 8-bit option type field (which is followed by the 8-bit option data length, followed by the option data). If no more options remain to be processed, the return value is -1 and *tptrp is NULL. If an error occurs, the return value is -1 and *tptrp is not NULL.

この関数は、補助データオブジェクトの次のホップバイホップオプションまたは宛先オプションを処理します。別のオプションの処理が残っている場合、関数の戻り値は0で、* tptrpは8ビットのオプションタイプフィールド(8ビットのオプションデータ長、オプションデータが続く)を指します。処理するオプションがなくなると、戻り値は-1になり、* tptrpはNULLになります。エラーが発生した場合、戻り値は-1で、* tptrpはNULLではありません。

cmsg is a pointer to cmsghdr structure of which cmsg_level equals IPPROTO_IPV6 and cmsg_type equals either IPV6_HOPOPTS or IPV6_DSTOPTS.

cmsgは、cmsg_levelがIPPROTO_IPV6に等しく、cmsg_typeがIPV6_HOPOPTSまたはIPV6_DSTOPTSに等しいcmsghdr構造体へのポインターです。

tptrp is a pointer to a pointer to an 8-bit byte and *tptrp is used by the function to remember its place in the ancillary data object each time the function is called. The first time this function is called for a given ancillary data object, *tptrp must be set to NULL.

tptrpは、8ビットバイトへのポインターへのポインターであり、* tptrpは、関数が呼び出されるたびに補助データオブジェクト内のその位置を記憶するために関数によって使用されます。この関数が特定の補助データオブジェクトに対して初めて呼び出されるときは、* tptrpをNULLに設定する必要があります。

Each time this function returns success, *tptrp points to the 8-bit option type field for the next option to be processed.

この関数が成功を返すたびに、* tptrpは次に処理されるオプションの8ビットオプションタイプフィールドを指します。

6.3.6. inet6_option_find
6.3.6. inet6_option_find
       int inet6_option_find(const struct cmsghdr *cmsg, uint8_t *tptrp,
                             int type);
        

This function is similar to the previously described inet6_option_next() function, except this function lets the caller specify the option type to be searched for, instead of always returning the next option in the ancillary data object. cmsg is a pointer to cmsghdr structure of which cmsg_level equals IPPROTO_IPV6 and cmsg_type equals either IPV6_HOPOPTS or IPV6_DSTOPTS.

この関数は、前述のinet6_option_next()関数と似ていますが、この関数は、呼び出し側が常に補助データオブジェクトの次のオプションを返すのではなく、検索するオプションタイプを指定できる点が異なります。 cmsgは、cmsg_levelがIPPROTO_IPV6に等しく、cmsg_typeがIPV6_HOPOPTSまたはIPV6_DSTOPTSに等しいcmsghdr構造体へのポインターです。

tptrp is a pointer to a pointer to an 8-bit byte and *tptrp is used by the function to remember its place in the ancillary data object each time the function is called. The first time this function is called for a given ancillary data object, *tptrp must be set to NULL.

tptrpは、8ビットバイトへのポインターへのポインターであり、* tptrpは、関数が呼び出されるたびに補助データオブジェクト内のその位置を記憶するために関数によって使用されます。この関数が特定の補助データオブジェクトに対して初めて呼び出されるときは、* tptrpをNULLに設定する必要があります。

This function starts searching for an option of the specified type beginning after the value of *tptrp. If an option of the specified type is located, this function returns 0 and *tptrp points to the 8- bit option type field for the option of the specified type. If an option of the specified type is not located, the return value is -1 and *tptrp is NULL. If an error occurs, the return value is -1 and *tptrp is not NULL.

この関数は、* tptrpの値の後から、指定されたタイプのオプションの検索を開始します。指定されたタイプのオプションが見つかった場合、この関数は0を返し、* tptrpは指定されたタイプのオプションの8ビットオプションタイプフィールドを指します。指定されたタイプのオプションが見つからない場合、戻り値は-1で、* tptrpはNULLです。エラーが発生した場合、戻り値は-1で、* tptrpはNULLではありません。

6.3.7. Options Examples
6.3.7. オプションの例

We now provide an example that builds two Hop-by-Hop options. First we define two options, called X and Y, taken from the example in Appendix A of [RFC-1883]. We assume that all options will have structure definitions similar to what is shown below.

次に、2つのホップバイホップオプションを構築する例を示します。最初に、[RFC-1883]の付録Aの例から取ったXとYという2つのオプションを定義します。すべてのオプションには、次に示すような構造定義があると想定しています。

        /* option X and option Y are defined in [RFC-1883], pp. 33-34 */
#define IP6_X_OPT_TYPE       X   /* replace X with assigned value */
#define IP6_X_OPT_LEN       12
#define IP6_X_OPT_MULTX      8   /* 8n + 2 alignment */
#define IP6_X_OPT_OFFSETY    2
        
struct ip6_X_opt {
  uint8_t   ip6_X_opt_pad[IP6_X_OPT_OFFSETY];
  uint8_t   ip6_X_opt_type;
  uint8_t   ip6_X_opt_len;
  uint32_t  ip6_X_opt_val1;
  uint64_t  ip6_X_opt_val2;
};
        
#define IP6_Y_OPT_TYPE       Y   /* replace Y with assigned value */
#define IP6_Y_OPT_LEN        7
#define IP6_Y_OPT_MULTX      4   /* 4n + 3 alignment */
#define IP6_Y_OPT_OFFSETY    3
        
struct ip6_Y_opt {
  uint8_t   ip6_Y_opt_pad[IP6_Y_OPT_OFFSETY];
  uint8_t   ip6_Y_opt_type;
  uint8_t   ip6_Y_opt_len;
  uint8_t   ip6_Y_opt_val1;
  uint16_t  ip6_Y_opt_val2;
  uint32_t  ip6_Y_opt_val3;
};
        

We now show the code fragment to build one ancillary data object containing both options.

次に、両方のオプションを含む1つの補助データオブジェクトを作成するコードフラグメントを示します。

struct msghdr  msg;
struct cmsghdr  *cmsgptr;
struct ip6_X_opt  optX;
struct ip6_Y_opt  optY;
        
msg.msg_control = malloc(inet6_option_space(sizeof(optX) +
                                            sizeof(optY)));
        

inet6_option_init(msg.msg_control, &cmsgptr, IPV6_HOPOPTS);

inet6_option_init(msg.msg_control、&cmsgptr、IPV6_HOPOPTS);

optX.ip6_X_opt_type = IP6_X_OPT_TYPE;
optX.ip6_X_opt_len  = IP6_X_OPT_LEN;
optX.ip6_X_opt_val1 = <32-bit value>;
optX.ip6_X_opt_val2 = <64-bit value>;
inet6_option_append(cmsgptr, &optX.ip6_X_opt_type,
                    IP6_X_OPT_MULTX, IP6_X_OPT_OFFSETY);
        
optY.ip6_Y_opt_type = IP6_Y_OPT_TYPE;
optY.ip6_Y_opt_len  = IP6_Y_OPT_LEN;
optY.ip6_Y_opt_val1 = <8-bit value>;
optY.ip6_Y_opt_val2 = <16-bit value>;
optY.ip6_Y_opt_val3 = <32-bit value>;
inet6_option_append(cmsgptr, &optY.ip6_Y_opt_type,
                    IP6_Y_OPT_MULTX, IP6_Y_OPT_OFFSETY);
        
msg.msg_controllen = cmsgptr->cmsg_len;
        

The call to inet6_option_init() builds the cmsghdr structure in the control buffer.

inet6_option_init()を呼び出すと、制御バッファーにcmsghdr構造が構築されます。

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_len = CMSG_LEN(0) = 12                             |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_level = IPPROTO_IPV6                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_type = IPV6_HOPOPTS                                |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        

Here we assume a 32-bit architecture where sizeof(struct cmsghdr) equals 12, with a desired alignment of 4-byte boundaries (that is, the ALIGN() macro shown in the sample implementations of the CMSG_xxx() macros rounds up to a multiple of 4).

ここでは、sizeof(struct cmsghdr)が12に等しい32ビットアーキテクチャーを想定しています。4バイト境界の望ましい配置(つまり、CMSG_xxx()マクロのサンプル実装に示されているALIGN()マクロは、 4の倍数)。

The first call to inet6_option_append() appends the X option. Since this is the first option in the ancillary data object, 2 bytes are allocated for the Next Header byte and for the Hdr Ext Len byte. The former will be set by the kernel, depending on the type of header that follows this header, and the latter byte is set to 1. These 2 bytes form the 2 bytes of padding (IP6_X_OPT_OFFSETY) required at the beginning of this option.

inet6_option_append()への最初の呼び出しは、Xオプションを追加します。これは補助データオブジェクトの最初のオプションなので、次のヘッダーバイトとHdr Ext Lenバイトに2バイトが割り当てられます。前者は、このヘッダーに続くヘッダーのタイプに応じてカーネルによって設定され、後者のバイトは1に設定されます。これらの2バイトは、このオプションの最初に必要な2バイトのパディング(IP6_X_OPT_OFFSETY)を形成します。

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_len = 28                                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_level = IPPROTO_IPV6                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_type = IPV6_HOPOPTS                                |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |  Next Header  | Hdr Ext Len=1 | Option Type=X |Opt Data Len=12|
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                         4-octet field                         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               |
     +                         8-octet field                         +
     |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        

The cmsg_len member of the cmsghdr structure is incremented by 16, the size of the option.

cmsghdr構造体のcmsg_lenメンバーは、オプションのサイズである16ずつ増加します。

The next call to inet6_option_append() appends the Y option to the ancillary data object.

次にinet6_option_append()を呼び出すと、Yオプションが補助データオブジェクトに追加されます。

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_len = 44                                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_level = IPPROTO_IPV6                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_type = IPV6_HOPOPTS                                |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |  Next Header  | Hdr Ext Len=3 | Option Type=X |Opt Data Len=12|
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                         4-octet field                         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               |
     +                         8-octet field                         +
     |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     | PadN Option=1 |Opt Data Len=1 |       0       | Option Type=Y |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |Opt Data Len=7 | 1-octet field |         2-octet field         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                         4-octet field                         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     | PadN Option=1 |Opt Data Len=2 |       0       |       0       |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        

16 bytes are appended by this function, so cmsg_len becomes 44. The inet6_option_append() function notices that the appended data requires 4 bytes of padding at the end, to make the size of the ancillary data object a multiple of 8, and appends the PadN option before returning. The Hdr Ext Len byte is incremented by 2 to become 3.

この関数によって16バイトが追加されるため、cmsg_lenは44になります。inet6_option_append()関数は、追加データの末尾に4バイトのパディングが必要であることを認識し、補助データオブジェクトのサイズを8の倍数にして、PadNを追加します。戻る前のオプション。 Hdr Ext Lenバイトは2ずつ増加して3になります。

Alternately, the application could build two ancillary data objects, one per option, although this will probably be less efficient than combining the two options into a single ancillary data object (as just shown). The kernel must combine these into a single Hop-by-Hop extension header in the final IPv6 packet.

別の方法として、アプリケーションは2つの補助データオブジェクトをオプションごとに1つずつ構築することもできますが、これはおそらく2つのオプションを1つの補助データオブジェクトに結合するよりも効率的ではありません(上記のとおり)。カーネルはこれらを結合して、最終的なIPv6パケットで単一のホップバイホップ拡張ヘッダーにする必要があります。

       struct msghdr  msg;
       struct cmsghdr  *cmsgptr;
       struct ip6_X_opt  optX;
       struct ip6_Y_opt  optY;
        
       msg.msg_control = malloc(inet6_option_space(sizeof(optX)) +
                                inet6_option_space(sizeof(optY)));
        

inet6_option_init(msg.msg_control, &cmsgptr, IPPROTO_HOPOPTS);

inet6_option_init(msg.msg_control、&cmsgptr、IPPROTO_HOPOPTS);

optX.ip6_X_opt_type = IP6_X_OPT_TYPE;

optX.ip6_X_opt_type = IP6_X_OPT_TYPE;

       optX.ip6_X_opt_len  = IP6_X_OPT_LEN;
       optX.ip6_X_opt_val1 = <32-bit value>;
       optX.ip6_X_opt_val2 = <64-bit value>;
       inet6_option_append(cmsgptr, &optX.ip6_X_opt_type,
                           IP6_X_OPT_MULTX, IP6_X_OPT_OFFSETY);
       msg.msg_controllen = CMSG_SPACE(sizeof(optX));
        
       inet6_option_init((u_char *)msg.msg_control + msg.msg_controllen,
                         &cmsgptr, IPPROTO_HOPOPTS);
        
       optY.ip6_Y_opt_type = IP6_Y_OPT_TYPE;
       optY.ip6_Y_opt_len  = IP6_Y_OPT_LEN;
       optY.ip6_Y_opt_val1 = <8-bit value>;
       optY.ip6_Y_opt_val2 = <16-bit value>;
       optY.ip6_Y_opt_val3 = <32-bit value>;
       inet6_option_append(cmsgptr, &optY.ip6_Y_opt_type,
                           IP6_Y_OPT_MULTX, IP6_Y_OPT_OFFSETY);
       msg.msg_controllen += cmsgptr->cmsg_len;
        

Each call to inet6_option_init() builds a new cmsghdr structure, and the final result looks like the following:

inet6_option_init()を呼び出すたびに、新しいcmsghdr構造が作成され、最終結果は次のようになります。

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_len = 28                                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_level = IPPROTO_IPV6                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_type = IPV6_HOPOPTS                                |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |  Next Header  | Hdr Ext Len=1 | Option Type=X |Opt Data Len=12|
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                         4-octet field                         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               |
     +                         8-octet field                         +
     |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_len = 28                                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_level = IPPROTO_IPV6                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_type = IPV6_HOPOPTS                                |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |  Next Header  | Hdr Ext Len=1 | Pad1 Option=0 | Option Type=Y |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |Opt Data Len=7 | 1-octet field |         2-octet field         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                         4-octet field                         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     | PadN Option=1 |Opt Data Len=2 |       0       |       0       |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        

When the kernel combines these two options into a single Hop-by-Hop extension header, the first 3 bytes of the second ancillary data object (the Next Header byte, the Hdr Ext Len byte, and the Pad1 option) will be combined into a PadN option occupying 3 bytes.

カーネルがこれらの2つのオプションを単一のホップバイホップ拡張ヘッダーに組み合わせると、2番目の補助データオブジェクトの最初の3バイト(次のヘッダーバイト、Hdr Ext Lenバイト、およびPad1オプション)は、 3バイトを占めるPadNオプション。

The following code fragment is a redo of the first example shown (building two options in a single ancillary data object) but this time we use inet6_option_alloc().

次のコードフラグメントは、最初の例(1つの補助データオブジェクトで2つのオプションを構築する)のやり直しですが、今回はinet6_option_alloc()を使用します。

uint8_t  *typep;
struct msghdr  msg;
struct cmsghdr  *cmsgptr;
struct ip6_X_opt  *optXp;  /* now a pointer, not a struct */
struct ip6_Y_opt  *optYp;  /* now a pointer, not a struct */
        
msg.msg_control = malloc(inet6_option_space(sizeof(*optXp) +
                                            sizeof(*optYp)));
        

inet6_option_init(msg.msg_control, &cmsgptr, IPV6_HOPOPTS);

inet6_option_init(msg.msg_control、&cmsgptr、IPV6_HOPOPTS);

typep = inet6_option_alloc(cmsgptr, IP6_X_OPT_LEN,
                           IP6_X_OPT_MULTX, IP6_X_OPT_OFFSETY);
optXp = (struct ip6_X_opt *) (typep - IP6_X_OPT_OFFSETY);
optXp->ip6_X_opt_type = IP6_X_OPT_TYPE;
optXp->ip6_X_opt_len  = IP6_X_OPT_LEN;
optXp->ip6_X_opt_val1 = <32-bit value>;
optXp->ip6_X_opt_val2 = <64-bit value>;
        
typep = inet6_option_alloc(cmsgptr, IP6_Y_OPT_LEN,
                           IP6_Y_OPT_MULTX, IP6_Y_OPT_OFFSETY);
optYp = (struct ip6_Y_opt *) (typep - IP6_Y_OPT_OFFSETY);
optYp->ip6_Y_opt_type = IP6_Y_OPT_TYPE;
optYp->ip6_Y_opt_len  = IP6_Y_OPT_LEN;
optYp->ip6_Y_opt_val1 = <8-bit value>;
optYp->ip6_Y_opt_val2 = <16-bit value>;
optYp->ip6_Y_opt_val3 = <32-bit value>;
        
msg.msg_controllen = cmsgptr->cmsg_len;
        

Notice that inet6_option_alloc() returns a pointer to the 8-bit option type field. If the program wants a pointer to an option structure that includes the padding at the front (as shown in our definitions of the ip6_X_opt and ip6_Y_opt structures), the y-offset at the beginning of the structure must be subtracted from the returned pointer.

inet6_option_alloc()は、8ビットオプションタイプフィールドへのポインタを返すことに注意してください。 (ip6_X_optおよびip6_Y_opt構造体の定義に示されているように)プログラムが先頭にパディングを含むオプション構造体へのポインターを必要とする場合、構造体の先頭のyオフセットを、返されたポインターから減算する必要があります。

The following code fragment shows the processing of Hop-by-Hop options using the inet6_option_next() function.

次のコードフラグメントは、inet6_option_next()関数を使用したホップバイホップオプションの処理を示しています。

    struct msghdr   msg;
    struct cmsghdr  *cmsgptr;
        
    /* fill in msg */
        
    /* call recvmsg() */
        
    for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
         cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
        if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
            cmsgptr->cmsg_type == IPV6_HOPOPTS) {
        
            uint8_t  *tptr = NULL;
        
            while (inet6_option_next(cmsgptr, &tptr) == 0) {
                if (*tptr == IP6_X_OPT_TYPE) {
                    struct ip6_X_opt  *optXp;
        
                    optXp = (struct ip6_X_opt *) (tptr - IP6_X_OPT_OFFSETY);
                    <do whatever with> optXp->ip6_X_opt_val1;
                    <do whatever with> optXp->ip6_X_opt_val2;
        
                } else if (*tptr == IP6_Y_OPT_TYPE) {
                    struct ip6_Y_opt  *optYp;
        
                    optYp = (struct ip6_Y_opt *) (tptr - IP6_Y_OPT_OFFSETY);
                    <do whatever with> optYp->ip6_Y_opt_val1;
                    <do whatever with> optYp->ip6_Y_opt_val2;
                    <do whatever with> optYp->ip6_Y_opt_val3;
                }
            }
            if (tptr != NULL)
                <error encountered by inet6_option_next()>;
        }
    }
        
7. Destination Options
7. 宛先オプション

A variable number of Destination options can appear in one or more Destination option headers. As defined in [RFC-1883], a Destination options header appearing before a Routing header is processed by the first destination plus any subsequent destinations specified in the Routing header, while a Destination options header appearing after a Routing header is processed only by the final destination. As with the Hop-by-Hop options, each option in a Destination options header is TLV-encoded with a type, length, and value.

可変数の宛先オプションは、1つ以上の宛先オプションヘッダーに表示できます。 [RFC-1883]で定義されているように、ルーティングヘッダーが最初の宛先とルーティングヘッダーで指定された後続の宛先によって処理される前に表示される宛先オプションヘッダー、ルーティングヘッダーが最後によってのみ処理された後に表示される宛先オプションヘッダー先。ホップバイホップオプションと同様に、宛先オプションヘッダーの各オプションは、タイプ、長さ、および値でTLVエンコードされます。

Today no Destination options are defined for IPv6 [RFC-1883], although proposals exist to use Destination options with mobility and anycasting.

今日、IPv6 [RFC-1883]には宛先オプションが定義されていませんが、モビリティとエニーキャスティングで宛先オプションを使用する提案が存在します。

7.1. Receiving Destination Options
7.1. 受信先オプション

To receive Destination options the application must enable the IPV6_DSTOPTS socket option:

宛先オプションを受信するには、アプリケーションでIPV6_DSTOPTSソケットオプションを有効にする必要があります。

       int  on = 1;
       setsockopt(fd, IPPROTO_IPV6, IPV6_DSTOPTS, &on, sizeof(on));
        

All the Destination options appearing before a Routing header are returned as one ancillary data object described by a cmsghdr structure and all the Destination options appearing after a Routing header are returned as another ancillary data object described by a cmsghdr structure. For these ancillary data objects, the cmsg_level member will be IPPROTO_IPV6 and the cmsg_type member will be IPV6_HOPOPTS. These options are then processed by calling the inet6_option_next() and inet6_option_find() functions.

ルーティングヘッダーの前に表示されるすべての宛先オプションは、cmsghdr構造体によって記述される1つの補助データオブジェクトとして返され、ルーティングヘッダーの後に表示されるすべての宛先オプションは、cmsghdr構造体によって記述される別の補助データオブジェクトとして返されます。これらの補助データオブジェクトの場合、cmsg_levelメンバーはIPPROTO_IPV6になり、cmsg_typeメンバーはIPV6_HOPOPTSになります。これらのオプションは、inet6_option_next()およびinet6_option_find()関数を呼び出して処理されます。

7.2. Sending Destination Options
7.2. 送信先オプション

To send one or more Destination options, the application just specifies them as ancillary data in a call to sendmsg(). No socket option need be set.

1つ以上の宛先オプションを送信するために、アプリケーションはsendmsg()の呼び出しでそれらを補助データとして指定するだけです。ソケットオプションを設定する必要はありません。

As described earlier, one set of Destination options can appear before a Routing header, and one set can appear after a Routing header. Each set can consist of one or more options.

前述のように、宛先オプションの1つのセットはルーティングヘッダーの前に表示でき、1つのセットはルーティングヘッダーの後に表示できます。各セットは、1つ以上のオプションで構成できます。

Normally all the Destination options in a set are specified by a single ancillary data object, since each option is itself TLV-encoded. Multiple ancillary data objects, each containing one or more Destination options, can also be specified, in which case the kernel will combine all the Destination options in the set into a single Destination extension header. But it should be more efficient to use a single ancillary data object to describe all the Destination options in a set. The cmsg_level member is set to IPPROTO_IPV6 and the cmsg_type member is set to IPV6_DSTOPTS. The option is normally constructed using the inet6_option_init(), inet6_option_append(), and inet6_option_alloc() functions.

各オプション自体がTLVエンコードされているため、通常、セット内のすべての宛先オプションは単一の補助データオブジェクトによって指定されます。それぞれが1つ以上の宛先オプションを含む複数の補助データオブジェクトを指定することもできます。その場合、カーネルはセット内のすべての宛先オプションを単一の宛先拡張ヘッダーに結合します。ただし、1つの補助データオブジェクトを使用して、セット内のすべての宛先オプションを記述する方が効率的です。 cmsg_levelメンバーはIPPROTO_IPV6に設定され、cmsg_typeメンバーはIPV6_DSTOPTSに設定されます。オプションは通常、inet6_option_init()、inet6_option_append()、およびinet6_option_alloc()関数を使用して構築されます。

Additional errors may be possible from sendmsg() if the specified option is in error.

指定されたオプションにエラーがある場合、sendmsg()から追加のエラーが発生する可能性があります。

8. Routing Header Option
8. ルーティングヘッダーオプション

Source routing in IPv6 is accomplished by specifying a Routing header as an extension header. There can be different types of Routing headers, but IPv6 currently defines only the Type 0 Routing header [RFC-1883]. This type supports up to 23 intermediate nodes. With this maximum number of intermediate nodes, a source, and a destination, there are 24 hops, each of which is defined as a strict or loose hop.

IPv6のソースルーティングは、ルーティングヘッダーを拡張ヘッダーとして指定することで実現されます。さまざまな種類のルーティングヘッダーが存在する可能性がありますが、IPv6では現在、タイプ0のルーティングヘッダーのみを定義しています[RFC-1883]。このタイプは、最大23の中間ノードをサポートします。この最大数の中間ノード、送信元、および宛先では、24のホップがあり、それぞれが厳密なホップまたはルーズホップとして定義されます。

Source routing with IPv4 sockets API (the IP_OPTIONS socket option) requires the application to build the source route in the format that appears as the IPv4 header option, requiring intimate knowledge of the IPv4 options format. This IPv6 API, however, defines eight functions that the application calls to build and examine a Routing header. Four functions build a Routing header:

IPv4ソケットAPIを使用したソースルーティング(IP_OPTIONSソケットオプション)では、アプリケーションがIPv4ヘッダーオプションとして表示される形式でソースルートを構築する必要があり、IPv4オプション形式の詳細な知識が必要です。ただし、このIPv6 APIは、アプリケーションがルーティングヘッダーを作成および検査するために呼び出す8つの関数を定義しています。 4つの関数がルーティングヘッダーを作成します。

   inet6_rthdr_space()    - return #bytes required for ancillary data
   inet6_rthdr_init()     - initialize ancillary data for Routing header
   inet6_rthdr_add()      - add IPv6 address & flags to Routing header
   inet6_rthdr_lasthop()  - specify the flags for the final hop
        

Four functions deal with a returned Routing header:

返されたルーティングヘッダーを処理する4つの関数:

    inet6_rthdr_reverse()  - reverse a Routing header
    inet6_rthdr_segments() - return #segments in a Routing header
    inet6_rthdr_getaddr()  - fetch one address from a Routing header
    inet6_rthdr_getflags() - fetch one flag from a Routing header
        

The function prototypes for these functions are all in the <netinet/in.h> header.

これらの関数の関数プロトタイプはすべて<netinet / in.h>ヘッダーにあります。

To receive a Routing header the application must enable the IPV6_RTHDR socket option:

ルーティングヘッダーを受信するには、アプリケーションでIPV6_RTHDRソケットオプションを有効にする必要があります。

       int  on = 1;
       setsockopt(fd, IPPROTO_IPV6, IPV6_RTHDR, &on, sizeof(on));
        

To send a Routing header the application just specifies it as ancillary data in a call to sendmsg().

ルーティングヘッダーを送信するには、アプリケーションはsendmsg()の呼び出しでそれを補助データとして指定するだけです。

A Routing header is passed between the application and the kernel as an ancillary data object. The cmsg_level member has a value of IPPROTO_IPV6 and the cmsg_type member has a value of IPV6_RTHDR. The contents of the cmsg_data[] member is implementation dependent and should not be accessed directly by the application, but should be accessed using the eight functions that we are about to describe.

ルーティングヘッダーは、アプリケーションとカーネルの間で補助データオブジェクトとして渡されます。 cmsg_levelメンバーの値はIPPROTO_IPV6で、cmsg_typeメンバーの値はIPV6_RTHDRです。 cmsg_data []メンバーの内容は実装に依存するため、アプリケーションから直接アクセスする必要はありませんが、これから説明する8つの関数を使用してアクセスする必要があります。

The following constants are defined in the <netinet/in.h> header:

次の定数は<netinet / in.h>ヘッダーで定義されています。

    #define IPV6_RTHDR_LOOSE     0 /* this hop need not be a neighbor */
    #define IPV6_RTHDR_STRICT    1 /* this hop must be a neighbor */
        
    #define IPV6_RTHDR_TYPE_0    0 /* IPv6 Routing header type 0 */
        

When a Routing header is specified, the destination address specified for connect(), sendto(), or sendmsg() is the final destination address of the datagram. The Routing header then contains the addresses of all the intermediate nodes.

ルーティングヘッダーが指定されている場合、connect()、sendto()、またはsendmsg()に指定された宛先アドレスは、データグラムの最終的な宛先アドレスです。ルーティングヘッダーには、すべての中間ノードのアドレスが含まれます。

8.1. inet6_rthdr_space
8.1. inet6_rthdr_space

size_t inet6_rthdr_space(int type, int segments);

size_t inet6_rthdr_space(intタイプ、intセグメント);

This function returns the number of bytes required to hold a Routing header of the specified type containing the specified number of segments (addresses). For an IPv6 Type 0 Routing header, the number of segments must be between 1 and 23, inclusive. The return value includes the size of the cmsghdr structure that precedes the Routing header, and any required padding.

この関数は、指定された数のセグメント(アドレス)を含む指定されたタイプのルーティングヘッダーを保持するために必要なバイト数を返します。 IPv6タイプ0ルーティングヘッダーの場合、セグメントの数は1〜23である必要があります。戻り値には、ルーティングヘッダーの前にあるcmsghdr構造体のサイズ、および必要なパディングが含まれます。

If the return value is 0, then either the type of the Routing header is not supported by this implementation or the number of segments is invalid for this type of Routing header.

戻り値が0の場合、ルーティングヘッダーのタイプがこの実装でサポートされていないか、セグメントの数がこのタイプのルーティングヘッダーに対して無効です。

(Note: This function returns the size but does not allocate the space required for the ancillary data. This allows an application to allocate a larger buffer, if other ancillary data objects are desired, since all the ancillary data objects must be specified to sendmsg() as a single msg_control buffer.)

(注:この関数はサイズを返しますが、補助データに必要なスペースは割り当てません。他の補助データオブジェクトが必要な場合は、アプリケーションがより大きなバッファーを割り当てることができます。すべての補助データオブジェクトをsendmsg( )単一のmsg_controlバッファとして。)

8.2. inet6_rthdr_init
8.2. inet6_rthdr_init
       struct cmsghdr *inet6_rthdr_init(void *bp, int type);
        

This function initializes the buffer pointed to by bp to contain a cmsghdr structure followed by a Routing header of the specified type. The cmsg_len member of the cmsghdr structure is initialized to the size of the structure plus the amount of space required by the Routing header. The cmsg_level and cmsg_type members are also initialized as required.

この関数は、bpが指すバッファーを初期化して、cmsghdr構造に続いて指定されたタイプのルーティングヘッダーを含めます。 cmsghdr構造体のcmsg_lenメンバーは、構造体のサイズにルーティングヘッダーで必要なスペースを加えたサイズに初期化されます。 cmsg_levelおよびcmsg_typeメンバーも必要に応じて初期化されます。

The caller must allocate the buffer and its size can be determined by calling inet6_rthdr_space().

呼び出し元はバッファを割り当てる必要があり、そのサイズはinet6_rthdr_space()を呼び出すことによって決定できます。

Upon success the return value is the pointer to the cmsghdr structure, and this is then used as the first argument to the next two functions. Upon an error the return value is NULL.

成功した場合、戻り値はcmsghdr構造体へのポインターであり、これは次の2つの関数の最初の引数として使用されます。エラーの場合、戻り値はNULLです。

8.3. inet6_rthdr_add
8.3. inet6_rthdr_add
    int inet6_rthdr_add(struct cmsghdr *cmsg,
                        const struct in6_addr *addr, unsigned int flags);
        

This function adds the address pointed to by addr to the end of the Routing header being constructed and sets the type of this hop to the value of flags. For an IPv6 Type 0 Routing header, flags must be either IPV6_RTHDR_LOOSE or IPV6_RTHDR_STRICT.

この関数は、構築中のルーティングヘッダーの末尾にaddrが指すアドレスを追加し、このホップのタイプをフラグの値に設定します。 IPv6タイプ0ルーティングヘッダーの場合、フラグはIPV6_RTHDR_LOOSEまたはIPV6_RTHDR_STRICTでなければなりません。

If successful, the cmsg_len member of the cmsghdr structure is updated to account for the new address in the Routing header and the return value of the function is 0. Upon an error the return value of the function is -1.

成功した場合、cmsghdr構造体のcmsg_lenメンバーは、ルーティングヘッダーの新しいアドレスを考慮して更新され、関数の戻り値は0です。エラーの場合、関数の戻り値は-1です。

8.4. inet6_rthdr_lasthop
8.4. inet6_rthdr_lasthop

int inet6_rthdr_lasthop(struct cmsghdr *cmsg, unsigned int flags);

int inet6_rthdr_lasthop(struct cmsghdr * cmsg、unsigned int flags);

This function specifies the Strict/Loose flag for the final hop of a Routing header. For an IPv6 Type 0 Routing header, flags must be either IPV6_RTHDR_LOOSE or IPV6_RTHDR_STRICT.

この関数は、ルーティングヘッダーの最終ホップのStrict / Looseフラグを指定します。 IPv6タイプ0ルーティングヘッダーの場合、フラグはIPV6_RTHDR_LOOSEまたはIPV6_RTHDR_STRICTでなければなりません。

The return value of the function is 0 upon success, or -1 upon an error.

関数の戻り値は、成功した場合は0、エラーの場合は-1です。

Notice that a Routing header specifying N intermediate nodes requires N+1 Strict/Loose flags. This requires N calls to inet6_rthdr_add() followed by one call to inet6_rthdr_lasthop().

N個の中間ノードを指定するRoutingヘッダーには、N + 1個のStrict / Looseフラグが必要です。これには、inet6_rthdr_add()へのN回の呼び出しの後に、inet6_rthdr_lasthop()への1回の呼び出しが必要です。

8.5. inet6_rthdr_reverse
8.5. inet6_rthdr_reverse
    int inet6_rthdr_reverse(const struct cmsghdr *in, struct cmsghdr *out);
        

This function takes a Routing header that was received as ancillary data (pointed to by the first argument) and writes a new Routing header that sends datagrams along the reverse of that route. Both arguments are allowed to point to the same buffer (that is, the reversal can occur in place).

この関数は、補助データとして受信されたルーティングヘッダー(最初の引数が指す)を受け取り、そのルートの逆に沿ってデータグラムを送信する新しいルーティングヘッダーを書き込みます。どちらの引数も同じバッファーを指すことができます(つまり、逆に配置できます)。

The return value of the function is 0 on success, or -1 upon an error.

関数の戻り値は、成功した場合は0、エラーの場合は-1です。

8.6. inet6_rthdr_segments
8.6. inet6_rthdr_segments
       int inet6_rthdr_segments(const struct cmsghdr *cmsg);
        

This function returns the number of segments (addresses) contained in the Routing header described by cmsg. On success the return value is between 1 and 23, inclusive. The return value of the function is -1 upon an error.

この関数は、cmsgによって記述されるルーティングヘッダーに含まれるセグメント(アドレス)の数を返します。成功した場合、戻り値は1〜23です。エラーの場合、関数の戻り値は-1です。

8.7. inet6_rthdr_getaddr
8.7. inet6_rthdr_getaddr
    struct in6_addr *inet6_rthdr_getaddr(struct cmsghdr *cmsg, int
    index);
        

This function returns a pointer to the IPv6 address specified by index (which must have a value between 1 and the value returned by inet6_rthdr_segments()) in the Routing header described by cmsg. An application should first call inet6_rthdr_segments() to obtain the number of segments in the Routing header.

この関数は、cmsgによって記述されるルーティングヘッダー内のインデックス(1とinet6_rthdr_segments()によって返される値の間にある必要があります)で指定されたIPv6アドレスへのポインターを返します。アプリケーションは最初にinet6_rthdr_segments()を呼び出して、ルーティングヘッダーのセグメント数を取得する必要があります。

Upon an error the return value of the function is NULL.

エラーが発生した場合、関数の戻り値はNULLです。

8.8. inet6_rthdr_getflags
8.8. inet6_rthdr_getflags
       int inet6_rthdr_getflags(const struct cmsghdr *cmsg, int index);
        

This function returns the flags value specified by index (which must have a value between 0 and the value returned by inet6_rthdr_segments()) in the Routing header described by cmsg. For an IPv6 Type 0 Routing header the return value will be either IPV6_RTHDR_LOOSE or IPV6_RTHDR_STRICT.

この関数は、cmsgによって記述されるルーティングヘッダー内のインデックスで指定されたフラグ値(0とinet6_rthdr_segments()によって返される値を持たなければならない)を返します。 IPv6タイプ0ルーティングヘッダーの場合、戻り値はIPV6_RTHDR_LOOSEまたはIPV6_RTHDR_STRICTになります。

Upon an error the return value of the function is -1.

エラーが発生した場合、関数の戻り値は-1です。

(Note: Addresses are indexed starting at 1, and flags starting at 0, to maintain consistency with the terminology and figures in [RFC-1883].)

(注:[RFC-1883]の用語と図との一貫性を維持するために、アドレスは1から始まり、フラグは0から始まります。)

8.9. Routing Header Example
8.9. ルーティングヘッダーの例

As an example of these Routing header functions, we go through the function calls for the example on p. 18 of [RFC-1883]. The source is S, the destination is D, and the three intermediate nodes are I1, I2, and I3. f0, f1, f2, and f3 are the Strict/Loose flags for each hop.

これらのルーティングヘッダー関数の例として、pの例の関数呼び出しについて説明します。 [RFC-1883]の18。送信元はS、宛先はD、3つの中間ノードはI1、I2、I3です。 f0、f1、f2、およびf3は、各ホップのStrict / Looseフラグです。

                   f0        f1        f2        f3
               S -----> I1 -----> I2 -----> I3 -----> D
        
       src:    *    S         S         S         S   S
       dst:    D   I1        I2        I3         D   D
       A[1]:  I1   I2        I1        I1        I1  I1
       A[2]:  I2   I3        I3        I2        I2  I2
       A[3]:  I3    D         D         D        I3  I3
       #seg:   3    3         2         1         0   3
        

check: f0 f1 f2 f3

チェック:f0 f1 f2 f3

src and dst are the source and destination IPv6 addresses in the IPv6 header. A[1], A[2], and A[3] are the three addresses in the Routing header. #seg is the Segments Left field in the Routing header. check indicates which bit of the Strict/Loose Bit Map (0 through 3, specified as f0 through f3) that node checks.

srcおよびdstは、IPv6ヘッダーの送信元および宛先IPv6アドレスです。 A [1]、A [2]、およびA [3]は、ルーティングヘッダーの3つのアドレスです。 #segは、ルーティングヘッダーの左セグメントフィールドです。 checkは、ノードがチェックするStrict / Looseビットマップのビット(0〜3、f0〜f3として指定)を示します。

The six values in the column beneath node S are the values in the Routing header specified by the application using sendmsg(). The function calls by the sender would look like:

ノードSの下の列にある6つの値は、sendmsg()を使用してアプリケーションによって指定されたルーティングヘッダーの値です。送信者による関数呼び出しは次のようになります。

       void  *ptr;
       struct msghdr  msg;
       struct cmsghdr  *cmsgptr;
       struct sockaddr_in6  I1, I2, I3, D;
       unsigned int  f0, f1, f2, f3;
        
       ptr = malloc(inet6_rthdr_space(IPV6_RTHDR_TYPE_0, 3));
       cmsgptr = inet6_rthdr_init(ptr, IPV6_RTHDR_TYPE_0);
        
       inet6_rthdr_add(cmsgptr, &I1.sin6_addr, f0);
       inet6_rthdr_add(cmsgptr, &I2.sin6_addr, f1);
       inet6_rthdr_add(cmsgptr, &I3.sin6_addr, f2);
       inet6_rthdr_lasthop(cmsgptr, f3);
        
       msg.msg_control = ptr;
       msg.msg_controllen = cmsgptr->cmsg_len;
        
       /* finish filling in msg{}, msg_name = D */
       /* call sendmsg() */
        

We also assume that the source address for the socket is not specified (i.e., the asterisk in the figure).

また、ソケットの送信元アドレスが指定されていないと仮定します(つまり、図のアスタリスク)。

The four columns of six values that are then shown between the five nodes are the values of the fields in the packet while the packet is in transit between the two nodes. Notice that before the packet is sent by the source node S, the source address is chosen (replacing the asterisk), I1 becomes the destination address of the datagram, the two addresses A[2] and A[3] are "shifted up", and D is moved to A[3]. If f0 is IPV6_RTHDR_STRICT, then I1 must be a neighbor of S.

5つのノードの間に表示される6つの値の4つの列は、パケットが2つのノード間で転送されている間のパケットのフィールドの値です。パケットが送信元ノードSによって送信される前に、送信元アドレスが選択され(アスタリスクの代わり)、I1がデータグラムの宛先アドレスになり、2つのアドレスA [2]とA [3]が「シフトアップ」されることに注意してください。 、およびDがA [3]に移動されます。 f0がIPV6_RTHDR_STRICTの場合、I1はSのネイバーでなければなりません。

The columns of values that are shown beneath the destination node are the values returned by recvmsg(), assuming the application has enabled both the IPV6_PKTINFO and IPV6_RTHDR socket options. The source address is S (contained in the sockaddr_in6 structure pointed to by the msg_name member), the destination address is D (returned as an ancillary data object in an in6_pktinfo structure), and the ancillary data object specifying the Routing header will contain three addresses (I1, I2, and I3) and four flags (f0, f1, f2, and f3). The number of segments in the Routing header is known from the Hdr Ext Len field in the Routing header (a value of 6, indicating 3 addresses).

アプリケーションがIPV6_PKTINFOとIPV6_RTHDRの両方のソケットオプションを有効にしている場合、宛先ノードの下に表示される値の列は、recvmsg()によって返される値です。送信元アドレスはS(msg_nameメンバーが指すsockaddr_in6構造に含まれる)、宛先アドレスはD(in6_pktinfo構造の補助データオブジェクトとして返される)、ルーティングヘッダーを指定する補助データオブジェクトには3つのアドレスが含まれる(I1、I2、I3)と4つのフラグ(f0、f1、f2、f3)。ルーティングヘッダーのセグメント数は、ルーティングヘッダーのHdr Ext Lenフィールドからわかります(値6、3つのアドレスを示します)。

The return value from inet6_rthdr_segments() will be 3 and inet6_rthdr_getaddr(1) will return I1, inet6_rthdr_getaddr(2) will return I2, and inet6_rthdr_getaddr(3) will return I3, The return value from inet6_rthdr_flags(0) will be f0, inet6_rthdr_flags(1) will return f1, inet6_rthdr_flags(2) will return f2, and inet6_rthdr_flags(3) will return f3.

inet6_rthdr_segments()からの戻り値は3になり、inet6_rthdr_getaddr(1)はI1を返し、inet6_rthdr_getaddr(2)はI2を返し、inet6_rthdr_getaddr(3)はI3を返します。 1)はf1を返し、inet6_rthdr_flags(2)はf2を返し、inet6_rthdr_flags(3)はf3を返します。

If the receiving application then calls inet6_rthdr_reverse(), the order of the three addresses will become I3, I2, and I1, and the order of the four Strict/Loose flags will become f3, f2, f1, and f0.

次に、受信アプリケーションがinet6_rthdr_reverse()を呼び出すと、3つのアドレスの順序はI3、I2、およびI1になり、4つのStrict / Looseフラグの順序はf3、f2、f1、およびf0になります。

We can also show what an implementation might store in the ancillary data object as the Routing header is being built by the sending process. If we assume a 32-bit architecture where sizeof(struct cmsghdr) equals 12, with a desired alignment of 4-byte boundaries, then the call to inet6_rthdr_space(3) returns 68: 12 bytes for the cmsghdr structure and 56 bytes for the Routing header (8 + 3*16).

ルーティングヘッダーが送信プロセスによって構築されているときに、実装が補助データオブジェクトに何を格納するかを示すこともできます。 sizeof(struct cmsghdr)が12で32バイトアーキテクチャで、4バイト境界の望ましい配置であると想定した場合、inet6_rthdr_space(3)への呼び出しは68を返します:cmsghdr構造体では12バイト、ルーティングでは56バイトヘッダー(8 + 3 * 16)。

The call to inet6_rthdr_init() initializes the ancillary data object to contain a Type 0 Routing header:

inet6_rthdr_init()を呼び出すと、補助データオブジェクトが初期化され、タイプ0ルーティングヘッダーが含まれます。

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_len = 20                                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_level = IPPROTO_IPV6                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_type = IPV6_RTHDR                                  |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |  Next Header  | Hdr Ext Len=0 | Routing Type=0|  Seg Left=0   |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |   Reserved    |             Strict/Loose Bit Map              |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        

The first call to inet6_rthdr_add() adds I1 to the list.

inet6_rthdr_add()への最初の呼び出しは、I1をリストに追加します。

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_len = 36                                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_level = IPPROTO_IPV6                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_type = IPV6_RTHDR                                  |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |  Next Header  | Hdr Ext Len=2 | Routing Type=0|  Seg Left=1   |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |   Reserved    |X|           Strict/Loose Bit Map              |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               |
     +                                                               +
     |                                                               |
     +                           Address[1] = I1                     +
     |                                                               |
     +                                                               +
     |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        

Bit 0 of the Strict/Loose Bit Map contains the value f0, which we just mark as X. cmsg_len is incremented by 16, the Hdr Ext Len field is incremented by 2, and the Segments Left field is incremented by 1.

Strict / Looseビットマップのビット0には、値f0が含まれています。これをXとしてマークします。cmsg_lenは16ずつ増加し、Hdr Ext Lenフィールドは2ずつ増加し、Segments Leftフィールドは1ずつ増加します。

The next call to inet6_rthdr_add() adds I2 to the list.

次にinet6_rthdr_add()を呼び出すと、I2がリストに追加されます。

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_len = 52                                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_level = IPPROTO_IPV6                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_type = IPV6_RTHDR                                  |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |  Next Header  | Hdr Ext Len=4 | Routing Type=0|  Seg Left=2   |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |   Reserved    |X|X|         Strict/Loose Bit Map              |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               |
     +                                                               +
     |                                                               |
     +                           Address[1] = I1                     +
     |                                                               |
     +                                                               +
     |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               |
     +                                                               +
     |                                                               |
     +                           Address[2] = I2                     +
     |                                                               |
     +                                                               +
     |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        

The next bit of the Strict/Loose Bit Map contains the value f1. cmsg_len is incremented by 16, the Hdr Ext Len field is incremented by 2, and the Segments Left field is incremented by 1.

Strict / Looseビットマップの次のビットには、値f1が含まれています。 cmsg_lenが16増加し、Hdr Ext Lenフィールドが2増加し、Segments Leftフィールドが1増加します。

The last call to inet6_rthdr_add() adds I3 to the list.

inet6_rthdr_add()への最後の呼び出しは、リストにI3を追加します。

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_len = 68                                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_level = IPPROTO_IPV6                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |       cmsg_type = IPV6_RTHDR                                  |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |  Next Header  | Hdr Ext Len=6 | Routing Type=0|  Seg Left=3   |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |   Reserved    |X|X|X|       Strict/Loose Bit Map              |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               |
     +                                                               +
     |                                                               |
     +                           Address[1] = I1                     +
     |                                                               |
     +                                                               +
     |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               |
     +                                                               +
     |                                                               |
     +                           Address[2] = I2                     +
     |                                                               |
     +                                                               +
     |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               |
     +                                                               +
     |                                                               |
     +                           Address[3] = I3                     +
     |                                                               |
     +                                                               +
     |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        

The next bit of the Strict/Loose Bit Map contains the value f2. cmsg_len is incremented by 16, the Hdr Ext Len field is incremented by 2, and the Segments Left field is incremented by 1.

Strict / Looseビットマップの次のビットには、値f2が含まれています。 cmsg_lenが16増加し、Hdr Ext Lenフィールドが2増加し、Segments Leftフィールドが1増加します。

Finally, the call to inet6_rthdr_lasthop() sets the next bit of the Strict/Loose Bit Map to the value specified by f3. All the lengths remain unchanged.

最後に、inet6_rthdr_lasthop()を呼び出すと、Strict / Looseビットマップの次のビットがf3で指定された値に設定されます。すべての長さは変更されません。

9. Ordering of Ancillary Data and IPv6 Extension Headers
9. 補助データとIPv6拡張ヘッダーの順序

Three IPv6 extension headers can be specified by the application and returned to the application using ancillary data with sendmsg() and recvmsg(): Hop-by-Hop options, Destination options, and the Routing header. When multiple ancillary data objects are transferred via sendmsg() or recvmsg() and these objects represent any of these three extension headers, their placement in the control buffer is directly tied to their location in the corresponding IPv6 datagram. This API imposes some ordering constraints when using multiple ancillary data objects with sendmsg().

アプリケーションで3つのIPv6拡張ヘッダーを指定し、sendmsg()およびrecvmsg()で補助データを使用してアプリケーションに返すことができます。ホップバイホップオプション、宛先オプション、およびルーティングヘッダー。 sendmsg()またはrecvmsg()を介して複数の補助データオブジェクトが転送され、これらのオブジェクトがこれら3つの拡張ヘッダーのいずれかを表す場合、コントロールバッファー内のそれらの配置は、対応するIPv6データグラム内の場所に直接関連付けられます。このAPIは、sendmsg()で複数の補助データオブジェクトを使用するときに、いくつかの順序付け制約を課します。

When multiple IPv6 Hop-by-Hop options having the same option type are specified, these options will be inserted into the Hop-by-Hop options header in the same order as they appear in the control buffer. But when multiple Hop-by-Hop options having different option types are specified, these options may be reordered by the kernel to reduce padding in the Hop-by-Hop options header. Hop-by-Hop options may appear anywhere in the control buffer and will always be collected by the kernel and placed into a single Hop-by-Hop options header that immediately follows the IPv6 header.

同じオプションタイプを持つ複数のIPv6ホップバイホップオプションが指定されている場合、これらのオプションは、制御バッファーに表示されるのと同じ順序でホップバイホップオプションヘッダーに挿入されます。ただし、異なるオプションタイプを持つ複数のホップバイホップオプションが指定されている場合、これらのオプションは、ホップバイホップオプションヘッダーのパディングを減らすためにカーネルによって並べ替えられる場合があります。ホップバイホップオプションは、コントロールバッファーのどこにでも出現する可能性があり、常にカーネルによって収集され、IPv6ヘッダーの直後に続く単一のホップバイホップオプションヘッダーに配置されます。

Similar rules apply to the Destination options: (1) those of the same type will appear in the same order as they are specified, and (2) those of differing types may be reordered. But the kernel will build up to two Destination options headers: one to precede the Routing header and one to follow the Routing header. If the application specifies a Routing header then all Destination options that appear in the control buffer before the Routing header will appear in a Destination options header before the Routing header and these options might be reordered, subject to the two rules that we just stated. Similarly all Destination options that appear in the control buffer after the Routing header will appear in a Destination options header after the Routing header, and these options might be reordered, subject to the two rules that we just stated.

Destinationオプションにも同様の規則が適用されます。(1)同じタイプのオプションは指定された順序で表示され、(2)異なるタイプのオプションは並べ替えられます。ただし、カーネルは最大2つの宛先オプションヘッダーを構築します。1つはルーティングヘッダーの前に、もう1つはルーティングヘッダーの後に続きます。アプリケーションがルーティングヘッダーを指定する場合、ルーティングヘッダーの前にコントロールバッファーに表示されるすべての宛先オプションは、ルーティングヘッダーの前の宛先オプションヘッダーに表示され、これらのオプションは、先ほど述べた2つのルールに従って並べ替えられる可能性があります。同様に、ルーティングヘッダーの後にコントロールバッファーに表示されるすべての宛先オプションは、ルーティングヘッダーの後にある宛先オプションヘッダーに表示されます。これらのオプションは、先ほど述べた2つのルールに従って並べ替えられる場合があります。

As an example, assume that an application specifies control information to sendmsg() containing six ancillary data objects: the first containing two Hop-by-Hop options, the second containing one Destination option, the third containing two Destination options, the fourth containing a Routing header, the fifth containing a Hop-by-Hop option, and the sixth containing two Destination options. We also assume that all the Hop-by-Hop options are of different types, as are all the Destination options. We number these options 1-9, corresponding to their order in the control buffer, and show them on the left below.

例として、アプリケーションが6つの補助データオブジェクトを含むsendmsg()に制御情報を指定すると仮定します。1つ目は2つのホップバイホップオプションを含み、2つ目は1つの宛先オプションを含み、3つ目は2つの宛先オプションを含み、4つ目はルーティングヘッダー。5番目にはホップバイホップオプションが含まれ、6番目には2つの宛先オプションが含まれます。また、すべての宛先オプションと同様に、すべてのホップバイホップオプションも異なるタイプであると想定しています。これらのオプションには、コントロールバッファーでの順序に応じて1〜9の番号を付け、左下に示します。

In the middle we show the final arrangement of the options in the extension headers built by the kernel. On the right we show the four ancillary data objects returned to the receiving application.

真ん中には、カーネルによって構築された拡張ヘッダーのオプションの最終的な配置を示します。右側には、受信アプリケーションに返された4つの補助データオブジェクトを示します。

          Sender's                                       Receiver's
       Ancillary Data      -->   IPv6 Extension   -->  Ancillary Data
          Objects                    Headers              Objects
       ------------------        ---------------       --------------
       HOPOPT-1,2 (first)        HOPHDR(J,7,1,2)       HOPOPT-7,1,2
       DSTOPT-3                  DSTHDR(4,5,3)         DSTOPT-4,5,3
       DSTOPT-4,5                RTHDR(6)              RTHDR-6
       RTHDR-6                   DSTHDR(8,9)           DSTOPT-8,9
       HOPOPT-7
       DSTOPT-8,9 (last)
        

The sender's two Hop-by-Hop ancillary data objects are reordered, as are the first two Destination ancillary data objects. We also show a Jumbo Payload option (denoted as J) inserted by the kernel before the sender's three Hop-by-Hop options. The first three Destination options must appear in a Destination header before the Routing header, and the final two Destination options must appear in a Destination header after the Routing header.

送信者の2つのホップバイホップ補助データオブジェクトは、最初の2つの宛先補助データオブジェクトと同様に並べ替えられます。また、送信者の3つのホップバイホップオプションの前にカーネルによって挿入されたジャンボペイロードオプション(Jと表記)も示しています。最初の3つの宛先オプションは、ルーティングヘッダーの前の宛先ヘッダーに表示され、最後の2つの宛先オプションは、ルーティングヘッダーの後の宛先ヘッダーに表示される必要があります。

If Destination options are specified in the control buffer after a Routing header, or if Destination options are specified without a Routing header, the kernel will place those Destination options after an authentication header and/or an encapsulating security payload header, if present.

宛先ヘッダーオプションがルーティングヘッダーの後にコントロールバッファーで指定されている場合、または宛先ヘッダーオプションがルーティングヘッダーなしで指定されている場合、カーネルは認証ヘッダーおよび/またはカプセル化セキュリティペイロードヘッダー(存在する場合)の後にそれらの宛先オプションを配置します。

10. IPv6-Specific Options with IPv4-Mapped IPv6 Addresses
10. IPv4にマップされたIPv6アドレスを持つIPv6固有のオプション

The various socket options and ancillary data specifications defined in this document apply only to true IPv6 sockets. It is possible to create an IPv6 socket that actually sends and receives IPv4 packets, using IPv4-mapped IPv6 addresses, but the mapping of the options defined in this document to an IPv4 datagram is beyond the scope of this document.

このドキュメントで定義されているさまざまなソケットオプションと補助データ仕様は、真のIPv6ソケットにのみ適用されます。 IPv4にマップされたIPv6アドレスを使用して、実際にIPv4パケットを送受信するIPv6ソケットを作成することは可能ですが、このドキュメントで定義されているオプションのIPv4データグラムへのマッピングは、このドキュメントの範囲を超えています。

In general, attempting to specify an IPv6-only option, such as the Hop-by-Hop options, Destination options, or Routing header on an IPv6 socket that is using IPv4-mapped IPv6 addresses, will probably result in an error. Some implementations, however, may provide access to the packet information (source/destination address, send/receive interface, and hop limit) on an IPv6 socket that is using IPv4-mapped IPv6 addresses.

一般に、ホップバイホップオプション、宛先オプション、またはIPv4にマップされたIPv6アドレスを使用しているIPv6ソケットのルーティングヘッダーなどのIPv6のみのオプションを指定しようとすると、おそらくエラーが発生します。ただし、実装によっては、IPv4にマップされたIPv6アドレスを使用しているIPv6ソケット上のパケット情報(送信元/宛先アドレス、送信/受信インターフェイス、およびホップ制限)へのアクセスを提供する場合があります。

11. rresvport_af
11. rresvport_af

The rresvport() function is used by the rcmd() function, and this function is in turn called by many of the "r" commands such as rlogin. While new applications are not being written to use the rcmd() function, legacy applications such as rlogin will continue to use it and these will be ported to IPv6.

rresvport()関数はrcmd()関数によって使用され、この関数は、rloginなどの多くの「r」コマンドによって呼び出されます。新しいアプリケーションはrcmd()関数を使用するように作成されていませんが、rloginなどのレガシーアプリケーションは引き続き使用し、これらはIPv6に移植されます。

rresvport() creates an IPv4/TCP socket and binds a "reserved port" to the socket. Instead of defining an IPv6 version of this function we define a new function that takes an address family as its argument.

rresvport()はIPv4 / TCPソケットを作成し、「予約済みポート」をソケットにバインドします。この関数のIPv6バージョンを定義する代わりに、アドレスファミリを引数として取る新しい関数を定義します。

       #include <unistd.h>
        
       int  rresvport_af(int *port, int family);
        

This function behaves the same as the existing rresvport() function, but instead of creating an IPv4/TCP socket, it can also create an IPv6/TCP socket. The family argument is either AF_INET or AF_INET6, and a new error return is EAFNOSUPPORT if the address family is not supported.

この関数は既存のrresvport()関数と同じように動作しますが、IPv4 / TCPソケットを作成する代わりに、IPv6 / TCPソケットを作成することもできます。ファミリ引数はAF_INETまたはAF_INET6のいずれかであり、アドレスファミリがサポートされていない場合、新しいエラーの戻りはEAFNOSUPPORTです。

(Note: There is little consensus on which header defines the rresvport() and rcmd() function prototypes. 4.4BSD defines it in <unistd.h>, others in <netdb.h>, and others don't define the function prototypes at all.)

(注:どのヘッダーがrresvport()およびrcmd()関数のプロトタイプを定義するかについてはほとんどコンセンサスがありません。4.4BSDは<unistd.h>で定義し、他は<netdb.h>で定義し、他は関数プロトタイプを定義しませんまったく。)

(Note: We define this function only, and do not define something like rcmd_af() or rcmd6(). The reason is that rcmd() calls gethostbyname(), which returns the type of address: AF_INET or AF_INET6. It should therefore be possible to modify rcmd() to support either IPv4 or IPv6, based on the address family returned by gethostbyname().)

(注:この関数のみを定義し、rcmd_af()やrcmd6()のようなものは定義しません。理由は、rcmd()がgethostbyname()を呼び出し、アドレスのタイプを返すためです:AF_INETまたはAF_INET6。したがって、 gethostbyname()によって返されるアドレスファミリに基づいて、IPv4またはIPv6のいずれかをサポートするようにrcmd()を変更することができます。)

12. Future Items
12. 今後のアイテム

Some additional items may require standardization, but no concrete proposals have been made for the API to perform these tasks. These may be addressed in a later document.

いくつかの追加項目は標準化を必要とする場合がありますが、APIがこれらのタスクを実行するための具体的な提案は行われていません。これらは、後のドキュメントで対処される可能性があります。

12.1. Flow Labels
12.1. フローラベル

Earlier revisions of this document specified a set of inet6_flow_XXX() functions to assign, share, and free IPv6 flow labels. Consensus, however, indicated that it was premature to specify this part of the API.

このドキュメントの以前のリビジョンでは、IPv6フローラベルを割り当て、共有、解放するための一連のinet6_flow_XXX()関数を指定していました。ただし、コンセンサスは、APIのこの部分を指定するのは時期尚早であることを示しました。

12.2. Path MTU Discovery and UDP
12.2. パスMTUディスカバリーとUDP

A standard method may be desirable for a UDP application to determine the "maximum send transport-message size" (Section 5.1 of [RFC-1981]) to a given destination. This would let the UDP application send smaller datagrams to the destination, avoiding fragmentation.

UDPアプリケーションが特定の宛先への「最大送信トランスポートメッセージサイズ」([RFC-1981]のセクション5.1)を決定するには、標準的な方法が望ましい場合があります。これにより、UDPアプリケーションはより小さいデータグラムを宛先に送信し、断片化を回避できます。

12.3. Neighbor Reachability and UDP
12.3. ネイバー到達可能性とUDP

A standard method may be desirable for a UDP application to tell the kernel that it is making forward progress with a given peer (Section 7.3.1 of [RFC-1970]). This could save unneeded neighbor solicitations and neighbor advertisements.

UDPアプリケーションが特定のピア([RFC-1970]のセクション7.3.1)で前進していることをカーネルに伝えるには、標準的な方法が望ましい場合があります。これにより、不要な近隣要請と近隣通知を節約できます。

13. Summary of New Definitions
13. 新しい定義の要約

The following list summarizes the constants and structure, definitions discussed in this memo, sorted by header.

次のリストは、このメモで説明されている定数と構造、定義をヘッダー別にソートしたものをまとめたものです。

     <netinet/icmp6.h> ICMP6_DST_UNREACH
     <netinet/icmp6.h> ICMP6_DST_UNREACH_ADDR
     <netinet/icmp6.h> ICMP6_DST_UNREACH_ADMIN
     <netinet/icmp6.h> ICMP6_DST_UNREACH_NOPORT
     <netinet/icmp6.h> ICMP6_DST_UNREACH_NOROUTE
     <netinet/icmp6.h> ICMP6_DST_UNREACH_NOTNEIGHBOR
     <netinet/icmp6.h> ICMP6_ECHO_REPLY
     <netinet/icmp6.h> ICMP6_ECHO_REQUEST
     <netinet/icmp6.h> ICMP6_INFOMSG_MASK
     <netinet/icmp6.h> ICMP6_MEMBERSHIP_QUERY
     <netinet/icmp6.h> ICMP6_MEMBERSHIP_REDUCTION
     <netinet/icmp6.h> ICMP6_MEMBERSHIP_REPORT
     <netinet/icmp6.h> ICMP6_PACKET_TOO_BIG
     <netinet/icmp6.h> ICMP6_PARAMPROB_HEADER
     <netinet/icmp6.h> ICMP6_PARAMPROB_NEXTHEADER
     <netinet/icmp6.h> ICMP6_PARAMPROB_OPTION
     <netinet/icmp6.h> ICMP6_PARAM_PROB
     <netinet/icmp6.h> ICMP6_TIME_EXCEEDED
     <netinet/icmp6.h> ICMP6_TIME_EXCEED_REASSEMBLY
     <netinet/icmp6.h> ICMP6_TIME_EXCEED_TRANSIT
     <netinet/icmp6.h> ND_NA_FLAG_OVERRIDE
     <netinet/icmp6.h> ND_NA_FLAG_ROUTER
     <netinet/icmp6.h> ND_NA_FLAG_SOLICITED
     <netinet/icmp6.h> ND_NEIGHBOR_ADVERT
     <netinet/icmp6.h> ND_NEIGHBOR_SOLICIT
     <netinet/icmp6.h> ND_OPT_MTU
     <netinet/icmp6.h> ND_OPT_PI_FLAG_AUTO
     <netinet/icmp6.h> ND_OPT_PI_FLAG_ONLINK
     <netinet/icmp6.h> ND_OPT_PREFIX_INFORMATION
        
     <netinet/icmp6.h> ND_OPT_REDIRECTED_HEADER
     <netinet/icmp6.h> ND_OPT_SOURCE_LINKADDR
     <netinet/icmp6.h> ND_OPT_TARGET_LINKADDR
     <netinet/icmp6.h> ND_RA_FLAG_MANAGED
     <netinet/icmp6.h> ND_RA_FLAG_OTHER
     <netinet/icmp6.h> ND_REDIRECT
     <netinet/icmp6.h> ND_ROUTER_ADVERT
     <netinet/icmp6.h> ND_ROUTER_SOLICIT
        
     <netinet/icmp6.h> struct icmp6_filter{};
     <netinet/icmp6.h> struct icmp6_hdr{};
     <netinet/icmp6.h> struct nd_neighbor_advert{};
     <netinet/icmp6.h> struct nd_neighbor_solicit{};
     <netinet/icmp6.h> struct nd_opt_hdr{};
     <netinet/icmp6.h> struct nd_opt_mtu{};
     <netinet/icmp6.h> struct nd_opt_prefix_info{};
     <netinet/icmp6.h> struct nd_opt_rd_hdr{};
     <netinet/icmp6.h> struct nd_redirect{};
     <netinet/icmp6.h> struct nd_router_advert{};
     <netinet/icmp6.h> struct nd_router_solicit{};
        
     <netinet/in.h>    IPPROTO_AH
     <netinet/in.h>    IPPROTO_DSTOPTS
     <netinet/in.h>    IPPROTO_ESP
     <netinet/in.h>    IPPROTO_FRAGMENT
     <netinet/in.h>    IPPROTO_HOPOPTS
     <netinet/in.h>    IPPROTO_ICMPV6
     <netinet/in.h>    IPPROTO_IPV6
     <netinet/in.h>    IPPROTO_NONE
     <netinet/in.h>    IPPROTO_ROUTING
     <netinet/in.h>    IPV6_DSTOPTS
     <netinet/in.h>    IPV6_HOPLIMIT
     <netinet/in.h>    IPV6_HOPOPTS
     <netinet/in.h>    IPV6_NEXTHOP
     <netinet/in.h>    IPV6_PKTINFO
     <netinet/in.h>    IPV6_PKTOPTIONS
     <netinet/in.h>    IPV6_RTHDR
     <netinet/in.h>    IPV6_RTHDR_LOOSE
     <netinet/in.h>    IPV6_RTHDR_STRICT
     <netinet/in.h>    IPV6_RTHDR_TYPE_0
     <netinet/in.h>    struct in6_pktinfo{};
        
     <netinet/ip6.h>   IP6F_OFF_MASK
     <netinet/ip6.h>   IP6F_RESERVED_MASK
     <netinet/ip6.h>   IP6F_MORE_FRAG
     <netinet/ip6.h>   struct ip6_dest{};
     <netinet/ip6.h>   struct ip6_frag{};
     <netinet/ip6.h>   struct ip6_hbh{};
        
     <netinet/ip6.h>   struct ip6_hdr{};
     <netinet/ip6.h>   struct ip6_rthdr{};
     <netinet/ip6.h>   struct ip6_rthdr0{};
        
     <sys/socket.h>    struct cmsghdr{};
     <sys/socket.h>    struct msghdr{};
        

The following list summarizes the function and macro prototypes discussed in this memo, sorted by header.

次のリストは、このメモで説明されている関数とマクロのプロトタイプを、ヘッダー順に並べ替えたものです。

<netinet/icmp6.h> void ICMP6_FILTER_SETBLOCK(int,
                                                struct icmp6_filter *);
<netinet/icmp6.h> void ICMP6_FILTER_SETBLOCKALL(struct icmp6_filter *);
<netinet/icmp6.h> void ICMP6_FILTER_SETPASS(int, struct icmp6_filter *);
<netinet/icmp6.h> void ICMP6_FILTER_SETPASSALL(struct icmp6_filter *);
<netinet/icmp6.h> int  ICMP6_FILTER_WILLBLOCK(int,
                                           const struct icmp6_filter *);
<netinet/icmp6.h> int  ICMP6_FILTER_WILLPASS(int,
                                           const struct icmp6_filter *);
        
<netinet/in.h>    int IN6_ARE_ADDR_EQUAL(const struct in6_addr *,
                                         const struct in6_addr *);
        
<netinet/in.h>    uint8_t *inet6_option_alloc(struct cmsghdr *,
                                               int, int, int);
<netinet/in.h>    int inet6_option_append(struct cmsghdr *,
                                          const uint8_t *, int, int);
<netinet/in.h>    int inet6_option_find(const struct cmsghdr *,
                                        uint8_t *, int);
<netinet/in.h>    int inet6_option_init(void *, struct cmsghdr **, int);
<netinet/in.h>    int inet6_option_next(const struct cmsghdr *,
                                        uint8_t **);
<netinet/in.h>    int inet6_option_space(int);
        
<netinet/in.h>    int inet6_rthdr_add(struct cmsghdr *,
                                      const struct in6_addr *,
                                      unsigned int);
<netinet/in.h>    struct in6_addr inet6_rthdr_getaddr(struct cmsghdr *,
                                                      int);
<netinet/in.h>    int inet6_rthdr_getflags(const struct cmsghdr *, int);
<netinet/in.h>    struct cmsghdr *inet6_rthdr_init(void *, int);
<netinet/in.h>    int inet6_rthdr_lasthop(struct cmsghdr *,
                                                          unsigned int);
<netinet/in.h>    int inet6_rthdr_reverse(const struct cmsghdr *,
                                          struct cmsghdr *);
<netinet/in.h>    int inet6_rthdr_segments(const struct cmsghdr *);
<netinet/in.h>    size_t inet6_rthdr_space(int, int);
        
<sys/socket.h>    unsigned char *CMSG_DATA(const struct cmsghdr *);
<sys/socket.h>    struct cmsghdr *CMSG_FIRSTHDR(const struct msghdr *);
<sys/socket.h>    unsigned int CMSG_LEN(unsigned int);
<sys/socket.h>    struct cmsghdr *CMSG_NXTHDR(const struct msghdr *mhdr,
                                              const struct cmsghdr *);
<sys/socket.h>    unsigned int CMSG_SPACE(unsigned int);
        
<unistd.h>        int rresvport_af(int *, int);
        
14. Security Considerations
14. セキュリティに関する考慮事項

The setting of certain Hop-by-Hop options and Destination options may be restricted to privileged processes. Similarly some Hop-by-Hop options and Destination options may not be returned to nonprivileged applications.

特定のホップバイホップオプションと宛先オプションの設定は、特権プロセスに制限される場合があります。同様に、一部のホップバイホップオプションと宛先オプションは、非特権アプリケーションに返されない場合があります。

15. Change History
15. 変更履歴

Changes from the June 1997 Edition (-03 draft)

1997年6月版からの変更点(ドラフト-03)

- Added a note that defined constants for multibyte fields are in network byte order. This affects the ip6f_offlg member of the Fragment header (Section 2.1.2) and the nd_na_flags_reserved member of the nd_neighbor_advert structure (Section 2.2.2).

- マルチバイトフィールドの定義済み定数はネットワークバイトオーダーであるという注記を追加しました。これは、Fragmentヘッダーのip6f_offlgメンバー(セクション2.1.2)およびnd_neighbor_advert構造のnd_na_flags_reservedメンバー(セクション2.2.2)に影響します。

- Section 5: the ipi6_ifindex member of the in6_pktinfo structure should be "unsigned int" instead of "int", for consistency with the interface indexes in [RFC-2133].

- セクション5:[RFC-2133]のインターフェイスインデックスとの整合性を保つため、in6_pktinfo構造体のipi6_ifindexメンバーは、 "int"ではなく "unsigned int"にする必要があります。

- Section 6.3.7: the three calls to inet6_option_space() in the examples needed to be arguments to malloc(). The final one of these was missing the "6" in the name "inet6_option_space".

- セクション6.3.7:例のinet6_option_space()への3つの呼び出しは、malloc()への引数である必要がありました。これらの最後の1つには、「inet6_option_space」という名前の「6」がありませんでした。

- Section 8.6: the function prototype for inet6_rthdr_segments() was missing the ending semicolon.

- セクション8.6:inet6_rthdr_segments()の関数プロトタイプに終了セミコロンがありませんでした。

Changes from the March 1997 Edition (-02 draft)

1997年3月版からの変更点(ドラフト-02)

- In May 1997 Draft 6.6 of Posix 1003.1g (called Posix.1g herein) passed ballot and will be forwarded to the IEEE Standards Board later in 1997 for final approval. Some changes made for this final Posix draft are incorporated into this Internet Draft, specifically the datatypes mentioned in Section 1 (and used throughout the text), and the socklen_t datatype used in Section 4.1 and 4.2.

- 1997年5月にPosix 1003.1g(ここではPosix.1gと呼ばれます)の草案6.6が投票に合格し、最終承認のために1997年後半にIEEE規格委員会に転送されます。この最終的なPosixドラフトに対して行われた変更の一部は、このインターネットドラフト、特にセクション1で言及された(そして本文全体で使用された)データ型、およびセクション4.1および4.2で使用されたsocklen_tデータ型に組み込まれています。

- Section 1: Added the intN_t signed datatypes, changed the datatype u_intN_t to uintN_t (no underscore after the "u"), and removed the datatype u_intNm_t, as per Draft 6.6 of Posix.1g.

-セクション1:Posix.1gのドラフト6.6に従って、intN_t署名付きデータ型を追加し、データ型u_intN_tをuintN_t(「u」の後に下線なし)に変更し、データ型u_intNm_tを削除しました。

- Name space issues for structure and constant names in Section 2: Many of the structure member names and constant names were changed so that the prefixes are the same. The following prefixes are used for structure members: "ip6_", "icmp6_", and "nd_". All constants have the prefixes "ICMP6_" and "ND_".

- セクション2の構造名と定数名の名前空間の問題:構造体のメンバー名と定数名の多くは、プレフィックスが同じになるように変更されました。構造体のメンバーには、「ip6 _」、「icmp6_」、および「nd_」という接頭辞が使用されます。すべての定数の接頭辞は「ICMP6_」と「ND_」です。

- New definitions: Section 2.1.2: contains definitions for the IPv6 extension headers, other than AH and ESP. Section 2.2.2: contains additional structures and constants for the neighbor discovery option header and redirected header.

- 新しい定義:セクション2.1.2:AHおよびESP以外のIPv6拡張ヘッダーの定義が含まれています。セクション2.2.2:近隣探索オプションヘッダーとリダイレクトされたヘッダーの追加の構造と定数が含まれています。

- Section 2.2.2: the enum for the neighbor discovery option field was changed to be a set of #define constants.

- セクション2.2.2:近隣探索オプションフィールドの列挙型が#define定数のセットに変更されました。

- Changed the word "function" to "macro" for references to all the uppercase names in Sections 2.3 (IN6_ARE_ADDR_EQUAL), 3.2 (ICMPV6_FILTER_xxx), and 4.3 (CMSG_xxx).

- セクション2.3(IN6_ARE_ADDR_EQUAL)、3.2(ICMPV6_FILTER_xxx)、および4.3(CMSG_xxx)のすべての大文字の名前を参照するために、「関数」という単語を「マクロ」に変更しました。

- Added more protocols to the /etc/protocols file (Section 2.4) and changed the name of "icmpv6" to "ipv6-icmp".

- / etc / protocolsファイルにプロトコルを追加し(セクション2.4)、「icmpv6」の名前を「ipv6-icmp」に変更しました。

- Section 3: Made it more explicit that an application cannot read or write entire IPv6 packets, that all extension headers are passed as ancillary data. Added a sentence that the kernel fragments packets written to an IPv6 raw socket when necessary. Added a note that IPPROTO_RAW raw IPv6 sockets are not special.

- セクション3:アプリケーションがIPv6パケット全体を読み書きできないことをより明確にし、すべての拡張ヘッダーが補助データとして渡されるようにしました。必要に応じて、カーネルがIPv6 RAWソケットに書き込まれたパケットをフラグメント化するという文を追加しました。 IPPROTO_RAW raw IPv6ソケットは特別ではないというメモを追加しました。

- Section 3.1: Explicitly stated that the checksum option applies to both outgoing packets and received packets.

- セクション3.1:チェックサムオプションが発信パケットと受信パケットの両方に適用されることを明示的に述べた。

- Section 3.2: Changed the array name within the icmp6_filter structure from "data" to "icmp6_filt". Changes the prefix for the filter macros from "ICMPV6_" to "ICMP6_", for consistency with the names in Section 2.2. Changed the example from a ping program to a program that wants to receive only router advertisements.

- セクション3.2:icmp6_filter構造内の配列名を「data」から「icmp6_filt」に変更しました。フィルターマクロのプレフィックスを「ICMPV6_」から「ICMP6_」に変更し、セクション2.2の名前との一貫性を保ちます。例をpingプログラムからルーター通知のみを受信するプログラムに変更しました。

- Section 4.1: Changed msg_namelen and msg_controllen from size_t to the Posix.1g socklen_t datatype. Updated the Note that follows.

- セクション4.1:msg_namelenおよびmsg_controllenをsize_tからPosix.1g socklen_tデータ型に変更しました。以下のメモを更新しました。

- Section 4.2: Changed cmsg_len from size_t to the Posix.1g socklen_t datatype. Updated the Note that follows.

- セクション4.2:cmsg_lenをsize_tからPosix.1g socklen_tデータ型に変更。以下のメモを更新しました。

- Section 4.4: Added a Note that the second and third arguments to getsockopt() and setsockopt() are intentionally the same as the cmsg_level and cmsg_type members.

- セクション4.4:getsockopt()およびsetsockopt()の2番目と3番目の引数がcmsg_levelおよびcmsg_typeメンバーと意図的に同じであるというメモを追加しました。

- Section 4.5: Reorganized the section into a description of the option, followed by the TCP semantics, and the UDP and raw socket semantics. Added a sentence on how to clear all the sticky options. Added a note that TCP need not save the options from the most recently received segment until the application says to do so. Added the statement that ancillary data is never passed with sendmsg() or recvmsg() on a TCP socket. Simplified the interaction of the sticky options with ancillary data for UDP or raw IP: none of the sticky options are sent if ancillary data is specified.

- セクション4.5:セクションをオプションの説明に再編成し、その後にTCPセマンティクス、UDPおよびrawソケットセマンティクスを示します。すべてのスティッキーオプションをクリアする方法に関する文を追加しました。アプリケーションがそうするまで、TCPは最後に受信したセグメントのオプションを保存する必要がないというメモを追加しました。 TCPソケットでsendmsg()またはrecvmsg()を使用して補助データが渡されないというステートメントを追加しました。スティッキオプションとUDPまたはraw IPの補助データとの相互作用を簡素化しました。補助データが指定されている場合、スティッキオプションは送信されません。

- Final paragraph of Section 5.1: ipi6_index should be ipi6_ifindex.

- セクション5.1の最後の段落:ipi6_indexはipi6_ifindexである必要があります。

- Section 5.4: Added a note on the term "privileged".

- セクション5.4:「特権」という用語に関する注記を追加しました。

- Section 5.5: Noted that the errors listed are examples, and the actual errors depend on the implementation.

- セクション5.5:リストされたエラーは例であり、実際のエラーは実装によって異なることに注意してください。

- Removed Section 6 ("Flow Labels") as the consensus is that it is premature to try and specify an API for this feature. Access to the flow label field in the IPv6 header is still provided through the sin6_flowinfo member of the IPv6 socket address structure in [RFC-2133]. Added a subsection to Section 13 that this is a future item.

- この機能のAPIを指定して試すのは時期尚早であるというコンセンサスがあるため、セクション6(「フローラベル」)を削除しました。 IPv6ヘッダーのフローラベルフィールドへのアクセスは、[RFC-2133]のIPv6ソケットアドレス構造のsin6_flowinfoメンバーを通じて引き続き提供されます。これは将来のアイテムであることをセクション13にサブセクションを追加しました。

All remaining changes are identified by their section number in the previous draft. With the removal of Section 6, the section numbers are decremented by one.

残りのすべての変更は、前のドラフトのセクション番号で識別されます。セクション6を削除すると、セクション番号が1つ減ります。

- Section 7.3.7: the calls to malloc() in all three examples should be calls to inet6_option_space() instead. The two calls to inet6_option_append() in the third example should be calls to inet6_option_alloc(). The two calls to CMSG_SPACE() in the first and third examples should be calls to CMSG_LEN(). The second call to CMSG_SPACE() in the second example should be a call to CMSG_LEN().

- セクション7.3.7:3つすべての例でのmalloc()の呼び出しは、代わりにinet6_option_space()の呼び出しである必要があります。 3番目の例のinet6_option_append()への2つの呼び出しは、inet6_option_alloc()への呼び出しでなければなりません。最初と3番目の例のCMSG_SPACE()への2つの呼び出しは、CMSG_LEN()への呼び出しでなければなりません。 2番目の例のCMSG_SPACE()への2番目の呼び出しは、CMSG_LEN()への呼び出しでなければなりません。

- Section 7.3.7: All the opt_X_ and opt_Y_ structure member names were changed to be ip6_X_opt_ and ip6_Y_opt_. The two structure names ipv6_opt_X and ipv6_opt_Y were changed to ip6_X_opt and ip6_Y_opt. The constants beginning with IPV6_OPT_X_ and IPV6_OPT_Y_ were changed to begin with IP6_X_OPT_ and IP6_Y_OPT_.

- セクション7.3.7:すべてのopt_X_およびopt_Y_構造体のメンバー名がip6_X_opt_およびip6_Y_opt_に変更されました。 2つの構造名ipv6_opt_Xおよびipv6_opt_Yがip6_X_optおよびip6_Y_optに変更されました。 IPV6_OPT_X_およびIPV6_OPT_Y_で始まる定数は、IP6_X_OPT_およびIP6_Y_OPT_で始まるように変更されました。

- Use the term "Routing header" throughout the draft, instead of "source routing". Changed the names of the eight inet6_srcrt_XXX() functions in Section 9 to inet6_rthdr_XXX(). Changed the name of the socket option from IPV6_SRCRT to IPV6_RTHDR, and the names of the three IPV6_SRCRT_xxx constants in Section 9 to IPV6_RTHDR_xxx.

- 「ソースルーティング」の代わりに、ドラフト全体で「ルーティングヘッダー」という用語を使用します。セクション9の8つのinet6_srcrt_XXX()関数の名前をinet6_rthdr_XXX()に変更しました。ソケットオプションの名前をIPV6_SRCRTからIPV6_RTHDRに変更し、セクション9の3つのIPV6_SRCRT_xxx定数の名前をIPV6_RTHDR_xxxに変更しました。

- Added a paragraph to Section 9 on how to receive and send a Routing header.

- ルーティングヘッダーの送受信方法に関するセクション9に段落を追加しました。

- Changed inet6_rthdr_add() and inet6_rthdr_reverse() so that they return -1 upon an error, instead of an Exxx errno value.

- エラー時にExxx errno値ではなく-1を返すようにinet6_rthdr_add()およびinet6_rthdr_reverse()を変更しました。

- In the description of inet6_rthdr_space() in Section 9.1, added the qualifier "For an IPv6 Type 0 Routing header" to the restriction of between 1 and 23 segments.

- セクション9.1のinet6_rthdr_space()の説明で、1〜23セグメントの制限に「IPv6タイプ0ルーティングヘッダーの場合」という修飾子を追加しました。

- Refer to final function argument in Sections 9.7 and 9.8 as index, not offset.

- セクション9.7および9.8の最後の関数引数をオフセットではなくインデックスとして参照してください。

- Updated Section 14 with new names from Section 2.

- セクション2からの新しい名前でセクション14を更新しました。

- Changed the References from "[n]" to "[RFC-abcd]".

- 参照を「[n]」から「[RFC-abcd]」に変更しました。

Changes from the February 1997 Edition (-01 draft)

1997年2月版からの変更点(ドラフト-01)

- Changed the name of the ip6hdr structure to ip6_hdr (Section 2.1) for consistency with the icmp6hdr structure. Also changed the name of the ip6hdrctl structure contained within the ip6_hdr structure to ip6_hdrctl (Section 2.1). Finally, changed the name of the icmp6hdr structure to icmp6_hdr (Section 2.2). All other occurrences of this structure name, within the Neighbor Discovery structures in Section 2.2.1, already contained the underscore.

- icmp6hdr構造との一貫性を保つために、ip6hdr構造の名前をip6_hdr(セクション2.1)に変更しました。また、ip6_hdr構造内に含まれるip6hdrctl構造の名前をip6_hdrctlに変更しました(セクション2.1)。最後に、icmp6hdr構造体の名前をicmp6_hdrに変更しました(セクション2.2)。セクション2.2.1のネイバー探索構造内でこの構造名の他のすべての出現箇所には、すでにアンダースコアが含まれていました。

- The "struct nd_router_solicit" and "struct nd_router_advert" should both begin with "nd6_". (Section 2.2.2).

- 「struct nd_router_solicit」と「struct nd_router_advert」はどちらも「nd6_」で始まる必要があります。 (セクション2.2.2)。

- Changed the name of in6_are_addr_equal to IN6_ARE_ADDR_EQUAL (Section 2.3) for consistency with basic API address testing functions. The header defining this macro is <netinet/in.h>.

- 基本的なAPIアドレステスト関数との一貫性を保つために、in6_are_addr_equalの名前をIN6_ARE_ADDR_EQUAL(セクション2.3)に変更しました。このマクロを定義するヘッダーは<netinet / in.h>です。

- getprotobyname("ipv6") now returns 41, not 0 (Section 2.4).

- getprotobyname( "ipv6")が0ではなく41を返すようになりました(セクション2.4)。

- The first occurrence of "struct icmpv6_filter" in Section 3.2 should be "struct icmp6_filter".

- セクション3.2で最初に現れる「struct icmpv6_filter」は「struct icmp6_filter」であるはずです。

- Changed the name of the CMSG_LENGTH() macro to CMSG_LEN() (Section 4.3.5), since LEN is used throughout the <netinet/*.h>

- <netinet / *。h>全体でLENが使用されているため、CMSG_LENGTH()マクロの名前をCMSG_LEN()に変更(セクション4.3.5)。

headers.

ヘッダー。

- Corrected the argument name for the sample implementations of the CMSG_SPACE() and CMSG_LEN() macros to be "length" (Sections 4.3.4 and 4.3.5).

- CMSG_SPACE()およびCMSG_LEN()マクロのサンプル実装の引数名を「長さ」に修正しました(セクション4.3.4および4.3.5)。

- Corrected the socket option mentioned in Section 5.1 to specify the interface for multicasting from IPV6_ADD_MEMBERSHIP to IPV6_MULTICAST_IF.

- 5.1で説明したソケットオプションを修正して、IPV6_ADD_MEMBERSHIPからIPV6_MULTICAST_IFへのマルチキャスト用のインターフェースを指定しました。

- There were numerous errors in the previous draft that specified <netinet/ip6.h> that should have been <netinet/in.h>. These have all been corrected and the locations of all definitions is now summarized in the new Section 14 ("Summary of New Definitions").

- 以前のドラフトには、<netinet / in.h>であるはずの<netinet / ip6.h>を指定する多数のエラーがありました。これらはすべて修正され、すべての定義の場所が新しいセクション14(「新しい定義の概要」)にまとめられています。

Changes from the October 1996 Edition (-00 draft)

1996年10月版からの変更点(ドラフト-00)

- Numerous rationale added using the format (Note: ...).

- 形式を使用して追加された多数の理論的根拠(注:...)。

- Added note that not all errors may be defined.

- すべてのエラーを定義できるわけではないという注記を追加しました。

- Added note about ICMPv4, IGMPv4, and ARPv4 terminology.

- ICMPv4、IGMPv4、およびARPv4の用語に関する注記を追加しました。

- Changed the name of <netinet/ip6_icmp.h> to <netinet/icmp6.h>.

- <netinet / ip6_icmp.h>の名前を<netinet / icmp6.h>に変更しました。

- Changed some names in Section 2.2.1: ICMPV6_PKT_TOOBIG to ICMPV6_PACKET_TOOBIG, ICMPV6_TIME_EXCEED to ICMPV6_TIME_EXCEEDED, ICMPV6_ECHORQST to ICMPV6_ECHOREQUEST, ICMPV6_ECHORPLY to ICMPV6_ECHOREPLY, ICMPV6_PARAMPROB_HDR to ICMPV6_PARAMPROB_HEADER, ICMPV6_PARAMPROB_NXT_HDR to ICMPV6_PARAMPROB_NEXTHEADER, and ICMPV6_PARAMPROB_OPTS to ICMPV6_PARAMPROB_OPTION.

- ICMPV6_PARAMPROB_OPTIONにICMPV6_PARAMPROB_NEXTHEADERにICMPV6_PARAMPROB_HEADER、ICMPV6_PARAMPROB_NXT_HDRにICMPV6_ECHOREPLY、ICMPV6_PARAMPROB_HDRにICMPV6_ECHOREQUEST、ICMPV6_ECHORPLYにICMPV6_TIME_EXCEEDED、ICMPV6_ECHORQSTにICMPV6_PACKET_TOOBIG、ICMPV6_TIME_EXCEEDにICMPV6_PKT_TOOBIG、およびICMPV6_PARAMPROB_OPTS:セクション2.2.1でいくつかの名前を変更しました。

- Prepend the prefix "icmp6_" to the three members of the icmp6_dataun union of the icmp6hdr structure (Section 2.2).

- プレフィックス "icmp6_"を、icmp6hdr構造体のicmp6_dataunユニオンの3つのメンバーに追加します(セクション2.2)。

- Moved the neighbor discovery definitions into the <netinet/icmp6.h> header, instead of being in their own header (Section 2.2.1).

- 近隣探索定義を独自のヘッダーではなく、<netinet / icmp6.h>ヘッダーに移動しました(セクション2.2.1)。

- Changed Section 2.3 ("Address Testing"). The basic macros are now in the basic API.

- セクション2.3(「アドレステスト」)を変更。基本的なマクロが基本的なAPIに含まれるようになりました。

- Added the new Section 2.4 on "Protocols File".

- 「プロトコルファイル」の新しいセクション2.4を追加しました。

- Added note to raw sockets description that something like BPF or DLPI must be used to read or write entire IPv6 packets.

- IPv6パケット全体の読み取りまたは書き込みにはBPFやDLPIなどを使用する必要があるというrawソケットの説明に注記を追加しました。

- Corrected example of IPV6_CHECKSUM socket option (Section 3.1). Also defined value of -1 to disable.

- IPV6_CHECKSUMソケットオプションの例を修正(セクション3.1)。また、無効にするには、値-1を定義します。

- Noted that <netinet/icmp6.h> defines all the ICMPv6 filtering constants, macros, and structures (Section 3.2).

- <netinet / icmp6.h>は、すべてのICMPv6フィルタリング定数、マクロ、および構造を定義することに注意してください(セクション3.2)。

- Added note on magic number 10240 for amount of ancillary data (Section 4.1).

- 補助データの量に関するマジック番号10240に関する注記を追加(セクション4.1)。

- Added possible padding to picture of ancillary data (Section 4.2).

- 補助データの画像に可能なパディングを追加しました(セクション4.2)。

- Defined <sys/socket.h> header for CMSG_xxx() functions (Section 4.2).

- CMSG_xxx()関数用に定義された<sys / socket.h>ヘッダー(セクション4.2)。

- Note that the data returned by getsockopt(IPV6_PKTOPTIONS) for a TCP socket is just from the optional headers, if present, of the most recently received segment. Also note that control information is never returned by recvmsg() for a TCP socket.

- TCPソケットのgetsockopt(IPV6_PKTOPTIONS)によって返されるデータは、存在する場合、最後に受信したセグメントのオプションのヘッダーからのものであることに注意してください。また、TCPソケットの場合、recvmsg()によって制御情報が返されることはありません。

- Changed header for struct in6_pktinfo from <netinet.in.h> to <netinet/ip6.h> (Section 5).

- struct in6_pktinfoのヘッダーを<netinet.in.h>から<netinet / ip6.h>に変更(セクション5)。

- Removed the old Sections 5.1 and 5.2, because the interface identification functions went into the basic API.

- インターフェイス識別機能が基本APIに組み込まれたため、古いセクション5.1および5.2を削除しました。

- Redid Section 5 to support the hop limit field.

- ホップ制限フィールドをサポートするためにセクション5をやり直しました。

- New Section 5.4 ("Next Hop Address").

- 新しいセクション5.4(「次ホップアドレス」)。

- New Section 6 ("Flow Labels").

- 新しいセクション6(「フローラベル」)。

- Changed all of Sections 7 and 8 dealing with Hop-by-Hop and Destination options. We now define a set of inet6_option_XXX() functions.

- ホップバイホップおよび宛先オプションを扱うセクション7および8のすべてを変更しました。次に、inet6_option_XXX()関数のセットを定義します。

- Changed header for IPV6_SRCRT_xxx constants from <netinet.in.h> to <netinet/ip6.h> (Section 9).

- IPV6_SRCRT_xxx定数のヘッダーを<netinet.in.h>から<netinet / ip6.h>に変更(セクション9)。

- Add inet6_rthdr_lasthop() function, and fix errors in description of Routing header (Section 9).

- inet6_rthdr_lasthop()関数を追加し、ルーティングヘッダーの説明のエラーを修正します(セクション9)。

- Reworded some of the Routing header descriptions to conform to the terminology in [RFC-1883].

- [RFC-1883]の用語に準拠するように、一部のルーティングヘッダーの説明を書き換えました。

- Added the example from [RFC-1883] for the Routing header (Section 9.9).

- [RFC-1883]のルーティングヘッダーの例を追加しました(セクション9.9)。

- Expanded the example in Section 10 to show multiple options per ancillary data object, and to show the receiver's ancillary data objects.

- セクション10の例を拡張して、補助データオブジェクトごとに複数のオプションを表示し、受信側の補助データオブジェクトを表示しました。

- New Section 11 ("IPv6-Specific Options with IPv4-Mapped IPv6 Addresses").

- 新しいセクション11(「IPv4にマップされたIPv6アドレスを使用したIPv6固有のオプション」)。

- New Section 12 ("rresvport_af").

- 新しいセクション12( "rresvport_af")。

- Redid old Section 10 ("Additional Items") into new Section 13 ("Future Items").

- 古いセクション10(「追加アイテム」)を新しいセクション13(「将来のアイテム」)に変更しました。

16. References
16. 参考文献

[RFC-1883] Deering, S., and R. Hinden, "Internet Protocol, Version 6 (IPv6), Specification", RFC 1883, December 1995.

[RFC-1883] Deering、S。、およびR. Hinden、「インターネットプロトコル、バージョン6(IPv6)、仕様」、RFC 1883、1995年12月。

[RFC-2133] Gilligan, R., Thomson, S., Bound, J., and W. Stevens, "Basic Socket Interface Extensions for IPv6", RFC 2133, April 1997.

[RFC-2133] Gilligan、R.、Thomson、S.、Bound、J.、and W. Stevens、 "Basic Socket Interface Extensions for IPv6"、RFC 2133、April 1997。

[RFC-1981] McCann, J., Deering, S., and J. Mogul, "Path MTU Discovery for IP version 6", RFC 1981, August 1996.

[RFC-1981] McCann、J.、Deering、S。、およびJ. Mogul、「IPバージョン6のPath MTU Discovery」、RFC 1981、1996年8月。

[RFC-1970] Narten, T., Nordmark, E., and W. Simpson, "Neighbor Discovery for IP Version 6 (IPv6)", RFC 1970, August 1996.

[RFC-1970] Narten、T.、Nordmark、E。、およびW. Simpson、「Neighbor Discovery for IP Version 6(IPv6)」、RFC 1970、1996年8月。

17. Acknowledgments
17. 謝辞

Matt Thomas and Jim Bound have been working on the technical details in this draft for over a year. Keith Sklower is the original implementor of ancillary data in the BSD networking code. Craig Metz provided lots of feedback, suggestions, and comments based on his implementing many of these features as the document was being written.

Matt ThomasとJim Boundは、このドラフトの技術的な詳細に1年以上取り組んできました。 Keith Sklowerは、BSDネットワーキングコードの補助データの元の実装者です。 Craig Metzは、ドキュメントの作成中にこれらの機能の多くを実装したことに基づいて、多くのフィードバック、提案、コメントを提供しました。

The following provided comments on earlier drafts: Pascal Anelli, Hamid Asayesh, Ran Atkinson, Karl Auerbach, Hamid Asayesh, Matt Crawford, Sam T. Denton, Richard Draves, Francis Dupont, Bob Gilligan, Tim Hartrick, Masaki Hirabaru, Yoshinobu Inoue, Mukesh Kacker, A. N. Kuznetsov, Pedro Marques, Jack McCann, der Mouse, John Moy, Thomas Narten, Erik Nordmark, Steve Parker, Charles Perkins, Tom Pusateri, Pedro Roque, Sameer Shah, Peter Sjodin, Stephen P. Spackman, Jinmei Tatuya, Karen Tracey, Quaizar Vohra, Carl Williams, Steve Wise, and Kazu Yamamoto.

以下は、以前のドラフトにコメントを提供しました:Pascal Anelli、Hamid Asayesh、Ran Atkinson、Karl Auerbach、Hamid Asayesh、Matt Crawford、Sam T. Denton、Richard Draves、Francis Dupont、Bob Gilligan、Tim Hartrick、Masaki Hirabaru、Yoshinobu Inoue、Mukesh Kacker、AN Kuznetsov、Pedro Marques、Jack McCann、der Mouse、John Moy、Thomas Narten、Erik Nordmark、Steve Parker、Charles Perkins、Tom Pusateri、Pedro Roque、Sameer Shah、Peter Sjodin、Stephen P. Spackman、Jinmei Tatuya、Karen Tracey、Quaizar Vohra、Carl Williams、Steve Wise、Kazu Yamamoto。

18. Authors' Addresses
18. 著者のアドレス

W. Richard Stevens 1202 E. Paseo del Zorro Tucson, AZ 85718

W。 りちゃrd Sてゔぇんs 1202 え。 ぱせお でl ぞっろ つcそん、 あZ 85718

   EMail: rstevens@kohala.com
        

Matt Thomas AltaVista Internet Software LJO2-1/J8 30 Porter Rd Littleton, MA 01460 EMail: matt.thomas@altavista-software.com

Matt Thomas AltaVistaインターネットソフトウェアLJO2-1 / J8 30 Porter Rd Littleton、MA 01460 Eメール:matt.thomas@altavista-software.com

19. 完全な著作権表示

Copyright (C) The Internet Society (1998). All Rights Reserved.

Copyright(C)The Internet Society(1998)。全著作権所有。

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

このドキュメントとその翻訳はコピーして他のユーザーに提供することができ、コメントまたはその他の方法で説明したり、その実装を支援する二次的著作物は、いかなる種類の制限なしに、全体または一部を準備、コピー、公開、および配布することができますただし、上記の著作権表示とこの段落は、そのようなすべてのコピーと派生物に含まれています。ただし、このドキュメント自体は、著作権に関する通知を削除したり、インターネットソサエティや他のインターネット組織への参照を削除したりするなど、いかなる方法でも変更できません。ただし、インターネット標準を開発する目的で必要な場合は除きます。インターネット標準のプロセスに従うか、または必要に応じて、それを英語以外の言語に翻訳する必要があります。

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

上記で付与された制限付きのアクセス許可は永続的であり、インターネットソサエティまたはその後継者または譲受人によって取り消されることはありません。

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

このドキュメントとここに含まれる情報は「現状有姿」で提供され、インターネット社会およびインターネット技術タスクフォースは、明示または黙示を問わず、ここに記載されている情報の使用が保証するものに限定されない一切の保証を含みません。商品性または特定の目的への適合性に関する権利または黙示の保証を侵害すること。