1CMSG(3) Linux Programmer's Manual CMSG(3)
2
3
4
6 CMSG_ALIGN, CMSG_SPACE, CMSG_NXTHDR, CMSG_FIRSTHDR - Access ancillary
7 data
8
10 #include <sys/socket.h>
11
12
13 struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *msgh);
14 struct cmsghdr *CMSG_NXTHDR(struct msghdr *msgh, struct cmsghdr *cmsg);
15 size_t CMSG_ALIGN(size_t length);
16 size_t CMSG_SPACE(size_t length);
17 size_t CMSG_LEN(size_t length);
18 unsigned char *CMSG_DATA(struct cmsghdr *cmsg);
19
20 struct cmsghdr {
21 socklen_t cmsg_len; /* data byte count, including header */
22 int cmsg_level; /* originating protocol */
23 int cmsg_type; /* protocol-specific type */
24 /* followed by unsigned char cmsg_data[]; */
25 };
26
28 These macros are used to create and access control messages (also
29 called ancillary data) that are not a part of the socket payload. This
30 control information may include the interface the packet was received
31 on, various rarely used header fields, an extended error description, a
32 set of file descriptors or Unix credentials. For instance, control
33 messages can be used to send additional header fields such as IP
34 options. Ancillary data is sent by calling sendmsg(2) and received by
35 calling recvmsg(2). See their manual pages for more information.
36
37 Ancillary data is a sequence of struct cmsghdr structures with appended
38 data. This sequence should only be accessed using the macros described
39 in this manual page and never directly. See the specific protocol man
40 pages for the available control message types. The maximum ancillary
41 buffer size allowed per socket can be set using the net.core.optmem_max
42 sysctl; see socket(7).
43
44 CMSG_FIRSTHDR() returns a pointer to the first cmsghdr in the ancillary
45 data buffer associated with the passed msghdr.
46
47 CMSG_NXTHDR() returns the next valid cmsghdr after the passed cmsghdr.
48 It returns NULL when there isn't enough space left in the buffer.
49
50 CMSG_ALIGN(), given a length, returns it including the required align‐
51 ment. This is a constant expression.
52
53 CMSG_SPACE() returns the number of bytes an ancillary element with pay‐
54 load of the passed data length occupies. This is a constant expres‐
55 sion.
56
57 CMSG_DATA returns a pointer to the data portion of a cmsghdr.
58
59 CMSG_LEN returns the value to store in the cmsg_len member of the cms‐
60 ghdr structure, taking into account any necessary alignment. It takes
61 the data length as an argument. This is a constant expression.
62
63 To create ancillary data, first initialize the msg_controllen member of
64 the msghdr with the length of the control message buffer. Use
65 CMSG_FIRSTHDR() on the msghdr to get the first control message and
66 CMSG_NEXTHDR to get all subsequent ones. In each control message, ini‐
67 tialize cmsg_len (with CMSG_LEN), the other cmsghdr header fields, and
68 the data portion using CMSG_DATA. Finally, the msg_controllen field of
69 the msghdr should be set to the sum of the CMSG_SPACE() of the length
70 of all control messages in the buffer. For more information on the
71 msghdr, see recvmsg(2).
72
73 When the control message buffer is too short to store all messages, the
74 MSG_CTRUNC flag is set in the msg_flags member of the msghdr.
75
77 This code looks for the IP_TTL option in a received ancillary buffer:
78
79 struct msghdr msgh;
80 struct cmsghdr *cmsg;
81 int *ttlptr;
82 int received_ttl;
83
84 /* Receive auxiliary data in msgh */
85 for (cmsg = CMSG_FIRSTHDR(&msgh);
86 cmsg != NULL;
87 cmsg = CMSG_NXTHDR(&msgh,cmsg)) {
88 if (cmsg->cmsg_level == IPPROTO_IP
89 && cmsg->cmsg_type == IP_TTL) {
90 ttlptr = (int *) CMSG_DATA(cmsg);
91 received_ttl = *ttlptr;
92 break;
93 }
94 }
95 if (cmsg == NULL) {
96 /*
97 * Error: IP_TTL not enabled or small buffer
98 * or I/O error.
99 */
100 }
101
102 The code below passes an array of file descriptors over a Unix socket
103 using SCM_RIGHTS:
104
105 struct msghdr msg = {0};
106 struct cmsghdr *cmsg;
107 int myfds[NUM_FD]; /* Contains the file descriptors to pass. */
108 char buf[CMSG_SPACE(sizeof myfds)]; /* ancillary data buffer */
109 int *fdptr;
110
111 msg.msg_control = buf;
112 msg.msg_controllen = sizeof buf;
113 cmsg = CMSG_FIRSTHDR(&msg);
114 cmsg->cmsg_level = SOL_SOCKET;
115 cmsg->cmsg_type = SCM_RIGHTS;
116 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD);
117 /* Initialize the payload: */
118 fdptr = (int *)CMSG_DATA(cmsg);
119 memcpy(fdptr, myfds, NUM_FD * sizeof(int));
120 /* Sum of the length of all control messages in the buffer: */
121 msg.msg_controllen = cmsg->cmsg_len;
122
124 For portability, ancillary data should be accessed only using the
125 macros described here. CMSG_ALIGN() is a Linux extension and should be
126 not used in portable programs.
127
128 In Linux, CMSG_LEN, CMSG_DATA, and CMSG_ALIGN() are constant expres‐
129 sions (assuming their argument is constant); this could be used to
130 declare the size of global variables. This may be not portable, how‐
131 ever.
132
134 This ancillary data model conforms to the POSIX.1g draft, 4.4BSD-Lite,
135 the IPv6 advanced API described in RFC 2292 and the SUSv2. CMSG_ALIGN
136 is a Linux extension.
137
139 recvmsg(2), sendmsg(2)
140
141 RFC 2292
142
143
144
145Linux Man Page 1998-10-02 CMSG(3)