1 2 #include <sys/cdefs.h> 3 __RCSID("$NetBSD: t_rfc6056.c,v 1.1 2011/09/24 18:34:18 christos Exp $"); 4 5 #include <sys/types.h> 6 #include <sys/socket.h> 7 #include <netinet/in.h> 8 #include <netinet/udp.h> 9 #include <arpa/inet.h> 10 #include <string.h> 11 #include <strings.h> 12 #include <stdio.h> 13 #include <unistd.h> 14 #include <errno.h> 15 #include <stdlib.h> 16 #include <netdb.h> 17 #include <err.h> 18 19 #include <atf-c.h> 20 21 static void 22 test(const char *hostname, const char *service, int family, int al) 23 { 24 static const char hello[] = "hello\n"; 25 int s, error; 26 struct sockaddr_storage ss; 27 struct addrinfo hints, *res; 28 29 memset(&hints, 0, sizeof(hints)); 30 hints.ai_family = family; 31 hints.ai_socktype = SOCK_DGRAM; 32 33 error = getaddrinfo(hostname, service, &hints, &res); 34 if (error) 35 errx(EXIT_FAILURE, "Cannot get address for %s (%s)", 36 hostname, gai_strerror(error)); 37 38 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 39 if (s == -1) 40 err(EXIT_FAILURE, "socket"); 41 42 if (setsockopt(s, IPPROTO_UDP, UDP_RFC6056ALGO, &al, sizeof(al)) == -1) 43 err(EXIT_FAILURE, "setsockopt"); 44 45 memset(&ss, 0, sizeof(ss)); 46 ss.ss_len = res->ai_addrlen; 47 ss.ss_family = res->ai_family; 48 49 if (bind(s, (struct sockaddr *)&ss, ss.ss_len) == -1) 50 err(EXIT_FAILURE, "bind"); 51 52 if (sendto(s, hello, sizeof(hello) - 1, 0, 53 res->ai_addr, res->ai_addrlen) == -1) 54 err(EXIT_FAILURE, "sendto"); 55 56 if (close(s) == -1) 57 err(EXIT_FAILURE, "close"); 58 59 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 60 if (s == -1) 61 err(EXIT_FAILURE, "socket"); 62 63 if (setsockopt(s, IPPROTO_UDP, UDP_RFC6056ALGO, &al, sizeof(al)) == -1) 64 err(EXIT_FAILURE, "setsockopt"); 65 66 if (connect(s, res->ai_addr, res->ai_addrlen) == -1) 67 err(EXIT_FAILURE, "connect"); 68 69 if (send(s, hello, sizeof(hello) - 1, 0) == -1) 70 err(EXIT_FAILURE, "send"); 71 72 if (close(s) == -1) 73 err(EXIT_FAILURE, "close"); 74 75 freeaddrinfo(res); 76 } 77 78 ATF_TC(inet4); 79 ATF_TC_HEAD(inet4, tc) 80 { 81 atf_tc_set_md_var(tc, "descr", "Checks random port allocation " 82 "for ipv4"); 83 } 84 85 ATF_TC_BODY(inet4, tc) 86 { 87 for (int i = 0; i < 6; i++) 88 test("localhost", "http", AF_INET, i); 89 } 90 91 ATF_TC(inet6); 92 ATF_TC_HEAD(inet6, tc) 93 { 94 atf_tc_set_md_var(tc, "descr", "Checks random port allocation " 95 "for ipv6"); 96 } 97 98 ATF_TC_BODY(inet6, tc) 99 { 100 for (int i = 0; i < 6; i++) 101 test("localhost", "http", AF_INET6, i); 102 } 103 104 ATF_TP_ADD_TCS(tp) 105 { 106 ATF_TP_ADD_TC(tp, inet4); 107 ATF_TP_ADD_TC(tp, inet6); 108 109 return atf_no_error(); 110 } 111