core: use string instead of compound literal
[rofl0r-proxychains-ng.git] / tests / test_getaddrinfo.c
blob462406f541d0b801c32eb48d8f2d92505c98d1f2
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <netdb.h>
4 #include <netinet/in.h>
5 #include <sys/socket.h>
6 #include <assert.h>
7 #include <string.h>
9 #ifndef NI_MAXHOST
10 #define NI_MAXHOST 1025
11 #endif
13 static int doit(const char* host, const char* service) {
14 struct addrinfo *result;
15 struct addrinfo *res;
16 int error;
18 /* resolve the domain name into a list of addresses */
19 error = getaddrinfo(host, service, NULL, &result);
20 if (error != 0)
22 fprintf(stderr, "error in getaddrinfo: %s\n", gai_strerror(error));
23 return EXIT_FAILURE;
26 /* loop over all returned results and do inverse lookup */
27 for (res = result; res != NULL; res = res->ai_next)
29 char hostname[NI_MAXHOST] = "";
31 error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, NI_MAXHOST, NULL, 0, 0);
32 if (error != 0)
34 fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(error));
35 continue;
37 int port = 0;
38 if(res->ai_family == AF_INET) port = ((struct sockaddr_in*)res->ai_addr)->sin_port;
39 else if(res->ai_family == AF_INET6) port = ((struct sockaddr_in6*)res->ai_addr)->sin6_port;
40 port = ntohs(port);
41 printf("hostname: %s, port: %d\n", hostname, port);
44 freeaddrinfo(result);
45 return EXIT_SUCCESS;
48 /* reproduce use of getaddrinfo as used by nmap 7.91's canonicalize_address */
49 int canonicalize_address(struct sockaddr_storage *ss, struct sockaddr_storage *output) {
50 char canonical_ip_string[NI_MAXHOST];
51 struct addrinfo *ai;
52 int rc;
53 /* Convert address to string. */
54 rc = getnameinfo((struct sockaddr *) ss, sizeof(*ss),
55 canonical_ip_string, sizeof(canonical_ip_string), NULL, 0, NI_NUMERICHOST);
56 assert(rc == 0);
57 struct addrinfo hints = {
58 .ai_family = ss->ss_family,
59 .ai_socktype = SOCK_DGRAM,
60 .ai_flags = AI_NUMERICHOST,
62 rc = getaddrinfo(canonical_ip_string, NULL, &hints, &ai);
63 if (rc != 0 || ai == NULL)
64 return -1;
65 assert(ai->ai_addrlen > 0 && ai->ai_addrlen <= (int) sizeof(*output));
66 memcpy(output, ai->ai_addr, ai->ai_addrlen);
67 freeaddrinfo(ai);
68 return 0;
71 int main(void) {
72 int ret;
73 ret = doit("www.example.com", NULL);
74 ret = doit("www.example.com", "80");
75 struct sockaddr_storage o, ss = {.ss_family = PF_INET};
76 struct sockaddr_in *v4 = &ss;
77 struct sockaddr_in6 *v6 = &ss;
78 memcpy(&v4->sin_addr, "\x7f\0\0\1", 4);
79 ret = canonicalize_address(&ss, &o);
80 assert (ret == 0);
81 ss.ss_family = PF_INET6;
82 memcpy(&v6->sin6_addr, "\0\0\0\0" "\0\0\0\0" "\0\0\0\0""\0\0\0\1", 16);
83 ret = canonicalize_address(&ss, &o);
84 assert (ret == 0);
85 return ret;