Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / tcpdump / print-lwres.c
blobbb6064d76d4490c1711b9f06fd0d184d201b9580
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2001 WIDE Project.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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
29 * SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
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)";
37 #else
38 __RCSID("$NetBSD: tcpdump2rcsid.ex,v 1.1 2001/06/25 20:09:58 itojun Exp $");
39 #endif
40 #endif
42 #ifdef HAVE_CONFIG_H
43 #include "config.h"
44 #endif
46 #include <tcpdump-stdinc.h>
48 #include "nameser.h"
50 #include <stdio.h>
51 #include <string.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
82 * no-op
84 #define LWRES_OPCODE_NOOP 0x00000000U
86 typedef struct {
87 /* public */
88 lwres_uint16_t datalength;
89 /* data follows */
90 } lwres_nooprequest_t;
92 typedef struct {
93 /* public */
94 lwres_uint16_t datalength;
95 /* data follows */
96 } lwres_noopresponse_t;
99 * get addresses by name
101 #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
103 typedef struct lwres_addr lwres_addr_t;
105 struct lwres_addr {
106 lwres_uint32_t family;
107 lwres_uint16_t length;
108 /* address folows */
111 typedef struct {
112 /* public */
113 lwres_uint32_t flags;
114 lwres_uint32_t addrtypes;
115 lwres_uint16_t namelen;
116 /* name follows */
117 } lwres_gabnrequest_t;
119 typedef struct {
120 /* public */
121 lwres_uint32_t flags;
122 lwres_uint16_t naliases;
123 lwres_uint16_t naddrs;
124 lwres_uint16_t realnamelen;
125 /* aliases follows */
126 /* addrs follows */
127 /* realname follows */
128 } lwres_gabnresponse_t;
131 * get name by address
133 #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
134 typedef struct {
135 /* public */
136 lwres_uint32_t flags;
137 lwres_addr_t addr;
138 /* addr body follows */
139 } lwres_gnbarequest_t;
141 typedef struct {
142 /* public */
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;
151 * get rdata by name
153 #define LWRES_OPCODE_GETRDATABYNAME 0x00010003U
155 typedef struct {
156 /* public */
157 lwres_uint32_t flags;
158 lwres_uint16_t rdclass;
159 lwres_uint16_t rdtype;
160 lwres_uint16_t namelen;
161 /* name follows */
162 } lwres_grbnrequest_t;
164 typedef struct {
165 /* public */
166 lwres_uint32_t flags;
167 lwres_uint16_t rdclass;
168 lwres_uint16_t rdtype;
169 lwres_uint32_t ttl;
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", },
190 { 0, NULL, },
193 /* print-domain.c */
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 *);
202 static int
203 lwres_printname(size_t l, const char *p0)
205 const char *p;
206 size_t i;
208 p = p0;
209 /* + 1 for terminating \0 */
210 if (p + l + 1 > (const char *)snapend)
211 goto trunc;
213 printf(" ");
214 for (i = 0; i < l; i++)
215 safeputchar(*p++);
216 p++; /* skip terminating \0 */
218 return p - p0;
220 trunc:
221 return -1;
224 static int
225 lwres_printnamelen(const char *p)
227 u_int16_t l;
228 int advance;
230 if (p + 2 > (const char *)snapend)
231 goto trunc;
232 l = EXTRACT_16BITS(p);
233 advance = lwres_printname(l, p + 2);
234 if (advance < 0)
235 goto trunc;
236 return 2 + advance;
238 trunc:
239 return -1;
242 static int
243 lwres_printbinlen(const char *p0)
245 const char *p;
246 u_int16_t l;
247 int i;
249 p = p0;
250 if (p + 2 > (const char *)snapend)
251 goto trunc;
252 l = EXTRACT_16BITS(p);
253 if (p + 2 + l > (const char *)snapend)
254 goto trunc;
255 p += 2;
256 for (i = 0; i < l; i++)
257 printf("%02x", *p++);
258 return p - p0;
260 trunc:
261 return -1;
264 static int
265 lwres_printaddr(lwres_addr_t *ap)
267 u_int16_t l;
268 const char *p;
269 int i;
271 TCHECK(ap->length);
272 l = EXTRACT_16BITS(&ap->length);
273 /* XXX ap points to packed struct */
274 p = (const char *)&ap->length + sizeof(ap->length);
275 TCHECK2(*p, l);
277 switch (EXTRACT_32BITS(&ap->family)) {
278 case 1: /* IPv4 */
279 if (l < 4)
280 return -1;
281 printf(" %s", ipaddr_string(p));
282 p += sizeof(struct in_addr);
283 break;
284 #ifdef INET6
285 case 2: /* IPv6 */
286 if (l < 16)
287 return -1;
288 printf(" %s", ip6addr_string(p));
289 p += sizeof(struct in6_addr);
290 break;
291 #endif
292 default:
293 printf(" %u/", EXTRACT_32BITS(&ap->family));
294 for (i = 0; i < l; i++)
295 printf("%02x", *p++);
298 return p - (const char *)ap;
300 trunc:
301 return -1;
304 void
305 lwres_print(register const u_char *bp, u_int length)
307 const struct lwres_lwpacket *np;
308 u_int32_t v;
309 const char *s;
310 int response;
311 int advance;
312 int unsupported = 0;
314 np = (const struct lwres_lwpacket *)bp;
315 TCHECK(np->authlength);
317 printf(" lwres");
318 v = EXTRACT_16BITS(&np->version);
319 if (vflag || v != LWRES_LWPACKETVERSION_0)
320 printf(" v%u", v);
321 if (v != LWRES_LWPACKETVERSION_0) {
322 s = (const char *)np + EXTRACT_32BITS(&np->length);
323 goto tail;
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 ? "" : "?");
333 /* pktflags */
334 v = EXTRACT_16BITS(&np->pktflags);
335 if (v & ~LWRES_LWPACKETFLAG_RESPONSE)
336 printf("[0x%x]", v);
338 if (vflag > 1) {
339 printf(" ("); /*)*/
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 */
344 if (vflag > 2) {
345 printf(" authtype:0x%x", EXTRACT_16BITS(&np->authtype));
346 printf(" authlen:%u", EXTRACT_16BITS(&np->authlength));
348 /*(*/
349 printf(")");
352 /* per-opcode content */
353 if (!response) {
355 * queries
357 lwres_gabnrequest_t *gabn;
358 lwres_gnbarequest_t *gnba;
359 lwres_grbnrequest_t *grbn;
360 u_int32_t l;
362 gabn = NULL;
363 gnba = NULL;
364 grbn = NULL;
366 switch (EXTRACT_32BITS(&np->opcode)) {
367 case LWRES_OPCODE_NOOP:
368 break;
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 */
378 if (vflag > 2) {
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:
386 printf(" IPv4");
387 break;
388 case LWRES_ADDRTYPE_V6:
389 printf(" IPv6");
390 break;
391 case LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6:
392 printf(" IPv4/6");
393 break;
395 if (v & ~(LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6))
396 printf("[0x%x]", v);
398 advance = lwres_printname(l, s);
399 if (advance < 0)
400 goto trunc;
401 s += advance;
402 break;
403 case LWRES_OPCODE_GETNAMEBYADDR:
404 gnba = (lwres_gnbarequest_t *)(np + 1);
405 TCHECK(gnba->addr);
407 /* BIND910: not used */
408 if (vflag > 2) {
409 printf(" flags:0x%x",
410 EXTRACT_32BITS(&gnba->flags));
413 s = (const char *)&gnba->addr;
415 advance = lwres_printaddr(&gnba->addr);
416 if (advance < 0)
417 goto trunc;
418 s += advance;
419 break;
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 */
426 if (vflag > 2) {
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);
444 if (advance < 0)
445 goto trunc;
446 s += advance;
447 break;
448 default:
449 unsupported++;
450 break;
452 } else {
454 * responses
456 lwres_gabnresponse_t *gabn;
457 lwres_gnbaresponse_t *gnba;
458 lwres_grbnresponse_t *grbn;
459 u_int32_t l, na;
460 u_int32_t i;
462 gabn = NULL;
463 gnba = NULL;
464 grbn = NULL;
466 switch (EXTRACT_32BITS(&np->opcode)) {
467 case LWRES_OPCODE_NOOP:
468 break;
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 */
478 if (vflag > 2) {
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);
487 if (advance < 0)
488 goto trunc;
489 s += advance;
491 /* aliases */
492 na = EXTRACT_16BITS(&gabn->naliases);
493 for (i = 0; i < na; i++) {
494 advance = lwres_printnamelen(s);
495 if (advance < 0)
496 goto trunc;
497 s += advance;
500 /* addrs */
501 na = EXTRACT_16BITS(&gabn->naddrs);
502 for (i = 0; i < na; i++) {
503 advance = lwres_printaddr((lwres_addr_t *)s);
504 if (advance < 0)
505 goto trunc;
506 s += advance;
508 break;
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 */
518 if (vflag > 2) {
519 printf(" flags:0x%x",
520 EXTRACT_32BITS(&gnba->flags));
523 printf(" %u", EXTRACT_16BITS(&gnba->naliases));
525 advance = lwres_printname(l, s);
526 if (advance < 0)
527 goto trunc;
528 s += advance;
530 /* aliases */
531 na = EXTRACT_16BITS(&gnba->naliases);
532 for (i = 0; i < na; i++) {
533 advance = lwres_printnamelen(s);
534 if (advance < 0)
535 goto trunc;
536 s += advance;
538 break;
539 case LWRES_OPCODE_GETRDATABYNAME:
540 /* XXX no trace, not tested */
541 grbn = (lwres_grbnresponse_t *)(np + 1);
542 TCHECK(grbn->nsigs);
544 /* BIND910: not used */
545 if (vflag > 2) {
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)));
556 printf(" TTL ");
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);
565 if (advance < 0)
566 goto trunc;
567 s += advance;
569 /* rdatas */
570 na = EXTRACT_16BITS(&grbn->nrdatas);
571 for (i = 0; i < na; i++) {
572 /* XXX should decode resource data */
573 advance = lwres_printbinlen(s);
574 if (advance < 0)
575 goto trunc;
576 s += advance;
579 /* sigs */
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);
584 if (advance < 0)
585 goto trunc;
586 s += advance;
588 break;
589 default:
590 unsupported++;
591 break;
595 tail:
596 /* length mismatch */
597 if (EXTRACT_32BITS(&np->length) != length) {
598 printf(" [len: %u != %u]", EXTRACT_32BITS(&np->length),
599 length);
601 if (!unsupported && s < (const char *)np + EXTRACT_32BITS(&np->length))
602 printf("[extra]");
603 return;
605 trunc:
606 printf("[|lwres]");
607 return;