cmsgのヘルプ・マニュアル
日本語 英語
cmsg --help
man cmsg
CMSG(3) Linux Programmer’s Manual CMSG(3)
名前
CMSG_ALIGN, CMSG_SPACE, CMSG_NXTHDR, CMSG_FIRSTHDR - 補助データにアクセ
スする。
書式
#include
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);
struct cmsghdr {
socklen_t cmsg_len; /* data byte count, including header */
int cmsg_level; /* originating protocol */
int cmsg_type; /* protocol-specific type */
/* followed by unsigned char cmsg_data[]; */
};
説明
こ れらのマクロは制御メッセージ (補助データ (ancillary data) とも呼ばれ
る) を作り、それにアクセスするために使われる。制御メッセージはソケッ ト
に のるデータではない。この制御情報は、到着したパケットへのインターフェ
イス、様々なあまり使われないヘッダーフィールド、エラー記述の拡張、フ ァ
イ ルデスクリプタの集合や、Unixにおける信頼情報 (credential) を含んでい
る。制御メッセージは、例えば IP オプションのような追加ヘッダーフィー ル
ド を送るのに使う事ができる。補助データは、 sendmsg(2) を呼び出して送り
、 recvmsg(2) を呼び出して受け取る。詳細はそれらのマニュアルページを 参
照。
補 助データは struct cmsghdr 構造体のシーケンスに追加データが付加された
ものである。このシーケンスにはこのマニュアルページに書かれているマク ロ
を 使ってアクセスすべきで、直接アクセスすべきではない。使用可能な制御メ
ッセージのタイプについては、それぞれのプロトコルのマニュアルページを 参
照 の こ と。接続毎の最大補助用バッファサイズは /proc/sys/net/core/opt-
mem_max を使って設定できる。 socket(7) を参照。
CMSG_FIRSTHDR() は、渡した msghdr に関連した補助データバッファ中の、 最
初の cmsghdr へのポインタを返す。
CMSG_NXTHDR() は、渡した cmsghdr の次にくる (有効な) cmsghdr を返す。バ
ッファに十分な空きが無い場合、NULL を返す。
CMSG_ALIGN() に長さを与えると、必要なアラインメントを加味した長さを返し
てくる。これは定数式である。
CMSG_SPACE() は 、与えたデータ長が占めるのに必要な補助要素 (ancillary
element) のバイト数を返す。これは定数式である。
CMSG_DATA() は、 cmsghdr のデータ部分へのポインタを返す。
CMSG_LEN() は、 cmsghdr 構造体の cmsg_len メンバにデータを格納する際 に
必 要な値を返す。アラインメントも考慮に入れられる。引数としてデータ長を
とる。これは定数式である。
補助データを作るためには最初に msghdr のメンバー msg_controllen を、 制
御メッセージバッファの長さで初期化する。 CMSG_FIRSTHDR() を msghdr に用
いると最初の制御メッセージが得られ、 CMSG_NEXTHDR() を使うと次の制御 メ
ッ セージが得られる。それぞれの制御メッセージでは、 cmsg_len を初期化す
る (CMSG_LEN() を使う)。その他の cmsghdr ヘッダーフィールド、そしてデー
タ 部 分 に 対しても CMSG_DATA() を使って初期化をする。最後に msghdr の
msg_controllen フィールドに、バッファ中の制御メ ッ セ ー ジ の 長 さ の
CMSG_SPACE() の合計がセットされる。 msghdr についての詳細は recvmsg(2)
を参照。
制御メッセージバッファが全てのメッセージを納めるのには短すぎる 場 合 、
msghdr の msg_flags メンバーに MSG_CTRUNC フラグがセットされる。
準拠
こ の補助データモデルは、POSIX.1g draft, 4.4BSD-Lite, RFC 2292 に記述さ
れている IPv6 advanced API, そして SUSv2 に準拠している。 CMSG_ALIGN()
は Linux の拡張である。
注意
移 植性のために、補助データへのアクセスには、ここで述べられているマクロ
を使うだけにすべきである。 CMSG_ALIGN() は Linux での拡張であり、移植性
を考えたプログラムでは使うべきではない。
Linux では CMSG_LEN(), CMSG_DATA(), CMSG_ALIGN() は定数式である (それら
の引数が定数とみなされる)。このことは、大域変数のサイズを宣言するのに使
える。しかし移植性はなくなるだろう。
例
次 のコードは、受け取った補助バッファから IP_TTL オプションを探すもので
ある。
struct msghdr msgh;
struct cmsghdr *cmsg;
int *ttlptr;
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) {
ttlptr = (int *) CMSG_DATA(cmsg);
received_ttl = *ttlptr;
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 buf[CMSG_SPACE(sizeof myfds)]; /* ancillary data buffer */
int *fdptr;
msg.msg_control = buf;
msg.msg_controllen = sizeof buf;
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD);
/* Initialize the payload: */
fdptr = (int *) CMSG_DATA(cmsg);
memcpy(fdptr, myfds, NUM_FD * sizeof(int));
/* Sum of the length of all control messages in the buffer: */
msg.msg_controllen = cmsg->cmsg_len;
関連項目
recvmsg(2), sendmsg(2)
RFC 2292
Linux 2008-11-20 CMSG(3)
CMSG(3) Linux Programmer’s Manual CMSG(3)
NAME
CMSG_ALIGN, CMSG_SPACE, CMSG_NXTHDR, CMSG_FIRSTHDR - Access ancillary
data
SYNOPSIS
#include
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);
struct cmsghdr {
socklen_t cmsg_len; /* data byte count, including header */
int cmsg_level; /* originating protocol */
int cmsg_type; /* protocol-specific type */
/* followed by unsigned char cmsg_data[]; */
};
DESCRIPTION
These macros are used to create and access control messages (also
called ancillary data) that are not a part of the socket payload. This
control information may include the interface the packet was received
on, various rarely used header fields, an extended error description, a
set of file descriptors or Unix credentials. For instance, control
messages can be used to send additional header fields such as IP
options. Ancillary data is sent by calling sendmsg(2) and received by
calling recvmsg(2). See their manual pages for more information.
Ancillary data is a sequence of struct cmsghdr structures with appended
data. This sequence should only be accessed using the macros described
in this manual page and never directly. See the specific protocol man
pages for the available control message types. The maximum ancillary
buffer size allowed per socket can be set using /proc/sys/net/core/opt-
mem_max; see socket(7).
CMSG_FIRSTHDR() returns a pointer to the first cmsghdr in the ancillary
data buffer associated with the passed msghdr.
CMSG_NXTHDR() returns the next valid cmsghdr after the passed cmsghdr.
It returns NULL when there isn’t enough space left in the buffer.
CMSG_ALIGN(), given a length, returns it including the required align-
ment. This is a constant expression.
CMSG_SPACE() returns the number of bytes an ancillary element with pay-
load of the passed data length occupies. This is a constant expres-
sion.
CMSG_DATA() returns a pointer to the data portion of a cmsghdr.
CMSG_LEN() returns the value to store in the cmsg_len member of the
cmsghdr structure, taking into account any necessary alignment. It
takes the data length as an argument. This is a constant expression.
To create ancillary data, first initialize the msg_controllen member of
the msghdr with the length of the control message buffer. Use
CMSG_FIRSTHDR() on the msghdr to get the first control message and
CMSG_NEXTHDR() to get all subsequent ones. In each control message,
initialize cmsg_len (with CMSG_LEN()), the other cmsghdr header fields,
and the data portion using CMSG_DATA(). Finally, the msg_controllen
field of the msghdr should be set to the sum of the CMSG_SPACE() of the
length of all control messages in the buffer. For more information on
the msghdr, see recvmsg(2).
When the control message buffer is too short to store all messages, the
MSG_CTRUNC flag is set in the msg_flags member of the msghdr.
CONFORMING TO
This ancillary data model conforms to the POSIX.1g draft, 4.4BSD-Lite,
the IPv6 advanced API described in RFC 2292 and the SUSv2.
CMSG_ALIGN() is a Linux extension.
NOTES
For portability, ancillary data should be accessed only using the
macros described here. CMSG_ALIGN() is a Linux extension and should be
not used in portable programs.
In Linux, CMSG_LEN(), CMSG_DATA(), and CMSG_ALIGN() are constant
expressions (assuming their argument is constant); this could be used
to declare the size of global variables. This may be not portable,
however.
EXAMPLE
This code looks for the IP_TTL option in a received ancillary buffer:
struct msghdr msgh;
struct cmsghdr *cmsg;
int *ttlptr;
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) {
ttlptr = (int *) CMSG_DATA(cmsg);
received_ttl = *ttlptr;
break;
}
}
if (cmsg == NULL) {
/*
* Error: IP_TTL not enabled or small buffer
* or I/O error.
*/
}
The code below passes an array of file descriptors over a Unix socket
using SCM_RIGHTS:
struct msghdr msg = {0};
struct cmsghdr *cmsg;
int myfds[NUM_FD]; /* Contains the file descriptors to pass. */
char buf[CMSG_SPACE(sizeof myfds)]; /* ancillary data buffer */
int *fdptr;
msg.msg_control = buf;
msg.msg_controllen = sizeof buf;
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD);
/* Initialize the payload: */
fdptr = (int *) CMSG_DATA(cmsg);
memcpy(fdptr, myfds, NUM_FD * sizeof(int));
/* Sum of the length of all control messages in the buffer: */
msg.msg_controllen = cmsg->cmsg_len;
SEE ALSO
recvmsg(2), sendmsg(2)
RFC 2292
COLOPHON
This page is part of release 3.22 of the Linux man-pages project. A
description of the project, and information about reporting bugs, can
be found at http://www.kernel.org/doc/man-pages/.
Linux 2008-11-20 CMSG(3)