2 * Copyright (C) Jakub Hrozek 2014 <jakub.hrozek@gmail.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 #include <netinet/in.h>
32 #include <arpa/nameser.h>
33 #include <arpa/inet.h>
37 #define MIN(a,b) ((a)<(b)?(a):(b))
42 static void print_asc(const uint8_t *buf, uint32_t len)
45 for (i = 0; i < len; i++) {
46 printf("%c", isprint(buf[i])?buf[i]:'.');
50 static void dump_data(const uint8_t *buf, int len)
53 static const uint8_t empty[16] = { 0, };
62 (memcmp(&buf[i], &empty, 16) == 0))
73 printf("%02x ", buf[i]);
76 if (i%8 == 0) printf(" ");
78 print_asc(&buf[i-16],8); printf(" ");
79 print_asc(&buf[i-8],8); printf("\n");
88 while (n--) printf(" ");
90 print_asc(&buf[i-(i%16)],n); printf( " " );
92 if (n>0) print_asc(&buf[i-n],n);
97 static void test_res_query_a_record(void **state)
100 struct __res_state dnsstate;
101 unsigned char answer[ANSIZE] = { 0 };
102 char addr[INET_ADDRSTRLEN];
104 ns_rr rr; /* expanded resource record */
106 (void) state; /* unused */
108 memset(&dnsstate, 0, sizeof(struct __res_state));
109 rv = res_ninit(&dnsstate);
110 assert_int_equal(rv, 0);
112 rv = res_nquery(&dnsstate, "cwrap.org", ns_c_in, ns_t_a,
113 answer, sizeof(answer));
114 assert_in_range(rv, 1, 100);
116 printf("dump answer:\n");
117 dump_data(answer, rv);
119 ns_initparse(answer, sizeof(answer), &handle);
120 /* The query must finish w/o an error, have one answer and the answer
121 * must be a parseable RR of type A and have the address that our
122 * fake hosts file contains
124 assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
125 assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
126 assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
127 assert_int_equal(ns_rr_type(rr), ns_t_a);
128 assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr),
129 addr, sizeof(addr)));
130 assert_string_equal(addr, "78.46.80.163");
133 static void test_res_query_srv_record(void **state)
136 struct __res_state dnsstate;
137 unsigned char answer[ANSIZE] = { 0 };
139 ns_rr rr; /* expanded resource record */
140 const uint8_t *rrdata;
144 char hostname[MAXDNAME];
146 (void) state; /* unused */
148 memset(&dnsstate, 0, sizeof(struct __res_state));
149 rv = res_ninit(&dnsstate);
150 assert_int_equal(rv, 0);
152 rv = res_nquery(&dnsstate, "_http._tcp.mxtoolbox.com", ns_c_in, ns_t_srv,
153 answer, sizeof(answer));
154 assert_in_range(rv, 1, 100);
156 printf("dump answer:\n");
157 dump_data(answer, rv);
159 ns_initparse(answer, sizeof(answer), &handle);
162 * The query must finish w/o an error, have one answer and the answer
163 * must be a parseable RR of type SRV and have the priority, weight,
164 * port and hostname as in the fake hosts file
166 assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
167 assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
168 assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
169 assert_int_equal(ns_rr_type(rr), ns_t_srv);
171 rrdata = ns_rr_rdata(rr);
172 NS_GET16(prio, rrdata);
173 NS_GET16(weight, rrdata);
174 NS_GET16(port, rrdata);
176 rv = ns_name_uncompress(ns_msg_base(handle),
180 assert_int_not_equal(rv, -1);
182 assert_int_equal(prio, 10);
183 assert_int_equal(weight, 100);
184 assert_int_equal(port, 80);
185 assert_string_equal(hostname, "mxtoolbox.com");
192 const struct CMUnitTest real_tests[] = {
193 cmocka_unit_test(test_res_query_a_record),
194 cmocka_unit_test(test_res_query_srv_record),
197 rc = cmocka_run_group_tests(real_tests, NULL, NULL);