10f74e101Schristos /* 20f74e101Schristos * Copyright (C) 2001 WIDE Project. 30f74e101Schristos * All rights reserved. 40f74e101Schristos * 50f74e101Schristos * Redistribution and use in source and binary forms, with or without 60f74e101Schristos * modification, are permitted provided that the following conditions 70f74e101Schristos * are met: 80f74e101Schristos * 1. Redistributions of source code must retain the above copyright 90f74e101Schristos * notice, this list of conditions and the following disclaimer. 100f74e101Schristos * 2. Redistributions in binary form must reproduce the above copyright 110f74e101Schristos * notice, this list of conditions and the following disclaimer in the 120f74e101Schristos * documentation and/or other materials provided with the distribution. 130f74e101Schristos * 3. Neither the name of the project nor the names of its contributors 140f74e101Schristos * may be used to endorse or promote products derived from this software 150f74e101Schristos * without specific prior written permission. 160f74e101Schristos * 170f74e101Schristos * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 180f74e101Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 190f74e101Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 200f74e101Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 210f74e101Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 220f74e101Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 230f74e101Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 240f74e101Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 250f74e101Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 260f74e101Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 270f74e101Schristos * SUCH DAMAGE. 280f74e101Schristos */ 290f74e101Schristos 3011b3aaa1Schristos #include <sys/cdefs.h> 310f74e101Schristos #ifndef lint 32*26ba0b50Schristos __RCSID("$NetBSD: print-lwres.c,v 1.9 2024/09/02 16:15:32 christos Exp $"); 330f74e101Schristos #endif 340f74e101Schristos 35dc860a36Sspz /* \summary: BIND9 Lightweight Resolver protocol printer */ 36dc860a36Sspz 37c74ad251Schristos #include <config.h> 380f74e101Schristos 39c74ad251Schristos #include "netdissect-stdinc.h" 400f74e101Schristos 41c74ad251Schristos #define ND_LONGJMP_FROM_TCHECK 42fdccd7e4Schristos #include "netdissect.h" 430f74e101Schristos #include "addrtoname.h" 44fdccd7e4Schristos #include "extract.h" 450f74e101Schristos 46c74ad251Schristos #include "nameser.h" 47c74ad251Schristos 480f74e101Schristos /* BIND9 lib/lwres/include/lwres */ 49c74ad251Schristos /* 50c74ad251Schristos * Use nd_uint16_t for lwres_uint16_t 51c74ad251Schristos * Use nd_uint32_t for lwres_uint32_t 52c74ad251Schristos */ 530f74e101Schristos 540f74e101Schristos struct lwres_lwpacket { 55c74ad251Schristos nd_uint32_t length; 56c74ad251Schristos nd_uint16_t version; 57c74ad251Schristos nd_uint16_t pktflags; 58c74ad251Schristos nd_uint32_t serial; 59c74ad251Schristos nd_uint32_t opcode; 60c74ad251Schristos nd_uint32_t result; 61c74ad251Schristos nd_uint32_t recvlength; 62c74ad251Schristos nd_uint16_t authtype; 63c74ad251Schristos nd_uint16_t authlength; 640f74e101Schristos }; 650f74e101Schristos 660f74e101Schristos #define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */ 670f74e101Schristos 680f74e101Schristos #define LWRES_LWPACKETVERSION_0 0 690f74e101Schristos 700f74e101Schristos #define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U 710f74e101Schristos #define LWRES_FLAG_SECUREDATA 0x00000002U 720f74e101Schristos 730f74e101Schristos /* 740f74e101Schristos * no-op 750f74e101Schristos */ 760f74e101Schristos #define LWRES_OPCODE_NOOP 0x00000000U 770f74e101Schristos 780f74e101Schristos typedef struct { 790f74e101Schristos /* public */ 80c74ad251Schristos nd_uint16_t datalength; 810f74e101Schristos /* data follows */ 820f74e101Schristos } lwres_nooprequest_t; 830f74e101Schristos 840f74e101Schristos typedef struct { 850f74e101Schristos /* public */ 86c74ad251Schristos nd_uint16_t datalength; 870f74e101Schristos /* data follows */ 880f74e101Schristos } lwres_noopresponse_t; 890f74e101Schristos 900f74e101Schristos /* 910f74e101Schristos * get addresses by name 920f74e101Schristos */ 930f74e101Schristos #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U 940f74e101Schristos 950f74e101Schristos typedef struct lwres_addr lwres_addr_t; 960f74e101Schristos 970f74e101Schristos struct lwres_addr { 98c74ad251Schristos nd_uint32_t family; 99c74ad251Schristos nd_uint16_t length; 100c74ad251Schristos /* address follows */ 1010f74e101Schristos }; 102c74ad251Schristos #define LWRES_ADDR_LEN 6 1030f74e101Schristos 1040f74e101Schristos typedef struct { 1050f74e101Schristos /* public */ 106c74ad251Schristos nd_uint32_t flags; 107c74ad251Schristos nd_uint32_t addrtypes; 108c74ad251Schristos nd_uint16_t namelen; 1090f74e101Schristos /* name follows */ 1100f74e101Schristos } lwres_gabnrequest_t; 111c74ad251Schristos #define LWRES_GABNREQUEST_LEN 10 1120f74e101Schristos 1130f74e101Schristos typedef struct { 1140f74e101Schristos /* public */ 115c74ad251Schristos nd_uint32_t flags; 116c74ad251Schristos nd_uint16_t naliases; 117c74ad251Schristos nd_uint16_t naddrs; 118c74ad251Schristos nd_uint16_t realnamelen; 1190f74e101Schristos /* aliases follows */ 1200f74e101Schristos /* addrs follows */ 1210f74e101Schristos /* realname follows */ 1220f74e101Schristos } lwres_gabnresponse_t; 123c74ad251Schristos #define LWRES_GABNRESPONSE_LEN 10 1240f74e101Schristos 1250f74e101Schristos /* 1260f74e101Schristos * get name by address 1270f74e101Schristos */ 1280f74e101Schristos #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U 1290f74e101Schristos typedef struct { 1300f74e101Schristos /* public */ 131c74ad251Schristos nd_uint32_t flags; 132c74ad251Schristos /* addr follows */ 1330f74e101Schristos } lwres_gnbarequest_t; 134c74ad251Schristos #define LWRES_GNBAREQUEST_LEN 4 1350f74e101Schristos 1360f74e101Schristos typedef struct { 1370f74e101Schristos /* public */ 138c74ad251Schristos nd_uint32_t flags; 139c74ad251Schristos nd_uint16_t naliases; 140c74ad251Schristos nd_uint16_t realnamelen; 1410f74e101Schristos /* aliases follows */ 1420f74e101Schristos /* realname follows */ 1430f74e101Schristos } lwres_gnbaresponse_t; 144c74ad251Schristos #define LWRES_GNBARESPONSE_LEN 8 1450f74e101Schristos 1460f74e101Schristos /* 1470f74e101Schristos * get rdata by name 1480f74e101Schristos */ 1490f74e101Schristos #define LWRES_OPCODE_GETRDATABYNAME 0x00010003U 1500f74e101Schristos 1510f74e101Schristos typedef struct { 1520f74e101Schristos /* public */ 153c74ad251Schristos nd_uint32_t flags; 154c74ad251Schristos nd_uint16_t rdclass; 155c74ad251Schristos nd_uint16_t rdtype; 156c74ad251Schristos nd_uint16_t namelen; 1570f74e101Schristos /* name follows */ 1580f74e101Schristos } lwres_grbnrequest_t; 159c74ad251Schristos #define LWRES_GRBNREQUEST_LEN 10 1600f74e101Schristos 1610f74e101Schristos typedef struct { 1620f74e101Schristos /* public */ 163c74ad251Schristos nd_uint32_t flags; 164c74ad251Schristos nd_uint16_t rdclass; 165c74ad251Schristos nd_uint16_t rdtype; 166c74ad251Schristos nd_uint32_t ttl; 167c74ad251Schristos nd_uint16_t nrdatas; 168c74ad251Schristos nd_uint16_t nsigs; 1690f74e101Schristos /* realname here (len + name) */ 1700f74e101Schristos /* rdata here (len + name) */ 1710f74e101Schristos /* signatures here (len + name) */ 1720f74e101Schristos } lwres_grbnresponse_t; 173c74ad251Schristos #define LWRES_GRBNRESPONSE_LEN 16 1740f74e101Schristos 1750f74e101Schristos #define LWRDATA_VALIDATED 0x00000001 1760f74e101Schristos 1770f74e101Schristos #define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */ 1780f74e101Schristos #define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */ 1790f74e101Schristos 1800f74e101Schristos #define LWRES_MAX_ALIASES 16 /* max # of aliases */ 1810f74e101Schristos #define LWRES_MAX_ADDRS 64 /* max # of addrs */ 1820f74e101Schristos 183870189d2Schristos static const struct tok opcode[] = { 1840f74e101Schristos { LWRES_OPCODE_NOOP, "noop", }, 1850f74e101Schristos { LWRES_OPCODE_GETADDRSBYNAME, "getaddrsbyname", }, 1860f74e101Schristos { LWRES_OPCODE_GETNAMEBYADDR, "getnamebyaddr", }, 1870f74e101Schristos { LWRES_OPCODE_GETRDATABYNAME, "getrdatabyname", }, 1880f74e101Schristos { 0, NULL, }, 1890f74e101Schristos }; 1900f74e101Schristos 1910f74e101Schristos /* print-domain.c */ 192870189d2Schristos extern const struct tok ns_type2str[]; 193870189d2Schristos extern const struct tok ns_class2str[]; 1940f74e101Schristos 195c74ad251Schristos static unsigned 196b3a00663Schristos lwres_printname(netdissect_options *ndo, 197c74ad251Schristos u_int l, const u_char *p0) 1980f74e101Schristos { 199c74ad251Schristos ND_PRINT(" "); 200c74ad251Schristos (void)nd_printn(ndo, p0, l, NULL); 201c74ad251Schristos p0 += l; 202c74ad251Schristos if (GET_U_1(p0)) 203c74ad251Schristos ND_PRINT(" (not NUL-terminated!)"); 204c74ad251Schristos return l + 1; 2050f74e101Schristos } 2060f74e101Schristos 207c74ad251Schristos static unsigned 208b3a00663Schristos lwres_printnamelen(netdissect_options *ndo, 209c74ad251Schristos const u_char *p) 2100f74e101Schristos { 211b3a00663Schristos uint16_t l; 2120f74e101Schristos int advance; 2130f74e101Schristos 214c74ad251Schristos l = GET_BE_U_2(p); 215b3a00663Schristos advance = lwres_printname(ndo, l, p + 2); 2160f74e101Schristos return 2 + advance; 2170f74e101Schristos } 2180f74e101Schristos 219c74ad251Schristos static unsigned 220b3a00663Schristos lwres_printbinlen(netdissect_options *ndo, 221c74ad251Schristos const u_char *p0) 2220f74e101Schristos { 223c74ad251Schristos const u_char *p; 224b3a00663Schristos uint16_t l; 2250f74e101Schristos int i; 2260f74e101Schristos 2270f74e101Schristos p = p0; 228c74ad251Schristos l = GET_BE_U_2(p); 2290f74e101Schristos p += 2; 230c74ad251Schristos for (i = 0; i < l; i++) { 231c74ad251Schristos ND_PRINT("%02x", GET_U_1(p)); 232c74ad251Schristos p++; 233c74ad251Schristos } 234c74ad251Schristos return 2 + l; 2350f74e101Schristos } 2360f74e101Schristos 2370f74e101Schristos static int 238b3a00663Schristos lwres_printaddr(netdissect_options *ndo, 239c74ad251Schristos const u_char *p0) 2400f74e101Schristos { 241c74ad251Schristos const u_char *p; 242c74ad251Schristos const lwres_addr_t *ap; 243b3a00663Schristos uint16_t l; 2440f74e101Schristos int i; 2450f74e101Schristos 246c74ad251Schristos p = p0; 247c74ad251Schristos ap = (const lwres_addr_t *)p; 248c74ad251Schristos l = GET_BE_U_2(ap->length); 249c74ad251Schristos p += LWRES_ADDR_LEN; 250c74ad251Schristos ND_TCHECK_LEN(p, l); 2510f74e101Schristos 252c74ad251Schristos switch (GET_BE_U_4(ap->family)) { 2530f74e101Schristos case 1: /* IPv4 */ 2540f74e101Schristos if (l < 4) 2550f74e101Schristos return -1; 256c74ad251Schristos ND_PRINT(" %s", GET_IPADDR_STRING(p)); 257c74ad251Schristos p += sizeof(nd_ipv4); 2580f74e101Schristos break; 2590f74e101Schristos case 2: /* IPv6 */ 2600f74e101Schristos if (l < 16) 2610f74e101Schristos return -1; 262c74ad251Schristos ND_PRINT(" %s", GET_IP6ADDR_STRING(p)); 263c74ad251Schristos p += sizeof(nd_ipv6); 2640f74e101Schristos break; 2650f74e101Schristos default: 266c74ad251Schristos ND_PRINT(" %u/", GET_BE_U_4(ap->family)); 267c74ad251Schristos for (i = 0; i < l; i++) { 268c74ad251Schristos ND_PRINT("%02x", GET_U_1(p)); 269c74ad251Schristos p++; 270c74ad251Schristos } 2710f74e101Schristos } 2720f74e101Schristos 273*26ba0b50Schristos return ND_BYTES_BETWEEN(p0, p); 2740f74e101Schristos } 2750f74e101Schristos 2760f74e101Schristos void 277b3a00663Schristos lwres_print(netdissect_options *ndo, 278c74ad251Schristos const u_char *bp, u_int length) 2790f74e101Schristos { 280c74ad251Schristos const u_char *p; 2810f74e101Schristos const struct lwres_lwpacket *np; 282b3a00663Schristos uint32_t v; 283c74ad251Schristos const u_char *s; 2840f74e101Schristos int response; 2850f74e101Schristos int advance; 2860f74e101Schristos int unsupported = 0; 2870f74e101Schristos 288c74ad251Schristos ndo->ndo_protocol = "lwres"; 2890f74e101Schristos np = (const struct lwres_lwpacket *)bp; 290c74ad251Schristos ND_TCHECK_2(np->authlength); 2910f74e101Schristos 292c74ad251Schristos ND_PRINT(" lwres"); 293c74ad251Schristos v = GET_BE_U_2(np->version); 294b3a00663Schristos if (ndo->ndo_vflag || v != LWRES_LWPACKETVERSION_0) 295c74ad251Schristos ND_PRINT(" v%u", v); 2960f74e101Schristos if (v != LWRES_LWPACKETVERSION_0) { 297*26ba0b50Schristos uint32_t pkt_len = GET_BE_U_4(np->length); 298*26ba0b50Schristos ND_TCHECK_LEN(bp, pkt_len); 299*26ba0b50Schristos s = bp + pkt_len; 3000f74e101Schristos goto tail; 3010f74e101Schristos } 3020f74e101Schristos 303c74ad251Schristos response = GET_BE_U_2(np->pktflags) & LWRES_LWPACKETFLAG_RESPONSE; 3040f74e101Schristos 3050f74e101Schristos /* opcode and pktflags */ 306c74ad251Schristos v = GET_BE_U_4(np->opcode); 307c74ad251Schristos ND_PRINT(" %s%s", tok2str(opcode, "#0x%x", v), response ? "" : "?"); 3080f74e101Schristos 3090f74e101Schristos /* pktflags */ 310c74ad251Schristos v = GET_BE_U_2(np->pktflags); 3110f74e101Schristos if (v & ~LWRES_LWPACKETFLAG_RESPONSE) 312c74ad251Schristos ND_PRINT("[0x%x]", v); 3130f74e101Schristos 314b3a00663Schristos if (ndo->ndo_vflag > 1) { 315c74ad251Schristos ND_PRINT(" ("); /*)*/ 316c74ad251Schristos ND_PRINT("serial:0x%x", GET_BE_U_4(np->serial)); 317c74ad251Schristos ND_PRINT(" result:0x%x", GET_BE_U_4(np->result)); 318c74ad251Schristos ND_PRINT(" recvlen:%u", GET_BE_U_4(np->recvlength)); 3190f74e101Schristos /* BIND910: not used */ 320b3a00663Schristos if (ndo->ndo_vflag > 2) { 321c74ad251Schristos ND_PRINT(" authtype:0x%x", GET_BE_U_2(np->authtype)); 322c74ad251Schristos ND_PRINT(" authlen:%u", GET_BE_U_2(np->authlength)); 3230f74e101Schristos } 3240f74e101Schristos /*(*/ 325c74ad251Schristos ND_PRINT(")"); 3260f74e101Schristos } 3270f74e101Schristos 3280f74e101Schristos /* per-opcode content */ 3290f74e101Schristos if (!response) { 3300f74e101Schristos /* 3310f74e101Schristos * queries 3320f74e101Schristos */ 333fdccd7e4Schristos const lwres_gabnrequest_t *gabn; 334fdccd7e4Schristos const lwres_gnbarequest_t *gnba; 335fdccd7e4Schristos const lwres_grbnrequest_t *grbn; 336b3a00663Schristos uint32_t l; 3370f74e101Schristos 3380f74e101Schristos gabn = NULL; 3390f74e101Schristos gnba = NULL; 3400f74e101Schristos grbn = NULL; 3410f74e101Schristos 342c74ad251Schristos p = (const u_char *)(np + 1); 343c74ad251Schristos switch (GET_BE_U_4(np->opcode)) { 3440f74e101Schristos case LWRES_OPCODE_NOOP: 345c74ad251Schristos s = p; 3460f74e101Schristos break; 3470f74e101Schristos case LWRES_OPCODE_GETADDRSBYNAME: 348c74ad251Schristos gabn = (const lwres_gabnrequest_t *)p; 349c74ad251Schristos ND_TCHECK_2(gabn->namelen); 3500f74e101Schristos 3510f74e101Schristos /* BIND910: not used */ 352b3a00663Schristos if (ndo->ndo_vflag > 2) { 353c74ad251Schristos ND_PRINT(" flags:0x%x", 354c74ad251Schristos GET_BE_U_4(gabn->flags)); 3550f74e101Schristos } 3560f74e101Schristos 357c74ad251Schristos v = GET_BE_U_4(gabn->addrtypes); 3580f74e101Schristos switch (v & (LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) { 3590f74e101Schristos case LWRES_ADDRTYPE_V4: 360c74ad251Schristos ND_PRINT(" IPv4"); 3610f74e101Schristos break; 3620f74e101Schristos case LWRES_ADDRTYPE_V6: 363c74ad251Schristos ND_PRINT(" IPv6"); 3640f74e101Schristos break; 3650f74e101Schristos case LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6: 366c74ad251Schristos ND_PRINT(" IPv4/6"); 3670f74e101Schristos break; 3680f74e101Schristos } 3690f74e101Schristos if (v & ~(LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) 370c74ad251Schristos ND_PRINT("[0x%x]", v); 3710f74e101Schristos 372c74ad251Schristos s = p + LWRES_GABNREQUEST_LEN; 373c74ad251Schristos l = GET_BE_U_2(gabn->namelen); 374b3a00663Schristos advance = lwres_printname(ndo, l, s); 3750f74e101Schristos s += advance; 3760f74e101Schristos break; 3770f74e101Schristos case LWRES_OPCODE_GETNAMEBYADDR: 378c74ad251Schristos gnba = (const lwres_gnbarequest_t *)p; 379c74ad251Schristos ND_TCHECK_4(gnba->flags); 3800f74e101Schristos 3810f74e101Schristos /* BIND910: not used */ 382b3a00663Schristos if (ndo->ndo_vflag > 2) { 383c74ad251Schristos ND_PRINT(" flags:0x%x", 384c74ad251Schristos GET_BE_U_4(gnba->flags)); 3850f74e101Schristos } 3860f74e101Schristos 387c74ad251Schristos s = p + LWRES_GNBAREQUEST_LEN; 388c74ad251Schristos advance = lwres_printaddr(ndo, s); 3890f74e101Schristos if (advance < 0) 390c74ad251Schristos goto invalid; 3910f74e101Schristos s += advance; 3920f74e101Schristos break; 3930f74e101Schristos case LWRES_OPCODE_GETRDATABYNAME: 3940f74e101Schristos /* XXX no trace, not tested */ 395c74ad251Schristos grbn = (const lwres_grbnrequest_t *)p; 396c74ad251Schristos ND_TCHECK_2(grbn->namelen); 3970f74e101Schristos 3980f74e101Schristos /* BIND910: not used */ 399b3a00663Schristos if (ndo->ndo_vflag > 2) { 400c74ad251Schristos ND_PRINT(" flags:0x%x", 401c74ad251Schristos GET_BE_U_4(grbn->flags)); 4020f74e101Schristos } 4030f74e101Schristos 404c74ad251Schristos ND_PRINT(" %s", tok2str(ns_type2str, "Type%u", 405c74ad251Schristos GET_BE_U_2(grbn->rdtype))); 406c74ad251Schristos if (GET_BE_U_2(grbn->rdclass) != C_IN) { 407c74ad251Schristos ND_PRINT(" %s", tok2str(ns_class2str, "Class%u", 408c74ad251Schristos GET_BE_U_2(grbn->rdclass))); 4090f74e101Schristos } 4100f74e101Schristos 411c74ad251Schristos s = p + LWRES_GRBNREQUEST_LEN; 412c74ad251Schristos l = GET_BE_U_2(grbn->namelen); 413b3a00663Schristos advance = lwres_printname(ndo, l, s); 4140f74e101Schristos s += advance; 4150f74e101Schristos break; 4160f74e101Schristos default: 417c74ad251Schristos s = p; 4180f74e101Schristos unsupported++; 4190f74e101Schristos break; 4200f74e101Schristos } 4210f74e101Schristos } else { 4220f74e101Schristos /* 4230f74e101Schristos * responses 4240f74e101Schristos */ 425fdccd7e4Schristos const lwres_gabnresponse_t *gabn; 426fdccd7e4Schristos const lwres_gnbaresponse_t *gnba; 427fdccd7e4Schristos const lwres_grbnresponse_t *grbn; 428b3a00663Schristos uint32_t l, na; 429b3a00663Schristos uint32_t i; 4300f74e101Schristos 4310f74e101Schristos gabn = NULL; 4320f74e101Schristos gnba = NULL; 4330f74e101Schristos grbn = NULL; 4340f74e101Schristos 435c74ad251Schristos p = (const u_char *)(np + 1); 436c74ad251Schristos switch (GET_BE_U_4(np->opcode)) { 4370f74e101Schristos case LWRES_OPCODE_NOOP: 438c74ad251Schristos s = p; 4390f74e101Schristos break; 4400f74e101Schristos case LWRES_OPCODE_GETADDRSBYNAME: 441c74ad251Schristos gabn = (const lwres_gabnresponse_t *)p; 442c74ad251Schristos ND_TCHECK_2(gabn->realnamelen); 4430f74e101Schristos 4440f74e101Schristos /* BIND910: not used */ 445b3a00663Schristos if (ndo->ndo_vflag > 2) { 446c74ad251Schristos ND_PRINT(" flags:0x%x", 447c74ad251Schristos GET_BE_U_4(gabn->flags)); 4480f74e101Schristos } 4490f74e101Schristos 450c74ad251Schristos ND_PRINT(" %u/%u", GET_BE_U_2(gabn->naliases), 451c74ad251Schristos GET_BE_U_2(gabn->naddrs)); 4520f74e101Schristos 453c74ad251Schristos s = p + LWRES_GABNRESPONSE_LEN; 454c74ad251Schristos l = GET_BE_U_2(gabn->realnamelen); 455b3a00663Schristos advance = lwres_printname(ndo, l, s); 4560f74e101Schristos s += advance; 4570f74e101Schristos 4580f74e101Schristos /* aliases */ 459c74ad251Schristos na = GET_BE_U_2(gabn->naliases); 4600f74e101Schristos for (i = 0; i < na; i++) { 461b3a00663Schristos advance = lwres_printnamelen(ndo, s); 4620f74e101Schristos s += advance; 4630f74e101Schristos } 4640f74e101Schristos 4650f74e101Schristos /* addrs */ 466c74ad251Schristos na = GET_BE_U_2(gabn->naddrs); 4670f74e101Schristos for (i = 0; i < na; i++) { 468c74ad251Schristos advance = lwres_printaddr(ndo, s); 4690f74e101Schristos if (advance < 0) 470c74ad251Schristos goto invalid; 4710f74e101Schristos s += advance; 4720f74e101Schristos } 4730f74e101Schristos break; 4740f74e101Schristos case LWRES_OPCODE_GETNAMEBYADDR: 475c74ad251Schristos gnba = (const lwres_gnbaresponse_t *)p; 476c74ad251Schristos ND_TCHECK_2(gnba->realnamelen); 4770f74e101Schristos 4780f74e101Schristos /* BIND910: not used */ 479b3a00663Schristos if (ndo->ndo_vflag > 2) { 480c74ad251Schristos ND_PRINT(" flags:0x%x", 481c74ad251Schristos GET_BE_U_4(gnba->flags)); 4820f74e101Schristos } 4830f74e101Schristos 484c74ad251Schristos ND_PRINT(" %u", GET_BE_U_2(gnba->naliases)); 4850f74e101Schristos 486c74ad251Schristos s = p + LWRES_GNBARESPONSE_LEN; 487c74ad251Schristos l = GET_BE_U_2(gnba->realnamelen); 488b3a00663Schristos advance = lwres_printname(ndo, l, s); 4890f74e101Schristos s += advance; 4900f74e101Schristos 4910f74e101Schristos /* aliases */ 492c74ad251Schristos na = GET_BE_U_2(gnba->naliases); 4930f74e101Schristos for (i = 0; i < na; i++) { 494b3a00663Schristos advance = lwres_printnamelen(ndo, s); 4950f74e101Schristos s += advance; 4960f74e101Schristos } 4970f74e101Schristos break; 4980f74e101Schristos case LWRES_OPCODE_GETRDATABYNAME: 4990f74e101Schristos /* XXX no trace, not tested */ 500c74ad251Schristos grbn = (const lwres_grbnresponse_t *)p; 501c74ad251Schristos ND_TCHECK_2(grbn->nsigs); 5020f74e101Schristos 5030f74e101Schristos /* BIND910: not used */ 504b3a00663Schristos if (ndo->ndo_vflag > 2) { 505c74ad251Schristos ND_PRINT(" flags:0x%x", 506c74ad251Schristos GET_BE_U_4(grbn->flags)); 5070f74e101Schristos } 5080f74e101Schristos 509c74ad251Schristos ND_PRINT(" %s", tok2str(ns_type2str, "Type%u", 510c74ad251Schristos GET_BE_U_2(grbn->rdtype))); 511c74ad251Schristos if (GET_BE_U_2(grbn->rdclass) != C_IN) { 512c74ad251Schristos ND_PRINT(" %s", tok2str(ns_class2str, "Class%u", 513c74ad251Schristos GET_BE_U_2(grbn->rdclass))); 5140f74e101Schristos } 515c74ad251Schristos ND_PRINT(" TTL "); 516c74ad251Schristos unsigned_relts_print(ndo, 517c74ad251Schristos GET_BE_U_4(grbn->ttl)); 518c74ad251Schristos ND_PRINT(" %u/%u", GET_BE_U_2(grbn->nrdatas), 519c74ad251Schristos GET_BE_U_2(grbn->nsigs)); 5200f74e101Schristos 521c74ad251Schristos s = p + LWRES_GRBNRESPONSE_LEN; 522b3a00663Schristos advance = lwres_printnamelen(ndo, s); 5230f74e101Schristos s += advance; 5240f74e101Schristos 5250f74e101Schristos /* rdatas */ 526c74ad251Schristos na = GET_BE_U_2(grbn->nrdatas); 5270f74e101Schristos for (i = 0; i < na; i++) { 5280f74e101Schristos /* XXX should decode resource data */ 529b3a00663Schristos advance = lwres_printbinlen(ndo, s); 5300f74e101Schristos s += advance; 5310f74e101Schristos } 5320f74e101Schristos 5330f74e101Schristos /* sigs */ 534c74ad251Schristos na = GET_BE_U_2(grbn->nsigs); 5350f74e101Schristos for (i = 0; i < na; i++) { 5360f74e101Schristos /* XXX how should we print it? */ 537b3a00663Schristos advance = lwres_printbinlen(ndo, s); 5380f74e101Schristos s += advance; 5390f74e101Schristos } 5400f74e101Schristos break; 5410f74e101Schristos default: 542c74ad251Schristos s = p; 5430f74e101Schristos unsupported++; 5440f74e101Schristos break; 5450f74e101Schristos } 5460f74e101Schristos } 5470f74e101Schristos 5480f74e101Schristos tail: 5490f74e101Schristos /* length mismatch */ 550c74ad251Schristos if (GET_BE_U_4(np->length) != length) { 551c74ad251Schristos ND_PRINT(" [len: %u != %u]", GET_BE_U_4(np->length), 552c74ad251Schristos length); 5530f74e101Schristos } 554*26ba0b50Schristos if (!unsupported && ND_BYTES_BETWEEN(bp, s) < GET_BE_U_4(np->length)) 555c74ad251Schristos ND_PRINT("[extra]"); 5560f74e101Schristos return; 5570f74e101Schristos 558c74ad251Schristos invalid: 559c74ad251Schristos nd_print_invalid(ndo); 5600f74e101Schristos } 561