print-lwres.c revision 98524
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 3198524Sfennerstatic const char rcsid[] = 3298524Sfenner "@(#) $Header: /tcpdump/master/tcpdump/print-lwres.c,v 1.5 2001/06/26 06:19:05 guy Exp $ (LBL)"; 3398524Sfenner#endif 3498524Sfenner 3598524Sfenner#ifdef HAVE_CONFIG_H 3698524Sfenner#include "config.h" 3798524Sfenner#endif 3898524Sfenner 3998524Sfenner#include <sys/param.h> 4098524Sfenner#include <sys/time.h> 4198524Sfenner 4298524Sfenner#include <netinet/in.h> 4398524Sfenner 4498524Sfenner#include "nameser.h" 4598524Sfenner 4698524Sfenner#include <stdio.h> 4798524Sfenner#include <string.h> 4898524Sfenner 4998524Sfenner#include "interface.h" 5098524Sfenner#include "addrtoname.h" 5198524Sfenner#include "extract.h" /* must come after interface.h */ 5298524Sfenner 5398524Sfenner/* BIND9 lib/lwres/include/lwres */ 5498524Sfennertypedef u_int32_t lwres_uint32_t; 5598524Sfennertypedef u_int16_t lwres_uint16_t; 5698524Sfennertypedef u_int8_t lwres_uint8_t; 5798524Sfenner 5898524Sfennerstruct lwres_lwpacket { 5998524Sfenner lwres_uint32_t length; 6098524Sfenner lwres_uint16_t version; 6198524Sfenner lwres_uint16_t pktflags; 6298524Sfenner lwres_uint32_t serial; 6398524Sfenner lwres_uint32_t opcode; 6498524Sfenner lwres_uint32_t result; 6598524Sfenner lwres_uint32_t recvlength; 6698524Sfenner lwres_uint16_t authtype; 6798524Sfenner lwres_uint16_t authlength; 6898524Sfenner}; 6998524Sfenner 7098524Sfenner#define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */ 7198524Sfenner 7298524Sfenner#define LWRES_LWPACKETVERSION_0 0 7398524Sfenner 7498524Sfenner#define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U 7598524Sfenner#define LWRES_FLAG_SECUREDATA 0x00000002U 7698524Sfenner 7798524Sfenner/* 7898524Sfenner * no-op 7998524Sfenner */ 8098524Sfenner#define LWRES_OPCODE_NOOP 0x00000000U 8198524Sfenner 8298524Sfennertypedef struct { 8398524Sfenner /* public */ 8498524Sfenner lwres_uint16_t datalength; 8598524Sfenner /* data follows */ 8698524Sfenner} lwres_nooprequest_t; 8798524Sfenner 8898524Sfennertypedef struct { 8998524Sfenner /* public */ 9098524Sfenner lwres_uint16_t datalength; 9198524Sfenner /* data follows */ 9298524Sfenner} lwres_noopresponse_t; 9398524Sfenner 9498524Sfenner/* 9598524Sfenner * get addresses by name 9698524Sfenner */ 9798524Sfenner#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U 9898524Sfenner 9998524Sfennertypedef struct lwres_addr lwres_addr_t; 10098524Sfenner 10198524Sfennerstruct lwres_addr { 10298524Sfenner lwres_uint32_t family; 10398524Sfenner lwres_uint16_t length; 10498524Sfenner /* address folows */ 10598524Sfenner}; 10698524Sfenner 10798524Sfennertypedef struct { 10898524Sfenner /* public */ 10998524Sfenner lwres_uint32_t flags; 11098524Sfenner lwres_uint32_t addrtypes; 11198524Sfenner lwres_uint16_t namelen; 11298524Sfenner /* name follows */ 11398524Sfenner} lwres_gabnrequest_t; 11498524Sfenner 11598524Sfennertypedef struct { 11698524Sfenner /* public */ 11798524Sfenner lwres_uint32_t flags; 11898524Sfenner lwres_uint16_t naliases; 11998524Sfenner lwres_uint16_t naddrs; 12098524Sfenner lwres_uint16_t realnamelen; 12198524Sfenner /* aliases follows */ 12298524Sfenner /* addrs follows */ 12398524Sfenner /* realname follows */ 12498524Sfenner} lwres_gabnresponse_t; 12598524Sfenner 12698524Sfenner/* 12798524Sfenner * get name by address 12898524Sfenner */ 12998524Sfenner#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U 13098524Sfennertypedef struct { 13198524Sfenner /* public */ 13298524Sfenner lwres_uint32_t flags; 13398524Sfenner lwres_addr_t addr; 13498524Sfenner /* addr body follows */ 13598524Sfenner} lwres_gnbarequest_t; 13698524Sfenner 13798524Sfennertypedef struct { 13898524Sfenner /* public */ 13998524Sfenner lwres_uint32_t flags; 14098524Sfenner lwres_uint16_t naliases; 14198524Sfenner lwres_uint16_t realnamelen; 14298524Sfenner /* aliases follows */ 14398524Sfenner /* realname follows */ 14498524Sfenner} lwres_gnbaresponse_t; 14598524Sfenner 14698524Sfenner/* 14798524Sfenner * get rdata by name 14898524Sfenner */ 14998524Sfenner#define LWRES_OPCODE_GETRDATABYNAME 0x00010003U 15098524Sfenner 15198524Sfennertypedef struct { 15298524Sfenner /* public */ 15398524Sfenner lwres_uint32_t flags; 15498524Sfenner lwres_uint16_t rdclass; 15598524Sfenner lwres_uint16_t rdtype; 15698524Sfenner lwres_uint16_t namelen; 15798524Sfenner /* name follows */ 15898524Sfenner} lwres_grbnrequest_t; 15998524Sfenner 16098524Sfennertypedef struct { 16198524Sfenner /* public */ 16298524Sfenner lwres_uint32_t flags; 16398524Sfenner lwres_uint16_t rdclass; 16498524Sfenner lwres_uint16_t rdtype; 16598524Sfenner lwres_uint32_t ttl; 16698524Sfenner lwres_uint16_t nrdatas; 16798524Sfenner lwres_uint16_t nsigs; 16898524Sfenner /* realname here (len + name) */ 16998524Sfenner /* rdata here (len + name) */ 17098524Sfenner /* signatures here (len + name) */ 17198524Sfenner} lwres_grbnresponse_t; 17298524Sfenner 17398524Sfenner#define LWRDATA_VALIDATED 0x00000001 17498524Sfenner 17598524Sfenner#define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */ 17698524Sfenner#define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */ 17798524Sfenner 17898524Sfenner#define LWRES_MAX_ALIASES 16 /* max # of aliases */ 17998524Sfenner#define LWRES_MAX_ADDRS 64 /* max # of addrs */ 18098524Sfenner 18198524Sfennerstruct tok opcode[] = { 18298524Sfenner { LWRES_OPCODE_NOOP, "noop", }, 18398524Sfenner { LWRES_OPCODE_GETADDRSBYNAME, "getaddrsbyname", }, 18498524Sfenner { LWRES_OPCODE_GETNAMEBYADDR, "getnamebyaddr", }, 18598524Sfenner { LWRES_OPCODE_GETRDATABYNAME, "getrdatabyname", }, 18698524Sfenner { 0, NULL, }, 18798524Sfenner}; 18898524Sfenner 18998524Sfenner/* print-domain.c */ 19098524Sfennerextern struct tok ns_type2str[]; 19198524Sfennerextern struct tok ns_class2str[]; 19298524Sfenner 19398524Sfennerstatic int lwres_printname(size_t, const char *); 19498524Sfennerstatic int lwres_printnamelen(const char *); 19598524Sfennerstatic int lwres_printbinlen(const char *); 19698524Sfennerstatic int lwres_printaddr(lwres_addr_t *); 19798524Sfenner 19898524Sfennerstatic int 19998524Sfennerlwres_printname(size_t l, const char *p0) 20098524Sfenner{ 20198524Sfenner const char *p; 20298524Sfenner int i; 20398524Sfenner 20498524Sfenner p = p0; 20598524Sfenner /* + 1 for terminating \0 */ 20698524Sfenner if (p + l + 1 > (const char *)snapend) 20798524Sfenner goto trunc; 20898524Sfenner 20998524Sfenner printf(" "); 21098524Sfenner for (i = 0; i < l; i++) 21198524Sfenner safeputchar(*p++); 21298524Sfenner p++; /* skip terminating \0 */ 21398524Sfenner 21498524Sfenner return p - p0; 21598524Sfenner 21698524Sfenner trunc: 21798524Sfenner return -1; 21898524Sfenner} 21998524Sfenner 22098524Sfennerstatic int 22198524Sfennerlwres_printnamelen(const char *p) 22298524Sfenner{ 22398524Sfenner u_int16_t l; 22498524Sfenner int advance; 22598524Sfenner 22698524Sfenner if (p + 2 > (const char *)snapend) 22798524Sfenner goto trunc; 22898524Sfenner l = EXTRACT_16BITS(p); 22998524Sfenner advance = lwres_printname(l, p + 2); 23098524Sfenner if (advance < 0) 23198524Sfenner goto trunc; 23298524Sfenner return 2 + advance; 23398524Sfenner 23498524Sfenner trunc: 23598524Sfenner return -1; 23698524Sfenner} 23798524Sfenner 23898524Sfennerstatic int 23998524Sfennerlwres_printbinlen(const char *p0) 24098524Sfenner{ 24198524Sfenner const char *p; 24298524Sfenner u_int16_t l; 24398524Sfenner int i; 24498524Sfenner 24598524Sfenner p = p0; 24698524Sfenner if (p + 2 > (const char *)snapend) 24798524Sfenner goto trunc; 24898524Sfenner l = EXTRACT_16BITS(p); 24998524Sfenner if (p + 2 + l > (const char *)snapend) 25098524Sfenner goto trunc; 25198524Sfenner p += 2; 25298524Sfenner for (i = 0; i < l; i++) 25398524Sfenner printf("%02x", *p++); 25498524Sfenner return p - p0; 25598524Sfenner 25698524Sfenner trunc: 25798524Sfenner return -1; 25898524Sfenner} 25998524Sfenner 26098524Sfennerstatic int 26198524Sfennerlwres_printaddr(lwres_addr_t *ap) 26298524Sfenner{ 26398524Sfenner u_int16_t l; 26498524Sfenner const char *p; 26598524Sfenner int i; 26698524Sfenner 26798524Sfenner TCHECK(ap->length); 26898524Sfenner l = ntohs(ap->length); 26998524Sfenner /* XXX ap points to packed struct */ 27098524Sfenner p = (const char *)&ap->length + sizeof(ap->length); 27198524Sfenner if (p + l > (const char *)snapend) 27298524Sfenner goto trunc; 27398524Sfenner 27498524Sfenner switch (ntohl(ap->family)) { 27598524Sfenner case 1: /* IPv4 */ 27698524Sfenner printf(" %s", ipaddr_string(p)); 27798524Sfenner p += sizeof(struct in_addr); 27898524Sfenner break; 27998524Sfenner#ifdef INET6 28098524Sfenner case 2: /* IPv6 */ 28198524Sfenner printf(" %s", ip6addr_string(p)); 28298524Sfenner p += sizeof(struct in6_addr); 28398524Sfenner break; 28498524Sfenner#endif 28598524Sfenner default: 28698524Sfenner printf(" %lu/", (unsigned long)ntohl(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"); 31198524Sfenner v = ntohs(np->version); 31298524Sfenner if (vflag || v != LWRES_LWPACKETVERSION_0) 31398524Sfenner printf(" v%u", v); 31498524Sfenner if (v != LWRES_LWPACKETVERSION_0) { 31598524Sfenner s = (const char *)np + ntohl(np->length); 31698524Sfenner goto tail; 31798524Sfenner } 31898524Sfenner 31998524Sfenner response = ntohs(np->pktflags) & LWRES_LWPACKETFLAG_RESPONSE; 32098524Sfenner 32198524Sfenner /* opcode and pktflags */ 32298524Sfenner v = (u_int32_t)ntohl(np->opcode); 32398524Sfenner s = tok2str(opcode, "#0x%x", v); 32498524Sfenner printf(" %s%s", s, response ? "" : "?"); 32598524Sfenner 32698524Sfenner /* pktflags */ 32798524Sfenner v = ntohs(np->pktflags); 32898524Sfenner if (v & ~LWRES_LWPACKETFLAG_RESPONSE) 32998524Sfenner printf("[0x%x]", v); 33098524Sfenner 33198524Sfenner if (vflag > 1) { 33298524Sfenner printf(" ("); /*)*/ 33398524Sfenner printf("serial:0x%lx", (unsigned long)ntohl(np->serial)); 33498524Sfenner printf(" result:0x%lx", (unsigned long)ntohl(np->result)); 33598524Sfenner printf(" recvlen:%lu", (unsigned long)ntohl(np->recvlength)); 33698524Sfenner /* BIND910: not used */ 33798524Sfenner if (vflag > 2) { 33898524Sfenner printf(" authtype:0x%x", ntohs(np->authtype)); 33998524Sfenner printf(" authlen:%u", ntohs(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 35998524Sfenner switch (ntohl(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); 36898524Sfenner l = ntohs(gabn->namelen); 36998524Sfenner 37098524Sfenner /* BIND910: not used */ 37198524Sfenner if (vflag > 2) { 37298524Sfenner printf(" flags:0x%lx", 37398524Sfenner (unsigned long)ntohl(gabn->flags)); 37498524Sfenner } 37598524Sfenner 37698524Sfenner v = (u_int32_t)ntohl(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) { 40298524Sfenner printf(" flags:0x%lx", 40398524Sfenner (unsigned long)ntohl(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) { 42098524Sfenner printf(" flags:0x%lx", 42198524Sfenner (unsigned long)ntohl(grbn->flags)); 42298524Sfenner } 42398524Sfenner 42498524Sfenner printf(" %s", tok2str(ns_type2str, "Type%d", 42598524Sfenner ntohs(grbn->rdtype))); 42698524Sfenner if (ntohs(grbn->rdclass) != C_IN); 42798524Sfenner printf(" %s", tok2str(ns_class2str, "Class%d", 42898524Sfenner ntohs(grbn->rdclass))); 42998524Sfenner 43098524Sfenner /* XXX grbn points to packed struct */ 43198524Sfenner s = (const char *)&grbn->namelen + 43298524Sfenner sizeof(grbn->namelen); 43398524Sfenner l = ntohs(gabn->namelen); 43498524Sfenner 43598524Sfenner advance = lwres_printname(l, s); 43698524Sfenner if (advance < 0) 43798524Sfenner goto trunc; 43898524Sfenner s += advance; 43998524Sfenner break; 44098524Sfenner default: 44198524Sfenner unsupported++; 44298524Sfenner break; 44398524Sfenner } 44498524Sfenner } else { 44598524Sfenner /* 44698524Sfenner * responses 44798524Sfenner */ 44898524Sfenner lwres_gabnresponse_t *gabn; 44998524Sfenner lwres_gnbaresponse_t *gnba; 45098524Sfenner lwres_grbnresponse_t *grbn; 45198524Sfenner u_int32_t l, na; 45298524Sfenner int i; 45398524Sfenner 45498524Sfenner gabn = NULL; 45598524Sfenner gnba = NULL; 45698524Sfenner grbn = NULL; 45798524Sfenner 45898524Sfenner switch (ntohl(np->opcode)) { 45998524Sfenner case LWRES_OPCODE_NOOP: 46098524Sfenner break; 46198524Sfenner case LWRES_OPCODE_GETADDRSBYNAME: 46298524Sfenner gabn = (lwres_gabnresponse_t *)(np + 1); 46398524Sfenner TCHECK(gabn->realnamelen); 46498524Sfenner /* XXX gabn points to packed struct */ 46598524Sfenner s = (const char *)&gabn->realnamelen + 46698524Sfenner sizeof(gabn->realnamelen); 46798524Sfenner l = ntohs(gabn->realnamelen); 46898524Sfenner 46998524Sfenner /* BIND910: not used */ 47098524Sfenner if (vflag > 2) { 47198524Sfenner printf(" flags:0x%lx", 47298524Sfenner (unsigned long)ntohl(gabn->flags)); 47398524Sfenner } 47498524Sfenner 47598524Sfenner printf(" %u/%u", ntohs(gabn->naliases), 47698524Sfenner ntohs(gabn->naddrs)); 47798524Sfenner 47898524Sfenner advance = lwres_printname(l, s); 47998524Sfenner if (advance < 0) 48098524Sfenner goto trunc; 48198524Sfenner s += advance; 48298524Sfenner 48398524Sfenner /* aliases */ 48498524Sfenner na = ntohs(gabn->naliases); 48598524Sfenner for (i = 0; i < na; i++) { 48698524Sfenner advance = lwres_printnamelen(s); 48798524Sfenner if (advance < 0) 48898524Sfenner goto trunc; 48998524Sfenner s += advance; 49098524Sfenner } 49198524Sfenner 49298524Sfenner /* addrs */ 49398524Sfenner na = ntohs(gabn->naddrs); 49498524Sfenner for (i = 0; i < na; i++) { 49598524Sfenner advance = lwres_printaddr((lwres_addr_t *)s); 49698524Sfenner if (advance < 0) 49798524Sfenner goto trunc; 49898524Sfenner s += advance; 49998524Sfenner } 50098524Sfenner break; 50198524Sfenner case LWRES_OPCODE_GETNAMEBYADDR: 50298524Sfenner gnba = (lwres_gnbaresponse_t *)(np + 1); 50398524Sfenner TCHECK(gnba->realnamelen); 50498524Sfenner /* XXX gnba points to packed struct */ 50598524Sfenner s = (const char *)&gnba->realnamelen + 50698524Sfenner sizeof(gnba->realnamelen); 50798524Sfenner l = ntohs(gnba->realnamelen); 50898524Sfenner 50998524Sfenner /* BIND910: not used */ 51098524Sfenner if (vflag > 2) { 51198524Sfenner printf(" flags:0x%lx", 51298524Sfenner (unsigned long)ntohl(gnba->flags)); 51398524Sfenner } 51498524Sfenner 51598524Sfenner printf(" %u", ntohs(gnba->naliases)); 51698524Sfenner 51798524Sfenner advance = lwres_printname(l, s); 51898524Sfenner if (advance < 0) 51998524Sfenner goto trunc; 52098524Sfenner s += advance; 52198524Sfenner 52298524Sfenner /* aliases */ 52398524Sfenner na = ntohs(gnba->naliases); 52498524Sfenner for (i = 0; i < na; i++) { 52598524Sfenner advance = lwres_printnamelen(s); 52698524Sfenner if (advance < 0) 52798524Sfenner goto trunc; 52898524Sfenner s += advance; 52998524Sfenner } 53098524Sfenner break; 53198524Sfenner case LWRES_OPCODE_GETRDATABYNAME: 53298524Sfenner /* XXX no trace, not tested */ 53398524Sfenner grbn = (lwres_grbnresponse_t *)(np + 1); 53498524Sfenner TCHECK(grbn->nsigs); 53598524Sfenner 53698524Sfenner /* BIND910: not used */ 53798524Sfenner if (vflag > 2) { 53898524Sfenner printf(" flags:0x%lx", 53998524Sfenner (unsigned long)ntohl(grbn->flags)); 54098524Sfenner } 54198524Sfenner 54298524Sfenner printf(" %s", tok2str(ns_type2str, "Type%d", 54398524Sfenner ntohs(grbn->rdtype))); 54498524Sfenner if (ntohs(grbn->rdclass) != C_IN); 54598524Sfenner printf(" %s", tok2str(ns_class2str, "Class%d", 54698524Sfenner ntohs(grbn->rdclass))); 54798524Sfenner printf(" TTL "); 54898524Sfenner relts_print(ntohl(grbn->ttl)); 54998524Sfenner printf(" %u/%u", ntohs(grbn->nrdatas), 55098524Sfenner ntohs(grbn->nsigs)); 55198524Sfenner 55298524Sfenner /* XXX grbn points to packed struct */ 55398524Sfenner s = (const char *)&grbn->nsigs+ sizeof(grbn->nsigs); 55498524Sfenner 55598524Sfenner advance = lwres_printnamelen(s); 55698524Sfenner if (advance < 0) 55798524Sfenner goto trunc; 55898524Sfenner s += advance; 55998524Sfenner 56098524Sfenner /* rdatas */ 56198524Sfenner na = ntohs(grbn->nrdatas); 56298524Sfenner for (i = 0; i < na; i++) { 56398524Sfenner /* XXX should decode resource data */ 56498524Sfenner advance = lwres_printbinlen(s); 56598524Sfenner if (advance < 0) 56698524Sfenner goto trunc; 56798524Sfenner s += advance; 56898524Sfenner } 56998524Sfenner 57098524Sfenner /* sigs */ 57198524Sfenner na = ntohs(grbn->nsigs); 57298524Sfenner for (i = 0; i < na; i++) { 57398524Sfenner /* XXX how should we print it? */ 57498524Sfenner advance = lwres_printbinlen(s); 57598524Sfenner if (advance < 0) 57698524Sfenner goto trunc; 57798524Sfenner s += advance; 57898524Sfenner } 57998524Sfenner break; 58098524Sfenner default: 58198524Sfenner unsupported++; 58298524Sfenner break; 58398524Sfenner } 58498524Sfenner } 58598524Sfenner 58698524Sfenner tail: 58798524Sfenner /* length mismatch */ 58898524Sfenner if (ntohl(np->length) != length) { 58998524Sfenner printf(" [len: %lu != %u]", (unsigned long)ntohl(np->length), 59098524Sfenner length); 59198524Sfenner } 59298524Sfenner if (!unsupported && s < (const char *)np + ntohl(np->length)) 59398524Sfenner printf("[extra]"); 59498524Sfenner return; 59598524Sfenner 59698524Sfenner trunc: 59798524Sfenner printf("[|lwres]"); 59898524Sfenner return; 59998524Sfenner} 600