1 |
|
|
/* |
2 |
|
|
* Copyright (C) 2001 WIDE Project. |
3 |
|
|
* All rights reserved. |
4 |
|
|
* |
5 |
|
|
* Redistribution and use in source and binary forms, with or without |
6 |
|
|
* modification, are permitted provided that the following conditions |
7 |
|
|
* are met: |
8 |
|
|
* 1. Redistributions of source code must retain the above copyright |
9 |
|
|
* notice, this list of conditions and the following disclaimer. |
10 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
11 |
|
|
* notice, this list of conditions and the following disclaimer in the |
12 |
|
|
* documentation and/or other materials provided with the distribution. |
13 |
|
|
* 3. Neither the name of the project nor the names of its contributors |
14 |
|
|
* may be used to endorse or promote products derived from this software |
15 |
|
|
* without specific prior written permission. |
16 |
|
|
* |
17 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND |
18 |
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
19 |
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
20 |
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE |
21 |
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
22 |
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
23 |
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
24 |
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
25 |
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
26 |
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
27 |
|
|
* SUCH DAMAGE. |
28 |
|
|
*/ |
29 |
|
|
|
30 |
|
|
#ifdef HAVE_CONFIG_H |
31 |
|
|
#include "config.h" |
32 |
|
|
#endif |
33 |
|
|
|
34 |
|
|
#include <sys/time.h> |
35 |
|
|
|
36 |
|
|
#include <netinet/in.h> |
37 |
|
|
|
38 |
|
|
#ifdef NOERROR |
39 |
|
|
#undef NOERROR /* Solaris sucks */ |
40 |
|
|
#endif |
41 |
|
|
#ifdef NOERROR |
42 |
|
|
#undef T_UNSPEC /* SINIX does too */ |
43 |
|
|
#endif |
44 |
|
|
#include "nameser.h" |
45 |
|
|
|
46 |
|
|
#include <stdio.h> |
47 |
|
|
#include <string.h> |
48 |
|
|
#include <stdlib.h> |
49 |
|
|
#include <resolv.h> /* for b64_ntop() proto */ |
50 |
|
|
|
51 |
|
|
#include "interface.h" |
52 |
|
|
#include "addrtoname.h" |
53 |
|
|
#include "extract.h" /* must come after interface.h */ |
54 |
|
|
|
55 |
|
|
/* BIND9 lib/lwres/include/lwres */ |
56 |
|
|
typedef u_int32_t lwres_uint32_t; |
57 |
|
|
typedef u_int16_t lwres_uint16_t; |
58 |
|
|
typedef u_int8_t lwres_uint8_t; |
59 |
|
|
|
60 |
|
|
struct lwres_lwpacket { |
61 |
|
|
lwres_uint32_t length; |
62 |
|
|
lwres_uint16_t version; |
63 |
|
|
lwres_uint16_t pktflags; |
64 |
|
|
lwres_uint32_t serial; |
65 |
|
|
lwres_uint32_t opcode; |
66 |
|
|
lwres_uint32_t result; |
67 |
|
|
lwres_uint32_t recvlength; |
68 |
|
|
lwres_uint16_t authtype; |
69 |
|
|
lwres_uint16_t authlength; |
70 |
|
|
}; |
71 |
|
|
|
72 |
|
|
#define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */ |
73 |
|
|
|
74 |
|
|
#define LWRES_LWPACKETVERSION_0 0 |
75 |
|
|
|
76 |
|
|
#define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U |
77 |
|
|
#define LWRES_FLAG_SECUREDATA 0x00000002U |
78 |
|
|
|
79 |
|
|
/* |
80 |
|
|
* no-op |
81 |
|
|
*/ |
82 |
|
|
#define LWRES_OPCODE_NOOP 0x00000000U |
83 |
|
|
|
84 |
|
|
typedef struct { |
85 |
|
|
/* public */ |
86 |
|
|
lwres_uint16_t datalength; |
87 |
|
|
/* data follows */ |
88 |
|
|
} lwres_nooprequest_t; |
89 |
|
|
|
90 |
|
|
typedef struct { |
91 |
|
|
/* public */ |
92 |
|
|
lwres_uint16_t datalength; |
93 |
|
|
/* data follows */ |
94 |
|
|
} lwres_noopresponse_t; |
95 |
|
|
|
96 |
|
|
/* |
97 |
|
|
* get addresses by name |
98 |
|
|
*/ |
99 |
|
|
#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U |
100 |
|
|
|
101 |
|
|
typedef struct lwres_addr lwres_addr_t; |
102 |
|
|
|
103 |
|
|
struct lwres_addr { |
104 |
|
|
lwres_uint32_t family; |
105 |
|
|
lwres_uint16_t length; |
106 |
|
|
/* address folows */ |
107 |
|
|
}; |
108 |
|
|
|
109 |
|
|
typedef struct { |
110 |
|
|
/* public */ |
111 |
|
|
lwres_uint32_t flags; |
112 |
|
|
lwres_uint32_t addrtypes; |
113 |
|
|
lwres_uint16_t namelen; |
114 |
|
|
/* name follows */ |
115 |
|
|
} lwres_gabnrequest_t; |
116 |
|
|
|
117 |
|
|
typedef struct { |
118 |
|
|
/* public */ |
119 |
|
|
lwres_uint32_t flags; |
120 |
|
|
lwres_uint16_t naliases; |
121 |
|
|
lwres_uint16_t naddrs; |
122 |
|
|
lwres_uint16_t realnamelen; |
123 |
|
|
/* aliases follows */ |
124 |
|
|
/* addrs follows */ |
125 |
|
|
/* realname follows */ |
126 |
|
|
} lwres_gabnresponse_t; |
127 |
|
|
|
128 |
|
|
/* |
129 |
|
|
* get name by address |
130 |
|
|
*/ |
131 |
|
|
#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U |
132 |
|
|
typedef struct { |
133 |
|
|
/* public */ |
134 |
|
|
lwres_uint32_t flags; |
135 |
|
|
lwres_addr_t addr; |
136 |
|
|
/* addr body follows */ |
137 |
|
|
} lwres_gnbarequest_t; |
138 |
|
|
|
139 |
|
|
typedef struct { |
140 |
|
|
/* public */ |
141 |
|
|
lwres_uint32_t flags; |
142 |
|
|
lwres_uint16_t naliases; |
143 |
|
|
lwres_uint16_t realnamelen; |
144 |
|
|
/* aliases follows */ |
145 |
|
|
/* realname follows */ |
146 |
|
|
} lwres_gnbaresponse_t; |
147 |
|
|
|
148 |
|
|
/* |
149 |
|
|
* get rdata by name |
150 |
|
|
*/ |
151 |
|
|
#define LWRES_OPCODE_GETRDATABYNAME 0x00010003U |
152 |
|
|
|
153 |
|
|
typedef struct { |
154 |
|
|
/* public */ |
155 |
|
|
lwres_uint32_t flags; |
156 |
|
|
lwres_uint16_t rdclass; |
157 |
|
|
lwres_uint16_t rdtype; |
158 |
|
|
lwres_uint16_t namelen; |
159 |
|
|
/* name follows */ |
160 |
|
|
} lwres_grbnrequest_t; |
161 |
|
|
|
162 |
|
|
typedef struct { |
163 |
|
|
/* public */ |
164 |
|
|
lwres_uint32_t flags; |
165 |
|
|
lwres_uint16_t rdclass; |
166 |
|
|
lwres_uint16_t rdtype; |
167 |
|
|
lwres_uint32_t ttl; |
168 |
|
|
lwres_uint16_t nrdatas; |
169 |
|
|
lwres_uint16_t nsigs; |
170 |
|
|
/* realname here (len + name) */ |
171 |
|
|
/* rdata here (len + name) */ |
172 |
|
|
/* signatures here (len + name) */ |
173 |
|
|
} lwres_grbnresponse_t; |
174 |
|
|
|
175 |
|
|
#define LWRDATA_VALIDATED 0x00000001 |
176 |
|
|
|
177 |
|
|
#define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */ |
178 |
|
|
#define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */ |
179 |
|
|
|
180 |
|
|
#define LWRES_MAX_ALIASES 16 /* max # of aliases */ |
181 |
|
|
#define LWRES_MAX_ADDRS 64 /* max # of addrs */ |
182 |
|
|
|
183 |
|
|
struct tok opcode[] = { |
184 |
|
|
{ LWRES_OPCODE_NOOP, "noop", }, |
185 |
|
|
{ LWRES_OPCODE_GETADDRSBYNAME, "getaddrsbyname", }, |
186 |
|
|
{ LWRES_OPCODE_GETNAMEBYADDR, "getnamebyaddr", }, |
187 |
|
|
{ LWRES_OPCODE_GETRDATABYNAME, "getrdatabyname", }, |
188 |
|
|
{ 0, NULL, }, |
189 |
|
|
}; |
190 |
|
|
|
191 |
|
|
/* print-domain.c */ |
192 |
|
|
extern struct tok ns_type2str[]; |
193 |
|
|
extern struct tok ns_class2str[]; |
194 |
|
|
|
195 |
|
|
static int lwres_printname(size_t, const char *); |
196 |
|
|
static int lwres_printnamelen(const char *); |
197 |
|
|
/* static int lwres_printbinlen(const char *); */ |
198 |
|
|
static int lwres_printb64len(const char *); |
199 |
|
|
static int lwres_printaddr(lwres_addr_t *); |
200 |
|
|
|
201 |
|
|
static int |
202 |
|
|
lwres_printname(size_t l, const char *p0) |
203 |
|
|
{ |
204 |
|
|
const char *p; |
205 |
|
|
int i; |
206 |
|
|
|
207 |
|
|
p = p0; |
208 |
|
|
/* + 1 for terminating \0 */ |
209 |
|
|
if (p + l + 1 > (const char *)snapend) |
210 |
|
|
goto trunc; |
211 |
|
|
|
212 |
|
|
printf(" "); |
213 |
|
|
for (i = 0; i < l; i++) |
214 |
|
|
safeputchar(*p++); |
215 |
|
|
p++; /* skip terminating \0 */ |
216 |
|
|
|
217 |
|
|
return p - p0; |
218 |
|
|
|
219 |
|
|
trunc: |
220 |
|
|
return -1; |
221 |
|
|
} |
222 |
|
|
|
223 |
|
|
static int |
224 |
|
|
lwres_printnamelen(const char *p) |
225 |
|
|
{ |
226 |
|
|
u_int16_t l; |
227 |
|
|
int advance; |
228 |
|
|
|
229 |
|
|
if (p + 2 > (const char *)snapend) |
230 |
|
|
goto trunc; |
231 |
|
|
l = EXTRACT_16BITS(p); |
232 |
|
|
advance = lwres_printname(l, p + 2); |
233 |
|
|
if (advance < 0) |
234 |
|
|
goto trunc; |
235 |
|
|
return 2 + advance; |
236 |
|
|
|
237 |
|
|
trunc: |
238 |
|
|
return -1; |
239 |
|
|
} |
240 |
|
|
|
241 |
|
|
#if 0 |
242 |
|
|
static int |
243 |
|
|
lwres_printbinlen(const char *p0) |
244 |
|
|
{ |
245 |
|
|
u_int8_t *p; |
246 |
|
|
u_int16_t l; |
247 |
|
|
int i; |
248 |
|
|
|
249 |
|
|
p = (u_int8_t *)p0; |
250 |
|
|
if (p + 2 > (u_int8_t *)snapend) |
251 |
|
|
goto trunc; |
252 |
|
|
l = EXTRACT_16BITS(p); |
253 |
|
|
if (p + 2 + l > (u_int8_t *)snapend) |
254 |
|
|
goto trunc; |
255 |
|
|
p += 2; |
256 |
|
|
for (i = 0; i < l; i++) |
257 |
|
|
printf("%02x", *p++); |
258 |
|
|
return p - (u_int8_t *)p0; |
259 |
|
|
|
260 |
|
|
trunc: |
261 |
|
|
return -1; |
262 |
|
|
} |
263 |
|
|
#endif |
264 |
|
|
|
265 |
|
|
static int |
266 |
|
|
lwres_printb64len(const char *p0) |
267 |
|
|
{ |
268 |
|
|
u_int8_t *p; |
269 |
|
|
u_int16_t l; |
270 |
|
|
char *dbuf, *b64buf; |
271 |
|
|
int i; |
272 |
|
|
|
273 |
|
|
p = (u_int8_t *)p0; |
274 |
|
|
if (p + 2 > (u_int8_t *)snapend) |
275 |
|
|
goto trunc; |
276 |
|
|
l = EXTRACT_16BITS(p); |
277 |
|
|
if (p + 2 + l > (u_int8_t *)snapend) |
278 |
|
|
goto trunc; |
279 |
|
|
|
280 |
|
|
dbuf = malloc(l + 1); |
281 |
|
|
if (!dbuf) |
282 |
|
|
return -1; |
283 |
|
|
|
284 |
|
|
b64buf = malloc((l + 2) * 4 / 3); |
285 |
|
|
if (!b64buf) |
286 |
|
|
{ |
287 |
|
|
free(dbuf); |
288 |
|
|
return -1; |
289 |
|
|
} |
290 |
|
|
|
291 |
|
|
memcpy(dbuf, p, l); |
292 |
|
|
*(dbuf + l) = (char)0; |
293 |
|
|
|
294 |
|
|
i = b64_ntop (dbuf, l, b64buf, (l + 2) * 4 / 3); |
295 |
|
|
b64buf[i] = (char)0; |
296 |
|
|
printf ("%s", b64buf); |
297 |
|
|
|
298 |
|
|
free (dbuf); |
299 |
|
|
free (b64buf); |
300 |
|
|
|
301 |
|
|
return l + 2; |
302 |
|
|
|
303 |
|
|
trunc: |
304 |
|
|
return -1; |
305 |
|
|
} |
306 |
|
|
|
307 |
|
|
static int |
308 |
|
|
lwres_printaddr(lwres_addr_t *ap) |
309 |
|
|
{ |
310 |
|
|
u_int16_t l; |
311 |
|
|
const char *p; |
312 |
|
|
int i; |
313 |
|
|
|
314 |
|
|
TCHECK(ap->length); |
315 |
|
|
l = ntohs(ap->length); |
316 |
|
|
/* XXX ap points to packed struct */ |
317 |
|
|
p = (const char *)&ap->length + sizeof(ap->length); |
318 |
|
|
if (p + l > (const char *)snapend) |
319 |
|
|
goto trunc; |
320 |
|
|
|
321 |
|
|
switch (ntohl(ap->family)) { |
322 |
|
|
case 1: /* IPv4 */ |
323 |
|
|
printf(" %s", ipaddr_string(p)); |
324 |
|
|
p += sizeof(struct in_addr); |
325 |
|
|
break; |
326 |
|
|
#ifdef INET6 |
327 |
|
|
case 2: /* IPv6 */ |
328 |
|
|
printf(" %s", ip6addr_string(p)); |
329 |
|
|
p += sizeof(struct in6_addr); |
330 |
|
|
break; |
331 |
|
|
#endif |
332 |
|
|
default: |
333 |
|
|
printf(" %lu/", (unsigned long)ntohl(ap->family)); |
334 |
|
|
for (i = 0; i < l; i++) |
335 |
|
|
printf("%02x", *p++); |
336 |
|
|
} |
337 |
|
|
|
338 |
|
|
return p - (const char *)ap; |
339 |
|
|
|
340 |
|
|
trunc: |
341 |
|
|
return -1; |
342 |
|
|
} |
343 |
|
|
|
344 |
|
|
void |
345 |
|
|
lwres_print(const u_char *bp, u_int length) |
346 |
|
|
{ |
347 |
|
|
const struct lwres_lwpacket *np; |
348 |
|
|
u_int32_t v; |
349 |
|
|
const char *s; |
350 |
|
|
int response; |
351 |
|
|
int advance; |
352 |
|
|
int unsupported = 0; |
353 |
|
|
|
354 |
|
|
np = (const struct lwres_lwpacket *)bp; |
355 |
|
|
TCHECK(np->authlength); |
356 |
|
|
|
357 |
|
|
printf(" lwres"); |
358 |
|
|
v = ntohs(np->version); |
359 |
|
|
if (vflag || v != LWRES_LWPACKETVERSION_0) |
360 |
|
|
printf(" v%u", v); |
361 |
|
|
if (v != LWRES_LWPACKETVERSION_0) { |
362 |
|
|
s = (const char *)np + ntohl(np->length); |
363 |
|
|
goto tail; |
364 |
|
|
} |
365 |
|
|
|
366 |
|
|
response = ntohs(np->pktflags) & LWRES_LWPACKETFLAG_RESPONSE; |
367 |
|
|
|
368 |
|
|
/* opcode and pktflags */ |
369 |
|
|
v = (u_int32_t)ntohl(np->opcode); |
370 |
|
|
s = tok2str(opcode, "#0x%x", v); |
371 |
|
|
printf(" %s%s", s, response ? "" : "?"); |
372 |
|
|
|
373 |
|
|
/* pktflags */ |
374 |
|
|
v = ntohs(np->pktflags); |
375 |
|
|
if (v & ~LWRES_LWPACKETFLAG_RESPONSE) |
376 |
|
|
printf("[0x%x]", v); |
377 |
|
|
|
378 |
|
|
if (vflag > 1) { |
379 |
|
|
printf(" ("); /*)*/ |
380 |
|
|
printf("serial:0x%lx", (unsigned long)ntohl(np->serial)); |
381 |
|
|
printf(" result:0x%lx", (unsigned long)ntohl(np->result)); |
382 |
|
|
printf(" recvlen:%lu", (unsigned long)ntohl(np->recvlength)); |
383 |
|
|
/* BIND910: not used */ |
384 |
|
|
if (vflag > 2) { |
385 |
|
|
printf(" authtype:0x%x", ntohs(np->authtype)); |
386 |
|
|
printf(" authlen:%u", ntohs(np->authlength)); |
387 |
|
|
} |
388 |
|
|
/*(*/ |
389 |
|
|
printf(")"); |
390 |
|
|
} |
391 |
|
|
|
392 |
|
|
/* per-opcode content */ |
393 |
|
|
if (!response) { |
394 |
|
|
/* |
395 |
|
|
* queries |
396 |
|
|
*/ |
397 |
|
|
lwres_gabnrequest_t *gabn; |
398 |
|
|
lwres_gnbarequest_t *gnba; |
399 |
|
|
lwres_grbnrequest_t *grbn; |
400 |
|
|
u_int32_t l; |
401 |
|
|
|
402 |
|
|
gabn = NULL; |
403 |
|
|
gnba = NULL; |
404 |
|
|
grbn = NULL; |
405 |
|
|
|
406 |
|
|
switch (ntohl(np->opcode)) { |
407 |
|
|
case LWRES_OPCODE_NOOP: |
408 |
|
|
break; |
409 |
|
|
case LWRES_OPCODE_GETADDRSBYNAME: |
410 |
|
|
gabn = (lwres_gabnrequest_t *)(np + 1); |
411 |
|
|
TCHECK(gabn->namelen); |
412 |
|
|
/* XXX gabn points to packed struct */ |
413 |
|
|
s = (const char *)&gabn->namelen + |
414 |
|
|
sizeof(gabn->namelen); |
415 |
|
|
l = ntohs(gabn->namelen); |
416 |
|
|
|
417 |
|
|
/* BIND910: not used */ |
418 |
|
|
if (vflag > 2) { |
419 |
|
|
printf(" flags:0x%lx", |
420 |
|
|
(unsigned long)ntohl(gabn->flags)); |
421 |
|
|
} |
422 |
|
|
|
423 |
|
|
v = (u_int32_t)ntohl(gabn->addrtypes); |
424 |
|
|
switch (v & (LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) { |
425 |
|
|
case LWRES_ADDRTYPE_V4: |
426 |
|
|
printf(" IPv4"); |
427 |
|
|
break; |
428 |
|
|
case LWRES_ADDRTYPE_V6: |
429 |
|
|
printf(" IPv6"); |
430 |
|
|
break; |
431 |
|
|
case LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6: |
432 |
|
|
printf(" IPv4/6"); |
433 |
|
|
break; |
434 |
|
|
} |
435 |
|
|
if (v & ~(LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) |
436 |
|
|
printf("[0x%x]", v); |
437 |
|
|
|
438 |
|
|
advance = lwres_printname(l, s); |
439 |
|
|
if (advance < 0) |
440 |
|
|
goto trunc; |
441 |
|
|
s += advance; |
442 |
|
|
break; |
443 |
|
|
case LWRES_OPCODE_GETNAMEBYADDR: |
444 |
|
|
gnba = (lwres_gnbarequest_t *)(np + 1); |
445 |
|
|
TCHECK(gnba->addr); |
446 |
|
|
|
447 |
|
|
/* BIND910: not used */ |
448 |
|
|
if (vflag > 2) { |
449 |
|
|
printf(" flags:0x%lx", |
450 |
|
|
(unsigned long)ntohl(gnba->flags)); |
451 |
|
|
} |
452 |
|
|
|
453 |
|
|
s = (const char *)&gnba->addr; |
454 |
|
|
|
455 |
|
|
advance = lwres_printaddr(&gnba->addr); |
456 |
|
|
if (advance < 0) |
457 |
|
|
goto trunc; |
458 |
|
|
s += advance; |
459 |
|
|
break; |
460 |
|
|
default: |
461 |
|
|
unsupported++; |
462 |
|
|
break; |
463 |
|
|
} |
464 |
|
|
} else { |
465 |
|
|
/* |
466 |
|
|
* responses |
467 |
|
|
*/ |
468 |
|
|
lwres_gabnresponse_t *gabn; |
469 |
|
|
lwres_gnbaresponse_t *gnba; |
470 |
|
|
lwres_grbnresponse_t *grbn; |
471 |
|
|
u_int32_t l, na; |
472 |
|
|
int i; |
473 |
|
|
|
474 |
|
|
gabn = NULL; |
475 |
|
|
gnba = NULL; |
476 |
|
|
grbn = NULL; |
477 |
|
|
|
478 |
|
|
switch (ntohl(np->opcode)) { |
479 |
|
|
case LWRES_OPCODE_NOOP: |
480 |
|
|
break; |
481 |
|
|
case LWRES_OPCODE_GETADDRSBYNAME: |
482 |
|
|
gabn = (lwres_gabnresponse_t *)(np + 1); |
483 |
|
|
TCHECK(gabn->realnamelen); |
484 |
|
|
/* XXX gabn points to packed struct */ |
485 |
|
|
s = (const char *)&gabn->realnamelen + |
486 |
|
|
sizeof(gabn->realnamelen); |
487 |
|
|
l = ntohs(gabn->realnamelen); |
488 |
|
|
|
489 |
|
|
/* BIND910: not used */ |
490 |
|
|
if (vflag > 2) { |
491 |
|
|
printf(" flags:0x%lx", |
492 |
|
|
(unsigned long)ntohl(gabn->flags)); |
493 |
|
|
} |
494 |
|
|
|
495 |
|
|
printf(" %u/%u", ntohs(gabn->naliases), |
496 |
|
|
ntohs(gabn->naddrs)); |
497 |
|
|
|
498 |
|
|
advance = lwres_printname(l, s); |
499 |
|
|
if (advance < 0) |
500 |
|
|
goto trunc; |
501 |
|
|
s += advance; |
502 |
|
|
|
503 |
|
|
/* aliases */ |
504 |
|
|
na = ntohs(gabn->naliases); |
505 |
|
|
for (i = 0; i < na; i++) { |
506 |
|
|
advance = lwres_printnamelen(s); |
507 |
|
|
if (advance < 0) |
508 |
|
|
goto trunc; |
509 |
|
|
s += advance; |
510 |
|
|
} |
511 |
|
|
|
512 |
|
|
/* addrs */ |
513 |
|
|
na = ntohs(gabn->naddrs); |
514 |
|
|
for (i = 0; i < na; i++) { |
515 |
|
|
advance = lwres_printaddr((lwres_addr_t *)s); |
516 |
|
|
if (advance < 0) |
517 |
|
|
goto trunc; |
518 |
|
|
s += advance; |
519 |
|
|
} |
520 |
|
|
break; |
521 |
|
|
case LWRES_OPCODE_GETNAMEBYADDR: |
522 |
|
|
gnba = (lwres_gnbaresponse_t *)(np + 1); |
523 |
|
|
TCHECK(gnba->realnamelen); |
524 |
|
|
/* XXX gnba points to packed struct */ |
525 |
|
|
s = (const char *)&gnba->realnamelen + |
526 |
|
|
sizeof(gnba->realnamelen); |
527 |
|
|
l = ntohs(gnba->realnamelen); |
528 |
|
|
|
529 |
|
|
/* BIND910: not used */ |
530 |
|
|
if (vflag > 2) { |
531 |
|
|
printf(" flags:0x%lx", |
532 |
|
|
(unsigned long)ntohl(gnba->flags)); |
533 |
|
|
} |
534 |
|
|
|
535 |
|
|
printf(" %u", ntohs(gnba->naliases)); |
536 |
|
|
|
537 |
|
|
advance = lwres_printname(l, s); |
538 |
|
|
if (advance < 0) |
539 |
|
|
goto trunc; |
540 |
|
|
s += advance; |
541 |
|
|
|
542 |
|
|
/* aliases */ |
543 |
|
|
na = ntohs(gnba->naliases); |
544 |
|
|
for (i = 0; i < na; i++) { |
545 |
|
|
advance = lwres_printnamelen(s); |
546 |
|
|
if (advance < 0) |
547 |
|
|
goto trunc; |
548 |
|
|
s += advance; |
549 |
|
|
} |
550 |
|
|
break; |
551 |
|
|
case LWRES_OPCODE_GETRDATABYNAME: |
552 |
|
|
/* XXX no trace, not tested */ |
553 |
|
|
grbn = (lwres_grbnresponse_t *)(np + 1); |
554 |
|
|
TCHECK(grbn->nsigs); |
555 |
|
|
|
556 |
|
|
/* BIND910: not used */ |
557 |
|
|
if (vflag > 2) { |
558 |
|
|
printf(" flags:0x%lx", |
559 |
|
|
(unsigned long)ntohl(grbn->flags)); |
560 |
|
|
} |
561 |
|
|
|
562 |
|
|
printf(" %s", tok2str(ns_type2str, "Type%d", |
563 |
|
|
ntohs(grbn->rdtype))); |
564 |
|
|
if (ntohs(grbn->rdclass) != C_IN) |
565 |
|
|
printf(" %s", tok2str(ns_class2str, "Class%d", |
566 |
|
|
ntohs(grbn->rdclass))); |
567 |
|
|
printf(" TTL "); |
568 |
|
|
relts_print(ntohl(grbn->ttl)); |
569 |
|
|
printf(" %u/%u", ntohs(grbn->nrdatas), |
570 |
|
|
ntohs(grbn->nsigs)); |
571 |
|
|
|
572 |
|
|
/* XXX grbn points to packed struct */ |
573 |
|
|
s = (const char *)&grbn->nsigs+ sizeof(grbn->nsigs); |
574 |
|
|
|
575 |
|
|
advance = lwres_printnamelen(s); |
576 |
|
|
if (advance < 0) |
577 |
|
|
goto trunc; |
578 |
|
|
s += advance; |
579 |
|
|
|
580 |
|
|
/* rdatas */ |
581 |
|
|
na = ntohs(grbn->nrdatas); |
582 |
|
|
if (na > 0) |
583 |
|
|
printf(" "); |
584 |
|
|
|
585 |
|
|
for (i = 0; i < na; i++) { |
586 |
|
|
/* XXX should decode resource data */ |
587 |
|
|
advance = lwres_printb64len(s); |
588 |
|
|
if (advance < 0) |
589 |
|
|
goto trunc; |
590 |
|
|
s += advance; |
591 |
|
|
} |
592 |
|
|
|
593 |
|
|
/* sigs */ |
594 |
|
|
na = ntohs(grbn->nsigs); |
595 |
|
|
if (na > 0) |
596 |
|
|
printf(" "); |
597 |
|
|
|
598 |
|
|
for (i = 0; i < na; i++) { |
599 |
|
|
/* XXX how should we print it? */ |
600 |
|
|
advance = lwres_printb64len(s); |
601 |
|
|
if (advance < 0) |
602 |
|
|
goto trunc; |
603 |
|
|
s += advance; |
604 |
|
|
} |
605 |
|
|
break; |
606 |
|
|
default: |
607 |
|
|
unsupported++; |
608 |
|
|
break; |
609 |
|
|
} |
610 |
|
|
} |
611 |
|
|
|
612 |
|
|
tail: |
613 |
|
|
/* length mismatch */ |
614 |
|
|
if (ntohl(np->length) != length) { |
615 |
|
|
printf(" [len: %lu != %u]", (unsigned long)ntohl(np->length), |
616 |
|
|
length); |
617 |
|
|
} |
618 |
|
|
if (!unsupported && s < (const char *)np + ntohl(np->length)) |
619 |
|
|
printf("[extra]"); |
620 |
|
|
return; |
621 |
|
|
|
622 |
|
|
trunc: |
623 |
|
|
printf("[|lwres]"); |
624 |
|
|
return; |
625 |
|
|
} |