2 * Copyright (C) 2001 WIDE Project.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
31 static const char rcsid
[] =
32 "@(#) $Header: /tcpdump/master/tcpdump/print-lwres.c,v 1.9 2002-12-11 07:14:04 guy Exp $ (LBL)";
39 #include <tcpdump-stdinc.h>
46 #include "interface.h"
47 #include "addrtoname.h"
48 #include "extract.h" /* must come after interface.h */
50 /* BIND9 lib/lwres/include/lwres */
51 typedef u_int32_t lwres_uint32_t
;
52 typedef u_int16_t lwres_uint16_t
;
53 typedef u_int8_t lwres_uint8_t
;
55 struct lwres_lwpacket
{
56 lwres_uint32_t length
;
57 lwres_uint16_t version
;
58 lwres_uint16_t pktflags
;
59 lwres_uint32_t serial
;
60 lwres_uint32_t opcode
;
61 lwres_uint32_t result
;
62 lwres_uint32_t recvlength
;
63 lwres_uint16_t authtype
;
64 lwres_uint16_t authlength
;
67 #define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */
69 #define LWRES_LWPACKETVERSION_0 0
71 #define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U
72 #define LWRES_FLAG_SECUREDATA 0x00000002U
77 #define LWRES_OPCODE_NOOP 0x00000000U
81 lwres_uint16_t datalength
;
83 } lwres_nooprequest_t
;
87 lwres_uint16_t datalength
;
89 } lwres_noopresponse_t
;
92 * get addresses by name
94 #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
96 typedef struct lwres_addr lwres_addr_t
;
99 lwres_uint32_t family
;
100 lwres_uint16_t length
;
106 lwres_uint32_t flags
;
107 lwres_uint32_t addrtypes
;
108 lwres_uint16_t namelen
;
110 } lwres_gabnrequest_t
;
114 lwres_uint32_t flags
;
115 lwres_uint16_t naliases
;
116 lwres_uint16_t naddrs
;
117 lwres_uint16_t realnamelen
;
118 /* aliases follows */
120 /* realname follows */
121 } lwres_gabnresponse_t
;
124 * get name by address
126 #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
129 lwres_uint32_t flags
;
131 /* addr body follows */
132 } lwres_gnbarequest_t
;
136 lwres_uint32_t flags
;
137 lwres_uint16_t naliases
;
138 lwres_uint16_t realnamelen
;
139 /* aliases follows */
140 /* realname follows */
141 } lwres_gnbaresponse_t
;
146 #define LWRES_OPCODE_GETRDATABYNAME 0x00010003U
150 lwres_uint32_t flags
;
151 lwres_uint16_t rdclass
;
152 lwres_uint16_t rdtype
;
153 lwres_uint16_t namelen
;
155 } lwres_grbnrequest_t
;
159 lwres_uint32_t flags
;
160 lwres_uint16_t rdclass
;
161 lwres_uint16_t rdtype
;
163 lwres_uint16_t nrdatas
;
164 lwres_uint16_t nsigs
;
165 /* realname here (len + name) */
166 /* rdata here (len + name) */
167 /* signatures here (len + name) */
168 } lwres_grbnresponse_t
;
170 #define LWRDATA_VALIDATED 0x00000001
172 #define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */
173 #define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */
175 #define LWRES_MAX_ALIASES 16 /* max # of aliases */
176 #define LWRES_MAX_ADDRS 64 /* max # of addrs */
178 struct tok opcode
[] = {
179 { LWRES_OPCODE_NOOP
, "noop", },
180 { LWRES_OPCODE_GETADDRSBYNAME
, "getaddrsbyname", },
181 { LWRES_OPCODE_GETNAMEBYADDR
, "getnamebyaddr", },
182 { LWRES_OPCODE_GETRDATABYNAME
, "getrdatabyname", },
187 extern struct tok ns_type2str
[];
188 extern struct tok ns_class2str
[];
190 static int lwres_printname(size_t, const char *);
191 static int lwres_printnamelen(const char *);
192 static int lwres_printbinlen(const char *);
193 static int lwres_printaddr(lwres_addr_t
*);
196 lwres_printname(size_t l
, const char *p0
)
202 /* + 1 for terminating \0 */
203 if (p
+ l
+ 1 > (const char *)snapend
)
207 for (i
= 0; i
< l
; i
++)
209 p
++; /* skip terminating \0 */
218 lwres_printnamelen(const char *p
)
223 if (p
+ 2 > (const char *)snapend
)
225 l
= EXTRACT_16BITS(p
);
226 advance
= lwres_printname(l
, p
+ 2);
236 lwres_printbinlen(const char *p0
)
243 if (p
+ 2 > (const char *)snapend
)
245 l
= EXTRACT_16BITS(p
);
246 if (p
+ 2 + l
> (const char *)snapend
)
249 for (i
= 0; i
< l
; i
++)
250 printf("%02x", *p
++);
258 lwres_printaddr(lwres_addr_t
*ap
)
265 l
= EXTRACT_16BITS(&ap
->length
);
266 /* XXX ap points to packed struct */
267 p
= (const char *)&ap
->length
+ sizeof(ap
->length
);
268 if (p
+ l
> (const char *)snapend
)
271 switch (EXTRACT_32BITS(&ap
->family
)) {
273 printf(" %s", ipaddr_string(p
));
274 p
+= sizeof(struct in_addr
);
278 printf(" %s", ip6addr_string(p
));
279 p
+= sizeof(struct in6_addr
);
283 printf(" %u/", EXTRACT_32BITS(&ap
->family
));
284 for (i
= 0; i
< l
; i
++)
285 printf("%02x", *p
++);
288 return p
- (const char *)ap
;
295 lwres_print(register const u_char
*bp
, u_int length
)
297 const struct lwres_lwpacket
*np
;
304 np
= (const struct lwres_lwpacket
*)bp
;
305 TCHECK(np
->authlength
);
308 v
= EXTRACT_16BITS(&np
->version
);
309 if (vflag
|| v
!= LWRES_LWPACKETVERSION_0
)
311 if (v
!= LWRES_LWPACKETVERSION_0
) {
312 s
= (const char *)np
+ EXTRACT_32BITS(&np
->length
);
316 response
= EXTRACT_16BITS(&np
->pktflags
) & LWRES_LWPACKETFLAG_RESPONSE
;
318 /* opcode and pktflags */
319 v
= EXTRACT_32BITS(&np
->opcode
);
320 s
= tok2str(opcode
, "#0x%x", v
);
321 printf(" %s%s", s
, response
? "" : "?");
324 v
= EXTRACT_16BITS(&np
->pktflags
);
325 if (v
& ~LWRES_LWPACKETFLAG_RESPONSE
)
330 printf("serial:0x%x", EXTRACT_32BITS(&np
->serial
));
331 printf(" result:0x%x", EXTRACT_32BITS(&np
->result
));
332 printf(" recvlen:%u", EXTRACT_32BITS(&np
->recvlength
));
333 /* BIND910: not used */
335 printf(" authtype:0x%x", EXTRACT_16BITS(&np
->authtype
));
336 printf(" authlen:%u", EXTRACT_16BITS(&np
->authlength
));
342 /* per-opcode content */
347 lwres_gabnrequest_t
*gabn
;
348 lwres_gnbarequest_t
*gnba
;
349 lwres_grbnrequest_t
*grbn
;
356 switch (EXTRACT_32BITS(&np
->opcode
)) {
357 case LWRES_OPCODE_NOOP
:
359 case LWRES_OPCODE_GETADDRSBYNAME
:
360 gabn
= (lwres_gabnrequest_t
*)(np
+ 1);
361 TCHECK(gabn
->namelen
);
362 /* XXX gabn points to packed struct */
363 s
= (const char *)&gabn
->namelen
+
364 sizeof(gabn
->namelen
);
365 l
= EXTRACT_16BITS(&gabn
->namelen
);
367 /* BIND910: not used */
369 printf(" flags:0x%x",
370 EXTRACT_32BITS(&gabn
->flags
));
373 v
= EXTRACT_32BITS(&gabn
->addrtypes
);
374 switch (v
& (LWRES_ADDRTYPE_V4
| LWRES_ADDRTYPE_V6
)) {
375 case LWRES_ADDRTYPE_V4
:
378 case LWRES_ADDRTYPE_V6
:
381 case LWRES_ADDRTYPE_V4
| LWRES_ADDRTYPE_V6
:
385 if (v
& ~(LWRES_ADDRTYPE_V4
| LWRES_ADDRTYPE_V6
))
388 advance
= lwres_printname(l
, s
);
393 case LWRES_OPCODE_GETNAMEBYADDR
:
394 gnba
= (lwres_gnbarequest_t
*)(np
+ 1);
397 /* BIND910: not used */
399 printf(" flags:0x%x",
400 EXTRACT_32BITS(&gnba
->flags
));
403 s
= (const char *)&gnba
->addr
;
405 advance
= lwres_printaddr(&gnba
->addr
);
410 case LWRES_OPCODE_GETRDATABYNAME
:
411 /* XXX no trace, not tested */
412 grbn
= (lwres_grbnrequest_t
*)(np
+ 1);
413 TCHECK(grbn
->namelen
);
415 /* BIND910: not used */
417 printf(" flags:0x%x",
418 EXTRACT_32BITS(&grbn
->flags
));
421 printf(" %s", tok2str(ns_type2str
, "Type%d",
422 EXTRACT_16BITS(&grbn
->rdtype
)));
423 if (EXTRACT_16BITS(&grbn
->rdclass
) != C_IN
) {
424 printf(" %s", tok2str(ns_class2str
, "Class%d",
425 EXTRACT_16BITS(&grbn
->rdclass
)));
428 /* XXX grbn points to packed struct */
429 s
= (const char *)&grbn
->namelen
+
430 sizeof(grbn
->namelen
);
431 l
= EXTRACT_16BITS(&gabn
->namelen
);
433 advance
= lwres_printname(l
, s
);
446 lwres_gabnresponse_t
*gabn
;
447 lwres_gnbaresponse_t
*gnba
;
448 lwres_grbnresponse_t
*grbn
;
456 switch (EXTRACT_32BITS(&np
->opcode
)) {
457 case LWRES_OPCODE_NOOP
:
459 case LWRES_OPCODE_GETADDRSBYNAME
:
460 gabn
= (lwres_gabnresponse_t
*)(np
+ 1);
461 TCHECK(gabn
->realnamelen
);
462 /* XXX gabn points to packed struct */
463 s
= (const char *)&gabn
->realnamelen
+
464 sizeof(gabn
->realnamelen
);
465 l
= EXTRACT_16BITS(&gabn
->realnamelen
);
467 /* BIND910: not used */
469 printf(" flags:0x%x",
470 EXTRACT_32BITS(&gabn
->flags
));
473 printf(" %u/%u", EXTRACT_16BITS(&gabn
->naliases
),
474 EXTRACT_16BITS(&gabn
->naddrs
));
476 advance
= lwres_printname(l
, s
);
482 na
= EXTRACT_16BITS(&gabn
->naliases
);
483 for (i
= 0; i
< na
; i
++) {
484 advance
= lwres_printnamelen(s
);
491 na
= EXTRACT_16BITS(&gabn
->naddrs
);
492 for (i
= 0; i
< na
; i
++) {
493 advance
= lwres_printaddr((lwres_addr_t
*)s
);
499 case LWRES_OPCODE_GETNAMEBYADDR
:
500 gnba
= (lwres_gnbaresponse_t
*)(np
+ 1);
501 TCHECK(gnba
->realnamelen
);
502 /* XXX gnba points to packed struct */
503 s
= (const char *)&gnba
->realnamelen
+
504 sizeof(gnba
->realnamelen
);
505 l
= EXTRACT_16BITS(&gnba
->realnamelen
);
507 /* BIND910: not used */
509 printf(" flags:0x%x",
510 EXTRACT_32BITS(&gnba
->flags
));
513 printf(" %u", EXTRACT_16BITS(&gnba
->naliases
));
515 advance
= lwres_printname(l
, s
);
521 na
= EXTRACT_16BITS(&gnba
->naliases
);
522 for (i
= 0; i
< na
; i
++) {
523 advance
= lwres_printnamelen(s
);
529 case LWRES_OPCODE_GETRDATABYNAME
:
530 /* XXX no trace, not tested */
531 grbn
= (lwres_grbnresponse_t
*)(np
+ 1);
534 /* BIND910: not used */
536 printf(" flags:0x%x",
537 EXTRACT_32BITS(&grbn
->flags
));
540 printf(" %s", tok2str(ns_type2str
, "Type%d",
541 EXTRACT_16BITS(&grbn
->rdtype
)));
542 if (EXTRACT_16BITS(&grbn
->rdclass
) != C_IN
) {
543 printf(" %s", tok2str(ns_class2str
, "Class%d",
544 EXTRACT_16BITS(&grbn
->rdclass
)));
547 relts_print(EXTRACT_32BITS(&grbn
->ttl
));
548 printf(" %u/%u", EXTRACT_16BITS(&grbn
->nrdatas
),
549 EXTRACT_16BITS(&grbn
->nsigs
));
551 /* XXX grbn points to packed struct */
552 s
= (const char *)&grbn
->nsigs
+ sizeof(grbn
->nsigs
);
554 advance
= lwres_printnamelen(s
);
560 na
= EXTRACT_16BITS(&grbn
->nrdatas
);
561 for (i
= 0; i
< na
; i
++) {
562 /* XXX should decode resource data */
563 advance
= lwres_printbinlen(s
);
570 na
= EXTRACT_16BITS(&grbn
->nsigs
);
571 for (i
= 0; i
< na
; i
++) {
572 /* XXX how should we print it? */
573 advance
= lwres_printbinlen(s
);
586 /* length mismatch */
587 if (EXTRACT_32BITS(&np
->length
) != length
) {
588 printf(" [len: %u != %u]", EXTRACT_32BITS(&np
->length
),
591 if (!unsupported
&& s
< (const char *)np
+ EXTRACT_32BITS(&np
->length
))