print-domain.c revision 98527
117680Spst/* 239300Sfenner * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 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. 2056896Sfenner * 2156896Sfenner * $FreeBSD: head/contrib/tcpdump/print-domain.c 98527 2002-06-21 00:49:02Z fenner $ 2217680Spst */ 2317680Spst 2417680Spst#ifndef lint 2526183Sfennerstatic const char rcsid[] = 2698527Sfenner "@(#) $Header: /tcpdump/master/tcpdump/print-domain.c,v 1.78 2001/10/19 09:00:48 guy Exp $ (LBL)"; 2717680Spst#endif 2817680Spst 2956896Sfenner#ifdef HAVE_CONFIG_H 3056896Sfenner#include "config.h" 3156896Sfenner#endif 3256896Sfenner 3317680Spst#include <sys/param.h> 3417680Spst#include <sys/time.h> 3517680Spst 3617680Spst#include <netinet/in.h> 3717680Spst 3875118Sfenner#include "nameser.h" 3917680Spst 4017680Spst#include <stdio.h> 4156896Sfenner#include <string.h> 4217680Spst 4317680Spst#include "interface.h" 4417680Spst#include "addrtoname.h" 4517680Spst#include "extract.h" /* must come after interface.h */ 4617680Spst 4798527Sfennerstatic const char *ns_ops[] = { 4898527Sfenner "", " inv_q", " stat", " op3", " notify", " update", " op6", " op7", 4917680Spst " op8", " updataA", " updateD", " updateDA", 5017680Spst " updateM", " updateMA", " zoneInit", " zoneRef", 5117680Spst}; 5217680Spst 5398527Sfennerstatic const char *ns_resp[] = { 5417680Spst "", " FormErr", " ServFail", " NXDomain", 5598527Sfenner " NotImp", " Refused", " YXDomain", " YXRRSet", 5698527Sfenner " NXRRSet", " NotAuth", " NotZone", " Resp11", 5717680Spst " Resp12", " Resp13", " Resp14", " NoChange", 5817680Spst}; 5917680Spst 6017680Spst/* skip over a domain name */ 6117680Spststatic const u_char * 6217680Spstns_nskip(register const u_char *cp, register const u_char *bp) 6317680Spst{ 6417680Spst register u_char i; 6517680Spst 6698527Sfenner if (!TTEST2(*cp, 1)) 6798527Sfenner return (NULL); 6817680Spst if (((i = *cp++) & INDIR_MASK) == INDIR_MASK) 6917680Spst return (cp + 1); 7098527Sfenner while (i) { 7175118Sfenner if ((i & INDIR_MASK) == EDNS0_MASK) { 7275118Sfenner int bitlen, bytelen; 7375118Sfenner 7475118Sfenner if ((i & ~INDIR_MASK) != EDNS0_ELT_BITLABEL) 7575118Sfenner return(NULL); /* unknown ELT */ 7698527Sfenner if (!TTEST2(*cp, 1)) 7798527Sfenner return (NULL); 7875118Sfenner if ((bitlen = *cp++) == 0) 7975118Sfenner bitlen = 256; 8075118Sfenner bytelen = (bitlen + 7) / 8; 8175118Sfenner cp += bytelen; 8275118Sfenner } else 8375118Sfenner cp += i; 8498527Sfenner if (!TTEST2(*cp, 1)) 8598527Sfenner return (NULL); 8617680Spst i = *cp++; 8717680Spst } 8817680Spst return (cp); 8917680Spst} 9017680Spst 9117680Spst/* print a <domain-name> */ 9217680Spststatic const u_char * 9375118Sfennerblabel_print(const u_char *cp) 9417680Spst{ 9575118Sfenner int bitlen, slen, b; 9675118Sfenner int truncated = 0; 9775118Sfenner const u_char *bitp, *lim; 9875118Sfenner char tc; 9975118Sfenner 10098527Sfenner if (!TTEST2(*cp, 1)) 10175118Sfenner return(NULL); 10275118Sfenner if ((bitlen = *cp) == 0) 10375118Sfenner bitlen = 256; 10475118Sfenner slen = (bitlen + 3) / 4; 10575118Sfenner if ((lim = cp + 1 + slen) > snapend) { 10675118Sfenner truncated = 1; 10775118Sfenner lim = snapend; 10875118Sfenner } 10975118Sfenner 11075118Sfenner /* print the bit string as a hex string */ 11175118Sfenner printf("\\[x"); 11275118Sfenner for (bitp = cp + 1, b = bitlen; bitp < lim && b > 7; b -= 8, bitp++) 11375118Sfenner printf("%02x", *bitp); 11475118Sfenner if (bitp == lim) 11575118Sfenner printf("..."); 11675118Sfenner else if (b > 4) { 11775118Sfenner tc = *bitp++; 11875118Sfenner printf("%02x", tc & (0xff << (8 - b))); 11975118Sfenner } else if (b > 0) { 12075118Sfenner tc = *bitp++; 12175118Sfenner printf("%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b))); 12275118Sfenner } 12375118Sfenner printf("/%d]", bitlen); 12475118Sfenner 12575118Sfenner return(truncated ? NULL : lim); 12675118Sfenner} 12775118Sfenner 12875118Sfennerstatic int 12975118Sfennerlabellen(const u_char *cp) 13075118Sfenner{ 13117680Spst register u_int i; 13217680Spst 13398527Sfenner if (!TTEST2(*cp, 1)) 13475118Sfenner return(-1); 13575118Sfenner i = *cp; 13675118Sfenner if ((i & INDIR_MASK) == EDNS0_MASK) { 13775118Sfenner int bitlen, elt; 13875118Sfenner 13975118Sfenner if ((elt = (i & ~INDIR_MASK)) != EDNS0_ELT_BITLABEL) 14075118Sfenner return(-1); 14198527Sfenner if (!TTEST2(*(cp + 1), 1)) 14275118Sfenner return(-1); 14375118Sfenner if ((bitlen = *(cp + 1)) == 0) 14475118Sfenner bitlen = 256; 14575118Sfenner return(((bitlen + 7) / 8) + 1); 14617680Spst } else 14775118Sfenner return(i); 14875118Sfenner} 14975118Sfenner 15075118Sfennerstatic const u_char * 15175118Sfennerns_nprint(register const u_char *cp, register const u_char *bp) 15275118Sfenner{ 15375118Sfenner register u_int i, l; 15475118Sfenner register const u_char *rp = NULL; 15575118Sfenner register int compress = 0; 15675118Sfenner int chars_processed; 15775118Sfenner int elt; 15875118Sfenner int data_size = snapend - bp; 15975118Sfenner 16075118Sfenner if ((l = labellen(cp)) < 0) 16175118Sfenner return(NULL); 16298527Sfenner if (!TTEST2(*cp, 1)) 16375118Sfenner return(NULL); 16475118Sfenner chars_processed = 1; 16575118Sfenner if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) { 16617680Spst compress = 0; 16775118Sfenner rp = cp + l; 16875118Sfenner } 16975118Sfenner 17017680Spst if (i != 0) 17117680Spst while (i && cp < snapend) { 17217680Spst if ((i & INDIR_MASK) == INDIR_MASK) { 17375118Sfenner if (!compress) { 17475118Sfenner rp = cp + 1; 17575118Sfenner compress = 1; 17675118Sfenner } 17798527Sfenner if (!TTEST2(*cp, 1)) 17898527Sfenner return(NULL); 17917680Spst cp = bp + (((i << 8) | *cp) & 0x3fff); 18075118Sfenner if ((l = labellen(cp)) < 0) 18175118Sfenner return(NULL); 18298527Sfenner if (!TTEST2(*cp, 1)) 18398527Sfenner return(NULL); 18417680Spst i = *cp++; 18575118Sfenner chars_processed++; 18675118Sfenner 18775118Sfenner /* 18875118Sfenner * If we've looked at every character in 18975118Sfenner * the message, this pointer will make 19075118Sfenner * us look at some character again, 19175118Sfenner * which means we're looping. 19275118Sfenner */ 19375118Sfenner if (chars_processed >= data_size) { 19475118Sfenner printf("<LOOP>"); 19575118Sfenner return (NULL); 19675118Sfenner } 19717680Spst continue; 19817680Spst } 19975118Sfenner if ((i & INDIR_MASK) == EDNS0_MASK) { 20075118Sfenner elt = (i & ~INDIR_MASK); 20175118Sfenner switch(elt) { 20275118Sfenner case EDNS0_ELT_BITLABEL: 20398527Sfenner if (blabel_print(cp) == NULL) 20498527Sfenner return (NULL); 20575118Sfenner break; 20675118Sfenner default: 20775118Sfenner /* unknown ELT */ 20875118Sfenner printf("<ELT %d>", elt); 20975118Sfenner return(NULL); 21075118Sfenner } 21175118Sfenner } else { 21275118Sfenner if (fn_printn(cp, l, snapend)) 21398527Sfenner return(NULL); 21475118Sfenner } 21575118Sfenner 21675118Sfenner cp += l; 21775118Sfenner chars_processed += l; 21817680Spst putchar('.'); 21998527Sfenner if ((l = labellen(cp)) < 0) 22075118Sfenner return(NULL); 22198527Sfenner if (!TTEST2(*cp, 1)) 22298527Sfenner return(NULL); 22317680Spst i = *cp++; 22475118Sfenner chars_processed++; 22517680Spst if (!compress) 22675118Sfenner rp += l + 1; 22717680Spst } 22817680Spst else 22917680Spst putchar('.'); 23017680Spst return (rp); 23117680Spst} 23217680Spst 23317680Spst/* print a <character-string> */ 23417680Spststatic const u_char * 23517680Spstns_cprint(register const u_char *cp, register const u_char *bp) 23617680Spst{ 23717680Spst register u_int i; 23817680Spst 23998527Sfenner if (!TTEST2(*cp, 1)) 24098527Sfenner return (NULL); 24117680Spst i = *cp++; 24298527Sfenner if (fn_printn(cp, i, snapend)) 24398527Sfenner return (NULL); 24417680Spst return (cp + i); 24517680Spst} 24617680Spst 24798527Sfennerstruct tok ns_type2str[] = { 24817680Spst { T_A, "A" }, 24917680Spst { T_NS, "NS" }, 25017680Spst { T_MD, "MD" }, 25117680Spst { T_MF, "MF" }, 25217680Spst { T_CNAME, "CNAME" }, 25317680Spst { T_SOA, "SOA" }, 25417680Spst { T_MB, "MB" }, 25517680Spst { T_MG, "MG" }, 25617680Spst { T_MR, "MR" }, 25717680Spst { T_NULL, "NULL" }, 25817680Spst { T_WKS, "WKS" }, 25917680Spst { T_PTR, "PTR" }, 26017680Spst { T_HINFO, "HINFO" }, 26117680Spst { T_MINFO, "MINFO" }, 26217680Spst { T_MX, "MX" }, 26317680Spst { T_TXT, "TXT" }, 26417680Spst { T_RP, "RP" }, 26517680Spst { T_AFSDB, "AFSDB" }, 26617680Spst { T_X25, "X25" }, 26717680Spst { T_ISDN, "ISDN" }, 26817680Spst { T_RT, "RT" }, 26917680Spst { T_NSAP, "NSAP" }, 27017680Spst { T_NSAP_PTR, "NSAP_PTR" }, 27117680Spst { T_SIG, "SIG" }, 27217680Spst { T_KEY, "KEY" }, 27317680Spst { T_PX, "PX" }, 27417680Spst { T_GPOS, "GPOS" }, 27517680Spst { T_AAAA, "AAAA" }, 27698527Sfenner { T_LOC, "LOC" }, 27798527Sfenner { T_NXT, "NXT" }, 27898527Sfenner { T_EID, "EID" }, 27998527Sfenner { T_NIMLOC, "NIMLOC" }, 28098527Sfenner { T_SRV, "SRV" }, 28198527Sfenner { T_ATMA, "ATMA" }, 28298527Sfenner { T_NAPTR, "NAPTR" }, 28398527Sfenner { T_A6, "A6" }, 28498527Sfenner { T_DNAME, "DNAME" }, 28598527Sfenner { T_OPT, "OPT" }, 28639300Sfenner { T_UINFO, "UINFO" }, 28739300Sfenner { T_UID, "UID" }, 28839300Sfenner { T_GID, "GID" }, 28917680Spst { T_UNSPEC, "UNSPEC" }, 29017680Spst { T_UNSPECA, "UNSPECA" }, 29198527Sfenner { T_TKEY, "TKEY" }, 29298527Sfenner { T_TSIG, "TSIG" }, 29398527Sfenner { T_IXFR, "IXFR" }, 29417680Spst { T_AXFR, "AXFR" }, 29517680Spst { T_MAILB, "MAILB" }, 29617680Spst { T_MAILA, "MAILA" }, 29717680Spst { T_ANY, "ANY" }, 29817680Spst { 0, NULL } 29917680Spst}; 30017680Spst 30198527Sfennerstruct tok ns_class2str[] = { 30217680Spst { C_IN, "IN" }, /* Not used */ 30398527Sfenner { C_CHAOS, "CHAOS" }, 30417680Spst { C_HS, "HS" }, 30517680Spst { C_ANY, "ANY" }, 30617680Spst { 0, NULL } 30717680Spst}; 30817680Spst 30917680Spst/* print a query */ 31075118Sfennerstatic const u_char * 31117680Spstns_qprint(register const u_char *cp, register const u_char *bp) 31217680Spst{ 31317680Spst register const u_char *np = cp; 31417680Spst register u_int i; 31517680Spst 31617680Spst cp = ns_nskip(cp, bp); 31717680Spst 31898527Sfenner if (cp == NULL || !TTEST2(*cp, 4)) 31975118Sfenner return(NULL); 32017680Spst 32117680Spst /* print the qtype and qclass (if it's not IN) */ 32217680Spst i = *cp++ << 8; 32317680Spst i |= *cp++; 32498527Sfenner printf(" %s", tok2str(ns_type2str, "Type%d", i)); 32517680Spst i = *cp++ << 8; 32617680Spst i |= *cp++; 32717680Spst if (i != C_IN) 32898527Sfenner printf(" %s", tok2str(ns_class2str, "(Class %d)", i)); 32917680Spst 33017680Spst fputs("? ", stdout); 33175118Sfenner cp = ns_nprint(np, bp); 33275118Sfenner return(cp ? cp + 4 : NULL); 33317680Spst} 33417680Spst 33517680Spst/* print a reply */ 33617680Spststatic const u_char * 33717680Spstns_rprint(register const u_char *cp, register const u_char *bp) 33817680Spst{ 33975118Sfenner register u_int class; 34017680Spst register u_short typ, len; 34117680Spst register const u_char *rp; 34217680Spst 34317680Spst if (vflag) { 34417680Spst putchar(' '); 34575118Sfenner if ((cp = ns_nprint(cp, bp)) == NULL) 34675118Sfenner return NULL; 34717680Spst } else 34817680Spst cp = ns_nskip(cp, bp); 34917680Spst 35098527Sfenner if (cp == NULL || !TTEST2(*cp, 10)) 35117680Spst return (snapend); 35217680Spst 35317680Spst /* print the type/qtype and class (if it's not IN) */ 35417680Spst typ = *cp++ << 8; 35517680Spst typ |= *cp++; 35675118Sfenner class = *cp++ << 8; 35775118Sfenner class |= *cp++; 35875118Sfenner if (class != C_IN && typ != T_OPT) 35998527Sfenner printf(" %s", tok2str(ns_class2str, "(Class %d)", class)); 36017680Spst 36117680Spst /* ignore ttl */ 36217680Spst cp += 4; 36317680Spst 36417680Spst len = *cp++ << 8; 36517680Spst len |= *cp++; 36617680Spst 36717680Spst rp = cp + len; 36817680Spst 36998527Sfenner printf(" %s", tok2str(ns_type2str, "Type%d", typ)); 37075118Sfenner if (rp > snapend) 37175118Sfenner return(NULL); 37275118Sfenner 37317680Spst switch (typ) { 37417680Spst case T_A: 37598527Sfenner if (!TTEST2(*cp, sizeof(struct in_addr))) 37675118Sfenner return(NULL); 37717680Spst printf(" %s", ipaddr_string(cp)); 37817680Spst break; 37917680Spst 38017680Spst case T_NS: 38117680Spst case T_CNAME: 38217680Spst case T_PTR: 38356896Sfenner#ifdef T_DNAME 38475118Sfenner case T_DNAME: 38556896Sfenner#endif 38617680Spst putchar(' '); 38775118Sfenner if (ns_nprint(cp, bp) == NULL) 38875118Sfenner return(NULL); 38917680Spst break; 39017680Spst 39175118Sfenner case T_SOA: 39275118Sfenner if (!vflag) 39375118Sfenner break; 39475118Sfenner putchar(' '); 39575118Sfenner if ((cp = ns_nprint(cp, bp)) == NULL) 39675118Sfenner return(NULL); 39775118Sfenner putchar(' '); 39875118Sfenner if ((cp = ns_nprint(cp, bp)) == NULL) 39975118Sfenner return(NULL); 40098527Sfenner if (!TTEST2(*cp, 5 * 4)) 40175118Sfenner return(NULL); 40275118Sfenner printf(" %u", EXTRACT_32BITS(cp)); 40375118Sfenner cp += 4; 40475118Sfenner printf(" %u", EXTRACT_32BITS(cp)); 40575118Sfenner cp += 4; 40675118Sfenner printf(" %u", EXTRACT_32BITS(cp)); 40775118Sfenner cp += 4; 40875118Sfenner printf(" %u", EXTRACT_32BITS(cp)); 40975118Sfenner cp += 4; 41075118Sfenner printf(" %u", EXTRACT_32BITS(cp)); 41175118Sfenner cp += 4; 41275118Sfenner break; 41317680Spst case T_MX: 41417680Spst putchar(' '); 41598527Sfenner if (!TTEST2(*cp, 2)) 41675118Sfenner return(NULL); 41775118Sfenner if (ns_nprint(cp + 2, bp) == NULL) 41875118Sfenner return(NULL); 41917680Spst printf(" %d", EXTRACT_16BITS(cp)); 42017680Spst break; 42117680Spst 42217680Spst case T_TXT: 42317680Spst putchar(' '); 42417680Spst (void)ns_cprint(cp, bp); 42517680Spst break; 42617680Spst 42756896Sfenner#ifdef INET6 42856896Sfenner case T_AAAA: 42998527Sfenner if (!TTEST2(*cp, sizeof(struct in6_addr))) 43075118Sfenner return(NULL); 43156896Sfenner printf(" %s", ip6addr_string(cp)); 43256896Sfenner break; 43356896Sfenner 43475118Sfenner case T_A6: 43556896Sfenner { 43656896Sfenner struct in6_addr a; 43775118Sfenner int pbit, pbyte; 43856896Sfenner 43998527Sfenner if (!TTEST2(*cp, 1)) 44098527Sfenner return(NULL); 44175118Sfenner pbit = *cp; 44275118Sfenner pbyte = (pbit & ~7) / 8; 44375118Sfenner if (pbit > 128) { 44475118Sfenner printf(" %u(bad plen)", pbit); 44575118Sfenner break; 44675118Sfenner } else if (pbit < 128) { 44798527Sfenner if (!TTEST2(*(cp + 1), sizeof(a) - pbyte)) 44898527Sfenner return(NULL); 44975118Sfenner memset(&a, 0, sizeof(a)); 45075118Sfenner memcpy(&a.s6_addr[pbyte], cp + 1, sizeof(a) - pbyte); 45175118Sfenner printf(" %u %s", pbit, ip6addr_string(&a)); 45275118Sfenner } 45375118Sfenner if (pbit > 0) { 45475118Sfenner putchar(' '); 45575118Sfenner if (ns_nprint(cp + 1 + sizeof(a) - pbyte, bp) == NULL) 45675118Sfenner return(NULL); 45775118Sfenner } 45856896Sfenner break; 45956896Sfenner } 46056896Sfenner#endif /*INET6*/ 46156896Sfenner 46275118Sfenner case T_OPT: 46375118Sfenner printf(" UDPsize=%u", class); 46475118Sfenner break; 46575118Sfenner 46617680Spst case T_UNSPECA: /* One long string */ 46798527Sfenner if (!TTEST2(*cp, len)) 46898527Sfenner return(NULL); 46998527Sfenner if (fn_printn(cp, len, snapend)) 47098527Sfenner return(NULL); 47198527Sfenner break; 47298527Sfenner 47398527Sfenner case T_TSIG: 47498527Sfenner { 47575118Sfenner if (cp + len > snapend) 47675118Sfenner return(NULL); 47798527Sfenner if (!vflag) 47898527Sfenner break; 47998527Sfenner putchar(' '); 48098527Sfenner if ((cp = ns_nprint(cp, bp)) == NULL) 48198527Sfenner return(NULL); 48298527Sfenner cp += 6; 48398527Sfenner if (!TTEST2(*cp, 2)) 48498527Sfenner return(NULL); 48598527Sfenner printf(" fudge=%u", EXTRACT_16BITS(cp)); 48698527Sfenner cp += 2; 48798527Sfenner if (!TTEST2(*cp, 2)) 48898527Sfenner return(NULL); 48998527Sfenner printf(" maclen=%u", EXTRACT_16BITS(cp)); 49098527Sfenner cp += 2 + EXTRACT_16BITS(cp); 49198527Sfenner if (!TTEST2(*cp, 2)) 49298527Sfenner return(NULL); 49398527Sfenner printf(" origid=%u", EXTRACT_16BITS(cp)); 49498527Sfenner cp += 2; 49598527Sfenner if (!TTEST2(*cp, 2)) 49698527Sfenner return(NULL); 49798527Sfenner printf(" error=%u", EXTRACT_16BITS(cp)); 49898527Sfenner cp += 2; 49998527Sfenner if (!TTEST2(*cp, 2)) 50098527Sfenner return(NULL); 50198527Sfenner printf(" otherlen=%u", EXTRACT_16BITS(cp)); 50298527Sfenner cp += 2; 50398527Sfenner } 50417680Spst } 50526183Sfenner return (rp); /* XXX This isn't always right */ 50617680Spst} 50717680Spst 50817680Spstvoid 50917680Spstns_print(register const u_char *bp, u_int length) 51017680Spst{ 51117680Spst register const HEADER *np; 51217680Spst register int qdcount, ancount, nscount, arcount; 51398527Sfenner register const u_char *cp; 51417680Spst 51517680Spst np = (const HEADER *)bp; 51680234Sfenner TCHECK(*np); 51717680Spst /* get the byte-order right */ 51817680Spst qdcount = ntohs(np->qdcount); 51917680Spst ancount = ntohs(np->ancount); 52017680Spst nscount = ntohs(np->nscount); 52117680Spst arcount = ntohs(np->arcount); 52217680Spst 52375118Sfenner if (DNS_QR(np)) { 52417680Spst /* this is a response */ 52575118Sfenner printf(" %d%s%s%s%s%s%s", 52617680Spst ntohs(np->id), 52775118Sfenner ns_ops[DNS_OPCODE(np)], 52875118Sfenner ns_resp[DNS_RCODE(np)], 52975118Sfenner DNS_AA(np)? "*" : "", 53075118Sfenner DNS_RA(np)? "" : "-", 53175118Sfenner DNS_TC(np)? "|" : "", 53275118Sfenner DNS_CD(np)? "%" : ""); 53375118Sfenner 53417680Spst if (qdcount != 1) 53517680Spst printf(" [%dq]", qdcount); 53617680Spst /* Print QUESTION section on -vv */ 53798527Sfenner cp = (const u_char *)(np + 1); 53898527Sfenner while (qdcount--) { 53998527Sfenner if (qdcount < ntohs(np->qdcount) - 1) 54098527Sfenner putchar(','); 54198527Sfenner if (vflag > 1) { 54298527Sfenner fputs(" q:", stdout); 54398527Sfenner if ((cp = ns_qprint(cp, bp)) == NULL) 54498527Sfenner goto trunc; 54598527Sfenner } else { 54698527Sfenner if ((cp = ns_nskip(cp, bp)) == NULL) 54798527Sfenner goto trunc; 54898527Sfenner cp += 4; /* skip QTYPE and QCLASS */ 54998527Sfenner } 55075118Sfenner } 55117680Spst printf(" %d/%d/%d", ancount, nscount, arcount); 55217680Spst if (ancount--) { 55375118Sfenner if ((cp = ns_rprint(cp, bp)) == NULL) 55475118Sfenner goto trunc; 55598527Sfenner while (cp < snapend && ancount--) { 55617680Spst putchar(','); 55775118Sfenner if ((cp = ns_rprint(cp, bp)) == NULL) 55875118Sfenner goto trunc; 55917680Spst } 56017680Spst } 56198527Sfenner if (ancount > 0) 56298527Sfenner goto trunc; 56375118Sfenner /* Print NS and AR sections on -vv */ 56475118Sfenner if (vflag > 1) { 56598527Sfenner if (cp < snapend && nscount--) { 56675118Sfenner fputs(" ns:", stdout); 56775118Sfenner if ((cp = ns_rprint(cp, bp)) == NULL) 56875118Sfenner goto trunc; 56998527Sfenner while (cp < snapend && nscount--) { 57075118Sfenner putchar(','); 57175118Sfenner if ((cp = ns_rprint(cp, bp)) == NULL) 57275118Sfenner goto trunc; 57375118Sfenner } 57475118Sfenner } 57598527Sfenner if (nscount > 0) 57698527Sfenner goto trunc; 57798527Sfenner if (cp < snapend && arcount--) { 57875118Sfenner fputs(" ar:", stdout); 57975118Sfenner if ((cp = ns_rprint(cp, bp)) == NULL) 58075118Sfenner goto trunc; 58198527Sfenner while (cp < snapend && arcount--) { 58275118Sfenner putchar(','); 58375118Sfenner if ((cp = ns_rprint(cp, bp)) == NULL) 58475118Sfenner goto trunc; 58575118Sfenner } 58675118Sfenner } 58798527Sfenner if (arcount > 0) 58898527Sfenner goto trunc; 58975118Sfenner } 59017680Spst } 59117680Spst else { 59217680Spst /* this is a request */ 59375118Sfenner printf(" %d%s%s%s", ntohs(np->id), ns_ops[DNS_OPCODE(np)], 59475118Sfenner DNS_RD(np) ? "+" : "", 59575118Sfenner DNS_AD(np) ? "$" : ""); 59617680Spst 59717680Spst /* any weirdness? */ 59875118Sfenner if (*(((u_short *)np)+1) & htons(0x6cf)) 59917680Spst printf(" [b2&3=0x%x]", ntohs(*(((u_short *)np)+1))); 60017680Spst 60175118Sfenner if (DNS_OPCODE(np) == IQUERY) { 60217680Spst if (qdcount) 60317680Spst printf(" [%dq]", qdcount); 60417680Spst if (ancount != 1) 60517680Spst printf(" [%da]", ancount); 60617680Spst } 60717680Spst else { 60817680Spst if (ancount) 60917680Spst printf(" [%da]", ancount); 61017680Spst if (qdcount != 1) 61117680Spst printf(" [%dq]", qdcount); 61217680Spst } 61317680Spst if (nscount) 61417680Spst printf(" [%dn]", nscount); 61517680Spst if (arcount) 61617680Spst printf(" [%dau]", arcount); 61717680Spst 61898527Sfenner cp = (const u_char *)(np + 1); 61975118Sfenner if (qdcount--) { 62098527Sfenner cp = ns_qprint(cp, (const u_char *)np); 62175118Sfenner if (!cp) 62275118Sfenner goto trunc; 62398527Sfenner while (cp < snapend && qdcount--) { 62475118Sfenner cp = ns_qprint((const u_char *)cp, 62575118Sfenner (const u_char *)np); 62675118Sfenner if (!cp) 62775118Sfenner goto trunc; 62875118Sfenner } 62975118Sfenner } 63098527Sfenner if (qdcount > 0) 63198527Sfenner goto trunc; 63275118Sfenner 63375118Sfenner /* Print remaining sections on -vv */ 63475118Sfenner if (vflag > 1) { 63575118Sfenner if (ancount--) { 63675118Sfenner if ((cp = ns_rprint(cp, bp)) == NULL) 63775118Sfenner goto trunc; 63898527Sfenner while (cp < snapend && ancount--) { 63975118Sfenner putchar(','); 64075118Sfenner if ((cp = ns_rprint(cp, bp)) == NULL) 64175118Sfenner goto trunc; 64275118Sfenner } 64375118Sfenner } 64498527Sfenner if (ancount > 0) 64598527Sfenner goto trunc; 64698527Sfenner if (cp < snapend && nscount--) { 64775118Sfenner fputs(" ns:", stdout); 64875118Sfenner if ((cp = ns_rprint(cp, bp)) == NULL) 64975118Sfenner goto trunc; 65075118Sfenner while (nscount-- && cp < snapend) { 65175118Sfenner putchar(','); 65275118Sfenner if ((cp = ns_rprint(cp, bp)) == NULL) 65375118Sfenner goto trunc; 65475118Sfenner } 65575118Sfenner } 65698527Sfenner if (nscount > 0) 65798527Sfenner goto trunc; 65898527Sfenner if (cp < snapend && arcount--) { 65975118Sfenner fputs(" ar:", stdout); 66075118Sfenner if ((cp = ns_rprint(cp, bp)) == NULL) 66175118Sfenner goto trunc; 66298527Sfenner while (cp < snapend && arcount--) { 66375118Sfenner putchar(','); 66475118Sfenner if ((cp = ns_rprint(cp, bp)) == NULL) 66575118Sfenner goto trunc; 66675118Sfenner } 66775118Sfenner } 66898527Sfenner if (arcount > 0) 66998527Sfenner goto trunc; 67075118Sfenner } 67117680Spst } 67217680Spst printf(" (%d)", length); 67375118Sfenner return; 67475118Sfenner 67575118Sfenner trunc: 67675118Sfenner printf("[|domain]"); 67775118Sfenner return; 67817680Spst} 679