diff options
| author | Andreas Schneider <asn@samba.org> | 2014-01-22 18:45:51 +0100 |
|---|---|---|
| committer | Michael Adam <obnox@samba.org> | 2014-05-21 15:05:35 +0200 |
| commit | c609a8a5547d0d1edc17069bcaf22bbb63802c3b (patch) | |
| tree | 9e81241336acb8189d70811185129b76387951e4 /src | |
| parent | 54d987e1316e058dea7a01853782677eaccef641 (diff) | |
| download | socket_wrapper-c609a8a5547d0d1edc17069bcaf22bbb63802c3b.tar.gz socket_wrapper-c609a8a5547d0d1edc17069bcaf22bbb63802c3b.tar.xz socket_wrapper-c609a8a5547d0d1edc17069bcaf22bbb63802c3b.zip | |
swrap: Add swrap_msghdr_add_cmsghdr().
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
Pair-Programmed-With: Michael Adam <obnox@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Michael Adam <obnox@samba.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/socket_wrapper.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index e1b69fa..d382459 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -2964,6 +2964,77 @@ int ioctl(int s, unsigned long int r, ...) return rc; } +/***************** + * CMSG + *****************/ + +#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL +/** + * @brief Add a cmsghdr to a msghdr. + * + * This is an function to add any type of cmsghdr. It will operate on the + * msg->msg_control and msg->msg_controllen you pass in by adapting them to + * the buffer position after the added cmsg element. Hence, this function is + * intended to be used with an intermediate msghdr and not on the original + * one handed in by the client. + * + * @param[in] msg The msghdr to which to add the cmsg. + * + * @param[in] level The cmsg level to set. + * + * @param[in] type The cmsg type to set. + * + * @param[in] data The cmsg data to set. + * + * @param[in] len the length of the data to set. + */ +static void swrap_msghdr_add_cmsghdr(struct msghdr *msg, + int level, + int type, + const void *data, + size_t len) +{ + size_t cmlen = CMSG_LEN(len); + size_t cmspace = CMSG_SPACE(len); + uint8_t cmbuf[cmspace]; + struct cmsghdr *cm = (struct cmsghdr *)cmbuf; + uint8_t *p; + + memset(cmbuf, 0, cmspace); + + if (msg->msg_controllen < cmlen) { + cmlen = msg->msg_controllen; + msg->msg_flags |= MSG_CTRUNC; + } + + if (msg->msg_controllen < cmspace) { + cmspace = msg->msg_controllen; + } + + /* + * We copy the full input data into an intermediate cmsghdr first + * in order to more easily cope with truncation. + */ + cm->cmsg_len = cmlen; + cm->cmsg_level = level; + cm->cmsg_type = type; + memcpy(CMSG_DATA(cm), data, len); + + /* + * We now copy the possibly truncated buffer. + * We copy cmlen bytes, but consume cmspace bytes, + * leaving the possible padding uninitialiazed. + */ + p = (uint8_t *)msg->msg_control; + memcpy(p, cm, cmlen); + p += cmspace; + msg->msg_control = p; + msg->msg_controllen -= cmspace; + + return; +} +#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ + static ssize_t swrap_sendmsg_before(int fd, struct socket_info *si, struct msghdr *msg, |
