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