1 /* $OpenBSD: gaitest.c,v 1.7 2020/02/14 19:17:33 schwarze Exp $ */ 2 /* $NetBSD: gaitest.c,v 1.3 2002/07/05 15:47:43 itojun Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, and 2002 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /* 34 * Please note: the order of the responses (and the regress test) 35 * is dependent on the "family" keywords in resolv.conf. 36 * 37 * This expects the default behaviour of "family inet4 inet6" 38 */ 39 40 #include <sys/types.h> 41 #include <sys/socket.h> 42 #include <netinet/in.h> 43 #include <arpa/inet.h> 44 #include <netdb.h> 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <unistd.h> 49 50 struct addrinfo ai; 51 52 char host[NI_MAXHOST]; 53 char serv[NI_MAXSERV]; 54 int vflag = 0; 55 56 static void usage(void); 57 static void print1(const char *, const struct addrinfo *, char *, char *); 58 int main(int, char *[]); 59 60 static void 61 usage() 62 { 63 fprintf(stderr, "usage: test [-f family] [-s socktype] [-p proto] [-DPRSv46] host serv\n"); 64 } 65 66 static void 67 print1(title, res, h, s) 68 const char *title; 69 const struct addrinfo *res; 70 char *h; 71 char *s; 72 { 73 char *start, *end; 74 int error; 75 const int niflag = NI_NUMERICHOST | NI_NUMERICSERV; 76 77 if (res->ai_addr) { 78 error = getnameinfo(res->ai_addr, res->ai_addr->sa_len, 79 host, sizeof(host), serv, sizeof(serv), 80 niflag); 81 h = host; 82 s = serv; 83 } else 84 error = 0; 85 86 if (vflag) { 87 start = "\t"; 88 end = "\n"; 89 } else { 90 start = " "; 91 end = ""; 92 } 93 printf("%s%s", title, end); 94 printf("%sflags 0x%x%s", start, res->ai_flags, end); 95 printf("%sfamily %d%s", start, res->ai_family, end); 96 printf("%ssocktype %d%s", start, res->ai_socktype, end); 97 printf("%sprotocol %d%s", start, res->ai_protocol, end); 98 printf("%saddrlen %d%s", start, res->ai_addrlen, end); 99 if (error) 100 printf("%serror %d%s", start, error, end); 101 else { 102 printf("%shost %s%s", start, h, end); 103 printf("%sserv %s%s", start, s, end); 104 } 105 #if 0 106 if (res->ai_canonname) 107 printf("%scname \"%s\"%s", start, res->ai_canonname, end); 108 #endif 109 if (!vflag) 110 printf("\n"); 111 112 } 113 114 int 115 main(argc, argv) 116 int argc; 117 char *argv[]; 118 { 119 struct addrinfo *res; 120 int error, i; 121 char *p, *q; 122 int c; 123 char nbuf[10]; 124 125 memset(&ai, 0, sizeof(ai)); 126 ai.ai_family = PF_UNSPEC; 127 ai.ai_flags |= AI_CANONNAME; 128 while ((c = getopt(argc, argv, "Df:p:PRs:Sv46")) != -1) { 129 switch (c) { 130 case 'D': 131 ai.ai_socktype = SOCK_DGRAM; 132 break; 133 case 'f': 134 ai.ai_family = atoi(optarg); 135 break; 136 case 'p': 137 ai.ai_protocol = atoi(optarg); 138 break; 139 case 'P': 140 ai.ai_flags |= AI_PASSIVE; 141 break; 142 case 'R': 143 ai.ai_socktype = SOCK_RAW; 144 break; 145 case 's': 146 ai.ai_socktype = atoi(optarg); 147 break; 148 case 'S': 149 ai.ai_socktype = SOCK_STREAM; 150 break; 151 case 'v': 152 vflag++; 153 break; 154 case '4': 155 ai.ai_family = PF_INET; 156 break; 157 case '6': 158 ai.ai_family = PF_INET6; 159 break; 160 default: 161 usage(); 162 exit(1); 163 } 164 } 165 argc -= optind; 166 argv += optind; 167 168 if (argc != 2){ 169 usage(); 170 exit(1); 171 } 172 173 p = *argv[0] ? argv[0] : NULL; 174 q = *argv[1] ? argv[1] : NULL; 175 176 print1("arg:", &ai, p ? p : "(empty)", q ? q : "(empty)"); 177 178 error = getaddrinfo(p, q, &ai, &res); 179 if (error) { 180 printf("%s\n", gai_strerror(error)); 181 exit(1); 182 } 183 184 i = 1; 185 do { 186 snprintf(nbuf, sizeof(nbuf), "ai%d:", i); 187 print1(nbuf, res, NULL, NULL); 188 189 i++; 190 } while ((res = res->ai_next) != NULL); 191 192 exit(0); 193 } 194