]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/test-resolv.c
sd-resolv: rename old asyncns variables
[thirdparty/systemd.git] / src / libsystemd / test-resolv.c
CommitLineData
edc6f2f5
TG
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
e963e3ad 3/***
edc6f2f5 4 This file is part of systemd.
e963e3ad
DB
5
6 Copyright 2005-2008 Lennart Poettering
7
edc6f2f5
TG
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
e963e3ad 12
edc6f2f5 13 systemd is distributed in the hope that it will be useful, but
e963e3ad
DB
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
edc6f2f5
TG
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
e963e3ad 21
e963e3ad
DB
22#include <string.h>
23#include <sys/types.h>
24#include <sys/socket.h>
25#include <arpa/inet.h>
26#include <stdio.h>
27#include <netinet/in.h>
28#include <arpa/nameser.h>
29#include <resolv.h>
30#include <assert.h>
31#include <signal.h>
32#include <errno.h>
33
5681d7fb
TG
34#include "sd-resolv.h"
35#include "resolv-util.h"
e963e3ad
DB
36#include "macro.h"
37
38int main(int argc, char *argv[]) {
39 int r = 1, ret;
12f404c4 40 _cleanup_resolv_free_ sd_resolv_t *resolv = NULL;
2a4be8ad
DB
41 _cleanup_resolv_addrinfo_free_ struct addrinfo *ai = NULL;
42 _cleanup_resolv_answer_free_ unsigned char *srv = NULL;
43 sd_resolv_query_t *q1, *q2, *q3;
e963e3ad
DB
44 struct addrinfo hints = {};
45 struct sockaddr_in sa = {};
46 char host[NI_MAXHOST] = "", serv[NI_MAXSERV] = "";
47
48 signal(SIGCHLD, SIG_IGN);
49
12f404c4
DB
50 resolv = sd_resolv_new(2);
51 if (!resolv)
e963e3ad
DB
52 log_oom();
53
54 /* Make a name -> address query */
55 hints.ai_family = PF_UNSPEC;
56 hints.ai_socktype = SOCK_STREAM;
57
12f404c4 58 q1 = sd_resolv_getaddrinfo(resolv, argc >= 2 ? argv[1] : "www.heise.de", NULL, &hints);
e963e3ad 59 if (!q1)
2a4be8ad 60 fprintf(stderr, "sd_resolv_getaddrinfo(): %s\n", strerror(errno));
e963e3ad
DB
61
62 /* Make an address -> name query */
63 sa.sin_family = AF_INET;
64 sa.sin_addr.s_addr = inet_addr(argc >= 3 ? argv[2] : "193.99.144.71");
65 sa.sin_port = htons(80);
66
12f404c4 67 q2 = sd_resolv_getnameinfo(resolv, (struct sockaddr*) &sa, sizeof(sa), 0, 1, 1);
e963e3ad 68 if (!q2)
2a4be8ad 69 fprintf(stderr, "sd_resolv_getnameinfo(): %s\n", strerror(errno));
e963e3ad
DB
70
71 /* Make a res_query() call */
12f404c4 72 q3 = sd_resolv_res_query(resolv, "_xmpp-client._tcp.gmail.com", C_IN, T_SRV);
e963e3ad 73 if (!q3)
2a4be8ad 74 fprintf(stderr, "sd_resolv_res_query(): %s\n", strerror(errno));
e963e3ad
DB
75
76 /* Wait until the three queries are completed */
12f404c4
DB
77 while (!sd_resolv_isdone(resolv, q1) ||
78 !sd_resolv_isdone(resolv, q2) ||
79 !sd_resolv_isdone(resolv, q3)) {
80 if (sd_resolv_wait(resolv, 1) < 0)
2a4be8ad 81 fprintf(stderr, "sd_resolv_wait(): %s\n", strerror(errno));
e963e3ad
DB
82 }
83
84 /* Interpret the result of the name -> addr query */
12f404c4 85 ret = sd_resolv_getaddrinfo_done(resolv, q1, &ai);
8e50b5a7 86 if (ret)
e963e3ad
DB
87 fprintf(stderr, "error: %s %i\n", gai_strerror(ret), ret);
88 else {
89 struct addrinfo *i;
90
91 for (i = ai; i; i = i->ai_next) {
92 char t[256];
93 const char *p = NULL;
94
95 if (i->ai_family == PF_INET)
96 p = inet_ntop(AF_INET, &((struct sockaddr_in*) i->ai_addr)->sin_addr, t, sizeof(t));
97 else if (i->ai_family == PF_INET6)
98 p = inet_ntop(AF_INET6, &((struct sockaddr_in6*) i->ai_addr)->sin6_addr, t, sizeof(t));
99
100 printf("%s\n", p);
101 }
102 }
103
104 /* Interpret the result of the addr -> name query */
12f404c4 105 ret = sd_resolv_getnameinfo_done(resolv, q2, host, sizeof(host), serv, sizeof(serv));
8e50b5a7 106 if (ret)
e963e3ad
DB
107 fprintf(stderr, "error: %s %i\n", gai_strerror(ret), ret);
108 else
109 printf("%s -- %s\n", host, serv);
110
111 /* Interpret the result of the SRV lookup */
12f404c4 112 ret = sd_resolv_res_done(resolv, q3, &srv);
8e50b5a7 113 if (ret < 0) {
e963e3ad
DB
114 fprintf(stderr, "error: %s %i\n", strerror(errno), ret);
115 } else if (ret == 0) {
116 fprintf(stderr, "No reply for SRV lookup\n");
117 } else {
118 int qdcount;
119 int ancount;
120 int len;
121 const unsigned char *pos = srv + sizeof(HEADER);
122 unsigned char *end = srv + ret;
123 HEADER *head = (HEADER *)srv;
124 char name[256];
125
126 qdcount = ntohs(head->qdcount);
127 ancount = ntohs(head->ancount);
128
129 printf("%d answers for srv lookup:\n", ancount);
130
131 /* Ignore the questions */
132 while (qdcount-- > 0 && (len = dn_expand(srv, end, pos, name, 255)) >= 0) {
133 assert(len >= 0);
134 pos += len + QFIXEDSZ;
135 }
136
137 /* Parse the answers */
138 while (ancount-- > 0 && (len = dn_expand(srv, end, pos, name, 255)) >= 0) {
139 /* Ignore the initial string */
140 uint16_t pref, weight, port;
141 assert(len >= 0);
142 pos += len;
143 /* Ignore type, ttl, class and dlen */
144 pos += 10;
145
146 GETSHORT(pref, pos);
147 GETSHORT(weight, pos);
148 GETSHORT(port, pos);
149 len = dn_expand(srv, end, pos, name, 255);
150 printf("\tpreference: %2d weight: %2d port: %d host: %s\n",
151 pref, weight, port, name);
152
153 pos += len;
154 }
155 }
156
157 r = 0;
158
159 return r;
160}