print-domain.c revision 26183
117680Spst/*
217680Spst * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
317680Spst *	The Regents of the University of California.  All rights reserved.
417680Spst *
517680Spst * Redistribution and use in source and binary forms, with or without
617680Spst * modification, are permitted provided that: (1) source code distributions
717680Spst * retain the above copyright notice and this paragraph in its entirety, (2)
817680Spst * distributions including binary code include the above copyright notice and
917680Spst * this paragraph in its entirety in the documentation or other materials
1017680Spst * provided with the distribution, and (3) all advertising materials mentioning
1117680Spst * features or use of this software display the following acknowledgement:
1217680Spst * ``This product includes software developed by the University of California,
1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1417680Spst * the University nor the names of its contributors may be used to endorse
1517680Spst * or promote products derived from this software without specific prior
1617680Spst * written permission.
1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2017680Spst */
2117680Spst
2217680Spst#ifndef lint
2326183Sfennerstatic const char rcsid[] =
2426183Sfenner    "@(#) $Header: print-domain.c,v 1.37 96/12/10 23:21:06 leres Exp $ (LBL)";
2517680Spst#endif
2617680Spst
2717680Spst#include <sys/param.h>
2817680Spst#include <sys/time.h>
2917680Spst#include <sys/socket.h>
3017680Spst
3117680Spst#if __STDC__
3217680Spststruct mbuf;
3317680Spststruct rtentry;
3417680Spst#endif
3517680Spst#include <net/if.h>
3617680Spst
3717680Spst#include <netinet/in.h>
3821262Swollman#include <net/ethernet.h>
3917680Spst#include <netinet/in_systm.h>
4017680Spst#include <netinet/ip.h>
4117680Spst#include <netinet/ip_var.h>
4217680Spst#include <netinet/udp.h>
4317680Spst#include <netinet/udp_var.h>
4417680Spst#include <netinet/tcp.h>
4517680Spst#include <netinet/tcpip.h>
4617680Spst
4717680Spst#undef NOERROR					/* Solaris sucks */
4817680Spst#undef T_UNSPEC					/* SINIX does too */
4917680Spst#include <arpa/nameser.h>
5017680Spst
5117680Spst#include <stdio.h>
5217680Spst
5317680Spst#include "interface.h"
5417680Spst#include "addrtoname.h"
5517680Spst#include "extract.h"                    /* must come after interface.h */
5617680Spst
5717680Spst/* Compatibility */
5817680Spst#ifndef T_TXT
5917680Spst#define T_TXT		16		/* text strings */
6017680Spst#endif
6117680Spst#ifndef T_RP
6217680Spst#define T_RP		17		/* responsible person */
6317680Spst#endif
6417680Spst#ifndef T_AFSDB
6517680Spst#define T_AFSDB		18		/* AFS cell database */
6617680Spst#endif
6717680Spst#ifndef T_X25
6817680Spst#define T_X25		19		/* X_25 calling address */
6917680Spst#endif
7017680Spst#ifndef T_ISDN
7117680Spst#define T_ISDN		20		/* ISDN calling address */
7217680Spst#endif
7317680Spst#ifndef T_RT
7417680Spst#define T_RT		21		/* router */
7517680Spst#endif
7617680Spst#ifndef T_NSAP
7717680Spst#define T_NSAP		22		/* NSAP address */
7817680Spst#endif
7917680Spst#ifndef T_NSAP_PTR
8017680Spst#define T_NSAP_PTR	23		/* reverse NSAP lookup (deprecated) */
8117680Spst#endif
8217680Spst#ifndef T_SIG
8317680Spst#define T_SIG		24		/* security signature */
8417680Spst#endif
8517680Spst#ifndef T_KEY
8617680Spst#define T_KEY		25		/* security key */
8717680Spst#endif
8817680Spst#ifndef T_PX
8917680Spst#define T_PX		26		/* X.400 mail mapping */
9017680Spst#endif
9117680Spst#ifndef T_GPOS
9217680Spst#define T_GPOS		27		/* geographical position (withdrawn) */
9317680Spst#endif
9417680Spst#ifndef T_AAAA
9517680Spst#define T_AAAA		28		/* IP6 Address */
9617680Spst#endif
9717680Spst#ifndef T_LOC
9817680Spst#define T_LOC		29		/* Location Information */
9917680Spst#endif
10017680Spst
10117680Spst#ifndef T_UNSPEC
10217680Spst#define T_UNSPEC	103		/* Unspecified format (binary data) */
10317680Spst#endif
10417680Spst#ifndef T_UNSPECA
10517680Spst#define T_UNSPECA	104		/* "unspecified ascii". Ugly MIT hack */
10617680Spst#endif
10717680Spst
10817680Spst#ifndef C_CHAOS
10917680Spst#define C_CHAOS		3		/* for chaos net (MIT) */
11017680Spst#endif
11117680Spst#ifndef C_HS
11217680Spst#define C_HS		4		/* for Hesiod name server (MIT) (XXX) */
11317680Spst#endif
11417680Spst
11517680Spststatic char *ns_ops[] = {
11617680Spst	"", " inv_q", " stat", " op3", " notify", " op5", " op6", " op7",
11717680Spst	" op8", " updataA", " updateD", " updateDA",
11817680Spst	" updateM", " updateMA", " zoneInit", " zoneRef",
11917680Spst};
12017680Spst
12117680Spststatic char *ns_resp[] = {
12217680Spst	"", " FormErr", " ServFail", " NXDomain",
12317680Spst	" NotImp", " Refused", " Resp6", " Resp7",
12417680Spst	" Resp8", " Resp9", " Resp10", " Resp11",
12517680Spst	" Resp12", " Resp13", " Resp14", " NoChange",
12617680Spst};
12717680Spst
12817680Spst/* skip over a domain name */
12917680Spststatic const u_char *
13017680Spstns_nskip(register const u_char *cp, register const u_char *bp)
13117680Spst{
13217680Spst	register u_char i;
13317680Spst
13417680Spst	if (((i = *cp++) & INDIR_MASK) == INDIR_MASK)
13517680Spst		return (cp + 1);
13617680Spst	while (i && cp < snapend) {
13717680Spst		cp += i;
13817680Spst		i = *cp++;
13917680Spst	}
14017680Spst	return (cp);
14117680Spst}
14217680Spst
14317680Spst/* print a <domain-name> */
14417680Spststatic const u_char *
14517680Spstns_nprint(register const u_char *cp, register const u_char *bp)
14617680Spst{
14717680Spst	register u_int i;
14817680Spst	register const u_char *rp;
14917680Spst	register int compress;
15017680Spst
15117680Spst	i = *cp++;
15217680Spst	rp = cp + i;
15317680Spst	if ((i & INDIR_MASK) == INDIR_MASK) {
15417680Spst		rp = cp + 1;
15517680Spst		compress = 1;
15617680Spst	} else
15717680Spst		compress = 0;
15817680Spst	if (i != 0)
15917680Spst		while (i && cp < snapend) {
16017680Spst			if ((i & INDIR_MASK) == INDIR_MASK) {
16117680Spst				cp = bp + (((i << 8) | *cp) & 0x3fff);
16217680Spst				i = *cp++;
16317680Spst				continue;
16417680Spst			}
16517680Spst			if (fn_printn(cp, i, snapend))
16617680Spst				break;
16717680Spst			cp += i;
16817680Spst			putchar('.');
16917680Spst			i = *cp++;
17017680Spst			if (!compress)
17117680Spst				rp += i + 1;
17217680Spst		}
17317680Spst	else
17417680Spst		putchar('.');
17517680Spst	return (rp);
17617680Spst}
17717680Spst
17817680Spst/* print a <character-string> */
17917680Spststatic const u_char *
18017680Spstns_cprint(register const u_char *cp, register const u_char *bp)
18117680Spst{
18217680Spst	register u_int i;
18317680Spst
18417680Spst	i = *cp++;
18517680Spst	(void)fn_printn(cp, i, snapend);
18617680Spst	return (cp + i);
18717680Spst}
18817680Spst
18917680Spststatic struct tok type2str[] = {
19017680Spst	{ T_A,		"A" },
19117680Spst	{ T_NS,		"NS" },
19217680Spst	{ T_MD,		"MD" },
19317680Spst	{ T_MF,		"MF" },
19417680Spst	{ T_CNAME,	"CNAME" },
19517680Spst	{ T_SOA,	"SOA" },
19617680Spst	{ T_MB,		"MB" },
19717680Spst	{ T_MG,		"MG" },
19817680Spst	{ T_MR,		"MR" },
19917680Spst	{ T_NULL,	"NULL" },
20017680Spst	{ T_WKS,	"WKS" },
20117680Spst	{ T_PTR,	"PTR" },
20217680Spst	{ T_HINFO,	"HINFO" },
20317680Spst	{ T_MINFO,	"MINFO" },
20417680Spst	{ T_MX,		"MX" },
20517680Spst	{ T_TXT,	"TXT" },
20617680Spst	{ T_RP,		"RP" },
20717680Spst	{ T_AFSDB,	"AFSDB" },
20817680Spst	{ T_X25,	"X25" },
20917680Spst	{ T_ISDN,	"ISDN" },
21017680Spst	{ T_RT,		"RT" },
21117680Spst	{ T_NSAP,	"NSAP" },
21217680Spst	{ T_NSAP_PTR,	"NSAP_PTR" },
21317680Spst	{ T_SIG,	"SIG" },
21417680Spst	{ T_KEY,	"KEY" },
21517680Spst	{ T_PX,		"PX" },
21617680Spst	{ T_GPOS,	"GPOS" },
21717680Spst	{ T_AAAA,	"AAAA" },
21817680Spst	{ T_LOC ,	"LOC " },
21917680Spst	{ T_UINFO,	"UINFO" },
22017680Spst	{ T_UID,	"UID" },
22117680Spst	{ T_GID,	"GID" },
22217680Spst	{ T_UNSPEC,	"UNSPEC" },
22317680Spst	{ T_UNSPECA,	"UNSPECA" },
22417680Spst	{ T_AXFR,	"AXFR" },
22517680Spst	{ T_MAILB,	"MAILB" },
22617680Spst	{ T_MAILA,	"MAILA" },
22717680Spst	{ T_ANY,	"ANY" },
22817680Spst	{ 0,		NULL }
22917680Spst};
23017680Spst
23117680Spststatic struct tok class2str[] = {
23217680Spst	{ C_IN,		"IN" },		/* Not used */
23317680Spst	{ C_CHAOS,	"CHAOS)" },
23417680Spst	{ C_HS,		"HS" },
23517680Spst	{ C_ANY,	"ANY" },
23617680Spst	{ 0,		NULL }
23717680Spst};
23817680Spst
23917680Spst/* print a query */
24017680Spststatic void
24117680Spstns_qprint(register const u_char *cp, register const u_char *bp)
24217680Spst{
24317680Spst	register const u_char *np = cp;
24417680Spst	register u_int i;
24517680Spst
24617680Spst	cp = ns_nskip(cp, bp);
24717680Spst
24817680Spst	if (cp + 4 > snapend)
24917680Spst		return;
25017680Spst
25117680Spst	/* print the qtype and qclass (if it's not IN) */
25217680Spst	i = *cp++ << 8;
25317680Spst	i |= *cp++;
25417680Spst	printf(" %s", tok2str(type2str, "Type%d", i));
25517680Spst	i = *cp++ << 8;
25617680Spst	i |= *cp++;
25717680Spst	if (i != C_IN)
25817680Spst		printf(" %s", tok2str(class2str, "(Class %d)", i));
25917680Spst
26017680Spst	fputs("? ", stdout);
26117680Spst	ns_nprint(np, bp);
26217680Spst}
26317680Spst
26417680Spst/* print a reply */
26517680Spststatic const u_char *
26617680Spstns_rprint(register const u_char *cp, register const u_char *bp)
26717680Spst{
26817680Spst	register u_int i;
26917680Spst	register u_short typ, len;
27017680Spst	register const u_char *rp;
27117680Spst
27217680Spst	if (vflag) {
27317680Spst		putchar(' ');
27417680Spst		cp = ns_nprint(cp, bp);
27517680Spst	} else
27617680Spst		cp = ns_nskip(cp, bp);
27717680Spst
27817680Spst	if (cp + 10 > snapend)
27917680Spst		return (snapend);
28017680Spst
28117680Spst	/* print the type/qtype and class (if it's not IN) */
28217680Spst	typ = *cp++ << 8;
28317680Spst	typ |= *cp++;
28417680Spst	i = *cp++ << 8;
28517680Spst	i |= *cp++;
28617680Spst	if (i != C_IN)
28717680Spst		printf(" %s", tok2str(class2str, "(Class %d)", i));
28817680Spst
28917680Spst	/* ignore ttl */
29017680Spst	cp += 4;
29117680Spst
29217680Spst	len = *cp++ << 8;
29317680Spst	len |= *cp++;
29417680Spst
29517680Spst	rp = cp + len;
29617680Spst
29717680Spst	printf(" %s", tok2str(type2str, "Type%d", typ));
29817680Spst	switch (typ) {
29917680Spst
30017680Spst	case T_A:
30117680Spst		printf(" %s", ipaddr_string(cp));
30217680Spst		break;
30317680Spst
30417680Spst	case T_NS:
30517680Spst	case T_CNAME:
30617680Spst	case T_PTR:
30717680Spst		putchar(' ');
30817680Spst		(void)ns_nprint(cp, bp);
30917680Spst		break;
31017680Spst
31117680Spst	case T_MX:
31217680Spst		putchar(' ');
31317680Spst		(void)ns_nprint(cp + 2, bp);
31417680Spst		printf(" %d", EXTRACT_16BITS(cp));
31517680Spst		break;
31617680Spst
31717680Spst	case T_TXT:
31817680Spst		putchar(' ');
31917680Spst		(void)ns_cprint(cp, bp);
32017680Spst		break;
32117680Spst
32217680Spst	case T_UNSPECA:		/* One long string */
32317680Spst	        printf(" %.*s", len, cp);
32417680Spst		break;
32517680Spst	}
32626183Sfenner	return (rp);		/* XXX This isn't always right */
32717680Spst}
32817680Spst
32917680Spstvoid
33017680Spstns_print(register const u_char *bp, u_int length)
33117680Spst{
33217680Spst	register const HEADER *np;
33317680Spst	register int qdcount, ancount, nscount, arcount;
33417680Spst	register const u_char *cp;
33517680Spst
33617680Spst	np = (const HEADER *)bp;
33717680Spst	/* get the byte-order right */
33817680Spst	qdcount = ntohs(np->qdcount);
33917680Spst	ancount = ntohs(np->ancount);
34017680Spst	nscount = ntohs(np->nscount);
34117680Spst	arcount = ntohs(np->arcount);
34217680Spst
34317680Spst	if (np->qr) {
34417680Spst		/* this is a response */
34517680Spst		printf(" %d%s%s%s%s%s",
34617680Spst			ntohs(np->id),
34717680Spst			ns_ops[np->opcode],
34817680Spst			ns_resp[np->rcode],
34917680Spst			np->aa? "*" : "",
35017680Spst			np->ra? "" : "-",
35117680Spst			np->tc? "|" : "");
35217680Spst		if (qdcount != 1)
35317680Spst			printf(" [%dq]", qdcount);
35417680Spst		/* Print QUESTION section on -vv */
35517680Spst		if (vflag > 1) {
35617680Spst		            fputs(" q: ", stdout);
35717680Spst			    cp = ns_nprint((const u_char *)(np + 1), bp);
35817680Spst		} else
35917680Spst			    cp = ns_nskip((const u_char *)(np + 1), bp);
36017680Spst		printf(" %d/%d/%d", ancount, nscount, arcount);
36117680Spst		if (ancount--) {
36217680Spst			cp = ns_rprint(cp + 4, bp);
36317680Spst			while (ancount-- && cp < snapend) {
36417680Spst				putchar(',');
36517680Spst				cp = ns_rprint(cp, bp);
36617680Spst			}
36717680Spst		}
36817680Spst	}
36917680Spst	else {
37017680Spst		/* this is a request */
37117680Spst		printf(" %d%s%s",
37217680Spst		        ntohs(np->id),
37317680Spst			ns_ops[np->opcode],
37417680Spst			np->rd? "+" : "");
37517680Spst
37617680Spst		/* any weirdness? */
37717680Spst		if (*(((u_short *)np)+1) & htons(0x6ff))
37817680Spst			printf(" [b2&3=0x%x]", ntohs(*(((u_short *)np)+1)));
37917680Spst
38017680Spst		if (np->opcode == IQUERY) {
38117680Spst			if (qdcount)
38217680Spst				printf(" [%dq]", qdcount);
38317680Spst			if (ancount != 1)
38417680Spst				printf(" [%da]", ancount);
38517680Spst		}
38617680Spst		else {
38717680Spst			if (ancount)
38817680Spst				printf(" [%da]", ancount);
38917680Spst			if (qdcount != 1)
39017680Spst				printf(" [%dq]", qdcount);
39117680Spst		}
39217680Spst		if (nscount)
39317680Spst			printf(" [%dn]", nscount);
39417680Spst		if (arcount)
39517680Spst			printf(" [%dau]", arcount);
39617680Spst
39717680Spst		ns_qprint((const u_char *)(np + 1), (const u_char *)np);
39817680Spst	}
39917680Spst	printf(" (%d)", length);
40017680Spst}
401