1 /* 2 * This file is part of net-y-unix strace test. 3 * 4 * Copyright (c) 2013-2017 Dmitry V. Levin <ldv (at) altlinux.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "tests.h" 31 #include <assert.h> 32 #include <stddef.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <unistd.h> 37 #include <sys/param.h> 38 #include <sys/socket.h> 39 #include <sys/un.h> 40 41 #define TEST_SOCKET "net-y-unix.socket" 42 43 int 44 main(void) 45 { 46 skip_if_unavailable("/proc/self/fd/"); 47 48 static const struct sockaddr_un addr = { 49 .sun_family = AF_UNIX, 50 .sun_path = TEST_SOCKET 51 }; 52 struct sockaddr * const listen_sa = tail_memdup(&addr, sizeof(addr)); 53 54 TAIL_ALLOC_OBJECT_CONST_PTR(socklen_t, len); 55 *len = offsetof(struct sockaddr_un, sun_path) + strlen(TEST_SOCKET) + 1; 56 if (*len > sizeof(addr)) 57 *len = sizeof(addr); 58 59 int listen_fd = socket(AF_UNIX, SOCK_STREAM, 0); 60 if (listen_fd < 0) 61 perror_msg_and_skip("socket"); 62 unsigned long listen_inode = inode_of_sockfd(listen_fd); 63 printf("socket(AF_UNIX, SOCK_STREAM, 0) = %d<socket:[%lu]>\n", 64 listen_fd, listen_inode); 65 66 (void) unlink(TEST_SOCKET); 67 if (bind(listen_fd, listen_sa, *len)) 68 perror_msg_and_skip("bind"); 69 printf("bind(%d<socket:[%lu]>, {sa_family=AF_UNIX, sun_path=\"%s\"}" 70 ", %u) = 0\n", 71 listen_fd, listen_inode, TEST_SOCKET, (unsigned) *len); 72 73 if (listen(listen_fd, 1)) 74 perror_msg_and_skip("listen"); 75 printf("listen(%d<socket:[%lu]>, 1) = 0\n", listen_fd, listen_inode); 76 77 TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, optval); 78 *len = sizeof(*optval); 79 if (getsockopt(listen_fd, SOL_SOCKET, SO_PASSCRED, optval, len)) 80 perror_msg_and_fail("getsockopt"); 81 printf("getsockopt(%d<socket:[%lu]>, SOL_SOCKET, SO_PASSCRED" 82 ", [%u], [%u]) = 0\n", 83 listen_fd, listen_inode, *optval, (unsigned) *len); 84 85 memset(listen_sa, 0, sizeof(addr)); 86 *len = sizeof(addr); 87 if (getsockname(listen_fd, listen_sa, len)) 88 perror_msg_and_fail("getsockname"); 89 printf("getsockname(%d<socket:[%lu]>, {sa_family=AF_UNIX" 90 ", sun_path=\"%s\"}, [%d->%d]) = 0\n", listen_fd, listen_inode, 91 TEST_SOCKET, (int) sizeof(addr), (int) *len); 92 93 int connect_fd = socket(AF_UNIX, SOCK_STREAM, 0); 94 if (connect_fd < 0) 95 perror_msg_and_fail("socket"); 96 unsigned long connect_inode = inode_of_sockfd(connect_fd); 97 printf("socket(AF_UNIX, SOCK_STREAM, 0) = %d<socket:[%lu]>\n", 98 connect_fd, connect_inode); 99 100 if (connect(connect_fd, listen_sa, *len)) 101 perror_msg_and_fail("connect"); 102 printf("connect(%d<socket:[%lu]>, {sa_family=AF_UNIX" 103 ", sun_path=\"%s\"}, %u) = 0\n", 104 connect_fd, connect_inode, TEST_SOCKET, (unsigned) *len); 105 106 struct sockaddr * const accept_sa = tail_alloc(sizeof(addr)); 107 memset(accept_sa, 0, sizeof(addr)); 108 *len = sizeof(addr); 109 int accept_fd = accept(listen_fd, accept_sa, len); 110 if (accept_fd < 0) 111 perror_msg_and_fail("accept"); 112 unsigned long accept_inode = inode_of_sockfd(accept_fd); 113 printf("accept(%d<socket:[%lu]>, {sa_family=AF_UNIX}" 114 ", [%d->%d]) = %d<socket:[%lu]>\n", 115 listen_fd, listen_inode, 116 (int) sizeof(addr), (int) *len, 117 accept_fd, accept_inode); 118 119 memset(listen_sa, 0, sizeof(addr)); 120 *len = sizeof(addr); 121 if (getpeername(connect_fd, listen_sa, len)) 122 perror_msg_and_fail("getpeername"); 123 printf("getpeername(%d<socket:[%lu]>, {sa_family=AF_UNIX" 124 ", sun_path=\"%s\"}, [%d->%d]) = 0\n", connect_fd, connect_inode, 125 TEST_SOCKET, (int) sizeof(addr), (int) *len); 126 127 char text[] = "text"; 128 assert(sendto(connect_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, 0) 129 == sizeof(text) - 1); 130 printf("sendto(%d<socket:[%lu]>, \"%s\", %u, MSG_DONTWAIT" 131 ", NULL, 0) = %u\n", 132 connect_fd, connect_inode, text, 133 (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1); 134 135 assert(close(connect_fd) == 0); 136 printf("close(%d<socket:[%lu]>) = 0\n", connect_fd, connect_inode); 137 138 assert(recvfrom(accept_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, NULL) 139 == sizeof(text) - 1); 140 printf("recvfrom(%d<socket:[%lu]>, \"%s\", %u, MSG_DONTWAIT" 141 ", NULL, NULL) = %u\n", 142 accept_fd, accept_inode, text, 143 (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1); 144 145 assert(close(accept_fd) == 0); 146 printf("close(%d<socket:[%lu]>) = 0\n", accept_fd, accept_inode); 147 148 connect_fd = socket(AF_UNIX, SOCK_STREAM, 0); 149 if (connect_fd < 0) 150 perror_msg_and_fail("socket"); 151 connect_inode = inode_of_sockfd(connect_fd); 152 printf("socket(AF_UNIX, SOCK_STREAM, 0) = %d<socket:[%lu]>\n", 153 connect_fd, connect_inode); 154 155 *optval = 1; 156 *len = sizeof(*optval); 157 if (setsockopt(connect_fd, SOL_SOCKET, SO_PASSCRED, optval, *len)) 158 perror_msg_and_fail("setsockopt"); 159 printf("setsockopt(%d<socket:[%lu]>, SOL_SOCKET, SO_PASSCRED" 160 ", [%u], %u) = 0\n", 161 connect_fd, connect_inode, *optval, (unsigned) *len); 162 163 memset(listen_sa, 0, sizeof(addr)); 164 *len = sizeof(addr); 165 if (getsockname(listen_fd, listen_sa, len)) 166 perror_msg_and_fail("getsockname"); 167 printf("getsockname(%d<socket:[%lu]>, {sa_family=AF_UNIX" 168 ", sun_path=\"%s\"}, [%d->%d]) = 0\n", 169 listen_fd, listen_inode, TEST_SOCKET, 170 (int) sizeof(addr), (int) *len); 171 172 if (connect(connect_fd, listen_sa, *len)) 173 perror_msg_and_fail("connect"); 174 printf("connect(%d<socket:[%lu]>, {sa_family=AF_UNIX" 175 ", sun_path=\"%s\"}, %u) = 0\n", 176 connect_fd, connect_inode, TEST_SOCKET, (unsigned) *len); 177 178 memset(accept_sa, 0, sizeof(addr)); 179 *len = sizeof(addr); 180 accept_fd = accept(listen_fd, accept_sa, len); 181 if (accept_fd < 0) 182 perror_msg_and_fail("accept"); 183 accept_inode = inode_of_sockfd(accept_fd); 184 const char * const sun_path1 = 185 ((struct sockaddr_un *) accept_sa)->sun_path + 1; 186 printf("accept(%d<socket:[%lu]>, {sa_family=AF_UNIX" 187 ", sun_path=@\"%s\"}, [%d->%d]) = %d<socket:[%lu]>\n", 188 listen_fd, listen_inode, sun_path1, 189 (int) sizeof(addr), (int) *len, 190 accept_fd, accept_inode); 191 192 memset(listen_sa, 0, sizeof(addr)); 193 *len = sizeof(addr); 194 if (getpeername(connect_fd, listen_sa, len)) 195 perror_msg_and_fail("getpeername"); 196 printf("getpeername(%d<socket:[%lu]>, {sa_family=AF_UNIX" 197 ", sun_path=\"%s\"}, [%d->%d]) = 0\n", 198 connect_fd, connect_inode, TEST_SOCKET, 199 (int) sizeof(addr), (int) *len); 200 201 memset(accept_sa, 0, sizeof(addr)); 202 *len = sizeof(addr); 203 if (getsockname(connect_fd, accept_sa, len)) 204 perror_msg_and_fail("getsockname"); 205 printf("getsockname(%d<socket:[%lu]>, {sa_family=AF_UNIX" 206 ", sun_path=@\"%s\"}, [%d->%d]) = 0\n", 207 connect_fd, connect_inode, sun_path1, 208 (int) sizeof(addr), (int) *len); 209 210 assert(sendto(connect_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, 0) 211 == sizeof(text) - 1); 212 printf("sendto(%d<socket:[%lu]>, \"%s\", %u, MSG_DONTWAIT" 213 ", NULL, 0) = %u\n", 214 connect_fd, connect_inode, text, 215 (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1); 216 217 assert(close(connect_fd) == 0); 218 printf("close(%d<socket:[%lu]>) = 0\n", connect_fd, connect_inode); 219 220 assert(recvfrom(accept_fd, text, sizeof(text) - 1, MSG_DONTWAIT, NULL, NULL) 221 == sizeof(text) - 1); 222 printf("recvfrom(%d<socket:[%lu]>, \"%s\", %u, MSG_DONTWAIT" 223 ", NULL, NULL) = %u\n", 224 accept_fd, accept_inode, text, 225 (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1); 226 227 assert(close(accept_fd) == 0); 228 printf("close(%d<socket:[%lu]>) = 0\n", accept_fd, accept_inode); 229 230 assert(unlink(TEST_SOCKET) == 0); 231 232 assert(close(listen_fd) == 0); 233 printf("close(%d<socket:[%lu]>) = 0\n", 234 listen_fd, listen_inode); 235 236 puts("+++ exited with 0 +++"); 237 return 0; 238 } 239