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.4 2001-02-09 05:16:48 guy Exp $ (LBL)";
39 #include <sys/param.h>
42 #include <netinet/in.h>
45 #undef NOERROR /* Solaris sucks */
48 #undef T_UNSPEC /* SINIX does too */
55 #include "interface.h"
56 #include "addrtoname.h"
57 #include "extract.h" /* must come after interface.h */
59 /* BIND9 lib/lwres/include/lwres */
60 typedef u_int32_t lwres_uint32_t
;
61 typedef u_int16_t lwres_uint16_t
;
62 typedef u_int8_t lwres_uint8_t
;
64 struct lwres_lwpacket
{
65 lwres_uint32_t length
;
66 lwres_uint16_t version
;
67 lwres_uint16_t pktflags
;
68 lwres_uint32_t serial
;
69 lwres_uint32_t opcode
;
70 lwres_uint32_t result
;
71 lwres_uint32_t recvlength
;
72 lwres_uint16_t authtype
;
73 lwres_uint16_t authlength
;
76 #define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */
78 #define LWRES_LWPACKETVERSION_0 0
80 #define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U
81 #define LWRES_FLAG_SECUREDATA 0x00000002U
86 #define LWRES_OPCODE_NOOP 0x00000000U
90 lwres_uint16_t datalength
;
92 } lwres_nooprequest_t
;
96 lwres_uint16_t datalength
;
98 } lwres_noopresponse_t
;
101 * get addresses by name
103 #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
105 typedef struct lwres_addr lwres_addr_t
;
108 lwres_uint32_t family
;
109 lwres_uint16_t length
;
115 lwres_uint32_t flags
;
116 lwres_uint32_t addrtypes
;
117 lwres_uint16_t namelen
;
119 } lwres_gabnrequest_t
;
123 lwres_uint32_t flags
;
124 lwres_uint16_t naliases
;
125 lwres_uint16_t naddrs
;
126 lwres_uint16_t realnamelen
;
127 /* aliases follows */
129 /* realname follows */
130 } lwres_gabnresponse_t
;
133 * get name by address
135 #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
138 lwres_uint32_t flags
;
140 /* addr body follows */
141 } lwres_gnbarequest_t
;
145 lwres_uint32_t flags
;
146 lwres_uint16_t naliases
;
147 lwres_uint16_t realnamelen
;
148 /* aliases follows */
149 /* realname follows */
150 } lwres_gnbaresponse_t
;
155 #define LWRES_OPCODE_GETRDATABYNAME 0x00010003U
159 lwres_uint32_t flags
;
160 lwres_uint16_t rdclass
;
161 lwres_uint16_t rdtype
;
162 lwres_uint16_t namelen
;
164 } lwres_grbnrequest_t
;
168 lwres_uint32_t flags
;
169 lwres_uint16_t rdclass
;
170 lwres_uint16_t rdtype
;
172 lwres_uint16_t nrdatas
;
173 lwres_uint16_t nsigs
;
174 /* realname here (len + name) */
175 /* rdata here (len + name) */
176 /* signatures here (len + name) */
177 } lwres_grbnresponse_t
;
179 #define LWRDATA_VALIDATED 0x00000001
181 #define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */
182 #define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */
184 #define LWRES_MAX_ALIASES 16 /* max # of aliases */
185 #define LWRES_MAX_ADDRS 64 /* max # of addrs */
187 struct tok opcode
[] = {
188 { LWRES_OPCODE_NOOP
, "noop", },
189 { LWRES_OPCODE_GETADDRSBYNAME
, "getaddrsbyname", },
190 { LWRES_OPCODE_GETNAMEBYADDR
, "getnamebyaddr", },
191 { LWRES_OPCODE_GETRDATABYNAME
, "getrdatabyname", },
196 extern struct tok ns_type2str
[];
197 extern struct tok ns_class2str
[];
199 static int lwres_printname(size_t, const char *);
200 static int lwres_printnamelen(const char *);
201 static int lwres_printbinlen(const char *);
202 static int lwres_printaddr(lwres_addr_t
*);
205 lwres_printname(size_t l
, const char *p0
)
211 /* + 1 for terminating \0 */
212 if (p
+ l
+ 1 > (const char *)snapend
)
216 for (i
= 0; i
< l
; i
++)
218 p
++; /* skip terminating \0 */
227 lwres_printnamelen(const char *p
)
232 if (p
+ 2 > (const char *)snapend
)
234 l
= EXTRACT_16BITS(p
);
235 advance
= lwres_printname(l
, p
+ 2);
245 lwres_printbinlen(const char *p0
)
252 if (p
+ 2 > (const char *)snapend
)
254 l
= EXTRACT_16BITS(p
);
255 if (p
+ 2 + l
> (const char *)snapend
)
258 for (i
= 0; i
< l
; i
++)
259 printf("%02x", *p
++);
267 lwres_printaddr(lwres_addr_t
*ap
)
274 l
= ntohs(ap
->length
);
275 /* XXX ap points to packed struct */
276 p
= (const char *)&ap
->length
+ sizeof(ap
->length
);
277 if (p
+ l
> (const char *)snapend
)
280 switch (ntohl(ap
->family
)) {
282 printf(" %s", ipaddr_string(p
));
283 p
+= sizeof(struct in_addr
);
287 printf(" %s", ip6addr_string(p
));
288 p
+= sizeof(struct in6_addr
);
292 printf(" %lu/", (unsigned long)ntohl(ap
->family
));
293 for (i
= 0; i
< l
; i
++)
294 printf("%02x", *p
++);
297 return p
- (const char *)ap
;
304 lwres_print(register const u_char
*bp
, u_int length
)
306 const struct lwres_lwpacket
*np
;
313 np
= (const struct lwres_lwpacket
*)bp
;
314 TCHECK(np
->authlength
);
317 v
= ntohs(np
->version
);
318 if (vflag
|| v
!= LWRES_LWPACKETVERSION_0
)
320 if (v
!= LWRES_LWPACKETVERSION_0
) {
321 s
= (const char *)np
+ ntohl(np
->length
);
325 response
= ntohs(np
->pktflags
) & LWRES_LWPACKETFLAG_RESPONSE
;
327 /* opcode and pktflags */
328 v
= (u_int32_t
)ntohl(np
->opcode
);
329 s
= tok2str(opcode
, "#0x%x", v
);
330 printf(" %s%s", s
, response
? "" : "?");
333 v
= ntohs(np
->pktflags
);
334 if (v
& ~LWRES_LWPACKETFLAG_RESPONSE
)
339 printf("serial:0x%lx", (unsigned long)ntohl(np
->serial
));
340 printf(" result:0x%lx", (unsigned long)ntohl(np
->result
));
341 printf(" recvlen:%lu", (unsigned long)ntohl(np
->recvlength
));
342 /* BIND910: not used */
344 printf(" authtype:0x%x", ntohs(np
->authtype
));
345 printf(" authlen:%u", ntohs(np
->authlength
));
351 /* per-opcode content */
356 lwres_gabnrequest_t
*gabn
;
357 lwres_gnbarequest_t
*gnba
;
358 lwres_grbnrequest_t
*grbn
;
365 switch (ntohl(np
->opcode
)) {
366 case LWRES_OPCODE_NOOP
:
368 case LWRES_OPCODE_GETADDRSBYNAME
:
369 gabn
= (lwres_gabnrequest_t
*)(np
+ 1);
370 TCHECK(gabn
->namelen
);
371 /* XXX gabn points to packed struct */
372 s
= (const char *)&gabn
->namelen
+
373 sizeof(gabn
->namelen
);
374 l
= ntohs(gabn
->namelen
);
376 /* BIND910: not used */
378 printf(" flags:0x%lx",
379 (unsigned long)ntohl(gabn
->flags
));
382 v
= (u_int32_t
)ntohl(gabn
->addrtypes
);
383 switch (v
& (LWRES_ADDRTYPE_V4
| LWRES_ADDRTYPE_V6
)) {
384 case LWRES_ADDRTYPE_V4
:
387 case LWRES_ADDRTYPE_V6
:
390 case LWRES_ADDRTYPE_V4
| LWRES_ADDRTYPE_V6
:
394 if (v
& ~(LWRES_ADDRTYPE_V4
| LWRES_ADDRTYPE_V6
))
397 advance
= lwres_printname(l
, s
);
402 case LWRES_OPCODE_GETNAMEBYADDR
:
403 gnba
= (lwres_gnbarequest_t
*)(np
+ 1);
406 /* BIND910: not used */
408 printf(" flags:0x%lx",
409 (unsigned long)ntohl(gnba
->flags
));
412 s
= (const char *)&gnba
->addr
;
414 advance
= lwres_printaddr(&gnba
->addr
);
419 case LWRES_OPCODE_GETRDATABYNAME
:
420 /* XXX no trace, not tested */
421 grbn
= (lwres_grbnrequest_t
*)(np
+ 1);
422 TCHECK(grbn
->namelen
);
424 /* BIND910: not used */
426 printf(" flags:0x%lx",
427 (unsigned long)ntohl(grbn
->flags
));
430 printf(" %s", tok2str(ns_type2str
, "Type%d",
431 ntohs(grbn
->rdtype
)));
432 if (ntohs(grbn
->rdclass
) != C_IN
);
433 printf(" %s", tok2str(ns_class2str
, "Class%d",
434 ntohs(grbn
->rdclass
)));
436 /* XXX grbn points to packed struct */
437 s
= (const char *)&grbn
->namelen
+
438 sizeof(grbn
->namelen
);
439 l
= ntohs(gabn
->namelen
);
441 advance
= lwres_printname(l
, s
);
454 lwres_gabnresponse_t
*gabn
;
455 lwres_gnbaresponse_t
*gnba
;
456 lwres_grbnresponse_t
*grbn
;
464 switch (ntohl(np
->opcode
)) {
465 case LWRES_OPCODE_NOOP
:
467 case LWRES_OPCODE_GETADDRSBYNAME
:
468 gabn
= (lwres_gabnresponse_t
*)(np
+ 1);
469 TCHECK(gabn
->realnamelen
);
470 /* XXX gabn points to packed struct */
471 s
= (const char *)&gabn
->realnamelen
+
472 sizeof(gabn
->realnamelen
);
473 l
= ntohs(gabn
->realnamelen
);
475 /* BIND910: not used */
477 printf(" flags:0x%lx",
478 (unsigned long)ntohl(gabn
->flags
));
481 printf(" %u/%u", ntohs(gabn
->naliases
),
482 ntohs(gabn
->naddrs
));
484 advance
= lwres_printname(l
, s
);
490 na
= ntohs(gabn
->naliases
);
491 for (i
= 0; i
< na
; i
++) {
492 advance
= lwres_printnamelen(s
);
499 na
= ntohs(gabn
->naddrs
);
500 for (i
= 0; i
< na
; i
++) {
501 advance
= lwres_printaddr((lwres_addr_t
*)s
);
507 case LWRES_OPCODE_GETNAMEBYADDR
:
508 gnba
= (lwres_gnbaresponse_t
*)(np
+ 1);
509 TCHECK(gnba
->realnamelen
);
510 /* XXX gnba points to packed struct */
511 s
= (const char *)&gnba
->realnamelen
+
512 sizeof(gnba
->realnamelen
);
513 l
= ntohs(gnba
->realnamelen
);
515 /* BIND910: not used */
517 printf(" flags:0x%lx",
518 (unsigned long)ntohl(gnba
->flags
));
521 printf(" %u", ntohs(gnba
->naliases
));
523 advance
= lwres_printname(l
, s
);
529 na
= ntohs(gnba
->naliases
);
530 for (i
= 0; i
< na
; i
++) {
531 advance
= lwres_printnamelen(s
);
537 case LWRES_OPCODE_GETRDATABYNAME
:
538 /* XXX no trace, not tested */
539 grbn
= (lwres_grbnresponse_t
*)(np
+ 1);
542 /* BIND910: not used */
544 printf(" flags:0x%lx",
545 (unsigned long)ntohl(grbn
->flags
));
548 printf(" %s", tok2str(ns_type2str
, "Type%d",
549 ntohs(grbn
->rdtype
)));
550 if (ntohs(grbn
->rdclass
) != C_IN
);
551 printf(" %s", tok2str(ns_class2str
, "Class%d",
552 ntohs(grbn
->rdclass
)));
554 relts_print(ntohl(grbn
->ttl
));
555 printf(" %u/%u", ntohs(grbn
->nrdatas
),
558 /* XXX grbn points to packed struct */
559 s
= (const char *)&grbn
->nsigs
+ sizeof(grbn
->nsigs
);
561 advance
= lwres_printnamelen(s
);
567 na
= ntohs(grbn
->nrdatas
);
568 for (i
= 0; i
< na
; i
++) {
569 /* XXX should decode resource data */
570 advance
= lwres_printbinlen(s
);
577 na
= ntohs(grbn
->nsigs
);
578 for (i
= 0; i
< na
; i
++) {
579 /* XXX how should we print it? */
580 advance
= lwres_printbinlen(s
);
593 /* length mismatch */
594 if (ntohl(np
->length
) != length
) {
595 printf(" [len: %lu != %u]", (unsigned long)ntohl(np
->length
),
598 if (!unsupported
&& s
< (const char *)np
+ ntohl(np
->length
))