4 * Copyright (C) 2001 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static const char rcsid
[] _U_
=
36 "@(#) Header: /tcpdump/master/tcpdump/print-lwres.c,v 1.13 2004/03/24 01:54:29 guy Exp (LBL)";
38 __RCSID("$NetBSD: tcpdump2rcsid.ex,v 1.1 2001/06/25 20:09:58 itojun Exp $");
46 #include <tcpdump-stdinc.h>
53 #include "interface.h"
54 #include "addrtoname.h"
55 #include "extract.h" /* must come after interface.h */
57 /* BIND9 lib/lwres/include/lwres */
58 typedef u_int32_t lwres_uint32_t
;
59 typedef u_int16_t lwres_uint16_t
;
60 typedef u_int8_t lwres_uint8_t
;
62 struct lwres_lwpacket
{
63 lwres_uint32_t length
;
64 lwres_uint16_t version
;
65 lwres_uint16_t pktflags
;
66 lwres_uint32_t serial
;
67 lwres_uint32_t opcode
;
68 lwres_uint32_t result
;
69 lwres_uint32_t recvlength
;
70 lwres_uint16_t authtype
;
71 lwres_uint16_t authlength
;
74 #define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */
76 #define LWRES_LWPACKETVERSION_0 0
78 #define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U
79 #define LWRES_FLAG_SECUREDATA 0x00000002U
84 #define LWRES_OPCODE_NOOP 0x00000000U
88 lwres_uint16_t datalength
;
90 } lwres_nooprequest_t
;
94 lwres_uint16_t datalength
;
96 } lwres_noopresponse_t
;
99 * get addresses by name
101 #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
103 typedef struct lwres_addr lwres_addr_t
;
106 lwres_uint32_t family
;
107 lwres_uint16_t length
;
113 lwres_uint32_t flags
;
114 lwres_uint32_t addrtypes
;
115 lwres_uint16_t namelen
;
117 } lwres_gabnrequest_t
;
121 lwres_uint32_t flags
;
122 lwres_uint16_t naliases
;
123 lwres_uint16_t naddrs
;
124 lwres_uint16_t realnamelen
;
125 /* aliases follows */
127 /* realname follows */
128 } lwres_gabnresponse_t
;
131 * get name by address
133 #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
136 lwres_uint32_t flags
;
138 /* addr body follows */
139 } lwres_gnbarequest_t
;
143 lwres_uint32_t flags
;
144 lwres_uint16_t naliases
;
145 lwres_uint16_t realnamelen
;
146 /* aliases follows */
147 /* realname follows */
148 } lwres_gnbaresponse_t
;
153 #define LWRES_OPCODE_GETRDATABYNAME 0x00010003U
157 lwres_uint32_t flags
;
158 lwres_uint16_t rdclass
;
159 lwres_uint16_t rdtype
;
160 lwres_uint16_t namelen
;
162 } lwres_grbnrequest_t
;
166 lwres_uint32_t flags
;
167 lwres_uint16_t rdclass
;
168 lwres_uint16_t rdtype
;
170 lwres_uint16_t nrdatas
;
171 lwres_uint16_t nsigs
;
172 /* realname here (len + name) */
173 /* rdata here (len + name) */
174 /* signatures here (len + name) */
175 } lwres_grbnresponse_t
;
177 #define LWRDATA_VALIDATED 0x00000001
179 #define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */
180 #define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */
182 #define LWRES_MAX_ALIASES 16 /* max # of aliases */
183 #define LWRES_MAX_ADDRS 64 /* max # of addrs */
185 struct tok opcode
[] = {
186 { LWRES_OPCODE_NOOP
, "noop", },
187 { LWRES_OPCODE_GETADDRSBYNAME
, "getaddrsbyname", },
188 { LWRES_OPCODE_GETNAMEBYADDR
, "getnamebyaddr", },
189 { LWRES_OPCODE_GETRDATABYNAME
, "getrdatabyname", },
194 extern struct tok ns_type2str
[];
195 extern struct tok ns_class2str
[];
197 static int lwres_printname(size_t, const char *);
198 static int lwres_printnamelen(const char *);
199 static int lwres_printbinlen(const char *);
200 static int lwres_printaddr(lwres_addr_t
*);
203 lwres_printname(size_t l
, const char *p0
)
209 /* + 1 for terminating \0 */
210 if (p
+ l
+ 1 > (const char *)snapend
)
214 for (i
= 0; i
< l
; i
++)
216 p
++; /* skip terminating \0 */
225 lwres_printnamelen(const char *p
)
230 if (p
+ 2 > (const char *)snapend
)
232 l
= EXTRACT_16BITS(p
);
233 advance
= lwres_printname(l
, p
+ 2);
243 lwres_printbinlen(const char *p0
)
250 if (p
+ 2 > (const char *)snapend
)
252 l
= EXTRACT_16BITS(p
);
253 if (p
+ 2 + l
> (const char *)snapend
)
256 for (i
= 0; i
< l
; i
++)
257 printf("%02x", *p
++);
265 lwres_printaddr(lwres_addr_t
*ap
)
272 l
= EXTRACT_16BITS(&ap
->length
);
273 /* XXX ap points to packed struct */
274 p
= (const char *)&ap
->length
+ sizeof(ap
->length
);
277 switch (EXTRACT_32BITS(&ap
->family
)) {
281 printf(" %s", ipaddr_string(p
));
282 p
+= sizeof(struct in_addr
);
288 printf(" %s", ip6addr_string(p
));
289 p
+= sizeof(struct in6_addr
);
293 printf(" %u/", EXTRACT_32BITS(&ap
->family
));
294 for (i
= 0; i
< l
; i
++)
295 printf("%02x", *p
++);
298 return p
- (const char *)ap
;
305 lwres_print(register const u_char
*bp
, u_int length
)
307 const struct lwres_lwpacket
*np
;
314 np
= (const struct lwres_lwpacket
*)bp
;
315 TCHECK(np
->authlength
);
318 v
= EXTRACT_16BITS(&np
->version
);
319 if (vflag
|| v
!= LWRES_LWPACKETVERSION_0
)
321 if (v
!= LWRES_LWPACKETVERSION_0
) {
322 s
= (const char *)np
+ EXTRACT_32BITS(&np
->length
);
326 response
= EXTRACT_16BITS(&np
->pktflags
) & LWRES_LWPACKETFLAG_RESPONSE
;
328 /* opcode and pktflags */
329 v
= EXTRACT_32BITS(&np
->opcode
);
330 s
= tok2str(opcode
, "#0x%x", v
);
331 printf(" %s%s", s
, response
? "" : "?");
334 v
= EXTRACT_16BITS(&np
->pktflags
);
335 if (v
& ~LWRES_LWPACKETFLAG_RESPONSE
)
340 printf("serial:0x%x", EXTRACT_32BITS(&np
->serial
));
341 printf(" result:0x%x", EXTRACT_32BITS(&np
->result
));
342 printf(" recvlen:%u", EXTRACT_32BITS(&np
->recvlength
));
343 /* BIND910: not used */
345 printf(" authtype:0x%x", EXTRACT_16BITS(&np
->authtype
));
346 printf(" authlen:%u", EXTRACT_16BITS(&np
->authlength
));
352 /* per-opcode content */
357 lwres_gabnrequest_t
*gabn
;
358 lwres_gnbarequest_t
*gnba
;
359 lwres_grbnrequest_t
*grbn
;
366 switch (EXTRACT_32BITS(&np
->opcode
)) {
367 case LWRES_OPCODE_NOOP
:
369 case LWRES_OPCODE_GETADDRSBYNAME
:
370 gabn
= (lwres_gabnrequest_t
*)(np
+ 1);
371 TCHECK(gabn
->namelen
);
372 /* XXX gabn points to packed struct */
373 s
= (const char *)&gabn
->namelen
+
374 sizeof(gabn
->namelen
);
375 l
= EXTRACT_16BITS(&gabn
->namelen
);
377 /* BIND910: not used */
379 printf(" flags:0x%x",
380 EXTRACT_32BITS(&gabn
->flags
));
383 v
= EXTRACT_32BITS(&gabn
->addrtypes
);
384 switch (v
& (LWRES_ADDRTYPE_V4
| LWRES_ADDRTYPE_V6
)) {
385 case LWRES_ADDRTYPE_V4
:
388 case LWRES_ADDRTYPE_V6
:
391 case LWRES_ADDRTYPE_V4
| LWRES_ADDRTYPE_V6
:
395 if (v
& ~(LWRES_ADDRTYPE_V4
| LWRES_ADDRTYPE_V6
))
398 advance
= lwres_printname(l
, s
);
403 case LWRES_OPCODE_GETNAMEBYADDR
:
404 gnba
= (lwres_gnbarequest_t
*)(np
+ 1);
407 /* BIND910: not used */
409 printf(" flags:0x%x",
410 EXTRACT_32BITS(&gnba
->flags
));
413 s
= (const char *)&gnba
->addr
;
415 advance
= lwres_printaddr(&gnba
->addr
);
420 case LWRES_OPCODE_GETRDATABYNAME
:
421 /* XXX no trace, not tested */
422 grbn
= (lwres_grbnrequest_t
*)(np
+ 1);
423 TCHECK(grbn
->namelen
);
425 /* BIND910: not used */
427 printf(" flags:0x%x",
428 EXTRACT_32BITS(&grbn
->flags
));
431 printf(" %s", tok2str(ns_type2str
, "Type%d",
432 EXTRACT_16BITS(&grbn
->rdtype
)));
433 if (EXTRACT_16BITS(&grbn
->rdclass
) != C_IN
) {
434 printf(" %s", tok2str(ns_class2str
, "Class%d",
435 EXTRACT_16BITS(&grbn
->rdclass
)));
438 /* XXX grbn points to packed struct */
439 s
= (const char *)&grbn
->namelen
+
440 sizeof(grbn
->namelen
);
441 l
= EXTRACT_16BITS(&grbn
->namelen
);
443 advance
= lwres_printname(l
, s
);
456 lwres_gabnresponse_t
*gabn
;
457 lwres_gnbaresponse_t
*gnba
;
458 lwres_grbnresponse_t
*grbn
;
466 switch (EXTRACT_32BITS(&np
->opcode
)) {
467 case LWRES_OPCODE_NOOP
:
469 case LWRES_OPCODE_GETADDRSBYNAME
:
470 gabn
= (lwres_gabnresponse_t
*)(np
+ 1);
471 TCHECK(gabn
->realnamelen
);
472 /* XXX gabn points to packed struct */
473 s
= (const char *)&gabn
->realnamelen
+
474 sizeof(gabn
->realnamelen
);
475 l
= EXTRACT_16BITS(&gabn
->realnamelen
);
477 /* BIND910: not used */
479 printf(" flags:0x%x",
480 EXTRACT_32BITS(&gabn
->flags
));
483 printf(" %u/%u", EXTRACT_16BITS(&gabn
->naliases
),
484 EXTRACT_16BITS(&gabn
->naddrs
));
486 advance
= lwres_printname(l
, s
);
492 na
= EXTRACT_16BITS(&gabn
->naliases
);
493 for (i
= 0; i
< na
; i
++) {
494 advance
= lwres_printnamelen(s
);
501 na
= EXTRACT_16BITS(&gabn
->naddrs
);
502 for (i
= 0; i
< na
; i
++) {
503 advance
= lwres_printaddr((lwres_addr_t
*)s
);
509 case LWRES_OPCODE_GETNAMEBYADDR
:
510 gnba
= (lwres_gnbaresponse_t
*)(np
+ 1);
511 TCHECK(gnba
->realnamelen
);
512 /* XXX gnba points to packed struct */
513 s
= (const char *)&gnba
->realnamelen
+
514 sizeof(gnba
->realnamelen
);
515 l
= EXTRACT_16BITS(&gnba
->realnamelen
);
517 /* BIND910: not used */
519 printf(" flags:0x%x",
520 EXTRACT_32BITS(&gnba
->flags
));
523 printf(" %u", EXTRACT_16BITS(&gnba
->naliases
));
525 advance
= lwres_printname(l
, s
);
531 na
= EXTRACT_16BITS(&gnba
->naliases
);
532 for (i
= 0; i
< na
; i
++) {
533 advance
= lwres_printnamelen(s
);
539 case LWRES_OPCODE_GETRDATABYNAME
:
540 /* XXX no trace, not tested */
541 grbn
= (lwres_grbnresponse_t
*)(np
+ 1);
544 /* BIND910: not used */
546 printf(" flags:0x%x",
547 EXTRACT_32BITS(&grbn
->flags
));
550 printf(" %s", tok2str(ns_type2str
, "Type%d",
551 EXTRACT_16BITS(&grbn
->rdtype
)));
552 if (EXTRACT_16BITS(&grbn
->rdclass
) != C_IN
) {
553 printf(" %s", tok2str(ns_class2str
, "Class%d",
554 EXTRACT_16BITS(&grbn
->rdclass
)));
557 relts_print(EXTRACT_32BITS(&grbn
->ttl
));
558 printf(" %u/%u", EXTRACT_16BITS(&grbn
->nrdatas
),
559 EXTRACT_16BITS(&grbn
->nsigs
));
561 /* XXX grbn points to packed struct */
562 s
= (const char *)&grbn
->nsigs
+ sizeof(grbn
->nsigs
);
564 advance
= lwres_printnamelen(s
);
570 na
= EXTRACT_16BITS(&grbn
->nrdatas
);
571 for (i
= 0; i
< na
; i
++) {
572 /* XXX should decode resource data */
573 advance
= lwres_printbinlen(s
);
580 na
= EXTRACT_16BITS(&grbn
->nsigs
);
581 for (i
= 0; i
< na
; i
++) {
582 /* XXX how should we print it? */
583 advance
= lwres_printbinlen(s
);
596 /* length mismatch */
597 if (EXTRACT_32BITS(&np
->length
) != length
) {
598 printf(" [len: %u != %u]", EXTRACT_32BITS(&np
->length
),
601 if (!unsupported
&& s
< (const char *)np
+ EXTRACT_32BITS(&np
->length
))