1 #include <mcheck.h>
2 #include <netdb.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <arpa/inet.h>
6 #include <arpa/nameser.h>
7 
8 
9 static int
do_test(void)10 do_test (void)
11 {
12   mtrace ();
13 
14   int result = 0;
15   struct addrinfo hints;
16   struct addrinfo *ai_res;
17   int s;
18 
19 #define T(no, fail, addr, fam, coraddr)					      \
20   s = getaddrinfo (addr, NULL, &hints, &ai_res);			      \
21   if (s != 0)								      \
22     {									      \
23       if (s != fail)							      \
24 	{								      \
25 	  printf ("getaddrinfo test %d failed: %s\n", no, gai_strerror (s));  \
26 	  result = 1;							      \
27 	}								      \
28       ai_res = NULL;							      \
29     }									      \
30   else if (fail)							      \
31     {									      \
32       printf ("getaddrinfo test %d should have failed but did not\n", no);    \
33       result = 1;							      \
34     }									      \
35   else if (ai_res->ai_family != fam)					      \
36     {									      \
37       printf ("\
38 getaddrinfo test %d return address of family %d, expected %d\n",	      \
39 	      no, ai_res->ai_family, fam);				      \
40       result = 1;							      \
41     }									      \
42   else if (fam == AF_INET)						      \
43     {									      \
44       if (ai_res->ai_addrlen != sizeof (struct sockaddr_in))		      \
45 	{								      \
46 	  printf ("getaddrinfo test %d: address size %zu, expected %zu\n",    \
47 		  no, (size_t) ai_res->ai_addrlen,			      \
48 		  sizeof (struct sockaddr_in));				      \
49 	  result = 1;							      \
50 	}								      \
51       else if (strcmp (coraddr, \
52 		       inet_ntoa (((struct sockaddr_in *) ai_res->ai_addr)->sin_addr))\
53 	       != 0)							      \
54 	{								      \
55 	  printf ("getaddrinfo test %d: got value %s, expected %s\n",	      \
56 		  no,							      \
57 		  inet_ntoa (((struct sockaddr_in *) ai_res->ai_addr)->sin_addr), \
58 		  coraddr);						      \
59 	  result = 1;							      \
60 	}								      \
61     }									      \
62   else									      \
63     {									      \
64       char buf[100];							      \
65 									      \
66       if (ai_res->ai_addrlen != sizeof (struct sockaddr_in6))		      \
67 	{								      \
68 	  printf ("getaddrinfo test %d: address size %zu, expected %zu\n",    \
69 		  no, (size_t) ai_res->ai_addrlen,			      \
70 		  sizeof (struct sockaddr_in6));			      \
71 	  result = 1;							      \
72 	}								      \
73       else if (strcmp (coraddr, \
74 		       inet_ntop (AF_INET6,				      \
75 				  &((struct sockaddr_in6 *) ai_res->ai_addr)->sin6_addr,\
76 				  buf, sizeof (buf)))			      \
77 	       != 0)							      \
78 	{								      \
79 	  printf ("getaddrinfo test %d: got value %s, expected %s\n",	      \
80 		  no,							      \
81 		  inet_ntop (AF_INET6,					      \
82 			     & ((struct sockaddr_in6 *) ai_res->ai_addr)->sin6_addr, \
83 			     buf, sizeof (buf)),			      \
84 		  coraddr);						      \
85 	  result = 1;							      \
86 	}								      \
87     }									      \
88   if (ai_res != NULL && ai_res->ai_next != NULL)			      \
89     {									      \
90       puts ("expected only one result");				      \
91       result = 1;							      \
92     }									      \
93   freeaddrinfo (ai_res)
94 
95 
96   memset (&hints, '\0', sizeof (hints));
97   hints.ai_family = AF_UNSPEC;
98   hints.ai_socktype = SOCK_STREAM;
99   T (1, 0, "127.0.0.1", AF_INET, "127.0.0.1");
100 
101   memset (&hints, '\0', sizeof (hints));
102   hints.ai_family = AF_INET;
103   hints.ai_socktype = SOCK_STREAM;
104   T (2, 0, "127.0.0.1", AF_INET, "127.0.0.1");
105 
106   memset (&hints, '\0', sizeof (hints));
107   hints.ai_family = AF_INET6;
108   hints.ai_socktype = SOCK_STREAM;
109   hints.ai_flags = AI_V4MAPPED;
110   T (3, 0, "127.0.0.1", AF_INET6, "::ffff:127.0.0.1");
111 
112   memset (&hints, '\0', sizeof (hints));
113   hints.ai_family = AF_INET6;
114   hints.ai_socktype = SOCK_STREAM;
115   T (4, EAI_ADDRFAMILY, "127.0.0.1", AF_INET6, "");
116 
117   memset (&hints, '\0', sizeof (hints));
118   hints.ai_family = AF_UNSPEC;
119   hints.ai_socktype = SOCK_STREAM;
120   T (5, 0, "::1", AF_INET6, "::1");
121 
122   memset (&hints, '\0', sizeof (hints));
123   hints.ai_family = AF_INET;
124   hints.ai_socktype = SOCK_STREAM;
125   T (6, EAI_ADDRFAMILY, "::1", AF_INET6, "");
126 
127   memset (&hints, '\0', sizeof (hints));
128   hints.ai_family = AF_INET6;
129   hints.ai_socktype = SOCK_STREAM;
130   T (7, 0, "::1", AF_INET6, "::1");
131 
132   memset (&hints, '\0', sizeof (hints));
133   hints.ai_family = AF_UNSPEC;
134   hints.ai_socktype = SOCK_STREAM;
135   T (8, 0, "::ffff:127.0.0.1", AF_INET6, "::ffff:127.0.0.1");
136 
137   memset (&hints, '\0', sizeof (hints));
138   hints.ai_family = AF_INET;
139   hints.ai_socktype = SOCK_STREAM;
140   T (9, 0, "::ffff:127.0.0.1", AF_INET, "127.0.0.1");
141 
142   memset (&hints, '\0', sizeof (hints));
143   hints.ai_family = AF_INET6;
144   hints.ai_socktype = SOCK_STREAM;
145   T (10, 0, "::ffff:127.0.0.1", AF_INET6, "::ffff:127.0.0.1");
146 
147   return result;
148 }
149 
150 #define TEST_FUNCTION do_test ()
151 #include "../test-skeleton.c"
152