Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       CMSG_ALIGN, CMSG_SPACE, CMSG_NXTHDR, CMSG_FIRSTHDR - 補助データにアクセスする。

書式

       #include <sys/socket.h>
       struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *msgh);
       struct cmsghdr *CMSG_NXTHDR(struct msghdr *msgh,
                                   struct cmsghdr *cmsg);
       size_t CMSG_ALIGN(size_t length);
       size_t CMSG_SPACE(size_t length);
       size_t CMSG_LEN(size_t length);
       unsigned char *CMSG_DATA(struct cmsghdr *cmsg);

説明

       これらのマクロは制御メッセージ (補助データ (ancillary data) とも呼ばれる) を作り、 それにアクセスするため
       に使われる。 制御メッセージはソケットにのるデータではない。  この制御情報は、到着したパケットへのインター
       フェイス、様々なあまり     使われないヘッダーフィールド、エラー記述の拡張、ファイルデスクリ    プタの集合
       や、UNIXにおける信頼情報 (credential) を含んでいる。 制御メッセージは、例えば  IP  オプションのような追加
       ヘッダーフィールドを 送るのに使う事ができる。 補助データは、 sendmsg(2) を呼び出して送り、 recvmsg(2)  を
       呼び出して受け取る。 詳細はそれらのマニュアルページを参照。

       補助データは cmsghdr 構造体のシーケンスに追加データが付加されたものである。使用可能な制御メッセージのタイ
       プについては、   それぞれのプロトコルのマニュアルページを参照のこと。接続毎の最大補助用バッファーサイズは
       /proc/sys/net/core/optmem_max を使って設定できる。 socket(7) を参照。

       cmsghdr 構造体は以下のように定義されている。

           struct cmsghdr {
               size_t cmsg_len;    /* Data byte count, including header
                                      (type is socklen_t in POSIX) */
               int    cmsg_level;  /* Originating protocol */
               int    cmsg_type;   /* Protocol-specific type */
           /* followed by
              unsigned char cmsg_data[]; */
           };

       The sequence of cmsghdr structures should never be accessed directly.  Instead, use  only  the  following
       macros:

       *  CMSG_FIRSTHDR()   returns  a pointer to the first cmsghdr in the ancillary data buffer associated with
          the passed msghdr.  It returns NULL if there isn't enough space for a cmsghdr in the buffer.

       *  CMSG_NXTHDR()  は、渡した cmsghdr の次にくる (有効な)  cmsghdr を返す。 バッファーに十分な空きが無い場
          合、NULL を返す。

          When  initializing  a  buffer  that will contain a series of cmsghdr structures (e.g., to be sent with
          sendmsg(2)), that buffer  should  first  be  zero-initialized  to  ensure  the  correct  operation  of
          CMSG_NXTHDR().

       *  CMSG_ALIGN()  に長さを与えると、必要なアラインメントを加味した長さを返してくる。 これは定数式である。

       *  CMSG_SPACE()  は、与えたデータ長が占めるのに必要な補助要素 (ancillary element) の バイト数を返す。これ
          は定数式である。

       *  CMSG_DATA()  returns a pointer to the data portion of a  cmsghdr.   The  pointer  returned  cannot  be
          assumed  to  be  suitably aligned for accessing arbitrary payload data types.  Applications should not
          cast it to a pointer type matching the payload, but should instead use memcpy(3)  to copy data  to  or
          from a suitably declared object.

       *  CMSG_LEN()   は、 cmsghdr 構造体の cmsg_len メンバにデータを格納する際に必要な値を返す。アラインメント
          も考慮に入れ られる。 引数としてデータ長をとる。これは定数式である。

       補助データを作るためには最初に msghdr のメンバー msg_controllen  を、制御メッセージバッファーの長さで初期
       化する。 CMSG_FIRSTHDR()  を msghdr に用いると最初の制御メッセージが得られ、 CMSG_NXTHDR() を使うと次の制
       御メッセージが得られる。 それぞれの制御メッセージでは、 cmsg_len を初期化する (CMSG_LEN()  を使う)。 その
       他の  cmsghdr  ヘッダーフィールド、そしてデータ部分に対しても  CMSG_DATA()  を使って初期化をする。 最後に
       msghdrmsg_controllen フィールドに、バッファー中の制御メッセージの長さの CMSG_SPACE() の合計がセットさ
       れる。 msghdr についての詳細は recvmsg(2)  を参照。

準拠

       This ancillary data model conforms to the POSIX.1g draft, 4.4BSD-Lite, the IPv6 advanced API described in
       RFC 2292 and SUSv2.  CMSG_FIRSTHDR(), CMSG_NXTHDR(), and  CMSG_DATA()   are  specified  in  POSIX.1-2008.
       CMSG_SPACE()  and CMSG_LEN()  will be included in the next POSIX release (Issue 8).

       CMSG_ALIGN()  is a Linux extension.

注意

       移植性のために、補助データへのアクセスには、             ここで述べられているマクロだけを使うべきである。
       CMSG_ALIGN()  は Linux での拡張であり、移植性を考えたプログラムでは使うべきではない。

       In Linux, CMSG_LEN(), CMSG_DATA(), and CMSG_ALIGN()  are constant expressions (assuming their argument is
       constant),  meaning  that these values can be used to declare the size of global variables.  This may not
       be portable, however.

       次のコードは、受け取った補助バッファーから IP_TTL オプションを探すものである。

           struct msghdr msgh;
           struct cmsghdr *cmsg;
           int received_ttl;

           /* Receive auxiliary data in msgh */

           for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
                   cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
               if (cmsg->cmsg_level == IPPROTO_IP
                       && cmsg->cmsg_type == IP_TTL) {
                   memcpy(&receive_ttl, CMSG_DATA(cmsg), sizeof(received_ttl));
                   break;
               }
           }

           if (cmsg == NULL) {
               /* Error: IP_TTL not enabled or small buffer or I/O error */
           }

       以下のコードは、 SCM_RIGHTS を使い、ファイルディスクリプターの配列を UNIX  ドメインソケットを通して送るも
       のである。

           struct msghdr msg = { 0 };
           struct cmsghdr *cmsg;
           int myfds[NUM_FD];  /* Contains the file descriptors to pass */
           char iobuf[1];
           struct iovec io = {
               .iov_base = iobuf,
               .iov_len = sizeof(iobuf)
           };
           union {         /* Ancillary data buffer, wrapped in a union
                              in order to ensure it is suitably aligned */
               char buf[CMSG_SPACE(sizeof(myfds))];
               struct cmsghdr align;
           } u;

           msg.msg_iov = &io;
           msg.msg_iovlen = 1;
           msg.msg_control = u.buf;
           msg.msg_controllen = sizeof(u.buf);
           cmsg = CMSG_FIRSTHDR(&msg);
           cmsg->cmsg_level = SOL_SOCKET;
           cmsg->cmsg_type = SCM_RIGHTS;
           cmsg->cmsg_len = CMSG_LEN(sizeof(myfds));
           memcpy(CMSG_DATA(cmsg), myfds, sizeof(myfds));

関連項目

       recvmsg(2), sendmsg(2)

       RFC 2292

この文書について

       この  man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告
       に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。