| 1 |  |  | /* | 
    
    | 2 |  |  |  * Copyright (C) 2001 WIDE Project. | 
    
    | 3 |  |  |  * All rights reserved. | 
    
    | 4 |  |  |  * | 
    
    | 5 |  |  |  * Redistribution and use in source and binary forms, with or without | 
    
    | 6 |  |  |  * modification, are permitted provided that the following conditions | 
    
    | 7 |  |  |  * are met: | 
    
    | 8 |  |  |  * 1. Redistributions of source code must retain the above copyright | 
    
    | 9 |  |  |  *    notice, this list of conditions and the following disclaimer. | 
    
    | 10 |  |  |  * 2. Redistributions in binary form must reproduce the above copyright | 
    
    | 11 |  |  |  *    notice, this list of conditions and the following disclaimer in the | 
    
    | 12 |  |  |  *    documentation and/or other materials provided with the distribution. | 
    
    | 13 |  |  |  * 3. Neither the name of the project nor the names of its contributors | 
    
    | 14 |  |  |  *    may be used to endorse or promote products derived from this software | 
    
    | 15 |  |  |  *    without specific prior written permission. | 
    
    | 16 |  |  |  * | 
    
    | 17 |  |  |  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | 
    
    | 18 |  |  |  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
    
    | 19 |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
    
    | 20 |  |  |  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | 
    
    | 21 |  |  |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
    
    | 22 |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
    
    | 23 |  |  |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
    
    | 24 |  |  |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
    
    | 25 |  |  |  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
    
    | 26 |  |  |  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
    
    | 27 |  |  |  * SUCH DAMAGE. | 
    
    | 28 |  |  |  */ | 
    
    | 29 |  |  |  | 
    
    | 30 |  |  | #ifdef HAVE_CONFIG_H | 
    
    | 31 |  |  | #include "config.h" | 
    
    | 32 |  |  | #endif | 
    
    | 33 |  |  |  | 
    
    | 34 |  |  | #include <sys/time.h> | 
    
    | 35 |  |  |  | 
    
    | 36 |  |  | #include <netinet/in.h> | 
    
    | 37 |  |  |  | 
    
    | 38 |  |  | #ifdef NOERROR | 
    
    | 39 |  |  | #undef NOERROR					/* Solaris sucks */ | 
    
    | 40 |  |  | #endif | 
    
    | 41 |  |  | #ifdef NOERROR | 
    
    | 42 |  |  | #undef T_UNSPEC					/* SINIX does too */ | 
    
    | 43 |  |  | #endif | 
    
    | 44 |  |  | #include "nameser.h" | 
    
    | 45 |  |  |  | 
    
    | 46 |  |  | #include <stdio.h> | 
    
    | 47 |  |  | #include <string.h> | 
    
    | 48 |  |  | #include <stdlib.h> | 
    
    | 49 |  |  | #include <resolv.h>			/* for b64_ntop() proto */ | 
    
    | 50 |  |  |  | 
    
    | 51 |  |  | #include "interface.h" | 
    
    | 52 |  |  | #include "addrtoname.h" | 
    
    | 53 |  |  | #include "extract.h"                    /* must come after interface.h */ | 
    
    | 54 |  |  |  | 
    
    | 55 |  |  | /* BIND9 lib/lwres/include/lwres */ | 
    
    | 56 |  |  | typedef u_int32_t lwres_uint32_t; | 
    
    | 57 |  |  | typedef u_int16_t lwres_uint16_t; | 
    
    | 58 |  |  | typedef u_int8_t lwres_uint8_t; | 
    
    | 59 |  |  |  | 
    
    | 60 |  |  | struct lwres_lwpacket { | 
    
    | 61 |  |  | 	lwres_uint32_t		length; | 
    
    | 62 |  |  | 	lwres_uint16_t		version; | 
    
    | 63 |  |  | 	lwres_uint16_t		pktflags; | 
    
    | 64 |  |  | 	lwres_uint32_t		serial; | 
    
    | 65 |  |  | 	lwres_uint32_t		opcode; | 
    
    | 66 |  |  | 	lwres_uint32_t		result; | 
    
    | 67 |  |  | 	lwres_uint32_t		recvlength; | 
    
    | 68 |  |  | 	lwres_uint16_t		authtype; | 
    
    | 69 |  |  | 	lwres_uint16_t		authlength; | 
    
    | 70 |  |  | }; | 
    
    | 71 |  |  |  | 
    
    | 72 |  |  | #define LWRES_LWPACKETFLAG_RESPONSE	0x0001U	/* if set, pkt is a response */ | 
    
    | 73 |  |  |  | 
    
    | 74 |  |  | #define LWRES_LWPACKETVERSION_0		0 | 
    
    | 75 |  |  |  | 
    
    | 76 |  |  | #define LWRES_FLAG_TRUSTNOTREQUIRED	0x00000001U | 
    
    | 77 |  |  | #define LWRES_FLAG_SECUREDATA		0x00000002U | 
    
    | 78 |  |  |  | 
    
    | 79 |  |  | /* | 
    
    | 80 |  |  |  * no-op | 
    
    | 81 |  |  |  */ | 
    
    | 82 |  |  | #define LWRES_OPCODE_NOOP		0x00000000U | 
    
    | 83 |  |  |  | 
    
    | 84 |  |  | typedef struct { | 
    
    | 85 |  |  | 	/* public */ | 
    
    | 86 |  |  | 	lwres_uint16_t			datalength; | 
    
    | 87 |  |  | 	/* data follows */ | 
    
    | 88 |  |  | } lwres_nooprequest_t; | 
    
    | 89 |  |  |  | 
    
    | 90 |  |  | typedef struct { | 
    
    | 91 |  |  | 	/* public */ | 
    
    | 92 |  |  | 	lwres_uint16_t			datalength; | 
    
    | 93 |  |  | 	/* data follows */ | 
    
    | 94 |  |  | } lwres_noopresponse_t; | 
    
    | 95 |  |  |  | 
    
    | 96 |  |  | /* | 
    
    | 97 |  |  |  * get addresses by name | 
    
    | 98 |  |  |  */ | 
    
    | 99 |  |  | #define LWRES_OPCODE_GETADDRSBYNAME	0x00010001U | 
    
    | 100 |  |  |  | 
    
    | 101 |  |  | typedef struct lwres_addr lwres_addr_t; | 
    
    | 102 |  |  |  | 
    
    | 103 |  |  | struct lwres_addr { | 
    
    | 104 |  |  | 	lwres_uint32_t			family; | 
    
    | 105 |  |  | 	lwres_uint16_t			length; | 
    
    | 106 |  |  | 	/* address folows */ | 
    
    | 107 |  |  | }; | 
    
    | 108 |  |  |  | 
    
    | 109 |  |  | typedef struct { | 
    
    | 110 |  |  | 	/* public */ | 
    
    | 111 |  |  | 	lwres_uint32_t			flags; | 
    
    | 112 |  |  | 	lwres_uint32_t			addrtypes; | 
    
    | 113 |  |  | 	lwres_uint16_t			namelen; | 
    
    | 114 |  |  | 	/* name follows */ | 
    
    | 115 |  |  | } lwres_gabnrequest_t; | 
    
    | 116 |  |  |  | 
    
    | 117 |  |  | typedef struct { | 
    
    | 118 |  |  | 	/* public */ | 
    
    | 119 |  |  | 	lwres_uint32_t			flags; | 
    
    | 120 |  |  | 	lwres_uint16_t			naliases; | 
    
    | 121 |  |  | 	lwres_uint16_t			naddrs; | 
    
    | 122 |  |  | 	lwres_uint16_t			realnamelen; | 
    
    | 123 |  |  | 	/* aliases follows */ | 
    
    | 124 |  |  | 	/* addrs follows */ | 
    
    | 125 |  |  | 	/* realname follows */ | 
    
    | 126 |  |  | } lwres_gabnresponse_t; | 
    
    | 127 |  |  |  | 
    
    | 128 |  |  | /* | 
    
    | 129 |  |  |  * get name by address | 
    
    | 130 |  |  |  */ | 
    
    | 131 |  |  | #define LWRES_OPCODE_GETNAMEBYADDR	0x00010002U | 
    
    | 132 |  |  | typedef struct { | 
    
    | 133 |  |  | 	/* public */ | 
    
    | 134 |  |  | 	lwres_uint32_t			flags; | 
    
    | 135 |  |  | 	lwres_addr_t			addr; | 
    
    | 136 |  |  | 	/* addr body follows */ | 
    
    | 137 |  |  | } lwres_gnbarequest_t; | 
    
    | 138 |  |  |  | 
    
    | 139 |  |  | typedef struct { | 
    
    | 140 |  |  | 	/* public */ | 
    
    | 141 |  |  | 	lwres_uint32_t			flags; | 
    
    | 142 |  |  | 	lwres_uint16_t			naliases; | 
    
    | 143 |  |  | 	lwres_uint16_t			realnamelen; | 
    
    | 144 |  |  | 	/* aliases follows */ | 
    
    | 145 |  |  | 	/* realname follows */ | 
    
    | 146 |  |  | } lwres_gnbaresponse_t; | 
    
    | 147 |  |  |  | 
    
    | 148 |  |  | /* | 
    
    | 149 |  |  |  * get rdata by name | 
    
    | 150 |  |  |  */ | 
    
    | 151 |  |  | #define LWRES_OPCODE_GETRDATABYNAME	0x00010003U | 
    
    | 152 |  |  |  | 
    
    | 153 |  |  | typedef struct { | 
    
    | 154 |  |  | 	/* public */ | 
    
    | 155 |  |  | 	lwres_uint32_t			flags; | 
    
    | 156 |  |  | 	lwres_uint16_t			rdclass; | 
    
    | 157 |  |  | 	lwres_uint16_t			rdtype; | 
    
    | 158 |  |  | 	lwres_uint16_t			namelen; | 
    
    | 159 |  |  | 	/* name follows */ | 
    
    | 160 |  |  | } lwres_grbnrequest_t; | 
    
    | 161 |  |  |  | 
    
    | 162 |  |  | typedef struct { | 
    
    | 163 |  |  | 	/* public */ | 
    
    | 164 |  |  | 	lwres_uint32_t			flags; | 
    
    | 165 |  |  | 	lwres_uint16_t			rdclass; | 
    
    | 166 |  |  | 	lwres_uint16_t			rdtype; | 
    
    | 167 |  |  | 	lwres_uint32_t			ttl; | 
    
    | 168 |  |  | 	lwres_uint16_t			nrdatas; | 
    
    | 169 |  |  | 	lwres_uint16_t			nsigs; | 
    
    | 170 |  |  | 	/* realname here (len + name) */ | 
    
    | 171 |  |  | 	/* rdata here (len + name) */ | 
    
    | 172 |  |  | 	/* signatures here (len + name) */ | 
    
    | 173 |  |  | } lwres_grbnresponse_t; | 
    
    | 174 |  |  |  | 
    
    | 175 |  |  | #define LWRDATA_VALIDATED	0x00000001 | 
    
    | 176 |  |  |  | 
    
    | 177 |  |  | #define LWRES_ADDRTYPE_V4		0x00000001U	/* ipv4 */ | 
    
    | 178 |  |  | #define LWRES_ADDRTYPE_V6		0x00000002U	/* ipv6 */ | 
    
    | 179 |  |  |  | 
    
    | 180 |  |  | #define LWRES_MAX_ALIASES		16		/* max # of aliases */ | 
    
    | 181 |  |  | #define LWRES_MAX_ADDRS			64		/* max # of addrs */ | 
    
    | 182 |  |  |  | 
    
    | 183 |  |  | struct tok opcode[] = { | 
    
    | 184 |  |  | 	{ LWRES_OPCODE_NOOP,		"noop", }, | 
    
    | 185 |  |  | 	{ LWRES_OPCODE_GETADDRSBYNAME,	"getaddrsbyname", }, | 
    
    | 186 |  |  | 	{ LWRES_OPCODE_GETNAMEBYADDR,	"getnamebyaddr", }, | 
    
    | 187 |  |  | 	{ LWRES_OPCODE_GETRDATABYNAME,	"getrdatabyname", }, | 
    
    | 188 |  |  | 	{ 0, 				NULL, }, | 
    
    | 189 |  |  | }; | 
    
    | 190 |  |  |  | 
    
    | 191 |  |  | /* print-domain.c */ | 
    
    | 192 |  |  | extern struct tok ns_type2str[]; | 
    
    | 193 |  |  | extern struct tok ns_class2str[]; | 
    
    | 194 |  |  |  | 
    
    | 195 |  |  | static int lwres_printname(size_t, const char *); | 
    
    | 196 |  |  | static int lwres_printnamelen(const char *); | 
    
    | 197 |  |  | /* static int lwres_printbinlen(const char *); */ | 
    
    | 198 |  |  | static int lwres_printb64len(const char *); | 
    
    | 199 |  |  | static int lwres_printaddr(lwres_addr_t *); | 
    
    | 200 |  |  |  | 
    
    | 201 |  |  | static int | 
    
    | 202 |  |  | lwres_printname(size_t l, const char *p0) | 
    
    | 203 |  |  | { | 
    
    | 204 |  |  | 	const char *p; | 
    
    | 205 |  |  | 	int i; | 
    
    | 206 |  |  |  | 
    
    | 207 |  |  | 	p = p0; | 
    
    | 208 |  |  | 	/* + 1 for terminating \0 */ | 
    
    | 209 |  |  | 	if (p + l + 1 > (const char *)snapend) | 
    
    | 210 |  |  | 		goto trunc; | 
    
    | 211 |  |  |  | 
    
    | 212 |  |  | 	printf(" "); | 
    
    | 213 |  |  | 	for (i = 0; i < l; i++) | 
    
    | 214 |  |  | 		safeputchar(*p++); | 
    
    | 215 |  |  | 	p++;	/* skip terminating \0 */ | 
    
    | 216 |  |  |  | 
    
    | 217 |  |  | 	return p - p0; | 
    
    | 218 |  |  |  | 
    
    | 219 |  |  |   trunc: | 
    
    | 220 |  |  | 	return -1; | 
    
    | 221 |  |  | } | 
    
    | 222 |  |  |  | 
    
    | 223 |  |  | static int | 
    
    | 224 |  |  | lwres_printnamelen(const char *p) | 
    
    | 225 |  |  | { | 
    
    | 226 |  |  | 	u_int16_t l; | 
    
    | 227 |  |  | 	int advance; | 
    
    | 228 |  |  |  | 
    
    | 229 |  |  | 	if (p + 2 > (const char *)snapend) | 
    
    | 230 |  |  | 		goto trunc; | 
    
    | 231 |  |  | 	l = EXTRACT_16BITS(p); | 
    
    | 232 |  |  | 	advance = lwres_printname(l, p + 2); | 
    
    | 233 |  |  | 	if (advance < 0) | 
    
    | 234 |  |  | 		goto trunc; | 
    
    | 235 |  |  | 	return 2 + advance; | 
    
    | 236 |  |  |  | 
    
    | 237 |  |  |   trunc: | 
    
    | 238 |  |  | 	return -1; | 
    
    | 239 |  |  | } | 
    
    | 240 |  |  |  | 
    
    | 241 |  |  | #if 0 | 
    
    | 242 |  |  | static int | 
    
    | 243 |  |  | lwres_printbinlen(const char *p0) | 
    
    | 244 |  |  | { | 
    
    | 245 |  |  | 	u_int8_t *p; | 
    
    | 246 |  |  | 	u_int16_t l; | 
    
    | 247 |  |  | 	int i; | 
    
    | 248 |  |  |  | 
    
    | 249 |  |  | 	p = (u_int8_t *)p0; | 
    
    | 250 |  |  | 	if (p + 2 > (u_int8_t *)snapend) | 
    
    | 251 |  |  | 		goto trunc; | 
    
    | 252 |  |  | 	l = EXTRACT_16BITS(p); | 
    
    | 253 |  |  | 	if (p + 2 + l > (u_int8_t *)snapend) | 
    
    | 254 |  |  | 		goto trunc; | 
    
    | 255 |  |  | 	p += 2; | 
    
    | 256 |  |  | 	for (i = 0; i < l; i++) | 
    
    | 257 |  |  | 		printf("%02x", *p++); | 
    
    | 258 |  |  | 	return p - (u_int8_t *)p0; | 
    
    | 259 |  |  |  | 
    
    | 260 |  |  |   trunc: | 
    
    | 261 |  |  | 	return -1; | 
    
    | 262 |  |  | } | 
    
    | 263 |  |  | #endif | 
    
    | 264 |  |  |  | 
    
    | 265 |  |  | static int | 
    
    | 266 |  |  | lwres_printb64len(const char *p0) | 
    
    | 267 |  |  | { | 
    
    | 268 |  |  | 	u_int8_t *p; | 
    
    | 269 |  |  | 	u_int16_t l; | 
    
    | 270 |  |  | 	char *dbuf, *b64buf; | 
    
    | 271 |  |  | 	int i; | 
    
    | 272 |  |  |  | 
    
    | 273 |  |  | 	p = (u_int8_t *)p0; | 
    
    | 274 |  |  | 	if (p + 2 > (u_int8_t *)snapend) | 
    
    | 275 |  |  | 		goto trunc; | 
    
    | 276 |  |  | 	l = EXTRACT_16BITS(p); | 
    
    | 277 |  |  | 	if (p + 2 + l > (u_int8_t *)snapend) | 
    
    | 278 |  |  | 		goto trunc; | 
    
    | 279 |  |  |  | 
    
    | 280 |  |  | 	dbuf = malloc(l + 1); | 
    
    | 281 |  |  | 	if (!dbuf) | 
    
    | 282 |  |  | 	  return -1; | 
    
    | 283 |  |  |  | 
    
    | 284 |  |  | 	b64buf = malloc((l + 2) * 4 / 3); | 
    
    | 285 |  |  | 	if (!b64buf) | 
    
    | 286 |  |  | 	  { | 
    
    | 287 |  |  | 	    free(dbuf); | 
    
    | 288 |  |  | 	    return -1; | 
    
    | 289 |  |  | 	  } | 
    
    | 290 |  |  |  | 
    
    | 291 |  |  | 	memcpy(dbuf, p, l); | 
    
    | 292 |  |  | 	*(dbuf + l) = (char)0; | 
    
    | 293 |  |  |  | 
    
    | 294 |  |  | 	i = b64_ntop (dbuf, l, b64buf, (l + 2) * 4 / 3); | 
    
    | 295 |  |  | 	b64buf[i] = (char)0; | 
    
    | 296 |  |  | 	printf ("%s", b64buf); | 
    
    | 297 |  |  |  | 
    
    | 298 |  |  | 	free (dbuf); | 
    
    | 299 |  |  | 	free (b64buf); | 
    
    | 300 |  |  |  | 
    
    | 301 |  |  | 	return l + 2; | 
    
    | 302 |  |  |  | 
    
    | 303 |  |  |   trunc: | 
    
    | 304 |  |  | 	return -1; | 
    
    | 305 |  |  | } | 
    
    | 306 |  |  |  | 
    
    | 307 |  |  | static int | 
    
    | 308 |  |  | lwres_printaddr(lwres_addr_t *ap) | 
    
    | 309 |  |  | { | 
    
    | 310 |  |  | 	u_int16_t l; | 
    
    | 311 |  |  | 	const char *p; | 
    
    | 312 |  |  | 	int i; | 
    
    | 313 |  |  |  | 
    
    | 314 |  |  | 	TCHECK(ap->length); | 
    
    | 315 |  |  | 	l = ntohs(ap->length); | 
    
    | 316 |  |  | 	/* XXX ap points to packed struct */ | 
    
    | 317 |  |  | 	p = (const char *)&ap->length + sizeof(ap->length); | 
    
    | 318 |  |  | 	if (p + l > (const char *)snapend) | 
    
    | 319 |  |  | 		goto trunc; | 
    
    | 320 |  |  |  | 
    
    | 321 |  |  | 	switch (ntohl(ap->family)) { | 
    
    | 322 |  |  | 	case 1:	/* IPv4 */ | 
    
    | 323 |  |  | 		printf(" %s", ipaddr_string(p)); | 
    
    | 324 |  |  | 		p += sizeof(struct in_addr); | 
    
    | 325 |  |  | 		break; | 
    
    | 326 |  |  | #ifdef INET6 | 
    
    | 327 |  |  | 	case 2:	/* IPv6 */ | 
    
    | 328 |  |  | 		printf(" %s", ip6addr_string(p)); | 
    
    | 329 |  |  | 		p += sizeof(struct in6_addr); | 
    
    | 330 |  |  | 		break; | 
    
    | 331 |  |  | #endif | 
    
    | 332 |  |  | 	default: | 
    
    | 333 |  |  | 		printf(" %lu/", (unsigned long)ntohl(ap->family)); | 
    
    | 334 |  |  | 		for (i = 0; i < l; i++) | 
    
    | 335 |  |  | 			printf("%02x", *p++); | 
    
    | 336 |  |  | 	} | 
    
    | 337 |  |  |  | 
    
    | 338 |  |  | 	return p - (const char *)ap; | 
    
    | 339 |  |  |  | 
    
    | 340 |  |  |   trunc: | 
    
    | 341 |  |  | 	return -1; | 
    
    | 342 |  |  | } | 
    
    | 343 |  |  |  | 
    
    | 344 |  |  | void | 
    
    | 345 |  |  | lwres_print(const u_char *bp, u_int length) | 
    
    | 346 |  |  | { | 
    
    | 347 |  |  | 	const struct lwres_lwpacket *np; | 
    
    | 348 |  |  | 	u_int32_t v; | 
    
    | 349 |  |  | 	const char *s; | 
    
    | 350 |  |  | 	int response; | 
    
    | 351 |  |  | 	int advance; | 
    
    | 352 |  |  | 	int unsupported = 0; | 
    
    | 353 |  |  |  | 
    
    | 354 |  |  | 	np = (const struct lwres_lwpacket *)bp; | 
    
    | 355 |  |  | 	TCHECK(np->authlength); | 
    
    | 356 |  |  |  | 
    
    | 357 |  |  | 	printf(" lwres"); | 
    
    | 358 |  |  | 	v = ntohs(np->version); | 
    
    | 359 |  |  | 	if (vflag || v != LWRES_LWPACKETVERSION_0) | 
    
    | 360 |  |  | 		printf(" v%u", v); | 
    
    | 361 |  |  | 	if (v != LWRES_LWPACKETVERSION_0) { | 
    
    | 362 |  |  | 		s = (const char *)np + ntohl(np->length); | 
    
    | 363 |  |  | 		goto tail; | 
    
    | 364 |  |  | 	} | 
    
    | 365 |  |  |  | 
    
    | 366 |  |  | 	response = ntohs(np->pktflags) & LWRES_LWPACKETFLAG_RESPONSE; | 
    
    | 367 |  |  |  | 
    
    | 368 |  |  | 	/* opcode and pktflags */ | 
    
    | 369 |  |  | 	v = (u_int32_t)ntohl(np->opcode); | 
    
    | 370 |  |  | 	s = tok2str(opcode, "#0x%x", v); | 
    
    | 371 |  |  | 	printf(" %s%s", s, response ? "" : "?"); | 
    
    | 372 |  |  |  | 
    
    | 373 |  |  | 	/* pktflags */ | 
    
    | 374 |  |  | 	v = ntohs(np->pktflags); | 
    
    | 375 |  |  | 	if (v & ~LWRES_LWPACKETFLAG_RESPONSE) | 
    
    | 376 |  |  | 		printf("[0x%x]", v); | 
    
    | 377 |  |  |  | 
    
    | 378 |  |  | 	if (vflag > 1) { | 
    
    | 379 |  |  | 		printf(" (");	/*)*/ | 
    
    | 380 |  |  | 		printf("serial:0x%lx", (unsigned long)ntohl(np->serial)); | 
    
    | 381 |  |  | 		printf(" result:0x%lx", (unsigned long)ntohl(np->result)); | 
    
    | 382 |  |  | 		printf(" recvlen:%lu", (unsigned long)ntohl(np->recvlength)); | 
    
    | 383 |  |  | 		/* BIND910: not used */ | 
    
    | 384 |  |  | 		if (vflag > 2) { | 
    
    | 385 |  |  | 			printf(" authtype:0x%x", ntohs(np->authtype)); | 
    
    | 386 |  |  | 			printf(" authlen:%u", ntohs(np->authlength)); | 
    
    | 387 |  |  | 		} | 
    
    | 388 |  |  | 		/*(*/ | 
    
    | 389 |  |  | 		printf(")"); | 
    
    | 390 |  |  | 	} | 
    
    | 391 |  |  |  | 
    
    | 392 |  |  | 	/* per-opcode content */ | 
    
    | 393 |  |  | 	if (!response) { | 
    
    | 394 |  |  | 		/* | 
    
    | 395 |  |  | 		 * queries | 
    
    | 396 |  |  | 		 */ | 
    
    | 397 |  |  | 		lwres_gabnrequest_t *gabn; | 
    
    | 398 |  |  | 		lwres_gnbarequest_t *gnba; | 
    
    | 399 |  |  | 		lwres_grbnrequest_t *grbn; | 
    
    | 400 |  |  | 		u_int32_t l; | 
    
    | 401 |  |  |  | 
    
    | 402 |  |  | 		gabn = NULL; | 
    
    | 403 |  |  | 		gnba = NULL; | 
    
    | 404 |  |  | 		grbn = NULL; | 
    
    | 405 |  |  |  | 
    
    | 406 |  |  | 		switch (ntohl(np->opcode)) { | 
    
    | 407 |  |  | 		case LWRES_OPCODE_NOOP: | 
    
    | 408 |  |  | 			break; | 
    
    | 409 |  |  | 		case LWRES_OPCODE_GETADDRSBYNAME: | 
    
    | 410 |  |  | 			gabn = (lwres_gabnrequest_t *)(np + 1); | 
    
    | 411 |  |  | 			TCHECK(gabn->namelen); | 
    
    | 412 |  |  | 			/* XXX gabn points to packed struct */ | 
    
    | 413 |  |  | 			s = (const char *)&gabn->namelen + | 
    
    | 414 |  |  | 			    sizeof(gabn->namelen); | 
    
    | 415 |  |  | 			l = ntohs(gabn->namelen); | 
    
    | 416 |  |  |  | 
    
    | 417 |  |  | 			/* BIND910: not used */ | 
    
    | 418 |  |  | 			if (vflag > 2) { | 
    
    | 419 |  |  | 				printf(" flags:0x%lx", | 
    
    | 420 |  |  | 				    (unsigned long)ntohl(gabn->flags)); | 
    
    | 421 |  |  | 			} | 
    
    | 422 |  |  |  | 
    
    | 423 |  |  | 			v = (u_int32_t)ntohl(gabn->addrtypes); | 
    
    | 424 |  |  | 			switch (v & (LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) { | 
    
    | 425 |  |  | 			case LWRES_ADDRTYPE_V4: | 
    
    | 426 |  |  | 				printf(" IPv4"); | 
    
    | 427 |  |  | 				break; | 
    
    | 428 |  |  | 			case LWRES_ADDRTYPE_V6: | 
    
    | 429 |  |  | 				printf(" IPv6"); | 
    
    | 430 |  |  | 				break; | 
    
    | 431 |  |  | 			case LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6: | 
    
    | 432 |  |  | 				printf(" IPv4/6"); | 
    
    | 433 |  |  | 				break; | 
    
    | 434 |  |  | 			} | 
    
    | 435 |  |  | 			if (v & ~(LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) | 
    
    | 436 |  |  | 				printf("[0x%x]", v); | 
    
    | 437 |  |  |  | 
    
    | 438 |  |  | 			advance = lwres_printname(l, s); | 
    
    | 439 |  |  | 			if (advance < 0) | 
    
    | 440 |  |  | 				goto trunc; | 
    
    | 441 |  |  | 			s += advance; | 
    
    | 442 |  |  | 			break; | 
    
    | 443 |  |  | 		case LWRES_OPCODE_GETNAMEBYADDR: | 
    
    | 444 |  |  | 			gnba = (lwres_gnbarequest_t *)(np + 1); | 
    
    | 445 |  |  | 			TCHECK(gnba->addr); | 
    
    | 446 |  |  |  | 
    
    | 447 |  |  | 			/* BIND910: not used */ | 
    
    | 448 |  |  | 			if (vflag > 2) { | 
    
    | 449 |  |  | 				printf(" flags:0x%lx", | 
    
    | 450 |  |  | 				    (unsigned long)ntohl(gnba->flags)); | 
    
    | 451 |  |  | 			} | 
    
    | 452 |  |  |  | 
    
    | 453 |  |  | 			s = (const char *)&gnba->addr; | 
    
    | 454 |  |  |  | 
    
    | 455 |  |  | 			advance = lwres_printaddr(&gnba->addr); | 
    
    | 456 |  |  | 			if (advance < 0) | 
    
    | 457 |  |  | 				goto trunc; | 
    
    | 458 |  |  | 			s += advance; | 
    
    | 459 |  |  | 			break; | 
    
    | 460 |  |  | 		default: | 
    
    | 461 |  |  | 			unsupported++; | 
    
    | 462 |  |  | 			break; | 
    
    | 463 |  |  | 		} | 
    
    | 464 |  |  | 	} else { | 
    
    | 465 |  |  | 		/* | 
    
    | 466 |  |  | 		 * responses | 
    
    | 467 |  |  | 		 */ | 
    
    | 468 |  |  | 		lwres_gabnresponse_t *gabn; | 
    
    | 469 |  |  | 		lwres_gnbaresponse_t *gnba; | 
    
    | 470 |  |  | 		lwres_grbnresponse_t *grbn; | 
    
    | 471 |  |  | 		u_int32_t l, na; | 
    
    | 472 |  |  | 		int i; | 
    
    | 473 |  |  |  | 
    
    | 474 |  |  | 		gabn = NULL; | 
    
    | 475 |  |  | 		gnba = NULL; | 
    
    | 476 |  |  | 		grbn = NULL; | 
    
    | 477 |  |  |  | 
    
    | 478 |  |  | 		switch (ntohl(np->opcode)) { | 
    
    | 479 |  |  | 		case LWRES_OPCODE_NOOP: | 
    
    | 480 |  |  | 			break; | 
    
    | 481 |  |  | 		case LWRES_OPCODE_GETADDRSBYNAME: | 
    
    | 482 |  |  | 			gabn = (lwres_gabnresponse_t *)(np + 1); | 
    
    | 483 |  |  | 			TCHECK(gabn->realnamelen); | 
    
    | 484 |  |  | 			/* XXX gabn points to packed struct */ | 
    
    | 485 |  |  | 			s = (const char *)&gabn->realnamelen + | 
    
    | 486 |  |  | 			    sizeof(gabn->realnamelen); | 
    
    | 487 |  |  | 			l = ntohs(gabn->realnamelen); | 
    
    | 488 |  |  |  | 
    
    | 489 |  |  | 			/* BIND910: not used */ | 
    
    | 490 |  |  | 			if (vflag > 2) { | 
    
    | 491 |  |  | 				printf(" flags:0x%lx", | 
    
    | 492 |  |  | 				    (unsigned long)ntohl(gabn->flags)); | 
    
    | 493 |  |  | 			} | 
    
    | 494 |  |  |  | 
    
    | 495 |  |  | 			printf(" %u/%u", ntohs(gabn->naliases), | 
    
    | 496 |  |  | 			    ntohs(gabn->naddrs)); | 
    
    | 497 |  |  |  | 
    
    | 498 |  |  | 			advance = lwres_printname(l, s); | 
    
    | 499 |  |  | 			if (advance < 0) | 
    
    | 500 |  |  | 				goto trunc; | 
    
    | 501 |  |  | 			s += advance; | 
    
    | 502 |  |  |  | 
    
    | 503 |  |  | 			/* aliases */ | 
    
    | 504 |  |  | 			na = ntohs(gabn->naliases); | 
    
    | 505 |  |  | 			for (i = 0; i < na; i++) { | 
    
    | 506 |  |  | 				advance = lwres_printnamelen(s); | 
    
    | 507 |  |  | 				if (advance < 0) | 
    
    | 508 |  |  | 					goto trunc; | 
    
    | 509 |  |  | 				s += advance; | 
    
    | 510 |  |  | 			} | 
    
    | 511 |  |  |  | 
    
    | 512 |  |  | 			/* addrs */ | 
    
    | 513 |  |  | 			na = ntohs(gabn->naddrs); | 
    
    | 514 |  |  | 			for (i = 0; i < na; i++) { | 
    
    | 515 |  |  | 				advance = lwres_printaddr((lwres_addr_t *)s); | 
    
    | 516 |  |  | 				if (advance < 0) | 
    
    | 517 |  |  | 					goto trunc; | 
    
    | 518 |  |  | 				s += advance; | 
    
    | 519 |  |  | 			} | 
    
    | 520 |  |  | 			break; | 
    
    | 521 |  |  | 		case LWRES_OPCODE_GETNAMEBYADDR: | 
    
    | 522 |  |  | 			gnba = (lwres_gnbaresponse_t *)(np + 1); | 
    
    | 523 |  |  | 			TCHECK(gnba->realnamelen); | 
    
    | 524 |  |  | 			/* XXX gnba points to packed struct */ | 
    
    | 525 |  |  | 			s = (const char *)&gnba->realnamelen + | 
    
    | 526 |  |  | 			    sizeof(gnba->realnamelen); | 
    
    | 527 |  |  | 			l = ntohs(gnba->realnamelen); | 
    
    | 528 |  |  |  | 
    
    | 529 |  |  | 			/* BIND910: not used */ | 
    
    | 530 |  |  | 			if (vflag > 2) { | 
    
    | 531 |  |  | 				printf(" flags:0x%lx", | 
    
    | 532 |  |  | 				    (unsigned long)ntohl(gnba->flags)); | 
    
    | 533 |  |  | 			} | 
    
    | 534 |  |  |  | 
    
    | 535 |  |  | 			printf(" %u", ntohs(gnba->naliases)); | 
    
    | 536 |  |  |  | 
    
    | 537 |  |  | 			advance = lwres_printname(l, s); | 
    
    | 538 |  |  | 			if (advance < 0) | 
    
    | 539 |  |  | 				goto trunc; | 
    
    | 540 |  |  | 			s += advance; | 
    
    | 541 |  |  |  | 
    
    | 542 |  |  | 			/* aliases */ | 
    
    | 543 |  |  | 			na = ntohs(gnba->naliases); | 
    
    | 544 |  |  | 			for (i = 0; i < na; i++) { | 
    
    | 545 |  |  | 				advance = lwres_printnamelen(s); | 
    
    | 546 |  |  | 				if (advance < 0) | 
    
    | 547 |  |  | 					goto trunc; | 
    
    | 548 |  |  | 				s += advance; | 
    
    | 549 |  |  | 			} | 
    
    | 550 |  |  | 			break; | 
    
    | 551 |  |  | 		case LWRES_OPCODE_GETRDATABYNAME: | 
    
    | 552 |  |  | 			/* XXX no trace, not tested */ | 
    
    | 553 |  |  | 			grbn = (lwres_grbnresponse_t *)(np + 1); | 
    
    | 554 |  |  | 			TCHECK(grbn->nsigs); | 
    
    | 555 |  |  |  | 
    
    | 556 |  |  | 			/* BIND910: not used */ | 
    
    | 557 |  |  | 			if (vflag > 2) { | 
    
    | 558 |  |  | 				printf(" flags:0x%lx", | 
    
    | 559 |  |  | 				    (unsigned long)ntohl(grbn->flags)); | 
    
    | 560 |  |  | 			} | 
    
    | 561 |  |  |  | 
    
    | 562 |  |  | 			printf(" %s", tok2str(ns_type2str, "Type%d", | 
    
    | 563 |  |  | 			    ntohs(grbn->rdtype))); | 
    
    | 564 |  |  | 			if (ntohs(grbn->rdclass) != C_IN) | 
    
    | 565 |  |  | 				printf(" %s", tok2str(ns_class2str, "Class%d", | 
    
    | 566 |  |  | 				    ntohs(grbn->rdclass))); | 
    
    | 567 |  |  | 			printf(" TTL "); | 
    
    | 568 |  |  | 			relts_print(ntohl(grbn->ttl)); | 
    
    | 569 |  |  | 			printf(" %u/%u", ntohs(grbn->nrdatas), | 
    
    | 570 |  |  | 			    ntohs(grbn->nsigs)); | 
    
    | 571 |  |  |  | 
    
    | 572 |  |  | 			/* XXX grbn points to packed struct */ | 
    
    | 573 |  |  | 			s = (const char *)&grbn->nsigs+ sizeof(grbn->nsigs); | 
    
    | 574 |  |  |  | 
    
    | 575 |  |  | 			advance = lwres_printnamelen(s); | 
    
    | 576 |  |  | 			if (advance < 0) | 
    
    | 577 |  |  | 				goto trunc; | 
    
    | 578 |  |  | 			s += advance; | 
    
    | 579 |  |  |  | 
    
    | 580 |  |  | 			/* rdatas */ | 
    
    | 581 |  |  | 			na = ntohs(grbn->nrdatas); | 
    
    | 582 |  |  | 			if (na > 0) | 
    
    | 583 |  |  | 			  printf(" "); | 
    
    | 584 |  |  |  | 
    
    | 585 |  |  | 			for (i = 0; i < na; i++) { | 
    
    | 586 |  |  | 				/* XXX should decode resource data */ | 
    
    | 587 |  |  | 				advance = lwres_printb64len(s); | 
    
    | 588 |  |  | 				if (advance < 0) | 
    
    | 589 |  |  | 					goto trunc; | 
    
    | 590 |  |  | 				s += advance; | 
    
    | 591 |  |  | 			} | 
    
    | 592 |  |  |  | 
    
    | 593 |  |  | 			/* sigs */ | 
    
    | 594 |  |  | 			na = ntohs(grbn->nsigs); | 
    
    | 595 |  |  | 			if (na > 0) | 
    
    | 596 |  |  | 			  printf(" "); | 
    
    | 597 |  |  |  | 
    
    | 598 |  |  | 			for (i = 0; i < na; i++) { | 
    
    | 599 |  |  | 				/* XXX how should we print it? */ | 
    
    | 600 |  |  | 				advance = lwres_printb64len(s); | 
    
    | 601 |  |  | 				if (advance < 0) | 
    
    | 602 |  |  | 					goto trunc; | 
    
    | 603 |  |  | 				s += advance; | 
    
    | 604 |  |  | 			} | 
    
    | 605 |  |  | 			break; | 
    
    | 606 |  |  | 		default: | 
    
    | 607 |  |  | 			unsupported++; | 
    
    | 608 |  |  | 			break; | 
    
    | 609 |  |  | 		} | 
    
    | 610 |  |  | 	} | 
    
    | 611 |  |  |  | 
    
    | 612 |  |  |   tail: | 
    
    | 613 |  |  | 	/* length mismatch */ | 
    
    | 614 |  |  | 	if (ntohl(np->length) != length) { | 
    
    | 615 |  |  | 		printf(" [len: %lu != %u]", (unsigned long)ntohl(np->length), | 
    
    | 616 |  |  | 		    length); | 
    
    | 617 |  |  | 	} | 
    
    | 618 |  |  | 	if (!unsupported && s < (const char *)np + ntohl(np->length)) | 
    
    | 619 |  |  | 		printf("[extra]"); | 
    
    | 620 |  |  | 	return; | 
    
    | 621 |  |  |  | 
    
    | 622 |  |  |   trunc: | 
    
    | 623 |  |  | 	printf("[|lwres]"); | 
    
    | 624 |  |  | 	return; | 
    
    | 625 |  |  | } |