18c3bc1afSRobert Watson /*- 28c3bc1afSRobert Watson * Copyright (c) 2008 Robert N. M. Watson 38c3bc1afSRobert Watson * All rights reserved. 48c3bc1afSRobert Watson * 58c3bc1afSRobert Watson * Redistribution and use in source and binary forms, with or without 68c3bc1afSRobert Watson * modification, are permitted provided that the following conditions 78c3bc1afSRobert Watson * are met: 88c3bc1afSRobert Watson * 1. Redistributions of source code must retain the above copyright 98c3bc1afSRobert Watson * notice, this list of conditions and the following disclaimer. 108c3bc1afSRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 118c3bc1afSRobert Watson * notice, this list of conditions and the following disclaimer in the 128c3bc1afSRobert Watson * documentation and/or other materials provided with the distribution. 138c3bc1afSRobert Watson * 148c3bc1afSRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 158c3bc1afSRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 168c3bc1afSRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 178c3bc1afSRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 188c3bc1afSRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 198c3bc1afSRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 208c3bc1afSRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 218c3bc1afSRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 228c3bc1afSRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 238c3bc1afSRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 248c3bc1afSRobert Watson * SUCH DAMAGE. 258c3bc1afSRobert Watson * 268c3bc1afSRobert Watson * $FreeBSD$ 278c3bc1afSRobert Watson */ 288c3bc1afSRobert Watson 298c3bc1afSRobert Watson #include <sys/param.h> 308c3bc1afSRobert Watson #include <sys/socket.h> 31a848550aSRobert Watson #include <sys/un.h> 328c3bc1afSRobert Watson 338c3bc1afSRobert Watson #include <netinet/in.h> 348c3bc1afSRobert Watson 358c3bc1afSRobert Watson #include <arpa/inet.h> 368c3bc1afSRobert Watson 378c3bc1afSRobert Watson #include <err.h> 388c3bc1afSRobert Watson #include <errno.h> 398c3bc1afSRobert Watson #include <fcntl.h> 408c3bc1afSRobert Watson #include <stdio.h> 418c3bc1afSRobert Watson #include <string.h> 428c3bc1afSRobert Watson #include <unistd.h> 438c3bc1afSRobert Watson 448c3bc1afSRobert Watson /* 458c3bc1afSRobert Watson * The UDP code allows transmitting zero-byte datagrams, but are they 468c3bc1afSRobert Watson * received? 478c3bc1afSRobert Watson */ 488c3bc1afSRobert Watson 498c3bc1afSRobert Watson #define THEPORT 9543 /* Arbitrary. */ 508c3bc1afSRobert Watson 518c3bc1afSRobert Watson static void 528c3bc1afSRobert Watson usage(void) 538c3bc1afSRobert Watson { 548c3bc1afSRobert Watson 558c3bc1afSRobert Watson errx(-1, "no arguments allowed\n"); 568c3bc1afSRobert Watson } 578c3bc1afSRobert Watson 58dba96bd9SRobert Watson static void 59dba96bd9SRobert Watson test(int domain, const char *domainstr, struct sockaddr *sa, socklen_t salen) 60dba96bd9SRobert Watson { 61dba96bd9SRobert Watson int sock_send, sock_receive; 62a848550aSRobert Watson ssize_t size; 63dba96bd9SRobert Watson 64dba96bd9SRobert Watson sock_send = socket(domain, SOCK_DGRAM, 0); 65dba96bd9SRobert Watson if (sock_send < 0) 66dba96bd9SRobert Watson err(-1, "socket(%s, SOCK_DGRAM, 0)", domainstr); 67dba96bd9SRobert Watson 68dba96bd9SRobert Watson sock_receive = socket(domain, SOCK_DGRAM, 0); 69dba96bd9SRobert Watson if (sock_receive < 0) 70dba96bd9SRobert Watson err(-1, "socket(%s, SOCK_DGRAM, 0)", domainstr); 71dba96bd9SRobert Watson 72dba96bd9SRobert Watson if (bind(sock_receive, sa, salen) < 0) 73dba96bd9SRobert Watson err(-1, "Protocol %s bind(sock_receive)", domainstr); 74dba96bd9SRobert Watson if (fcntl(sock_receive, F_SETFL, O_NONBLOCK, 1) < 0) 75dba96bd9SRobert Watson err(-1, "Protocll %s fcntl(sock_receive, FL_SETFL, " 76dba96bd9SRobert Watson "O_NONBLOCK)", domainstr); 77dba96bd9SRobert Watson 78dba96bd9SRobert Watson if (connect(sock_send, sa, salen) < 0) 79dba96bd9SRobert Watson err(-1, "Protocol %s connect(sock_send)", domainstr); 80dba96bd9SRobert Watson 81a848550aSRobert Watson size = recv(sock_receive, NULL, 0, 0); 82a848550aSRobert Watson if (size > 0) 83*4039f071SEd Maste errx(-1, "Protocol %s recv(sock_receive, NULL, 0) before: %zd", 84a848550aSRobert Watson domainstr, size); 85a848550aSRobert Watson else if (size < 0) 86dba96bd9SRobert Watson err(-1, "Protocol %s recv(sock_receive, NULL, 0) before", 87dba96bd9SRobert Watson domainstr); 88dba96bd9SRobert Watson 89a848550aSRobert Watson size = send(sock_send, NULL, 0, 0); 90a848550aSRobert Watson if (size < 0) 91dba96bd9SRobert Watson err(-1, "Protocol %s send(sock_send, NULL, 0)", domainstr); 92dba96bd9SRobert Watson 93dba96bd9SRobert Watson (void)sleep(1); 94a848550aSRobert Watson size = recv(sock_receive, NULL, 0, 0); 95a848550aSRobert Watson if (size < 0) 96dba96bd9SRobert Watson err(-1, "Protocol %s recv(sock_receive, NULL, 0) test", 97dba96bd9SRobert Watson domainstr); 98dba96bd9SRobert Watson 99a848550aSRobert Watson size = recv(sock_receive, NULL, 0, 0); 100a848550aSRobert Watson if (size > 0) 101*4039f071SEd Maste errx(-1, "Protocol %s recv(sock_receive, NULL, 0) after: %zd", 102a848550aSRobert Watson domainstr, size); 103a848550aSRobert Watson else if (size < 0) 104dba96bd9SRobert Watson err(-1, "Protocol %s recv(sock_receive, NULL, 0) after", 105dba96bd9SRobert Watson domainstr); 106dba96bd9SRobert Watson } 107dba96bd9SRobert Watson 1088c3bc1afSRobert Watson int 1098c3bc1afSRobert Watson main(int argc, __unused char *argv[]) 1108c3bc1afSRobert Watson { 111a848550aSRobert Watson struct sockaddr_un sun; 112dba96bd9SRobert Watson struct sockaddr_in6 sin6; 1138c3bc1afSRobert Watson struct sockaddr_in sin; 114dba96bd9SRobert Watson struct in6_addr loopback6addr = IN6ADDR_LOOPBACK_INIT; 1158c3bc1afSRobert Watson 1168c3bc1afSRobert Watson if (argc != 1) 1178c3bc1afSRobert Watson usage(); 1188c3bc1afSRobert Watson 1198c3bc1afSRobert Watson bzero(&sin, sizeof(sin)); 1208c3bc1afSRobert Watson sin.sin_len = sizeof(sin); 1218c3bc1afSRobert Watson sin.sin_family = AF_INET; 1228c3bc1afSRobert Watson sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 1238c3bc1afSRobert Watson sin.sin_port = htons(THEPORT); 1248c3bc1afSRobert Watson 125dba96bd9SRobert Watson test(PF_INET, "PF_INET", (struct sockaddr *)&sin, sizeof(sin)); 1268c3bc1afSRobert Watson 127dba96bd9SRobert Watson bzero(&sin6, sizeof(sin6)); 128dba96bd9SRobert Watson sin6.sin6_len = sizeof(sin6); 129dba96bd9SRobert Watson sin6.sin6_family = AF_INET6; 130dba96bd9SRobert Watson sin6.sin6_addr = loopback6addr; 131dba96bd9SRobert Watson sin6.sin6_port = htons(THEPORT); 1328c3bc1afSRobert Watson 133dba96bd9SRobert Watson test(PF_INET6, "PF_INET6", (struct sockaddr *)&sin6, sizeof(sin6)); 1348c3bc1afSRobert Watson 135a848550aSRobert Watson bzero(&sun, sizeof(sun)); 136a848550aSRobert Watson sun.sun_len = sizeof(sun); 137a848550aSRobert Watson sun.sun_family = AF_LOCAL; 138a848550aSRobert Watson strlcpy(sun.sun_path, "/tmp/udpzerosize-socket", sizeof(sun.sun_path)); 139a848550aSRobert Watson if (unlink(sun.sun_path) < 0 && errno != ENOENT) 140a848550aSRobert Watson err(-1, "unlink: %s", sun.sun_path); 141a848550aSRobert Watson 142a848550aSRobert Watson test(PF_LOCAL, "PF_LOCAL", (struct sockaddr *)&sun, sizeof(sun)); 143a848550aSRobert Watson 1448c3bc1afSRobert Watson return (0); 1458c3bc1afSRobert Watson } 146