Home | History | Annotate | Download | only in tests-mx32
      1 /*
      2  * This file is part of net-yy-inet strace test.
      3  *
      4  * Copyright (c) 2014-2016 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 <string.h>
     35 #include <unistd.h>
     36 #include <sys/socket.h>
     37 #include <netinet/in.h>
     38 #include <netinet/tcp.h>
     39 #include <arpa/inet.h>
     40 
     41 int
     42 main(void)
     43 {
     44 	const struct sockaddr_in addr = {
     45 		.sin_family = AF_INET,
     46 		.sin_addr.s_addr = htonl(INADDR_LOOPBACK)
     47 	};
     48 	struct sockaddr * const listen_sa = tail_memdup(&addr, sizeof(addr));
     49 	socklen_t * const len = tail_alloc(sizeof(socklen_t));
     50 	*len = sizeof(addr);
     51 
     52 	const int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
     53 	if (listen_fd < 0)
     54 		perror_msg_and_skip("socket");
     55 	const unsigned long listen_inode = inode_of_sockfd(listen_fd);
     56 	printf("socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = %d<TCP:[%lu]>\n",
     57 	       listen_fd, listen_inode);
     58 
     59 	if (bind(listen_fd, listen_sa, *len))
     60 		perror_msg_and_skip("bind");
     61 	printf("bind(%d<TCP:[%lu]>, {sa_family=AF_INET, sin_port=htons(0)"
     62 	       ", sin_addr=inet_addr(\"127.0.0.1\")}, %u) = 0\n",
     63 	       listen_fd, listen_inode, (unsigned) *len);
     64 
     65 	if (listen(listen_fd, 1))
     66 		perror_msg_and_skip("listen");
     67 	printf("listen(%d<TCP:[%lu]>, 1) = 0\n", 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_in *) listen_sa) -> sin_port);
     75 	printf("getsockname(%d<TCP:[127.0.0.1:%u]>, {sa_family=AF_INET"
     76 	       ", sin_port=htons(%u), sin_addr=inet_addr(\"127.0.0.1\")}"
     77 	       ", [%u]) = 0\n",
     78 	       listen_fd, listen_port, listen_port, (unsigned) *len);
     79 
     80 	unsigned int * const optval = tail_alloc(sizeof(unsigned int));
     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:[127.0.0.1:%u]>, SOL_TCP, TCP_MAXSEG"
     85 	       ", [%u], [%u]) = 0\n",
     86 	       listen_fd, listen_port, *optval, (unsigned) *len);
     87 
     88 	const int connect_fd = socket(AF_INET, 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_INET, SOCK_STREAM, IPPROTO_IP) = %d<TCP:[%lu]>\n",
     93 	       connect_fd, connect_inode);
     94 
     95 	*len = sizeof(addr);
     96 	if (connect(connect_fd, listen_sa, *len))
     97 		perror_msg_and_fail("connect");
     98 	printf("connect(%d<TCP:[%lu]>, {sa_family=AF_INET, sin_port=htons(%u)"
     99 	       ", sin_addr=inet_addr(\"127.0.0.1\")}, %u) = 0\n",
    100 	       connect_fd, connect_inode, listen_port, (unsigned) *len);
    101 
    102 	struct sockaddr * const accept_sa = tail_alloc(sizeof(addr));
    103 	memset(accept_sa, 0, sizeof(addr));
    104 	*len = sizeof(addr);
    105 	const int accept_fd = accept(listen_fd, accept_sa, len);
    106 	if (accept_fd < 0)
    107 		perror_msg_and_fail("accept");
    108 	const unsigned int connect_port =
    109 		ntohs(((struct sockaddr_in *) accept_sa) -> sin_port);
    110 	printf("accept(%d<TCP:[127.0.0.1:%u]>, {sa_family=AF_INET"
    111 	       ", sin_port=htons(%u), sin_addr=inet_addr(\"127.0.0.1\")}"
    112 	       ", [%u]) = %d<TCP:[127.0.0.1:%u->127.0.0.1:%u]>\n",
    113 	       listen_fd, listen_port, connect_port, (unsigned) *len,
    114 	       accept_fd, listen_port, connect_port);
    115 
    116 	memset(accept_sa, 0, sizeof(addr));
    117 	*len = sizeof(addr);
    118 	if (getpeername(accept_fd, accept_sa, len))
    119 		perror_msg_and_fail("getpeername");
    120 	printf("getpeername(%d<TCP:[127.0.0.1:%u->127.0.0.1:%u]>"
    121 	       ", {sa_family=AF_INET, sin_port=htons(%u)"
    122 	       ", sin_addr=inet_addr(\"127.0.0.1\")}, [%u]) = 0\n",
    123 	       accept_fd, listen_port, connect_port, connect_port,
    124 	       (unsigned) *len);
    125 
    126 	memset(listen_sa, 0, sizeof(addr));
    127 	*len = sizeof(addr);
    128 	if (getpeername(connect_fd, listen_sa, len))
    129 		perror_msg_and_fail("getpeername");
    130 	printf("getpeername(%d<TCP:[127.0.0.1:%u->127.0.0.1:%u]>"
    131 	       ", {sa_family=AF_INET, sin_port=htons(%u)"
    132 	       ", sin_addr=inet_addr(\"127.0.0.1\")}, [%u]) = 0\n",
    133 	       connect_fd, connect_port, listen_port, listen_port,
    134 	       (unsigned) *len);
    135 
    136 	*len = sizeof(*optval);
    137 	if (setsockopt(connect_fd, SOL_TCP, TCP_MAXSEG, optval, *len))
    138 		perror_msg_and_fail("setsockopt");
    139 	printf("setsockopt(%d<TCP:[127.0.0.1:%u->127.0.0.1:%u]>"
    140 	       ", SOL_TCP, TCP_MAXSEG, [%u], %u) = 0\n",
    141 	       connect_fd, connect_port, listen_port, *optval,
    142 	       (unsigned) *len);
    143 
    144 	char text[] = "text";
    145 	assert(sendto(connect_fd, text, sizeof(text) - 1,
    146 	       MSG_DONTROUTE | MSG_DONTWAIT, NULL, 0) == sizeof(text) - 1);
    147 	printf("sendto(%d<TCP:[127.0.0.1:%u->127.0.0.1:%u]>, \"%s\", %u"
    148 	       ", MSG_DONTROUTE|MSG_DONTWAIT, NULL, 0) = %u\n",
    149 	       connect_fd, connect_port, listen_port, text,
    150 	       (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1);
    151 
    152 	assert(close(connect_fd) == 0);
    153 	printf("close(%d<TCP:[127.0.0.1:%u->127.0.0.1:%u]>) = 0\n",
    154 	       connect_fd, connect_port, listen_port);
    155 
    156 	assert(recvfrom(accept_fd, text, sizeof(text) - 1, MSG_WAITALL,
    157 			NULL, NULL) == sizeof(text) - 1);
    158 	printf("recvfrom(%d<TCP:[127.0.0.1:%u->127.0.0.1:%u]>, \"%s\", %u"
    159 	       ", MSG_WAITALL, NULL, NULL) = %u\n",
    160 	       accept_fd, listen_port, connect_port, text,
    161 	       (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1);
    162 
    163 	assert(close(accept_fd) == 0);
    164 	printf("close(%d<TCP:[127.0.0.1:%u->127.0.0.1:%u]>) = 0\n",
    165 	       accept_fd, listen_port, connect_port);
    166 
    167 	assert(close(listen_fd) == 0);
    168 	printf("close(%d<TCP:[127.0.0.1:%u]>) = 0\n",
    169 	       listen_fd, listen_port);
    170 
    171 	puts("+++ exited with 0 +++");
    172 	return 0;
    173 }
    174