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 3098524Sfenner#ifndef lint 31127668Sbmsstatic const char rcsid[] _U_ = 32190207Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-lwres.c,v 1.13 2004-03-24 01:54:29 guy Exp $ (LBL)"; 3398524Sfenner#endif 3498524Sfenner 3598524Sfenner#ifdef HAVE_CONFIG_H 3698524Sfenner#include "config.h" 3798524Sfenner#endif 3898524Sfenner 39127668Sbms#include <tcpdump-stdinc.h> 4098524Sfenner 4198524Sfenner#include "nameser.h" 4298524Sfenner 4398524Sfenner#include <stdio.h> 4498524Sfenner#include <string.h> 4598524Sfenner 4698524Sfenner#include "interface.h" 4798524Sfenner#include "addrtoname.h" 4898524Sfenner#include "extract.h" /* must come after interface.h */ 4998524Sfenner 5098524Sfenner/* BIND9 lib/lwres/include/lwres */ 5198524Sfennertypedef u_int32_t lwres_uint32_t; 5298524Sfennertypedef u_int16_t lwres_uint16_t; 5398524Sfennertypedef u_int8_t lwres_uint8_t; 5498524Sfenner 5598524Sfennerstruct lwres_lwpacket { 5698524Sfenner lwres_uint32_t length; 5798524Sfenner lwres_uint16_t version; 5898524Sfenner lwres_uint16_t pktflags; 5998524Sfenner lwres_uint32_t serial; 6098524Sfenner lwres_uint32_t opcode; 6198524Sfenner lwres_uint32_t result; 6298524Sfenner lwres_uint32_t recvlength; 6398524Sfenner lwres_uint16_t authtype; 6498524Sfenner lwres_uint16_t authlength; 6598524Sfenner}; 6698524Sfenner 6798524Sfenner#define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */ 6898524Sfenner 6998524Sfenner#define LWRES_LWPACKETVERSION_0 0 7098524Sfenner 7198524Sfenner#define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U 7298524Sfenner#define LWRES_FLAG_SECUREDATA 0x00000002U 7398524Sfenner 7498524Sfenner/* 7598524Sfenner * no-op 7698524Sfenner */ 7798524Sfenner#define LWRES_OPCODE_NOOP 0x00000000U 7898524Sfenner 7998524Sfennertypedef struct { 8098524Sfenner /* public */ 8198524Sfenner lwres_uint16_t datalength; 8298524Sfenner /* data follows */ 8398524Sfenner} lwres_nooprequest_t; 8498524Sfenner 8598524Sfennertypedef struct { 8698524Sfenner /* public */ 8798524Sfenner lwres_uint16_t datalength; 8898524Sfenner /* data follows */ 8998524Sfenner} lwres_noopresponse_t; 9098524Sfenner 9198524Sfenner/* 9298524Sfenner * get addresses by name 9398524Sfenner */ 9498524Sfenner#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U 9598524Sfenner 9698524Sfennertypedef struct lwres_addr lwres_addr_t; 9798524Sfenner 9898524Sfennerstruct lwres_addr { 9998524Sfenner lwres_uint32_t family; 10098524Sfenner lwres_uint16_t length; 10198524Sfenner /* address folows */ 10298524Sfenner}; 10398524Sfenner 10498524Sfennertypedef struct { 10598524Sfenner /* public */ 10698524Sfenner lwres_uint32_t flags; 10798524Sfenner lwres_uint32_t addrtypes; 10898524Sfenner lwres_uint16_t namelen; 10998524Sfenner /* name follows */ 11098524Sfenner} lwres_gabnrequest_t; 11198524Sfenner 11298524Sfennertypedef struct { 11398524Sfenner /* public */ 11498524Sfenner lwres_uint32_t flags; 11598524Sfenner lwres_uint16_t naliases; 11698524Sfenner lwres_uint16_t naddrs; 11798524Sfenner lwres_uint16_t realnamelen; 11898524Sfenner /* aliases follows */ 11998524Sfenner /* addrs follows */ 12098524Sfenner /* realname follows */ 12198524Sfenner} lwres_gabnresponse_t; 12298524Sfenner 12398524Sfenner/* 12498524Sfenner * get name by address 12598524Sfenner */ 12698524Sfenner#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U 12798524Sfennertypedef struct { 12898524Sfenner /* public */ 12998524Sfenner lwres_uint32_t flags; 13098524Sfenner lwres_addr_t addr; 13198524Sfenner /* addr body follows */ 13298524Sfenner} lwres_gnbarequest_t; 13398524Sfenner 13498524Sfennertypedef struct { 13598524Sfenner /* public */ 13698524Sfenner lwres_uint32_t flags; 13798524Sfenner lwres_uint16_t naliases; 13898524Sfenner lwres_uint16_t realnamelen; 13998524Sfenner /* aliases follows */ 14098524Sfenner /* realname follows */ 14198524Sfenner} lwres_gnbaresponse_t; 14298524Sfenner 14398524Sfenner/* 14498524Sfenner * get rdata by name 14598524Sfenner */ 14698524Sfenner#define LWRES_OPCODE_GETRDATABYNAME 0x00010003U 14798524Sfenner 14898524Sfennertypedef struct { 14998524Sfenner /* public */ 15098524Sfenner lwres_uint32_t flags; 15198524Sfenner lwres_uint16_t rdclass; 15298524Sfenner lwres_uint16_t rdtype; 15398524Sfenner lwres_uint16_t namelen; 15498524Sfenner /* name follows */ 15598524Sfenner} lwres_grbnrequest_t; 15698524Sfenner 15798524Sfennertypedef struct { 15898524Sfenner /* public */ 15998524Sfenner lwres_uint32_t flags; 16098524Sfenner lwres_uint16_t rdclass; 16198524Sfenner lwres_uint16_t rdtype; 16298524Sfenner lwres_uint32_t ttl; 16398524Sfenner lwres_uint16_t nrdatas; 16498524Sfenner lwres_uint16_t nsigs; 16598524Sfenner /* realname here (len + name) */ 16698524Sfenner /* rdata here (len + name) */ 16798524Sfenner /* signatures here (len + name) */ 16898524Sfenner} lwres_grbnresponse_t; 16998524Sfenner 17098524Sfenner#define LWRDATA_VALIDATED 0x00000001 17198524Sfenner 17298524Sfenner#define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */ 17398524Sfenner#define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */ 17498524Sfenner 17598524Sfenner#define LWRES_MAX_ALIASES 16 /* max # of aliases */ 17698524Sfenner#define LWRES_MAX_ADDRS 64 /* max # of addrs */ 17798524Sfenner 17898524Sfennerstruct tok opcode[] = { 17998524Sfenner { LWRES_OPCODE_NOOP, "noop", }, 18098524Sfenner { LWRES_OPCODE_GETADDRSBYNAME, "getaddrsbyname", }, 18198524Sfenner { LWRES_OPCODE_GETNAMEBYADDR, "getnamebyaddr", }, 18298524Sfenner { LWRES_OPCODE_GETRDATABYNAME, "getrdatabyname", }, 18398524Sfenner { 0, NULL, }, 18498524Sfenner}; 18598524Sfenner 18698524Sfenner/* print-domain.c */ 18798524Sfennerextern struct tok ns_type2str[]; 18898524Sfennerextern struct tok ns_class2str[]; 18998524Sfenner 19098524Sfennerstatic int lwres_printname(size_t, const char *); 19198524Sfennerstatic int lwres_printnamelen(const char *); 19298524Sfennerstatic int lwres_printbinlen(const char *); 19398524Sfennerstatic int lwres_printaddr(lwres_addr_t *); 19498524Sfenner 19598524Sfennerstatic int 19698524Sfennerlwres_printname(size_t l, const char *p0) 19798524Sfenner{ 19898524Sfenner const char *p; 199127668Sbms size_t i; 20098524Sfenner 20198524Sfenner p = p0; 20298524Sfenner /* + 1 for terminating \0 */ 20398524Sfenner if (p + l + 1 > (const char *)snapend) 20498524Sfenner goto trunc; 20598524Sfenner 20698524Sfenner printf(" "); 20798524Sfenner for (i = 0; i < l; i++) 20898524Sfenner safeputchar(*p++); 20998524Sfenner p++; /* skip terminating \0 */ 21098524Sfenner 21198524Sfenner return p - p0; 21298524Sfenner 21398524Sfenner trunc: 21498524Sfenner return -1; 21598524Sfenner} 21698524Sfenner 21798524Sfennerstatic int 21898524Sfennerlwres_printnamelen(const char *p) 21998524Sfenner{ 22098524Sfenner u_int16_t l; 22198524Sfenner int advance; 22298524Sfenner 22398524Sfenner if (p + 2 > (const char *)snapend) 22498524Sfenner goto trunc; 22598524Sfenner l = EXTRACT_16BITS(p); 22698524Sfenner advance = lwres_printname(l, p + 2); 22798524Sfenner if (advance < 0) 22898524Sfenner goto trunc; 22998524Sfenner return 2 + advance; 23098524Sfenner 23198524Sfenner trunc: 23298524Sfenner return -1; 23398524Sfenner} 23498524Sfenner 23598524Sfennerstatic int 23698524Sfennerlwres_printbinlen(const char *p0) 23798524Sfenner{ 23898524Sfenner const char *p; 23998524Sfenner u_int16_t l; 24098524Sfenner int i; 24198524Sfenner 24298524Sfenner p = p0; 24398524Sfenner if (p + 2 > (const char *)snapend) 24498524Sfenner goto trunc; 24598524Sfenner l = EXTRACT_16BITS(p); 24698524Sfenner if (p + 2 + l > (const char *)snapend) 24798524Sfenner goto trunc; 24898524Sfenner p += 2; 24998524Sfenner for (i = 0; i < l; i++) 25098524Sfenner printf("%02x", *p++); 25198524Sfenner return p - p0; 25298524Sfenner 25398524Sfenner trunc: 25498524Sfenner return -1; 25598524Sfenner} 25698524Sfenner 25798524Sfennerstatic int 25898524Sfennerlwres_printaddr(lwres_addr_t *ap) 25998524Sfenner{ 26098524Sfenner u_int16_t l; 26198524Sfenner const char *p; 26298524Sfenner int i; 26398524Sfenner 26498524Sfenner TCHECK(ap->length); 265127668Sbms l = EXTRACT_16BITS(&ap->length); 26698524Sfenner /* XXX ap points to packed struct */ 26798524Sfenner p = (const char *)&ap->length + sizeof(ap->length); 268127668Sbms TCHECK2(*p, l); 26998524Sfenner 270127668Sbms switch (EXTRACT_32BITS(&ap->family)) { 27198524Sfenner case 1: /* IPv4 */ 272127668Sbms if (l < 4) 273127668Sbms return -1; 27498524Sfenner printf(" %s", ipaddr_string(p)); 27598524Sfenner p += sizeof(struct in_addr); 27698524Sfenner break; 27798524Sfenner#ifdef INET6 27898524Sfenner case 2: /* IPv6 */ 279127668Sbms if (l < 16) 280127668Sbms return -1; 28198524Sfenner printf(" %s", ip6addr_string(p)); 28298524Sfenner p += sizeof(struct in6_addr); 28398524Sfenner break; 28498524Sfenner#endif 28598524Sfenner default: 286127668Sbms printf(" %u/", EXTRACT_32BITS(&ap->family)); 28798524Sfenner for (i = 0; i < l; i++) 28898524Sfenner printf("%02x", *p++); 28998524Sfenner } 29098524Sfenner 29198524Sfenner return p - (const char *)ap; 29298524Sfenner 29398524Sfenner trunc: 29498524Sfenner return -1; 29598524Sfenner} 29698524Sfenner 29798524Sfennervoid 29898524Sfennerlwres_print(register const u_char *bp, u_int length) 29998524Sfenner{ 30098524Sfenner const struct lwres_lwpacket *np; 30198524Sfenner u_int32_t v; 30298524Sfenner const char *s; 30398524Sfenner int response; 30498524Sfenner int advance; 30598524Sfenner int unsupported = 0; 30698524Sfenner 30798524Sfenner np = (const struct lwres_lwpacket *)bp; 30898524Sfenner TCHECK(np->authlength); 30998524Sfenner 31098524Sfenner printf(" lwres"); 311127668Sbms v = EXTRACT_16BITS(&np->version); 31298524Sfenner if (vflag || v != LWRES_LWPACKETVERSION_0) 31398524Sfenner printf(" v%u", v); 31498524Sfenner if (v != LWRES_LWPACKETVERSION_0) { 315127668Sbms s = (const char *)np + EXTRACT_32BITS(&np->length); 31698524Sfenner goto tail; 31798524Sfenner } 31898524Sfenner 319127668Sbms response = EXTRACT_16BITS(&np->pktflags) & LWRES_LWPACKETFLAG_RESPONSE; 32098524Sfenner 32198524Sfenner /* opcode and pktflags */ 322127668Sbms v = EXTRACT_32BITS(&np->opcode); 32398524Sfenner s = tok2str(opcode, "#0x%x", v); 32498524Sfenner printf(" %s%s", s, response ? "" : "?"); 32598524Sfenner 32698524Sfenner /* pktflags */ 327127668Sbms v = EXTRACT_16BITS(&np->pktflags); 32898524Sfenner if (v & ~LWRES_LWPACKETFLAG_RESPONSE) 32998524Sfenner printf("[0x%x]", v); 33098524Sfenner 33198524Sfenner if (vflag > 1) { 33298524Sfenner printf(" ("); /*)*/ 333127668Sbms printf("serial:0x%x", EXTRACT_32BITS(&np->serial)); 334127668Sbms printf(" result:0x%x", EXTRACT_32BITS(&np->result)); 335127668Sbms printf(" recvlen:%u", EXTRACT_32BITS(&np->recvlength)); 33698524Sfenner /* BIND910: not used */ 33798524Sfenner if (vflag > 2) { 338127668Sbms printf(" authtype:0x%x", EXTRACT_16BITS(&np->authtype)); 339127668Sbms printf(" authlen:%u", EXTRACT_16BITS(&np->authlength)); 34098524Sfenner } 34198524Sfenner /*(*/ 34298524Sfenner printf(")"); 34398524Sfenner } 34498524Sfenner 34598524Sfenner /* per-opcode content */ 34698524Sfenner if (!response) { 34798524Sfenner /* 34898524Sfenner * queries 34998524Sfenner */ 35098524Sfenner lwres_gabnrequest_t *gabn; 35198524Sfenner lwres_gnbarequest_t *gnba; 35298524Sfenner lwres_grbnrequest_t *grbn; 35398524Sfenner u_int32_t l; 35498524Sfenner 35598524Sfenner gabn = NULL; 35698524Sfenner gnba = NULL; 35798524Sfenner grbn = NULL; 35898524Sfenner 359127668Sbms switch (EXTRACT_32BITS(&np->opcode)) { 36098524Sfenner case LWRES_OPCODE_NOOP: 36198524Sfenner break; 36298524Sfenner case LWRES_OPCODE_GETADDRSBYNAME: 36398524Sfenner gabn = (lwres_gabnrequest_t *)(np + 1); 36498524Sfenner TCHECK(gabn->namelen); 36598524Sfenner /* XXX gabn points to packed struct */ 36698524Sfenner s = (const char *)&gabn->namelen + 36798524Sfenner sizeof(gabn->namelen); 368127668Sbms l = EXTRACT_16BITS(&gabn->namelen); 36998524Sfenner 37098524Sfenner /* BIND910: not used */ 37198524Sfenner if (vflag > 2) { 372127668Sbms printf(" flags:0x%x", 373127668Sbms EXTRACT_32BITS(&gabn->flags)); 37498524Sfenner } 37598524Sfenner 376127668Sbms v = EXTRACT_32BITS(&gabn->addrtypes); 37798524Sfenner switch (v & (LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) { 37898524Sfenner case LWRES_ADDRTYPE_V4: 37998524Sfenner printf(" IPv4"); 38098524Sfenner break; 38198524Sfenner case LWRES_ADDRTYPE_V6: 38298524Sfenner printf(" IPv6"); 38398524Sfenner break; 38498524Sfenner case LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6: 38598524Sfenner printf(" IPv4/6"); 38698524Sfenner break; 38798524Sfenner } 38898524Sfenner if (v & ~(LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) 38998524Sfenner printf("[0x%x]", v); 39098524Sfenner 39198524Sfenner advance = lwres_printname(l, s); 39298524Sfenner if (advance < 0) 39398524Sfenner goto trunc; 39498524Sfenner s += advance; 39598524Sfenner break; 39698524Sfenner case LWRES_OPCODE_GETNAMEBYADDR: 39798524Sfenner gnba = (lwres_gnbarequest_t *)(np + 1); 39898524Sfenner TCHECK(gnba->addr); 39998524Sfenner 40098524Sfenner /* BIND910: not used */ 40198524Sfenner if (vflag > 2) { 402127668Sbms printf(" flags:0x%x", 403127668Sbms EXTRACT_32BITS(&gnba->flags)); 40498524Sfenner } 40598524Sfenner 40698524Sfenner s = (const char *)&gnba->addr; 40798524Sfenner 40898524Sfenner advance = lwres_printaddr(&gnba->addr); 40998524Sfenner if (advance < 0) 41098524Sfenner goto trunc; 41198524Sfenner s += advance; 41298524Sfenner break; 41398524Sfenner case LWRES_OPCODE_GETRDATABYNAME: 41498524Sfenner /* XXX no trace, not tested */ 41598524Sfenner grbn = (lwres_grbnrequest_t *)(np + 1); 41698524Sfenner TCHECK(grbn->namelen); 41798524Sfenner 41898524Sfenner /* BIND910: not used */ 41998524Sfenner if (vflag > 2) { 420127668Sbms printf(" flags:0x%x", 421127668Sbms EXTRACT_32BITS(&grbn->flags)); 42298524Sfenner } 42398524Sfenner 42498524Sfenner printf(" %s", tok2str(ns_type2str, "Type%d", 425127668Sbms EXTRACT_16BITS(&grbn->rdtype))); 426127668Sbms if (EXTRACT_16BITS(&grbn->rdclass) != C_IN) { 42798524Sfenner printf(" %s", tok2str(ns_class2str, "Class%d", 428127668Sbms EXTRACT_16BITS(&grbn->rdclass))); 429127668Sbms } 43098524Sfenner 43198524Sfenner /* XXX grbn points to packed struct */ 43298524Sfenner s = (const char *)&grbn->namelen + 43398524Sfenner sizeof(grbn->namelen); 434127668Sbms l = EXTRACT_16BITS(&grbn->namelen); 43598524Sfenner 43698524Sfenner advance = lwres_printname(l, s); 43798524Sfenner if (advance < 0) 43898524Sfenner goto trunc; 43998524Sfenner s += advance; 44098524Sfenner break; 44198524Sfenner default: 44298524Sfenner unsupported++; 44398524Sfenner break; 44498524Sfenner } 44598524Sfenner } else { 44698524Sfenner /* 44798524Sfenner * responses 44898524Sfenner */ 44998524Sfenner lwres_gabnresponse_t *gabn; 45098524Sfenner lwres_gnbaresponse_t *gnba; 45198524Sfenner lwres_grbnresponse_t *grbn; 45298524Sfenner u_int32_t l, na; 453127668Sbms u_int32_t i; 45498524Sfenner 45598524Sfenner gabn = NULL; 45698524Sfenner gnba = NULL; 45798524Sfenner grbn = NULL; 45898524Sfenner 459127668Sbms switch (EXTRACT_32BITS(&np->opcode)) { 46098524Sfenner case LWRES_OPCODE_NOOP: 46198524Sfenner break; 46298524Sfenner case LWRES_OPCODE_GETADDRSBYNAME: 46398524Sfenner gabn = (lwres_gabnresponse_t *)(np + 1); 46498524Sfenner TCHECK(gabn->realnamelen); 46598524Sfenner /* XXX gabn points to packed struct */ 46698524Sfenner s = (const char *)&gabn->realnamelen + 46798524Sfenner sizeof(gabn->realnamelen); 468127668Sbms l = EXTRACT_16BITS(&gabn->realnamelen); 46998524Sfenner 47098524Sfenner /* BIND910: not used */ 47198524Sfenner if (vflag > 2) { 472127668Sbms printf(" flags:0x%x", 473127668Sbms EXTRACT_32BITS(&gabn->flags)); 47498524Sfenner } 47598524Sfenner 476127668Sbms printf(" %u/%u", EXTRACT_16BITS(&gabn->naliases), 477127668Sbms EXTRACT_16BITS(&gabn->naddrs)); 47898524Sfenner 47998524Sfenner advance = lwres_printname(l, s); 48098524Sfenner if (advance < 0) 48198524Sfenner goto trunc; 48298524Sfenner s += advance; 48398524Sfenner 48498524Sfenner /* aliases */ 485127668Sbms na = EXTRACT_16BITS(&gabn->naliases); 48698524Sfenner for (i = 0; i < na; i++) { 48798524Sfenner advance = lwres_printnamelen(s); 48898524Sfenner if (advance < 0) 48998524Sfenner goto trunc; 49098524Sfenner s += advance; 49198524Sfenner } 49298524Sfenner 49398524Sfenner /* addrs */ 494127668Sbms na = EXTRACT_16BITS(&gabn->naddrs); 49598524Sfenner for (i = 0; i < na; i++) { 49698524Sfenner advance = lwres_printaddr((lwres_addr_t *)s); 49798524Sfenner if (advance < 0) 49898524Sfenner goto trunc; 49998524Sfenner s += advance; 50098524Sfenner } 50198524Sfenner break; 50298524Sfenner case LWRES_OPCODE_GETNAMEBYADDR: 50398524Sfenner gnba = (lwres_gnbaresponse_t *)(np + 1); 50498524Sfenner TCHECK(gnba->realnamelen); 50598524Sfenner /* XXX gnba points to packed struct */ 50698524Sfenner s = (const char *)&gnba->realnamelen + 50798524Sfenner sizeof(gnba->realnamelen); 508127668Sbms l = EXTRACT_16BITS(&gnba->realnamelen); 50998524Sfenner 51098524Sfenner /* BIND910: not used */ 51198524Sfenner if (vflag > 2) { 512127668Sbms printf(" flags:0x%x", 513127668Sbms EXTRACT_32BITS(&gnba->flags)); 51498524Sfenner } 51598524Sfenner 516127668Sbms printf(" %u", EXTRACT_16BITS(&gnba->naliases)); 51798524Sfenner 51898524Sfenner advance = lwres_printname(l, s); 51998524Sfenner if (advance < 0) 52098524Sfenner goto trunc; 52198524Sfenner s += advance; 52298524Sfenner 52398524Sfenner /* aliases */ 524127668Sbms na = EXTRACT_16BITS(&gnba->naliases); 52598524Sfenner for (i = 0; i < na; i++) { 52698524Sfenner advance = lwres_printnamelen(s); 52798524Sfenner if (advance < 0) 52898524Sfenner goto trunc; 52998524Sfenner s += advance; 53098524Sfenner } 53198524Sfenner break; 53298524Sfenner case LWRES_OPCODE_GETRDATABYNAME: 53398524Sfenner /* XXX no trace, not tested */ 53498524Sfenner grbn = (lwres_grbnresponse_t *)(np + 1); 53598524Sfenner TCHECK(grbn->nsigs); 53698524Sfenner 53798524Sfenner /* BIND910: not used */ 53898524Sfenner if (vflag > 2) { 539127668Sbms printf(" flags:0x%x", 540127668Sbms EXTRACT_32BITS(&grbn->flags)); 54198524Sfenner } 54298524Sfenner 54398524Sfenner printf(" %s", tok2str(ns_type2str, "Type%d", 544127668Sbms EXTRACT_16BITS(&grbn->rdtype))); 545127668Sbms if (EXTRACT_16BITS(&grbn->rdclass) != C_IN) { 54698524Sfenner printf(" %s", tok2str(ns_class2str, "Class%d", 547127668Sbms EXTRACT_16BITS(&grbn->rdclass))); 548127668Sbms } 54998524Sfenner printf(" TTL "); 550127668Sbms relts_print(EXTRACT_32BITS(&grbn->ttl)); 551127668Sbms printf(" %u/%u", EXTRACT_16BITS(&grbn->nrdatas), 552127668Sbms EXTRACT_16BITS(&grbn->nsigs)); 55398524Sfenner 55498524Sfenner /* XXX grbn points to packed struct */ 55598524Sfenner s = (const char *)&grbn->nsigs+ sizeof(grbn->nsigs); 55698524Sfenner 55798524Sfenner advance = lwres_printnamelen(s); 55898524Sfenner if (advance < 0) 55998524Sfenner goto trunc; 56098524Sfenner s += advance; 56198524Sfenner 56298524Sfenner /* rdatas */ 563127668Sbms na = EXTRACT_16BITS(&grbn->nrdatas); 56498524Sfenner for (i = 0; i < na; i++) { 56598524Sfenner /* XXX should decode resource data */ 56698524Sfenner advance = lwres_printbinlen(s); 56798524Sfenner if (advance < 0) 56898524Sfenner goto trunc; 56998524Sfenner s += advance; 57098524Sfenner } 57198524Sfenner 57298524Sfenner /* sigs */ 573127668Sbms na = EXTRACT_16BITS(&grbn->nsigs); 57498524Sfenner for (i = 0; i < na; i++) { 57598524Sfenner /* XXX how should we print it? */ 57698524Sfenner advance = lwres_printbinlen(s); 57798524Sfenner if (advance < 0) 57898524Sfenner goto trunc; 57998524Sfenner s += advance; 58098524Sfenner } 58198524Sfenner break; 58298524Sfenner default: 58398524Sfenner unsupported++; 58498524Sfenner break; 58598524Sfenner } 58698524Sfenner } 58798524Sfenner 58898524Sfenner tail: 58998524Sfenner /* length mismatch */ 590127668Sbms if (EXTRACT_32BITS(&np->length) != length) { 591127668Sbms printf(" [len: %u != %u]", EXTRACT_32BITS(&np->length), 59298524Sfenner length); 59398524Sfenner } 594127668Sbms if (!unsupported && s < (const char *)np + EXTRACT_32BITS(&np->length)) 59598524Sfenner printf("[extra]"); 59698524Sfenner return; 59798524Sfenner 59898524Sfenner trunc: 59998524Sfenner printf("[|lwres]"); 60098524Sfenner return; 60198524Sfenner} 602