(root)/
strace-6.5/
tests/
net-yy-inet.c
       1  /*
       2   * This file is part of net-yy-inet strace test.
       3   *
       4   * Copyright (c) 2014-2016 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2016-2023 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include <assert.h>
      13  #include <fcntl.h>
      14  #include <stddef.h>
      15  #include <stdio.h>
      16  #include <string.h>
      17  #include <unistd.h>
      18  #include <sys/socket.h>
      19  #include <netinet/in.h>
      20  #include <netinet/tcp.h>
      21  #include <arpa/inet.h>
      22  
      23  #ifndef ADDR_FAMILY
      24  # define ADDR_FAMILY_FIELD sin_family
      25  # define ADDR_FAMILY AF_INET
      26  # define AF_STR "AF_INET"
      27  # define LOOPBACK_FIELD .sin_addr.s_addr = htonl(INADDR_LOOPBACK)
      28  # define LOOPBACK "127.0.0.1"
      29  # define SOCKADDR_TYPE sockaddr_in
      30  # define TCP_STR "TCP"
      31  # define INPORT sin_port
      32  # define INPORT_STR "sin_port"
      33  # define INADDR_STR "sin_addr=inet_addr(\"" LOOPBACK "\")"
      34  # define SA_FIELDS ""
      35  #endif
      36  
      37  int
      38  main(void)
      39  {
      40  	skip_if_unavailable("/proc/self/fd/");
      41  
      42  	const struct SOCKADDR_TYPE addr = {
      43  		.ADDR_FAMILY_FIELD = ADDR_FAMILY,
      44  		LOOPBACK_FIELD
      45  	};
      46  	struct sockaddr * const listen_sa = tail_memdup(&addr, sizeof(addr));
      47  	TAIL_ALLOC_OBJECT_CONST_PTR(socklen_t, len);
      48  	*len = sizeof(addr);
      49  
      50  	const int listen_fd = socket(ADDR_FAMILY, SOCK_STREAM, 0);
      51  	if (listen_fd < 0)
      52  		perror_msg_and_skip("socket");
      53  	const unsigned long listen_inode = inode_of_sockfd(listen_fd);
      54  	printf("socket(" AF_STR ", SOCK_STREAM, IPPROTO_IP) = %d<" TCP_STR
      55  	       ":[%lu]>\n",
      56  	       listen_fd, listen_inode);
      57  
      58  	if (bind(listen_fd, listen_sa, *len))
      59  		perror_msg_and_skip("bind");
      60  	printf("bind(%d<" TCP_STR ":[%lu]>, {sa_family=" AF_STR ", " INPORT_STR
      61  	       "=htons(0), " INADDR_STR SA_FIELDS "}, %u) = 0\n",
      62  	       listen_fd, listen_inode, (unsigned) *len);
      63  
      64  	if (listen(listen_fd, 1))
      65  		perror_msg_and_skip("listen");
      66  	printf("listen(%d<" TCP_STR ":[%lu]>, 1) = 0\n",
      67  	       listen_fd, listen_inode);
      68  
      69  	memset(listen_sa, 0, sizeof(addr));
      70  	*len = sizeof(addr);
      71  	if (getsockname(listen_fd, listen_sa, len))
      72  		perror_msg_and_fail("getsockname");
      73  	const unsigned int listen_port =
      74  		ntohs(((struct SOCKADDR_TYPE *) listen_sa)->INPORT);
      75  	printf("getsockname(%d<" TCP_STR ":[" LOOPBACK ":%u]>, {sa_family="
      76  	       AF_STR ", " INPORT_STR "=htons(%u), " INADDR_STR SA_FIELDS "}"
      77  	       ", [%u]) = 0\n",
      78  	       listen_fd, listen_port, listen_port, (unsigned) *len);
      79  
      80  	TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, optval);
      81  	*len = sizeof(*optval);
      82  	if (getsockopt(listen_fd, SOL_TCP, TCP_MAXSEG, optval, len))
      83  		perror_msg_and_fail("getsockopt");
      84  	printf("getsockopt(%d<" TCP_STR ":[" LOOPBACK ":%u]>, SOL_TCP, "
      85  	       "TCP_MAXSEG, [%u], [%u]) = 0\n",
      86  	       listen_fd, listen_port, *optval, (unsigned) *len);
      87  
      88  	const int connect_fd = socket(ADDR_FAMILY, SOCK_STREAM, 0);
      89  	if (connect_fd < 0)
      90  		perror_msg_and_fail("socket");
      91  	const unsigned long connect_inode = inode_of_sockfd(connect_fd);
      92  	printf("socket(" AF_STR ", SOCK_STREAM, IPPROTO_IP) = %d<" TCP_STR
      93  	       ":[%lu]>\n",
      94  	       connect_fd, connect_inode);
      95  
      96  	*len = sizeof(addr);
      97  	if (connect(connect_fd, listen_sa, *len))
      98  		perror_msg_and_fail("connect");
      99  	printf("connect(%d<" TCP_STR ":[%lu]>, {sa_family=" AF_STR ", "
     100  	       INPORT_STR "=htons(%u), " INADDR_STR SA_FIELDS "}, %u) = 0\n",
     101  	       connect_fd, connect_inode, listen_port, (unsigned) *len);
     102  
     103  	struct sockaddr * const accept_sa = tail_alloc(sizeof(addr));
     104  	memset(accept_sa, 0, sizeof(addr));
     105  	*len = sizeof(addr);
     106  	const int accept_fd = accept4(listen_fd, accept_sa, len, O_CLOEXEC);
     107  	if (accept_fd < 0)
     108  		perror_msg_and_fail("accept");
     109  	const unsigned int connect_port =
     110  		ntohs(((struct SOCKADDR_TYPE *) accept_sa)->INPORT);
     111  	printf("accept4(%d<" TCP_STR ":[" LOOPBACK ":%u]>, {sa_family=" AF_STR
     112  	       ", " INPORT_STR "=htons(%u), " INADDR_STR SA_FIELDS "}, [%u]"
     113  	       ", SOCK_CLOEXEC) = %d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK
     114  	       ":%u]>\n",
     115  	       listen_fd, listen_port, connect_port, (unsigned) *len,
     116  	       accept_fd, listen_port, connect_port);
     117  
     118  	memset(accept_sa, 0, sizeof(addr));
     119  	*len = sizeof(addr);
     120  	if (getpeername(accept_fd, accept_sa, len))
     121  		perror_msg_and_fail("getpeername");
     122  	printf("getpeername(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>"
     123  	       ", {sa_family=" AF_STR ", " INPORT_STR "=htons(%u)"
     124  	       ", " INADDR_STR SA_FIELDS "}, [%u]) = 0\n",
     125  	       accept_fd, listen_port, connect_port, connect_port,
     126  	       (unsigned) *len);
     127  
     128  	memset(listen_sa, 0, sizeof(addr));
     129  	*len = sizeof(addr);
     130  	if (getpeername(connect_fd, listen_sa, len))
     131  		perror_msg_and_fail("getpeername");
     132  	printf("getpeername(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>"
     133  	       ", {sa_family=" AF_STR ", " INPORT_STR "=htons(%u)"
     134  	       ", " INADDR_STR SA_FIELDS "}, [%u]) = 0\n",
     135  	       connect_fd, connect_port, listen_port, listen_port,
     136  	       (unsigned) *len);
     137  
     138  	*len = sizeof(*optval);
     139  	if (setsockopt(connect_fd, SOL_TCP, TCP_MAXSEG, optval, *len))
     140  		perror_msg_and_fail("setsockopt");
     141  	printf("setsockopt(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>"
     142  	       ", SOL_TCP, TCP_MAXSEG, [%u], %u) = 0\n",
     143  	       connect_fd, connect_port, listen_port, *optval,
     144  	       (unsigned) *len);
     145  
     146  	char text[] = "text";
     147  	assert(sendto(connect_fd, text, sizeof(text) - 1,
     148  	       MSG_DONTROUTE | MSG_DONTWAIT, NULL, 0) == sizeof(text) - 1);
     149  	printf("sendto(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>, "
     150  	       "\"%s\", %u, MSG_DONTROUTE|MSG_DONTWAIT, NULL, 0) = %u\n",
     151  	       connect_fd, connect_port, listen_port, text,
     152  	       (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1);
     153  
     154  	assert(close(connect_fd) == 0);
     155  	printf("close(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>) = "
     156  	       "0\n",
     157  	       connect_fd, connect_port, listen_port);
     158  
     159  	assert(recvfrom(accept_fd, text, sizeof(text) - 1, MSG_WAITALL,
     160  			NULL, NULL) == sizeof(text) - 1);
     161  	printf("recvfrom(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>, "
     162  	       "\"%s\", %u, MSG_WAITALL, NULL, NULL) = %u\n",
     163  	       accept_fd, listen_port, connect_port, text,
     164  	       (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1);
     165  
     166  	assert(close(accept_fd) == 0);
     167  	printf("close(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>) = "
     168  	       "0\n",
     169  	       accept_fd, listen_port, connect_port);
     170  
     171  	assert(close(listen_fd) == 0);
     172  	printf("close(%d<" TCP_STR ":[" LOOPBACK ":%u]>) = 0\n",
     173  	       listen_fd, listen_port);
     174  
     175  	puts("+++ exited with 0 +++");
     176  	return 0;
     177  }