00001 /* $Id: asyncns-test.c 27 2007-02-16 13:51:03Z lennart $ */ 00002 00003 /*** 00004 This file is part of libasyncns. 00005 00006 libasyncns is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU Lesser General Public License as 00008 published by the Free Software Foundation; either version 2 of the 00009 License, or (at your option) any later version. 00010 00011 libasyncns is distributed in the hope that it will be useful, but 00012 WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 General Public License for more details. 00015 00016 You should have received a copy of the GNU Lesser General Public 00017 License along with libasyncns; if not, write to the Free Software 00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00019 USA. 00020 ***/ 00021 00022 #if HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <string.h> 00027 #include <sys/types.h> 00028 #include <sys/socket.h> 00029 #include <arpa/inet.h> 00030 #include <stdio.h> 00031 #include <netinet/in.h> 00032 #include <arpa/nameser.h> 00033 #include <resolv.h> 00034 #include <assert.h> 00035 00036 #include "asyncns.h" 00037 00038 int main(int argc, char *argv[]) { 00039 asyncns_t* asyncns = NULL; 00040 asyncns_query_t *q1, *q2, *q3; 00041 int r = 1, ret; 00042 struct addrinfo *ai, hints; 00043 struct sockaddr_in sa; 00044 char host[NI_MAXHOST] = "", serv[NI_MAXSERV] = ""; 00045 unsigned char *srv; 00046 00047 if (!(asyncns = asyncns_new(10))) { 00048 fprintf(stderr, "asyncns_new() failed\n"); 00049 goto fail; 00050 } 00051 00052 /* Make a name -> address query */ 00053 memset(&hints, 0, sizeof(hints)); 00054 hints.ai_family = PF_UNSPEC; 00055 hints.ai_socktype = SOCK_STREAM; 00056 00057 q1 = asyncns_getaddrinfo(asyncns, argc >= 2 ? argv[1] : "www.heise.de", NULL, &hints); 00058 00059 /* Make an address -> name query */ 00060 memset(&sa, 0, sizeof(sa)); 00061 sa.sin_family = AF_INET; 00062 sa.sin_addr.s_addr = inet_addr(argc >= 3 ? argv[2] : "193.99.144.71"); 00063 sa.sin_port = htons(80); 00064 00065 q2 = asyncns_getnameinfo(asyncns, (struct sockaddr*) &sa, sizeof(sa), 0, 1, 1); 00066 00067 /* Make a res_query() call */ 00068 q3 = asyncns_res_query(asyncns, "_xmpp-client._tcp.gmail.com", C_IN, T_SRV); 00069 00070 /* Wait until the three queries are completed */ 00071 while (!asyncns_isdone(asyncns, q1) 00072 || !asyncns_isdone(asyncns, q2) 00073 || !asyncns_isdone(asyncns, q3)) { 00074 if (asyncns_wait(asyncns, 1) < 0) 00075 goto fail; 00076 } 00077 00078 /* Interpret the result of the name -> addr query */ 00079 if ((ret = asyncns_getaddrinfo_done(asyncns, q1, &ai))) 00080 fprintf(stderr, "error: %s %i\n", gai_strerror(ret), ret); 00081 else { 00082 struct addrinfo *i; 00083 00084 for (i = ai; i; i = i->ai_next) { 00085 char t[256]; 00086 const char *p = NULL; 00087 00088 if (i->ai_family == PF_INET) 00089 p = inet_ntop(AF_INET, &((struct sockaddr_in*) i->ai_addr)->sin_addr, t, sizeof(t)); 00090 else if (i->ai_family == PF_INET6) 00091 p = inet_ntop(AF_INET6, &((struct sockaddr_in6*) i->ai_addr)->sin6_addr, t, sizeof(t)); 00092 00093 printf("%s\n", p); 00094 } 00095 00096 asyncns_freeaddrinfo(ai); 00097 } 00098 00099 /* Interpret the result of the addr -> name query */ 00100 if ((ret = asyncns_getnameinfo_done(asyncns, q2, host, sizeof(host), serv, sizeof(serv)))) 00101 fprintf(stderr, "error: %s %i\n", gai_strerror(ret), ret); 00102 else 00103 printf("%s -- %s\n", host, serv); 00104 00105 /* Interpret the result of the SRV lookup */ 00106 if ((ret = asyncns_res_done(asyncns, q3, &srv)) < 0) { 00107 fprintf(stderr, "error: %s %i\n", strerror(ret), ret); 00108 } else if (ret == 0) { 00109 fprintf(stderr, "No reply for SRV lookup\n"); 00110 } else { 00111 int qdcount; 00112 int ancount; 00113 int len; 00114 const unsigned char *pos = srv + sizeof(HEADER); 00115 unsigned char *end = srv + ret; 00116 HEADER *head = (HEADER *)srv; 00117 char name[256]; 00118 00119 qdcount = ntohs(head->qdcount); 00120 ancount = ntohs(head->ancount); 00121 00122 printf("%d answers for srv lookup:\n", ancount); 00123 00124 /* Ignore the questions */ 00125 while (qdcount-- > 0 && (len = dn_expand(srv, end, pos, name, 255)) >= 0) { 00126 assert(len >= 0); 00127 pos += len + QFIXEDSZ; 00128 } 00129 00130 /* Parse the answers */ 00131 while (ancount-- > 0 && (len = dn_expand(srv, end, pos, name, 255)) >= 0) { 00132 /* Ignore the initial string */ 00133 uint16_t pref, weight, port; 00134 assert(len >= 0); 00135 pos += len; 00136 /* Ignore type, ttl, class and dlen */ 00137 pos += 10; 00138 00139 GETSHORT(pref, pos); 00140 GETSHORT(weight, pos); 00141 GETSHORT(port, pos); 00142 len = dn_expand(srv, end, pos, name, 255); 00143 printf("\tpreference: %2d weight: %2d port: %d host: %s\n", 00144 pref, weight, port, name); 00145 00146 pos += len; 00147 } 00148 } 00149 00150 r = 0; 00151 00152 fail: 00153 00154 if (asyncns) 00155 asyncns_free(asyncns); 00156 00157 return r; 00158 }