EN JA
CMSG(3)
CMSG(3) Linux Programmer's Manual CMSG(3)

名前

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

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/optmem_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_NXTHDR() を使うと次の制御メッセージが得られる。それぞれの制御メッセージでは、 cmsg_len を初期化する ( CMSG_LEN() を使う)。その他の cmsghdr ヘッダーフィールド、そしてデータ部分に対しても CMSG_DATA() を使って初期化をする。最後に msghdrmsg_controllen フィールドに、バッファ中の制御メッセージの長さの CMSG_SPACE() の合計がセットされる。 msghdr についての詳細は recvmsg(2) を参照。

制御メッセージバッファが全てのメッセージを納めるのには短すぎる場合、 msghdrmsg_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

この文書について

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