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