17555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin/* 27555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * Check decoding of struct msghdr ancillary data. 37555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * 47555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org> 539bac055674d23770b9a724221b728e443196ea7Elliott Hughes * Copyright (c) 2016-2017 The strace developers. 67555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * All rights reserved. 77555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * 87555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * Redistribution and use in source and binary forms, with or without 97555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * modification, are permitted provided that the following conditions 107555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * are met: 117555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * 1. Redistributions of source code must retain the above copyright 127555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * notice, this list of conditions and the following disclaimer. 137555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * 2. Redistributions in binary form must reproduce the above copyright 147555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * notice, this list of conditions and the following disclaimer in the 157555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * documentation and/or other materials provided with the distribution. 167555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * 3. The name of the author may not be used to endorse or promote products 177555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * derived from this software without specific prior written permission. 187555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * 197555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 207555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 217555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 227555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 237555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 247555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 257555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 267555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 277555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 287555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 297555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin */ 307555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 317555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#include "tests.h" 327555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#include <errno.h> 338da9668b1ba68ec71ad4d3dd96f9c73ca38430caDmitry V. Levin#include <limits.h> 347555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#include <stddef.h> 357555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#include <stdio.h> 367555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#include <string.h> 377555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#include <unistd.h> 387555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#include <sys/socket.h> 397555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#include <net/if.h> 407555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#include <netinet/in.h> 417555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#include <arpa/inet.h> 427555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 43dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes#include "xlat.h" 44dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes#include "xlat/scmvals.h" 45dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 467555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#ifndef SOL_IP 477555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin# define SOL_IP 0 487555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#endif 497555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#ifndef SOL_TCP 507555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin# define SOL_TCP 6 517555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#endif 527555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 537555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#ifndef SCM_SECURITY 547555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin# define SCM_SECURITY 3 557555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#endif 567555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 577555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#define MIN_SIZE_OF(type, member) \ 587555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (offsetof(type, member) + sizeof(((type *) 0)->member)) 597555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 607555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic struct cmsghdr * 617555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinget_cmsghdr(void *const page, const size_t len) 627555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 637555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin return page - CMSG_ALIGN(len); 647555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 657555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 667555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 677555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinprint_fds(const struct cmsghdr *const cmsg, const size_t cmsg_len) 687555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 697555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin size_t nfd = cmsg_len > CMSG_LEN(0) 707555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ? (cmsg_len - CMSG_LEN(0)) / sizeof(int) : 0; 717555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (!nfd) 727555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin return; 737555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 747555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf(", cmsg_data=["); 757555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int *fdp = (int *) CMSG_DATA(cmsg); 767555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin size_t i; 777555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin for (i = 0; i < nfd; ++i) { 787555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (i) 797555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf(", "); 80074c630705aa65f0795209a0e8ce954520226e57Dmitry V. Levin#if !VERBOSE 81d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin if (i >= DEFAULT_STRLEN) { 82d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin printf("..."); 83d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin break; 84d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin } 85d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin#endif 867555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("%d", fdp[i]); 877555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin } 887555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("]"); 897555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 907555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 917555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 927555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_scm_rights1(struct msghdr *const mh, 937555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const size_t msg_controllen, 947555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin void *const page, 957555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const void *const src, 967555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const size_t cmsg_len) 977555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 987555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const size_t aligned_cms_len = 997555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len > CMSG_LEN(0) ? CMSG_ALIGN(cmsg_len) : CMSG_LEN(0); 1007555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (cmsg_len >= CMSG_LEN(0) 1017555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin && aligned_cms_len + CMSG_LEN(0) <= msg_controllen) 1027555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin return; 1037555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1047555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct cmsghdr *cmsg = get_cmsghdr(page, msg_controllen); 1057555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1067555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (msg_controllen >= MIN_SIZE_OF(struct cmsghdr, cmsg_len)) 1077555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_len = cmsg_len; 1087555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (msg_controllen >= MIN_SIZE_OF(struct cmsghdr, cmsg_level)) 1097555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_level = SOL_SOCKET; 1107555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (msg_controllen >= MIN_SIZE_OF(struct cmsghdr, cmsg_type)) 1117555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_type = SCM_RIGHTS; 1127555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1137555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin size_t src_len = 1147555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len < msg_controllen ? cmsg_len : msg_controllen; 1157555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (src_len > CMSG_LEN(0)) 1167555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin memcpy(CMSG_DATA(cmsg), src, src_len - CMSG_LEN(0)); 1177555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1187555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_control = cmsg; 1197555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_controllen = msg_controllen; 1207555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1217555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int rc = sendmsg(-1, mh, 0); 1227555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int saved_errno = errno; 1237555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1247555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 1257555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_iovlen=0"); 1267555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (msg_controllen < CMSG_LEN(0)) { 1277555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (msg_controllen) 1287555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf(", msg_control=%p", cmsg); 1297555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin } else { 1307555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf(", msg_control=[{cmsg_len=%lu, cmsg_level=SOL_SOCKET" 1317555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", cmsg_type=SCM_RIGHTS", (unsigned long) cmsg_len); 1327555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin print_fds(cmsg, src_len); 1337555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("}"); 1347555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (aligned_cms_len < msg_controllen) 1357555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf(", %p", (void *) cmsg + aligned_cms_len); 1367555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("]"); 1377555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin } 1387555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1397555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin errno = saved_errno; 1407555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf(", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n", 1417555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned long) msg_controllen, rc, errno2name()); 1427555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 1437555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1447555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 1457555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_scm_rights2(struct msghdr *const mh, 1467555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const size_t msg_controllen, 1477555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin void *const page, 1487555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const int *const *const src, 1497555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const size_t *const cmsg_len) 1507555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 1517555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const size_t aligned_cms_len[2] = { 1527555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len[0] > CMSG_LEN(0) ? CMSG_ALIGN(cmsg_len[0]) : CMSG_LEN(0), 1537555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len[1] > CMSG_LEN(0) ? CMSG_ALIGN(cmsg_len[1]) : CMSG_LEN(0) 1547555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin }; 1557555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (cmsg_len[0] < CMSG_LEN(0) 1567555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin || aligned_cms_len[0] + CMSG_LEN(0) > msg_controllen 1577555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin || aligned_cms_len[0] + aligned_cms_len[1] + CMSG_LEN(0) <= msg_controllen) 1587555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin return; 1597555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1607555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct cmsghdr *const cmsg[2] = { 1617555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin get_cmsghdr(page, msg_controllen), 1627555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (void *) get_cmsghdr(page, msg_controllen) + aligned_cms_len[0] 1637555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin }; 1647555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg[0]->cmsg_len = cmsg_len[0]; 1657555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg[0]->cmsg_level = SOL_SOCKET; 1667555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg[0]->cmsg_type = SCM_RIGHTS; 1677555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (cmsg_len[0] > CMSG_LEN(0)) 1687555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin memcpy(CMSG_DATA(cmsg[0]), src[0], cmsg_len[0] - CMSG_LEN(0)); 1697555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1707555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const size_t msg_controllen1 = msg_controllen - aligned_cms_len[0]; 1717555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (msg_controllen1 >= MIN_SIZE_OF(struct cmsghdr, cmsg_len)) 1727555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg[1]->cmsg_len = cmsg_len[1]; 1737555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (msg_controllen >= MIN_SIZE_OF(struct cmsghdr, cmsg_level)) 1747555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg[1]->cmsg_level = SOL_SOCKET; 1757555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (msg_controllen >= MIN_SIZE_OF(struct cmsghdr, cmsg_type)) 1767555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg[1]->cmsg_type = SCM_RIGHTS; 1777555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin size_t src1_len = 1787555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len[1] < msg_controllen1 ? cmsg_len[1] : msg_controllen1; 1797555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (src1_len > CMSG_LEN(0)) 1807555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin memcpy(CMSG_DATA(cmsg[1]), src[1], src1_len - CMSG_LEN(0)); 1817555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1827555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_control = cmsg[0]; 1837555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_controllen = msg_controllen; 1847555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1857555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int rc = sendmsg(-1, mh, 0); 1867555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int saved_errno = errno; 1877555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 1887555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 1897555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_iovlen=0, msg_control=[{cmsg_len=%lu" 1907555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS", 1917555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned long) cmsg_len[0]); 1927555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin print_fds(cmsg[0], cmsg_len[0]); 1937555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("}, {cmsg_len=%lu, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS", 1947555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned long) cmsg_len[1]); 1957555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin print_fds(cmsg[1], src1_len); 1967555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("}"); 1977555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (aligned_cms_len[1] < msg_controllen1) 1987555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf(", %p", (void *) cmsg[1] + aligned_cms_len[1]); 1997555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("]"); 2007555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 2017555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin errno = saved_errno; 2027555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf(", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n", 2037555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned long) msg_controllen, rc, errno2name()); 2047555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 2057555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 2067555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 207d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levintest_scm_rights3(struct msghdr *const mh, void *const page, const size_t nfds) 208d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin{ 209d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin const size_t len = CMSG_SPACE(sizeof(int) * nfds); 210d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin struct cmsghdr *cmsg = get_cmsghdr(page, len); 211d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin 212d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin cmsg->cmsg_len = CMSG_LEN(sizeof(int) * nfds); 213d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin cmsg->cmsg_level = SOL_SOCKET; 214d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin cmsg->cmsg_type = SCM_RIGHTS; 215d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin int *fdp = (int *) CMSG_DATA(cmsg); 216d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin size_t i; 217d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin for (i = 0; i < nfds; ++i) 218d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin fdp[i] = i; 219d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin 220d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin mh->msg_control = cmsg; 221d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin mh->msg_controllen = len; 222d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin 223d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin int rc = sendmsg(-1, mh, 0); 224d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 225d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin ", msg_iovlen=0, msg_control=[{cmsg_len=%u" 226d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS", 227d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin (unsigned) cmsg->cmsg_len); 228d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin print_fds(cmsg, cmsg->cmsg_len); 229d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin printf("}], msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n", 230d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin (unsigned long) len, rc, errno2name()); 231d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin} 232d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin 233d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levinstatic void 234dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughestest_scm_timestamp(struct msghdr *const mh, void *const page) 235dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes{ 236dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes size_t len = CMSG_SPACE(sizeof(struct timeval)); 237dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes struct cmsghdr *cmsg = get_cmsghdr(page, len); 238dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 239dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_len = CMSG_LEN(sizeof(struct timeval)); 240dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_level = SOL_SOCKET; 241dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_type = SCM_TIMESTAMP; 242dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes struct timeval *tv = (struct timeval *) CMSG_DATA(cmsg); 243dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes tv->tv_sec = 123456789; 244dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes tv->tv_usec = 987654; 245dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 246dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes mh->msg_control = cmsg; 247dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes mh->msg_controllen = len; 248dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 249dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes int rc = sendmsg(-1, mh, 0); 250dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 251dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", msg_iovlen=0, msg_control=[{cmsg_len=%u" 252dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_TIMESTAMP" 253dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", cmsg_data={tv_sec=%lld, tv_usec=%llu}}]" 254dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n", 255dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned) cmsg->cmsg_len, 256dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec), 257dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned long) len, rc, errno2name()); 258dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 259dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes len = CMSG_SPACE(sizeof(struct timeval) - sizeof(long)); 260dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg = get_cmsghdr(page, len); 261dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 262dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_len = CMSG_LEN(sizeof(struct timeval) - sizeof(long)); 263dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_level = SOL_SOCKET; 264dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_type = SCM_TIMESTAMP; 265dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 266dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes mh->msg_control = cmsg; 267dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes mh->msg_controllen = len; 268dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 269dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes rc = sendmsg(-1, mh, 0); 270dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 271dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", msg_iovlen=0, msg_control=[{cmsg_len=%u" 272dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_TIMESTAMP, cmsg_data=?}]" 273dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n", 274dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned) cmsg->cmsg_len, 275dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned long) len, rc, errno2name()); 276dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes} 277dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 278dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughesstatic void 279dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughestest_scm_timestampns(struct msghdr *const mh, void *const page) 280dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes{ 281dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes size_t len = CMSG_SPACE(sizeof(struct timespec)); 282dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes struct cmsghdr *cmsg = get_cmsghdr(page, len); 283dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 284dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_len = CMSG_LEN(sizeof(struct timespec)); 285dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_level = SOL_SOCKET; 286dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_type = SCM_TIMESTAMPNS; 287dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes struct timespec *ts = (struct timespec *) CMSG_DATA(cmsg); 288dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ts->tv_sec = 123456789; 289dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ts->tv_nsec = 987654321; 290dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 291dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes mh->msg_control = cmsg; 292dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes mh->msg_controllen = len; 293dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 294dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes int rc = sendmsg(-1, mh, 0); 295dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 296dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", msg_iovlen=0, msg_control=[{cmsg_len=%u" 297dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_TIMESTAMPNS" 298dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", cmsg_data={tv_sec=%lld, tv_nsec=%llu}}]" 299dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n", 300dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned) cmsg->cmsg_len, 301dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec), 302dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned long) len, rc, errno2name()); 303dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 304dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes len = CMSG_SPACE(sizeof(struct timespec) - sizeof(long)); 305dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg = get_cmsghdr(page, len); 306dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 307dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_len = CMSG_LEN(sizeof(struct timespec) - sizeof(long)); 308dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_level = SOL_SOCKET; 309dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_type = SCM_TIMESTAMPNS; 310dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 311dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes mh->msg_control = cmsg; 312dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes mh->msg_controllen = len; 313dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 314dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes rc = sendmsg(-1, mh, 0); 315dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 316dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", msg_iovlen=0, msg_control=[{cmsg_len=%u" 317dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_TIMESTAMPNS" 318dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", cmsg_data=?}]" 319dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n", 320dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned) cmsg->cmsg_len, 321dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned long) len, rc, errno2name()); 322dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes} 323dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 324dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughesstatic void 325dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughestest_scm_timestamping(struct msghdr *const mh, void *const page) 326dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes{ 327dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes size_t len = CMSG_SPACE(3 * sizeof(struct timespec)); 328dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes struct cmsghdr *cmsg = get_cmsghdr(page, len); 329dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 330dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_len = CMSG_LEN(3 * sizeof(struct timespec)); 331dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_level = SOL_SOCKET; 332dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_type = SCM_TIMESTAMPING; 333dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes struct timespec *ts = (struct timespec *) CMSG_DATA(cmsg); 334dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ts[0].tv_sec = 123456789; 335dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ts[0].tv_nsec = 987654321; 336dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ts[1].tv_sec = 123456790; 337dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ts[1].tv_nsec = 987654320; 338dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ts[2].tv_sec = 123456791; 339dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ts[2].tv_nsec = 987654319; 340dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 341dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes mh->msg_control = cmsg; 342dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes mh->msg_controllen = len; 343dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 344dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes int rc = sendmsg(-1, mh, 0); 345dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 346dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", msg_iovlen=0, msg_control=[{cmsg_len=%u" 347dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_TIMESTAMPING" 348dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", cmsg_data=[{tv_sec=%lld, tv_nsec=%llu}" 349dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", {tv_sec=%lld, tv_nsec=%llu}, {tv_sec=%lld, tv_nsec=%llu}]}]" 350dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n", 351dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned) cmsg->cmsg_len, (long long) ts[0].tv_sec, 352dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes zero_extend_signed_to_ull(ts[0].tv_nsec), 353dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (long long) ts[1].tv_sec, 354dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes zero_extend_signed_to_ull(ts[1].tv_nsec), 355dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (long long) ts[2].tv_sec, 356dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes zero_extend_signed_to_ull(ts[2].tv_nsec), 357dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned long) len, rc, errno2name()); 358dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 359dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes len = CMSG_SPACE(3 * sizeof(struct timespec) - sizeof(long)); 360dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg = get_cmsghdr(page, len); 361dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 362dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_len = CMSG_LEN(3 * sizeof(struct timespec) - sizeof(long)); 363dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_level = SOL_SOCKET; 364dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes cmsg->cmsg_type = SCM_TIMESTAMPING; 365dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 366dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes mh->msg_control = cmsg; 367dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes mh->msg_controllen = len; 368dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 369dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes rc = sendmsg(-1, mh, 0); 370dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 371dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", msg_iovlen=0, msg_control=[{cmsg_len=%u" 372dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_TIMESTAMPING" 373dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", cmsg_data=?}]" 374dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes ", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n", 375dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned) cmsg->cmsg_len, 376dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned long) len, rc, errno2name()); 377dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes} 378dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 379dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughesstatic void 3807555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinprint_security(const struct cmsghdr *const cmsg, const size_t cmsg_len) 3817555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 3827555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int n = cmsg_len > CMSG_LEN(0) ? cmsg_len - CMSG_LEN(0) : 0; 3837555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (!n) 3847555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin return; 3857555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 3867555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf(", cmsg_data=\"%.*s\"", n, CMSG_DATA(cmsg)); 3877555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 3887555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 3897555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 3907555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_scm_security(struct msghdr *const mh, 3917555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const size_t msg_controllen, 3927555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin void *const page, 3937555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const void *const src, 3947555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const size_t cmsg_len, 3957555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const int cmsg_level, 3967555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const char *const cmsg_level_str) 3977555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 3987555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const size_t aligned_cms_len = 3997555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len > CMSG_LEN(0) ? CMSG_ALIGN(cmsg_len) : CMSG_LEN(0); 4007555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (cmsg_len >= CMSG_LEN(0) 4017555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin && aligned_cms_len + CMSG_LEN(0) <= msg_controllen) 4027555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin return; 4037555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4047555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct cmsghdr *cmsg = get_cmsghdr(page, msg_controllen); 4057555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4067555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_len = cmsg_len; 4077555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_level = cmsg_level; 4087555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_type = SCM_SECURITY; 4097555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4107555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin size_t src_len = 4117555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len < msg_controllen ? cmsg_len : msg_controllen; 4127555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (src_len > CMSG_LEN(0)) 4137555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin memcpy(CMSG_DATA(cmsg), src, src_len - CMSG_LEN(0)); 4147555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4157555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_control = cmsg; 4167555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_controllen = msg_controllen; 4177555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4187555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int rc = sendmsg(-1, mh, 0); 4197555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int saved_errno = errno; 4207555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4217555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 4227555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_iovlen=0, msg_control=[{cmsg_len=%lu, cmsg_level=%s" 4237555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", cmsg_type=SCM_SECURITY", 4247555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned long) cmsg_len, cmsg_level_str); 4257555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin print_security(cmsg, src_len); 4267555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("}"); 4277555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (aligned_cms_len < msg_controllen) 4287555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf(", %p", (void *) cmsg + aligned_cms_len); 4297555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("]"); 4307555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4317555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin errno = saved_errno; 4327555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf(", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n", 4337555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned long) msg_controllen, rc, errno2name()); 4347555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 4357555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4367555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 4377555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_unknown_type(struct msghdr *const mh, 4387555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin void *const page, 4397555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const int cmsg_level, 4407555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const char *const cmsg_level_str, 4417555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const char *const cmsg_type_str) 4427555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 4437555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct cmsghdr *cmsg = get_cmsghdr(page, CMSG_LEN(0)); 4447555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4457555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_len = CMSG_LEN(0); 4467555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_level = cmsg_level; 4477555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_type = 0xfacefeed; 4487555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4497555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_control = cmsg; 4507555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_controllen = cmsg->cmsg_len; 4517555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4527555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int rc = sendmsg(-1, mh, 0); 4537555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 4547555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_iovlen=0, msg_control=[{cmsg_len=%u, cmsg_level=%s" 4557555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", cmsg_type=%#x /* %s */}], msg_controllen=%u, msg_flags=0}" 4567555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", 0) = %d %s (%m)\n", 4577555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned) cmsg->cmsg_len, cmsg_level_str, cmsg->cmsg_type, 4587555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_type_str, (unsigned) mh->msg_controllen, rc, errno2name()); 4597555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 4607555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4617555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 4627555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_sol_socket(struct msghdr *const mh, void *const page) 4637555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 4647555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin static const int fds0[] = { -10, -11, -12, -13 }; 4657555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin static const int fds1[] = { -15, -16, -17, -18 }; 4667555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin size_t msg_controllen, max_msg_controllen; 4677555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4687555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin max_msg_controllen = CMSG_SPACE(sizeof(fds0)) + sizeof(*fds0) - 1; 4697555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin for (msg_controllen = 0; 4707555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin msg_controllen <= max_msg_controllen; 4717555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin msg_controllen++) { 4727555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin size_t cmsg_len; 4737555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4747555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin for (cmsg_len = 0; 4757555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len <= msg_controllen + CMSG_LEN(0); 4767555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len++) { 4777555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin test_scm_rights1(mh, msg_controllen, 4787555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin page, fds0, cmsg_len); 4797555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin } 4807555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin } 4817555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4827555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin max_msg_controllen = 4837555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin CMSG_SPACE(sizeof(fds0)) + CMSG_SPACE(sizeof(fds1)) + 4847555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin sizeof(*fds0) - 1; 4857555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin for (msg_controllen = CMSG_LEN(0) * 2; 4867555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin msg_controllen <= max_msg_controllen; 4877555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin msg_controllen++) { 4887555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin static const int *const fdps[] = { fds0, fds1 }; 4897555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin size_t cmsg_len[2]; 4907555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4917555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin for (cmsg_len[0] = CMSG_LEN(0); 4927555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin CMSG_ALIGN(cmsg_len[0]) + CMSG_LEN(0) <= msg_controllen 4937555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin && CMSG_ALIGN(cmsg_len[0]) <= CMSG_SPACE(sizeof(fds0)); 4947555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len[0]++) { 4957555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const size_t msg_controllen1 = 4967555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin msg_controllen - CMSG_ALIGN(cmsg_len[0]); 4977555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 4987555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin for (cmsg_len[1] = 0; 4997555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len[1] <= msg_controllen1 + CMSG_LEN(0); 5007555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len[1]++) { 5017555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin test_scm_rights2(mh, msg_controllen, 5027555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin page, fdps, cmsg_len); 5037555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin } 5047555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin } 5057555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin } 5067555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5077555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin static const char text[16] = "0123456789abcdef"; 5087555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin max_msg_controllen = CMSG_SPACE(sizeof(text)) + CMSG_LEN(0) - 1; 5097555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin for (msg_controllen = CMSG_LEN(0); 5107555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin msg_controllen <= max_msg_controllen; 5117555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin msg_controllen++) { 5127555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin size_t cmsg_len; 5137555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5147555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin for (cmsg_len = 0; 5157555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len <= msg_controllen + CMSG_LEN(0) 5167555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin && cmsg_len <= CMSG_LEN(sizeof(text)); 5177555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg_len++) { 5187555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin test_scm_security(mh, msg_controllen, 5197555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin page, text, cmsg_len, 520d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes ARG_STR(SOL_SOCKET)); 5217555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin } 5227555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin } 5237555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 524d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin test_scm_rights3(mh, page, DEFAULT_STRLEN - 1); 525d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin test_scm_rights3(mh, page, DEFAULT_STRLEN); 526d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin test_scm_rights3(mh, page, DEFAULT_STRLEN + 1); 527d35d5ecc4d8ac1bd3617e6f5f85ca738041130ebDmitry V. Levin 528dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes test_scm_timestamp(mh, page); 529dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes test_scm_timestampns(mh, page); 530dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes test_scm_timestamping(mh, page); 531dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 532d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_unknown_type(mh, page, ARG_STR(SOL_SOCKET), "SCM_???"); 5337555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 5347555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5357555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 5367555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_ip_pktinfo(struct msghdr *const mh, void *const page, 537dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes const int cmsg_type, const char *const cmsg_type_str) 5387555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 5397555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const unsigned int len = CMSG_SPACE(sizeof(struct in_pktinfo)); 5407555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct cmsghdr *const cmsg = get_cmsghdr(page, len); 5417555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5427555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); 5437555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_level = SOL_IP; 5447555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_type = cmsg_type; 5457555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5467555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct in_pktinfo *const info = (struct in_pktinfo *) CMSG_DATA(cmsg); 54777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes info->ipi_ifindex = ifindex_lo(); 5487555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin info->ipi_spec_dst.s_addr = inet_addr("1.2.3.4"); 5497555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin info->ipi_addr.s_addr = inet_addr("5.6.7.8"); 5507555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5517555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_control = cmsg; 5527555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_controllen = len; 5537555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5547555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int rc = sendmsg(-1, mh, 0); 5557555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 5567555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_iovlen=0, msg_control=[{cmsg_len=%u, cmsg_level=SOL_IP" 5577555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", cmsg_type=%s, cmsg_data={ipi_ifindex=%s" 5587555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", ipi_spec_dst=inet_addr(\"%s\")" 5597555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", ipi_addr=inet_addr(\"%s\")}}]" 5607555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_controllen=%u, msg_flags=0}, 0) = %d %s (%m)\n", 5617555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned) cmsg->cmsg_len, cmsg_type_str, 56277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes IFINDEX_LO_STR, "1.2.3.4", "5.6.7.8", len, rc, errno2name()); 5637555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 5647555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5657555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 5667555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_ip_uint(struct msghdr *const mh, void *const page, 5677555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const int cmsg_type, const char *const cmsg_type_str) 5687555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 5697555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const unsigned int len = CMSG_SPACE(sizeof(int)); 5707555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct cmsghdr *const cmsg = get_cmsghdr(page, len); 5717555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5727555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 5737555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_level = SOL_IP; 5747555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_type = cmsg_type; 5757555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5767555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin unsigned int *u = (void *) CMSG_DATA(cmsg); 5777555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin *u = 0xfacefeed; 5787555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5797555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_control = cmsg; 5807555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_controllen = len; 5817555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5827555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int rc = sendmsg(-1, mh, 0); 5837555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 5847555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_iovlen=0, msg_control=[{cmsg_len=%u" 5857555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", cmsg_level=SOL_IP, cmsg_type=%s, cmsg_data=[%u]}]" 5867555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_controllen=%u, msg_flags=0}, 0) = %d %s (%m)\n", 5877555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned) cmsg->cmsg_len, cmsg_type_str, *u, len, 5887555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin rc, errno2name()); 5897555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 5907555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5917555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 5927555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_ip_uint8_t(struct msghdr *const mh, void *const page, 593dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes const int cmsg_type, const char *const cmsg_type_str) 5947555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 5957555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const unsigned int len = CMSG_SPACE(1); 5967555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct cmsghdr *const cmsg = get_cmsghdr(page, len); 5977555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 5987555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_len = CMSG_LEN(1); 5997555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_level = SOL_IP; 6007555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_type = cmsg_type; 6017555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin *CMSG_DATA(cmsg) = 'A'; 6027555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6037555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_control = cmsg; 6047555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_controllen = len; 6057555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6067555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int rc = sendmsg(-1, mh, 0); 6077555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 6087555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_iovlen=0, msg_control=[{cmsg_len=%u" 6097555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", cmsg_level=SOL_IP, cmsg_type=%s, cmsg_data=[%#x]}]" 6107555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_controllen=%u, msg_flags=0}, 0) = %d %s (%m)\n", 6117555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned) cmsg->cmsg_len, cmsg_type_str, 6127555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned) (uint8_t) 'A', len, rc, errno2name()); 6137555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 6147555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6157555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 6167555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinprint_ip_opts(const void *const cmsg_data, const unsigned int data_len) 6177555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 6187555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const unsigned char *const opts = cmsg_data; 6197555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin unsigned int i; 6207555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin for (i = 0; i < data_len; ++i) { 6217555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin if (i) 6227555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf(", "); 623074c630705aa65f0795209a0e8ce954520226e57Dmitry V. Levin#if !VERBOSE 62467135824fe8f1a78349e5297bf0db323925376ecDmitry V. Levin if (i >= DEFAULT_STRLEN) { 62567135824fe8f1a78349e5297bf0db323925376ecDmitry V. Levin printf("..."); 62667135824fe8f1a78349e5297bf0db323925376ecDmitry V. Levin break; 62767135824fe8f1a78349e5297bf0db323925376ecDmitry V. Levin } 62867135824fe8f1a78349e5297bf0db323925376ecDmitry V. Levin#endif 6297555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("0x%02x", opts[i]); 6307555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin } 6317555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 6327555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6337555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 6347555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_ip_opts(struct msghdr *const mh, void *const page, 6357555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const int cmsg_type, const char *const cmsg_type_str, 6367555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const unsigned int opts_len) 6377555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 6387555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin unsigned int len = CMSG_SPACE(opts_len); 6397555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct cmsghdr *cmsg = get_cmsghdr(page, len); 6407555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6417555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_len = CMSG_LEN(opts_len); 6427555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_level = SOL_IP; 6437555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_type = cmsg_type; 6447555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin unsigned int i; 6457555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin for (i = 0; i < opts_len; ++i) 6467555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin CMSG_DATA(cmsg)[i] = 'A' + i; 6477555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6487555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_control = cmsg; 6497555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_controllen = len; 6507555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6517555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int rc = sendmsg(-1, mh, 0); 6527555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 6537555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_iovlen=0, msg_control=[{cmsg_len=%u" 6547555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", cmsg_level=SOL_IP, cmsg_type=%s, cmsg_data=[", 6557555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned) cmsg->cmsg_len, cmsg_type_str); 6567555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin print_ip_opts(CMSG_DATA(cmsg), opts_len); 6577555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("]}], msg_controllen=%u, msg_flags=0}, 0) = %d %s (%m)\n", 6587555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin len, rc, errno2name()); 6597555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 6607555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6617555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#ifdef IP_CHECKSUM 6627555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstruct sock_ee { 6637555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin uint32_t ee_errno; 6647555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin uint8_t ee_origin; 6657555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin uint8_t ee_type; 6667555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin uint8_t ee_code; 6677555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin uint8_t ee_pad; 6687555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin uint32_t ee_info; 6697555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin uint32_t ee_data; 6707555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct sockaddr_in offender; 6717555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin}; 6727555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6737555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 6747555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_ip_recverr(struct msghdr *const mh, void *const page, 675dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes const int cmsg_type, const char *const cmsg_type_str) 6767555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 6777555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const unsigned int len = CMSG_SPACE(sizeof(struct sock_ee)); 6787555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct cmsghdr *const cmsg = get_cmsghdr(page, len); 6797555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6807555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_len = CMSG_LEN(sizeof(struct sock_ee)); 6817555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_level = SOL_IP; 6827555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_type = cmsg_type; 6837555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6847555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct sock_ee *const e = (struct sock_ee *) CMSG_DATA(cmsg); 6857555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin e->ee_errno = 0xdeadbeef; 6867555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin e->ee_origin = 2; 6877555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin e->ee_type = 3; 6887555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin e->ee_code = 4; 6897555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin e->ee_info = 0xfacefeed; 6907555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin e->ee_data = 0xbadc0ded; 6917555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin e->offender.sin_family = AF_INET, 6927555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin e->offender.sin_port = htons(12345), 6937555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin e->offender.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 6947555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6957555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_control = cmsg; 6967555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_controllen = len; 6977555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 6987555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int rc = sendmsg(-1, mh, 0); 6997555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 7007555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_iovlen=0, msg_control=[{cmsg_len=%u, cmsg_level=SOL_IP" 7017555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", cmsg_type=%s, cmsg_data={ee_errno=%u, ee_origin=%u" 7027555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", ee_type=%u, ee_code=%u, ee_info=%u, ee_data=%u" 7037555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", offender={sa_family=AF_INET, sin_port=htons(%hu)" 7047555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", sin_addr=inet_addr(\"127.0.0.1\")}}}]" 7057555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_controllen=%u, msg_flags=0}, 0) = %d %s (%m)\n", 7067555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned) cmsg->cmsg_len, cmsg_type_str, 7077555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin e->ee_errno, e->ee_origin, e->ee_type, 7087555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin e->ee_code, e->ee_info, e->ee_data, 7097555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ntohs(e->offender.sin_port), 7107555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin len, rc, errno2name()); 7117555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 7127555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#endif 7137555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 7147555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#ifdef IP_ORIGDSTADDR 7157555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 7167555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_ip_origdstaddr(struct msghdr *const mh, void *const page, 7177555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const int cmsg_type, const char *const cmsg_type_str) 7187555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 7197555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin const unsigned int len = CMSG_SPACE(sizeof(struct sockaddr_in)); 7207555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct cmsghdr *const cmsg = get_cmsghdr(page, len); 7217555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 7227555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_len = CMSG_LEN(sizeof(struct sockaddr_in)); 7237555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_level = SOL_IP; 7247555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_type = cmsg_type; 7257555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 7267555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct sockaddr_in *const sin = (struct sockaddr_in *) CMSG_DATA(cmsg); 7277555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin sin->sin_family = AF_INET, 7287555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin sin->sin_port = htons(12345), 7297555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK); 7307555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 7317555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_control = cmsg; 7327555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_controllen = len; 7337555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 7347555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int rc = sendmsg(-1, mh, 0); 7357555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 7367555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_iovlen=0, msg_control=[{cmsg_len=%u, cmsg_level=SOL_IP" 7377555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", cmsg_type=%s, cmsg_data={sa_family=AF_INET" 7387555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", sin_port=htons(%hu), sin_addr=inet_addr(\"127.0.0.1\")}}]" 7397555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_controllen=%u, msg_flags=0}, 0) = %d %s (%m)\n", 7407555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned) cmsg->cmsg_len, cmsg_type_str, 7417555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ntohs(sin->sin_port), len, rc, errno2name()); 7427555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 7437555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#endif 7447555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 7457555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 7467555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_sol_ip(struct msghdr *const mh, void *const page) 7477555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 748d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_pktinfo(mh, page, ARG_STR(IP_PKTINFO)); 749d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_uint(mh, page, ARG_STR(IP_TTL)); 750d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_uint8_t(mh, page, ARG_STR(IP_TOS)); 751d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_opts(mh, page, ARG_STR(IP_RECVOPTS), 1); 752d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_opts(mh, page, ARG_STR(IP_RECVOPTS), 2); 753d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_opts(mh, page, ARG_STR(IP_RECVOPTS), 3); 754d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_opts(mh, page, ARG_STR(IP_RECVOPTS), 4); 755d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), 5); 756d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), 6); 757d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), 7); 758d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), 8); 759d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), DEFAULT_STRLEN - 1); 760d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), DEFAULT_STRLEN); 761d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), DEFAULT_STRLEN + 1); 7627555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#ifdef IP_CHECKSUM 763d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_recverr(mh, page, ARG_STR(IP_RECVERR)); 7647555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#endif 7657555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#ifdef IP_ORIGDSTADDR 766d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_origdstaddr(mh, page, ARG_STR(IP_ORIGDSTADDR)); 7677555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#endif 7687555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#ifdef IP_CHECKSUM 769d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_ip_uint(mh, page, ARG_STR(IP_CHECKSUM)); 7707555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin#endif 7717555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin test_scm_security(mh, CMSG_LEN(0), page, 0, CMSG_LEN(0), 772d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes ARG_STR(SOL_IP)); 773d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes test_unknown_type(mh, page, ARG_STR(SOL_IP), "IP_???"); 7747555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 7757555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 7767555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinstatic void 7777555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levintest_unknown_level(struct msghdr *const mh, void *const page) 7787555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 7797555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin struct cmsghdr *cmsg = get_cmsghdr(page, CMSG_LEN(0)); 7807555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 7817555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_len = CMSG_LEN(0); 7827555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_level = SOL_TCP; 7837555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin cmsg->cmsg_type = 0xdeadbeef; 7847555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 7857555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_control = cmsg; 7867555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_controllen = cmsg->cmsg_len; 7877555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 7887555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int rc = sendmsg(-1, mh, 0); 7897555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 7907555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_iovlen=0, msg_control=[{cmsg_len=%u, cmsg_level=%s" 7917555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", cmsg_type=%#x}], msg_controllen=%u, msg_flags=0}" 7927555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", 0) = %d %s (%m)\n", 7937555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned) cmsg->cmsg_len, "SOL_TCP", cmsg->cmsg_type, 7947555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin (unsigned) mh->msg_controllen, rc, errno2name()); 7957555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 7967555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 797bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levinstatic void 798bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levintest_big_len(struct msghdr *const mh) 799bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin{ 800bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin int optmem_max; 801bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin 802bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin if (read_int_from_file("/proc/sys/net/core/optmem_max", &optmem_max) 803bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin || optmem_max <= 0 || optmem_max > 0x100000) 8048da9668b1ba68ec71ad4d3dd96f9c73ca38430caDmitry V. Levin optmem_max = sizeof(long long) * (2 * IOV_MAX + 512); 805bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin optmem_max = (optmem_max + sizeof(long long) - 1) 806bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin & ~(sizeof(long long) - 1); 807bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin 808bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin const size_t len = optmem_max * 2; 809bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin struct cmsghdr *const cmsg = tail_alloc(len); 810bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin cmsg->cmsg_len = len; 811bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin cmsg->cmsg_level = SOL_SOCKET; 812bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin cmsg->cmsg_type = SCM_RIGHTS; 813bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin 814bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin mh->msg_control = cmsg; 815bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin mh->msg_controllen = len; 816bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin 817bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin int rc = sendmsg(-1, mh, 0); 818bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin if (EBADF != errno) 819bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin perror_msg_and_skip("sendmsg"); 820bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin 821bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 822bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin ", msg_iovlen=0, msg_control=[{cmsg_len=%u" 823bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS", 824bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin (unsigned) cmsg->cmsg_len); 825bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin print_fds(cmsg, optmem_max); 826bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin printf("}, ...], msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n", 827bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin (unsigned long) len, rc, errno2name()); 828bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin} 829bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin 8307555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levinint main(int ac, const char **av) 8317555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin{ 8327555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin int rc = sendmsg(-1, 0, 0); 8337555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, NULL, 0) = %d %s (%m)\n", rc, errno2name()); 8347555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 83539bac055674d23770b9a724221b728e443196ea7Elliott Hughes TAIL_ALLOC_OBJECT_CONST_PTR(struct msghdr, mh); 8367555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin memset(mh, 0, sizeof(*mh)); 837bf2698a6b8fa9e78e82ec2acaeef39273e95ab17Dmitry V. Levin test_big_len(mh); 8387555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 8397555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin rc = sendmsg(-1, mh + 1, 0); 8407555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, %p, 0) = %d %s (%m)\n", 8417555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh + 1, rc, errno2name()); 8427555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 8437555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin void *page = tail_alloc(1) + 1; 8447555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_control = page; 8457555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin mh->msg_controllen = CMSG_LEN(0); 8467555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin rc = sendmsg(-1, mh, 0); 8477555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL" 8487555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_iovlen=0, msg_control=%p, msg_controllen=%u" 8497555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin ", msg_flags=0}, 0) = %d %s (%m)\n", 8507555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin page, (unsigned) CMSG_LEN(0), rc, errno2name()); 8517555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 8527555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin test_sol_socket(mh, page); 8537555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin test_sol_ip(mh, page); 8547555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin test_unknown_level(mh, page); 8557555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin 8567555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin puts("+++ exited with 0 +++"); 8577555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin return 0; 8587555ffc39063b620243d2a1ed367a9d1f4a7203bDmitry V. Levin} 859