名前
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 メンバにデータを格納する際に必要な値を返す。アラインメントも考慮に入れ られる。 引数としてデータ長をとる。これは定数式である。
準拠
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/ に書かれている。2020-11-01 | Linux |