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> 318c3bc1afSRobert Watson 328c3bc1afSRobert Watson #include <netinet/in.h> 338c3bc1afSRobert Watson 348c3bc1afSRobert Watson #include <arpa/inet.h> 358c3bc1afSRobert Watson 368c3bc1afSRobert Watson #include <err.h> 378c3bc1afSRobert Watson #include <errno.h> 388c3bc1afSRobert Watson #include <fcntl.h> 398c3bc1afSRobert Watson #include <stdio.h> 408c3bc1afSRobert Watson #include <string.h> 418c3bc1afSRobert Watson #include <unistd.h> 428c3bc1afSRobert Watson 438c3bc1afSRobert Watson /* 448c3bc1afSRobert Watson * The UDP code allows transmitting zero-byte datagrams, but are they 458c3bc1afSRobert Watson * received? 468c3bc1afSRobert Watson */ 478c3bc1afSRobert Watson 488c3bc1afSRobert Watson #define THEPORT 9543 /* Arbitrary. */ 498c3bc1afSRobert Watson 508c3bc1afSRobert Watson static void 518c3bc1afSRobert Watson usage(void) 528c3bc1afSRobert Watson { 538c3bc1afSRobert Watson 548c3bc1afSRobert Watson errx(-1, "no arguments allowed\n"); 558c3bc1afSRobert Watson } 568c3bc1afSRobert Watson 57dba96bd9SRobert Watson static void 58dba96bd9SRobert Watson test(int domain, const char *domainstr, struct sockaddr *sa, socklen_t salen) 59dba96bd9SRobert Watson { 60dba96bd9SRobert Watson int sock_send, sock_receive; 61dba96bd9SRobert Watson 62dba96bd9SRobert Watson sock_send = socket(domain, SOCK_DGRAM, 0); 63dba96bd9SRobert Watson if (sock_send < 0) 64dba96bd9SRobert Watson err(-1, "socket(%s, SOCK_DGRAM, 0)", domainstr); 65dba96bd9SRobert Watson 66dba96bd9SRobert Watson sock_receive = socket(domain, SOCK_DGRAM, 0); 67dba96bd9SRobert Watson if (sock_receive < 0) 68dba96bd9SRobert Watson err(-1, "socket(%s, SOCK_DGRAM, 0)", domainstr); 69dba96bd9SRobert Watson 70dba96bd9SRobert Watson if (bind(sock_receive, sa, salen) < 0) 71dba96bd9SRobert Watson err(-1, "Protocol %s bind(sock_receive)", domainstr); 72dba96bd9SRobert Watson if (fcntl(sock_receive, F_SETFL, O_NONBLOCK, 1) < 0) 73dba96bd9SRobert Watson err(-1, "Protocll %s fcntl(sock_receive, FL_SETFL, " 74dba96bd9SRobert Watson "O_NONBLOCK)", domainstr); 75dba96bd9SRobert Watson 76dba96bd9SRobert Watson if (connect(sock_send, sa, salen) < 0) 77dba96bd9SRobert Watson err(-1, "Protocol %s connect(sock_send)", domainstr); 78dba96bd9SRobert Watson 79dba96bd9SRobert Watson if (recv(sock_receive, NULL, 0, 0) >= 0 || errno != EAGAIN) 80dba96bd9SRobert Watson err(-1, "Protocol %s recv(sock_receive, NULL, 0) before", 81dba96bd9SRobert Watson domainstr); 82dba96bd9SRobert Watson 83dba96bd9SRobert Watson if (send(sock_send, NULL, 0, 0) < 0) 84dba96bd9SRobert Watson err(-1, "Protocol %s send(sock_send, NULL, 0)", domainstr); 85dba96bd9SRobert Watson 86dba96bd9SRobert Watson (void)sleep(1); 87dba96bd9SRobert Watson if (recv(sock_receive, NULL, 0, 0) < 0) 88dba96bd9SRobert Watson err(-1, "Protocol %s recv(sock_receive, NULL, 0) test", 89dba96bd9SRobert Watson domainstr); 90dba96bd9SRobert Watson 91dba96bd9SRobert Watson if (recv(sock_receive, NULL, 0, 0) >= 0 || errno != EAGAIN) 92dba96bd9SRobert Watson err(-1, "Protocol %s recv(sock_receive, NULL, 0) after", 93dba96bd9SRobert Watson domainstr); 94dba96bd9SRobert Watson 95dba96bd9SRobert Watson } 96dba96bd9SRobert Watson 978c3bc1afSRobert Watson int 988c3bc1afSRobert Watson main(int argc, __unused char *argv[]) 998c3bc1afSRobert Watson { 100dba96bd9SRobert Watson struct sockaddr_in6 sin6; 1018c3bc1afSRobert Watson struct sockaddr_in sin; 102dba96bd9SRobert Watson struct in6_addr loopback6addr = IN6ADDR_LOOPBACK_INIT; 1038c3bc1afSRobert Watson 1048c3bc1afSRobert Watson if (argc != 1) 1058c3bc1afSRobert Watson usage(); 1068c3bc1afSRobert Watson 1078c3bc1afSRobert Watson bzero(&sin, sizeof(sin)); 1088c3bc1afSRobert Watson sin.sin_len = sizeof(sin); 1098c3bc1afSRobert Watson sin.sin_family = AF_INET; 1108c3bc1afSRobert Watson sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 1118c3bc1afSRobert Watson sin.sin_port = htons(THEPORT); 1128c3bc1afSRobert Watson 113dba96bd9SRobert Watson test(PF_INET, "PF_INET", (struct sockaddr *)&sin, sizeof(sin)); 1148c3bc1afSRobert Watson 115dba96bd9SRobert Watson bzero(&sin6, sizeof(sin6)); 116dba96bd9SRobert Watson sin6.sin6_len = sizeof(sin6); 117dba96bd9SRobert Watson sin6.sin6_family = AF_INET6; 118dba96bd9SRobert Watson sin6.sin6_addr = loopback6addr; 119dba96bd9SRobert Watson sin6.sin6_port = htons(THEPORT); 1208c3bc1afSRobert Watson 121dba96bd9SRobert Watson test(PF_INET6, "PF_INET6", (struct sockaddr *)&sin6, sizeof(sin6)); 1228c3bc1afSRobert Watson 1238c3bc1afSRobert Watson return (0); 1248c3bc1afSRobert Watson } 125