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