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