1.\" $NetBSD: CMSG_DATA.3,v 1.2 2008/06/20 14:35:10 christos Exp $ 2.\" $OpenBSD: CMSG_DATA.3,v 1.5 2008/03/24 16:11:07 deraadt Exp $ 3.\" Written by Jared Yanovich <jaredy@openbsd.org> 4.\" Public domain, July 3, 2005 5.Dd June 20, 2008 6.Dt CMSG_DATA 3 7.Os 8.Sh NAME 9.Nm CMSG_DATA , 10.Nm CMSG_FIRSTHDR , 11.Nm CMSG_LEN , 12.Nm CMSG_NXTHDR , 13.Nm CMSG_SPACE 14.Nd socket control message routines 15.Sh SYNOPSIS 16.In sys/socket.h 17.Ft void * 18.Fn CMSG_DATA "struct cmsghdr *" 19.Ft struct cmsghdr * 20.Fn CMSG_FIRSTHDR "struct msghdr *" 21.Ft size_t 22.Fn CMSG_LEN "size_t" 23.Ft struct cmsghdr * 24.Fn CMSG_NXTHDR "struct msghdr *" "struct cmsghdr *" 25.Ft size_t 26.Fn CMSG_SPACE "size_t" 27.Sh DESCRIPTION 28The control message API is used to construct ancillary data objects for 29use in control messages sent and received across sockets. 30.Pp 31Control messages are passed around by the 32.Xr recvmsg 2 33and 34.Xr sendmsg 2 35system calls. 36The 37.Vt cmsghdr 38structure, described in 39.Xr recvmsg 2 , 40is used to specify a chain of control messages. 41.Pp 42These routines should be used instead of directly accessing the control 43message header members and data buffers as they ensure that necessary 44alignment constraints are met. 45.Pp 46The following routines are provided: 47.Bl -tag -width Ds 48.It Fn CMSG_DATA cmsg 49This routine accesses the data portion of the control message header 50.Fa cmsg . 51It ensures proper alignment constraints on the beginning of ancillary 52data are met. 53.It Fn CMSG_FIRSTHDR mhdr 54This routine accesses the first control message attached to the 55message 56.Fa msg . 57If no control messages are attached to the message, this routine 58returns 59.Dv NULL . 60.It Fn CMSG_LEN len 61This routine determines the size in bytes of a control message, 62which includes the control message header. 63.Fa len 64specifies the length of the data held by the control message. 65This value is what is normally stored in the 66.Fa cmsg_len 67of each control message. 68This routine accounts for any alignment constraints on the beginning of 69ancillary data. 70This macro might not evaluate to a compile-time constant. 71.It Fn CMSG_NXTHDR mhdr cmsg 72This routine returns the location of the control message following 73.Fa cmsg 74in the message 75.Fa mhdr . 76If 77.Fa cmsg 78is the last control message in the chain, this routine returns 79.Dv NULL . 80.It Fn CMSG_SPACE len 81This routine determines the size in bytes needed to hold a control 82message and its contents of length 83.Fa len , 84which includes the control message header. 85This value is what is normally stored in 86.Fa msg_msgcontrollen . 87This routine accounts for any alignment constraints on the beginning of 88ancillary data as well as any needed to pad the next control message. 89This macro might not evaluate to a compile-time constant. 90.El 91.Sh EXAMPLES 92The following example constructs a control message containing a file 93descriptor and passes it over a socket: 94.Bd -literal -offset indent 95struct msghdr msg; 96struct cmsghdr *cmsg; 97/* We use a union to make sure hdr is aligned */ 98union { 99 struct cmsghdr hdr; 100 unsigned char buf[CMSG_SPACE(sizeof(int))]; 101} *cmsgbuf; 102 103/* 104 * We allocate in the heap instead of the stack to avoid C99 105 * variable stack allocation, which breaks gcc -fstack-protector. 106 */ 107if ((cmsgbuf = malloc(sizeof(*cmsgbuf))) == NULL) 108 err(1, "malloc"); 109(void)memset(&msg, 0, sizeof(msg)); 110msg.msg_control = cmsgbuf->buf; 111msg.msg_controllen = sizeof(cmsgbuf->buf); 112 113cmsg = CMSG_FIRSTHDR(&msg); 114cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 115cmsg->cmsg_level = SOL_SOCKET; 116cmsg->cmsg_type = SCM_RIGHTS; 117*(int *)CMSG_DATA(cmsg) = fd; 118 119if (sendmsg(s, &msg, 0) == -1) 120 err(1, "sendmsg"); 121free(cmsgbuf); 122.Ed 123.Pp 124And an example that receives and decomposes the control message: 125.Bd -literal -offset indent 126struct msghdr msg; 127struct cmsghdr *cmsg; 128union { 129 struct cmsghdr hdr; 130 unsigned char buf[CMSG_SPACE(sizeof(int))]; 131} *cmsgbuf; 132 133if ((cmsgbuf = malloc(sizeof(*cmsgbuf))) == NULL) 134 err(1, "malloc"); 135(void)memset(&msg, 0, sizeof(msg)); 136msg.msg_control = cmsgbuf->buf; 137msg.msg_controllen = sizeof(cmsgbuf->buf); 138 139if (recvmsg(s, &msg, 0) == -1) 140 err(1, "recvmsg"); 141if ((msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) 142 errx(1, "control message truncated"); 143for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; 144 cmsg = CMSG_NXTHDR(&msg, cmsg)) { 145 if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) && 146 cmsg->cmsg_level == SOL_SOCKET && 147 cmsg->cmsg_type == SCM_RIGHTS) { 148 fd = *(int *)CMSG_DATA(cmsg); 149 /* Do something with the descriptor. */ 150 } 151} 152free(cmsgbuf); 153.Ed 154.Sh SEE ALSO 155.Xr recvmsg 2 , 156.Xr sendmsg 2 , 157.Xr socket 2 158.Sh HISTORY 159The control message API first appeared in 160.Bx 4.2 . 161