198524Sfenner/* 298524Sfenner * Copyright (C) 2001 WIDE Project. 398524Sfenner * All rights reserved. 498524Sfenner * 598524Sfenner * Redistribution and use in source and binary forms, with or without 698524Sfenner * modification, are permitted provided that the following conditions 798524Sfenner * are met: 898524Sfenner * 1. Redistributions of source code must retain the above copyright 998524Sfenner * notice, this list of conditions and the following disclaimer. 1098524Sfenner * 2. Redistributions in binary form must reproduce the above copyright 1198524Sfenner * notice, this list of conditions and the following disclaimer in the 1298524Sfenner * documentation and/or other materials provided with the distribution. 1398524Sfenner * 3. Neither the name of the project nor the names of its contributors 1498524Sfenner * may be used to endorse or promote products derived from this software 1598524Sfenner * without specific prior written permission. 1698524Sfenner * 1798524Sfenner * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 1898524Sfenner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1998524Sfenner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2098524Sfenner * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2198524Sfenner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2298524Sfenner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2398524Sfenner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2498524Sfenner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2598524Sfenner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2698524Sfenner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2798524Sfenner * SUCH DAMAGE. 2898524Sfenner */ 2998524Sfenner 30276788Sdelphij#define NETDISSECT_REWORKED 3198524Sfenner#ifdef HAVE_CONFIG_H 3298524Sfenner#include "config.h" 3398524Sfenner#endif 3498524Sfenner 35127668Sbms#include <tcpdump-stdinc.h> 3698524Sfenner 3798524Sfenner#include "nameser.h" 3898524Sfenner 3998524Sfenner#include <stdio.h> 4098524Sfenner#include <string.h> 4198524Sfenner 4298524Sfenner#include "interface.h" 4398524Sfenner#include "addrtoname.h" 4498524Sfenner#include "extract.h" /* must come after interface.h */ 4598524Sfenner 4698524Sfenner/* BIND9 lib/lwres/include/lwres */ 47276788Sdelphijtypedef uint32_t lwres_uint32_t; 48276788Sdelphijtypedef uint16_t lwres_uint16_t; 49276788Sdelphijtypedef uint8_t lwres_uint8_t; 5098524Sfenner 5198524Sfennerstruct lwres_lwpacket { 5298524Sfenner lwres_uint32_t length; 5398524Sfenner lwres_uint16_t version; 5498524Sfenner lwres_uint16_t pktflags; 5598524Sfenner lwres_uint32_t serial; 5698524Sfenner lwres_uint32_t opcode; 5798524Sfenner lwres_uint32_t result; 5898524Sfenner lwres_uint32_t recvlength; 5998524Sfenner lwres_uint16_t authtype; 6098524Sfenner lwres_uint16_t authlength; 6198524Sfenner}; 6298524Sfenner 6398524Sfenner#define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */ 6498524Sfenner 6598524Sfenner#define LWRES_LWPACKETVERSION_0 0 6698524Sfenner 6798524Sfenner#define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U 6898524Sfenner#define LWRES_FLAG_SECUREDATA 0x00000002U 6998524Sfenner 7098524Sfenner/* 7198524Sfenner * no-op 7298524Sfenner */ 7398524Sfenner#define LWRES_OPCODE_NOOP 0x00000000U 7498524Sfenner 7598524Sfennertypedef struct { 7698524Sfenner /* public */ 7798524Sfenner lwres_uint16_t datalength; 7898524Sfenner /* data follows */ 7998524Sfenner} lwres_nooprequest_t; 8098524Sfenner 8198524Sfennertypedef struct { 8298524Sfenner /* public */ 8398524Sfenner lwres_uint16_t datalength; 8498524Sfenner /* data follows */ 8598524Sfenner} lwres_noopresponse_t; 8698524Sfenner 8798524Sfenner/* 8898524Sfenner * get addresses by name 8998524Sfenner */ 9098524Sfenner#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U 9198524Sfenner 9298524Sfennertypedef struct lwres_addr lwres_addr_t; 9398524Sfenner 9498524Sfennerstruct lwres_addr { 9598524Sfenner lwres_uint32_t family; 9698524Sfenner lwres_uint16_t length; 9798524Sfenner /* address folows */ 9898524Sfenner}; 9998524Sfenner 10098524Sfennertypedef struct { 10198524Sfenner /* public */ 10298524Sfenner lwres_uint32_t flags; 10398524Sfenner lwres_uint32_t addrtypes; 10498524Sfenner lwres_uint16_t namelen; 10598524Sfenner /* name follows */ 10698524Sfenner} lwres_gabnrequest_t; 10798524Sfenner 10898524Sfennertypedef struct { 10998524Sfenner /* public */ 11098524Sfenner lwres_uint32_t flags; 11198524Sfenner lwres_uint16_t naliases; 11298524Sfenner lwres_uint16_t naddrs; 11398524Sfenner lwres_uint16_t realnamelen; 11498524Sfenner /* aliases follows */ 11598524Sfenner /* addrs follows */ 11698524Sfenner /* realname follows */ 11798524Sfenner} lwres_gabnresponse_t; 11898524Sfenner 11998524Sfenner/* 12098524Sfenner * get name by address 12198524Sfenner */ 12298524Sfenner#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U 12398524Sfennertypedef struct { 12498524Sfenner /* public */ 12598524Sfenner lwres_uint32_t flags; 12698524Sfenner lwres_addr_t addr; 12798524Sfenner /* addr body follows */ 12898524Sfenner} lwres_gnbarequest_t; 12998524Sfenner 13098524Sfennertypedef struct { 13198524Sfenner /* public */ 13298524Sfenner lwres_uint32_t flags; 13398524Sfenner lwres_uint16_t naliases; 13498524Sfenner lwres_uint16_t realnamelen; 13598524Sfenner /* aliases follows */ 13698524Sfenner /* realname follows */ 13798524Sfenner} lwres_gnbaresponse_t; 13898524Sfenner 13998524Sfenner/* 14098524Sfenner * get rdata by name 14198524Sfenner */ 14298524Sfenner#define LWRES_OPCODE_GETRDATABYNAME 0x00010003U 14398524Sfenner 14498524Sfennertypedef struct { 14598524Sfenner /* public */ 14698524Sfenner lwres_uint32_t flags; 14798524Sfenner lwres_uint16_t rdclass; 14898524Sfenner lwres_uint16_t rdtype; 14998524Sfenner lwres_uint16_t namelen; 15098524Sfenner /* name follows */ 15198524Sfenner} lwres_grbnrequest_t; 15298524Sfenner 15398524Sfennertypedef struct { 15498524Sfenner /* public */ 15598524Sfenner lwres_uint32_t flags; 15698524Sfenner lwres_uint16_t rdclass; 15798524Sfenner lwres_uint16_t rdtype; 15898524Sfenner lwres_uint32_t ttl; 15998524Sfenner lwres_uint16_t nrdatas; 16098524Sfenner lwres_uint16_t nsigs; 16198524Sfenner /* realname here (len + name) */ 16298524Sfenner /* rdata here (len + name) */ 16398524Sfenner /* signatures here (len + name) */ 16498524Sfenner} lwres_grbnresponse_t; 16598524Sfenner 16698524Sfenner#define LWRDATA_VALIDATED 0x00000001 16798524Sfenner 16898524Sfenner#define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */ 16998524Sfenner#define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */ 17098524Sfenner 17198524Sfenner#define LWRES_MAX_ALIASES 16 /* max # of aliases */ 17298524Sfenner#define LWRES_MAX_ADDRS 64 /* max # of addrs */ 17398524Sfenner 174276788Sdelphijstatic const struct tok opcode[] = { 17598524Sfenner { LWRES_OPCODE_NOOP, "noop", }, 17698524Sfenner { LWRES_OPCODE_GETADDRSBYNAME, "getaddrsbyname", }, 17798524Sfenner { LWRES_OPCODE_GETNAMEBYADDR, "getnamebyaddr", }, 17898524Sfenner { LWRES_OPCODE_GETRDATABYNAME, "getrdatabyname", }, 17998524Sfenner { 0, NULL, }, 18098524Sfenner}; 18198524Sfenner 18298524Sfenner/* print-domain.c */ 183276788Sdelphijextern const struct tok ns_type2str[]; 184276788Sdelphijextern const struct tok ns_class2str[]; 18598524Sfenner 18698524Sfennerstatic int 187276788Sdelphijlwres_printname(netdissect_options *ndo, 188276788Sdelphij size_t l, const char *p0) 18998524Sfenner{ 19098524Sfenner const char *p; 191127668Sbms size_t i; 19298524Sfenner 19398524Sfenner p = p0; 19498524Sfenner /* + 1 for terminating \0 */ 195276788Sdelphij if (p + l + 1 > (const char *)ndo->ndo_snapend) 19698524Sfenner goto trunc; 19798524Sfenner 198276788Sdelphij ND_PRINT((ndo, " ")); 19998524Sfenner for (i = 0; i < l; i++) 200276788Sdelphij safeputchar(ndo, *p++); 20198524Sfenner p++; /* skip terminating \0 */ 20298524Sfenner 20398524Sfenner return p - p0; 20498524Sfenner 20598524Sfenner trunc: 20698524Sfenner return -1; 20798524Sfenner} 20898524Sfenner 20998524Sfennerstatic int 210276788Sdelphijlwres_printnamelen(netdissect_options *ndo, 211276788Sdelphij const char *p) 21298524Sfenner{ 213276788Sdelphij uint16_t l; 21498524Sfenner int advance; 21598524Sfenner 216276788Sdelphij if (p + 2 > (const char *)ndo->ndo_snapend) 21798524Sfenner goto trunc; 21898524Sfenner l = EXTRACT_16BITS(p); 219276788Sdelphij advance = lwres_printname(ndo, l, p + 2); 22098524Sfenner if (advance < 0) 22198524Sfenner goto trunc; 22298524Sfenner return 2 + advance; 22398524Sfenner 22498524Sfenner trunc: 22598524Sfenner return -1; 22698524Sfenner} 22798524Sfenner 22898524Sfennerstatic int 229276788Sdelphijlwres_printbinlen(netdissect_options *ndo, 230276788Sdelphij const char *p0) 23198524Sfenner{ 23298524Sfenner const char *p; 233276788Sdelphij uint16_t l; 23498524Sfenner int i; 23598524Sfenner 23698524Sfenner p = p0; 237276788Sdelphij if (p + 2 > (const char *)ndo->ndo_snapend) 23898524Sfenner goto trunc; 23998524Sfenner l = EXTRACT_16BITS(p); 240276788Sdelphij if (p + 2 + l > (const char *)ndo->ndo_snapend) 24198524Sfenner goto trunc; 24298524Sfenner p += 2; 24398524Sfenner for (i = 0; i < l; i++) 244276788Sdelphij ND_PRINT((ndo, "%02x", *p++)); 24598524Sfenner return p - p0; 24698524Sfenner 24798524Sfenner trunc: 24898524Sfenner return -1; 24998524Sfenner} 25098524Sfenner 25198524Sfennerstatic int 252276788Sdelphijlwres_printaddr(netdissect_options *ndo, 253276788Sdelphij lwres_addr_t *ap) 25498524Sfenner{ 255276788Sdelphij uint16_t l; 25698524Sfenner const char *p; 25798524Sfenner int i; 25898524Sfenner 259276788Sdelphij ND_TCHECK(ap->length); 260127668Sbms l = EXTRACT_16BITS(&ap->length); 26198524Sfenner /* XXX ap points to packed struct */ 26298524Sfenner p = (const char *)&ap->length + sizeof(ap->length); 263276788Sdelphij ND_TCHECK2(*p, l); 26498524Sfenner 265127668Sbms switch (EXTRACT_32BITS(&ap->family)) { 26698524Sfenner case 1: /* IPv4 */ 267127668Sbms if (l < 4) 268127668Sbms return -1; 269276788Sdelphij ND_PRINT((ndo, " %s", ipaddr_string(ndo, p))); 27098524Sfenner p += sizeof(struct in_addr); 27198524Sfenner break; 27298524Sfenner#ifdef INET6 27398524Sfenner case 2: /* IPv6 */ 274127668Sbms if (l < 16) 275127668Sbms return -1; 276276788Sdelphij ND_PRINT((ndo, " %s", ip6addr_string(ndo, p))); 27798524Sfenner p += sizeof(struct in6_addr); 27898524Sfenner break; 27998524Sfenner#endif 28098524Sfenner default: 281276788Sdelphij ND_PRINT((ndo, " %u/", EXTRACT_32BITS(&ap->family))); 28298524Sfenner for (i = 0; i < l; i++) 283276788Sdelphij ND_PRINT((ndo, "%02x", *p++)); 28498524Sfenner } 28598524Sfenner 28698524Sfenner return p - (const char *)ap; 28798524Sfenner 28898524Sfenner trunc: 28998524Sfenner return -1; 29098524Sfenner} 29198524Sfenner 29298524Sfennervoid 293276788Sdelphijlwres_print(netdissect_options *ndo, 294276788Sdelphij register const u_char *bp, u_int length) 29598524Sfenner{ 29698524Sfenner const struct lwres_lwpacket *np; 297276788Sdelphij uint32_t v; 29898524Sfenner const char *s; 29998524Sfenner int response; 30098524Sfenner int advance; 30198524Sfenner int unsupported = 0; 30298524Sfenner 30398524Sfenner np = (const struct lwres_lwpacket *)bp; 304276788Sdelphij ND_TCHECK(np->authlength); 30598524Sfenner 306276788Sdelphij ND_PRINT((ndo, " lwres")); 307127668Sbms v = EXTRACT_16BITS(&np->version); 308276788Sdelphij if (ndo->ndo_vflag || v != LWRES_LWPACKETVERSION_0) 309276788Sdelphij ND_PRINT((ndo, " v%u", v)); 31098524Sfenner if (v != LWRES_LWPACKETVERSION_0) { 311127668Sbms s = (const char *)np + EXTRACT_32BITS(&np->length); 31298524Sfenner goto tail; 31398524Sfenner } 31498524Sfenner 315127668Sbms response = EXTRACT_16BITS(&np->pktflags) & LWRES_LWPACKETFLAG_RESPONSE; 31698524Sfenner 31798524Sfenner /* opcode and pktflags */ 318127668Sbms v = EXTRACT_32BITS(&np->opcode); 31998524Sfenner s = tok2str(opcode, "#0x%x", v); 320276788Sdelphij ND_PRINT((ndo, " %s%s", s, response ? "" : "?")); 32198524Sfenner 32298524Sfenner /* pktflags */ 323127668Sbms v = EXTRACT_16BITS(&np->pktflags); 32498524Sfenner if (v & ~LWRES_LWPACKETFLAG_RESPONSE) 325276788Sdelphij ND_PRINT((ndo, "[0x%x]", v)); 32698524Sfenner 327276788Sdelphij if (ndo->ndo_vflag > 1) { 328276788Sdelphij ND_PRINT((ndo, " (")); /*)*/ 329276788Sdelphij ND_PRINT((ndo, "serial:0x%x", EXTRACT_32BITS(&np->serial))); 330276788Sdelphij ND_PRINT((ndo, " result:0x%x", EXTRACT_32BITS(&np->result))); 331276788Sdelphij ND_PRINT((ndo, " recvlen:%u", EXTRACT_32BITS(&np->recvlength))); 33298524Sfenner /* BIND910: not used */ 333276788Sdelphij if (ndo->ndo_vflag > 2) { 334276788Sdelphij ND_PRINT((ndo, " authtype:0x%x", EXTRACT_16BITS(&np->authtype))); 335276788Sdelphij ND_PRINT((ndo, " authlen:%u", EXTRACT_16BITS(&np->authlength))); 33698524Sfenner } 33798524Sfenner /*(*/ 338276788Sdelphij ND_PRINT((ndo, ")")); 33998524Sfenner } 34098524Sfenner 34198524Sfenner /* per-opcode content */ 34298524Sfenner if (!response) { 34398524Sfenner /* 34498524Sfenner * queries 34598524Sfenner */ 34698524Sfenner lwres_gabnrequest_t *gabn; 34798524Sfenner lwres_gnbarequest_t *gnba; 34898524Sfenner lwres_grbnrequest_t *grbn; 349276788Sdelphij uint32_t l; 35098524Sfenner 35198524Sfenner gabn = NULL; 35298524Sfenner gnba = NULL; 35398524Sfenner grbn = NULL; 35498524Sfenner 355127668Sbms switch (EXTRACT_32BITS(&np->opcode)) { 35698524Sfenner case LWRES_OPCODE_NOOP: 35798524Sfenner break; 35898524Sfenner case LWRES_OPCODE_GETADDRSBYNAME: 35998524Sfenner gabn = (lwres_gabnrequest_t *)(np + 1); 360276788Sdelphij ND_TCHECK(gabn->namelen); 36198524Sfenner /* XXX gabn points to packed struct */ 36298524Sfenner s = (const char *)&gabn->namelen + 36398524Sfenner sizeof(gabn->namelen); 364127668Sbms l = EXTRACT_16BITS(&gabn->namelen); 36598524Sfenner 36698524Sfenner /* BIND910: not used */ 367276788Sdelphij if (ndo->ndo_vflag > 2) { 368276788Sdelphij ND_PRINT((ndo, " flags:0x%x", 369276788Sdelphij EXTRACT_32BITS(&gabn->flags))); 37098524Sfenner } 37198524Sfenner 372127668Sbms v = EXTRACT_32BITS(&gabn->addrtypes); 37398524Sfenner switch (v & (LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) { 37498524Sfenner case LWRES_ADDRTYPE_V4: 375276788Sdelphij ND_PRINT((ndo, " IPv4")); 37698524Sfenner break; 37798524Sfenner case LWRES_ADDRTYPE_V6: 378276788Sdelphij ND_PRINT((ndo, " IPv6")); 37998524Sfenner break; 38098524Sfenner case LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6: 381276788Sdelphij ND_PRINT((ndo, " IPv4/6")); 38298524Sfenner break; 38398524Sfenner } 38498524Sfenner if (v & ~(LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) 385276788Sdelphij ND_PRINT((ndo, "[0x%x]", v)); 38698524Sfenner 387276788Sdelphij advance = lwres_printname(ndo, l, s); 38898524Sfenner if (advance < 0) 38998524Sfenner goto trunc; 39098524Sfenner s += advance; 39198524Sfenner break; 39298524Sfenner case LWRES_OPCODE_GETNAMEBYADDR: 39398524Sfenner gnba = (lwres_gnbarequest_t *)(np + 1); 394276788Sdelphij ND_TCHECK(gnba->addr); 39598524Sfenner 39698524Sfenner /* BIND910: not used */ 397276788Sdelphij if (ndo->ndo_vflag > 2) { 398276788Sdelphij ND_PRINT((ndo, " flags:0x%x", 399276788Sdelphij EXTRACT_32BITS(&gnba->flags))); 40098524Sfenner } 40198524Sfenner 40298524Sfenner s = (const char *)&gnba->addr; 40398524Sfenner 404276788Sdelphij advance = lwres_printaddr(ndo, &gnba->addr); 40598524Sfenner if (advance < 0) 40698524Sfenner goto trunc; 40798524Sfenner s += advance; 40898524Sfenner break; 40998524Sfenner case LWRES_OPCODE_GETRDATABYNAME: 41098524Sfenner /* XXX no trace, not tested */ 41198524Sfenner grbn = (lwres_grbnrequest_t *)(np + 1); 412276788Sdelphij ND_TCHECK(grbn->namelen); 41398524Sfenner 41498524Sfenner /* BIND910: not used */ 415276788Sdelphij if (ndo->ndo_vflag > 2) { 416276788Sdelphij ND_PRINT((ndo, " flags:0x%x", 417276788Sdelphij EXTRACT_32BITS(&grbn->flags))); 41898524Sfenner } 41998524Sfenner 420276788Sdelphij ND_PRINT((ndo, " %s", tok2str(ns_type2str, "Type%d", 421276788Sdelphij EXTRACT_16BITS(&grbn->rdtype)))); 422127668Sbms if (EXTRACT_16BITS(&grbn->rdclass) != C_IN) { 423276788Sdelphij ND_PRINT((ndo, " %s", tok2str(ns_class2str, "Class%d", 424276788Sdelphij EXTRACT_16BITS(&grbn->rdclass)))); 425127668Sbms } 42698524Sfenner 42798524Sfenner /* XXX grbn points to packed struct */ 42898524Sfenner s = (const char *)&grbn->namelen + 42998524Sfenner sizeof(grbn->namelen); 430127668Sbms l = EXTRACT_16BITS(&grbn->namelen); 43198524Sfenner 432276788Sdelphij advance = lwres_printname(ndo, l, s); 43398524Sfenner if (advance < 0) 43498524Sfenner goto trunc; 43598524Sfenner s += advance; 43698524Sfenner break; 43798524Sfenner default: 43898524Sfenner unsupported++; 43998524Sfenner break; 44098524Sfenner } 44198524Sfenner } else { 44298524Sfenner /* 44398524Sfenner * responses 44498524Sfenner */ 44598524Sfenner lwres_gabnresponse_t *gabn; 44698524Sfenner lwres_gnbaresponse_t *gnba; 44798524Sfenner lwres_grbnresponse_t *grbn; 448276788Sdelphij uint32_t l, na; 449276788Sdelphij uint32_t i; 45098524Sfenner 45198524Sfenner gabn = NULL; 45298524Sfenner gnba = NULL; 45398524Sfenner grbn = NULL; 45498524Sfenner 455127668Sbms switch (EXTRACT_32BITS(&np->opcode)) { 45698524Sfenner case LWRES_OPCODE_NOOP: 45798524Sfenner break; 45898524Sfenner case LWRES_OPCODE_GETADDRSBYNAME: 45998524Sfenner gabn = (lwres_gabnresponse_t *)(np + 1); 460276788Sdelphij ND_TCHECK(gabn->realnamelen); 46198524Sfenner /* XXX gabn points to packed struct */ 46298524Sfenner s = (const char *)&gabn->realnamelen + 46398524Sfenner sizeof(gabn->realnamelen); 464127668Sbms l = EXTRACT_16BITS(&gabn->realnamelen); 46598524Sfenner 46698524Sfenner /* BIND910: not used */ 467276788Sdelphij if (ndo->ndo_vflag > 2) { 468276788Sdelphij ND_PRINT((ndo, " flags:0x%x", 469276788Sdelphij EXTRACT_32BITS(&gabn->flags))); 47098524Sfenner } 47198524Sfenner 472276788Sdelphij ND_PRINT((ndo, " %u/%u", EXTRACT_16BITS(&gabn->naliases), 473276788Sdelphij EXTRACT_16BITS(&gabn->naddrs))); 47498524Sfenner 475276788Sdelphij advance = lwres_printname(ndo, l, s); 47698524Sfenner if (advance < 0) 47798524Sfenner goto trunc; 47898524Sfenner s += advance; 47998524Sfenner 48098524Sfenner /* aliases */ 481127668Sbms na = EXTRACT_16BITS(&gabn->naliases); 48298524Sfenner for (i = 0; i < na; i++) { 483276788Sdelphij advance = lwres_printnamelen(ndo, s); 48498524Sfenner if (advance < 0) 48598524Sfenner goto trunc; 48698524Sfenner s += advance; 48798524Sfenner } 48898524Sfenner 48998524Sfenner /* addrs */ 490127668Sbms na = EXTRACT_16BITS(&gabn->naddrs); 49198524Sfenner for (i = 0; i < na; i++) { 492276788Sdelphij advance = lwres_printaddr(ndo, (lwres_addr_t *)s); 49398524Sfenner if (advance < 0) 49498524Sfenner goto trunc; 49598524Sfenner s += advance; 49698524Sfenner } 49798524Sfenner break; 49898524Sfenner case LWRES_OPCODE_GETNAMEBYADDR: 49998524Sfenner gnba = (lwres_gnbaresponse_t *)(np + 1); 500276788Sdelphij ND_TCHECK(gnba->realnamelen); 50198524Sfenner /* XXX gnba points to packed struct */ 50298524Sfenner s = (const char *)&gnba->realnamelen + 50398524Sfenner sizeof(gnba->realnamelen); 504127668Sbms l = EXTRACT_16BITS(&gnba->realnamelen); 50598524Sfenner 50698524Sfenner /* BIND910: not used */ 507276788Sdelphij if (ndo->ndo_vflag > 2) { 508276788Sdelphij ND_PRINT((ndo, " flags:0x%x", 509276788Sdelphij EXTRACT_32BITS(&gnba->flags))); 51098524Sfenner } 51198524Sfenner 512276788Sdelphij ND_PRINT((ndo, " %u", EXTRACT_16BITS(&gnba->naliases))); 51398524Sfenner 514276788Sdelphij advance = lwres_printname(ndo, l, s); 51598524Sfenner if (advance < 0) 51698524Sfenner goto trunc; 51798524Sfenner s += advance; 51898524Sfenner 51998524Sfenner /* aliases */ 520127668Sbms na = EXTRACT_16BITS(&gnba->naliases); 52198524Sfenner for (i = 0; i < na; i++) { 522276788Sdelphij advance = lwres_printnamelen(ndo, s); 52398524Sfenner if (advance < 0) 52498524Sfenner goto trunc; 52598524Sfenner s += advance; 52698524Sfenner } 52798524Sfenner break; 52898524Sfenner case LWRES_OPCODE_GETRDATABYNAME: 52998524Sfenner /* XXX no trace, not tested */ 53098524Sfenner grbn = (lwres_grbnresponse_t *)(np + 1); 531276788Sdelphij ND_TCHECK(grbn->nsigs); 53298524Sfenner 53398524Sfenner /* BIND910: not used */ 534276788Sdelphij if (ndo->ndo_vflag > 2) { 535276788Sdelphij ND_PRINT((ndo, " flags:0x%x", 536276788Sdelphij EXTRACT_32BITS(&grbn->flags))); 53798524Sfenner } 53898524Sfenner 539276788Sdelphij ND_PRINT((ndo, " %s", tok2str(ns_type2str, "Type%d", 540276788Sdelphij EXTRACT_16BITS(&grbn->rdtype)))); 541127668Sbms if (EXTRACT_16BITS(&grbn->rdclass) != C_IN) { 542276788Sdelphij ND_PRINT((ndo, " %s", tok2str(ns_class2str, "Class%d", 543276788Sdelphij EXTRACT_16BITS(&grbn->rdclass)))); 544127668Sbms } 545276788Sdelphij ND_PRINT((ndo, " TTL ")); 546276788Sdelphij relts_print(ndo, EXTRACT_32BITS(&grbn->ttl)); 547276788Sdelphij ND_PRINT((ndo, " %u/%u", EXTRACT_16BITS(&grbn->nrdatas), 548276788Sdelphij EXTRACT_16BITS(&grbn->nsigs))); 54998524Sfenner 55098524Sfenner /* XXX grbn points to packed struct */ 55198524Sfenner s = (const char *)&grbn->nsigs+ sizeof(grbn->nsigs); 55298524Sfenner 553276788Sdelphij advance = lwres_printnamelen(ndo, s); 55498524Sfenner if (advance < 0) 55598524Sfenner goto trunc; 55698524Sfenner s += advance; 55798524Sfenner 55898524Sfenner /* rdatas */ 559127668Sbms na = EXTRACT_16BITS(&grbn->nrdatas); 56098524Sfenner for (i = 0; i < na; i++) { 56198524Sfenner /* XXX should decode resource data */ 562276788Sdelphij advance = lwres_printbinlen(ndo, s); 56398524Sfenner if (advance < 0) 56498524Sfenner goto trunc; 56598524Sfenner s += advance; 56698524Sfenner } 56798524Sfenner 56898524Sfenner /* sigs */ 569127668Sbms na = EXTRACT_16BITS(&grbn->nsigs); 57098524Sfenner for (i = 0; i < na; i++) { 57198524Sfenner /* XXX how should we print it? */ 572276788Sdelphij advance = lwres_printbinlen(ndo, s); 57398524Sfenner if (advance < 0) 57498524Sfenner goto trunc; 57598524Sfenner s += advance; 57698524Sfenner } 57798524Sfenner break; 57898524Sfenner default: 57998524Sfenner unsupported++; 58098524Sfenner break; 58198524Sfenner } 58298524Sfenner } 58398524Sfenner 58498524Sfenner tail: 58598524Sfenner /* length mismatch */ 586127668Sbms if (EXTRACT_32BITS(&np->length) != length) { 587276788Sdelphij ND_PRINT((ndo, " [len: %u != %u]", EXTRACT_32BITS(&np->length), 588276788Sdelphij length)); 58998524Sfenner } 590127668Sbms if (!unsupported && s < (const char *)np + EXTRACT_32BITS(&np->length)) 591276788Sdelphij ND_PRINT((ndo, "[extra]")); 59298524Sfenner return; 59398524Sfenner 59498524Sfenner trunc: 595276788Sdelphij ND_PRINT((ndo, "[|lwres]")); 59698524Sfenner} 597